summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2004-07-28 03:11:36 +0000
committerkan <kan@FreeBSD.org>2004-07-28 03:11:36 +0000
commite0020c9fe3d2c91658ad0f59cb6a55c44f909db3 (patch)
treeb406472295ae0b130894cc19f02f43b36157fec6 /contrib/gcc/config
parentb754d213ab76dee1e7bcd5acb4becd5658c0ca99 (diff)
parent5e00ec74d8ce58f99801200d4d3d0412c7cc1b28 (diff)
downloadFreeBSD-src-e0020c9fe3d2c91658ad0f59cb6a55c44f909db3.zip
FreeBSD-src-e0020c9fe3d2c91658ad0f59cb6a55c44f909db3.tar.gz
This commit was generated by cvs2svn to compensate for changes in r132718,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/gcc/config')
-rw-r--r--contrib/gcc/config/alpha/alpha-modes.def23
-rw-r--r--contrib/gcc/config/alpha/alpha-protos.h245
-rw-r--r--contrib/gcc/config/alpha/alpha.h528
-rw-r--r--contrib/gcc/config/alpha/alpha.md697
-rw-r--r--contrib/gcc/config/alpha/ev4.md8
-rw-r--r--contrib/gcc/config/alpha/ev5.md8
-rw-r--r--contrib/gcc/config/alpha/ev6.md8
-rw-r--r--contrib/gcc/config/alpha/gnu.h6
-rw-r--r--contrib/gcc/config/alpha/lib1funcs.asm2
-rw-r--r--contrib/gcc/config/alpha/linux-elf.h18
-rw-r--r--contrib/gcc/config/alpha/linux.h18
-rw-r--r--contrib/gcc/config/alpha/netbsd.h13
-rw-r--r--contrib/gcc/config/alpha/openbsd.h50
-rw-r--r--contrib/gcc/config/alpha/osf.h48
-rw-r--r--contrib/gcc/config/alpha/osf5.h22
-rw-r--r--contrib/gcc/config/alpha/t-osf-pthread5
-rw-r--r--contrib/gcc/config/alpha/t-osf44
-rw-r--r--contrib/gcc/config/alpha/unicosmk.h91
-rw-r--r--contrib/gcc/config/alpha/vms-cc.c81
-rw-r--r--contrib/gcc/config/alpha/vms-crt0-64.c10
-rw-r--r--contrib/gcc/config/alpha/vms-crt0.c10
-rw-r--r--contrib/gcc/config/alpha/vms-dwarf2.asm8
-rw-r--r--contrib/gcc/config/alpha/vms-dwarf2eh.asm8
-rw-r--r--contrib/gcc/config/alpha/vms-ld.c74
-rw-r--r--contrib/gcc/config/alpha/vms-psxcrt0-64.c10
-rw-r--r--contrib/gcc/config/alpha/vms-psxcrt0.c10
-rw-r--r--contrib/gcc/config/alpha/vms.h98
-rw-r--r--contrib/gcc/config/alpha/vms64.h8
-rw-r--r--contrib/gcc/config/alpha/vms_tramp.asm8
-rw-r--r--contrib/gcc/config/alpha/xm-vms.h11
-rw-r--r--contrib/gcc/config/arm/README-interworking2
-rw-r--r--contrib/gcc/config/arm/aof.h295
-rw-r--r--contrib/gcc/config/arm/aout.h154
-rw-r--r--contrib/gcc/config/arm/arm-modes.def66
-rw-r--r--contrib/gcc/config/arm/arm-protos.h346
-rw-r--r--contrib/gcc/config/arm/arm.c4192
-rw-r--r--contrib/gcc/config/arm/arm.h1374
-rw-r--r--contrib/gcc/config/arm/arm.md3143
-rw-r--r--contrib/gcc/config/arm/cirrus.md478
-rw-r--r--contrib/gcc/config/arm/coff.h50
-rw-r--r--contrib/gcc/config/arm/crtn.asm2
-rw-r--r--contrib/gcc/config/arm/ecos-elf.h26
-rw-r--r--contrib/gcc/config/arm/elf.h75
-rw-r--r--contrib/gcc/config/arm/fpa.md752
-rw-r--r--contrib/gcc/config/arm/freebsd.h49
-rw-r--r--contrib/gcc/config/arm/ieee754-df.S1224
-rw-r--r--contrib/gcc/config/arm/ieee754-sf.S816
-rw-r--r--contrib/gcc/config/arm/iwmmxt.md1524
-rw-r--r--contrib/gcc/config/arm/kaos-arm.h24
-rw-r--r--contrib/gcc/config/arm/kaos-strongarm.h24
-rw-r--r--contrib/gcc/config/arm/lib1funcs.asm668
-rw-r--r--contrib/gcc/config/arm/linux-elf.h52
-rw-r--r--contrib/gcc/config/arm/linux-gas.h32
-rw-r--r--contrib/gcc/config/arm/mmintrin.h1257
-rw-r--r--contrib/gcc/config/arm/netbsd-elf.h36
-rw-r--r--contrib/gcc/config/arm/netbsd.h38
-rw-r--r--contrib/gcc/config/arm/pe.c41
-rw-r--r--contrib/gcc/config/arm/pe.h86
-rw-r--r--contrib/gcc/config/arm/rtems-elf.h27
-rw-r--r--contrib/gcc/config/arm/semi.h32
-rw-r--r--contrib/gcc/config/arm/semiaof.h30
-rw-r--r--contrib/gcc/config/arm/strongarm-coff.h26
-rw-r--r--contrib/gcc/config/arm/strongarm-elf.h26
-rw-r--r--contrib/gcc/config/arm/strongarm-pe.h26
-rw-r--r--contrib/gcc/config/arm/t-arm-coff2
-rw-r--r--contrib/gcc/config/arm/t-arm-elf35
-rw-r--r--contrib/gcc/config/arm/t-linux3
-rw-r--r--contrib/gcc/config/arm/t-netbsd5
-rw-r--r--contrib/gcc/config/arm/t-pe8
-rw-r--r--contrib/gcc/config/arm/t-semi6
-rw-r--r--contrib/gcc/config/arm/t-strongarm-pe5
-rw-r--r--contrib/gcc/config/arm/t-vxworks10
-rw-r--r--contrib/gcc/config/arm/t-wince-pe37
-rw-r--r--contrib/gcc/config/arm/t-xscale-elf4
-rw-r--r--contrib/gcc/config/arm/uclinux-elf.h26
-rw-r--r--contrib/gcc/config/arm/unknown-elf.h39
-rw-r--r--contrib/gcc/config/arm/vxworks.h95
-rw-r--r--contrib/gcc/config/arm/wince-pe.h29
-rw-r--r--contrib/gcc/config/arm/xscale-elf.h51
-rw-r--r--contrib/gcc/config/darwin-c.c33
-rw-r--r--contrib/gcc/config/darwin-protos.h170
-rw-r--r--contrib/gcc/config/darwin.c609
-rw-r--r--contrib/gcc/config/darwin.h154
-rw-r--r--contrib/gcc/config/dbx.h8
-rw-r--r--contrib/gcc/config/dbxcoff.h16
-rw-r--r--contrib/gcc/config/dbxelf.h16
-rw-r--r--contrib/gcc/config/elfos.h86
-rw-r--r--contrib/gcc/config/fp-bit.c104
-rw-r--r--contrib/gcc/config/fp-bit.h8
-rw-r--r--contrib/gcc/config/freebsd-nthr.h8
-rw-r--r--contrib/gcc/config/frv/cmovd.c17
-rw-r--r--contrib/gcc/config/frv/cmovh.c17
-rw-r--r--contrib/gcc/config/frv/cmovw.c17
-rw-r--r--contrib/gcc/config/frv/frv-abi.h8
-rw-r--r--contrib/gcc/config/frv/frv-asm.h18
-rw-r--r--contrib/gcc/config/frv/frv-modes.def14
-rw-r--r--contrib/gcc/config/frv/frv-protos.h329
-rw-r--r--contrib/gcc/config/frv/frv.c1736
-rw-r--r--contrib/gcc/config/frv/frv.h392
-rw-r--r--contrib/gcc/config/frv/frv.md70
-rw-r--r--contrib/gcc/config/frv/frvbegin.c33
-rw-r--r--contrib/gcc/config/frv/frvend.c19
-rw-r--r--contrib/gcc/config/frv/lib1funcs.asm17
-rw-r--r--contrib/gcc/config/frv/t-frv6
-rw-r--r--contrib/gcc/config/gnu.h12
-rw-r--r--contrib/gcc/config/gofast.h146
-rw-r--r--contrib/gcc/config/i386/athlon.md1033
-rw-r--r--contrib/gcc/config/i386/att.h30
-rw-r--r--contrib/gcc/config/i386/beos-elf.h11
-rw-r--r--contrib/gcc/config/i386/biarch64.h8
-rw-r--r--contrib/gcc/config/i386/bsd.h27
-rw-r--r--contrib/gcc/config/i386/crtdll.h27
-rw-r--r--contrib/gcc/config/i386/cygming.h391
-rw-r--r--contrib/gcc/config/i386/cygwin.asm42
-rw-r--r--contrib/gcc/config/i386/cygwin.h560
-rw-r--r--contrib/gcc/config/i386/cygwin1.c54
-rw-r--r--contrib/gcc/config/i386/cygwin2.c67
-rw-r--r--contrib/gcc/config/i386/darwin.h27
-rw-r--r--contrib/gcc/config/i386/djgpp.h29
-rw-r--r--contrib/gcc/config/i386/emmintrin.h22
-rw-r--r--contrib/gcc/config/i386/freebsd-aout.h12
-rw-r--r--contrib/gcc/config/i386/gas.h18
-rw-r--r--contrib/gcc/config/i386/gnu.h10
-rw-r--r--contrib/gcc/config/i386/gthr-win32.c4
-rw-r--r--contrib/gcc/config/i386/i386-aout.h8
-rw-r--r--contrib/gcc/config/i386/i386-coff.h15
-rw-r--r--contrib/gcc/config/i386/i386-interix.h78
-rw-r--r--contrib/gcc/config/i386/i386-interix3.h10
-rw-r--r--contrib/gcc/config/i386/i386-modes.def42
-rw-r--r--contrib/gcc/config/i386/i386-protos.h400
-rw-r--r--contrib/gcc/config/i386/i386elf.h18
-rw-r--r--contrib/gcc/config/i386/k6.md14
-rw-r--r--contrib/gcc/config/i386/kaos-i386.h24
-rw-r--r--contrib/gcc/config/i386/kfreebsdgnu.h35
-rw-r--r--contrib/gcc/config/i386/linux-aout.h13
-rw-r--r--contrib/gcc/config/i386/linux.h45
-rw-r--r--contrib/gcc/config/i386/linux64.h41
-rw-r--r--contrib/gcc/config/i386/lynx-ng.h15
-rw-r--r--contrib/gcc/config/i386/lynx.h15
-rw-r--r--contrib/gcc/config/i386/mingw32.h63
-rw-r--r--contrib/gcc/config/i386/mmintrin.h8
-rw-r--r--contrib/gcc/config/i386/moss.h9
-rw-r--r--contrib/gcc/config/i386/netbsd-elf.h16
-rw-r--r--contrib/gcc/config/i386/netbsd.h2
-rw-r--r--contrib/gcc/config/i386/netbsd64.h14
-rw-r--r--contrib/gcc/config/i386/nto.h99
-rw-r--r--contrib/gcc/config/i386/openbsd.h13
-rw-r--r--contrib/gcc/config/i386/pentium.md20
-rw-r--r--contrib/gcc/config/i386/pmmintrin.h12
-rw-r--r--contrib/gcc/config/i386/ppro.md12
-rw-r--r--contrib/gcc/config/i386/ptx4-i.h18
-rw-r--r--contrib/gcc/config/i386/rtemself.h9
-rw-r--r--contrib/gcc/config/i386/sco5.h17
-rw-r--r--contrib/gcc/config/i386/sol2.h25
-rw-r--r--contrib/gcc/config/i386/svr3dbx.h10
-rw-r--r--contrib/gcc/config/i386/svr3gas.h12
-rw-r--r--contrib/gcc/config/i386/sysv3.h15
-rw-r--r--contrib/gcc/config/i386/sysv4-cpp.h10
-rw-r--r--contrib/gcc/config/i386/sysv4.h27
-rw-r--r--contrib/gcc/config/i386/sysv5.h8
-rw-r--r--contrib/gcc/config/i386/t-beos3
-rw-r--r--contrib/gcc/config/i386/t-cygming19
-rw-r--r--contrib/gcc/config/i386/t-cygwin27
-rw-r--r--contrib/gcc/config/i386/t-interix5
-rw-r--r--contrib/gcc/config/i386/t-nto4
-rw-r--r--contrib/gcc/config/i386/t-sco51
-rw-r--r--contrib/gcc/config/i386/t-vxworks8
-rw-r--r--contrib/gcc/config/i386/unix.h10
-rw-r--r--contrib/gcc/config/i386/uwin.h14
-rw-r--r--contrib/gcc/config/i386/vsta.h8
-rw-r--r--contrib/gcc/config/i386/vxworks.h74
-rw-r--r--contrib/gcc/config/i386/winnt.c379
-rw-r--r--contrib/gcc/config/i386/x-mingw324
-rw-r--r--contrib/gcc/config/i386/xm-cygwin.h23
-rw-r--r--contrib/gcc/config/i386/xm-djgpp.h23
-rw-r--r--contrib/gcc/config/i386/xm-mingw32.h40
-rw-r--r--contrib/gcc/config/i386/xmmintrin.h31
-rw-r--r--contrib/gcc/config/ia64/crtbegin.asm269
-rw-r--r--contrib/gcc/config/ia64/crtend.asm102
-rw-r--r--contrib/gcc/config/ia64/crti.asm20
-rw-r--r--contrib/gcc/config/ia64/crtn.asm14
-rw-r--r--contrib/gcc/config/ia64/elf.h10
-rw-r--r--contrib/gcc/config/ia64/fde-glibc.c14
-rw-r--r--contrib/gcc/config/ia64/freebsd.h19
-rw-r--r--contrib/gcc/config/ia64/hpux.h55
-rw-r--r--contrib/gcc/config/ia64/ia64-c.c20
-rw-r--r--contrib/gcc/config/ia64/ia64-modes.def51
-rw-r--r--contrib/gcc/config/ia64/ia64-protos.h222
-rw-r--r--contrib/gcc/config/ia64/ia64.c5224
-rw-r--r--contrib/gcc/config/ia64/ia64.h286
-rw-r--r--contrib/gcc/config/ia64/ia64.md1861
-rw-r--r--contrib/gcc/config/ia64/itanium1.md1616
-rw-r--r--contrib/gcc/config/ia64/itanium2.md1762
-rw-r--r--contrib/gcc/config/ia64/lib1funcs.asm46
-rw-r--r--contrib/gcc/config/ia64/linux.h124
-rw-r--r--contrib/gcc/config/ia64/quadlib.c8
-rw-r--r--contrib/gcc/config/ia64/sysv4.h26
-rw-r--r--contrib/gcc/config/ia64/t-hpux11
-rw-r--r--contrib/gcc/config/ia64/t-ia6413
-rw-r--r--contrib/gcc/config/ia64/unwind-ia64.c168
-rw-r--r--contrib/gcc/config/ia64/unwind-ia64.h8
-rw-r--r--contrib/gcc/config/interix.h21
-rw-r--r--contrib/gcc/config/interix3.h8
-rw-r--r--contrib/gcc/config/kaos.h31
-rw-r--r--contrib/gcc/config/kfreebsdgnu.h41
-rw-r--r--contrib/gcc/config/libgloss.h8
-rw-r--r--contrib/gcc/config/linux-aout.h18
-rw-r--r--contrib/gcc/config/linux.h53
-rw-r--r--contrib/gcc/config/lynx-ng.h8
-rw-r--r--contrib/gcc/config/lynx.h27
-rw-r--r--contrib/gcc/config/netbsd-aout.h12
-rw-r--r--contrib/gcc/config/netbsd-elf.h9
-rw-r--r--contrib/gcc/config/netbsd.h21
-rw-r--r--contrib/gcc/config/openbsd-oldgas.h8
-rw-r--r--contrib/gcc/config/openbsd.h23
-rw-r--r--contrib/gcc/config/ptx4.h49
-rw-r--r--contrib/gcc/config/rs6000/40x.md107
-rw-r--r--contrib/gcc/config/rs6000/440.md120
-rw-r--r--contrib/gcc/config/rs6000/603.md127
-rw-r--r--contrib/gcc/config/rs6000/6xx.md234
-rw-r--r--contrib/gcc/config/rs6000/7450.md162
-rw-r--r--contrib/gcc/config/rs6000/7xx.md167
-rw-r--r--contrib/gcc/config/rs6000/8540.md235
-rw-r--r--contrib/gcc/config/rs6000/aix.h134
-rw-r--r--contrib/gcc/config/rs6000/aix41.h29
-rw-r--r--contrib/gcc/config/rs6000/aix43.h41
-rw-r--r--contrib/gcc/config/rs6000/aix51.h46
-rw-r--r--contrib/gcc/config/rs6000/aix52.h46
-rw-r--r--contrib/gcc/config/rs6000/altivec-defs.h30
-rw-r--r--contrib/gcc/config/rs6000/altivec.h69
-rw-r--r--contrib/gcc/config/rs6000/altivec.md486
-rw-r--r--contrib/gcc/config/rs6000/beos.h30
-rw-r--r--contrib/gcc/config/rs6000/biarch64.h22
-rw-r--r--contrib/gcc/config/rs6000/crtsavres.asm102
-rw-r--r--contrib/gcc/config/rs6000/darwin-ldouble.c205
-rw-r--r--contrib/gcc/config/rs6000/darwin.h170
-rw-r--r--contrib/gcc/config/rs6000/default64.h24
-rw-r--r--contrib/gcc/config/rs6000/eabi-ci.asm2
-rw-r--r--contrib/gcc/config/rs6000/eabi-cn.asm2
-rw-r--r--contrib/gcc/config/rs6000/eabi.h39
-rw-r--r--contrib/gcc/config/rs6000/eabialtivec.h34
-rw-r--r--contrib/gcc/config/rs6000/eabisim.h33
-rw-r--r--contrib/gcc/config/rs6000/eabispe.h70
-rw-r--r--contrib/gcc/config/rs6000/freebsd.h29
-rw-r--r--contrib/gcc/config/rs6000/gnu.h30
-rw-r--r--contrib/gcc/config/rs6000/host-darwin.c189
-rw-r--r--contrib/gcc/config/rs6000/kaos-ppc.h24
-rw-r--r--contrib/gcc/config/rs6000/libgcc-ppc64.ver7
-rw-r--r--contrib/gcc/config/rs6000/linux.h60
-rw-r--r--contrib/gcc/config/rs6000/linux64.h686
-rw-r--r--contrib/gcc/config/rs6000/linuxaltivec.h32
-rw-r--r--contrib/gcc/config/rs6000/linuxspe.h70
-rw-r--r--contrib/gcc/config/rs6000/lynx.h80
-rw-r--r--contrib/gcc/config/rs6000/lynxbase.h45
-rw-r--r--contrib/gcc/config/rs6000/mpc.md99
-rw-r--r--contrib/gcc/config/rs6000/netbsd.h50
-rw-r--r--contrib/gcc/config/rs6000/power4.md392
-rw-r--r--contrib/gcc/config/rs6000/power5.md299
-rw-r--r--contrib/gcc/config/rs6000/ppc-asm.h38
-rw-r--r--contrib/gcc/config/rs6000/ppc64-fp.c55
-rw-r--r--contrib/gcc/config/rs6000/rios1.md179
-rw-r--r--contrib/gcc/config/rs6000/rios2.md117
-rw-r--r--contrib/gcc/config/rs6000/rs6000-c.c41
-rw-r--r--contrib/gcc/config/rs6000/rs6000-modes.def43
-rw-r--r--contrib/gcc/config/rs6000/rs6000-protos.h350
-rw-r--r--contrib/gcc/config/rs6000/rs6000.c7611
-rw-r--r--contrib/gcc/config/rs6000/rs6000.h934
-rw-r--r--contrib/gcc/config/rs6000/rs6000.md3233
-rw-r--r--contrib/gcc/config/rs6000/rs64.md128
-rw-r--r--contrib/gcc/config/rs6000/rtems.h27
-rw-r--r--contrib/gcc/config/rs6000/sol-ci.asm2
-rw-r--r--contrib/gcc/config/rs6000/sol-cn.asm2
-rw-r--r--contrib/gcc/config/rs6000/spe.h649
-rw-r--r--contrib/gcc/config/rs6000/spe.md530
-rw-r--r--contrib/gcc/config/rs6000/sysv4.h656
-rw-r--r--contrib/gcc/config/rs6000/sysv4le.h41
-rw-r--r--contrib/gcc/config/rs6000/t-beos17
-rw-r--r--contrib/gcc/config/rs6000/t-darwin9
-rw-r--r--contrib/gcc/config/rs6000/t-fprules29
-rw-r--r--contrib/gcc/config/rs6000/t-linux6453
-rw-r--r--contrib/gcc/config/rs6000/t-newas17
-rw-r--r--contrib/gcc/config/rs6000/t-ppccomm23
-rw-r--r--contrib/gcc/config/rs6000/t-ppcgas7
-rw-r--r--contrib/gcc/config/rs6000/t-rs600031
-rw-r--r--contrib/gcc/config/rs6000/t-spe68
-rw-r--r--contrib/gcc/config/rs6000/t-vxworks10
-rw-r--r--contrib/gcc/config/rs6000/tramp.asm2
-rw-r--r--contrib/gcc/config/rs6000/vxworks.h82
-rw-r--r--contrib/gcc/config/rs6000/windiss.h42
-rw-r--r--contrib/gcc/config/rs6000/x-darwin4
-rw-r--r--contrib/gcc/config/rs6000/x-linux642
-rw-r--r--contrib/gcc/config/rs6000/xcoff.h165
-rw-r--r--contrib/gcc/config/rtems.h24
-rw-r--r--contrib/gcc/config/s390/2064.md131
-rw-r--r--contrib/gcc/config/s390/2084.md262
-rw-r--r--contrib/gcc/config/s390/fixdfdi.h24
-rw-r--r--contrib/gcc/config/s390/linux.h73
-rw-r--r--contrib/gcc/config/s390/s390-modes.def60
-rw-r--r--contrib/gcc/config/s390/s390-protos.h161
-rw-r--r--contrib/gcc/config/s390/s390.c3889
-rw-r--r--contrib/gcc/config/s390/s390.h457
-rw-r--r--contrib/gcc/config/s390/s390.md5624
-rw-r--r--contrib/gcc/config/s390/s390x.h25
-rw-r--r--contrib/gcc/config/s390/t-tpf13
-rw-r--r--contrib/gcc/config/s390/tpf.h112
-rw-r--r--contrib/gcc/config/sol2.h47
-rw-r--r--contrib/gcc/config/sparc/aout.h26
-rw-r--r--contrib/gcc/config/sparc/biarch64.h10
-rw-r--r--contrib/gcc/config/sparc/cypress.md8
-rw-r--r--contrib/gcc/config/sparc/elf.h30
-rw-r--r--contrib/gcc/config/sparc/gmon-sol2.c29
-rw-r--r--contrib/gcc/config/sparc/hypersparc.md8
-rw-r--r--contrib/gcc/config/sparc/linux.h89
-rw-r--r--contrib/gcc/config/sparc/linux64.h102
-rw-r--r--contrib/gcc/config/sparc/lite.h18
-rw-r--r--contrib/gcc/config/sparc/litecoff.h19
-rw-r--r--contrib/gcc/config/sparc/liteelf.h25
-rw-r--r--contrib/gcc/config/sparc/netbsd-elf.h41
-rw-r--r--contrib/gcc/config/sparc/openbsd.h29
-rw-r--r--contrib/gcc/config/sparc/openbsd64.h19
-rw-r--r--contrib/gcc/config/sparc/pbd.h39
-rw-r--r--contrib/gcc/config/sparc/rtemself.h23
-rw-r--r--contrib/gcc/config/sparc/sol2-64.h11
-rw-r--r--contrib/gcc/config/sparc/sol2-bi.h80
-rw-r--r--contrib/gcc/config/sparc/sol2-gas-bi.h6
-rw-r--r--contrib/gcc/config/sparc/sol2-gld-bi.h27
-rw-r--r--contrib/gcc/config/sparc/sol2-gld.h5
-rw-r--r--contrib/gcc/config/sparc/sol2.h86
-rw-r--r--contrib/gcc/config/sparc/sol26-sld.h7
-rw-r--r--contrib/gcc/config/sparc/sp64-aout.h10
-rw-r--r--contrib/gcc/config/sparc/sp64-elf.h22
-rw-r--r--contrib/gcc/config/sparc/sp86x-elf.h25
-rw-r--r--contrib/gcc/config/sparc/sparc-modes.def24
-rw-r--r--contrib/gcc/config/sparc/sparc-protos.h177
-rw-r--r--contrib/gcc/config/sparc/sparc.c2926
-rw-r--r--contrib/gcc/config/sparc/sparc.h525
-rw-r--r--contrib/gcc/config/sparc/sparc.md729
-rw-r--r--contrib/gcc/config/sparc/sparclet.md8
-rw-r--r--contrib/gcc/config/sparc/supersparc.md8
-rw-r--r--contrib/gcc/config/sparc/sysv4-only.h35
-rw-r--r--contrib/gcc/config/sparc/sysv4.h24
-rw-r--r--contrib/gcc/config/sparc/t-sol23
-rw-r--r--contrib/gcc/config/sparc/ultra1_2.md58
-rw-r--r--contrib/gcc/config/sparc/ultra3.md29
-rw-r--r--contrib/gcc/config/svr3.h81
-rw-r--r--contrib/gcc/config/svr4.h39
-rw-r--r--contrib/gcc/config/t-darwin18
-rw-r--r--contrib/gcc/config/t-freebsd3
-rw-r--r--contrib/gcc/config/t-gnu2
-rw-r--r--contrib/gcc/config/t-kfreebsd-gnu16
-rw-r--r--contrib/gcc/config/t-libunwind6
-rw-r--r--contrib/gcc/config/t-linux7
-rw-r--r--contrib/gcc/config/t-netbsd3
-rw-r--r--contrib/gcc/config/t-openbsd3
-rw-r--r--contrib/gcc/config/t-rtems3
-rw-r--r--contrib/gcc/config/t-slibgcc-darwin30
-rw-r--r--contrib/gcc/config/t-slibgcc-elf-ver5
-rw-r--r--contrib/gcc/config/t-vxworks22
-rw-r--r--contrib/gcc/config/usegas.h8
-rw-r--r--contrib/gcc/config/vxlib.c325
-rw-r--r--contrib/gcc/config/vxworks.h64
-rw-r--r--contrib/gcc/config/windiss.h38
362 files changed, 50065 insertions, 26969 deletions
diff --git a/contrib/gcc/config/alpha/alpha-modes.def b/contrib/gcc/config/alpha/alpha-modes.def
new file mode 100644
index 0000000..8e9e698
--- /dev/null
+++ b/contrib/gcc/config/alpha/alpha-modes.def
@@ -0,0 +1,23 @@
+/* Alpha extra machine modes.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* 128-bit floating point. This gets reset in alpha_override_options
+ if VAX float format is in use. */
+FLOAT_MODE (TF, 16, ieee_quad_format);
diff --git a/contrib/gcc/config/alpha/alpha-protos.h b/contrib/gcc/config/alpha/alpha-protos.h
index fe4943b..95f1ad2 100644
--- a/contrib/gcc/config/alpha/alpha-protos.h
+++ b/contrib/gcc/config/alpha/alpha-protos.h
@@ -1,182 +1,123 @@
/* Prototypes for alpha.c functions used in the md file & elsewhere.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
extern int alpha_next_sequence_number;
-extern void literal_section PARAMS ((void));
-extern void override_options PARAMS ((void));
-extern int zap_mask PARAMS ((HOST_WIDE_INT));
-extern int direct_return PARAMS ((void));
-
-extern int alpha_sa_size PARAMS ((void));
-extern int alpha_pv_save_size PARAMS ((void));
-extern int alpha_using_fp PARAMS ((void));
-extern void alpha_write_verstamp PARAMS ((FILE *));
-extern void alpha_expand_prologue PARAMS ((void));
-extern void alpha_expand_epilogue PARAMS ((void));
-extern void alpha_output_filename PARAMS ((FILE *, const char *));
-extern void alpha_output_lineno PARAMS ((FILE *, int));
-
-extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_6bit_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_8bit_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_const_int_operand PARAMS ((rtx, enum machine_mode));
-extern int cint8_operand PARAMS ((rtx, enum machine_mode));
-extern int add_operand PARAMS ((rtx, enum machine_mode));
-extern int sext_add_operand PARAMS ((rtx, enum machine_mode));
-extern int const48_operand PARAMS ((rtx, enum machine_mode));
-extern int and_operand PARAMS ((rtx, enum machine_mode));
-extern int or_operand PARAMS ((rtx, enum machine_mode));
-extern int mode_width_operand PARAMS ((rtx, enum machine_mode));
-extern int mode_mask_operand PARAMS ((rtx, enum machine_mode));
-extern int mul8_operand PARAMS ((rtx, enum machine_mode));
-extern int const0_operand PARAMS ((rtx, enum machine_mode));
-extern int hard_fp_register_operand PARAMS ((rtx, enum machine_mode));
-extern int hard_int_register_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int some_operand PARAMS ((rtx, enum machine_mode));
-extern int some_ni_operand PARAMS ((rtx, enum machine_mode));
-extern int input_operand PARAMS ((rtx, enum machine_mode));
-extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
-extern int direct_call_operand PARAMS ((rtx, enum machine_mode));
-extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int dtp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int dtp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int gotdtp_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int tp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int tp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int gottp_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int call_operand PARAMS ((rtx, enum machine_mode));
-extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int alpha_zero_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int alpha_swapped_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int signed_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int alpha_fp_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int divmod_operator PARAMS ((rtx, enum machine_mode));
-extern int aligned_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int unaligned_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_unaligned_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int any_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_not_elim_operand PARAMS ((rtx, enum machine_mode));
-extern int normal_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_no_subreg_operand PARAMS ((rtx, enum machine_mode));
-extern int addition_operation PARAMS ((rtx, enum machine_mode));
-
-extern bool alpha_const_ok_for_letter_p PARAMS ((HOST_WIDE_INT, int));
-extern bool alpha_const_double_ok_for_letter_p PARAMS ((rtx, int));
-extern bool alpha_extra_constraint PARAMS ((rtx, int));
-
-extern rtx alpha_tablejump_addr_vec PARAMS ((rtx));
-extern rtx alpha_tablejump_best_label PARAMS ((rtx));
-
-extern bool alpha_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
-extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
- int, int, int));
-
-extern rtx split_small_symbolic_operand PARAMS ((rtx));
-
-extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
-extern rtx get_unaligned_address PARAMS ((rtx, int));
-extern enum reg_class alpha_preferred_reload_class PARAMS ((rtx,
- enum reg_class));
-extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
- enum machine_mode,
- rtx, int));
-
-extern void alpha_set_memflags PARAMS ((rtx, rtx));
-extern rtx alpha_emit_set_const PARAMS ((rtx, enum machine_mode,
- HOST_WIDE_INT, int));
-extern rtx alpha_emit_set_long_const PARAMS ((rtx, HOST_WIDE_INT,
- HOST_WIDE_INT));
-extern bool alpha_expand_mov PARAMS ((enum machine_mode, rtx *));
-extern bool alpha_expand_mov_nobwx PARAMS ((enum machine_mode, rtx *));
-extern void alpha_emit_floatuns PARAMS ((rtx[]));
-extern rtx alpha_emit_conditional_move PARAMS ((rtx, enum machine_mode));
-extern void alpha_split_tfmode_pair PARAMS ((rtx[]));
-extern void alpha_split_tfmode_frobsign PARAMS ((rtx[],
- rtx (*)(rtx, rtx, rtx)));
-extern void alpha_expand_unaligned_load PARAMS ((rtx, rtx, HOST_WIDE_INT,
- HOST_WIDE_INT, int));
-extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,
- HOST_WIDE_INT));
-extern int alpha_expand_block_move PARAMS ((rtx []));
-extern int alpha_expand_block_clear PARAMS ((rtx []));
-extern rtx alpha_expand_zap_mask PARAMS ((HOST_WIDE_INT));
-extern void alpha_expand_builtin_vector_binop PARAMS ((rtx (*)(rtx, rtx, rtx),
- enum machine_mode,
- rtx, rtx, rtx));
-extern rtx alpha_return_addr PARAMS ((int, rtx));
-extern rtx alpha_gp_save_rtx PARAMS ((void));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern void print_operand_address PARAMS ((FILE *, rtx));
-extern void alpha_initialize_trampoline PARAMS ((rtx, rtx, rtx, int, int, int));
-extern void alpha_reorg PARAMS ((rtx));
-
-extern tree alpha_build_va_list PARAMS ((void));
-extern void alpha_va_start PARAMS ((tree, rtx));
-extern rtx alpha_va_arg PARAMS ((tree, tree));
-extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
- tree, int));
-extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
-extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
-
-extern int alpha_find_lo_sum_using_gp PARAMS ((rtx));
+extern void literal_section (void);
+extern void override_options (void);
+extern int zap_mask (HOST_WIDE_INT);
+extern int direct_return (void);
+
+extern int alpha_sa_size (void);
+extern HOST_WIDE_INT alpha_initial_elimination_offset (unsigned int,
+ unsigned int);
+extern int alpha_pv_save_size (void);
+extern int alpha_using_fp (void);
+extern void alpha_expand_prologue (void);
+extern void alpha_expand_epilogue (void);
+extern void alpha_output_filename (FILE *, const char *);
+extern void alpha_output_lineno (FILE *, int);
+
+extern bool alpha_const_ok_for_letter_p (HOST_WIDE_INT, int);
+extern bool alpha_const_double_ok_for_letter_p (rtx, int);
+extern bool alpha_extra_constraint (rtx, int);
+
+extern rtx alpha_tablejump_addr_vec (rtx);
+extern rtx alpha_tablejump_best_label (rtx);
+
+extern bool alpha_legitimate_address_p (enum machine_mode, rtx, int);
+extern rtx alpha_legitimize_address (rtx, rtx, enum machine_mode);
+extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
+ int, int, int);
+
+extern rtx split_small_symbolic_operand (rtx);
+
+extern void get_aligned_mem (rtx, rtx *, rtx *);
+extern rtx get_unaligned_address (rtx, int);
+extern enum reg_class alpha_preferred_reload_class (rtx, enum reg_class);
+extern enum reg_class secondary_reload_class (enum reg_class,
+ enum machine_mode, rtx, int);
+
+extern void alpha_set_memflags (rtx, rtx);
+extern rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT, int);
+extern rtx alpha_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
+extern bool alpha_expand_mov (enum machine_mode, rtx *);
+extern bool alpha_expand_mov_nobwx (enum machine_mode, rtx *);
+extern void alpha_emit_floatuns (rtx[]);
+extern rtx alpha_emit_conditional_move (rtx, enum machine_mode);
+extern void alpha_split_tfmode_pair (rtx[]);
+extern void alpha_split_tfmode_frobsign (rtx[], rtx (*)(rtx, rtx, rtx));
+extern void alpha_expand_unaligned_load (rtx, rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT, int);
+extern void alpha_expand_unaligned_store (rtx, rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT);
+extern int alpha_expand_block_move (rtx []);
+extern int alpha_expand_block_clear (rtx []);
+extern rtx alpha_expand_zap_mask (HOST_WIDE_INT);
+extern void alpha_expand_builtin_vector_binop (rtx (*)(rtx, rtx, rtx),
+ enum machine_mode,
+ rtx, rtx, rtx);
+extern rtx alpha_return_addr (int, rtx);
+extern rtx alpha_gp_save_rtx (void);
+extern void print_operand (FILE *, rtx, int);
+extern void print_operand_address (FILE *, rtx);
+extern void alpha_initialize_trampoline (rtx, rtx, rtx, int, int, int);
+
+extern void alpha_va_start (tree, rtx);
+extern rtx alpha_va_arg (tree, tree);
+extern rtx function_arg (CUMULATIVE_ARGS, enum machine_mode, tree, int);
+extern rtx function_value (tree, tree, enum machine_mode);
+
+extern void alpha_start_function (FILE *, const char *, tree);
+extern void alpha_end_function (FILE *, const char *, tree);
+
+extern int alpha_find_lo_sum_using_gp (rtx);
#ifdef REAL_VALUE_TYPE
-extern int check_float_value PARAMS ((enum machine_mode,
- REAL_VALUE_TYPE *, int));
+extern int check_float_value (enum machine_mode, REAL_VALUE_TYPE *, int);
#endif
#ifdef RTX_CODE
-extern rtx alpha_emit_conditional_branch PARAMS ((enum rtx_code));
-extern rtx alpha_emit_setcc PARAMS ((enum rtx_code));
-extern int alpha_split_conditional_move PARAMS ((enum rtx_code, rtx, rtx,
- rtx, rtx));
-extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[]));
-extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[]));
+extern rtx alpha_emit_conditional_branch (enum rtx_code);
+extern rtx alpha_emit_setcc (enum rtx_code);
+extern int alpha_split_conditional_move (enum rtx_code, rtx, rtx, rtx, rtx);
+extern void alpha_emit_xfloating_arith (enum rtx_code, rtx[]);
+extern void alpha_emit_xfloating_cvt (enum rtx_code, rtx[]);
#endif
-extern rtx alpha_need_linkage PARAMS ((const char *, int));
-extern rtx alpha_use_linkage PARAMS ((rtx, tree, int, int));
+extern rtx alpha_need_linkage (const char *, int);
+extern rtx alpha_use_linkage (rtx, tree, int, int);
#if TARGET_ABI_OPEN_VMS
-#ifdef HAVE_MACHINE_MODES
-extern enum avms_arg_type alpha_arg_type PARAMS ((enum machine_mode));
+extern enum avms_arg_type alpha_arg_type (enum machine_mode);
+extern rtx alpha_arg_info_reg_val (CUMULATIVE_ARGS);
#endif
-extern rtx alpha_arg_info_reg_val PARAMS ((CUMULATIVE_ARGS));
-#endif /* TARGET_ABI_OPEN_VMS */
-extern rtx unicosmk_add_call_info_word PARAMS ((rtx));
+extern rtx unicosmk_add_call_info_word (rtx);
#if TARGET_ABI_UNICOSMK
-extern void unicosmk_defer_case_vector PARAMS ((rtx, rtx));
-extern void unicosmk_add_extern PARAMS ((const char *));
-extern void unicosmk_output_align PARAMS ((FILE *, int));
-extern char * unicosmk_text_section PARAMS ((void));
-extern char * unicosmk_data_section PARAMS ((void));
-extern void unicosmk_asm_file_start PARAMS ((FILE *));
-extern void unicosmk_asm_file_end PARAMS ((FILE *));
-extern void unicosmk_output_common PARAMS ((FILE *, const char *, int, int));
-#endif /* TARGET_ABI_UNICOSMK */
+extern void unicosmk_defer_case_vector (rtx, rtx);
+extern void unicosmk_add_extern (const char *);
+extern void unicosmk_output_align (FILE *, int);
+extern char * unicosmk_text_section (void);
+extern char * unicosmk_data_section (void);
+extern void unicosmk_output_common (FILE *, const char *, int, int);
+extern int unicosmk_initial_elimination_offset (int, int);
+#endif
diff --git a/contrib/gcc/config/alpha/alpha.h b/contrib/gcc/config/alpha/alpha.h
index 6b52700..d59797c 100644
--- a/contrib/gcc/config/alpha/alpha.h
+++ b/contrib/gcc/config/alpha/alpha.h
@@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -67,6 +67,8 @@ Boston, MA 02111-1307, USA. */
builtin_define ("_IEEE_FP"); \
if (TARGET_IEEE_WITH_INEXACT) \
builtin_define ("_IEEE_FP_INEXACT"); \
+ if (TARGET_LONG_DOUBLE_128) \
+ builtin_define ("__LONG_DOUBLE_128__"); \
\
/* Macros dependent on the C dialect. */ \
SUBTARGET_LANGUAGE_CPP_BUILTINS(); \
@@ -78,14 +80,14 @@ Boston, MA 02111-1307, USA. */
{ \
if (preprocessing_asm_p ()) \
builtin_define_std ("LANGUAGE_ASSEMBLY"); \
- else if (c_language == clk_c) \
- builtin_define_std ("LANGUAGE_C"); \
- else if (c_language == clk_cplusplus) \
+ else if (c_dialect_cxx ()) \
{ \
builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \
} \
- if (flag_objc) \
+ else \
+ builtin_define_std ("LANGUAGE_C"); \
+ if (c_dialect_objc ()) \
{ \
builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
builtin_define ("__LANGUAGE_OBJECTIVE_C__"); \
@@ -112,9 +114,12 @@ Boston, MA 02111-1307, USA. */
mirrors this list, so changes to alpha.md must be made at the same time. */
enum processor_type
- {PROCESSOR_EV4, /* 2106[46]{a,} */
+{
+ PROCESSOR_EV4, /* 2106[46]{a,} */
PROCESSOR_EV5, /* 21164{a,pc,} */
- PROCESSOR_EV6}; /* 21264 */
+ PROCESSOR_EV6, /* 21264 */
+ PROCESSOR_MAX
+};
extern enum processor_type alpha_cpu;
@@ -222,6 +227,15 @@ extern int alpha_tls_size;
#define MASK_TLS_KERNEL (1 << 14)
#define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL)
+/* This means use direct branches to local functions. */
+#define MASK_SMALL_TEXT (1 << 15)
+#define TARGET_SMALL_TEXT (target_flags & MASK_SMALL_TEXT)
+
+/* This means use IEEE quad-format for long double. Assumes the
+ presence of the GEM support library routines. */
+#define MASK_LONG_DOUBLE_128 (1 << 16)
+#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
+
/* This means that the processor is an EV5, EV56, or PCA56.
Unlike alpha_cpu this is not affected by -mtune= setting. */
#define MASK_CPU_EV5 (1 << 28)
@@ -254,7 +268,7 @@ extern int alpha_tls_size;
#define TARGET_CAN_FAULT_IN_PROLOGUE 0
#endif
#ifndef TARGET_HAS_XFLOATING_LIBS
-#define TARGET_HAS_XFLOATING_LIBS 0
+#define TARGET_HAS_XFLOATING_LIBS TARGET_LONG_DOUBLE_128
#endif
#ifndef TARGET_PROFILING_NEEDS_GP
#define TARGET_PROFILING_NEEDS_GP 0
@@ -310,8 +324,15 @@ extern int alpha_tls_size;
N_("Emit 16-bit relocations to the small data areas")}, \
{"large-data", -MASK_SMALL_DATA, \
N_("Emit 32-bit relocations to the small data areas")}, \
+ {"small-text", MASK_SMALL_TEXT, \
+ N_("Emit direct branches to local functions")}, \
+ {"large-text", -MASK_SMALL_TEXT, ""}, \
{"tls-kernel", MASK_TLS_KERNEL, \
N_("Emit rdval instead of rduniq for thread pointer")}, \
+ {"long-double-128", MASK_LONG_DOUBLE_128, \
+ N_("Use 128-bit long double")}, \
+ {"long-double-64", -MASK_LONG_DOUBLE_128, \
+ N_("Use 64-bit long double")}, \
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \
| TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
@@ -340,27 +361,34 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define TARGET_OPTIONS \
{ \
{"cpu=", &alpha_cpu_string, \
- N_("Use features of and schedule given CPU")}, \
+ N_("Use features of and schedule given CPU"), 0}, \
{"tune=", &alpha_tune_string, \
- N_("Schedule given CPU")}, \
+ N_("Schedule given CPU"), 0}, \
{"fp-rounding-mode=", &alpha_fprm_string, \
- N_("Control the generated fp rounding mode")}, \
+ N_("Control the generated fp rounding mode"), 0}, \
{"fp-trap-mode=", &alpha_fptm_string, \
- N_("Control the IEEE trap mode")}, \
+ N_("Control the IEEE trap mode"), 0}, \
{"trap-precision=", &alpha_tp_string, \
- N_("Control the precision given to fp exceptions")}, \
+ N_("Control the precision given to fp exceptions"), 0}, \
{"memory-latency=", &alpha_mlat_string, \
- N_("Tune expected memory latency")}, \
+ N_("Tune expected memory latency"), 0}, \
{"tls-size=", &alpha_tls_size_string, \
- N_("Specify bit size of immediate TLS offsets")}, \
+ N_("Specify bit size of immediate TLS offsets"), 0}, \
}
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }
+
/* This macro defines names of additional specifications to put in the
specs that can be used in various specifications like CC1_SPEC. Its
definition is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -421,7 +449,18 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+
+/* Define this to set long double type size to use in libgcc2.c, which can
+ not depend on target_flags. */
+#ifdef __LONG_DOUBLE_128__
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#endif
+
+/* Work around target_flags dependency in ada/targtyps.c. */
+#define WIDEST_HARDWARE_FP_SIZE 64
#define WCHAR_TYPE "unsigned int"
#define WCHAR_TYPE_SIZE 32
@@ -444,15 +483,6 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
(MODE) = DImode; \
}
-/* Define this if function arguments should also be promoted using the above
- procedure. */
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted. */
-
-#define PROMOTE_FUNCTION_RETURN
-
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields.
@@ -482,7 +512,7 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define PARM_BOUNDARY 64
/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY 64
+#define STACK_BOUNDARY 128
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -571,44 +601,30 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
/* List the order in which to allocate registers. Each register must be
- listed once, even those in FIXED_REGISTERS.
-
- We allocate in the following order:
- $f10-$f15 (nonsaved floating-point register)
- $f22-$f30 (likewise)
- $f21-$f16 (likewise, but input args)
- $f0 (nonsaved, but return value)
- $f1 (nonsaved, but immediate before saved)
- $f2-$f9 (saved floating-point registers)
- $1-$8 (nonsaved integer registers)
- $22-$25 (likewise)
- $28 (likewise)
- $0 (likewise, but return value)
- $21-$16 (likewise, but input args)
- $27 (procedure value in OSF, nonsaved in NT)
- $9-$14 (saved integer registers)
- $26 (return PC)
- $15 (frame pointer)
- $29 (global pointer)
- $30, $31, $f31 (stack pointer and always zero/ap & fp) */
-
-#define REG_ALLOC_ORDER \
- {42, 43, 44, 45, 46, 47, \
- 54, 55, 56, 57, 58, 59, 60, 61, 62, \
- 53, 52, 51, 50, 49, 48, \
- 32, 33, \
- 34, 35, 36, 37, 38, 39, 40, 41, \
- 1, 2, 3, 4, 5, 6, 7, 8, \
- 22, 23, 24, 25, \
- 28, \
- 0, \
- 21, 20, 19, 18, 17, 16, \
- 27, \
- 9, 10, 11, 12, 13, 14, \
- 26, \
- 15, \
- 29, \
- 30, 31, 63 }
+ listed once, even those in FIXED_REGISTERS. */
+
+#define REG_ALLOC_ORDER { \
+ 1, 2, 3, 4, 5, 6, 7, 8, /* nonsaved integer registers */ \
+ 22, 23, 24, 25, 28, /* likewise */ \
+ 0, /* likewise, but return value */ \
+ 21, 20, 19, 18, 17, 16, /* likewise, but input args */ \
+ 27, /* likewise, but OSF procedure value */ \
+ \
+ 42, 43, 44, 45, 46, 47, /* nonsaved floating-point registers */ \
+ 54, 55, 56, 57, 58, 59, /* likewise */ \
+ 60, 61, 62, /* likewise */ \
+ 32, 33, /* likewise, but return values */ \
+ 53, 52, 51, 50, 49, 48, /* likewise, but input args */ \
+ \
+ 9, 10, 11, 12, 13, 14, /* saved integer registers */ \
+ 26, /* return address */ \
+ 15, /* hard frame pointer */ \
+ \
+ 34, 35, 36, 37, 38, 39, /* saved floating-point registers */ \
+ 40, 41, /* likewise */ \
+ \
+ 29, 30, 31, 63 /* gp, sp, ap, sfp */ \
+}
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@@ -620,12 +636,11 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
On Alpha, the integer registers can hold any mode. The floating-point
- registers can hold 32-bit and 64-bit integers as well, but not 16-bit
- or 8-bit values. */
+ registers can hold 64-bit integers as well, but not smaller values. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
((REGNO) >= 32 && (REGNO) <= 62 \
- ? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
+ ? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode \
: 1)
/* Value is 1 if MODE is a supported vector mode. */
@@ -686,11 +701,6 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
current_file functions. Moreover, we do not expose the ldgp
until after reload, so we're probably safe. */
/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
-
-/* Register in which address to store a structure value
- arrives in the function. On the Alpha, the address is passed
- as a hidden argument. */
-#define STRUCT_VALUE 0
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
@@ -810,7 +820,7 @@ enum reg_class {
'U' is a symbolic operand.
- 'W' is a vector zero. */
+ 'W' is a vector zero. */
#define EXTRA_CONSTRAINT alpha_extra_constraint
@@ -953,19 +963,8 @@ extern int alpha_memory_latency;
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-{ if ((FROM) == FRAME_POINTER_REGNUM) \
- (OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \
- + alpha_sa_size ()); \
- else if ((FROM) == ARG_POINTER_REGNUM) \
- (OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \
- + alpha_sa_size () \
- + (ALPHA_ROUND (get_frame_size () \
- + current_function_pretend_args_size) \
- - current_function_pretend_args_size)); \
- else \
- abort (); \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ ((OFFSET) = alpha_initial_elimination_offset(FROM, TO))
/* Define this if stack space is still allocated for a parameter passed
in a register. */
@@ -988,37 +987,14 @@ extern int alpha_memory_latency;
On Alpha the value is found in $0 for integer functions and
$f0 for floating-point functions. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- || POINTER_TYPE_P (VALTYPE)) \
- ? word_mode : TYPE_MODE (VALTYPE), \
- ((TARGET_FPREGS \
- && (TREE_CODE (VALTYPE) == REAL_TYPE \
- || TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \
- ? 32 : 0))
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ function_value (VALTYPE, FUNC, VOIDmode)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, \
- (TARGET_FPREGS \
- && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
- ? 32 : 0))
-
-/* The definition of this macro implies that there are cases where
- a scalar value cannot be returned in registers.
-
- For the Alpha, any structure or union type is returned in memory, as
- are integers whose size is larger than 64 bits. */
-
-#define RETURN_IN_MEMORY(TYPE) \
- (TYPE_MODE (TYPE) == BLKmode \
- || TYPE_MODE (TYPE) == TFmode \
- || TYPE_MODE (TYPE) == TCmode \
- || (TREE_CODE (TYPE) == INTEGER_TYPE && TYPE_PRECISION (TYPE) > 64))
+#define LIBCALL_VALUE(MODE) \
+ function_value (NULL, NULL, MODE)
/* 1 if N is a possible register number for a function value
as seen by the caller. */
@@ -1048,7 +1024,8 @@ extern int alpha_memory_latency;
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+ (CUM) = 0
/* Define intermediate macro to compute the size (in registers) of an argument
for the Alpha. */
@@ -1096,13 +1073,6 @@ extern int alpha_memory_latency;
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
((MODE) == TFmode || (MODE) == TCmode)
-/* Specify the padding direction of arguments.
-
- On the Alpha, we must pad upwards in order to be able to pass args in
- registers. */
-
-#define FUNCTION_ARG_PADDING(MODE, TYPE) upward
-
/* For an arg passed partly in registers and partly in memory,
this is the number of registers used.
For args passed entirely in registers or entirely in memory, zero. */
@@ -1111,68 +1081,6 @@ extern int alpha_memory_latency;
((CUM) < 6 && 6 < (CUM) + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
? 6 - (CUM) : 0)
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as above.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed.
-
- On the Alpha, we allocate space for all 12 arg registers, but only
- push those that are remaining.
-
- However, if NO registers need to be saved, don't allocate any space.
- This is not only because we won't need the space, but because AP includes
- the current_pretend_args_size and we don't want to mess up any
- ap-relative addresses already made.
-
- If we are not to use the floating-point registers, save the integer
- registers where we would put the floating-point registers. This is
- not the most efficient way to implement varargs with just one register
- class, but it isn't worth doing anything more efficient in this rare
- case. */
-
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-{ if ((CUM) < 6) \
- { \
- if (! (NO_RTL)) \
- { \
- rtx tmp; int set = get_varargs_alias_set (); \
- tmp = gen_rtx_MEM (BLKmode, \
- plus_constant (virtual_incoming_args_rtx, \
- ((CUM) + 6)* UNITS_PER_WORD)); \
- set_mem_alias_set (tmp, set); \
- move_block_from_reg \
- (16 + CUM, tmp, \
- 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \
- \
- tmp = gen_rtx_MEM (BLKmode, \
- plus_constant (virtual_incoming_args_rtx, \
- (CUM) * UNITS_PER_WORD)); \
- set_mem_alias_set (tmp, set); \
- move_block_from_reg \
- (16 + (TARGET_FPREGS ? 32 : 0) + CUM, tmp, \
- 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \
- } \
- PRETEND_SIZE = 12 * UNITS_PER_WORD; \
- } \
-}
-
-/* We do not allow indirect calls to be optimized into sibling calls, nor
- can we allow a call to a function in a different compilation unit to
- be optimized into a sibcall. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) \
- (DECL \
- && (! TREE_PUBLIC (DECL) \
- || (TREE_ASM_WRITTEN (DECL) && (*targetm.binds_local_p) (DECL))))
-
/* Try to output insns to set TARGET equal to the constant C if it can be
done in less than N insns. Do all computations in MODE. Returns the place
where the output has been placed if it can be done and the insns have been
@@ -1212,6 +1120,10 @@ extern struct alpha_compare alpha_compare;
#define PROFILE_BEFORE_PROLOGUE 1
+/* Never use profile counters. */
+
+#define NO_PROFILE_COUNTERS 1
+
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. Under OSF/1, profiling is enabled
by simply passing -pg to the assembler and linker. */
@@ -1287,12 +1199,6 @@ do { \
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
-/* #define HAVE_PRE_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT 0 */
-
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@@ -1417,14 +1323,6 @@ do { \
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
{ if (GET_CODE (ADDR) == AND) goto LABEL; }
-
-/* Compute the cost of an address. For the Alpha, all valid addresses are
- the same cost. */
-
-#define ADDRESS_COST(X) 0
-
-/* Machine-dependent reorg pass. */
-#define MACHINE_DEPENDENT_REORG(X) alpha_reorg(X)
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
@@ -1443,14 +1341,6 @@ do { \
/* Define this as 1 if `char' should by default be signed; else as 0. */
#define DEFAULT_SIGNED_CHAR 1
-/* This flag, if defined, says the same insns that convert to a signed fixnum
- also convert validly to an unsigned one.
-
- We actually lie a bit here as overflow conditions are different. But
- they aren't being checked anyway. */
-
-#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
-
/* Max number of bytes we can move to or from memory
in one reasonably fast instruction. */
@@ -1494,10 +1384,9 @@ do { \
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-/* We assume that the store-condition-codes instructions store 0 for false
- and some other value for true. This is the value stored for true. */
-
-#define STORE_FLAG_VALUE 1
+/* The CIX ctlz and cttz instructions return 64 for zero. */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, TARGET_CIX)
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, TARGET_CIX)
/* Define the value returned by a floating-point comparison instruction. */
@@ -1548,162 +1437,6 @@ do { \
/* Define this to be nonzero if shift instructions ignore all but the low-order
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- If this is an 8-bit constant, return zero since it can be used
- nearly anywhere with no cost. If it is a valid operand for an
- ADD or AND, likewise return 0 if we know it will be used in that
- context. Otherwise, return 2 since it might be used there later.
- All other constants take at least two insns. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) >= 0 && INTVAL (RTX) < 256) \
- return 0; \
- case CONST_DOUBLE: \
- if ((RTX) == CONST0_RTX (GET_MODE (RTX))) \
- return 0; \
- else if (((OUTER_CODE) == PLUS && add_operand (RTX, VOIDmode)) \
- || ((OUTER_CODE) == AND && and_operand (RTX, VOIDmode))) \
- return 0; \
- else if (add_operand (RTX, VOIDmode) || and_operand (RTX, VOIDmode)) \
- return 2; \
- else \
- return COSTS_N_INSNS (2); \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (3); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (2); \
- default: abort(); \
- }
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case PLUS: case MINUS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (4); \
- default: abort(); \
- } \
- else if (GET_CODE (XEXP (X, 0)) == MULT \
- && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \
- return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \
- + rtx_cost (XEXP (X, 1), OUTER_CODE)); \
- break; \
- case MULT: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (6); \
- return COSTS_N_INSNS (23); \
- case PROCESSOR_EV5: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (4); \
- else if (GET_MODE (X) == DImode) \
- return COSTS_N_INSNS (12); \
- else \
- return COSTS_N_INSNS (8); \
- case PROCESSOR_EV6: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (4); \
- else \
- return COSTS_N_INSNS (7); \
- default: abort(); \
- } \
- case ASHIFT: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && INTVAL (XEXP (X, 1)) <= 3) \
- break; \
- /* ... fall through ... */ \
- case ASHIFTRT: case LSHIFTRT: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (1); \
- default: abort(); \
- } \
- case IF_THEN_ELSE: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_EV5: \
- return COSTS_N_INSNS (1); \
- default: abort(); \
- } \
- case DIV: case UDIV: case MOD: case UMOD: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (34); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (63); \
- else \
- return COSTS_N_INSNS (70); \
- case PROCESSOR_EV5: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (15); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (22); \
- else \
- return COSTS_N_INSNS (70); /* ??? */ \
- case PROCESSOR_EV6: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (12); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (15); \
- else \
- return COSTS_N_INSNS (70); /* ??? */ \
- default: abort(); \
- } \
- case MEM: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (3); \
- case PROCESSOR_EV5: \
- return COSTS_N_INSNS (2); \
- default: abort(); \
- } \
- case NEG: case ABS: \
- if (! FLOAT_MODE_P (GET_MODE (X))) \
- break; \
- /* ... fall through ... */ \
- case FLOAT: case UNSIGNED_FLOAT: case FIX: case UNSIGNED_FIX: \
- case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (4); \
- default: abort(); \
- }
/* Control the assembler format that we output. */
@@ -1759,18 +1492,12 @@ do { \
#define USER_LABEL_PREFIX ""
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "$%s%d:\n", PREFIX, NUM)
-
/* This is how to output a label for a jump table. Arguments are the same as
- for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+ for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
-{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+{ ASM_OUTPUT_ALIGN (FILE, 2); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
@@ -1824,22 +1551,6 @@ do { \
} \
while (0)
-/* This is how to output an insn to push a register on the stack.
- It need not be very fast code. */
-
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
- fprintf (FILE, "\tsubq $30,8,$30\n\tst%s $%s%d,0($30)\n", \
- (REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \
- (REGNO) & 31);
-
-/* This is how to output an insn to pop a register from the stack.
- It need not be very fast code. */
-
-#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
- fprintf (FILE, "\tld%s $%s%d,0($30)\n\taddq $30,8,$30\n", \
- (REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \
- (REGNO) & 31);
-
/* This is how to output an element of a case-vector that is absolute.
(Alpha does not use such vectors, but we must define this macro anyway.) */
@@ -1862,7 +1573,7 @@ do { \
/* This is how to advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.space %d\n", (SIZE))
+ fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* This says how to output an assembler line
to define a global common symbol. */
@@ -1870,7 +1581,7 @@ do { \
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs ("\t.comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%d\n", (SIZE)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -1878,15 +1589,7 @@ do { \
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED) \
( fputs ("\t.lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%d\n", (SIZE)))
-
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)))
/* Print operand X (an rtx) in assembler syntax to file FILE.
@@ -1908,11 +1611,14 @@ do { \
- Generates double precision suffix for floating point
instructions (t for IEEE, g for VAX)
+
+ + Generates a nop instruction after a noreturn call at the very end
+ of the function
*/
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
- || (CODE) == '#' || (CODE) == '*' || (CODE) == '&')
+ || (CODE) == '#' || (CODE) == '*' || (CODE) == '&' || (CODE) == '+')
/* Print a memory address as an operand to reference that memory location. */
@@ -1943,8 +1649,9 @@ do { \
{"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \
{"alpha_fp_comparison_operator", {EQ, LE, LT, UNORDERED}}, \
{"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \
+ {"fix_operator", {FIX, UNSIGNED_FIX}}, \
{"const0_operand", {CONST_INT, CONST_DOUBLE, CONST_VECTOR}}, \
- {"current_file_function_operand", {SYMBOL_REF}}, \
+ {"samegp_function_operand", {SYMBOL_REF}}, \
{"direct_call_operand", {SYMBOL_REF}}, \
{"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"small_symbolic_operand", {SYMBOL_REF, CONST}}, \
@@ -1965,6 +1672,7 @@ do { \
{"unaligned_memory_operand", {MEM}}, \
{"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \
{"any_memory_operand", {MEM}}, \
+ {"normal_memory_operand", {MEM}}, \
{"hard_fp_register_operand", {SUBREG, REG}}, \
{"hard_int_register_operand", {SUBREG, REG}}, \
{"reg_not_elim_operand", {SUBREG, REG}}, \
@@ -1974,10 +1682,6 @@ do { \
{"some_small_symbolic_operand", {SET, PARALLEL, PREFETCH, UNSPEC, \
UNSPEC_VOLATILE}},
-/* Define the `__builtin_va_list' type for the ABI. */
-#define BUILD_VA_LIST_TYPE(VALIST) \
- (VALIST) = alpha_build_va_list ()
-
/* Implement `va_start' for varargs and stdarg. */
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
alpha_va_start (valist, nextarg)
@@ -2024,7 +1728,7 @@ extern long alpha_auto_offset;
#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + alpha_arg_offset)
-#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE, COUNTER) \
alpha_output_lineno (STREAM, LINE)
#define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \
diff --git a/contrib/gcc/config/alpha/alpha.md b/contrib/gcc/config/alpha/alpha.md
index f7e9fa4..998e300 100644
--- a/contrib/gcc/config/alpha/alpha.md
+++ b/contrib/gcc/config/alpha/alpha.md
@@ -1,22 +1,22 @@
;; Machine description for DEC Alpha for GNU C compiler
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;; 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -30,7 +30,7 @@
(UNSPEC_INSXH 2)
(UNSPEC_MSKXH 3)
(UNSPEC_CVTQL 4)
- (UNSPEC_NT_LDA 5)
+ (UNSPEC_CVTLQ 5)
(UNSPEC_UMK_LAUM 6)
(UNSPEC_UMK_LALM 7)
(UNSPEC_UMK_LAL 8)
@@ -97,8 +97,8 @@
;; separately.
(define_attr "type"
- "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
-fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
+ "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
+ icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_string "iadd"))
;; Describe a user's asm statement.
@@ -120,7 +120,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; The ROUND_SUFFIX attribute marks which instructions require a
;; rounding-mode suffix. The value NONE indicates no suffix,
-;; the value NORMAL indicates a suffix controled by alpha_fprm.
+;; the value NORMAL indicates a suffix controlled by alpha_fprm.
(define_attr "round_suffix" "none,normal,c"
(const_string "none"))
@@ -133,7 +133,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; V_SV_SVI accepts /v, /sv and /svi (cvttq only)
;; U_SU_SUI accepts /u, /su and /sui (most fp instructions)
;;
-;; The actual suffix emitted is controled by alpha_fptm.
+;; The actual suffix emitted is controlled by alpha_fptm.
(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
(const_string "none"))
@@ -154,6 +154,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
]
(const_string "no")))
+;; The CANNOT_COPY attribute marks instructions with relocations that
+;; cannot easily be duplicated. This includes insns with gpdisp relocs
+;; since they have to stay in 1-1 correspondence with one another. This
+;; also includes jsr insns, since they must stay in correspondence with
+;; the immediately following gpdisp instructions.
+
+(define_attr "cannot_copy" "false,true"
+ (const_string "false"))
;; Include scheduling descriptions.
@@ -177,41 +185,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
""
"")
-(define_insn "*extendsidi2_nofix"
- [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
- (sign_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
- "! TARGET_FIX"
- "@
- addl $31,%1,%0
- ldl %0,%1
- cvtlq %1,%0
- lds %0,%1\;cvtlq %0,%0"
- [(set_attr "type" "iadd,ild,fadd,fld")
- (set_attr "length" "*,*,*,8")])
+(define_insn "*cvtlq"
+ [(set (match_operand:DI 0 "register_operand" "=f")
+ (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
+ UNSPEC_CVTLQ))]
+ ""
+ "cvtlq %1,%0"
+ [(set_attr "type" "fadd")])
-(define_insn "*extendsidi2_fix"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f")
+(define_insn "*extendsidi2_1"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
(sign_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
- "TARGET_FIX"
+ (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
+ ""
"@
addl $31,%1,%0
ldl %0,%1
- ftois %1,%0
- cvtlq %1,%0
lds %0,%1\;cvtlq %0,%0"
- [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
- (set_attr "length" "*,*,*,*,8")])
+ [(set_attr "type" "iadd,ild,fld")
+ (set_attr "length" "*,*,8")])
-;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
(define_split
[(set (match_operand:DI 0 "hard_fp_register_operand" "")
(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
- "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
;; Optimize sign-extension of SImode loads. This shows up in the wake of
;; reload when converting fp->int.
@@ -227,28 +230,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(sign_extend:DI (match_dup 1)))]
"")
-(define_peephole2
- [(set (match_operand:SI 0 "hard_int_register_operand" "")
- (match_operand:SI 1 "hard_fp_register_operand" ""))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
- (sign_extend:DI (match_dup 0)))]
- "TARGET_FIX
- && (true_regnum (operands[0]) == true_regnum (operands[2])
- || peep2_reg_dead_p (2, operands[0]))"
- [(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
-
-(define_peephole2
- [(set (match_operand:DI 0 "hard_fp_register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
- (match_dup 0))]
- "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
- [(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
-
;; Don't say we have addsi3 if optimizing. This generates better code. We
;; have the anonymous addsi3 pattern below in case combine wants to make it.
(define_expand "addsi3"
@@ -413,7 +394,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
(high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
- "TARGET_EXPLICIT_RELOCS"
+ "TARGET_EXPLICIT_RELOCS && reload_completed"
"ldah %0,%2(%1)\t\t!gprelhigh"
[(set_attr "usegp" "yes")])
@@ -1337,7 +1318,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"eqv %r1,%2,%0"
[(set_attr "type" "ilog")])
-;; Handle the FFS insn iff we support CIX.
+;; Handle FFS and related insns iff we support CIX.
(define_expand "ffsdi2"
[(set (match_dup 2)
@@ -1361,6 +1342,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
; reuse the existing type name.
[(set_attr "type" "mvi")])
+
+(define_insn "clzdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (clz:DI (match_operand:DI 1 "register_operand" "r")))]
+ "TARGET_CIX"
+ "ctlz %1,%0"
+ [(set_attr "type" "mvi")])
+
+(define_insn "ctzdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ctz:DI (match_operand:DI 1 "register_operand" "r")))]
+ "TARGET_CIX"
+ "cttz %1,%0"
+ [(set_attr "type" "mvi")])
+
+(define_insn "popcountdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
+ "TARGET_CIX"
+ "ctpop %1,%0"
+ [(set_attr "type" "mvi")])
;; Next come the shifts and the various extract and insert operations.
@@ -2305,8 +2307,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; processing, it is cheaper to do the truncation in the int regs.
(define_insn "*cvtql"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (unspec:SI [(match_operand:DI 1 "reg_or_0_operand" "fG")]
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
UNSPEC_CVTQL))]
"TARGET_FP"
"cvtql%/ %R1,%0"
@@ -2316,37 +2318,46 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(define_insn_and_split "*fix_truncdfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
+ (subreg:SI
+ (match_operator:DI 4 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
(clobber (match_scratch:DI 2 "=&f"))
- (clobber (match_scratch:SI 3 "=&f"))]
+ (clobber (match_scratch:SF 3 "=&f"))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ""
+ [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
+ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 3))]
+{
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn_and_split "*fix_truncdfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
+ (subreg:SI
+ (match_operator:DI 3 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+ [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
+ (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 4))]
+{
+ operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn "*fix_truncdfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+ (match_operator:DI 2 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2354,9 +2365,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
-(define_insn "fix_truncdfdi2"
+(define_insn "*fix_truncdfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+ (match_operator:DI 2 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
"TARGET_FP"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2364,44 +2376,64 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
+(define_expand "fix_truncdfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+ "TARGET_FP"
+ "")
+
+(define_expand "fixuns_truncdfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+ "TARGET_FP"
+ "")
+
;; Likewise between SFmode and SImode.
(define_insn_and_split "*fix_truncsfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
+ (subreg:SI
+ (match_operator:DI 4 "fix_operator"
+ [(float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
(clobber (match_scratch:DI 2 "=&f"))
- (clobber (match_scratch:SI 3 "=&f"))]
+ (clobber (match_scratch:SF 3 "=&f"))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ""
+ [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
+ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 3))]
+{
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn_and_split "*fix_truncsfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
+ (subreg:SI
+ (match_operator:DI 3 "fix_operator"
+ [(float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+ [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
+ (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 4))]
+{
+ operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn "*fix_truncsfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
- (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
+ (match_operator:DI 2 "fix_operator"
+ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2409,10 +2441,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
-(define_insn "fix_truncsfdi2"
+(define_insn "*fix_truncsfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
- (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
+ (match_operator:DI 2 "fix_operator"
+ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
"TARGET_FP"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2420,12 +2452,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
+(define_expand "fix_truncsfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+ "TARGET_FP"
+ "")
+
+(define_expand "fixuns_truncsfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (unsigned_fix:DI
+ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+ "TARGET_FP"
+ "")
+
(define_expand "fix_trunctfdi2"
[(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:TF 1 "general_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FIX, operands); DONE;")
+(define_expand "fixuns_trunctfdi2"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
+
(define_insn "*floatdisf_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
@@ -2446,6 +2497,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "sui")])
+(define_insn_and_split "*floatsisf2_ieee"
+ [(set (match_operand:SF 0 "register_operand" "=&f")
+ (float:SF (match_operand:SI 1 "memory_operand" "m")))
+ (clobber (match_scratch:DI 2 "=&f"))
+ (clobber (match_scratch:SF 3 "=&f"))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsisf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_FP"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+})
+
(define_insn "*floatdidf_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
@@ -2466,6 +2546,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "sui")])
+(define_insn_and_split "*floatsidf2_ieee"
+ [(set (match_operand:DF 0 "register_operand" "=&f")
+ (float:DF (match_operand:SI 1 "memory_operand" "m")))
+ (clobber (match_scratch:DI 2 "=&f"))
+ (clobber (match_scratch:SF 3 "=&f"))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsidf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_FP"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
+
(define_expand "floatditf2"
[(use (match_operand:TF 0 "register_operand" ""))
(use (match_operand:DI 1 "general_operand" ""))]
@@ -4594,7 +4704,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
- bsr $26,$%0..ng
+ bsr $26,%0\t\t!samegp
ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
[(set_attr "type" "jsr")
(set_attr "length" "12,*,16")])
@@ -4607,8 +4717,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[0], Pmode)
- && peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[0], Pmode)
+ && (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(call (mem:DI (match_dup 2))
(match_dup 1))
(set (reg:DI 26) (plus:DI (pc) (const_int 4)))
@@ -4637,8 +4748,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[0], Pmode)
- && ! peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[0], Pmode)
+ && ! (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(call (mem:DI (match_dup 2))
(match_dup 1))
(set (reg:DI 26) (plus:DI (pc) (const_int 4)))
@@ -4678,7 +4790,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (match_operand 3 "const_int_operand" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
+
+;; We output a nop after noreturn calls at the very end of the function to
+;; ensure that the return address always remains in the caller's code range,
+;; as not doing so might confuse unwinding engines.
+;;
+;; The potential change in insn length is not reflected in the length
+;; attributes at this stage. Since the extra space is only actually added at
+;; the very end of the compilation process (via final/print_operand), it
+;; really seems harmless and not worth the trouble of some extra computation
+;; cost and complexity.
(define_insn "*call_osf_1_noreturn"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
@@ -4688,9 +4811,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
"@
- jsr $26,($27),0
- bsr $26,$%0..ng
- jsr $26,%0"
+ jsr $26,($27),0%+
+ bsr $26,$%0..ng%+
+ jsr $26,%0%+"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,8")])
@@ -4715,7 +4838,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
- br $31,$%0..ng
+ br $31,%0\t\t!samegp
ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
[(set_attr "type" "jsr")
(set_attr "length" "*,8")])
@@ -4754,20 +4877,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 26))
(clobber (reg:DI 27))]
"TARGET_ABI_OPEN_VMS"
- "*
{
switch (which_alternative)
{
case 0:
- return \"mov %2,$27\;jsr $26,0\;ldq $27,0($29)\";
+ return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
case 1:
operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0);
operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 0);
- return \"ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)\";
+ return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
default:
abort();
}
-}"
+}
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
@@ -5086,27 +5208,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
operands[1] = force_reg (TFmode, operands[1]);
})
-(define_insn "*movsi_nofix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
- "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%r1,%0
- lda %0,%1($31)
- ldah %0,%h1($31)
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
-
-(define_insn "*movsi_fix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
- "TARGET_ABI_OSF && TARGET_FIX
+(define_insn "*movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ"))]
+ "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
@@ -5114,38 +5219,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
lda %0,%1($31)
ldah %0,%h1($31)
ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0
- ftois %1,%0
- itofs %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movsi_nt_vms_nofix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
- "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
- && !TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%1,%0
- lda %0,%1
- ldah %0,%h1
- lda %0,%1
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
+ stl %r1,%0"
+ [(set_attr "type" "ilog,iadd,iadd,ild,ist")])
-(define_insn "*movsi_nt_vms_fix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
- (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
+(define_insn "*movsi_nt_vms"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ"))]
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
- && TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
@@ -5154,13 +5234,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
ldah %0,%h1
lda %0,%1
ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0
- ftois %1,%0
- itofs %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+ stl %r1,%0"
+ [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist")])
(define_insn "*movhi_nobwx"
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -5243,7 +5318,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; Split the load of an address into a four-insn sequence on Unicos/Mk.
;; Always generate a REG_EQUAL note for the last instruction to facilitate
-;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL
+;; optimizations. If the symbolic operand is a label_ref, generate REG_LABEL
;; notes and update LABEL_NUSES because this is not done automatically.
;; Labels may be incorrectly deleted if we don't do this.
;;
@@ -5399,7 +5474,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
UNSPEC_SYMBOL))]
- "TARGET_EXPLICIT_RELOCS"
+ "TARGET_EXPLICIT_RELOCS && flag_inline_functions"
"#"
""
[(set (match_dup 0) (match_dup 1))]
@@ -5635,7 +5710,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(define_expand "aligned_loadqi"
[(set (match_operand:SI 3 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 8)
(match_operand:DI 2 "const_int_operand" "")))]
@@ -5646,7 +5721,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(define_expand "aligned_loadhi"
[(set (match_operand:SI 3 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 16)
(match_operand:DI 2 "const_int_operand" "")))]
@@ -5662,7 +5737,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; operand 3 can overlap the input and output registers.
(define_expand "unaligned_loadqi"
- [(use (match_operand:QI 0 "register_operand" ""))
+ [(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))]
@@ -5683,7 +5758,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 8)
(ashift:DI (match_dup 3) (const_int 3))))]
@@ -5696,7 +5771,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 8)
(minus:DI
@@ -5706,7 +5781,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"")
(define_expand "unaligned_loadhi"
- [(use (match_operand:QI 0 "register_operand" ""))
+ [(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))]
@@ -5727,7 +5802,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 16)
(ashift:DI (match_dup 3) (const_int 3))))]
@@ -5740,7 +5815,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(plus:DI (match_dup 1) (const_int 1)))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 16)
(minus:DI
@@ -5935,9 +6010,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
{
rtx scratch, seq;
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[1], QImode))
{
seq = gen_reload_inqi_help (operands[0], operands[1],
@@ -5956,8 +6028,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
addr = get_unaligned_address (operands[1], 0);
- seq = gen_unaligned_loadqi (operands[0], addr, scratch,
- gen_rtx_REG (DImode, REGNO (operands[0])));
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ seq = gen_unaligned_loadqi (operands[0], addr, scratch, operands[0]);
alpha_set_memflags (seq, operands[1]);
}
emit_insn (seq);
@@ -5972,9 +6044,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
{
rtx scratch, seq;
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[1], HImode))
{
seq = gen_reload_inhi_help (operands[0], operands[1],
@@ -5993,8 +6062,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
addr = get_unaligned_address (operands[1], 0);
- seq = gen_unaligned_loadhi (operands[0], addr, scratch,
- gen_rtx_REG (DImode, REGNO (operands[0])));
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ seq = gen_unaligned_loadhi (operands[0], addr, scratch, operands[0]);
alpha_set_memflags (seq, operands[1]);
}
emit_insn (seq);
@@ -6007,9 +6076,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[0], QImode))
{
emit_insn (gen_reload_outqi_help
@@ -6042,9 +6108,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[0], HImode))
{
emit_insn (gen_reload_outhi_help
@@ -6075,71 +6138,47 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; always get a proper address for a stack slot during reload_foo
;; expansion, so we must delay our address manipulations until after.
-(define_insn "reload_inqi_help"
+(define_insn_and_split "reload_inqi_help"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 1 "memory_operand" "m"))
(clobber (match_operand:SI 2 "register_operand" "=r"))]
"! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_inhi_help"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (match_operand:HI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_outqi_help"
- [(set (match_operand:QI 0 "memory_operand" "=m")
- (match_operand:QI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_outhi_help"
- [(set (match_operand:HI 0 "memory_operand" "=m")
- (match_operand:HI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_split
- [(set (match_operand:QI 0 "register_operand" "")
- (match_operand:QI 1 "memory_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))]
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
+ operands[0] = gen_lowpart (DImode, operands[0]);
emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
operands[2]));
DONE;
})
-(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (match_operand:HI 1 "memory_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))]
+(define_insn_and_split "reload_inhi_help"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (match_operand:HI 1 "memory_operand" "m"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))]
+ "! TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
+ operands[0] = gen_lowpart (DImode, operands[0]);
emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
operands[2]));
DONE;
})
-(define_split
- [(set (match_operand:QI 0 "memory_operand" "")
- (match_operand:QI 1 "register_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+(define_insn_and_split "reload_outqi_help"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (match_operand:QI 1 "register_operand" "r"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "! TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
@@ -6150,11 +6189,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
DONE;
})
-(define_split
- [(set (match_operand:HI 0 "memory_operand" "")
- (match_operand:HI 1 "register_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+(define_insn_and_split "reload_outhi_help"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (match_operand:HI 1 "register_operand" "r"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "! TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
@@ -6494,6 +6535,56 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
FAIL;
})
+(define_expand "movstrdi"
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_operand:DI 3 "immediate_operand" ""))
+ (use (match_dup 4))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 18))
+ (clobber (reg:DI 19))
+ (clobber (reg:DI 20))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))])]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE");
+ alpha_need_linkage (XSTR (operands[4], 0), 0);
+})
+
+(define_insn "*movstrdi_1"
+ [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+ (match_operand:BLK 1 "memory_operand" "m,m"))
+ (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
+ (use (match_operand:DI 3 "immediate_operand" ""))
+ (use (match_operand:DI 4 "call_operand" "i,i"))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 18))
+ (clobber (reg:DI 19))
+ (clobber (reg:DI 20))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1);
+ switch (which_alternative)
+ {
+ case 0:
+ return "lda $16,%0\;bis $31,%2,$17\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
+ case 1:
+ return "lda $16,%0\;lda $17,%2($31)\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
+ default:
+ abort();
+ }
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "28")])
+
(define_expand "clrstrqi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
@@ -6506,6 +6597,51 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
else
FAIL;
})
+
+(define_expand "clrstrdi"
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (const_int 0))
+ (use (match_operand:DI 1 "immediate_operand" ""))
+ (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_dup 3))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))])]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands[3] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
+ alpha_need_linkage (XSTR (operands[3], 0), 0);
+})
+
+(define_insn "*clrstrdi_1"
+ [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+ (const_int 0))
+ (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
+ (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_operand:DI 3 "call_operand" "i,i"))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1);
+ switch (which_alternative)
+ {
+ case 0:
+ return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
+ case 1:
+ return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
+ default:
+ abort();
+ }
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "24")])
+
;; Subroutine of stack space allocation. Perform a stack probe.
(define_expand "probe_stack"
@@ -6605,7 +6741,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
""
{
operands[2] = gen_label_rtx ();
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+ (*targetm.asm_out.internal_label) (asm_out_file, "L",
CODE_LABEL_NUMBER (operands[2]));
return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
@@ -6648,7 +6784,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "ldah %0,0(%1)\t\t!gpdisp!%2")
+ "ldah %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6656,7 +6793,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2")
+ "lda %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6664,7 +6802,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+ "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6672,7 +6811,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
""
- "ldgp %0,0(%1)\n$%~..ng:")
+ "ldgp %0,0(%1)\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6722,17 +6862,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
DONE;
})
-;; In creating a large stack frame, NT _must_ use ldah+lda to load
-;; the frame size into a register. We use this pattern to ensure
-;; we get lda instead of addq.
-(define_insn "nt_lda"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_dup 0)
- (match_operand:DI 1 "const_int_operand" "n")]
- UNSPEC_NT_LDA))]
- ""
- "lda %0,%1(%0)")
-
(define_expand "builtin_longjmp"
[(use (match_operand:DI 0 "register_operand" "r"))]
"TARGET_ABI_OSF"
@@ -6786,7 +6915,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(const_int 0)]
"
{
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
DONE;
}")
@@ -7046,7 +7175,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7061,7 +7190,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7076,7 +7205,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7091,7 +7220,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7106,7 +7235,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extwh_be;
else
@@ -7121,7 +7250,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extlh_be;
else
@@ -7136,7 +7265,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extqh_be;
else
@@ -7151,7 +7280,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_insbl_be;
else
@@ -7167,7 +7296,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_inswl_be;
else
@@ -7183,7 +7312,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_insll_be;
else
@@ -7200,7 +7329,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_insql_be;
else
@@ -7245,7 +7374,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7262,7 +7391,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7279,7 +7408,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7296,7 +7425,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7719,7 +7848,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
- bsr $26,$%1..ng
+ bsr $26,%1\t\t!samegp
ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
[(set_attr "type" "jsr")
(set_attr "length" "12,*,16")])
@@ -7733,8 +7862,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[1], Pmode)
- && peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[1], Pmode)
+ && (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(match_dup 2)))
@@ -7765,8 +7895,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[1], Pmode)
- && ! peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[1], Pmode)
+ && ! (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(match_dup 2)))
@@ -7808,7 +7939,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (match_operand 4 "" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
(define_insn "*call_value_osf_1_noreturn"
[(set (match_operand 0 "" "")
@@ -7819,9 +7951,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
"@
- jsr $26,($27),0
- bsr $26,$%1..ng
- jsr $26,%1"
+ jsr $26,($27),0%+
+ bsr $26,$%1..ng%+
+ jsr $26,%1%+"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,8")])
@@ -7910,7 +8042,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
- br $31,$%1..ng
+ br $31,%1\t\t!samegp
ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
[(set_attr "type" "jsr")
(set_attr "length" "*,8")])
@@ -7952,20 +8084,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 26))
(clobber (reg:DI 27))]
"TARGET_ABI_OPEN_VMS"
- "*
{
switch (which_alternative)
{
case 0:
- return \"mov %3,$27\;jsr $26,0\;ldq $27,0($29)\";
+ return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
case 1:
operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0);
operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 0);
- return \"ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)\";
+ return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
default:
abort();
}
-}"
+}
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
diff --git a/contrib/gcc/config/alpha/ev4.md b/contrib/gcc/config/alpha/ev4.md
index 41e1efd..cee3ae6 100644
--- a/contrib/gcc/config/alpha/ev4.md
+++ b/contrib/gcc/config/alpha/ev4.md
@@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV4.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/alpha/ev5.md b/contrib/gcc/config/alpha/ev5.md
index 832cf6b..20757e1 100644
--- a/contrib/gcc/config/alpha/ev5.md
+++ b/contrib/gcc/config/alpha/ev5.md
@@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV5.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/alpha/ev6.md b/contrib/gcc/config/alpha/ev6.md
index 12204b6..23a09b0 100644
--- a/contrib/gcc/config/alpha/ev6.md
+++ b/contrib/gcc/config/alpha/ev6.md
@@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV6.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/alpha/gnu.h b/contrib/gcc/config/alpha/gnu.h
index 9b25daf..40348c6 100644
--- a/contrib/gcc/config/alpha/gnu.h
+++ b/contrib/gcc/config/alpha/gnu.h
@@ -6,12 +6,8 @@
#undef TARGET_OS_CPP_BUILTINS /* config.gcc includes alpha/linux.h. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
- builtin_define ("__GNU__"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__gnu_hurd__"); \
+ HURD_TARGET_OS_CPP_BUILTINS(); \
builtin_define ("_LONGLONG"); \
- builtin_define_std ("unix"); \
- builtin_assert ("system=gnu"); \
} while (0)
#undef ELF_DYNAMIC_LINKER
diff --git a/contrib/gcc/config/alpha/lib1funcs.asm b/contrib/gcc/config/alpha/lib1funcs.asm
index 6bea231..a2abb1f 100644
--- a/contrib/gcc/config/alpha/lib1funcs.asm
+++ b/contrib/gcc/config/alpha/lib1funcs.asm
@@ -307,7 +307,7 @@ $46:
conventions. */
#if TYPE == UNSIGNED && SIZE == 32
/* This could be avoided by adding some CPP hair to the divide loop.
- It is probably not worth the added complexity. */
+ It is probably not worth the added complexity. */
addl RETREG,0,RETREG
#endif
diff --git a/contrib/gcc/config/alpha/linux-elf.h b/contrib/gcc/config/alpha/linux-elf.h
index 49f5181..025b9a2 100644
--- a/contrib/gcc/config/alpha/linux-elf.h
+++ b/contrib/gcc/config/alpha/linux-elf.h
@@ -3,20 +3,20 @@
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Richard Henderson.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,11 +27,7 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_EXTRA_SPECS \
{ "elf_dynamic_linker", ELF_DYNAMIC_LINKER },
-#ifdef USE_GNULIBC_1
-#define ELF_DYNAMIC_LINKER "/lib/ld.so.1"
-#else
#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-#endif
#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \
%{O*:-O3} %{!O*:-O1} \
@@ -42,8 +38,8 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker %(elf_dynamic_linker)}} \
%{static:-static}}"
-#ifndef USE_GNULIBC_1
#undef LIB_SPEC
#define LIB_SPEC \
-"%{pthread:-lpthread }%{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
-#endif
+"%{pthread:-lpthread} %{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
+
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
diff --git a/contrib/gcc/config/alpha/linux.h b/contrib/gcc/config/alpha/linux.h
index 3a2940c..a4bc3d3 100644
--- a/contrib/gcc/config/alpha/linux.h
+++ b/contrib/gcc/config/alpha/linux.h
@@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler,
for Alpha Linux-based GNU systems.
- Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Henderson.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -30,8 +30,10 @@ Boston, MA 02111-1307, USA. */
builtin_define_std ("linux"); \
builtin_define_std ("unix"); \
builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
/* The GNU C++ standard library requires this. */ \
- if (c_language == clk_cplusplus) \
+ if (c_dialect_cxx ()) \
builtin_define ("_GNU_SOURCE"); \
} while (0)
@@ -59,6 +61,10 @@ Boston, MA 02111-1307, USA. */
/* Define this so that all GNU/Linux targets handle the same pragmas. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
+/* Determine whether the the entire c99 runtime is present in the
+ runtime library. */
+#define TARGET_C99_FUNCTIONS 1
+
#define TARGET_HAS_F_SETLKW
#define LINK_GCC_C_SEQUENCE_SPEC \
diff --git a/contrib/gcc/config/alpha/netbsd.h b/contrib/gcc/config/alpha/netbsd.h
index e1da9cf..d4f833a 100644
--- a/contrib/gcc/config/alpha/netbsd.h
+++ b/contrib/gcc/config/alpha/netbsd.h
@@ -1,21 +1,21 @@
/* Definitions of target machine for GNU compiler,
for Alpha NetBSD systems.
- Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,7 +25,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
NETBSD_OS_CPP_BUILTINS_ELF(); \
- NETBSD_OS_CPP_BUILTINS_LP64(); \
} while (0)
@@ -77,7 +76,7 @@ Boston, MA 02111-1307, USA. */
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#undef TARGET_VERSION
diff --git a/contrib/gcc/config/alpha/openbsd.h b/contrib/gcc/config/alpha/openbsd.h
index b82b66d..b9df2e4 100644
--- a/contrib/gcc/config/alpha/openbsd.h
+++ b/contrib/gcc/config/alpha/openbsd.h
@@ -1,36 +1,26 @@
/* Configuration file for an alpha OpenBSD target.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* We settle for little endian for now. */
#define TARGET_ENDIAN_DEFAULT 0
-#define OBSD_NO_DYNAMIC_LIBRARIES
-#define OBSD_HAS_DECLARE_FUNCTION_NAME
-#define OBSD_HAS_DECLARE_FUNCTION_SIZE
-#define OBSD_HAS_DECLARE_OBJECT
-
-/* alpha ecoff supports only weak aliases, see below. */
-#define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS (FILE,NAME,0)
-
-#include <openbsd.h>
-
/* Controlling the compilation driver. */
/* alpha needs __start. */
@@ -82,38 +72,18 @@ Boston, MA 02111-1307, USA. */
/* Assembler format: exception region output. */
/* All configurations that don't use elf must be explicit about not using
- dwarf unwind information. egcs doesn't try too hard to check internal
- configuration files... */
+ dwarf unwind information. */
#ifdef INCOMING_RETURN_ADDR_RTX
#undef DWARF2_UNWIND_INFO
#define DWARF2_UNWIND_INFO 0
#endif
-/* Assembler format: file framework. */
-
-/* Taken from alpha/osf.h. This used to be common to all alpha
- configurations, but elf has departed from it.
- Check alpha/alpha.h, alpha/osf.h for it when egcs is upgraded. */
-#ifndef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-{ \
- alpha_write_verstamp (FILE); \
- fprintf (FILE, "\t.set noreorder\n"); \
- fprintf (FILE, "\t.set volatile\n"); \
- fprintf (FILE, "\t.set noat\n"); \
- if (TARGET_SUPPORT_ARCH) \
- fprintf (FILE, "\t.arch %s\n", \
- TARGET_CPU_EV6 ? "ev6" \
- : (TARGET_CPU_EV5 \
- ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
- : "ev4")); \
- \
- ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
-}
-#endif
-
/* Assembler format: label output. */
+/* alpha ecoff supports only weak aliases. */
+#undef ASM_WEAKEN_LABEL
+#define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS (FILE,NAME,0)
+
#define ASM_OUTPUT_WEAK_ALIAS(FILE,NAME,VALUE) \
do { \
fputs ("\t.weakext\t", FILE); \
diff --git a/contrib/gcc/config/alpha/osf.h b/contrib/gcc/config/alpha/osf.h
index 2be2a42..1ae6db3 100644
--- a/contrib/gcc/config/alpha/osf.h
+++ b/contrib/gcc/config/alpha/osf.h
@@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on OSF/1.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -49,6 +49,13 @@ Boston, MA 02111-1307, USA. */
to be defined for <math.h>. */ \
if (LONG_DOUBLE_TYPE_SIZE == 128) \
builtin_define ("__X_FLOAT"); \
+ \
+ /* Tru64 UNIX V4/V5 provide several ISO C94 \
+ features protected by the corresponding \
+ __STDC_VERSION__ macro. libstdc++ v3 \
+ needs them as well. */ \
+ if (c_dialect_cxx ()) \
+ builtin_define ("__STDC_VERSION__=199409L"); \
} while (0)
/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4
@@ -84,22 +91,6 @@ Boston, MA 02111-1307, USA. */
#define MD_STARTFILE_PREFIX "/usr/lib/cmplrs/cc/"
-#define ASM_FILE_START(FILE) \
-{ \
- alpha_write_verstamp (FILE); \
- fprintf (FILE, "\t.set noreorder\n"); \
- fprintf (FILE, "\t.set volatile\n"); \
- fprintf (FILE, "\t.set noat\n"); \
- if (TARGET_SUPPORT_ARCH) \
- fprintf (FILE, "\t.arch %s\n", \
- TARGET_CPU_EV6 ? "ev6" \
- : (TARGET_CPU_EV5 \
- ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
- : "ev4")); \
- \
- ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
-}
-
/* Tru64 UNIX V5.1 requires a special as flag. Empty by default. */
#define ASM_OLDAS_SPEC ""
@@ -154,14 +145,11 @@ Boston, MA 02111-1307, USA. */
/* Attempt to turn on access permissions for the stack. */
-#define TRANSFER_FROM_TRAMPOLINE \
-extern void __enable_execute_stack PARAMS ((void *)); \
- \
+#define ENABLE_EXECUTE_STACK \
void \
-__enable_execute_stack (addr) \
- void *addr; \
+__enable_execute_stack (void *addr) \
{ \
- extern int mprotect PARAMS ((const void *, size_t, int)); \
+ extern int mprotect (const void *, size_t, int); \
long size = getpagesize (); \
long mask = ~(size-1); \
char *page = (char *) (((long) addr) & mask); \
@@ -181,6 +169,10 @@ __enable_execute_stack (addr) \
#define LD_INIT_SWITCH "-init"
#define LD_FINI_SWITCH "-fini"
+/* The linker needs a space after "-o". This allows -oldstyle_liblookup to
+ be passed to ld. */
+#define SWITCHES_NEED_SPACES "o"
+
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations.
diff --git a/contrib/gcc/config/alpha/osf5.h b/contrib/gcc/config/alpha/osf5.h
index e483124..e96ae7e 100644
--- a/contrib/gcc/config/alpha/osf5.h
+++ b/contrib/gcc/config/alpha/osf5.h
@@ -1,29 +1,26 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on Tru64 5.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Tru64 5.1 uses IEEE QUAD format. */
-/* ??? However, since there is no support for VAX H_floating, we must
- drop back to a 64-bit long double to avoid a crash looking for the
- format associated with TFmode. */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_FLOAT_VAX ? 64 : 128)
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT MASK_FP | MASK_FPREGS | MASK_LONG_DOUBLE_128
/* In Tru64 UNIX V5.1, Compaq introduced a new assembler
(/usr/lib/cmplrs/cc/adu) which currently (versions between 3.04.29 and
@@ -49,3 +46,8 @@
linked. */
#undef TARGET_LD_BUGGY_LDGP
#define TARGET_LD_BUGGY_LDGP 1
+
+/* Tru64 v5.1 has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
diff --git a/contrib/gcc/config/alpha/t-osf-pthread b/contrib/gcc/config/alpha/t-osf-pthread
new file mode 100644
index 0000000..968e65c
--- /dev/null
+++ b/contrib/gcc/config/alpha/t-osf-pthread
@@ -0,0 +1,5 @@
+# Provide dummy POSIX threads functions
+LIB2FUNCS_EXTRA += $(srcdir)/gthr-posix.c
+
+# Compile libgcc2 with POSIX threads supports
+TARGET_LIBGCC2_CFLAGS=-pthread
diff --git a/contrib/gcc/config/alpha/t-osf4 b/contrib/gcc/config/alpha/t-osf4
index 0525d61..fe747a3 100644
--- a/contrib/gcc/config/alpha/t-osf4
+++ b/contrib/gcc/config/alpha/t-osf4
@@ -10,7 +10,11 @@ SHLIB_NAME = @shlib_base_name@.so
SHLIB_SONAME = @shlib_base_name@.so.1
SHLIB_OBJS = @shlib_objs@
+# Hide all POSIX threads related symbols provided by gthr-posix.c. This
+# only has an effect if t-osf-pthread is in use.
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
+ -Wl,-hidden_symbol,pthread\* -Wl,-hidden_symbol,__pthread\* \
+ -Wl,-hidden_symbol,sched_get_\* -Wl,-hidden_symbol,sched_yield \
-Wl,-msym -Wl,-set_version,gcc.1 -Wl,-soname,$(SHLIB_SONAME) \
-o $(SHLIB_NAME) @multilib_flags@ $(SHLIB_OBJS) -lc && \
rm -f $(SHLIB_SONAME) && \
diff --git a/contrib/gcc/config/alpha/unicosmk.h b/contrib/gcc/config/alpha/unicosmk.h
index 8f7b53d..9d966d6 100644
--- a/contrib/gcc/config/alpha/unicosmk.h
+++ b/contrib/gcc/config/alpha/unicosmk.h
@@ -4,20 +4,20 @@
Free Software Foundation, Inc.
Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -102,8 +102,6 @@ Boston, MA 02111-1307, USA. */
other its replacement, at the start of a routine. This is somewhat
complicated on the T3E which is why we use a function. */
-extern int unicosmk_initial_elimination_offset PARAMS ((int, int));
-
#undef INITIAL_ELIMINATION_OFFSET
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
do { \
@@ -178,7 +176,7 @@ typedef struct {
function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
#undef INIT_CUMULATIVE_ARGS
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
do { (CUM).num_args = 0; \
(CUM).num_arg_words = 0; \
(CUM).num_reg_words = 0; \
@@ -220,41 +218,11 @@ do { \
++(CUM).num_args; \
} while(0)
-/* We want the default definition for this.
- ??? In fact, we should delete the definition from alpha.h as it
- corresponds to the default definition for little-endian machines. */
-
-#undef FUNCTION_ARG_PADDING
-
/* An argument is passed either entirely in registers or entirely on stack. */
#undef FUNCTION_ARG_PARTIAL_NREGS
/* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
- arguments on the stack. Unfortunately, it doesn't always store the first
- one (i.e. the one that arrives in $16 or $f16). This is not a problem
- with stdargs as we always have at least one named argument there. */
-
-#undef SETUP_INCOMING_VARARGS
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-{ if ((CUM).num_reg_words < 6) \
- { \
- if (! (NO_RTL)) \
- { \
- int start = (CUM).num_reg_words + 1; \
- \
- emit_insn (gen_umk_mismatch_args (GEN_INT (start))); \
- emit_insn (gen_arg_home_umk ()); \
- } \
- \
- PRETEND_SIZE = 0; \
- } \
-}
-
/* This ensures that $15 increments/decrements in leaf functions won't get
eliminated. */
@@ -319,43 +287,33 @@ do { fprintf (FILE, "\tbr $1,0\n"); \
COMMON_SECTION \
SSIB_SECTION
-extern void common_section PARAMS ((void));
+extern void common_section (void);
#define COMMON_SECTION \
void \
-common_section () \
+common_section (void) \
{ \
in_section = in_common; \
}
-extern void ssib_section PARAMS ((void));
+extern void ssib_section (void);
#define SSIB_SECTION \
void \
-ssib_section () \
+ssib_section (void) \
{ \
in_section = in_ssib; \
}
-/* This outputs text to go at the start of an assembler file. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) unicosmk_asm_file_start (FILE)
-
-/* This outputs text to go at the end of an assembler file. */
-
-#undef ASM_FILE_END
-#define ASM_FILE_END(FILE) unicosmk_asm_file_end (FILE)
-
-/* We take care of that in ASM_FILE_START. */
+/* We take care of this in unicosmk_file_start. */
#undef ASM_OUTPUT_SOURCE_FILENAME
/* This is how to output a label for a jump table. Arguments are the same as
- for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+ for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
/* CAM has some restrictions with respect to string literals. It won't
accept lines with more that 256 characters which means that we have
@@ -453,7 +411,8 @@ ssib_section () \
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM,SIZE) \
- fprintf ((STREAM), "\t.byte\t0:%d\n", (SIZE));
+ fprintf ((STREAM), "\t.byte\t0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
+ (SIZE));
/* This says how to output an assembler line to define a global common
symbol. We need the alignment information because it has to be supplied
@@ -470,7 +429,7 @@ ssib_section () \
do { data_section (); \
fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf (FILE, "\t.byte 0:%d\n", SIZE); \
+ fprintf (FILE, "\t.byte 0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",(SIZE));\
} while (0)
/* CAM does not allow us to declare a symbol as external first and then
@@ -521,28 +480,9 @@ ssib_section () \
#undef SDB_DEBUGGING_INFO
#undef MIPS_DEBUGGING_INFO
#undef DBX_DEBUGGING_INFO
-#undef DWARF_DEBUGGING_INFO
#undef DWARF2_DEBUGGING_INFO
#undef DWARF2_UNWIND_INFO
#undef INCOMING_RETURN_ADDR_RTX
-
-
-/* We use the functions provided by the system library for integer
- division. */
-
-#undef UDIVDI3_LIBCALL
-#undef DIVDI3_LIBCALL
-#define UDIVDI3_LIBCALL "$uldiv"
-#define DIVDI3_LIBCALL "$sldiv"
-
-/* This is necessary to prevent gcc from generating calls to __divsi3. */
-
-#define INIT_TARGET_OPTABS \
- do { \
- sdiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
- udiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
- } while (0)
-
#undef ASM_OUTPUT_SOURCE_LINE
/* We don't need a start file. */
@@ -555,7 +495,6 @@ ssib_section () \
#undef LIB_SPEC
#define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
-#undef BUILD_VA_LIST_TYPE
#undef EXPAND_BUILTIN_VA_START
#undef EXPAND_BUILTIN_VA_ARG
diff --git a/contrib/gcc/config/alpha/vms-cc.c b/contrib/gcc/config/alpha/vms-cc.c
index 26c3ae3..672a30f 100644
--- a/contrib/gcc/config/alpha/vms-cc.c
+++ b/contrib/gcc/config/alpha/vms-cc.c
@@ -1,21 +1,21 @@
/* VMS DEC C wrapper.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,6 +25,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#undef PATH_SEPARATOR
#undef PATH_SEPARATOR_STR
@@ -32,50 +34,47 @@ Boston, MA 02111-1307, USA. */
#define PATH_SEPARATOR_STR ","
/* These can be set by command line arguments */
-int verbose = 0;
-int save_temps = 0;
+static int verbose = 0;
+static int save_temps = 0;
-int comp_arg_max = -1;
-const char **comp_args = 0;
-int comp_arg_index = -1;
-char *objfilename = 0;
+static int comp_arg_max = -1;
+static const char **comp_args = 0;
+static int comp_arg_index = -1;
+static char *objfilename = 0;
-char *system_search_dirs = (char *) "";
-char *search_dirs;
+static char *system_search_dirs = (char *) "";
+static char *search_dirs;
-char *default_defines = (char *) "";
-char *defines;
+static char *default_defines = (char *) "";
+static char *defines;
/* Translate a Unix syntax directory specification into VMS syntax.
- If indicators of VMS syntax found, return input string. */
-static char *to_host_dir_spec PARAMS ((char *));
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_dir_spec (char *);
/* Translate a Unix syntax file specification into VMS syntax.
- If indicators of VMS syntax found, return input string. */
-static char *to_host_file_spec PARAMS ((char *));
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_file_spec (char *);
-/* Add a translated arg to the list to be passed to DEC CC */
-static void addarg PARAMS ((const char *));
+/* Add a translated arg to the list to be passed to DEC CC. */
+static void addarg (const char *);
/* Preprocess the number of args in P_ARGC and contained in ARGV.
- Look for special flags, etc. that must be handled first. */
-static void preprocess_args PARAMS ((int *, char **));
+ Look for special flags, etc. that must be handled first. */
+static void preprocess_args (int *, char **);
/* Process the number of args in P_ARGC and contained in ARGV. Look
- for special flags, etc. that must be handled for the VMS compiler. */
-static void process_args PARAMS ((int *, char **));
+ for special flags, etc. that must be handled for the VMS compiler. */
+static void process_args (int *, char **);
/* Action routine called by decc$to_vms */
-static int translate_unix PARAMS ((char *, int));
-
-int main PARAMS ((int, char **));
+static int translate_unix (char *, int);
/* Add the argument contained in STR to the list of arguments to pass to the
compiler. */
static void
-addarg (str)
- const char *str;
+addarg (const char *str)
{
int i;
@@ -98,9 +97,7 @@ addarg (str)
}
static void
-preprocess_args (p_argc, argv)
- int *p_argc;
- char *argv[];
+preprocess_args (int *p_argc, char *argv[])
{
int i;
@@ -120,9 +117,7 @@ preprocess_args (p_argc, argv)
}
static void
-process_args (p_argc, argv)
- int *p_argc;
- char *argv[];
+process_args (int *p_argc, char *argv[])
{
int i;
@@ -183,9 +178,7 @@ process_args (p_argc, argv)
typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int i;
char cwdev [128], *devptr;
@@ -318,17 +311,14 @@ static char new_host_dirspec [255];
static char filename_buff [256];
static int
-translate_unix (name, type)
- char *name;
- int type ATTRIBUTE_UNUSED;
+translate_unix (char *name, int type ATTRIBUTE_UNUSED)
{
strcpy (filename_buff, name);
return 0;
}
static char *
-to_host_dir_spec (dirspec)
- char *dirspec;
+to_host_dir_spec (char *dirspec)
{
int len = strlen (dirspec);
@@ -351,8 +341,7 @@ to_host_dir_spec (dirspec)
}
static char *
-to_host_file_spec (filespec)
- char *filespec;
+to_host_file_spec (char *filespec)
{
strcpy (new_host_filespec, "");
if (strchr (filespec, ']') || strchr (filespec, ':'))
diff --git a/contrib/gcc/config/alpha/vms-crt0-64.c b/contrib/gcc/config/alpha/vms-crt0-64.c
index 82ba322..9792f92 100644
--- a/contrib/gcc/config/alpha/vms-crt0-64.c
+++ b/contrib/gcc/config/alpha/vms-crt0-64.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -77,7 +77,7 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
#pragma __pointer_size long
- /* Reallocate argv with 64 bit pointers. */
+ /* Reallocate argv with 64 bit pointers. */
long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
for (i = 0; i < argc; i++)
diff --git a/contrib/gcc/config/alpha/vms-crt0.c b/contrib/gcc/config/alpha/vms-crt0.c
index b7665f9..88896c6 100644
--- a/contrib/gcc/config/alpha/vms-crt0.c
+++ b/contrib/gcc/config/alpha/vms-crt0.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,7 +33,7 @@ You Lose! This file can only be compiled with DEC C.
#else
/* This file can only be compiled with DEC C, due to the call to
- lib$establish. */
+ lib$establish. */
#include <stdlib.h>
#include <string.h>
diff --git a/contrib/gcc/config/alpha/vms-dwarf2.asm b/contrib/gcc/config/alpha/vms-dwarf2.asm
index a94ae24..1f68a80 100644
--- a/contrib/gcc/config/alpha/vms-dwarf2.asm
+++ b/contrib/gcc/config/alpha/vms-dwarf2.asm
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/vms-dwarf2eh.asm b/contrib/gcc/config/alpha/vms-dwarf2eh.asm
index 22f7050..2cdbeb1 100644
--- a/contrib/gcc/config/alpha/vms-dwarf2eh.asm
+++ b/contrib/gcc/config/alpha/vms-dwarf2eh.asm
@@ -2,9 +2,9 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/vms-ld.c b/contrib/gcc/config/alpha/vms-ld.c
index e5688d8..cb1d4c9 100644
--- a/contrib/gcc/config/alpha/vms-ld.c
+++ b/contrib/gcc/config/alpha/vms-ld.c
@@ -1,22 +1,22 @@
/* VMS linker wrapper.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
@@ -42,7 +44,7 @@ static char *vmsdwarf2spec = 0;
/* File specification for vms-dwarf2eh.o. */
static char *vmsdwarf2ehspec = 0;
-/* verbose = 1 if -v passed. */
+/* verbose = 1 if -v passed. */
static int verbose = 0;
/* save_temps = 1 if -save-temps passed. */
@@ -87,39 +89,38 @@ static char *search_dirs;
/* Add STR to the list of arguments to pass to the linker. Expand the list as
necessary to accommodate. */
-static void addarg PARAMS ((const char *));
+static void addarg (const char *);
/* Check to see if NAME is a regular file, i.e. not a directory */
-static int is_regular_file PARAMS ((char *));
+static int is_regular_file (char *);
/* Translate a Unix syntax file specification FILESPEC into VMS syntax.
- If indicators of VMS syntax found, return input string. */
-static char *to_host_file_spec PARAMS ((char *));
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_file_spec (char *);
-/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
-static char *locate_lib PARAMS ((char *, char *));
+/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
+static char *locate_lib (char *, char *);
/* Given a library name NAME, i.e. foo, Look for libfoo.lib and then
libfoo.a in the set of directories we are allowed to search in. */
-static const char *expand_lib PARAMS ((char *));
+static const char *expand_lib (char *);
/* Preprocess the number of args P_ARGC in ARGV.
- Look for special flags, etc. that must be handled first. */
-static void preprocess_args PARAMS ((int *, char **));
+ Look for special flags, etc. that must be handled first. */
+static void preprocess_args (int *, char **);
/* Preprocess the number of args P_ARGC in ARGV. Look for
- special flags, etc. that must be handled for the VMS linker. */
-static void process_args PARAMS ((int *, char **));
+ special flags, etc. that must be handled for the VMS linker. */
+static void process_args (int *, char **);
/* Action routine called by decc$to_vms. NAME is a file name or
- directory name. TYPE is unused. */
-static int translate_unix PARAMS ((char *, int));
+ directory name. TYPE is unused. */
+static int translate_unix (char *, int);
-int main PARAMS ((int, char **));
+int main (int, char **);
static void
-addarg (str)
- const char *str;
+addarg (const char *str)
{
int i;
@@ -142,9 +143,7 @@ addarg (str)
}
static char *
-locate_lib (lib_name, path_val)
- char *lib_name;
- char *path_val;
+locate_lib (char *lib_name, char *path_val)
{
int lib_len = strlen (lib_name);
char *eptr, *sptr;
@@ -204,8 +203,7 @@ locate_lib (lib_name, path_val)
}
static const char *
-expand_lib (name)
- char *name;
+expand_lib (char *name)
{
char *lib, *lib_path;
@@ -238,8 +236,7 @@ expand_lib (name)
}
static int
-is_regular_file (name)
- char *name;
+is_regular_file (char *name)
{
int ret;
struct stat statbuf;
@@ -249,9 +246,7 @@ is_regular_file (name)
}
static void
-preprocess_args (p_argc, argv)
- int *p_argc;
- char **argv;
+preprocess_args (int *p_argc, char **argv)
{
int i;
@@ -303,9 +298,7 @@ preprocess_args (p_argc, argv)
}
static void
-process_args (p_argc, argv)
- int *p_argc;
- char **argv;
+process_args (int *p_argc, char **argv)
{
int i;
@@ -379,9 +372,7 @@ process_args (p_argc, argv)
and args to be what the VMS linker wants. */
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int i;
char cwdev [128], *devptr;
@@ -751,17 +742,14 @@ static char new_host_filespec [255];
static char filename_buff [256];
static int
-translate_unix (name, type)
- char *name;
- int type ATTRIBUTE_UNUSED;
+translate_unix (char *name, int type ATTRIBUTE_UNUSED)
{
strcpy (filename_buff, name);
return 0;
}
static char *
-to_host_file_spec (filespec)
- char *filespec;
+to_host_file_spec (char *filespec)
{
strcpy (new_host_filespec, "");
if (strchr (filespec, ']') || strchr (filespec, ':'))
diff --git a/contrib/gcc/config/alpha/vms-psxcrt0-64.c b/contrib/gcc/config/alpha/vms-psxcrt0-64.c
index b16e8b4..8ca9e1d 100644
--- a/contrib/gcc/config/alpha/vms-psxcrt0-64.c
+++ b/contrib/gcc/config/alpha/vms-psxcrt0-64.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -79,7 +79,7 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
#pragma __pointer_size long
- /* Reallocate argv with 64 bit pointers. */
+ /* Reallocate argv with 64 bit pointers. */
long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
for (i = 0; i < argc; i++)
diff --git a/contrib/gcc/config/alpha/vms-psxcrt0.c b/contrib/gcc/config/alpha/vms-psxcrt0.c
index c4140b4..65962ee 100644
--- a/contrib/gcc/config/alpha/vms-psxcrt0.c
+++ b/contrib/gcc/config/alpha/vms-psxcrt0.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,7 +33,7 @@ You Lose! This file can only be compiled with DEC C.
#else
/* This file can only be compiled with DEC C, due to the call to
- lib$establish. */
+ lib$establish. */
#include <stdlib.h>
#include <string.h>
diff --git a/contrib/gcc/config/alpha/vms.h b/contrib/gcc/config/alpha/vms.h
index 8df6156..f7058f3 100644
--- a/contrib/gcc/config/alpha/vms.h
+++ b/contrib/gcc/config/alpha/vms.h
@@ -1,21 +1,21 @@
/* Output variables, constants and external declarations, for GNU compiler.
- Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002
+ Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,9 +41,6 @@ Boston, MA 02111-1307, USA. */
builtin_define ("__IEEE_FLOAT"); \
} while (0)
-/* By default, allow $ to be part of an identifier. */
-#define DOLLARS_IN_IDENTIFIERS 2
-
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP|MASK_FPREGS|MASK_GAS)
#undef TARGET_ABI_OPEN_VMS
@@ -54,9 +51,6 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);
-/* The structure return address arrives as an "argument" on VMS. */
-#undef STRUCT_VALUE_REGNUM
-#define STRUCT_VALUE 0
#undef PCC_STATIC_STRUCT_RETURN
/* "long" is 32 bits, but 64 bits for Ada. */
@@ -178,7 +172,7 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
For a library call, FNTYPE is 0. */
#undef INIT_CUMULATIVE_ARGS
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
(CUM).num_args = 0; \
(CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64; \
(CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;
@@ -205,61 +199,10 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
+ ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
? 6 - (CUM).num_args : 0)
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as for INIT_CUMULATIVE_ARGS.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed.
-
- For VMS, we allocate space for all 6 arg registers plus a count.
-
- However, if NO registers need to be saved, don't allocate any space.
- This is not only because we won't need the space, but because AP includes
- the current_pretend_args_size and we don't want to mess up any
- ap-relative addresses already made. */
-
-#undef SETUP_INCOMING_VARARGS
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-{ if ((CUM).num_args < 6) \
- { \
- if (! (NO_RTL)) \
- { \
- emit_move_insn (gen_rtx_REG (DImode, 1), \
- virtual_incoming_args_rtx); \
- emit_insn (gen_arg_home ()); \
- } \
- \
- PRETEND_SIZE = 7 * UNITS_PER_WORD; \
- } \
-}
-
/* ABI has stack checking, but it's broken. */
#undef STACK_CHECK_BUILTIN
#define STACK_CHECK_BUILTIN 0
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-{ \
- alpha_write_verstamp (FILE); \
- fprintf (FILE, "\t.set noreorder\n"); \
- fprintf (FILE, "\t.set volatile\n"); \
- if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
- { \
- fprintf (FILE, "\t.arch %s\n", \
- (TARGET_CPU_EV6 ? "ev6" \
- : TARGET_MAX ? "pca56" : "ev56")); \
- } \
- ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
-}
-
#define LINK_SECTION_ASM_OP "\t.link"
#define READONLY_DATA_SECTION_ASM_OP "\t.rdata"
#define LITERALS_SECTION_ASM_OP "\t.literals"
@@ -272,7 +215,7 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
void \
-link_section () \
+link_section (void) \
{ \
if (in_section != in_link) \
{ \
@@ -281,7 +224,7 @@ link_section () \
} \
} \
void \
-literals_section () \
+literals_section (void) \
{ \
if (in_section != in_literals) \
{ \
@@ -290,8 +233,8 @@ literals_section () \
} \
}
-extern void link_section PARAMS ((void));
-extern void literals_section PARAMS ((void));
+extern void link_section (void);
+extern void literals_section (void);
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
@@ -306,7 +249,7 @@ extern void literals_section PARAMS ((void));
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
-{ ASM_OUTPUT_ALIGN (FILE, 3); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+{ ASM_OUTPUT_ALIGN (FILE, 3); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This says how to output assembler code to declare an
uninitialized external linkage data object. */
@@ -318,7 +261,7 @@ extern void literals_section PARAMS ((void));
do { \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
@@ -448,10 +391,7 @@ do { \
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE VMS_AND_DWARF2_DEBUG
-#undef ASM_FORMAT_PRIVATE_NAME
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12), \
- sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
+#define ASM_PN_FORMAT "%s___%lu"
/* ??? VMS uses different linkage. */
#undef TARGET_ASM_OUTPUT_MI_THUNK
@@ -479,7 +419,7 @@ do { \
}
/* Link with vms-dwarf2.o if -g (except -g0). This causes the
- VMS link to pull all the dwarf2 debug sections together. */
+ VMS link to pull all the dwarf2 debug sections together. */
#undef LINK_SPEC
#define LINK_SPEC "%{g:-g vms-dwarf2.o%s} %{g0} %{g1:-g1 vms-dwarf2.o%s} \
%{g2:-g2 vms-dwarf2.o%s} %{g3:-g3 vms-dwarf2.o%s} %{shared} %{v} %{map}"
@@ -491,16 +431,6 @@ do { \
#undef LIB_SPEC
#define LIB_SPEC "-lc"
-/* Define the names of the division and modulus functions. */
-#define DIVSI3_LIBCALL "OTS$DIV_I"
-#define DIVDI3_LIBCALL "OTS$DIV_L"
-#define UDIVSI3_LIBCALL "OTS$DIV_UI"
-#define UDIVDI3_LIBCALL "OTS$DIV_UL"
-#define MODSI3_LIBCALL "OTS$REM_I"
-#define MODDI3_LIBCALL "OTS$REM_L"
-#define UMODSI3_LIBCALL "OTS$REM_UI"
-#define UMODDI3_LIBCALL "OTS$REM_UL"
-
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain
diff --git a/contrib/gcc/config/alpha/vms64.h b/contrib/gcc/config/alpha/vms64.h
index 3b4f587..29de9a5 100644
--- a/contrib/gcc/config/alpha/vms64.h
+++ b/contrib/gcc/config/alpha/vms64.h
@@ -2,20 +2,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/vms_tramp.asm b/contrib/gcc/config/alpha/vms_tramp.asm
index 9a6a1c8..1eb1e2b 100644
--- a/contrib/gcc/config/alpha/vms_tramp.asm
+++ b/contrib/gcc/config/alpha/vms_tramp.asm
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/xm-vms.h b/contrib/gcc/config/alpha/xm-vms.h
index 7bfceba..bdac52e 100644
--- a/contrib/gcc/config/alpha/xm-vms.h
+++ b/contrib/gcc/config/alpha/xm-vms.h
@@ -2,26 +2,23 @@
Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
Contributed by Klaus Kaempf (kkaempf@progis.de).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define HOST_WIDE_INT long long
-#define HOST_BITS_PER_WIDE_INT 64
-
/* A couple of conditionals for execution machine are controlled here. */
#ifndef VMS
#define VMS
diff --git a/contrib/gcc/config/arm/README-interworking b/contrib/gcc/config/arm/README-interworking
index de8b278..0a03cdc 100644
--- a/contrib/gcc/config/arm/README-interworking
+++ b/contrib/gcc/config/arm/README-interworking
@@ -404,7 +404,7 @@ Instead the pseudo op is attached to a new label .real_start_of_<name>
(where <name> is the name of the function) which indicates the start
of the Thumb code. This does have the interesting side effect in that
if this function is now called from a Thumb mode piece of code
-outsside of the current file, the linker will generate a calling stub
+outside of the current file, the linker will generate a calling stub
to switch from Thumb mode into ARM mode, and then this is immediately
overridden by the function's header which switches back into Thumb
mode.
diff --git a/contrib/gcc/config/arm/aof.h b/contrib/gcc/config/arm/aof.h
index 965337c..5a6ab2c 100644
--- a/contrib/gcc/config/arm/aof.h
+++ b/contrib/gcc/config/arm/aof.h
@@ -1,24 +1,24 @@
/* Definitions of target machine for GNU compiler, for Advanced RISC Machines
ARM compilation, AOF Assembler.
- Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 2000, 2003 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
@@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
#define LINK_LIBGCC_SPECIAL 1
#define LINK_SPEC "%{aof} %{bin} %{aif} %{ihf} %{shl,*} %{reent*} %{split} \
- %{ov*,*} %{reloc*} -nodebug"
+ %{ov*} %{reloc*} -nodebug"
#define STARTFILE_SPEC "crtbegin.o%s"
@@ -59,64 +59,70 @@ Boston, MA 02111-1307, USA. */
#define EXTRA_SECTIONS in_zero_init, in_common
#define EXTRA_SECTION_FUNCTIONS \
-ZERO_INIT_SECTION \
-COMMON_SECTION
+ ZERO_INIT_SECTION \
+ COMMON_SECTION
#define ZERO_INIT_SECTION \
-void \
-zero_init_section () \
-{ \
- static int zero_init_count = 1; \
- if (in_section != in_zero_init) \
- { \
- fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
- zero_init_count++); \
- in_section = in_zero_init; \
- } \
-}
+ void \
+ zero_init_section () \
+ { \
+ static int zero_init_count = 1; \
+ \
+ if (in_section != in_zero_init) \
+ { \
+ fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
+ zero_init_count++); \
+ in_section = in_zero_init; \
+ } \
+ }
/* Used by ASM_OUTPUT_COMMON (below) to tell varasm.c that we've
changed areas. */
#define COMMON_SECTION \
-void \
-common_section () \
-{ \
- if (in_section != in_common) \
- { \
+ void \
+ common_section () \
+ { \
+ if (in_section != in_common) \
in_section = in_common; \
- } \
-}
-#define CTOR_LIST_BEGIN \
-asm (CTORS_SECTION_ASM_OP); \
-extern func_ptr __CTOR_END__[1]; \
-func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
+ }
-#define CTOR_LIST_END \
-asm (CTORS_SECTION_ASM_OP); \
-func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
+#define CTOR_LIST_BEGIN \
+ asm (CTORS_SECTION_ASM_OP); \
+ extern func_ptr __CTOR_END__[1]; \
+ func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
-#define DO_GLOBAL_CTORS_BODY \
-do { \
- func_ptr *ptr = __CTOR_LIST__ + 1; \
- while (*ptr) \
- (*ptr++) (); \
-} while (0)
+#define CTOR_LIST_END \
+ asm (CTORS_SECTION_ASM_OP); \
+ func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
-#define DTOR_LIST_BEGIN \
-asm (DTORS_SECTION_ASM_OP); \
-extern func_ptr __DTOR_END__[1]; \
-func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
+#define DO_GLOBAL_CTORS_BODY \
+ do \
+ { \
+ func_ptr *ptr = __CTOR_LIST__ + 1; \
+ \
+ while (*ptr) \
+ (*ptr++) (); \
+ } \
+ while (0)
-#define DTOR_LIST_END \
-asm (DTORS_SECTION_ASM_OP); \
-func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+#define DTOR_LIST_BEGIN \
+ asm (DTORS_SECTION_ASM_OP); \
+ extern func_ptr __DTOR_END__[1]; \
+ func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
-#define DO_GLOBAL_DTORS_BODY \
-do { \
- func_ptr *ptr = __DTOR_LIST__ + 1; \
- while (*ptr) \
- (*ptr++) (); \
-} while (0)
+#define DTOR_LIST_END \
+ asm (DTORS_SECTION_ASM_OP); \
+ func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+
+#define DO_GLOBAL_DTORS_BODY \
+ do \
+ { \
+ func_ptr *ptr = __DTOR_LIST__ + 1; \
+ \
+ while (*ptr) \
+ (*ptr++) (); \
+ } \
+ while (0)
/* We really want to put Thumb tables in a read-only data section, but
switching to another section during function output is not
@@ -124,68 +130,18 @@ do { \
whole table generation until the end of the function. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
-#ifndef ARM_OS_NAME
-#define ARM_OS_NAME "(generic)"
-#endif
-
-/* For the AOF linker, we need to reference __main to force the standard
- library to get linked in. */
-
-#define ASM_FILE_START(STREAM) \
-{ \
- fprintf ((STREAM), "%s Generated by gcc %s for ARM/%s\n", \
- ASM_COMMENT_START, version_string, ARM_OS_NAME); \
- fprintf ((STREAM), "__r0\tRN\t0\n"); \
- fprintf ((STREAM), "__a1\tRN\t0\n"); \
- fprintf ((STREAM), "__a2\tRN\t1\n"); \
- fprintf ((STREAM), "__a3\tRN\t2\n"); \
- fprintf ((STREAM), "__a4\tRN\t3\n"); \
- fprintf ((STREAM), "__v1\tRN\t4\n"); \
- fprintf ((STREAM), "__v2\tRN\t5\n"); \
- fprintf ((STREAM), "__v3\tRN\t6\n"); \
- fprintf ((STREAM), "__v4\tRN\t7\n"); \
- fprintf ((STREAM), "__v5\tRN\t8\n"); \
- fprintf ((STREAM), "__v6\tRN\t9\n"); \
- fprintf ((STREAM), "__sl\tRN\t10\n"); \
- fprintf ((STREAM), "__fp\tRN\t11\n"); \
- fprintf ((STREAM), "__ip\tRN\t12\n"); \
- fprintf ((STREAM), "__sp\tRN\t13\n"); \
- fprintf ((STREAM), "__lr\tRN\t14\n"); \
- fprintf ((STREAM), "__pc\tRN\t15\n"); \
- fprintf ((STREAM), "__f0\tFN\t0\n"); \
- fprintf ((STREAM), "__f1\tFN\t1\n"); \
- fprintf ((STREAM), "__f2\tFN\t2\n"); \
- fprintf ((STREAM), "__f3\tFN\t3\n"); \
- fprintf ((STREAM), "__f4\tFN\t4\n"); \
- fprintf ((STREAM), "__f5\tFN\t5\n"); \
- fprintf ((STREAM), "__f6\tFN\t6\n"); \
- fprintf ((STREAM), "__f7\tFN\t7\n"); \
- text_section (); \
-}
-
/* Some systems use __main in a way incompatible with its use in gcc, in these
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
give the same symbol without quotes for an alternative entry point. You
- must define both, or neither. */
+ must define both, or neither. */
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain
-#define ASM_FILE_END(STREAM) \
-do \
-{ \
- if (flag_pic) \
- aof_dump_pic_table (STREAM); \
- aof_dump_imports (STREAM); \
- fputs ("\tEND\n", (STREAM)); \
-} while (0);
-
#define ASM_COMMENT_START ";"
+#define ASM_APP_ON ""
+#define ASM_APP_OFF ""
-#define ASM_APP_ON ""
-
-#define ASM_APP_OFF ""
-
-#define ASM_OUTPUT_ASCII(STREAM,PTR,LEN) \
+#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
{ \
int i; \
const char *ptr = (PTR); \
@@ -193,31 +149,30 @@ do \
for (i = 0; i < (long)(LEN); i++) \
fprintf ((STREAM), " &%02x%s", \
(unsigned ) *(ptr++), \
- (i + 1 < (long)(LEN) \
+ (i + 1 < (long)(LEN) \
? ((i & 3) == 3 ? "\n\tDCB" : ",") \
: "\n")); \
}
#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
-/* Output of Uninitialized Variables */
+/* Output of Uninitialized Variables. */
-#define ASM_OUTPUT_COMMON(STREAM,NAME,SIZE,ROUNDED) \
+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
(common_section (), \
fprintf ((STREAM), "\tAREA "), \
assemble_name ((STREAM), (NAME)), \
fprintf ((STREAM), ", DATA, COMMON\n\t%% %d\t%s size=%d\n", \
- (ROUNDED), ASM_COMMENT_START, SIZE))
+ (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)))
-#define ASM_OUTPUT_LOCAL(STREAM,NAME,SIZE,ROUNDED) \
+#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \
(zero_init_section (), \
assemble_name ((STREAM), (NAME)), \
fprintf ((STREAM), "\n"), \
fprintf ((STREAM), "\t%% %d\t%s size=%d\n", \
- (ROUNDED), ASM_COMMENT_START, SIZE))
+ (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)))
/* Output and Generation of Labels */
-
extern int arm_main_function;
/* Globalizing directive for a label. */
@@ -267,26 +222,31 @@ do { \
#define ASM_GENERATE_INTERNAL_LABEL(STRING,PREFIX,NUM) \
sprintf ((STRING), "*|%s..%ld|", (PREFIX), (long)(NUM))
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \
- ((OUTVAR) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
-
-/* How initialization functions are handled */
+/* How initialization functions are handled. */
#define CTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_ctorsvec|, DATA, READONLY"
#define DTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_dtorsvec|, DATA, READONLY"
-/* Output of Assembler Instructions */
-
-#define REGISTER_NAMES \
-{ \
- "a1", "a2", "a3", "a4", \
- "v1", "v2", "v3", "v4", \
- "v5", "v6", "sl", "fp", \
- "ip", "sp", "lr", "pc", \
- "f0", "f1", "f2", "f3", \
- "f4", "f5", "f6", "f7", \
- "cc", "sfp", "afp" \
+/* Output of Assembler Instructions. */
+
+#define REGISTER_NAMES \
+{ \
+ "a1", "a2", "a3", "a4", \
+ "v1", "v2", "v3", "v4", \
+ "v5", "v6", "sl", "fp", \
+ "ip", "sp", "lr", "pc", \
+ "f0", "f1", "f2", "f3", \
+ "f4", "f5", "f6", "f7", \
+ "cc", "sfp", "afp", \
+ "mv0", "mv1", "mv2", "mv3", \
+ "mv4", "mv5", "mv6", "mv7", \
+ "mv8", "mv9", "mv10", "mv11", \
+ "mv12", "mv13", "mv14", "mv15", \
+ "wcgr0", "wcgr1", "wcgr2", "wcgr3", \
+ "wr0", "wr1", "wr2", "wr3", \
+ "wr4", "wr5", "wr6", "wr7", \
+ "wr8", "wr9", "wr10", "wr11", \
+ "wr12", "wr13", "wr14", "wr15" \
}
#define ADDITIONAL_REGISTER_NAMES \
@@ -316,37 +276,40 @@ do { \
/* AOF does not prefix user function names with an underscore. */
#define ARM_MCOUNT_NAME "_mcount"
-/* Output of Dispatch Tables */
-
-#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
- do { \
- if (TARGET_ARM) \
- fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
- else \
- fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
- } while (0)
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
+/* Output of Dispatch Tables. */
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
+ do \
+ { \
+ if (TARGET_ARM) \
+ fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
+ else \
+ fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
+ } \
+ while (0)
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))
-/* A label marking the start of a jump table is a data label. */
-#define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) \
+/* A label marking the start of a jump table is a data label. */
+#define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
fprintf ((STREAM), "\tALIGN\n|%s..%d|\n", (PREFIX), (NUM))
-/* Assembler Commands for Alignment */
-
-#define ASM_OUTPUT_SKIP(STREAM,NBYTES) \
- fprintf ((STREAM), "\t%%\t%d\n", (NBYTES))
-
-#define ASM_OUTPUT_ALIGN(STREAM,POWER) \
-do { \
- register int amount = 1 << (POWER); \
- if (amount == 2) \
- fprintf ((STREAM), "\tALIGN 2\n"); \
- else if (amount == 4) \
- fprintf ((STREAM), "\tALIGN\n"); \
- else \
- fprintf ((STREAM), "\tALIGN %d\n", amount); \
-} while (0)
+/* Assembler Commands for Alignment. */
+#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
+ fprintf ((STREAM), "\t%%\t%d\n", (int) (NBYTES))
+
+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+ do \
+ { \
+ int amount = 1 << (POWER); \
+ \
+ if (amount == 2) \
+ fprintf ((STREAM), "\tALIGN 2\n"); \
+ else if (amount == 4) \
+ fprintf ((STREAM), "\tALIGN\n"); \
+ else \
+ fprintf ((STREAM), "\tALIGN %d\n", amount); \
+ } \
+ while (0)
#undef DBX_DEBUGGING_INFO
diff --git a/contrib/gcc/config/arm/aout.h b/contrib/gcc/config/arm/aout.h
index 8f4a605..1f060fa 100644
--- a/contrib/gcc/config/arm/aout.h
+++ b/contrib/gcc/config/arm/aout.h
@@ -3,40 +3,22 @@
Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk).
-This file is part of GNU CC.
-
-GNU CC 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 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#ifndef ARM_OS_NAME
-#define ARM_OS_NAME "(generic)"
-#endif
-
-/* The text to go at the start of the assembler file */
-#ifndef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
-{ \
- asm_fprintf (STREAM,"%Rrfp\t.req\t%Rr9\n"); \
- asm_fprintf (STREAM,"%Rsl\t.req\t%Rr10\n"); \
- asm_fprintf (STREAM,"%Rfp\t.req\t%Rr11\n"); \
- asm_fprintf (STREAM,"%Rip\t.req\t%Rr12\n"); \
- asm_fprintf (STREAM,"%Rsp\t.req\t%Rr13\n"); \
- asm_fprintf (STREAM,"%Rlr\t.req\t%Rr14\n"); \
- asm_fprintf (STREAM,"%Rpc\t.req\t%Rr15\n"); \
-}
-#endif
+ 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 2, 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 COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#ifndef ASM_APP_ON
#define ASM_APP_ON ""
@@ -52,7 +34,7 @@ Boston, MA 02111-1307, USA. */
/* Note: If USER_LABEL_PREFIX or LOCAL_LABEL_PREFIX are changed,
make sure that this change is reflected in the function
- coff_arm_is_local_label_name() in bfd/coff-arm.c */
+ coff_arm_is_local_label_name() in bfd/coff-arm.c. */
#ifndef REGISTER_PREFIX
#define REGISTER_PREFIX ""
#endif
@@ -65,7 +47,6 @@ Boston, MA 02111-1307, USA. */
#define LOCAL_LABEL_PREFIX ""
#endif
-
/* The assembler's names for the registers. */
#ifndef REGISTER_NAMES
#define REGISTER_NAMES \
@@ -73,7 +54,16 @@ Boston, MA 02111-1307, USA. */
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc", \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "cc", "sfp", "afp" \
+ "cc", "sfp", "afp", \
+ "mv0", "mv1", "mv2", "mv3", \
+ "mv4", "mv5", "mv6", "mv7", \
+ "mv8", "mv9", "mv10", "mv11", \
+ "mv12", "mv13", "mv14", "mv15", \
+ "wcgr0", "wcgr1", "wcgr2", "wcgr3", \
+ "wr0", "wr1", "wr2", "wr3", \
+ "wr4", "wr5", "wr6", "wr7", \
+ "wr8", "wr9", "wr10", "wr11", \
+ "wr12", "wr13", "wr14", "wr15" \
}
#endif
@@ -98,11 +88,75 @@ Boston, MA 02111-1307, USA. */
{"r12", 12}, /* ip */ \
{"r13", 13}, /* sp */ \
{"r14", 14}, /* lr */ \
- {"r15", 15} /* pc */ \
+ {"r15", 15}, /* pc */ \
+ {"mvf0", 27}, \
+ {"mvf1", 28}, \
+ {"mvf2", 29}, \
+ {"mvf3", 30}, \
+ {"mvf4", 31}, \
+ {"mvf5", 32}, \
+ {"mvf6", 33}, \
+ {"mvf7", 34}, \
+ {"mvf8", 35}, \
+ {"mvf9", 36}, \
+ {"mvf10", 37}, \
+ {"mvf11", 38}, \
+ {"mvf12", 39}, \
+ {"mvf13", 40}, \
+ {"mvf14", 41}, \
+ {"mvf15", 42}, \
+ {"mvd0", 27}, \
+ {"mvd1", 28}, \
+ {"mvd2", 29}, \
+ {"mvd3", 30}, \
+ {"mvd4", 31}, \
+ {"mvd5", 32}, \
+ {"mvd6", 33}, \
+ {"mvd7", 34}, \
+ {"mvd8", 35}, \
+ {"mvd9", 36}, \
+ {"mvd10", 37}, \
+ {"mvd11", 38}, \
+ {"mvd12", 39}, \
+ {"mvd13", 40}, \
+ {"mvd14", 41}, \
+ {"mvd15", 42}, \
+ {"mvfx0", 27}, \
+ {"mvfx1", 28}, \
+ {"mvfx2", 29}, \
+ {"mvfx3", 30}, \
+ {"mvfx4", 31}, \
+ {"mvfx5", 32}, \
+ {"mvfx6", 33}, \
+ {"mvfx7", 34}, \
+ {"mvfx8", 35}, \
+ {"mvfx9", 36}, \
+ {"mvfx10", 37}, \
+ {"mvfx11", 38}, \
+ {"mvfx12", 39}, \
+ {"mvfx13", 40}, \
+ {"mvfx14", 41}, \
+ {"mvfx15", 42}, \
+ {"mvdx0", 27}, \
+ {"mvdx1", 28}, \
+ {"mvdx2", 29}, \
+ {"mvdx3", 30}, \
+ {"mvdx4", 31}, \
+ {"mvdx5", 32}, \
+ {"mvdx6", 33}, \
+ {"mvdx7", 34}, \
+ {"mvdx8", 35}, \
+ {"mvdx9", 36}, \
+ {"mvdx10", 37}, \
+ {"mvdx11", 38}, \
+ {"mvdx12", 39}, \
+ {"mvdx13", 40}, \
+ {"mvdx14", 41}, \
+ {"mvdx15", 42} \
}
#endif
-/* Arm Assembler barfs on dollars */
+/* Arm Assembler barfs on dollars. */
#define DOLLARS_IN_IDENTIFIERS 0
#ifndef NO_DOLLAR_IN_LABEL
@@ -110,7 +164,7 @@ Boston, MA 02111-1307, USA. */
#endif
/* Generate DBX debugging information. riscix.h will undefine this because
- the native assembler does not support stabs. */
+ the native assembler does not support stabs. */
#define DBX_DEBUGGING_INFO 1
/* Acorn dbx moans about continuation chars, so don't use any. */
@@ -127,7 +181,7 @@ Boston, MA 02111-1307, USA. */
output_quoted_string (STREAM, NAME); \
fprintf (STREAM, ",%d,0,315,%s\n", N_SO, &ltext_label_name[1]); \
text_section (); \
- ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \
+ (*targetm.asm_out.internal_label) (STREAM, "Ltext", 0); \
} \
while (0)
@@ -151,11 +205,6 @@ Boston, MA 02111-1307, USA. */
sprintf (STRING, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned int)(NUM))
#endif
-/* Construct a private name. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
- ((OUTVAR) = (char *) alloca (strlen (NAME) + 10), \
- sprintf (OUTVAR, "%s.%d", NAME, NUMBER))
-
/* Output an element of a dispatch table. */
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE)
@@ -173,12 +222,12 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
- output_ascii_pseudo_op (STREAM, (const unsigned char *)(PTR), LEN)
+ output_ascii_pseudo_op (STREAM, (const unsigned char *) (PTR), LEN)
/* Output a gap. In fact we fill it with nulls. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
- fprintf (STREAM, "\t.space\t%d\n", NBYTES)
+ fprintf (STREAM, "\t.space\t%d\n", (int) (NBYTES))
/* Align output to a power of two. Horrible /bin/as. */
#ifndef ASM_OUTPUT_ALIGN
@@ -195,7 +244,7 @@ Boston, MA 02111-1307, USA. */
while (0)
#endif
-/* Output a common block */
+/* Output a common block. */
#ifndef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
do \
@@ -203,7 +252,7 @@ Boston, MA 02111-1307, USA. */
fprintf (STREAM, "\t.comm\t"); \
assemble_name (STREAM, NAME); \
asm_fprintf (STREAM, ", %d\t%@ %d\n", \
- ROUNDED, SIZE); \
+ (int)(ROUNDED), (int)(SIZE)); \
} \
while (0)
#endif
@@ -219,7 +268,7 @@ Boston, MA 02111-1307, USA. */
bss_section (); \
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL (STREAM, NAME); \
- fprintf (STREAM, "\t.space\t%d\n", SIZE); \
+ fprintf (STREAM, "\t.space\t%d\n", (int)(SIZE)); \
} \
while (0)
#endif
@@ -229,9 +278,6 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGN)
#endif
-
-/* Output a source line for the debugger. */
-/* #define ASM_OUTPUT_SOURCE_LINE(STREAM,LINE) */
/* Output a #ident directive. */
#ifndef ASM_OUTPUT_IDENT
diff --git a/contrib/gcc/config/arm/arm-modes.def b/contrib/gcc/config/arm/arm-modes.def
index 48f9ddf..b853551 100644
--- a/contrib/gcc/config/arm/arm-modes.def
+++ b/contrib/gcc/config/arm/arm-modes.def
@@ -5,42 +5,48 @@
More major hacks by Richard Earnshaw (rearnsha@arm.com)
Minor hacks by Nick Clifton (nickc@cygnus.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Extended precision floating point.
+ FIXME What format is this? */
+FLOAT_MODE (XF, 12, 0);
/* CCFPEmode should be used with floating inequalities,
CCFPmode should be used with floating equalities.
CC_NOOVmode should be used with SImode integer equalities.
CC_Zmode should be used if only the Z flag is set correctly
- CCmode should be used otherwise. */
+ CC_Nmode should be used if only the N (sign) flag is set correctly
+ CCmode should be used otherwise. */
-CC (CC_NOOV)
-CC (CC_Z)
-CC (CC_SWP)
-CC (CCFP)
-CC (CCFPE)
-CC (CC_DNE)
-CC (CC_DEQ)
-CC (CC_DLE)
-CC (CC_DLT)
-CC (CC_DGE)
-CC (CC_DGT)
-CC (CC_DLEU)
-CC (CC_DLTU)
-CC (CC_DGEU)
-CC (CC_DGTU)
-CC (CC_C)
+CC_MODE (CC_NOOV);
+CC_MODE (CC_Z);
+CC_MODE (CC_SWP);
+CC_MODE (CCFP);
+CC_MODE (CCFPE);
+CC_MODE (CC_DNE);
+CC_MODE (CC_DEQ);
+CC_MODE (CC_DLE);
+CC_MODE (CC_DLT);
+CC_MODE (CC_DGE);
+CC_MODE (CC_DGT);
+CC_MODE (CC_DLEU);
+CC_MODE (CC_DLTU);
+CC_MODE (CC_DGEU);
+CC_MODE (CC_DGTU);
+CC_MODE (CC_C);
+CC_MODE (CC_N);
diff --git a/contrib/gcc/config/arm/arm-protos.h b/contrib/gcc/config/arm/arm-protos.h
index cae9bea..471254e 100644
--- a/contrib/gcc/config/arm/arm-protos.h
+++ b/contrib/gcc/config/arm/arm-protos.h
@@ -1,220 +1,206 @@
/* Prototypes for exported functions defined in arm.c and pe.c
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@arm.com)
Minor hacks by Nick Clifton (nickc@cygnus.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#ifndef GCC_ARM_PROTOS_H
#define GCC_ARM_PROTOS_H
-extern void rdata_section PARAMS ((void));
-extern void arm_override_options PARAMS ((void));
-extern int use_return_insn PARAMS ((int));
-extern int arm_regno_class PARAMS ((int));
-extern void arm_finalize_pic PARAMS ((int));
-extern int arm_volatile_func PARAMS ((void));
-extern const char * arm_output_epilogue PARAMS ((int));
-extern void arm_expand_prologue PARAMS ((void));
-extern HOST_WIDE_INT arm_get_frame_size PARAMS ((void));
-/* Used in arm.md, but defined in output.c. */
-extern void assemble_align PARAMS ((int));
-extern const char * arm_strip_name_encoding PARAMS ((const char *));
-extern void arm_asm_output_labelref PARAMS ((FILE *, const char *));
-extern unsigned long arm_current_func_type PARAMS ((void));
-extern unsigned int arm_compute_initial_elimination_offset PARAMS ((unsigned int, unsigned int));
+extern void arm_override_options (void);
+extern int use_return_insn (int, rtx);
+extern int arm_regno_class (int);
+extern void arm_finalize_pic (int);
+extern int arm_volatile_func (void);
+extern const char *arm_output_epilogue (rtx);
+extern void arm_expand_prologue (void);
+extern HOST_WIDE_INT arm_get_frame_size (void);
+extern const char *arm_strip_name_encoding (const char *);
+extern void arm_asm_output_labelref (FILE *, const char *);
+extern unsigned long arm_current_func_type (void);
+extern unsigned int arm_compute_initial_elimination_offset (unsigned int,
+ unsigned int);
#ifdef TREE_CODE
-extern int arm_return_in_memory PARAMS ((tree));
-extern void arm_encode_call_attribute PARAMS ((tree, int));
-extern int arm_function_ok_for_sibcall PARAMS ((tree));
+extern int arm_return_in_memory (tree);
+extern void arm_encode_call_attribute (tree, int);
#endif
#ifdef RTX_CODE
-extern int arm_hard_regno_mode_ok PARAMS ((unsigned int,
- enum machine_mode));
-extern int const_ok_for_arm PARAMS ((HOST_WIDE_INT));
-extern int arm_split_constant PARAMS ((RTX_CODE, enum machine_mode,
- HOST_WIDE_INT, rtx, rtx, int));
-extern RTX_CODE arm_canonicalize_comparison PARAMS ((RTX_CODE, rtx *));
-extern int legitimate_pic_operand_p PARAMS ((rtx));
-extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
-extern int arm_rtx_costs PARAMS ((rtx, RTX_CODE, RTX_CODE));
-extern int const_double_rtx_ok_for_fpu PARAMS ((rtx));
-extern int neg_const_double_rtx_ok_for_fpu PARAMS ((rtx));
+extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
+extern int const_ok_for_arm (HOST_WIDE_INT);
+extern int arm_split_constant (RTX_CODE, enum machine_mode, HOST_WIDE_INT, rtx,
+ rtx, int);
+extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
+extern int legitimate_pic_operand_p (rtx);
+extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern int arm_legitimate_address_p (enum machine_mode, rtx, int);
+extern int thumb_legitimate_address_p (enum machine_mode, rtx, int);
+extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
+extern rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
+extern int const_double_rtx_ok_for_fpa (rtx);
+extern int neg_const_double_rtx_ok_for_fpa (rtx);
/* Predicates. */
-extern int s_register_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_hard_register_operand PARAMS ((rtx, enum machine_mode));
-extern int f_register_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_int_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_reload_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_rhs_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_rhsm_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_add_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_not_operand PARAMS ((rtx, enum machine_mode));
-extern int offsettable_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int alignable_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int bad_signed_byte_operand PARAMS ((rtx, enum machine_mode));
-extern int fpu_rhs_operand PARAMS ((rtx, enum machine_mode));
-extern int fpu_add_operand PARAMS ((rtx, enum machine_mode));
-extern int power_of_two_operand PARAMS ((rtx, enum machine_mode));
-extern int nonimmediate_di_operand PARAMS ((rtx, enum machine_mode));
-extern int di_operand PARAMS ((rtx, enum machine_mode));
-extern int nonimmediate_soft_df_operand PARAMS ((rtx, enum machine_mode));
-extern int soft_df_operand PARAMS ((rtx, enum machine_mode));
-extern int index_operand PARAMS ((rtx, enum machine_mode));
-extern int const_shift_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int shiftable_operator PARAMS ((rtx, enum machine_mode));
-extern int shift_operator PARAMS ((rtx, enum machine_mode));
-extern int equality_operator PARAMS ((rtx, enum machine_mode));
-extern int minmax_operator PARAMS ((rtx, enum machine_mode));
-extern int cc_register PARAMS ((rtx, enum machine_mode));
-extern int dominant_cc_register PARAMS ((rtx, enum machine_mode));
-extern int logical_binary_operator PARAMS ((rtx, enum machine_mode));
-extern int multi_register_push PARAMS ((rtx, enum machine_mode));
-extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
-
-extern int symbol_mentioned_p PARAMS ((rtx));
-extern int label_mentioned_p PARAMS ((rtx));
-extern RTX_CODE minmax_code PARAMS ((rtx));
-extern int adjacent_mem_locations PARAMS ((rtx, rtx));
-extern int load_multiple_sequence PARAMS ((rtx *, int, int *, int *,
- HOST_WIDE_INT *));
-extern const char * emit_ldm_seq PARAMS ((rtx *, int));
-extern int store_multiple_sequence PARAMS ((rtx *, int, int *, int *,
- HOST_WIDE_INT *));
-extern const char * emit_stm_seq PARAMS ((rtx *, int));
-extern rtx arm_gen_load_multiple PARAMS ((int, int, rtx, int, int, int,
- int, int));
-extern rtx arm_gen_store_multiple PARAMS ((int, int, rtx, int, int, int,
- int, int));
-extern int arm_gen_movstrqi PARAMS ((rtx *));
-extern rtx arm_gen_rotated_half_load PARAMS ((rtx));
-extern enum machine_mode arm_select_cc_mode PARAMS ((RTX_CODE, rtx, rtx));
-extern rtx arm_gen_compare_reg PARAMS ((RTX_CODE, rtx, rtx));
-extern rtx arm_gen_return_addr_mask PARAMS ((void));
-extern void arm_reload_in_hi PARAMS ((rtx *));
-extern void arm_reload_out_hi PARAMS ((rtx *));
-extern void arm_reorg PARAMS ((rtx));
-extern const char * fp_immediate_constant PARAMS ((rtx));
-extern const char * output_call PARAMS ((rtx *));
-extern const char * output_call_mem PARAMS ((rtx *));
-extern const char * output_mov_long_double_fpu_from_arm PARAMS ((rtx *));
-extern const char * output_mov_long_double_arm_from_fpu PARAMS ((rtx *));
-extern const char * output_mov_long_double_arm_from_arm PARAMS ((rtx *));
-extern const char * output_mov_double_fpu_from_arm PARAMS ((rtx *));
-extern const char * output_mov_double_arm_from_fpu PARAMS ((rtx *));
-extern const char * output_move_double PARAMS ((rtx *));
-extern const char * output_mov_immediate PARAMS ((rtx *));
-extern const char * output_add_immediate PARAMS ((rtx *));
-extern const char * arithmetic_instr PARAMS ((rtx, int));
-extern void output_ascii_pseudo_op PARAMS ((FILE *, const unsigned char *,
- int));
-extern const char * output_return_instruction PARAMS ((rtx, int, int));
-extern void arm_poke_function_name PARAMS ((FILE *, const char *));
-extern void arm_print_operand PARAMS ((FILE *, rtx, int));
-extern void arm_print_operand_address PARAMS ((FILE *, rtx));
-extern void arm_final_prescan_insn PARAMS ((rtx));
-extern int arm_go_if_legitimate_address PARAMS ((enum machine_mode, rtx));
-extern int arm_debugger_arg_offset PARAMS ((int, rtx));
-extern int arm_is_longcall_p PARAMS ((rtx, int, int));
+extern int s_register_operand (rtx, enum machine_mode);
+extern int arm_hard_register_operand (rtx, enum machine_mode);
+extern int f_register_operand (rtx, enum machine_mode);
+extern int reg_or_int_operand (rtx, enum machine_mode);
+extern int arm_reload_memory_operand (rtx, enum machine_mode);
+extern int arm_rhs_operand (rtx, enum machine_mode);
+extern int arm_rhsm_operand (rtx, enum machine_mode);
+extern int arm_add_operand (rtx, enum machine_mode);
+extern int arm_addimm_operand (rtx, enum machine_mode);
+extern int arm_not_operand (rtx, enum machine_mode);
+extern int offsettable_memory_operand (rtx, enum machine_mode);
+extern int alignable_memory_operand (rtx, enum machine_mode);
+extern int bad_signed_byte_operand (rtx, enum machine_mode);
+extern int fpa_rhs_operand (rtx, enum machine_mode);
+extern int fpa_add_operand (rtx, enum machine_mode);
+extern int power_of_two_operand (rtx, enum machine_mode);
+extern int nonimmediate_di_operand (rtx, enum machine_mode);
+extern int di_operand (rtx, enum machine_mode);
+extern int nonimmediate_soft_df_operand (rtx, enum machine_mode);
+extern int soft_df_operand (rtx, enum machine_mode);
+extern int index_operand (rtx, enum machine_mode);
+extern int const_shift_operand (rtx, enum machine_mode);
+extern int arm_comparison_operator (rtx, enum machine_mode);
+extern int shiftable_operator (rtx, enum machine_mode);
+extern int shift_operator (rtx, enum machine_mode);
+extern int equality_operator (rtx, enum machine_mode);
+extern int minmax_operator (rtx, enum machine_mode);
+extern int cc_register (rtx, enum machine_mode);
+extern int dominant_cc_register (rtx, enum machine_mode);
+extern int logical_binary_operator (rtx, enum machine_mode);
+extern int multi_register_push (rtx, enum machine_mode);
+extern int load_multiple_operation (rtx, enum machine_mode);
+extern int store_multiple_operation (rtx, enum machine_mode);
+extern int cirrus_fp_register (rtx, enum machine_mode);
+extern int cirrus_general_operand (rtx, enum machine_mode);
+extern int cirrus_register_operand (rtx, enum machine_mode);
+extern int cirrus_shift_const (rtx, enum machine_mode);
+extern int cirrus_memory_offset (rtx);
+
+extern int symbol_mentioned_p (rtx);
+extern int label_mentioned_p (rtx);
+extern RTX_CODE minmax_code (rtx);
+extern int adjacent_mem_locations (rtx, rtx);
+extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
+extern const char *emit_ldm_seq (rtx *, int);
+extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
+extern const char * emit_stm_seq (rtx *, int);
+extern rtx arm_gen_load_multiple (int, int, rtx, int, int, int, int, int);
+extern rtx arm_gen_store_multiple (int, int, rtx, int, int, int, int, int);
+extern int arm_gen_movstrqi (rtx *);
+extern rtx arm_gen_rotated_half_load (rtx);
+extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
+extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx,
+ HOST_WIDE_INT);
+extern rtx arm_gen_compare_reg (RTX_CODE, rtx, rtx);
+extern rtx arm_gen_return_addr_mask (void);
+extern void arm_reload_in_hi (rtx *);
+extern void arm_reload_out_hi (rtx *);
+extern const char *fp_immediate_constant (rtx);
+extern const char *output_call (rtx *);
+extern const char *output_call_mem (rtx *);
+extern const char *output_mov_long_double_fpa_from_arm (rtx *);
+extern const char *output_mov_long_double_arm_from_fpa (rtx *);
+extern const char *output_mov_long_double_arm_from_arm (rtx *);
+extern const char *output_mov_double_fpa_from_arm (rtx *);
+extern const char *output_mov_double_arm_from_fpa (rtx *);
+extern const char *output_move_double (rtx *);
+extern const char *output_mov_immediate (rtx *);
+extern const char *output_add_immediate (rtx *);
+extern const char *arithmetic_instr (rtx, int);
+extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);
+extern const char *output_return_instruction (rtx, int, int);
+extern void arm_poke_function_name (FILE *, const char *);
+extern void arm_print_operand (FILE *, rtx, int);
+extern void arm_print_operand_address (FILE *, rtx);
+extern void arm_final_prescan_insn (rtx);
+extern int arm_go_if_legitimate_address (enum machine_mode, rtx);
+extern int arm_debugger_arg_offset (int, rtx);
+extern int arm_is_longcall_p (rtx, int, int);
+extern int arm_emit_vector_const (FILE *, rtx);
+extern const char * arm_output_load_gr (rtx *);
#if defined TREE_CODE
-extern rtx arm_function_arg PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern void arm_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx,
- int));
-extern rtx arm_va_arg PARAMS ((tree, tree));
-extern int arm_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-
+extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
+extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern rtx arm_va_arg (tree, tree);
+extern int arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
#endif
#if defined AOF_ASSEMBLER
-extern rtx aof_pic_entry PARAMS ((rtx));
-extern void aof_dump_pic_table PARAMS ((FILE *));
-extern char * aof_text_section PARAMS ((void));
-extern char * aof_data_section PARAMS ((void));
-extern void aof_add_import PARAMS ((const char *));
-extern void aof_delete_import PARAMS ((const char *));
-extern void aof_dump_imports PARAMS ((FILE *));
-extern void zero_init_section PARAMS ((void));
-extern void common_section PARAMS ((void));
+extern rtx aof_pic_entry (rtx);
+extern char *aof_text_section (void);
+extern char *aof_data_section (void);
+extern void aof_add_import (const char *);
+extern void aof_delete_import (const char *);
+extern void zero_init_section (void);
+extern void common_section (void);
#endif /* AOF_ASSEMBLER */
#endif /* RTX_CODE */
-extern int arm_float_words_big_endian PARAMS ((void));
+extern int arm_float_words_big_endian (void);
/* Thumb functions. */
-extern void arm_init_expanders PARAMS ((void));
-extern int thumb_far_jump_used_p PARAMS ((int));
-extern const char * thumb_unexpanded_epilogue PARAMS ((void));
-extern HOST_WIDE_INT thumb_get_frame_size PARAMS ((void));
-extern void thumb_expand_prologue PARAMS ((void));
-extern void thumb_expand_epilogue PARAMS ((void));
+extern void arm_init_expanders (void);
+extern int thumb_far_jump_used_p (int);
+extern const char *thumb_unexpanded_epilogue (void);
+extern HOST_WIDE_INT thumb_get_frame_size (void);
+extern void thumb_expand_prologue (void);
+extern void thumb_expand_epilogue (void);
#ifdef TREE_CODE
-extern int is_called_in_ARM_mode PARAMS ((tree));
+extern int is_called_in_ARM_mode (tree);
#endif
-extern int thumb_shiftable_const PARAMS ((unsigned HOST_WIDE_INT));
+extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
#ifdef RTX_CODE
-extern void thumb_final_prescan_insn PARAMS ((rtx));
-extern const char * thumb_load_double_from_address
- PARAMS ((rtx *));
-extern const char * thumb_output_move_mem_multiple
- PARAMS ((int, rtx *));
-extern void thumb_expand_movstrqi PARAMS ((rtx *));
-extern int thumb_cmp_operand PARAMS ((rtx, enum machine_mode));
-extern rtx * thumb_legitimize_pic_address
- PARAMS ((rtx, enum machine_mode, rtx));
-extern int thumb_go_if_legitimate_address
- PARAMS ((enum machine_mode, rtx));
-extern rtx arm_return_addr PARAMS ((int, rtx));
-extern void thumb_reload_out_hi PARAMS ((rtx *));
-extern void thumb_reload_in_hi PARAMS ((rtx *));
+extern void thumb_final_prescan_insn (rtx);
+extern const char *thumb_load_double_from_address (rtx *);
+extern const char *thumb_output_move_mem_multiple (int, rtx *);
+extern void thumb_expand_movstrqi (rtx *);
+extern int thumb_cmp_operand (rtx, enum machine_mode);
+extern int thumb_cbrch_target_operand (rtx, enum machine_mode);
+extern rtx *thumb_legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern int thumb_go_if_legitimate_address (enum machine_mode, rtx);
+extern rtx arm_return_addr (int, rtx);
+extern void thumb_reload_out_hi (rtx *);
+extern void thumb_reload_in_hi (rtx *);
#endif
/* Defined in pe.c. */
-extern int arm_dllexport_name_p PARAMS ((const char *));
-extern int arm_dllimport_name_p PARAMS ((const char *));
+extern int arm_dllexport_name_p (const char *);
+extern int arm_dllimport_name_p (const char *);
#ifdef TREE_CODE
-extern void arm_pe_unique_section PARAMS ((tree, int));
-extern void arm_pe_encode_section_info PARAMS ((tree, int));
-extern int arm_dllexport_p PARAMS ((tree));
-extern int arm_dllimport_p PARAMS ((tree));
-extern void arm_mark_dllexport PARAMS ((tree));
-extern void arm_mark_dllimport PARAMS ((tree));
-#endif
-
-extern void arm_init_builtins PARAMS ((void));
-#if defined (TREE_CODE) && defined (RTX_CODE)
-extern rtx arm_expand_builtin PARAMS ((tree, rtx, rtx,
- enum machine_mode, int));
+extern void arm_pe_unique_section (tree, int);
+extern void arm_pe_encode_section_info (tree, rtx, int);
+extern int arm_dllexport_p (tree);
+extern int arm_dllimport_p (tree);
+extern void arm_mark_dllexport (tree);
+extern void arm_mark_dllimport (tree);
#endif
-#ifdef GCC_C_PRAGMA_H /* included from code that cares about pragmas */
-extern void arm_pr_long_calls PARAMS ((cpp_reader *));
-extern void arm_pr_no_long_calls PARAMS ((cpp_reader *));
-extern void arm_pr_long_calls_off PARAMS ((cpp_reader *));
-#endif
+extern void arm_pr_long_calls (struct cpp_reader *);
+extern void arm_pr_no_long_calls (struct cpp_reader *);
+extern void arm_pr_long_calls_off (struct cpp_reader *);
#endif /* ! GCC_ARM_PROTOS_H */
diff --git a/contrib/gcc/config/arm/arm.c b/contrib/gcc/config/arm/arm.c
index 7422f1d..91e4486 100644
--- a/contrib/gcc/config/arm/arm.c
+++ b/contrib/gcc/config/arm/arm.c
@@ -1,29 +1,31 @@
/* Output routines for GCC for ARM.
- Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "obstack.h"
@@ -48,91 +50,107 @@ Boston, MA 02111-1307, USA. */
#include "tm_p.h"
#include "target.h"
#include "target-def.h"
+#include "debug.h"
/* Forward definitions of types. */
typedef struct minipool_node Mnode;
typedef struct minipool_fixup Mfix;
-/* In order to improve the layout of the prototypes below
- some short type abbreviations are defined here. */
-#define Hint HOST_WIDE_INT
-#define Mmode enum machine_mode
-#define Ulong unsigned long
-#define Ccstar const char *
-
const struct attribute_spec arm_attribute_table[];
/* Forward function declarations. */
-static void arm_add_gc_roots PARAMS ((void));
-static int arm_gen_constant PARAMS ((enum rtx_code, Mmode, Hint, rtx, rtx, int, int));
-static unsigned bit_count PARAMS ((Ulong));
-static int const_ok_for_op PARAMS ((Hint, enum rtx_code));
-static rtx emit_multi_reg_push PARAMS ((int));
-static rtx emit_sfm PARAMS ((int, int));
+static void arm_add_gc_roots (void);
+static int arm_gen_constant (enum rtx_code, enum machine_mode, HOST_WIDE_INT,
+ rtx, rtx, int, int);
+static unsigned bit_count (unsigned long);
+static int arm_address_register_rtx_p (rtx, int);
+static int arm_legitimate_index_p (enum machine_mode, rtx, int);
+static int thumb_base_register_rtx_p (rtx, enum machine_mode, int);
+inline static int thumb_index_register_rtx_p (rtx, int);
+static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
+static rtx emit_multi_reg_push (int);
+static rtx emit_sfm (int, int);
#ifndef AOF_ASSEMBLER
-static bool arm_assemble_integer PARAMS ((rtx, unsigned int, int));
+static bool arm_assemble_integer (rtx, unsigned int, int);
#endif
-static Ccstar fp_const_from_val PARAMS ((REAL_VALUE_TYPE *));
-static arm_cc get_arm_condition_code PARAMS ((rtx));
-static void init_fpa_table PARAMS ((void));
-static Hint int_log2 PARAMS ((Hint));
-static rtx is_jump_table PARAMS ((rtx));
-static Ccstar output_multi_immediate PARAMS ((rtx *, Ccstar, Ccstar, int, Hint));
-static void print_multi_reg PARAMS ((FILE *, Ccstar, int, int));
-static Mmode select_dominance_cc_mode PARAMS ((rtx, rtx, Hint));
-static Ccstar shift_op PARAMS ((rtx, Hint *));
-static struct machine_function * arm_init_machine_status PARAMS ((void));
-static int number_of_first_bit_set PARAMS ((int));
-static void replace_symbols_in_block PARAMS ((tree, rtx, rtx));
-static void thumb_exit PARAMS ((FILE *, int, rtx));
-static void thumb_pushpop PARAMS ((FILE *, int, int));
-static Ccstar thumb_condition_code PARAMS ((rtx, int));
-static rtx is_jump_table PARAMS ((rtx));
-static Hint get_jump_table_size PARAMS ((rtx));
-static Mnode * move_minipool_fix_forward_ref PARAMS ((Mnode *, Mnode *, Hint));
-static Mnode * add_minipool_forward_ref PARAMS ((Mfix *));
-static Mnode * move_minipool_fix_backward_ref PARAMS ((Mnode *, Mnode *, Hint));
-static Mnode * add_minipool_backward_ref PARAMS ((Mfix *));
-static void assign_minipool_offsets PARAMS ((Mfix *));
-static void arm_print_value PARAMS ((FILE *, rtx));
-static void dump_minipool PARAMS ((rtx));
-static int arm_barrier_cost PARAMS ((rtx));
-static Mfix * create_fix_barrier PARAMS ((Mfix *, Hint));
-static void push_minipool_barrier PARAMS ((rtx, Hint));
-static void push_minipool_fix PARAMS ((rtx, Hint, rtx *, Mmode, rtx));
-static void note_invalid_constants PARAMS ((rtx, Hint));
-static int current_file_function_operand PARAMS ((rtx));
-static Ulong arm_compute_save_reg0_reg12_mask PARAMS ((void));
-static Ulong arm_compute_save_reg_mask PARAMS ((void));
-static Ulong arm_isr_value PARAMS ((tree));
-static Ulong arm_compute_func_type PARAMS ((void));
-static tree arm_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static tree arm_handle_isr_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static void arm_output_function_epilogue PARAMS ((FILE *, Hint));
-static void arm_output_function_prologue PARAMS ((FILE *, Hint));
-static void thumb_output_function_prologue PARAMS ((FILE *, Hint));
-static int arm_comp_type_attributes PARAMS ((tree, tree));
-static void arm_set_default_type_attributes PARAMS ((tree));
-static int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int count_insns_for_constant PARAMS ((HOST_WIDE_INT, int));
-static int arm_get_strip_length PARAMS ((int));
+static const char *fp_const_from_val (REAL_VALUE_TYPE *);
+static arm_cc get_arm_condition_code (rtx);
+static void init_fpa_table (void);
+static HOST_WIDE_INT int_log2 (HOST_WIDE_INT);
+static rtx is_jump_table (rtx);
+static const char *output_multi_immediate (rtx *, const char *, const char *,
+ int, HOST_WIDE_INT);
+static void print_multi_reg (FILE *, const char *, int, int);
+static const char *shift_op (rtx, HOST_WIDE_INT *);
+static struct machine_function *arm_init_machine_status (void);
+static int number_of_first_bit_set (int);
+static void replace_symbols_in_block (tree, rtx, rtx);
+static void thumb_exit (FILE *, int, rtx);
+static void thumb_pushpop (FILE *, int, int, int *, int);
+static rtx is_jump_table (rtx);
+static HOST_WIDE_INT get_jump_table_size (rtx);
+static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
+static Mnode *add_minipool_forward_ref (Mfix *);
+static Mnode *move_minipool_fix_backward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
+static Mnode *add_minipool_backward_ref (Mfix *);
+static void assign_minipool_offsets (Mfix *);
+static void arm_print_value (FILE *, rtx);
+static void dump_minipool (rtx);
+static int arm_barrier_cost (rtx);
+static Mfix *create_fix_barrier (Mfix *, HOST_WIDE_INT);
+static void push_minipool_barrier (rtx, HOST_WIDE_INT);
+static void push_minipool_fix (rtx, HOST_WIDE_INT, rtx *, enum machine_mode,
+ rtx);
+static void arm_reorg (void);
+static bool note_invalid_constants (rtx, HOST_WIDE_INT, int);
+static int current_file_function_operand (rtx);
+static unsigned long arm_compute_save_reg0_reg12_mask (void);
+static unsigned long arm_compute_save_reg_mask (void);
+static unsigned long arm_isr_value (tree);
+static unsigned long arm_compute_func_type (void);
+static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
+static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
+static void arm_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void arm_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void thumb_output_function_prologue (FILE *, HOST_WIDE_INT);
+static int arm_comp_type_attributes (tree, tree);
+static void arm_set_default_type_attributes (tree);
+static int arm_adjust_cost (rtx, rtx, rtx, int);
+static int arm_use_dfa_pipeline_interface (void);
+static int count_insns_for_constant (HOST_WIDE_INT, int);
+static int arm_get_strip_length (int);
+static bool arm_function_ok_for_sibcall (tree, tree);
+static void arm_internal_label (FILE *, const char *, unsigned long);
+static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ tree);
+static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
+static bool arm_rtx_costs (rtx, int, int, int *);
+static int arm_address_cost (rtx);
+static bool arm_memory_load_p (rtx);
+static bool arm_cirrus_insn_p (rtx);
+static void cirrus_reorg (rtx);
+static void arm_init_builtins (void);
+static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void arm_init_iwmmxt_builtins (void);
+static rtx safe_vector_operand (rtx, enum machine_mode);
+static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
+static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+
#ifdef OBJECT_FORMAT_ELF
-static void arm_elf_asm_named_section PARAMS ((const char *, unsigned int));
+static void arm_elf_asm_named_section (const char *, unsigned int);
#endif
#ifndef ARM_PE
-static void arm_encode_section_info PARAMS ((tree, int));
+static void arm_encode_section_info (tree, rtx, int);
#endif
#ifdef AOF_ASSEMBLER
-static void aof_globalize_label PARAMS ((FILE *, const char *));
+static void aof_globalize_label (FILE *, const char *);
+static void aof_dump_imports (FILE *);
+static void aof_dump_pic_table (FILE *);
+static void aof_file_start (void);
+static void aof_file_end (void);
#endif
-static void arm_output_mi_thunk PARAMS ((FILE *, tree,
- HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
-
-#undef Hint
-#undef Mmode
-#undef Ulong
-#undef Ccstar
+
/* Initialize the GCC target structure. */
#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -152,6 +170,10 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#define TARGET_ASM_ALIGNED_SI_OP "\tDCD\t"
#undef TARGET_ASM_GLOBALIZE_LABEL
#define TARGET_ASM_GLOBALIZE_LABEL aof_globalize_label
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START aof_file_start
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END aof_file_end
#else
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP NULL
@@ -171,15 +193,12 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES arm_set_default_type_attributes
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS arm_init_builtins
-
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN arm_expand_builtin
-
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE arm_use_dfa_pipeline_interface
+
#undef TARGET_ENCODE_SECTION_INFO
#ifdef ARM_PE
#define TARGET_ENCODE_SECTION_INFO arm_pe_encode_section_info
@@ -187,14 +206,33 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#define TARGET_ENCODE_SECTION_INFO arm_encode_section_info
#endif
-#undef TARGET_STRIP_NAME_ENCODING
+#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING arm_strip_name_encoding
-#undef TARGET_ASM_OUTPUT_MI_THUNK
+#undef TARGET_ASM_INTERNAL_LABEL
+#define TARGET_ASM_INTERNAL_LABEL arm_internal_label
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
+
+#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
-#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS arm_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST arm_address_cost
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG arm_reorg
+
+#undef TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS arm_init_builtins
+#undef TARGET_EXPAND_BUILTIN
+#define TARGET_EXPAND_BUILTIN arm_expand_builtin
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -215,10 +253,10 @@ int making_const_table;
rtx arm_compare_op0, arm_compare_op1;
/* What type of floating point are we tuning for? */
-enum floating_point_type arm_fpu;
+enum fputype arm_fpu_tune;
/* What type of floating point instructions are available? */
-enum floating_point_type arm_fpu_arch;
+enum fputype arm_fpu_arch;
/* What program mode is the cpu running in? 26-bit mode or 32-bit mode. */
enum prog_mode_type arm_prgmode;
@@ -240,8 +278,13 @@ int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
#define FL_THUMB (1 << 6) /* Thumb aware */
#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */
#define FL_STRONG (1 << 8) /* StrongARM */
-#define FL_ARCH5E (1 << 9) /* DSP extenstions to v5 */
+#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */
#define FL_XSCALE (1 << 10) /* XScale */
+#define FL_CIRRUS (1 << 11) /* Cirrus/DSP. */
+#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
+#define FL_ARCH6J (1 << 12) /* Architecture rel 6. Adds
+ media instructions. */
+#define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */
/* The bits in this mask specify which
instructions we are allowed to generate. */
@@ -274,12 +317,21 @@ int arm_ld_sched = 0;
/* Nonzero if this chip is a StrongARM. */
int arm_is_strong = 0;
+/* Nonzero if this chip supports Intel Wireless MMX technology. */
+int arm_arch_iwmmxt = 0;
+
/* Nonzero if this chip is an XScale. */
-int arm_is_xscale = 0;
+int arm_arch_xscale = 0;
+
+/* Nonzero if tuning for XScale */
+int arm_tune_xscale = 0;
/* Nonzero if this chip is an ARM6 or an ARM7. */
int arm_is_6_or_7 = 0;
+/* Nonzero if this chip is a Cirrus/DSP. */
+int arm_is_cirrus = 0;
+
/* Nonzero if generating Thumb instructions. */
int thumb_code = 0;
@@ -352,16 +404,17 @@ static const struct processors all_cores[] =
{"arm700", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm700i", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm710", FL_MODE26 | FL_MODE32 },
- {"arm710t", FL_MODE26 | FL_MODE32 | FL_THUMB },
{"arm720", FL_MODE26 | FL_MODE32 },
- {"arm720t", FL_MODE26 | FL_MODE32 | FL_THUMB },
- {"arm740t", FL_MODE26 | FL_MODE32 | FL_THUMB },
{"arm710c", FL_MODE26 | FL_MODE32 },
{"arm7100", FL_MODE26 | FL_MODE32 },
{"arm7500", FL_MODE26 | FL_MODE32 },
- /* Doesn't have an external co-proc, but does have embedded fpu. */
+ /* Doesn't have an external co-proc, but does have embedded fpa. */
{"arm7500fe", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ /* V4 Architecture Processors */
{"arm7tdmi", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {"arm710t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {"arm720t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {"arm740t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
{"arm8", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
{"arm810", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
{"arm9", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
@@ -370,14 +423,21 @@ static const struct processors all_cores[] =
{"arm940t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
{"arm9tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
{"arm9e", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
+ {"ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
{"strongarm", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm1100", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm1110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
+ /* V5 Architecture Processors */
{"arm10tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
{"arm1020t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
+ {"arm926ejs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
+ {"arm1026ejs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
{"xscale", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE },
-
+ {"iwmmxt", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT },
+ /* V6 Architecture Processors */
+ {"arm1136js", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J },
+ {"arm1136jfs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J | FL_VFPV2 },
{NULL, 0}
};
@@ -396,10 +456,13 @@ static const struct processors all_architectures[] =
{ "armv5", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
{ "armv5t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
{ "armv5te", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
+ { "armv6j", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J },
+ { "ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
+ {"iwmmxt", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT },
{ NULL, 0 }
};
-/* This is a magic stucture. The 'string' field is magically filled in
+/* This is a magic structure. The 'string' field is magically filled in
with a pointer to the value specified by the user on the command line
assuming that the user has specified such a value. */
@@ -413,8 +476,7 @@ struct arm_cpu_select arm_select[] =
/* Return the number of bits set in VALUE. */
static unsigned
-bit_count (value)
- unsigned long value;
+bit_count (unsigned long value)
{
unsigned long count = 0;
@@ -430,7 +492,7 @@ bit_count (value)
/* Fix up any incompatible options that the user has specified.
This has now turned into a maze. */
void
-arm_override_options ()
+arm_override_options (void)
{
unsigned i;
@@ -493,6 +555,12 @@ arm_override_options ()
{ TARGET_CPU_arm9, "arm9" },
{ TARGET_CPU_strongarm, "strongarm" },
{ TARGET_CPU_xscale, "xscale" },
+ { TARGET_CPU_ep9312, "ep9312" },
+ { TARGET_CPU_iwmmxt, "iwmmxt" },
+ { TARGET_CPU_arm926ej_s, "arm926ej-s" },
+ { TARGET_CPU_arm1026ej_s, "arm1026ej-s" },
+ { TARGET_CPU_arm1136j_s, "arm1136j_s" },
+ { TARGET_CPU_arm1136jf_s, "arm1136jf_s" },
{ TARGET_CPU_generic, "arm" },
{ 0, 0 }
};
@@ -622,6 +690,9 @@ arm_override_options ()
target_flags &= ~ARM_FLAG_THUMB;
}
+ if (!TARGET_APCS_32)
+ inform ("future releases of GCC will not support -mapcs-26");
+
if (TARGET_APCS_FRAME && TARGET_THUMB)
{
/* warning ("ignoring -mapcs-frame because -mthumb was used"); */
@@ -684,40 +755,62 @@ arm_override_options ()
arm_arch4 = (insn_flags & FL_ARCH4) != 0;
arm_arch5 = (insn_flags & FL_ARCH5) != 0;
arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
- arm_is_xscale = (insn_flags & FL_XSCALE) != 0;
+ arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
arm_is_strong = (tune_flags & FL_STRONG) != 0;
thumb_code = (TARGET_ARM == 0);
arm_is_6_or_7 = (((tune_flags & (FL_MODE26 | FL_MODE32))
&& !(tune_flags & FL_ARCH4))) != 0;
+ arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
+ arm_is_cirrus = (tune_flags & FL_CIRRUS) != 0;
+ arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
- /* Default value for floating point code... if no co-processor
- bus, then schedule for emulated floating point. Otherwise,
- assume the user has an FPA.
- Note: this does not prevent use of floating point instructions,
- -msoft-float does that. */
- arm_fpu = (tune_flags & FL_CO_PROC) ? FP_HARD : FP_SOFT3;
+ if (TARGET_IWMMXT && (! TARGET_ATPCS))
+ target_flags |= ARM_FLAG_ATPCS;
+
+ if (arm_is_cirrus)
+ {
+ arm_fpu_tune = FPUTYPE_MAVERICK;
+
+ /* Ignore -mhard-float if -mcpu=ep9312. */
+ if (TARGET_HARD_FLOAT)
+ target_flags ^= ARM_FLAG_SOFT_FLOAT;
+ }
+ else
+ /* Default value for floating point code... if no co-processor
+ bus, then schedule for emulated floating point. Otherwise,
+ assume the user has an FPA.
+ Note: this does not prevent use of floating point instructions,
+ -msoft-float does that. */
+ arm_fpu_tune = (tune_flags & FL_CO_PROC) ? FPUTYPE_FPA : FPUTYPE_FPA_EMU3;
if (target_fp_name)
{
if (streq (target_fp_name, "2"))
- arm_fpu_arch = FP_SOFT2;
+ arm_fpu_arch = FPUTYPE_FPA_EMU2;
else if (streq (target_fp_name, "3"))
- arm_fpu_arch = FP_SOFT3;
+ arm_fpu_arch = FPUTYPE_FPA_EMU3;
else
error ("invalid floating point emulation option: -mfpe-%s",
target_fp_name);
}
else
- arm_fpu_arch = FP_DEFAULT;
+ arm_fpu_arch = FPUTYPE_DEFAULT;
- if (TARGET_FPE && arm_fpu != FP_HARD)
- arm_fpu = FP_SOFT2;
+ if (TARGET_FPE)
+ {
+ if (arm_fpu_tune == FPUTYPE_FPA_EMU3)
+ arm_fpu_tune = FPUTYPE_FPA_EMU2;
+ else if (arm_fpu_tune == FPUTYPE_MAVERICK)
+ warning ("-mfpe switch not supported by ep9312 target cpu - ignored.");
+ else if (arm_fpu_tune != FPUTYPE_FPA)
+ arm_fpu_tune = FPUTYPE_FPA_EMU2;
+ }
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
- if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD)
+ if ((TARGET_SOFT_FLOAT || arm_fpu_tune != FPUTYPE_FPA)
&& (tune_flags & FL_MODE32) == 0)
flag_schedule_insns = flag_schedule_insns_after_reload = 0;
@@ -756,30 +849,44 @@ arm_override_options ()
flag_schedule_insns = 0;
}
- /* If optimizing for space, don't synthesize constants.
- For processors with load scheduling, it never costs more than 2 cycles
- to load a constant, and the load scheduler may well reduce that to 1. */
- if (optimize_size || (tune_flags & FL_LDSCHED))
- arm_constant_limit = 1;
-
- if (arm_is_xscale)
- arm_constant_limit = 2;
-
- /* If optimizing for size, bump the number of instructions that we
- are prepared to conditionally execute (even on a StrongARM).
- Otherwise for the StrongARM, which has early execution of branches,
- a sequence that is worth skipping is shorter. */
if (optimize_size)
- max_insns_skipped = 6;
- else if (arm_is_strong)
- max_insns_skipped = 3;
+ {
+ /* There's some dispute as to whether this should be 1 or 2. However,
+ experiments seem to show that in pathological cases a setting of
+ 1 degrades less severely than a setting of 2. This could change if
+ other parts of the compiler change their behavior. */
+ arm_constant_limit = 1;
+
+ /* If optimizing for size, bump the number of instructions that we
+ are prepared to conditionally execute (even on a StrongARM). */
+ max_insns_skipped = 6;
+ }
+ else
+ {
+ /* For processors with load scheduling, it never costs more than
+ 2 cycles to load a constant, and the load scheduler may well
+ reduce that to 1. */
+ if (tune_flags & FL_LDSCHED)
+ arm_constant_limit = 1;
+
+ /* On XScale the longer latency of a load makes it more difficult
+ to achieve a good schedule, so it's faster to synthesize
+ constants that can be done in two insns. */
+ if (arm_tune_xscale)
+ arm_constant_limit = 2;
+
+ /* StrongARM has early execution of branches, so a sequence
+ that is worth skipping is shorter. */
+ if (arm_is_strong)
+ max_insns_skipped = 3;
+ }
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
}
static void
-arm_add_gc_roots ()
+arm_add_gc_roots (void)
{
gcc_obstack_init(&minipool_obstack);
minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
@@ -816,8 +923,7 @@ static const isr_attribute_arg isr_attribute_args [] =
function, or ARM_FT_UNKNOWN if the type cannot be determined. */
static unsigned long
-arm_isr_value (argument)
- tree argument;
+arm_isr_value (tree argument)
{
const isr_attribute_arg * ptr;
const char * arg;
@@ -834,7 +940,7 @@ arm_isr_value (argument)
arg = TREE_STRING_POINTER (TREE_VALUE (argument));
/* Check it against the list of known arguments. */
- for (ptr = isr_attribute_args; ptr->arg != NULL; ptr ++)
+ for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++)
if (streq (arg, ptr->arg))
return ptr->return_value;
@@ -845,7 +951,7 @@ arm_isr_value (argument)
/* Computes the type of the current function. */
static unsigned long
-arm_compute_func_type ()
+arm_compute_func_type (void)
{
unsigned long type = ARM_FT_UNKNOWN;
tree a;
@@ -892,7 +998,7 @@ arm_compute_func_type ()
/* Returns the type of the current function. */
unsigned long
-arm_current_func_type ()
+arm_current_func_type (void)
{
if (ARM_FUNC_TYPE (cfun->machine->func_type) == ARM_FT_UNKNOWN)
cfun->machine->func_type = arm_compute_func_type ();
@@ -900,20 +1006,22 @@ arm_current_func_type ()
return cfun->machine->func_type;
}
-/* Return 1 if it is possible to return using a single instruction. */
+/* Return 1 if it is possible to return using a single instruction.
+ If SIBLING is non-null, this is a test for a return before a sibling
+ call. SIBLING is the call insn, so we can examine its register usage. */
int
-use_return_insn (iscond)
- int iscond;
+use_return_insn (int iscond, rtx sibling)
{
int regno;
unsigned int func_type;
unsigned long saved_int_regs;
+ unsigned HOST_WIDE_INT stack_adjust;
/* Never use a return instruction before reload has run. */
if (!reload_completed)
return 0;
-
+
func_type = arm_current_func_type ();
/* Naked functions and volatile functions need special
@@ -924,19 +1032,61 @@ use_return_insn (iscond)
/* So do interrupt functions that use the frame pointer. */
if (IS_INTERRUPT (func_type) && frame_pointer_needed)
return 0;
-
+
+ stack_adjust = arm_get_frame_size () + current_function_outgoing_args_size;
+
/* As do variadic functions. */
if (current_function_pretend_args_size
|| cfun->machine->uses_anonymous_args
- /* Of if the function calls __builtin_eh_return () */
+ /* Or if the function calls __builtin_eh_return () */
|| ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
- /* Or if there is no frame pointer and there is a stack adjustment. */
- || ((arm_get_frame_size () + current_function_outgoing_args_size != 0)
- && !frame_pointer_needed))
+ /* Or if the function calls alloca */
+ || current_function_calls_alloca
+ /* Or if there is a stack adjustment. However, if the stack pointer
+ is saved on the stack, we can use a pre-incrementing stack load. */
+ || !(stack_adjust == 0 || (frame_pointer_needed && stack_adjust == 4)))
return 0;
saved_int_regs = arm_compute_save_reg_mask ();
+ /* Unfortunately, the insn
+
+ ldmib sp, {..., sp, ...}
+
+ triggers a bug on most SA-110 based devices, such that the stack
+ pointer won't be correctly restored if the instruction takes a
+ page fault. We work around this problem by popping r3 along with
+ the other registers, since that is never slower than executing
+ another instruction.
+
+ We test for !arm_arch5 here, because code for any architecture
+ less than this could potentially be run on one of the buggy
+ chips. */
+ if (stack_adjust == 4 && !arm_arch5)
+ {
+ /* Validate that r3 is a call-clobbered register (always true in
+ the default abi) ... */
+ if (!call_used_regs[3])
+ return 0;
+
+ /* ... that it isn't being used for a return value (always true
+ until we implement return-in-regs), or for a tail-call
+ argument ... */
+ if (sibling)
+ {
+ if (GET_CODE (sibling) != CALL_INSN)
+ abort ();
+
+ if (find_regno_fusage (sibling, USE, 3))
+ return 0;
+ }
+
+ /* ... and that there are no call-saved registers in r0-r2
+ (always true in the default ABI). */
+ if (saved_int_regs & 0x7)
+ return 0;
+ }
+
/* Can't be done if interworking with Thumb, and any registers have been
stacked. */
if (TARGET_INTERWORK && saved_int_regs != 0)
@@ -960,21 +1110,25 @@ use_return_insn (iscond)
if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM)))
return 0;
- /* Can't be done if any of the FPU regs are pushed,
+ /* Can't be done if any of the FPA regs are pushed,
since this also requires an insn. */
if (TARGET_HARD_FLOAT)
for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++)
if (regs_ever_live[regno] && !call_used_regs[regno])
return 0;
+ if (TARGET_REALLY_IWMMXT)
+ for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
+ if (regs_ever_live[regno] && ! call_used_regs [regno])
+ return 0;
+
return 1;
}
/* Return TRUE if int I is a valid immediate ARM constant. */
int
-const_ok_for_arm (i)
- HOST_WIDE_INT i;
+const_ok_for_arm (HOST_WIDE_INT i)
{
unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT)0xFF;
@@ -1005,9 +1159,7 @@ const_ok_for_arm (i)
/* Return true if I is a valid constant for the operation CODE. */
static int
-const_ok_for_op (i, code)
- HOST_WIDE_INT i;
- enum rtx_code code;
+const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
{
if (const_ok_for_arm (i))
return 1;
@@ -1041,13 +1193,8 @@ const_ok_for_op (i, code)
Return value is the number of insns emitted. */
int
-arm_split_constant (code, mode, val, target, source, subtargets)
- enum rtx_code code;
- enum machine_mode mode;
- HOST_WIDE_INT val;
- rtx target;
- rtx source;
- int subtargets;
+arm_split_constant (enum rtx_code code, enum machine_mode mode,
+ HOST_WIDE_INT val, rtx target, rtx source, int subtargets)
{
if (subtargets || code == SET
|| (GET_CODE (target) == REG && GET_CODE (source) == REG
@@ -1095,9 +1242,7 @@ arm_split_constant (code, mode, val, target, source, subtargets)
}
static int
-count_insns_for_constant (remainder, i)
- HOST_WIDE_INT remainder;
- int i;
+count_insns_for_constant (HOST_WIDE_INT remainder, int i)
{
HOST_WIDE_INT temp1;
int num_insns = 0;
@@ -1127,14 +1272,9 @@ count_insns_for_constant (remainder, i)
RTL generation. */
static int
-arm_gen_constant (code, mode, val, target, source, subtargets, generate)
- enum rtx_code code;
- enum machine_mode mode;
- HOST_WIDE_INT val;
- rtx target;
- rtx source;
- int subtargets;
- int generate;
+arm_gen_constant (enum rtx_code code, enum machine_mode mode,
+ HOST_WIDE_INT val, rtx target, rtx source, int subtargets,
+ int generate)
{
int can_invert = 0;
int can_negate = 0;
@@ -1709,9 +1849,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
immediate value easier to load. */
enum rtx_code
-arm_canonicalize_comparison (code, op1)
- enum rtx_code code;
- rtx * op1;
+arm_canonicalize_comparison (enum rtx_code code, rtx * op1)
{
unsigned HOST_WIDE_INT i = INTVAL (*op1);
@@ -1771,10 +1909,8 @@ arm_canonicalize_comparison (code, op1)
/* Decide whether a type should be returned in memory (true)
or in a register (false). This is called by the macro
RETURN_IN_MEMORY. */
-
int
-arm_return_in_memory (type)
- tree type;
+arm_return_in_memory (tree type)
{
HOST_WIDE_INT size;
@@ -1791,12 +1927,12 @@ arm_return_in_memory (type)
return (size < 0 || size > UNITS_PER_WORD);
}
- /* For the arm-wince targets we choose to be compitable with Microsoft's
+ /* For the arm-wince targets we choose to be compatible with Microsoft's
ARM and Thumb compilers, which always return aggregates in memory. */
#ifndef ARM_WINCE
/* All structures/unions bigger than one word are returned in memory.
Also catch the case where int_size_in_bytes returns -1. In this case
- the aggregate is either huge or of varaible size, and in either case
+ the aggregate is either huge or of variable size, and in either case
we will want to return it via memory and not in a register. */
if (size < 0 || size > UNITS_PER_WORD)
return 1;
@@ -1876,11 +2012,13 @@ arm_return_in_memory (type)
return 1;
}
-/* Indicate whether or not words of a double are in big-endian order. */
+/* Indicate whether or not words of a double are in big-endian order. */
int
-arm_float_words_big_endian ()
+arm_float_words_big_endian (void)
{
+ if (TARGET_CIRRUS)
+ return 0;
/* For FPA, float words are always big-endian. For VFP, floats words
follow the memory system mode. */
@@ -1901,14 +2039,13 @@ arm_float_words_big_endian ()
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is NULL. */
void
-arm_init_cumulative_args (pcum, fntype, libname, indirect)
- CUMULATIVE_ARGS * pcum;
- tree fntype;
- rtx libname ATTRIBUTE_UNUSED;
- int indirect ATTRIBUTE_UNUSED;
+arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
+ rtx libname ATTRIBUTE_UNUSED,
+ tree fndecl ATTRIBUTE_UNUSED)
{
/* On the ARM, the offset starts at 0. */
- pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype))) ? 1 : 0);
+ pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype), fntype)) ? 1 : 0);
+ pcum->iwmmxt_nregs = 0;
pcum->call_cookie = CALL_NORMAL;
@@ -1924,6 +2061,24 @@ arm_init_cumulative_args (pcum, fntype, libname, indirect)
else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (fntype)))
pcum->call_cookie = CALL_LONG;
}
+
+ /* Varargs vectors are treated the same as long long.
+ named_count avoids having to change the way arm handles 'named' */
+ pcum->named_count = 0;
+ pcum->nargs = 0;
+
+ if (TARGET_REALLY_IWMMXT && fntype)
+ {
+ tree fn_arg;
+
+ for (fn_arg = TYPE_ARG_TYPES (fntype);
+ fn_arg;
+ fn_arg = TREE_CHAIN (fn_arg))
+ pcum->named_count += 1;
+
+ if (! pcum->named_count)
+ pcum->named_count = INT_MAX;
+ }
}
/* Determine where to put an argument to a function.
@@ -1940,12 +2095,33 @@ arm_init_cumulative_args (pcum, fntype, libname, indirect)
(otherwise it is an extra parameter matching an ellipsis). */
rtx
-arm_function_arg (pcum, mode, type, named)
- CUMULATIVE_ARGS * pcum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named;
+arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED, int named)
{
+ if (TARGET_REALLY_IWMMXT)
+ {
+ if (VECTOR_MODE_SUPPORTED_P (mode))
+ {
+ /* varargs vectors are treated the same as long long.
+ named_count avoids having to change the way arm handles 'named' */
+ if (pcum->named_count <= pcum->nargs + 1)
+ {
+ if (pcum->nregs == 1)
+ pcum->nregs += 1;
+ if (pcum->nregs <= 2)
+ return gen_rtx_REG (mode, pcum->nregs);
+ else
+ return NULL_RTX;
+ }
+ else if (pcum->iwmmxt_nregs <= 9)
+ return gen_rtx_REG (mode, pcum->iwmmxt_nregs + FIRST_IWMMXT_REGNUM);
+ else
+ return NULL_RTX;
+ }
+ else if ((mode == DImode || mode == DFmode) && pcum->nregs & 1)
+ pcum->nregs += 1;
+ }
+
if (mode == VOIDmode)
/* Compute operand 2 of the call insn. */
return GEN_INT (pcum->call_cookie);
@@ -1960,11 +2136,9 @@ arm_function_arg (pcum, mode, type, named)
extension to the ARM ABI. */
int
-arm_function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type;
- int named ATTRIBUTE_UNUSED;
+arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, int named ATTRIBUTE_UNUSED)
{
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
}
@@ -1972,8 +2146,7 @@ arm_function_arg_pass_by_reference (cum, mode, type, named)
/* Implement va_arg. */
rtx
-arm_va_arg (valist, type)
- tree valist, type;
+arm_va_arg (tree valist, tree type)
{
/* Variable sized types are passed by reference. */
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
@@ -1982,6 +2155,26 @@ arm_va_arg (valist, type)
return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
}
+ if (FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), NULL) == IWMMXT_ALIGNMENT)
+ {
+ tree minus_eight;
+ tree t;
+
+ /* Maintain 64-bit alignment of the valist pointer by
+ constructing: valist = ((valist + (8 - 1)) & -8). */
+ minus_eight = build_int_2 (- (IWMMXT_ALIGNMENT / BITS_PER_UNIT), -1);
+ t = build_int_2 ((IWMMXT_ALIGNMENT / BITS_PER_UNIT) - 1, 0);
+ t = build (PLUS_EXPR, TREE_TYPE (valist), valist, t);
+ t = build (BIT_AND_EXPR, TREE_TYPE (t), t, minus_eight);
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+ /* This is to stop the combine pass optimizing
+ away the alignment adjustment. */
+ mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
+ }
+
return std_expand_builtin_va_arg (valist, type);
}
@@ -1996,22 +2189,19 @@ typedef enum
static arm_pragma_enum arm_pragma_long_calls = OFF;
void
-arm_pr_long_calls (pfile)
- cpp_reader * pfile ATTRIBUTE_UNUSED;
+arm_pr_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
{
arm_pragma_long_calls = LONG;
}
void
-arm_pr_no_long_calls (pfile)
- cpp_reader * pfile ATTRIBUTE_UNUSED;
+arm_pr_no_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
{
arm_pragma_long_calls = SHORT;
}
void
-arm_pr_long_calls_off (pfile)
- cpp_reader * pfile ATTRIBUTE_UNUSED;
+arm_pr_long_calls_off (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
{
arm_pragma_long_calls = OFF;
}
@@ -2050,14 +2240,9 @@ const struct attribute_spec arm_attribute_table[] =
/* Handle an attribute requiring a FUNCTION_DECL;
arguments as in struct attribute_spec.handler. */
-
static tree
-arm_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
- tree * node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool * no_add_attrs;
+arm_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_DECL)
{
@@ -2071,14 +2256,9 @@ arm_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
/* Handle an "interrupt" or "isr" attribute;
arguments as in struct attribute_spec.handler. */
-
static tree
-arm_handle_isr_attribute (node, name, args, flags, no_add_attrs)
- tree * node;
- tree name;
- tree args;
- int flags;
- bool * no_add_attrs;
+arm_handle_isr_attribute (tree *node, tree name, tree args, int flags,
+ bool *no_add_attrs)
{
if (DECL_P (*node))
{
@@ -2136,11 +2316,8 @@ arm_handle_isr_attribute (node, name, args, flags, no_add_attrs)
/* Return 0 if the attributes for two types are incompatible, 1 if they
are compatible, and 2 if they are nearly compatible (which causes a
warning to be generated). */
-
static int
-arm_comp_type_attributes (type1, type2)
- tree type1;
- tree type2;
+arm_comp_type_attributes (tree type1, tree type2)
{
int l1, l2, s1, s2;
@@ -2181,11 +2358,8 @@ arm_comp_type_attributes (type1, type2)
/* Encode long_call or short_call attribute by prefixing
symbol name in DECL with a special character FLAG. */
-
void
-arm_encode_call_attribute (decl, flag)
- tree decl;
- int flag;
+arm_encode_call_attribute (tree decl, int flag)
{
const char * str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
int len = strlen (str);
@@ -2206,10 +2380,8 @@ arm_encode_call_attribute (decl, flag)
/* Assigns default attributes to newly defined type. This is used to
set short_call/long_call attributes for function types of
functions defined inside corresponding #pragma scopes. */
-
static void
-arm_set_default_type_attributes (type)
- tree type;
+arm_set_default_type_attributes (tree type)
{
/* Add __attribute__ ((long_call)) to all functions, when
inside #pragma long_calls or __attribute__ ((short_call)),
@@ -2232,12 +2404,10 @@ arm_set_default_type_attributes (type)
}
/* Return 1 if the operand is a SYMBOL_REF for a function known to be
- defined within the current compilation unit. If this caanot be
+ defined within the current compilation unit. If this cannot be
determined, then 0 is returned. */
-
static int
-current_file_function_operand (sym_ref)
- rtx sym_ref;
+current_file_function_operand (rtx sym_ref)
{
/* This is a bit of a fib. A function will have a short call flag
applied to its name if it has the short call attribute, or it has
@@ -2277,12 +2447,8 @@ current_file_function_operand (sym_ref)
"call_symbol" and "call_symbol_value" patterns and to 0 in the "call"
and "call_value" patterns. This is because of the difference in the
SYM_REFs passed by these patterns. */
-
int
-arm_is_longcall_p (sym_ref, call_cookie, call_symbol)
- rtx sym_ref;
- int call_cookie;
- int call_symbol;
+arm_is_longcall_p (rtx sym_ref, int call_cookie, int call_symbol)
{
if (!call_symbol)
{
@@ -2310,17 +2476,18 @@ arm_is_longcall_p (sym_ref, call_cookie, call_symbol)
}
/* Return nonzero if it is ok to make a tail-call to DECL. */
-
-int
-arm_function_ok_for_sibcall (decl)
- tree decl;
+static bool
+arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
int call_type = TARGET_LONG_CALLS ? CALL_LONG : CALL_NORMAL;
+ if (cfun->machine->sibcall_blocked)
+ return false;
+
/* Never tailcall something for which we have no decl, or if we
are in Thumb mode. */
if (decl == NULL || TARGET_THUMB)
- return 0;
+ return false;
/* Get the calling method. */
if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
@@ -2332,26 +2499,29 @@ arm_function_ok_for_sibcall (decl)
a branch instruction. However, if not compiling PIC, we know
we can reach the symbol if it is in this compilation unit. */
if (call_type == CALL_LONG && (flag_pic || !TREE_ASM_WRITTEN (decl)))
- return 0;
+ return false;
/* If we are interworking and the function is not declared static
then we can't tail-call it unless we know that it exists in this
compilation unit (since it might be a Thumb routine). */
if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl))
- return 0;
+ return false;
/* Never tailcall from an ISR routine - it needs a special exit sequence. */
if (IS_INTERRUPT (arm_current_func_type ()))
- return 0;
+ return false;
/* Everything else is ok. */
- return 1;
+ return true;
}
+/* Addressing mode support functions. */
+
+/* Return nonzero if X is a legitimate immediate operand when compiling
+ for PIC. */
int
-legitimate_pic_operand_p (x)
- rtx x;
+legitimate_pic_operand_p (rtx x)
{
if (CONSTANT_P (x)
&& flag_pic
@@ -2365,10 +2535,7 @@ legitimate_pic_operand_p (x)
}
rtx
-legitimize_pic_address (orig, mode, reg)
- rtx orig;
- enum machine_mode mode;
- rtx reg;
+legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{
if (GET_CODE (orig) == SYMBOL_REF
|| GET_CODE (orig) == LABEL_REF)
@@ -2406,7 +2573,7 @@ legitimize_pic_address (orig, mode, reg)
if ((GET_CODE (orig) == LABEL_REF
|| (GET_CODE (orig) == SYMBOL_REF &&
- ENCODED_SHORT_CALL_ATTR_P (XSTR (orig, 0))))
+ SYMBOL_REF_LOCAL_P (orig)))
&& NEED_GOT_RELOC)
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
else
@@ -2455,14 +2622,14 @@ legitimize_pic_address (orig, mode, reg)
{
/* The base register doesn't really matter, we only want to
test the index for the appropriate mode. */
- ARM_GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
-
- if (!no_new_pseudos)
- offset = force_reg (Pmode, offset);
- else
- abort ();
+ if (!arm_legitimate_index_p (mode, offset, 0))
+ {
+ if (!no_new_pseudos)
+ offset = force_reg (Pmode, offset);
+ else
+ abort ();
+ }
- win:
if (GET_CODE (offset) == CONST_INT)
return plus_constant (base, INTVAL (offset));
}
@@ -2486,10 +2653,8 @@ legitimize_pic_address (orig, mode, reg)
generated insns at the start of the function); false if called
by an exception receiver that needs the PIC register reloaded
(in which case the insns are just dumped at the current location). */
-
void
-arm_finalize_pic (prologue)
- int prologue ATTRIBUTE_UNUSED;
+arm_finalize_pic (int prologue ATTRIBUTE_UNUSED)
{
#ifndef AOF_ASSEMBLER
rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx;
@@ -2540,6 +2705,417 @@ arm_finalize_pic (prologue)
#endif /* AOF_ASSEMBLER */
}
+/* Return nonzero if X is valid as an ARM state addressing register. */
+static int
+arm_address_register_rtx_p (rtx x, int strict_p)
+{
+ int regno;
+
+ if (GET_CODE (x) != REG)
+ return 0;
+
+ regno = REGNO (x);
+
+ if (strict_p)
+ return ARM_REGNO_OK_FOR_BASE_P (regno);
+
+ return (regno <= LAST_ARM_REGNUM
+ || regno >= FIRST_PSEUDO_REGISTER
+ || regno == FRAME_POINTER_REGNUM
+ || regno == ARG_POINTER_REGNUM);
+}
+
+/* Return nonzero if X is a valid ARM state address operand. */
+int
+arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
+{
+ if (arm_address_register_rtx_p (x, strict_p))
+ return 1;
+
+ else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
+ return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
+
+ else if ((GET_CODE (x) == POST_MODIFY || GET_CODE (x) == PRE_MODIFY)
+ && GET_MODE_SIZE (mode) <= 4
+ && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
+ && GET_CODE (XEXP (x, 1)) == PLUS
+ && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
+ return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), strict_p);
+
+ /* After reload constants split into minipools will have addresses
+ from a LABEL_REF. */
+ else if (reload_completed
+ && (GET_CODE (x) == LABEL_REF
+ || (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
+ return 1;
+
+ else if (mode == TImode)
+ return 0;
+
+ else if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
+ {
+ if (GET_CODE (x) == PLUS
+ && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+
+ if (val == 4 || val == -4 || val == -8)
+ return 1;
+ }
+ }
+
+ else if (GET_CODE (x) == PLUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ return ((arm_address_register_rtx_p (xop0, strict_p)
+ && arm_legitimate_index_p (mode, xop1, strict_p))
+ || (arm_address_register_rtx_p (xop1, strict_p)
+ && arm_legitimate_index_p (mode, xop0, strict_p)));
+ }
+
+#if 0
+ /* Reload currently can't handle MINUS, so disable this for now */
+ else if (GET_CODE (x) == MINUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ return (arm_address_register_rtx_p (xop0, strict_p)
+ && arm_legitimate_index_p (mode, xop1, strict_p));
+ }
+#endif
+
+ else if (GET_MODE_CLASS (mode) != MODE_FLOAT
+ && GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x)
+ && ! (flag_pic
+ && symbol_mentioned_p (get_pool_constant (x))))
+ return 1;
+
+ else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_DEC)
+ && (GET_MODE_SIZE (mode) <= 4)
+ && arm_address_register_rtx_p (XEXP (x, 0), strict_p))
+ return 1;
+
+ return 0;
+}
+
+/* Return nonzero if INDEX is valid for an address index operand in
+ ARM state. */
+static int
+arm_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
+{
+ HOST_WIDE_INT range;
+ enum rtx_code code = GET_CODE (index);
+
+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ return (code == CONST_INT && INTVAL (index) < 1024
+ && INTVAL (index) > -1024
+ && (INTVAL (index) & 3) == 0);
+
+ if (TARGET_CIRRUS
+ && (GET_MODE_CLASS (mode) == MODE_FLOAT || mode == DImode))
+ return (code == CONST_INT
+ && INTVAL (index) < 255
+ && INTVAL (index) > -255);
+
+ if (arm_address_register_rtx_p (index, strict_p)
+ && GET_MODE_SIZE (mode) <= 4)
+ return 1;
+
+ if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
+ return (code == CONST_INT
+ && INTVAL (index) < 256
+ && INTVAL (index) > -256);
+
+ /* XXX What about ldrsb? */
+ if (GET_MODE_SIZE (mode) <= 4 && code == MULT
+ && (!arm_arch4 || (mode) != HImode))
+ {
+ rtx xiop0 = XEXP (index, 0);
+ rtx xiop1 = XEXP (index, 1);
+
+ return ((arm_address_register_rtx_p (xiop0, strict_p)
+ && power_of_two_operand (xiop1, SImode))
+ || (arm_address_register_rtx_p (xiop1, strict_p)
+ && power_of_two_operand (xiop0, SImode)));
+ }
+
+ if (GET_MODE_SIZE (mode) <= 4
+ && (code == LSHIFTRT || code == ASHIFTRT
+ || code == ASHIFT || code == ROTATERT)
+ && (!arm_arch4 || (mode) != HImode))
+ {
+ rtx op = XEXP (index, 1);
+
+ return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
+ && GET_CODE (op) == CONST_INT
+ && INTVAL (op) > 0
+ && INTVAL (op) <= 31);
+ }
+
+ /* XXX For ARM v4 we may be doing a sign-extend operation during the
+ load, but that has a restricted addressing range and we are unable
+ to tell here whether that is the case. To be safe we restrict all
+ loads to that range. */
+ if (arm_arch4)
+ range = (mode == HImode || mode == QImode) ? 256 : 4096;
+ else
+ range = (mode == HImode) ? 4095 : 4096;
+
+ return (code == CONST_INT
+ && INTVAL (index) < range
+ && INTVAL (index) > -range);
+}
+
+/* Return nonzero if X is valid as a Thumb state base register. */
+static int
+thumb_base_register_rtx_p (rtx x, enum machine_mode mode, int strict_p)
+{
+ int regno;
+
+ if (GET_CODE (x) != REG)
+ return 0;
+
+ regno = REGNO (x);
+
+ if (strict_p)
+ return THUMB_REGNO_MODE_OK_FOR_BASE_P (regno, mode);
+
+ return (regno <= LAST_LO_REGNUM
+ || regno > LAST_VIRTUAL_REGISTER
+ || regno == FRAME_POINTER_REGNUM
+ || (GET_MODE_SIZE (mode) >= 4
+ && (regno == STACK_POINTER_REGNUM
+ || regno >= FIRST_PSEUDO_REGISTER
+ || x == hard_frame_pointer_rtx
+ || x == arg_pointer_rtx)));
+}
+
+/* Return nonzero if x is a legitimate index register. This is the case
+ for any base register that can access a QImode object. */
+inline static int
+thumb_index_register_rtx_p (rtx x, int strict_p)
+{
+ return thumb_base_register_rtx_p (x, QImode, strict_p);
+}
+
+/* Return nonzero if x is a legitimate Thumb-state address.
+
+ The AP may be eliminated to either the SP or the FP, so we use the
+ least common denominator, e.g. SImode, and offsets from 0 to 64.
+
+ ??? Verify whether the above is the right approach.
+
+ ??? Also, the FP may be eliminated to the SP, so perhaps that
+ needs special handling also.
+
+ ??? Look at how the mips16 port solves this problem. It probably uses
+ better ways to solve some of these problems.
+
+ Although it is not incorrect, we don't accept QImode and HImode
+ addresses based on the frame pointer or arg pointer until the
+ reload pass starts. This is so that eliminating such addresses
+ into stack based ones won't produce impossible code. */
+int
+thumb_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
+{
+ /* ??? Not clear if this is right. Experiment. */
+ if (GET_MODE_SIZE (mode) < 4
+ && !(reload_in_progress || reload_completed)
+ && (reg_mentioned_p (frame_pointer_rtx, x)
+ || reg_mentioned_p (arg_pointer_rtx, x)
+ || reg_mentioned_p (virtual_incoming_args_rtx, x)
+ || reg_mentioned_p (virtual_outgoing_args_rtx, x)
+ || reg_mentioned_p (virtual_stack_dynamic_rtx, x)
+ || reg_mentioned_p (virtual_stack_vars_rtx, x)))
+ return 0;
+
+ /* Accept any base register. SP only in SImode or larger. */
+ else if (thumb_base_register_rtx_p (x, mode, strict_p))
+ return 1;
+
+ /* This is PC relative data before arm_reorg runs. */
+ else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
+ && GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x) && ! flag_pic)
+ return 1;
+
+ /* This is PC relative data after arm_reorg runs. */
+ else if (GET_MODE_SIZE (mode) >= 4 && reload_completed
+ && (GET_CODE (x) == LABEL_REF
+ || (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
+ return 1;
+
+ /* Post-inc indexing only supported for SImode and larger. */
+ else if (GET_CODE (x) == POST_INC && GET_MODE_SIZE (mode) >= 4
+ && thumb_index_register_rtx_p (XEXP (x, 0), strict_p))
+ return 1;
+
+ else if (GET_CODE (x) == PLUS)
+ {
+ /* REG+REG address can be any two index registers. */
+ /* We disallow FRAME+REG addressing since we know that FRAME
+ will be replaced with STACK, and SP relative addressing only
+ permits SP+OFFSET. */
+ if (GET_MODE_SIZE (mode) <= 4
+ && XEXP (x, 0) != frame_pointer_rtx
+ && XEXP (x, 1) != frame_pointer_rtx
+ && thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
+ && thumb_index_register_rtx_p (XEXP (x, 1), strict_p))
+ return 1;
+
+ /* REG+const has 5-7 bit offset for non-SP registers. */
+ else if ((thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
+ || XEXP (x, 0) == arg_pointer_rtx)
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
+ return 1;
+
+ /* REG+const has 10 bit offset for SP, but only SImode and
+ larger is supported. */
+ /* ??? Should probably check for DI/DFmode overflow here
+ just like GO_IF_LEGITIMATE_OFFSET does. */
+ else if (GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM
+ && GET_MODE_SIZE (mode) >= 4
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && INTVAL (XEXP (x, 1)) >= 0
+ && INTVAL (XEXP (x, 1)) + GET_MODE_SIZE (mode) <= 1024
+ && (INTVAL (XEXP (x, 1)) & 3) == 0)
+ return 1;
+
+ else if (GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
+ && GET_MODE_SIZE (mode) >= 4
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) & 3) == 0)
+ return 1;
+ }
+
+ else if (GET_MODE_CLASS (mode) != MODE_FLOAT
+ && GET_MODE_SIZE (mode) == 4
+ && GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x)
+ && !(flag_pic
+ && symbol_mentioned_p (get_pool_constant (x))))
+ return 1;
+
+ return 0;
+}
+
+/* Return nonzero if VAL can be used as an offset in a Thumb-state address
+ instruction of mode MODE. */
+int
+thumb_legitimate_offset_p (enum machine_mode mode, HOST_WIDE_INT val)
+{
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 1:
+ return val >= 0 && val < 32;
+
+ case 2:
+ return val >= 0 && val < 64 && (val & 1) == 0;
+
+ default:
+ return (val >= 0
+ && (val + GET_MODE_SIZE (mode)) <= 128
+ && (val & 3) == 0);
+ }
+}
+
+/* Try machine-dependent ways of modifying an illegitimate address
+ to be legitimate. If we find one, return the new, valid address. */
+rtx
+arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
+{
+ if (GET_CODE (x) == PLUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
+ xop0 = force_reg (SImode, xop0);
+
+ if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
+ xop1 = force_reg (SImode, xop1);
+
+ if (ARM_BASE_REGISTER_RTX_P (xop0)
+ && GET_CODE (xop1) == CONST_INT)
+ {
+ HOST_WIDE_INT n, low_n;
+ rtx base_reg, val;
+ n = INTVAL (xop1);
+
+ if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
+ {
+ low_n = n & 0x0f;
+ n &= ~0x0f;
+ if (low_n > 4)
+ {
+ n += 16;
+ low_n -= 16;
+ }
+ }
+ else
+ {
+ low_n = ((mode) == TImode ? 0
+ : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
+ n -= low_n;
+ }
+
+ base_reg = gen_reg_rtx (SImode);
+ val = force_operand (gen_rtx_PLUS (SImode, xop0,
+ GEN_INT (n)), NULL_RTX);
+ emit_move_insn (base_reg, val);
+ x = (low_n == 0 ? base_reg
+ : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));
+ }
+ else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+ x = gen_rtx_PLUS (SImode, xop0, xop1);
+ }
+
+ /* XXX We don't allow MINUS any more -- see comment in
+ arm_legitimate_address_p (). */
+ else if (GET_CODE (x) == MINUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ if (CONSTANT_P (xop0))
+ xop0 = force_reg (SImode, xop0);
+
+ if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
+ xop1 = force_reg (SImode, xop1);
+
+ if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+ x = gen_rtx_MINUS (SImode, xop0, xop1);
+ }
+
+ if (flag_pic)
+ {
+ /* We need to find and carefully transform any SYMBOL and LABEL
+ references; so go back to the original address expression. */
+ rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
+
+ if (new_x != orig_x)
+ x = new_x;
+ }
+
+ return x;
+}
+
+
+
#define REG_OR_SUBREG_REG(X) \
(GET_CODE (X) == REG \
|| (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
@@ -2550,12 +3126,9 @@ arm_finalize_pic (prologue)
#ifndef COSTS_N_INSNS
#define COSTS_N_INSNS(N) ((N) * 4 - 2)
#endif
-
-int
-arm_rtx_costs (x, code, outer)
- rtx x;
- enum rtx_code code;
- enum rtx_code outer;
+/* Worker routine for arm_rtx_costs. */
+static inline int
+arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
{
enum machine_mode mode = GET_MODE (x);
enum rtx_code subcode;
@@ -2605,12 +3178,12 @@ arm_rtx_costs (x, code, outer)
return COSTS_N_INSNS (2);
return COSTS_N_INSNS (3);
}
- else if (outer == PLUS
+ else if ((outer == PLUS || outer == COMPARE)
&& INTVAL (x) < 256 && INTVAL (x) > -256)
- return 0;
- else if (outer == COMPARE
- && (unsigned HOST_WIDE_INT) INTVAL (x) < 256)
- return 0;
+ return 0;
+ else if (outer == AND
+ && INTVAL (x) < 256 && INTVAL (x) >= -256)
+ return COSTS_N_INSNS (1);
else if (outer == ASHIFT || outer == ASHIFTRT
|| outer == LSHIFTRT)
return 0;
@@ -2634,7 +3207,7 @@ arm_rtx_costs (x, code, outer)
case AND:
case XOR:
case IOR:
- /* XXX guess. */
+ /* XXX guess. */
return 8;
case ADDRESSOF:
@@ -2647,7 +3220,7 @@ arm_rtx_costs (x, code, outer)
? 4 : 0));
case IF_THEN_ELSE:
- /* XXX a guess. */
+ /* XXX a guess. */
if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
return 14;
return 2;
@@ -2673,16 +3246,6 @@ arm_rtx_costs (x, code, outer)
default:
return 99;
-#if 0
- case FFS:
- case FLOAT:
- case FIX:
- case UNSIGNED_FIX:
- /* XXX guess */
- fprintf (stderr, "unexpected code for thumb in rtx_costs: %s\n",
- rtx_name[code]);
- abort ();
-#endif
}
}
@@ -2697,7 +3260,9 @@ arm_rtx_costs (x, code, outer)
case DIV:
case MOD:
- return 100;
+ case UDIV:
+ case UMOD:
+ return optimize_size ? COSTS_N_INSNS (2) : 100;
case ROTATE:
if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
@@ -2735,11 +3300,11 @@ arm_rtx_costs (x, code, outer)
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
|| (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
- && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
+ && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
? 0 : 8)
+ ((REG_OR_SUBREG_REG (XEXP (x, 0))
|| (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
- && const_double_rtx_ok_for_fpu (XEXP (x, 0))))
+ && const_double_rtx_ok_for_fpa (XEXP (x, 0))))
? 0 : 8));
if (((GET_CODE (XEXP (x, 0)) == CONST_INT
@@ -2764,7 +3329,7 @@ arm_rtx_costs (x, code, outer)
return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
+ ((REG_OR_SUBREG_REG (XEXP (x, 1))
|| (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
- && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
+ && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
? 0 : 8));
/* Fall through */
@@ -2830,19 +3395,41 @@ arm_rtx_costs (x, code, outer)
{
unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
& (unsigned HOST_WIDE_INT) 0xffffffff);
- int add_cost = const_ok_for_arm (i) ? 4 : 8;
- int j;
+ int cost, const_ok = const_ok_for_arm (i);
+ int j, booth_unit_size;
+
+ if (arm_tune_xscale)
+ {
+ unsigned HOST_WIDE_INT masked_const;
+
+ /* The cost will be related to two insns.
+ First a load of the constant (MOV or LDR), then a multiply. */
+ cost = 2;
+ if (! const_ok)
+ cost += 1; /* LDR is probably more expensive because
+ of longer result latency. */
+ masked_const = i & 0xffff8000;
+ if (masked_const != 0 && masked_const != 0xffff8000)
+ {
+ masked_const = i & 0xf8000000;
+ if (masked_const == 0 || masked_const == 0xf8000000)
+ cost += 1;
+ else
+ cost += 2;
+ }
+ return cost;
+ }
/* Tune as appropriate. */
- int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
-
+ cost = const_ok ? 4 : 8;
+ booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
for (j = 0; i && j < 32; j += booth_unit_size)
{
i >>= booth_unit_size;
- add_cost += 2;
+ cost += 2;
}
- return add_cost;
+ return cost;
}
return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
@@ -2900,6 +3487,13 @@ arm_rtx_costs (x, code, outer)
case SImode:
return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
+ case V8QImode:
+ case V4HImode:
+ case V2SImode:
+ case V4QImode:
+ case V2HImode:
+ return 1;
+
default:
break;
}
@@ -2924,10 +3518,10 @@ arm_rtx_costs (x, code, outer)
return 6;
case CONST_DOUBLE:
- if (const_double_rtx_ok_for_fpu (x))
+ if (const_double_rtx_ok_for_fpa (x))
return outer == SET ? 2 : -1;
else if ((outer == COMPARE || outer == PLUS)
- && neg_const_double_rtx_ok_for_fpu (x))
+ && neg_const_double_rtx_ok_for_fpa (x))
return -1;
return 7;
@@ -2936,21 +3530,82 @@ arm_rtx_costs (x, code, outer)
}
}
+static bool
+arm_rtx_costs (rtx x, int code, int outer_code, int *total)
+{
+ *total = arm_rtx_costs_1 (x, code, outer_code);
+ return true;
+}
+
+/* All address computations that can be done are free, but rtx cost returns
+ the same for practically all of them. So we weight the different types
+ of address here in the order (most pref first):
+ PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
+static inline int
+arm_arm_address_cost (rtx x)
+{
+ enum rtx_code c = GET_CODE (x);
+
+ if (c == PRE_INC || c == PRE_DEC || c == POST_INC || c == POST_DEC)
+ return 0;
+ if (c == MEM || c == LABEL_REF || c == SYMBOL_REF)
+ return 10;
+
+ if (c == PLUS || c == MINUS)
+ {
+ char cl0 = GET_RTX_CLASS (GET_CODE (XEXP (x, 0)));
+ char cl1 = GET_RTX_CLASS (GET_CODE (XEXP (x, 1)));
+
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT)
+ return 2;
+
+ if (cl0 == '2' || cl0 == 'c' || cl1 == '2' || cl1 == 'c')
+ return 3;
+
+ return 4;
+ }
+
+ return 6;
+}
+
+static inline int
+arm_thumb_address_cost (rtx x)
+{
+ enum rtx_code c = GET_CODE (x);
+
+ if (c == REG)
+ return 1;
+ if (c == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ return 1;
+
+ return 2;
+}
+
+static int
+arm_address_cost (rtx x)
+{
+ return TARGET_ARM ? arm_arm_address_cost (x) : arm_thumb_address_cost (x);
+}
+
+static int
+arm_use_dfa_pipeline_interface (void)
+{
+ return true;
+}
+
static int
-arm_adjust_cost (insn, link, dep, cost)
- rtx insn;
- rtx link;
- rtx dep;
- int cost;
+arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
{
rtx i_pat, d_pat;
/* Some true dependencies can have a higher cost depending
on precisely how certain input operands are used. */
- if (arm_is_xscale
+ if (arm_tune_xscale
&& REG_NOTE_KIND (link) == 0
- && recog_memoized (insn) < 0
- && recog_memoized (dep) < 0)
+ && recog_memoized (insn) >= 0
+ && recog_memoized (dep) >= 0)
{
int shift_opnum = get_attr_shift (insn);
enum attr_type attr_type = get_attr_type (dep);
@@ -3017,8 +3672,6 @@ arm_adjust_cost (insn, link, dep, cost)
return cost;
}
-/* This code has been fixed for cross compilation. */
-
static int fpa_consts_inited = 0;
static const char * const strings_fpa[8] =
@@ -3030,7 +3683,7 @@ static const char * const strings_fpa[8] =
static REAL_VALUE_TYPE values_fpa[8];
static void
-init_fpa_table ()
+init_fpa_table (void)
{
int i;
REAL_VALUE_TYPE r;
@@ -3044,11 +3697,9 @@ init_fpa_table ()
fpa_consts_inited = 1;
}
-/* Return TRUE if rtx X is a valid immediate FPU constant. */
-
+/* Return TRUE if rtx X is a valid immediate FPA constant. */
int
-const_double_rtx_ok_for_fpu (x)
- rtx x;
+const_double_rtx_ok_for_fpa (rtx x)
{
REAL_VALUE_TYPE r;
int i;
@@ -3067,11 +3718,9 @@ const_double_rtx_ok_for_fpu (x)
return 0;
}
-/* Return TRUE if rtx X is a valid immediate FPU constant. */
-
+/* Return TRUE if rtx X is a valid immediate FPA constant. */
int
-neg_const_double_rtx_ok_for_fpu (x)
- rtx x;
+neg_const_double_rtx_ok_for_fpa (rtx x)
{
REAL_VALUE_TYPE r;
int i;
@@ -3100,11 +3749,8 @@ neg_const_double_rtx_ok_for_fpu (x)
code. SUBREG(MEM) always needs a reload in the places where
s_register_operand is used, and this seemed to lead to excessive
reloading. */
-
int
-s_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+s_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -3121,11 +3767,8 @@ s_register_operand (op, mode)
}
/* A hard register operand (even before reload. */
-
int
-arm_hard_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_hard_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -3135,11 +3778,8 @@ arm_hard_register_operand (op, mode)
}
/* Only accept reg, subreg(reg), const_int. */
-
int
-reg_or_int_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_int_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return 1;
@@ -3158,11 +3798,8 @@ reg_or_int_operand (op, mode)
}
/* Return 1 if OP is an item in memory, given that we are in reload. */
-
int
-arm_reload_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+arm_reload_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int regno = true_regnum (op);
@@ -3176,18 +3813,11 @@ arm_reload_memory_operand (op, mode)
memory access (architecture V4).
MODE is QImode if called when computing constraints, or VOIDmode when
emitting patterns. In this latter case we cannot use memory_operand()
- because it will fail on badly formed MEMs, which is precisly what we are
+ because it will fail on badly formed MEMs, which is precisely what we are
trying to catch. */
-
int
-bad_signed_byte_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+bad_signed_byte_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
-#if 0
- if ((mode == QImode && !memory_operand (op, mode)) || GET_CODE (op) != MEM)
- return 0;
-#endif
if (GET_CODE (op) != MEM)
return 0;
@@ -3211,11 +3841,8 @@ bad_signed_byte_operand (op, mode)
}
/* Return TRUE for valid operands for the rhs of an ARM instruction. */
-
int
-arm_rhs_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_rhs_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))));
@@ -3223,11 +3850,8 @@ arm_rhs_operand (op, mode)
/* Return TRUE for valid operands for the
rhs of an ARM instruction, or a load. */
-
int
-arm_rhsm_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_rhsm_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))
@@ -3236,11 +3860,8 @@ arm_rhsm_operand (op, mode)
/* Return TRUE for valid operands for the rhs of an ARM instruction, or if a
constant that is valid when negated. */
-
int
-arm_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_add_operand (rtx op, enum machine_mode mode)
{
if (TARGET_THUMB)
return thumb_cmp_operand (op, mode);
@@ -3251,10 +3872,17 @@ arm_add_operand (op, mode)
|| const_ok_for_arm (-INTVAL (op)))));
}
+/* Return TRUE for valid ARM constants (or when valid if negated). */
+int
+arm_addimm_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT
+ && (const_ok_for_arm (INTVAL (op))
+ || const_ok_for_arm (-INTVAL (op))));
+}
+
int
-arm_not_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_not_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -3264,11 +3892,8 @@ arm_not_operand (op, mode)
/* Return TRUE if the operand is a memory reference which contains an
offsettable address. */
-
int
-offsettable_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+offsettable_memory_operand (rtx op, enum machine_mode mode)
{
if (mode == VOIDmode)
mode = GET_MODE (op);
@@ -3281,11 +3906,8 @@ offsettable_memory_operand (op, mode)
/* Return TRUE if the operand is a memory reference which is, or can be
made word aligned by adjusting the offset. */
-
int
-alignable_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+alignable_memory_operand (rtx op, enum machine_mode mode)
{
rtx reg;
@@ -3310,11 +3932,8 @@ alignable_memory_operand (op, mode)
/* Similar to s_register_operand, but does not allow hard integer
registers. */
-
int
-f_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+f_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -3326,15 +3945,12 @@ f_register_operand (op, mode)
to be a register operand. */
return (GET_CODE (op) == REG
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
- || REGNO_REG_CLASS (REGNO (op)) == FPU_REGS));
+ || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
}
-/* Return TRUE for valid operands for the rhs of an FPU instruction. */
-
+/* Return TRUE for valid operands for the rhs of an FPA instruction. */
int
-fpu_rhs_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpa_rhs_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3343,15 +3959,13 @@ fpu_rhs_operand (op, mode)
return FALSE;
if (GET_CODE (op) == CONST_DOUBLE)
- return const_double_rtx_ok_for_fpu (op);
+ return const_double_rtx_ok_for_fpa (op);
return FALSE;
}
int
-fpu_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpa_add_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3360,18 +3974,263 @@ fpu_add_operand (op, mode)
return FALSE;
if (GET_CODE (op) == CONST_DOUBLE)
- return (const_double_rtx_ok_for_fpu (op)
- || neg_const_double_rtx_ok_for_fpu (op));
+ return (const_double_rtx_ok_for_fpa (op)
+ || neg_const_double_rtx_ok_for_fpa (op));
return FALSE;
}
-/* Return nonzero if OP is a constant power of two. */
+/* Return nonzero if OP is a valid Cirrus memory address pattern. */
+int
+cirrus_memory_offset (rtx op)
+{
+ /* Reject eliminable registers. */
+ if (! (reload_in_progress || reload_completed)
+ && ( reg_mentioned_p (frame_pointer_rtx, op)
+ || reg_mentioned_p (arg_pointer_rtx, op)
+ || reg_mentioned_p (virtual_incoming_args_rtx, op)
+ || reg_mentioned_p (virtual_outgoing_args_rtx, op)
+ || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
+ || reg_mentioned_p (virtual_stack_vars_rtx, op)))
+ return 0;
+
+ if (GET_CODE (op) == MEM)
+ {
+ rtx ind;
+
+ ind = XEXP (op, 0);
+
+ /* Match: (mem (reg)). */
+ if (GET_CODE (ind) == REG)
+ return 1;
+
+ /* Match:
+ (mem (plus (reg)
+ (const))). */
+ if (GET_CODE (ind) == PLUS
+ && GET_CODE (XEXP (ind, 0)) == REG
+ && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
+ && GET_CODE (XEXP (ind, 1)) == CONST_INT)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Return nonzero if OP is a Cirrus or general register. */
+int
+cirrus_register_operand (rtx op, enum machine_mode mode)
+{
+ if (GET_MODE (op) != mode && mode != VOIDmode)
+ return FALSE;
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ return (GET_CODE (op) == REG
+ && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
+ || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
+}
+
+/* Return nonzero if OP is a cirrus FP register. */
+int
+cirrus_fp_register (rtx op, enum machine_mode mode)
+{
+ if (GET_MODE (op) != mode && mode != VOIDmode)
+ return FALSE;
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ return (GET_CODE (op) == REG
+ && (REGNO (op) >= FIRST_PSEUDO_REGISTER
+ || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
+}
+
+/* Return nonzero if OP is a 6bit constant (0..63). */
+int
+cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT
+ && INTVAL (op) >= 0
+ && INTVAL (op) < 64);
+}
+
+/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
+ Use by the Cirrus Maverick code which has to workaround
+ a hardware bug triggered by such instructions. */
+static bool
+arm_memory_load_p (rtx insn)
+{
+ rtx body, lhs, rhs;;
+
+ if (insn == NULL_RTX || GET_CODE (insn) != INSN)
+ return false;
+
+ body = PATTERN (insn);
+
+ if (GET_CODE (body) != SET)
+ return false;
+
+ lhs = XEXP (body, 0);
+ rhs = XEXP (body, 1);
+
+ lhs = REG_OR_SUBREG_RTX (lhs);
+
+ /* If the destination is not a general purpose
+ register we do not have to worry. */
+ if (GET_CODE (lhs) != REG
+ || REGNO_REG_CLASS (REGNO (lhs)) != GENERAL_REGS)
+ return false;
+
+ /* As well as loads from memory we also have to react
+ to loads of invalid constants which will be turned
+ into loads from the minipool. */
+ return (GET_CODE (rhs) == MEM
+ || GET_CODE (rhs) == SYMBOL_REF
+ || note_invalid_constants (insn, -1, false));
+}
+
+/* Return TRUE if INSN is a Cirrus instruction. */
+static bool
+arm_cirrus_insn_p (rtx insn)
+{
+ enum attr_cirrus attr;
+
+ /* get_attr aborts on USE and CLOBBER. */
+ if (!insn
+ || GET_CODE (insn) != INSN
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return 0;
+
+ attr = get_attr_cirrus (insn);
+
+ return attr != CIRRUS_NOT;
+}
+
+/* Cirrus reorg for invalid instruction combinations. */
+static void
+cirrus_reorg (rtx first)
+{
+ enum attr_cirrus attr;
+ rtx body = PATTERN (first);
+ rtx t;
+ int nops;
+
+ /* Any branch must be followed by 2 non Cirrus instructions. */
+ if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
+ {
+ nops = 0;
+ t = next_nonnote_insn (first);
+
+ if (arm_cirrus_insn_p (t))
+ ++ nops;
+
+ if (arm_cirrus_insn_p (next_nonnote_insn (t)))
+ ++ nops;
+
+ while (nops --)
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+
+ /* (float (blah)) is in parallel with a clobber. */
+ if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
+ body = XVECEXP (body, 0, 0);
+
+ if (GET_CODE (body) == SET)
+ {
+ rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1);
+
+ /* cfldrd, cfldr64, cfstrd, cfstr64 must
+ be followed by a non Cirrus insn. */
+ if (get_attr_cirrus (first) == CIRRUS_DOUBLE)
+ {
+ if (arm_cirrus_insn_p (next_nonnote_insn (first)))
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+ else if (arm_memory_load_p (first))
+ {
+ unsigned int arm_regno;
+
+ /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr,
+ ldr/cfmv64hr combination where the Rd field is the same
+ in both instructions must be split with a non Cirrus
+ insn. Example:
+
+ ldr r0, blah
+ nop
+ cfmvsr mvf0, r0. */
+
+ /* Get Arm register number for ldr insn. */
+ if (GET_CODE (lhs) == REG)
+ arm_regno = REGNO (lhs);
+ else if (GET_CODE (rhs) == REG)
+ arm_regno = REGNO (rhs);
+ else
+ abort ();
+
+ /* Next insn. */
+ first = next_nonnote_insn (first);
+
+ if (! arm_cirrus_insn_p (first))
+ return;
+
+ body = PATTERN (first);
+
+ /* (float (blah)) is in parallel with a clobber. */
+ if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0))
+ body = XVECEXP (body, 0, 0);
+ if (GET_CODE (body) == FLOAT)
+ body = XEXP (body, 0);
+
+ if (get_attr_cirrus (first) == CIRRUS_MOVE
+ && GET_CODE (XEXP (body, 1)) == REG
+ && arm_regno == REGNO (XEXP (body, 1)))
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+ }
+
+ /* get_attr aborts on USE and CLOBBER. */
+ if (!first
+ || GET_CODE (first) != INSN
+ || GET_CODE (PATTERN (first)) == USE
+ || GET_CODE (PATTERN (first)) == CLOBBER)
+ return;
+
+ attr = get_attr_cirrus (first);
+
+ /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...)
+ must be followed by a non-coprocessor instruction. */
+ if (attr == CIRRUS_COMPARE)
+ {
+ nops = 0;
+
+ t = next_nonnote_insn (first);
+
+ if (arm_cirrus_insn_p (t))
+ ++ nops;
+
+ if (arm_cirrus_insn_p (next_nonnote_insn (t)))
+ ++ nops;
+
+ while (nops --)
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+}
+
+/* Return nonzero if OP is a constant power of two. */
int
-power_of_two_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+power_of_two_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -3387,11 +4246,8 @@ power_of_two_operand (op, mode)
Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
Note that this disallows MEM(REG+REG), but allows
MEM(PRE/POST_INC/DEC(REG)). */
-
int
-di_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+di_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3417,11 +4273,8 @@ di_operand (op, mode)
}
/* Like di_operand, but don't accept constants. */
-
int
-nonimmediate_di_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+nonimmediate_di_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3442,11 +4295,8 @@ nonimmediate_di_operand (op, mode)
Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
Note that this disallows MEM(REG+REG), but allows
MEM(PRE/POST_INC/DEC(REG)). */
-
int
-soft_df_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+soft_df_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3474,11 +4324,8 @@ soft_df_operand (op, mode)
}
/* Like soft_df_operand, but don't accept constants. */
-
int
-nonimmediate_soft_df_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+nonimmediate_soft_df_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3495,11 +4342,8 @@ nonimmediate_soft_df_operand (op, mode)
}
/* Return TRUE for valid index operands. */
-
int
-index_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+index_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (immediate_operand (op, mode)
@@ -3510,11 +4354,8 @@ index_operand (op, mode)
/* Return TRUE for valid shifts by a constant. This also accepts any
power of two on the (somewhat overly relaxed) assumption that the
shift operator in this case was a mult. */
-
int
-const_shift_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+const_shift_operand (rtx op, enum machine_mode mode)
{
return (power_of_two_operand (op, mode)
|| (immediate_operand (op, mode)
@@ -3524,11 +4365,8 @@ const_shift_operand (op, mode)
/* Return TRUE for arithmetic operators which can be combined with a multiply
(shift). */
-
int
-shiftable_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+shiftable_operator (rtx x, enum machine_mode mode)
{
enum rtx_code code;
@@ -3542,11 +4380,8 @@ shiftable_operator (x, mode)
}
/* Return TRUE for binary logical operators. */
-
int
-logical_binary_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+logical_binary_operator (rtx x, enum machine_mode mode)
{
enum rtx_code code;
@@ -3559,11 +4394,8 @@ logical_binary_operator (x, mode)
}
/* Return TRUE for shift operators. */
-
int
-shift_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+shift_operator (rtx x,enum machine_mode mode)
{
enum rtx_code code;
@@ -3580,21 +4412,15 @@ shift_operator (x, mode)
}
/* Return TRUE if x is EQ or NE. */
-
int
-equality_operator (x, mode)
- rtx x;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+equality_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (x) == EQ || GET_CODE (x) == NE;
}
/* Return TRUE if x is a comparison operator other than LTGT or UNEQ. */
-
int
-arm_comparison_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+arm_comparison_operator (rtx x, enum machine_mode mode)
{
return (comparison_operator (x, mode)
&& GET_CODE (x) != LTGT
@@ -3602,11 +4428,8 @@ arm_comparison_operator (x, mode)
}
/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
-
int
-minmax_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+minmax_operator (rtx x, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (x);
@@ -3618,11 +4441,8 @@ minmax_operator (x, mode)
/* Return TRUE if this is the condition code register, if we aren't given
a mode, accept any class CCmode register. */
-
int
-cc_register (x, mode)
- rtx x;
- enum machine_mode mode;
+cc_register (rtx x, enum machine_mode mode)
{
if (mode == VOIDmode)
{
@@ -3643,11 +4463,8 @@ cc_register (x, mode)
/* Return TRUE if this is the condition code register, if we aren't given
a mode, accept any class CCmode register which indicates a dominance
expression. */
-
int
-dominant_cc_register (x, mode)
- rtx x;
- enum machine_mode mode;
+dominant_cc_register (rtx x, enum machine_mode mode)
{
if (mode == VOIDmode)
{
@@ -3657,7 +4474,7 @@ dominant_cc_register (x, mode)
return FALSE;
}
- if ( mode != CC_DNEmode && mode != CC_DEQmode
+ if (mode != CC_DNEmode && mode != CC_DEQmode
&& mode != CC_DLEmode && mode != CC_DLTmode
&& mode != CC_DGEmode && mode != CC_DGTmode
&& mode != CC_DLEUmode && mode != CC_DLTUmode
@@ -3668,10 +4485,8 @@ dominant_cc_register (x, mode)
}
/* Return TRUE if X references a SYMBOL_REF. */
-
int
-symbol_mentioned_p (x)
- rtx x;
+symbol_mentioned_p (rtx x)
{
const char * fmt;
int i;
@@ -3699,10 +4514,8 @@ symbol_mentioned_p (x)
}
/* Return TRUE if X references a LABEL_REF. */
-
int
-label_mentioned_p (x)
- rtx x;
+label_mentioned_p (rtx x)
{
const char * fmt;
int i;
@@ -3729,8 +4542,7 @@ label_mentioned_p (x)
}
enum rtx_code
-minmax_code (x)
- rtx x;
+minmax_code (rtx x)
{
enum rtx_code code = GET_CODE (x);
@@ -3747,10 +4559,8 @@ minmax_code (x)
}
/* Return 1 if memory locations are adjacent. */
-
int
-adjacent_mem_locations (a, b)
- rtx a, b;
+adjacent_mem_locations (rtx a, rtx b)
{
if ((GET_CODE (XEXP (a, 0)) == REG
|| (GET_CODE (XEXP (a, 0)) == PLUS
@@ -3778,6 +4588,12 @@ adjacent_mem_locations (a, b)
else
reg1 = REGNO (XEXP (b, 0));
+ /* Don't accept any offset that will require multiple
+ instructions to handle, since this would cause the
+ arith_adjacentmem pattern to output an overlong sequence. */
+ if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
+ return 0;
+
return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
}
return 0;
@@ -3785,11 +4601,8 @@ adjacent_mem_locations (a, b)
/* Return 1 if OP is a load multiple operation. It is known to be
parallel and the first section will be tested. */
-
int
-load_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT count = XVECLEN (op, 0);
int dest_regno;
@@ -3810,7 +4623,6 @@ load_multiple_operation (op, mode)
/* Now check it more carefully. */
if (GET_CODE (SET_DEST (elt)) != REG
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
- || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
|| GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
|| INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
return 0;
@@ -3848,11 +4660,8 @@ load_multiple_operation (op, mode)
/* Return 1 if OP is a store multiple operation. It is known to be
parallel and the first section will be tested. */
-
int
-store_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT count = XVECLEN (op, 0);
int src_regno;
@@ -3873,7 +4682,6 @@ store_multiple_operation (op, mode)
/* Now check it more carefully. */
if (GET_CODE (SET_DEST (elt)) != REG
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
- || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
|| GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
|| INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
return 0;
@@ -3910,12 +4718,8 @@ store_multiple_operation (op, mode)
}
int
-load_multiple_sequence (operands, nops, regs, base, load_offset)
- rtx * operands;
- int nops;
- int * regs;
- int * base;
- HOST_WIDE_INT * load_offset;
+load_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
+ HOST_WIDE_INT *load_offset)
{
int unsorted_regs[4];
HOST_WIDE_INT unsorted_offsets[4];
@@ -4085,9 +4889,7 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
}
const char *
-emit_ldm_seq (operands, nops)
- rtx * operands;
- int nops;
+emit_ldm_seq (rtx *operands, int nops)
{
int regs[4];
int base_reg;
@@ -4145,12 +4947,8 @@ emit_ldm_seq (operands, nops)
}
int
-store_multiple_sequence (operands, nops, regs, base, load_offset)
- rtx * operands;
- int nops;
- int * regs;
- int * base;
- HOST_WIDE_INT * load_offset;
+store_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
+ HOST_WIDE_INT * load_offset)
{
int unsorted_regs[4];
HOST_WIDE_INT unsorted_offsets[4];
@@ -4282,9 +5080,7 @@ store_multiple_sequence (operands, nops, regs, base, load_offset)
}
const char *
-emit_stm_seq (operands, nops)
- rtx * operands;
- int nops;
+emit_stm_seq (rtx *operands, int nops)
{
int regs[4];
int base_reg;
@@ -4328,9 +5124,7 @@ emit_stm_seq (operands, nops)
}
int
-multi_register_push (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != PARALLEL
|| (GET_CODE (XVECEXP (op, 0, 0)) != SET)
@@ -4344,16 +5138,9 @@ multi_register_push (op, mode)
/* Routines for use in generating RTL. */
rtx
-arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
- in_struct_p, scalar_p)
- int base_regno;
- int count;
- rtx from;
- int up;
- int write_back;
- int unchanging_p;
- int in_struct_p;
- int scalar_p;
+arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
+ int write_back, int unchanging_p, int in_struct_p,
+ int scalar_p)
{
int i = 0, j;
rtx result;
@@ -4388,7 +5175,7 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
for counts of 3 or 4 regs. */
- if (arm_is_xscale && count <= 2 && ! optimize_size)
+ if (arm_tune_xscale && count <= 2 && ! optimize_size)
{
rtx seq;
@@ -4437,16 +5224,9 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
}
rtx
-arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
- in_struct_p, scalar_p)
- int base_regno;
- int count;
- rtx to;
- int up;
- int write_back;
- int unchanging_p;
- int in_struct_p;
- int scalar_p;
+arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
+ int write_back, int unchanging_p, int in_struct_p,
+ int scalar_p)
{
int i = 0, j;
rtx result;
@@ -4455,7 +5235,7 @@ arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
/* See arm_gen_load_multiple for discussion of
the pros/cons of ldm/stm usage for XScale. */
- if (arm_is_xscale && count <= 2 && ! optimize_size)
+ if (arm_tune_xscale && count <= 2 && ! optimize_size)
{
rtx seq;
@@ -4505,8 +5285,7 @@ arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
}
int
-arm_gen_movstrqi (operands)
- rtx * operands;
+arm_gen_movstrqi (rtx *operands)
{
HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
int i;
@@ -4689,8 +5468,7 @@ arm_gen_movstrqi (operands)
known to be alignable and of the form reg, or plus (reg, const). */
rtx
-arm_gen_rotated_half_load (memref)
- rtx memref;
+arm_gen_rotated_half_load (rtx memref)
{
HOST_WIDE_INT offset = 0;
rtx base = XEXP (memref, 0);
@@ -4714,19 +5492,17 @@ arm_gen_rotated_half_load (memref)
return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
}
-/* Select a dominance comparison mode if possible. We support three forms.
- COND_OR == 0 => (X && Y)
- COND_OR == 1 => ((! X( || Y)
- COND_OR == 2 => (X || Y)
- If we are unable to support a dominance comparsison we return CC mode.
- This will then fail to match for the RTL expressions that generate this
- call. */
-
-static enum machine_mode
-select_dominance_cc_mode (x, y, cond_or)
- rtx x;
- rtx y;
- HOST_WIDE_INT cond_or;
+/* Select a dominance comparison mode if possible for a test of the general
+ form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms.
+ COND_OR == DOM_CC_X_AND_Y => (X && Y)
+ COND_OR == DOM_CC_NX_OR_Y => ((! X) || Y)
+ COND_OR == DOM_CC_X_OR_Y => (X || Y)
+ In all cases OP will be either EQ or NE, but we don't need to know which
+ here. If we are unable to support a dominance comparison we return
+ CC mode. This will then fail to match for the RTL expressions that
+ generate this call. */
+enum machine_mode
+arm_select_dominance_cc_mode (rtx x, rtx y, HOST_WIDE_INT cond_or)
{
enum rtx_code cond1, cond2;
int swapped = 0;
@@ -4743,7 +5519,7 @@ select_dominance_cc_mode (x, y, cond_or)
/* The if_then_else variant of this tests the second condition if the
first passes, but is true if the first fails. Reverse the first
condition to get a true "inclusive-or" expression. */
- if (cond_or == 1)
+ if (cond_or == DOM_CC_NX_OR_Y)
cond1 = reverse_condition (cond1);
/* If the comparisons are not equal, and one doesn't dominate the other,
@@ -4763,7 +5539,7 @@ select_dominance_cc_mode (x, y, cond_or)
switch (cond1)
{
case EQ:
- if (cond2 == EQ || !cond_or)
+ if (cond2 == EQ || cond_or == DOM_CC_X_AND_Y)
return CC_DEQmode;
switch (cond2)
@@ -4778,7 +5554,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case LT:
- if (cond2 == LT || !cond_or)
+ if (cond2 == LT || cond_or == DOM_CC_X_AND_Y)
return CC_DLTmode;
if (cond2 == LE)
return CC_DLEmode;
@@ -4787,7 +5563,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case GT:
- if (cond2 == GT || !cond_or)
+ if (cond2 == GT || cond_or == DOM_CC_X_AND_Y)
return CC_DGTmode;
if (cond2 == GE)
return CC_DGEmode;
@@ -4796,7 +5572,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case LTU:
- if (cond2 == LTU || !cond_or)
+ if (cond2 == LTU || cond_or == DOM_CC_X_AND_Y)
return CC_DLTUmode;
if (cond2 == LEU)
return CC_DLEUmode;
@@ -4805,7 +5581,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case GTU:
- if (cond2 == GTU || !cond_or)
+ if (cond2 == GTU || cond_or == DOM_CC_X_AND_Y)
return CC_DGTUmode;
if (cond2 == GEU)
return CC_DGEUmode;
@@ -4838,10 +5614,7 @@ select_dominance_cc_mode (x, y, cond_or)
}
enum machine_mode
-arm_select_cc_mode (op, x, y)
- enum rtx_code op;
- rtx x;
- rtx y;
+arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
{
/* All floating point compares return CCFP if it is an equality
comparison, and CCFPE otherwise. */
@@ -4865,6 +5638,8 @@ arm_select_cc_mode (op, x, y)
case LE:
case GT:
case GE:
+ if (TARGET_CIRRUS)
+ return CCFPmode;
return CCFPEmode;
default:
@@ -4904,24 +5679,35 @@ arm_select_cc_mode (op, x, y)
|| XEXP (x, 2) == const1_rtx)
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
- return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
- INTVAL (XEXP (x, 2)));
+ return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
+ INTVAL (XEXP (x, 2)));
/* Alternate canonicalizations of the above. These are somewhat cleaner. */
if (GET_CODE (x) == AND
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
- return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 0);
+ return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
+ DOM_CC_X_AND_Y);
if (GET_CODE (x) == IOR
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
- return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 2);
+ return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
+ DOM_CC_X_OR_Y);
+
+ /* An operation (on Thumb) where we want to test for a single bit.
+ This is done by shifting that bit up into the top bit of a
+ scratch register; we can then branch on the sign bit. */
+ if (TARGET_THUMB
+ && GET_MODE (x) == SImode
+ && (op == EQ || op == NE)
+ && (GET_CODE (x) == ZERO_EXTRACT))
+ return CC_Nmode;
/* An operation that sets the condition codes as a side-effect, the
V flag is not set correctly, so we can only use comparisons where
this doesn't matter. (For LT and GE we can use "mi" and "pl"
- instead. */
+ instead.) */
if (GET_MODE (x) == SImode
&& y == const0_rtx
&& (op == EQ || op == NE || op == LT || op == GE)
@@ -4931,7 +5717,8 @@ arm_select_cc_mode (op, x, y)
|| GET_CODE (x) == NOT || GET_CODE (x) == NEG
|| GET_CODE (x) == LSHIFTRT
|| GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
- || GET_CODE (x) == ROTATERT || GET_CODE (x) == ZERO_EXTRACT))
+ || GET_CODE (x) == ROTATERT
+ || (TARGET_ARM && GET_CODE (x) == ZERO_EXTRACT)))
return CC_NOOVmode;
if (GET_MODE (x) == QImode && (op == EQ || op == NE))
@@ -4948,11 +5735,8 @@ arm_select_cc_mode (op, x, y)
/* X and Y are two things to compare using CODE. Emit the compare insn and
return the rtx for register 0 in the proper mode. FP means this is a
floating point compare: I don't think that it is needed on the arm. */
-
rtx
-arm_gen_compare_reg (code, x, y)
- enum rtx_code code;
- rtx x, y;
+arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
{
enum machine_mode mode = SELECT_CC_MODE (code, x, y);
rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM);
@@ -4966,9 +5750,8 @@ arm_gen_compare_reg (code, x, y)
/* Generate a sequence of insns that will generate the correct return
address mask depending on the physical architecture that the program
is running on. */
-
rtx
-arm_gen_return_addr_mask ()
+arm_gen_return_addr_mask (void)
{
rtx reg = gen_reg_rtx (Pmode);
@@ -4977,8 +5760,7 @@ arm_gen_return_addr_mask ()
}
void
-arm_reload_in_hi (operands)
- rtx * operands;
+arm_reload_in_hi (rtx *operands)
{
rtx ref = operands[1];
rtx base, scratch;
@@ -5089,16 +5871,14 @@ arm_reload_in_hi (operands)
0))));
}
-/* Handle storing a half-word to memory during reload by synthesising as two
+/* Handle storing a half-word to memory during reload by synthesizing as two
byte stores. Take care not to clobber the input values until after we
have moved them somewhere safe. This code assumes that if the DImode
scratch in operands[2] overlaps either the input value or output address
in some way, then that value must die in this insn (we absolutely need
two scratch registers for some corner cases). */
-
void
-arm_reload_out_hi (operands)
- rtx * operands;
+arm_reload_out_hi (rtx *operands)
{
rtx ref = operands[0];
rtx outval = operands[1];
@@ -5256,11 +6036,8 @@ arm_reload_out_hi (operands)
}
/* Print a symbolic form of X to the debug file, F. */
-
static void
-arm_print_value (f, x)
- FILE * f;
- rtx x;
+arm_print_value (FILE *f, rtx x)
{
switch (GET_CODE (x))
{
@@ -5272,6 +6049,21 @@ arm_print_value (f, x)
fprintf (f, "<0x%lx,0x%lx>", (long)XWINT (x, 2), (long)XWINT (x, 3));
return;
+ case CONST_VECTOR:
+ {
+ int i;
+
+ fprintf (f, "<");
+ for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
+ {
+ fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (CONST_VECTOR_ELT (x, i)));
+ if (i < (CONST_VECTOR_NUNITS (x) - 1))
+ fputc (',', f);
+ }
+ fprintf (f, ">");
+ }
+ return;
+
case CONST_STRING:
fprintf (f, "\"%s\"", XSTR (x, 0));
return;
@@ -5392,6 +6184,8 @@ struct minipool_node
rtx value;
/* The mode of value. */
enum machine_mode mode;
+ /* The size of the value. With iWMMXt enabled
+ sizes > 4 also imply an alignment of 8-bytes. */
int fix_size;
};
@@ -5425,10 +6219,8 @@ Mfix * minipool_barrier;
/* Determines if INSN is the start of a jump table. Returns the end
of the TABLE or NULL_RTX. */
-
static rtx
-is_jump_table (insn)
- rtx insn;
+is_jump_table (rtx insn)
{
rtx table;
@@ -5450,8 +6242,7 @@ is_jump_table (insn)
#endif
static HOST_WIDE_INT
-get_jump_table_size (insn)
- rtx insn;
+get_jump_table_size (rtx insn)
{
/* ADDR_VECs only take room if read-only data does into the text
section. */
@@ -5472,13 +6263,10 @@ get_jump_table_size (insn)
/* Move a minipool fix MP from its current location to before MAX_MP.
If MAX_MP is NULL, then MP doesn't need moving, but the addressing
- contrains may need updating. */
-
+ constraints may need updating. */
static Mnode *
-move_minipool_fix_forward_ref (mp, max_mp, max_address)
- Mnode * mp;
- Mnode * max_mp;
- HOST_WIDE_INT max_address;
+move_minipool_fix_forward_ref (Mnode *mp, Mnode *max_mp,
+ HOST_WIDE_INT max_address)
{
/* This should never be true and the code below assumes these are
different. */
@@ -5533,10 +6321,8 @@ move_minipool_fix_forward_ref (mp, max_mp, max_address)
/* Add a constant to the minipool for a forward reference. Returns the
node added or NULL if the constant will not fit in this pool. */
-
static Mnode *
-add_minipool_forward_ref (fix)
- Mfix * fix;
+add_minipool_forward_ref (Mfix *fix)
{
/* If set, max_mp is the first pool_entry that has a lower
constraint than the one we are trying to add. */
@@ -5575,13 +6361,26 @@ add_minipool_forward_ref (fix)
if (max_mp == NULL
&& mp->max_address > max_address)
max_mp = mp;
+
+ /* If we are inserting an 8-bytes aligned quantity and
+ we have not already found an insertion point, then
+ make sure that all such 8-byte aligned quantities are
+ placed at the start of the pool. */
+ if (TARGET_REALLY_IWMMXT
+ && max_mp == NULL
+ && fix->fix_size == 8
+ && mp->fix_size != 8)
+ {
+ max_mp = mp;
+ max_address = mp->max_address;
+ }
}
/* The value is not currently in the minipool, so we need to create
a new entry for it. If MAX_MP is NULL, the entry will be put on
the end of the list since the placement is less constrained than
any existing entry. Otherwise, we insert the new fix before
- MAX_MP and, if neceesary, adjust the constraints on the other
+ MAX_MP and, if necessary, adjust the constraints on the other
entries. */
mp = xmalloc (sizeof (* mp));
mp->fix_size = fix->fix_size;
@@ -5639,10 +6438,8 @@ add_minipool_forward_ref (fix)
}
static Mnode *
-move_minipool_fix_backward_ref (mp, min_mp, min_address)
- Mnode * mp;
- Mnode * min_mp;
- HOST_WIDE_INT min_address;
+move_minipool_fix_backward_ref (Mnode *mp, Mnode *min_mp,
+ HOST_WIDE_INT min_address)
{
HOST_WIDE_INT offset;
@@ -5702,17 +6499,15 @@ move_minipool_fix_backward_ref (mp, min_mp, min_address)
somewhat confusing because the calculated offsets for each fix do
not take into account the size of the pool (which is still under
construction. */
-
static Mnode *
-add_minipool_backward_ref (fix)
- Mfix * fix;
+add_minipool_backward_ref (Mfix *fix)
{
/* If set, min_mp is the last pool_entry that has a lower constraint
than the one we are trying to add. */
- Mnode * min_mp = NULL;
+ Mnode *min_mp = NULL;
/* This can be negative, since it is only a constraint. */
HOST_WIDE_INT min_address = fix->address - fix->backwards;
- Mnode * mp;
+ Mnode *mp;
/* If we can't reach the current pool from this insn, or if we can't
insert this entry at the end of the pool without pushing other
@@ -5752,7 +6547,14 @@ add_minipool_backward_ref (fix)
{
/* Note the insertion point if necessary. */
if (mp->min_address < min_address)
- min_mp = mp;
+ {
+ /* For now, we do not allow the insertion of 8-byte alignment
+ requiring nodes anywhere but at the start of the pool. */
+ if (TARGET_REALLY_IWMMXT && fix->fix_size == 8 && mp->fix_size != 8)
+ return NULL;
+ else
+ min_mp = mp;
+ }
else if (mp->max_address
< minipool_barrier->address + mp->offset + fix->fix_size)
{
@@ -5763,6 +6565,18 @@ add_minipool_backward_ref (fix)
min_mp = mp;
min_address = mp->min_address + fix->fix_size;
}
+ /* If we are inserting an 8-bytes aligned quantity and
+ we have not already found an insertion point, then
+ make sure that all such 8-byte aligned quantities are
+ placed at the start of the pool. */
+ else if (TARGET_REALLY_IWMMXT
+ && min_mp == NULL
+ && fix->fix_size == 8
+ && mp->fix_size < 8)
+ {
+ min_mp = mp;
+ min_address = mp->min_address + fix->fix_size;
+ }
}
}
@@ -5829,11 +6643,10 @@ add_minipool_backward_ref (fix)
}
static void
-assign_minipool_offsets (barrier)
- Mfix * barrier;
+assign_minipool_offsets (Mfix *barrier)
{
HOST_WIDE_INT offset = 0;
- Mnode * mp;
+ Mnode *mp;
minipool_barrier = barrier;
@@ -5848,19 +6661,27 @@ assign_minipool_offsets (barrier)
/* Output the literal table */
static void
-dump_minipool (scan)
- rtx scan;
+dump_minipool (rtx scan)
{
Mnode * mp;
Mnode * nmp;
+ int align64 = 0;
+
+ if (TARGET_REALLY_IWMMXT)
+ for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
+ if (mp->refcount > 0 && mp->fix_size == 8)
+ {
+ align64 = 1;
+ break;
+ }
if (rtl_dump_file)
fprintf (rtl_dump_file,
- ";; Emitting minipool after insn %u; address %ld\n",
- INSN_UID (scan), (unsigned long) minipool_barrier->address);
+ ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n",
+ INSN_UID (scan), (unsigned long) minipool_barrier->address, align64 ? 8 : 4);
scan = emit_label_after (gen_label_rtx (), scan);
- scan = emit_insn_after (gen_align_4 (), scan);
+ scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan);
scan = emit_label_after (minipool_vector_label, scan);
for (mp = minipool_vector_head; mp != NULL; mp = nmp)
@@ -5919,10 +6740,8 @@ dump_minipool (scan)
}
/* Return the cost of forcibly inserting a barrier after INSN. */
-
static int
-arm_barrier_cost (insn)
- rtx insn;
+arm_barrier_cost (rtx insn)
{
/* Basing the location of the pool on the loop depth is preferable,
but at the moment, the basic block information seems to be
@@ -5956,11 +6775,8 @@ arm_barrier_cost (insn)
(FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
Create the barrier by inserting a jump and add a new fix entry for
it. */
-
static Mfix *
-create_fix_barrier (fix, max_address)
- Mfix * fix;
- HOST_WIDE_INT max_address;
+create_fix_barrier (Mfix *fix, HOST_WIDE_INT max_address)
{
HOST_WIDE_INT count = 0;
rtx barrier;
@@ -6042,9 +6858,7 @@ create_fix_barrier (fix, max_address)
/* Record that there is a natural barrier in the insn stream at
ADDRESS. */
static void
-push_minipool_barrier (insn, address)
- rtx insn;
- HOST_WIDE_INT address;
+push_minipool_barrier (rtx insn, HOST_WIDE_INT address)
{
Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
@@ -6066,17 +6880,13 @@ push_minipool_barrier (insn, address)
fixing; VALUE is the constant that must be loaded, which is of type
MODE. */
static void
-push_minipool_fix (insn, address, loc, mode, value)
- rtx insn;
- HOST_WIDE_INT address;
- rtx * loc;
- enum machine_mode mode;
- rtx value;
+push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx *loc,
+ enum machine_mode mode, rtx value)
{
Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
#ifdef AOF_ASSEMBLER
- /* PIC symbol refereneces need to be converted into offsets into the
+ /* PIC symbol references need to be converted into offsets into the
based area. */
/* XXX This shouldn't be done here. */
if (flag_pic && GET_CODE (value) == SYMBOL_REF)
@@ -6099,6 +6909,13 @@ push_minipool_fix (insn, address, loc, mode, value)
if (fix->forwards == 0 && fix->backwards == 0)
abort ();
+ /* With iWMMXt enabled, the pool is aligned to an 8-byte boundary.
+ So there might be an empty word before the start of the pool.
+ Hence we reduce the forward range by 4 to allow for this
+ possibility. */
+ if (TARGET_REALLY_IWMMXT && fix->fix_size == 8)
+ fix->forwards -= 4;
+
if (rtl_dump_file)
{
fprintf (rtl_dump_file,
@@ -6121,13 +6938,15 @@ push_minipool_fix (insn, address, loc, mode, value)
minipool_fix_tail = fix;
}
-/* Scan INSN and note any of its operands that need fixing. */
-
-static void
-note_invalid_constants (insn, address)
- rtx insn;
- HOST_WIDE_INT address;
+/* Scan INSN and note any of its operands that need fixing.
+ If DO_PUSHES is false we do not actually push any of the fixups
+ needed. The function returns TRUE is any fixups were needed/pushed.
+ This is used by arm_memory_load_p() which needs to know about loads
+ of constants that will be converted into minipool loads. */
+static bool
+note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
{
+ bool result = false;
int opno;
extract_insn (insn);
@@ -6135,8 +6954,10 @@ note_invalid_constants (insn, address)
if (!constrain_operands (1))
fatal_insn_not_found (insn);
- /* Fill in recog_op_alt with information about the constraints of this
- insn. */
+ if (recog_data.n_alternatives == 0)
+ return false;
+
+ /* Fill in recog_op_alt with information about the constraints of this insn. */
preprocess_constraints ();
for (opno = 0; opno < recog_data.n_operands; opno++)
@@ -6154,32 +6975,47 @@ note_invalid_constants (insn, address)
rtx op = recog_data.operand[opno];
if (CONSTANT_P (op))
- push_minipool_fix (insn, address, recog_data.operand_loc[opno],
- recog_data.operand_mode[opno], op);
-#if 0
- /* RWE: Now we look correctly at the operands for the insn,
- this shouldn't be needed any more. */
-#ifndef AOF_ASSEMBLER
- /* XXX Is this still needed? */
- else if (GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_PIC_SYM)
- push_minipool_fix (insn, address, recog_data.operand_loc[opno],
- recog_data.operand_mode[opno],
- XVECEXP (op, 0, 0));
-#endif
-#endif
+ {
+ if (do_pushes)
+ push_minipool_fix (insn, address, recog_data.operand_loc[opno],
+ recog_data.operand_mode[opno], op);
+ result = true;
+ }
else if (GET_CODE (op) == MEM
&& GET_CODE (XEXP (op, 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
- push_minipool_fix (insn, address, recog_data.operand_loc[opno],
- recog_data.operand_mode[opno],
- get_pool_constant (XEXP (op, 0)));
+ {
+ if (do_pushes)
+ {
+ rtx cop = avoid_constant_pool_reference (op);
+
+ /* Casting the address of something to a mode narrower
+ than a word can cause avoid_constant_pool_reference()
+ to return the pool reference itself. That's no good to
+ us here. Lets just hope that we can use the
+ constant pool value directly. */
+ if (op == cop)
+ cop = get_pool_constant (XEXP (op, 0));
+
+ push_minipool_fix (insn, address,
+ recog_data.operand_loc[opno],
+ recog_data.operand_mode[opno], cop);
+ }
+
+ result = true;
+ }
}
}
+
+ return result;
}
-void
-arm_reorg (first)
- rtx first;
+/* Gcc puts the pool in the wrong place for ARM, since we can only
+ load addresses a limited distance around the pc. We do some
+ special munging to move the constant pool values to the correct
+ point in the code. */
+static void
+arm_reorg (void)
{
rtx insn;
HOST_WIDE_INT address = 0;
@@ -6189,20 +7025,26 @@ arm_reorg (first)
/* The first insn must always be a note, or the code below won't
scan it properly. */
- if (GET_CODE (first) != NOTE)
+ insn = get_insns ();
+ if (GET_CODE (insn) != NOTE)
abort ();
/* Scan all the insns and record the operands that will need fixing. */
- for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
+ for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn))
{
+ if (TARGET_CIRRUS_FIX_INVALID_INSNS
+ && (arm_cirrus_insn_p (insn)
+ || GET_CODE (insn) == JUMP_INSN
+ || arm_memory_load_p (insn)))
+ cirrus_reorg (insn);
+
if (GET_CODE (insn) == BARRIER)
push_minipool_barrier (insn, address);
- else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
- || GET_CODE (insn) == JUMP_INSN)
+ else if (INSN_P (insn))
{
rtx table;
- note_invalid_constants (insn, address);
+ note_invalid_constants (insn, address, true);
address += get_attr_length (insn);
/* If the insn is a vector jump, add the size of the table
@@ -6336,10 +7178,8 @@ arm_reorg (first)
/* If the rtx is the correct value then return the string of the number.
In this way we can ensure that valid double constants are generated even
when cross compiling. */
-
const char *
-fp_immediate_constant (x)
- rtx x;
+fp_immediate_constant (rtx x)
{
REAL_VALUE_TYPE r;
int i;
@@ -6356,10 +7196,8 @@ fp_immediate_constant (x)
}
/* As for fp_immediate_constant, but value is passed directly, not in rtx. */
-
static const char *
-fp_const_from_val (r)
- REAL_VALUE_TYPE * r;
+fp_const_from_val (REAL_VALUE_TYPE *r)
{
int i;
@@ -6377,13 +7215,8 @@ fp_const_from_val (r)
MASK is the ARM register set mask of which only bits 0-15 are important.
REG is the base register, either the frame pointer or the stack pointer,
INSTR is the possibly suffixed load or store instruction. */
-
static void
-print_multi_reg (stream, instr, reg, mask)
- FILE * stream;
- const char * instr;
- int reg;
- int mask;
+print_multi_reg (FILE *stream, const char *instr, int reg, int mask)
{
int i;
int not_first = FALSE;
@@ -6402,14 +7235,25 @@ print_multi_reg (stream, instr, reg, mask)
not_first = TRUE;
}
- fprintf (stream, "}%s\n", TARGET_APCS_32 ? "" : "^");
+ fprintf (stream, "}");
+
+ /* Add a ^ character for the 26-bit ABI, but only if we were loading
+ the PC. Otherwise we would generate an UNPREDICTABLE instruction.
+ Strictly speaking the instruction would be unpredicatble only if
+ we were writing back the base register as well, but since we never
+ want to generate an LDM type 2 instruction (register bank switching)
+ which is what you get if the PC is not being loaded, we do not need
+ to check for writeback. */
+ if (! TARGET_APCS_32
+ && ((mask & (1 << PC_REGNUM)) != 0))
+ fprintf (stream, "^");
+
+ fprintf (stream, "\n");
}
/* Output a 'call' insn. */
-
const char *
-output_call (operands)
- rtx * operands;
+output_call (rtx *operands)
{
/* Handle calls to lr using ip (which may be clobbered in subr anyway). */
@@ -6430,10 +7274,8 @@ output_call (operands)
}
/* Output a 'call' insn that is a reference in memory. */
-
const char *
-output_call_mem (operands)
- rtx * operands;
+output_call_mem (rtx *operands)
{
if (TARGET_INTERWORK)
{
@@ -6460,13 +7302,11 @@ output_call_mem (operands)
}
-/* Output a move from arm registers to an fpu registers.
- OPERANDS[0] is an fpu register.
+/* Output a move from arm registers to an fpa registers.
+ OPERANDS[0] is an fpa register.
OPERANDS[1] is the first registers of an arm register pair. */
-
const char *
-output_mov_long_double_fpu_from_arm (operands)
- rtx * operands;
+output_mov_long_double_fpa_from_arm (rtx *operands)
{
int arm_reg0 = REGNO (operands[1]);
rtx ops[3];
@@ -6484,13 +7324,11 @@ output_mov_long_double_fpu_from_arm (operands)
return "";
}
-/* Output a move from an fpu register to arm registers.
+/* Output a move from an fpa register to arm registers.
OPERANDS[0] is the first registers of an arm register pair.
- OPERANDS[1] is an fpu register. */
-
+ OPERANDS[1] is an fpa register. */
const char *
-output_mov_long_double_arm_from_fpu (operands)
- rtx * operands;
+output_mov_long_double_arm_from_fpa (rtx *operands)
{
int arm_reg0 = REGNO (operands[0]);
rtx ops[3];
@@ -6510,10 +7348,8 @@ output_mov_long_double_arm_from_fpu (operands)
/* Output a move from arm registers to arm registers of a long double
OPERANDS[0] is the destination.
OPERANDS[1] is the source. */
-
const char *
-output_mov_long_double_arm_from_arm (operands)
- rtx * operands;
+output_mov_long_double_arm_from_arm (rtx *operands)
{
/* We have to be careful here because the two might overlap. */
int dest_start = REGNO (operands[0]);
@@ -6544,13 +7380,11 @@ output_mov_long_double_arm_from_arm (operands)
}
-/* Output a move from arm registers to an fpu registers.
- OPERANDS[0] is an fpu register.
+/* Output a move from arm registers to an fpa registers.
+ OPERANDS[0] is an fpa register.
OPERANDS[1] is the first registers of an arm register pair. */
-
const char *
-output_mov_double_fpu_from_arm (operands)
- rtx * operands;
+output_mov_double_fpa_from_arm (rtx *operands)
{
int arm_reg0 = REGNO (operands[1]);
rtx ops[2];
@@ -6565,13 +7399,11 @@ output_mov_double_fpu_from_arm (operands)
return "";
}
-/* Output a move from an fpu register to arm registers.
+/* Output a move from an fpa register to arm registers.
OPERANDS[0] is the first registers of an arm register pair.
- OPERANDS[1] is an fpu register. */
-
+ OPERANDS[1] is an fpa register. */
const char *
-output_mov_double_arm_from_fpu (operands)
- rtx * operands;
+output_mov_double_arm_from_fpa (rtx *operands)
{
int arm_reg0 = REGNO (operands[0]);
rtx ops[2];
@@ -6589,10 +7421,8 @@ output_mov_double_arm_from_fpu (operands)
/* Output a move between double words.
It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
or MEM<-REG and all MEMs must be offsettable addresses. */
-
const char *
-output_move_double (operands)
- rtx * operands;
+output_move_double (rtx *operands)
{
enum rtx_code code0 = GET_CODE (operands[0]);
enum rtx_code code1 = GET_CODE (operands[1]);
@@ -6616,6 +7446,105 @@ output_move_double (operands)
else
output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
}
+ else if (code1 == CONST_VECTOR)
+ {
+ HOST_WIDE_INT hint = 0;
+
+ switch (GET_MODE (operands[1]))
+ {
+ case V2SImode:
+ otherops[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 1)));
+ operands[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)));
+ break;
+
+ case V4HImode:
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint = INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ }
+ else
+ {
+ hint = INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ }
+
+ otherops[1] = GEN_INT (hint);
+ hint = 0;
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ }
+ else
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ }
+
+ operands[1] = GEN_INT (hint);
+ break;
+
+ case V8QImode:
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
+ }
+ else
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
+ }
+
+ otherops[1] = GEN_INT (hint);
+ hint = 0;
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ }
+ else
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ }
+
+ operands[1] = GEN_INT (hint);
+ break;
+
+ default:
+ abort ();
+ }
+ output_mov_immediate (operands);
+ output_mov_immediate (otherops);
+ }
else if (code1 == CONST_DOUBLE)
{
if (GET_MODE (operands[1]) == DFmode)
@@ -6715,7 +7644,7 @@ output_move_double (operands)
{
if (GET_CODE (otherops[2]) == CONST_INT)
{
- switch (INTVAL (otherops[2]))
+ switch ((int) INTVAL (otherops[2]))
{
case -8:
output_asm_insn ("ldm%?db\t%1, %M0", otherops);
@@ -6791,7 +7720,7 @@ output_move_double (operands)
case PLUS:
if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
{
- switch (INTVAL (XEXP (XEXP (operands[0], 0), 1)))
+ switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
{
case -8:
output_asm_insn ("stm%?db\t%m0, %M1", operands);
@@ -6825,10 +7754,8 @@ output_move_double (operands)
/* Output an arbitrary MOV reg, #n.
OPERANDS[0] is a register. OPERANDS[1] is a const_int. */
-
const char *
-output_mov_immediate (operands)
- rtx * operands;
+output_mov_immediate (rtx *operands)
{
HOST_WIDE_INT n = INTVAL (operands[1]);
@@ -6848,9 +7775,9 @@ output_mov_immediate (operands)
int i;
/* If all else fails, make it out of ORRs or BICs as appropriate. */
- for (i = 0; i < 32; i ++)
+ for (i = 0; i < 32; i++)
if (n & 1 << i)
- n_ones ++;
+ n_ones++;
if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */
output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1, ~ n);
@@ -6863,10 +7790,8 @@ output_mov_immediate (operands)
/* Output an ADD r, s, #n where n may be too big for one instruction.
If adding zero to one register, output nothing. */
-
const char *
-output_add_immediate (operands)
- rtx * operands;
+output_add_immediate (rtx *operands)
{
HOST_WIDE_INT n = INTVAL (operands[2]);
@@ -6891,14 +7816,9 @@ output_add_immediate (operands)
INSTR2 is the output pattern to use for subsequent constants.
IMMED_OP is the index of the constant slot in OPERANDS.
N is the constant value. */
-
static const char *
-output_multi_immediate (operands, instr1, instr2, immed_op, n)
- rtx * operands;
- const char * instr1;
- const char * instr2;
- int immed_op;
- HOST_WIDE_INT n;
+output_multi_immediate (rtx *operands, const char *instr1, const char *instr2,
+ int immed_op, HOST_WIDE_INT n)
{
#if HOST_BITS_PER_WIDE_INT > 32
n &= 0xffffffff;
@@ -6935,11 +7855,8 @@ output_multi_immediate (operands, instr1, instr2, immed_op, n)
The returned result should not be overwritten. OP is the rtx of the
operation. SHIFT_FIRST_ARG is TRUE if the first argument of the operator
was shifted. */
-
const char *
-arithmetic_instr (op, shift_first_arg)
- rtx op;
- int shift_first_arg;
+arithmetic_instr (rtx op, int shift_first_arg)
{
switch (GET_CODE (op))
{
@@ -6968,11 +7885,8 @@ arithmetic_instr (op, shift_first_arg)
OP is the rtx code of the shift.
On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
shift. */
-
static const char *
-shift_op (op, amountp)
- rtx op;
- HOST_WIDE_INT *amountp;
+shift_op (rtx op, HOST_WIDE_INT *amountp)
{
const char * mnem;
enum rtx_code code = GET_CODE (op);
@@ -7045,8 +7959,7 @@ shift_op (op, amountp)
/* Obtain the shift from the POWER of two. */
static HOST_WIDE_INT
-int_log2 (power)
- HOST_WIDE_INT power;
+int_log2 (HOST_WIDE_INT power)
{
HOST_WIDE_INT shift = 0;
@@ -7054,7 +7967,7 @@ int_log2 (power)
{
if (shift > 31)
abort ();
- shift ++;
+ shift++;
}
return shift;
@@ -7065,10 +7978,7 @@ int_log2 (power)
#define MAX_ASCII_LEN 51
void
-output_ascii_pseudo_op (stream, p, len)
- FILE * stream;
- const unsigned char * p;
- int len;
+output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len)
{
int i;
int len_so_far = 0;
@@ -7122,7 +8032,7 @@ output_ascii_pseudo_op (stream, p, len)
case '\\':
putc ('\\', stream);
len_so_far++;
- /* drop through. */
+ /* Drop through. */
default:
if (c >= ' ' && c <= '~')
@@ -7145,9 +8055,8 @@ output_ascii_pseudo_op (stream, p, len)
/* Compute the register sabe mask for registers 0 through 12
inclusive. This code is used by both arm_compute_save_reg_mask
and arm_compute_initial_elimination_offset. */
-
static unsigned long
-arm_compute_save_reg0_reg12_mask ()
+arm_compute_save_reg0_reg12_mask (void)
{
unsigned long func_type = arm_current_func_type ();
unsigned int save_reg_mask = 0;
@@ -7207,7 +8116,7 @@ arm_compute_save_reg0_reg12_mask ()
saved on the stack for the current function. */
static unsigned long
-arm_compute_save_reg_mask ()
+arm_compute_save_reg_mask (void)
{
unsigned int save_reg_mask = 0;
unsigned long func_type = arm_current_func_type ();
@@ -7239,7 +8148,7 @@ arm_compute_save_reg_mask ()
it. If we are pushing other registers onto the stack however, we
can save an instruction in the epilogue by pushing the link register
now and then popping it back into the PC. This incurs extra memory
- accesses though, so we only do it when optimising for size, and only
+ accesses though, so we only do it when optimizing for size, and only
if we know that we will not need a fancy return sequence. */
if (regs_ever_live [LR_REGNUM]
|| (save_reg_mask
@@ -7250,17 +8159,41 @@ arm_compute_save_reg_mask ()
if (cfun->machine->lr_save_eliminated)
save_reg_mask &= ~ (1 << LR_REGNUM);
+ if (TARGET_REALLY_IWMMXT
+ && ((bit_count (save_reg_mask)
+ + ARM_NUM_INTS (current_function_pretend_args_size)) % 2) != 0)
+ {
+ unsigned int reg;
+
+ /* The total number of registers that are going to be pushed
+ onto the stack is odd. We need to ensure that the stack
+ is 64-bit aligned before we start to save iWMMXt registers,
+ and also before we start to create locals. (A local variable
+ might be a double or long long which we will load/store using
+ an iWMMXt instruction). Therefore we need to push another
+ ARM register, so that the stack will be 64-bit aligned. We
+ try to avoid using the arg registers (r0 -r3) as they might be
+ used to pass values in a tail call. */
+ for (reg = 4; reg <= 12; reg++)
+ if ((save_reg_mask & (1 << reg)) == 0)
+ break;
+
+ if (reg <= 12)
+ save_reg_mask |= (1 << reg);
+ else
+ {
+ cfun->machine->sibcall_blocked = 1;
+ save_reg_mask |= (1 << 3);
+ }
+ }
+
return save_reg_mask;
}
-/* Generate a function exit sequence. If REALLY_RETURN is true, then do
+/* Generate a function exit sequence. If REALLY_RETURN is false, then do
everything bar the final return instruction. */
-
const char *
-output_return_instruction (operand, really_return, reverse)
- rtx operand;
- int really_return;
- int reverse;
+output_return_instruction (rtx operand, int really_return, int reverse)
{
char conditional[10];
char instr[100];
@@ -7275,8 +8208,9 @@ output_return_instruction (operand, really_return, reverse)
if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
{
- /* If this function was declared non-returning, and we have found a tail
- call, then we have to trust that the called function won't return. */
+ /* If this function was declared non-returning, and we have
+ found a tail call, then we have to trust that the called
+ function won't return. */
if (really_return)
{
rtx ops[2];
@@ -7315,15 +8249,25 @@ output_return_instruction (operand, really_return, reverse)
return_reg = reg_names[LR_REGNUM];
if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
- /* There are two possible reasons for the IP register being saved.
- Either a stack frame was created, in which case IP contains the
- old stack pointer, or an ISR routine corrupted it. If this in an
- ISR routine then just restore IP, otherwise restore IP into SP. */
- if (! IS_INTERRUPT (func_type))
- {
- live_regs_mask &= ~ (1 << IP_REGNUM);
- live_regs_mask |= (1 << SP_REGNUM);
- }
+ {
+ /* There are three possible reasons for the IP register
+ being saved. 1) a stack frame was created, in which case
+ IP contains the old stack pointer, or 2) an ISR routine
+ corrupted it, or 3) it was saved to align the stack on
+ iWMMXt. In case 1, restore IP into SP, otherwise just
+ restore IP. */
+ if (frame_pointer_needed)
+ {
+ live_regs_mask &= ~ (1 << IP_REGNUM);
+ live_regs_mask |= (1 << SP_REGNUM);
+ }
+ else
+ {
+ if (! IS_INTERRUPT (func_type)
+ && ! TARGET_REALLY_IWMMXT)
+ abort ();
+ }
+ }
/* On some ARM architectures it is faster to use LDR rather than
LDM to load a single register. On other architectures, the
@@ -7348,11 +8292,29 @@ output_return_instruction (operand, really_return, reverse)
char *p;
int first = 1;
- /* Generate the load multiple instruction to restore the registers. */
- if (frame_pointer_needed)
- sprintf (instr, "ldm%sea\t%%|fp, {", conditional);
- else if (live_regs_mask & (1 << SP_REGNUM))
- sprintf (instr, "ldm%sfd\t%%|sp, {", conditional);
+ /* Generate the load multiple instruction to restore the
+ registers. Note we can get here, even if
+ frame_pointer_needed is true, but only if sp already
+ points to the base of the saved core registers. */
+ if (live_regs_mask & (1 << SP_REGNUM))
+ {
+ unsigned HOST_WIDE_INT stack_adjust =
+ arm_get_frame_size () + current_function_outgoing_args_size;
+
+ if (stack_adjust != 0 && stack_adjust != 4)
+ abort ();
+
+ if (stack_adjust && arm_arch5)
+ sprintf (instr, "ldm%sib\t%%|sp, {", conditional);
+ else
+ {
+ /* If we can't use ldmib (SA110 bug), then try to pop r3
+ instead. */
+ if (stack_adjust)
+ live_regs_mask |= 1 << 3;
+ sprintf (instr, "ldm%sfd\t%%|sp, {", conditional);
+ }
+ }
else
sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
@@ -7378,20 +8340,22 @@ output_return_instruction (operand, really_return, reverse)
if (live_regs_mask & (1 << LR_REGNUM))
{
- int l = strlen (return_reg);
-
- if (! first)
- {
- memcpy (p, ", ", 2);
- p += 2;
- }
-
- memcpy (p, "%|", 2);
- memcpy (p + 2, return_reg, l);
- strcpy (p + 2 + l, ((TARGET_APCS_32
- && !IS_INTERRUPT (func_type))
- || !really_return)
- ? "}" : "}^");
+ sprintf (p, "%s%%|%s}", first ? "" : ", ", return_reg);
+ /* Decide if we need to add the ^ symbol to the end of the
+ register list. This causes the saved condition codes
+ register to be copied into the current condition codes
+ register. We do the copy if we are conforming to the 32-bit
+ ABI and this is an interrupt function, or if we are
+ conforming to the 26-bit ABI. There is a special case for
+ the 26-bit ABI however, which is if we are writing back the
+ stack pointer but not loading the PC. In this case adding
+ the ^ symbol would create a type 2 LDM instruction, where
+ writeback is UNPREDICTABLE. We are safe in leaving the ^
+ character off in this case however, since the actual return
+ instruction will be a MOVS which will restore the CPSR. */
+ if ((TARGET_APCS_32 && IS_INTERRUPT (func_type))
+ || (! TARGET_APCS_32 && really_return))
+ strcat (p, "^");
}
else
strcpy (p, "}");
@@ -7471,18 +8435,15 @@ output_return_instruction (operand, really_return, reverse)
a leaf function. These function types will not contain a stack
backtrace structure, therefore it is not possible to determine the
function name. */
-
void
-arm_poke_function_name (stream, name)
- FILE * stream;
- const char * name;
+arm_poke_function_name (FILE *stream, const char *name)
{
unsigned long alignlength;
unsigned long length;
rtx x;
length = strlen (name) + 1;
- alignlength = ROUND_UP (length);
+ alignlength = ROUND_UP_WORD (length);
ASM_OUTPUT_ASCII (stream, name, length);
ASM_OUTPUT_ALIGN (stream, 2);
@@ -7492,11 +8453,8 @@ arm_poke_function_name (stream, name)
/* Place some comments into the assembler stream
describing the current function. */
-
static void
-arm_output_function_prologue (f, frame_size)
- FILE * f;
- HOST_WIDE_INT frame_size;
+arm_output_function_prologue (FILE *f, HOST_WIDE_INT frame_size)
{
unsigned long func_type;
@@ -7543,7 +8501,7 @@ arm_output_function_prologue (f, frame_size)
if (IS_NESTED (func_type))
asm_fprintf (f, "\t%@ Nested: function declared inside another function.\n");
- asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %d\n",
+ asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %wd\n",
current_function_args_size,
current_function_pretend_args_size, frame_size);
@@ -7563,8 +8521,7 @@ arm_output_function_prologue (f, frame_size)
}
const char *
-arm_output_epilogue (really_return)
- int really_return;
+arm_output_epilogue (rtx sibling)
{
int reg;
unsigned long saved_regs_mask;
@@ -7576,10 +8533,12 @@ arm_output_epilogue (really_return)
int frame_size = arm_get_frame_size ();
FILE * f = asm_out_file;
rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
+ unsigned int lrm_count = 0;
+ int really_return = (sibling == NULL);
/* If we have already generated the return instruction
then it is futile to generate anything else. */
- if (use_return_insn (FALSE) && return_used_this_function)
+ if (use_return_insn (FALSE, sibling) && return_used_this_function)
return "";
func_type = arm_current_func_type ();
@@ -7607,12 +8566,15 @@ arm_output_epilogue (really_return)
abort ();
saved_regs_mask = arm_compute_save_reg_mask ();
-
+
+ if (TARGET_IWMMXT)
+ lrm_count = bit_count (saved_regs_mask);
+
/* XXX We should adjust floats_offset for any anonymous args, and then
re-adjust vfp_offset below to compensate. */
/* Compute how far away the floats will be. */
- for (reg = 0; reg <= LAST_ARM_REGNUM; reg ++)
+ for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
if (saved_regs_mask & (1 << reg))
floats_offset += 4;
@@ -7620,7 +8582,7 @@ arm_output_epilogue (really_return)
{
int vfp_offset = 4;
- if (arm_fpu_arch == FP_SOFT2)
+ if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
{
for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
if (regs_ever_live[reg] && !call_used_regs[reg])
@@ -7665,6 +8627,26 @@ arm_output_epilogue (really_return)
FP_REGNUM, floats_offset - vfp_offset);
}
+ if (TARGET_IWMMXT)
+ {
+ /* The frame pointer is guaranteed to be non-double-word aligned.
+ This is because it is set to (old_stack_pointer - 4) and the
+ old_stack_pointer was double word aligned. Thus the offset to
+ the iWMMXt registers to be loaded must also be non-double-word
+ sized, so that the resultant address *is* double-word aligned.
+ We can ignore floats_offset since that was already included in
+ the live_regs_mask. */
+ lrm_count += (lrm_count % 2 ? 2 : 1);
+
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && !call_used_regs[reg])
+ {
+ asm_fprintf (f, "\twldrd\t%r, [%r, #-%d]\n",
+ reg, FP_REGNUM, lrm_count * 4);
+ lrm_count += 2;
+ }
+ }
+
/* saved_regs_mask should contain the IP, which at the time of stack
frame generation actually contains the old stack pointer. So a
quick way to unwind the stack is just pop the IP register directly
@@ -7684,8 +8666,22 @@ arm_output_epilogue (really_return)
saved_regs_mask &= ~ (1 << LR_REGNUM);
else
saved_regs_mask &= ~ (1 << PC_REGNUM);
-
- print_multi_reg (f, "ldmea\t%r", FP_REGNUM, saved_regs_mask);
+
+ /* We must use SP as the base register, because SP is one of the
+ registers being restored. If an interrupt or page fault
+ happens in the ldm instruction, the SP might or might not
+ have been restored. That would be bad, as then SP will no
+ longer indicate the safe area of stack, and we can get stack
+ corruption. Using SP as the base register means that it will
+ be reset correctly to the original value, should an interrupt
+ occur. If the stack pointer already points at the right
+ place, then omit the subtraction. */
+ if (((frame_size + current_function_outgoing_args_size + floats_offset)
+ != 4 * (1 + (int) bit_count (saved_regs_mask)))
+ || current_function_calls_alloca)
+ asm_fprintf (f, "\tsub\t%r, %r, #%d\n", SP_REGNUM, FP_REGNUM,
+ 4 * bit_count (saved_regs_mask));
+ print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
if (IS_INTERRUPT (func_type))
/* Interrupt handlers will have pushed the
@@ -7703,7 +8699,7 @@ arm_output_epilogue (really_return)
output_add_immediate (operands);
}
- if (arm_fpu_arch == FP_SOFT2)
+ if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
{
for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
if (regs_ever_live[reg] && !call_used_regs[reg])
@@ -7742,6 +8738,11 @@ arm_output_epilogue (really_return)
start_reg, reg - start_reg, SP_REGNUM);
}
+ if (TARGET_IWMMXT)
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && !call_used_regs[reg])
+ asm_fprintf (f, "\twldrd\t%r, [%r, #+8]!\n", reg, SP_REGNUM);
+
/* If we can, restore the LR into the PC. */
if (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
&& really_return
@@ -7784,13 +8785,6 @@ arm_output_epilogue (really_return)
}
}
-#if 0
- if (ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER)
- /* Adjust the stack to remove the exception handler stuff. */
- asm_fprintf (f, "\tadd\t%r, %r, %r\n", SP_REGNUM, SP_REGNUM,
- REGNO (eh_ofs));
-#endif
-
if (! really_return
|| (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
&& current_function_pretend_args_size == 0
@@ -7842,9 +8836,8 @@ arm_output_epilogue (really_return)
}
static void
-arm_output_function_epilogue (file, frame_size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT frame_size;
+arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT frame_size)
{
if (TARGET_THUMB)
{
@@ -7858,7 +8851,7 @@ arm_output_function_epilogue (file, frame_size)
/* We need to take into account any stack-frame rounding. */
frame_size = arm_get_frame_size ();
- if (use_return_insn (FALSE)
+ if (use_return_insn (FALSE, NULL)
&& return_used_this_function
&& (frame_size + current_function_outgoing_args_size) != 0
&& !frame_pointer_needed)
@@ -7873,10 +8866,8 @@ arm_output_function_epilogue (file, frame_size)
Unfortunately, since this insn does not reflect very well the actual
semantics of the operation, we need to annotate the insn for the benefit
of DWARF2 frame unwind information. */
-
static rtx
-emit_multi_reg_push (mask)
- int mask;
+emit_multi_reg_push (int mask)
{
int num_regs = 0;
int num_dwarf_regs;
@@ -8002,9 +8993,7 @@ emit_multi_reg_push (mask)
}
static rtx
-emit_sfm (base_reg, count)
- int base_reg;
- int count;
+emit_sfm (int base_reg, int count)
{
rtx par;
rtx dwarf;
@@ -8094,11 +9083,8 @@ emit_sfm (base_reg, count)
The sign of the number returned reflects the direction of stack
growth, so the values are positive for all eliminations except
from the soft frame pointer to the hard frame pointer. */
-
unsigned int
-arm_compute_initial_elimination_offset (from, to)
- unsigned int from;
- unsigned int to;
+arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
{
unsigned int local_vars = arm_get_frame_size ();
unsigned int outgoing_args = current_function_outgoing_args_size;
@@ -8118,34 +9104,32 @@ arm_compute_initial_elimination_offset (from, to)
/* Make sure that we compute which registers will be saved
on the stack using the same algorithm that is used by
- arm_compute_save_reg_mask(). */
- reg_mask = arm_compute_save_reg0_reg12_mask ();
+ the prologue creation code. */
+ reg_mask = arm_compute_save_reg_mask ();
/* Now count the number of bits set in save_reg_mask.
- For each set bit we need 4 bytes of stack space. */
- while (reg_mask)
- {
- call_saved_registers += 4;
- reg_mask = reg_mask & ~ (reg_mask & - reg_mask);
- }
-
- if ((regs_ever_live[LR_REGNUM]
- /* If optimizing for size, then we save the link register if
- any other integer register is saved. This gives a smaller
- return sequence. */
- || (optimize_size && call_saved_registers > 0))
- /* But if a stack frame is going to be created, the LR will
- be saved as part of that, so we do not need to allow for
- it here. */
- && ! frame_pointer_needed)
- call_saved_registers += 4;
+ If we have already counted the registers in the stack
+ frame, do not count them again. Non call-saved registers
+ might be saved in the call-save area of the stack, if
+ doing so will preserve the stack's alignment. Hence we
+ must count them here. For each set bit we need 4 bytes
+ of stack space. */
+ if (frame_pointer_needed)
+ reg_mask &= 0x07ff;
+ call_saved_registers += 4 * bit_count (reg_mask);
/* If the hard floating point registers are going to be
used then they must be saved on the stack as well.
Each register occupies 12 bytes of stack space. */
- for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg ++)
+ for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
if (regs_ever_live[reg] && ! call_used_regs[reg])
call_saved_registers += 12;
+
+ if (TARGET_REALLY_IWMMXT)
+ /* Check for the call-saved iWMMXt registers. */
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && ! call_used_regs [reg])
+ call_saved_registers += 8;
}
/* The stack frame contains 4 registers - the old frame pointer,
@@ -8227,13 +9211,12 @@ arm_compute_initial_elimination_offset (from, to)
/* Calculate the size of the stack frame, taking into account any
padding that is required to ensure stack-alignment. */
-
HOST_WIDE_INT
-arm_get_frame_size ()
+arm_get_frame_size (void)
{
int regno;
- int base_size = ROUND_UP (get_frame_size ());
+ int base_size = ROUND_UP_WORD (get_frame_size ());
int entry_size = 0;
unsigned long func_type = arm_current_func_type ();
int leaf;
@@ -8288,6 +9271,14 @@ arm_get_frame_size ()
entry_size += 12;
}
+ if (TARGET_REALLY_IWMMXT)
+ {
+ /* Check for the call-saved iWMMXt registers. */
+ for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
+ if (regs_ever_live [regno] && ! call_used_regs [regno])
+ entry_size += 8;
+ }
+
if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
base_size += 4;
if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
@@ -8299,9 +9290,8 @@ arm_get_frame_size ()
}
/* Generate the prologue instructions for entry into an ARM function. */
-
void
-arm_expand_prologue ()
+arm_expand_prologue (void)
{
int reg;
rtx amount;
@@ -8460,12 +9450,24 @@ arm_expand_prologue ()
RTX_FRAME_RELATED_P (insn) = 1;
}
+ if (TARGET_IWMMXT)
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && ! call_used_regs [reg])
+ {
+ insn = gen_rtx_PRE_DEC (V2SImode, stack_pointer_rtx);
+ insn = gen_rtx_MEM (V2SImode, insn);
+ insn = emit_insn (gen_rtx_SET (VOIDmode, insn,
+ gen_rtx_REG (V2SImode, reg)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
if (! IS_VOLATILE (func_type))
{
- /* Save any floating point call-saved registers used by this function. */
- if (arm_fpu_arch == FP_SOFT2)
+ /* Save any floating point call-saved registers used by this
+ function. */
+ if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
{
- for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg --)
+ for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
if (regs_ever_live[reg] && !call_used_regs[reg])
{
insn = gen_rtx_PRE_DEC (XFmode, stack_pointer_rtx);
@@ -8479,7 +9481,7 @@ arm_expand_prologue ()
{
int start_reg = LAST_ARM_FP_REGNUM;
- for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg --)
+ for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
{
if (regs_ever_live[reg] && !call_used_regs[reg])
{
@@ -8524,7 +9526,8 @@ arm_expand_prologue ()
insn = gen_rtx_REG (SImode, 3);
else /* if (current_function_pretend_args_size == 0) */
{
- insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx, GEN_INT (4));
+ insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx,
+ GEN_INT (4));
insn = gen_rtx_MEM (SImode, insn);
}
@@ -8587,12 +9590,8 @@ arm_expand_prologue ()
before output.
If CODE is 'B' then output a bitwise inverted value of X (a const int).
If X is a REG and CODE is `M', output a ldm/stm style multi-reg. */
-
void
-arm_print_operand (stream, x, code)
- FILE * stream;
- rtx x;
- int code;
+arm_print_operand (FILE *stream, rtx x, int code)
{
switch (code)
{
@@ -8655,6 +9654,16 @@ arm_print_operand (stream, x, code)
fprintf (stream, "%s", arithmetic_instr (x, 1));
return;
+ /* Truncate Cirrus shift counts. */
+ case 's':
+ if (GET_CODE (x) == CONST_INT)
+ {
+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x3f);
+ return;
+ }
+ arm_print_operand (stream, x, 0);
+ return;
+
case 'I':
fprintf (stream, "%s", arithmetic_instr (x, 0));
return;
@@ -8670,10 +9679,7 @@ arm_print_operand (stream, x, code)
if (val == -1)
arm_print_operand (stream, XEXP (x, 1), 0);
else
- {
- fputc ('#', stream);
- fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
- }
+ fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val);
}
}
return;
@@ -8682,13 +9688,13 @@ arm_print_operand (stream, x, code)
In a pair of registers containing a DI or DF value the 'Q'
operand returns the register number of the register containing
- the least signficant part of the value. The 'R' operand returns
+ the least significant part of the value. The 'R' operand returns
the register number of the register containing the most
significant part of the value.
The 'H' operand returns the higher of the two register numbers.
On a run where WORDS_BIG_ENDIAN is true the 'H' operand is the
- same as the 'Q' operand, since the most signficant part of the
+ same as the 'Q' operand, since the most significant part of the
value is held in the lower number register. The reverse is true
on systems where WORDS_BIG_ENDIAN is false.
@@ -8740,11 +9746,8 @@ arm_print_operand (stream, x, code)
if (x == const_true_rtx)
return;
- if (TARGET_ARM)
- fputs (arm_condition_codes[get_arm_condition_code (x)],
- stream);
- else
- fputs (thumb_condition_code (x, 0), stream);
+ fputs (arm_condition_codes[get_arm_condition_code (x)],
+ stream);
return;
case 'D':
@@ -8753,12 +9756,76 @@ arm_print_operand (stream, x, code)
if (x == const_true_rtx)
abort ();
- if (TARGET_ARM)
- fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
- (get_arm_condition_code (x))],
- stream);
+ fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
+ (get_arm_condition_code (x))],
+ stream);
+ return;
+
+ /* Cirrus registers can be accessed in a variety of ways:
+ single floating point (f)
+ double floating point (d)
+ 32bit integer (fx)
+ 64bit integer (dx). */
+ case 'W': /* Cirrus register in F mode. */
+ case 'X': /* Cirrus register in D mode. */
+ case 'Y': /* Cirrus register in FX mode. */
+ case 'Z': /* Cirrus register in DX mode. */
+ if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
+ abort ();
+
+ fprintf (stream, "mv%s%s",
+ code == 'W' ? "f"
+ : code == 'X' ? "d"
+ : code == 'Y' ? "fx" : "dx", reg_names[REGNO (x)] + 2);
+
+ return;
+
+ /* Print cirrus register in the mode specified by the register's mode. */
+ case 'V':
+ {
+ int mode = GET_MODE (x);
+
+ if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
+ abort ();
+
+ fprintf (stream, "mv%s%s",
+ mode == DFmode ? "d"
+ : mode == SImode ? "fx"
+ : mode == DImode ? "dx"
+ : "f", reg_names[REGNO (x)] + 2);
+
+ return;
+ }
+
+ case 'U':
+ if (GET_CODE (x) != REG
+ || REGNO (x) < FIRST_IWMMXT_GR_REGNUM
+ || REGNO (x) > LAST_IWMMXT_GR_REGNUM)
+ /* Bad value for wCG register number. */
+ abort ();
+ else
+ fprintf (stream, "%d", REGNO (x) - FIRST_IWMMXT_GR_REGNUM);
+ return;
+
+ /* Print an iWMMXt control register name. */
+ case 'w':
+ if (GET_CODE (x) != CONST_INT
+ || INTVAL (x) < 0
+ || INTVAL (x) >= 16)
+ /* Bad value for wC register number. */
+ abort ();
else
- fputs (thumb_condition_code (x, 1), stream);
+ {
+ static const char * wc_reg_names [16] =
+ {
+ "wCID", "wCon", "wCSSF", "wCASF",
+ "wC4", "wC5", "wC6", "wC7",
+ "wCGR0", "wCGR1", "wCGR2", "wCGR3",
+ "wC12", "wC13", "wC14", "wC15"
+ };
+
+ fprintf (stream, wc_reg_names [INTVAL (x)]);
+ }
return;
default:
@@ -8787,12 +9854,8 @@ arm_print_operand (stream, x, code)
#ifndef AOF_ASSEMBLER
/* Target hook for assembling integer objects. The ARM version needs to
handle word-sized values specially. */
-
static bool
-arm_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
if (size == UNITS_PER_WORD && aligned_p)
{
@@ -8800,13 +9863,13 @@ arm_assemble_integer (x, size, aligned_p)
output_addr_const (asm_out_file, x);
/* Mark symbols as position independent. We only do this in the
- .text segment, not in the .data segment. */
+ .text segment, not in the .data segment. */
if (NEED_GOT_RELOC && flag_pic && making_const_table &&
(GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
{
if (GET_CODE (x) == SYMBOL_REF
&& (CONSTANT_POOL_ADDRESS_P (x)
- || ENCODED_SHORT_CALL_ATTR_P (XSTR (x, 0))))
+ || SYMBOL_REF_LOCAL_P (x)))
fputs ("(GOTOFF)", asm_out_file);
else if (GET_CODE (x) == LABEL_REF)
fputs ("(GOTOFF)", asm_out_file);
@@ -8817,6 +9880,36 @@ arm_assemble_integer (x, size, aligned_p)
return true;
}
+ if (VECTOR_MODE_SUPPORTED_P (GET_MODE (x)))
+ {
+ int i, units;
+
+ if (GET_CODE (x) != CONST_VECTOR)
+ abort ();
+
+ units = CONST_VECTOR_NUNITS (x);
+
+ switch (GET_MODE (x))
+ {
+ case V2SImode: size = 4; break;
+ case V4HImode: size = 2; break;
+ case V8QImode: size = 1; break;
+ default:
+ abort ();
+ }
+
+ for (i = 0; i < units; i++)
+ {
+ rtx elt;
+
+ elt = CONST_VECTOR_ELT (x, i);
+ assemble_integer
+ (elt, size, i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, 1);
+ }
+
+ return true;
+ }
+
return default_assemble_integer (x, size, aligned_p);
}
#endif
@@ -8838,7 +9931,7 @@ arm_assemble_integer (x, size, aligned_p)
0 -> 2 final_prescan_insn if the `target' is an unconditional branch
1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
- 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL if the `target' label is reached
+ 3 -> 0 (*targetm.asm_out.internal_label) if the `target' label is reached
(the target label has CODE_LABEL_NUMBER equal to arm_target_label).
4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
(the target insn is arm_target_insn).
@@ -8855,10 +9948,8 @@ arm_assemble_integer (x, size, aligned_p)
/* Returns the index of the ARM condition code string in
`arm_condition_codes'. COMPARISON should be an rtx like
`(eq (...) (...))'. */
-
static enum arm_cond_code
-get_arm_condition_code (comparison)
- rtx comparison;
+get_arm_condition_code (rtx comparison)
{
enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
int code;
@@ -8907,6 +9998,14 @@ get_arm_condition_code (comparison)
default: abort ();
}
+ case CC_Nmode:
+ switch (comp_code)
+ {
+ case NE: return ARM_MI;
+ case EQ: return ARM_PL;
+ default: abort ();
+ }
+
case CCFPEmode:
case CCFPmode:
/* These encodings assume that AC=1 in the FPA system control
@@ -8978,10 +10077,8 @@ get_arm_condition_code (comparison)
abort ();
}
-
void
-arm_final_prescan_insn (insn)
- rtx insn;
+arm_final_prescan_insn (rtx insn)
{
/* BODY will hold the body of INSN. */
rtx body = PATTERN (insn);
@@ -9065,15 +10162,6 @@ arm_final_prescan_insn (insn)
if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
body = XVECEXP (body, 0, 0);
-#if 0
- /* If this is a conditional return then we don't want to know */
- if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
- && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
- && (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN
- || GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN))
- return;
-#endif
-
if (reverse
|| (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
&& GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
@@ -9201,7 +10289,8 @@ arm_final_prescan_insn (insn)
/* If this is an unconditional branch to the same label, succeed.
If it is to another label, do nothing. If it is conditional,
fail. */
- /* XXX Probably, the tests for SET and the PC are unnecessary. */
+ /* XXX Probably, the tests for SET and the PC are
+ unnecessary. */
scanbody = PATTERN (this_insn);
if (GET_CODE (scanbody) == SET
@@ -9219,7 +10308,7 @@ arm_final_prescan_insn (insn)
/* Fail if a conditional return is undesirable (eg on a
StrongARM), but still allow this if optimizing for size. */
else if (GET_CODE (scanbody) == RETURN
- && !use_return_insn (TRUE)
+ && !use_return_insn (TRUE, NULL)
&& !optimize_size)
fail = TRUE;
else if (GET_CODE (scanbody) == RETURN
@@ -9252,6 +10341,18 @@ arm_final_prescan_insn (insn)
|| GET_CODE (scanbody) == PARALLEL)
|| get_attr_conds (this_insn) != CONDS_NOCOND)
fail = TRUE;
+
+ /* A conditional cirrus instruction must be followed by
+ a non Cirrus instruction. However, since we
+ conditionalize instructions in this function and by
+ the time we get here we can't add instructions
+ (nops), because shorten_branches() has already been
+ called, we will disable conditionalizing Cirrus
+ instructions to be safe. */
+ if (GET_CODE (scanbody) != USE
+ && GET_CODE (scanbody) != CLOBBER
+ && get_attr_cirrus (this_insn) != CIRRUS_NOT)
+ fail = TRUE;
break;
default:
@@ -9273,7 +10374,7 @@ arm_final_prescan_insn (insn)
}
if (!this_insn)
{
- /* Oh, dear! we ran off the end.. give up */
+ /* Oh, dear! we ran off the end.. give up. */
recog (PATTERN (insn), insn, NULL);
arm_ccfsm_state = 0;
arm_target_insn = NULL;
@@ -9318,11 +10419,8 @@ arm_final_prescan_insn (insn)
/* Returns true if REGNO is a valid register
for holding a quantity of tyoe MODE. */
-
int
-arm_hard_regno_mode_ok (regno, mode)
- unsigned int regno;
- enum machine_mode mode;
+arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
{
if (GET_MODE_CLASS (mode) == MODE_CC)
return regno == CC_REGNUM;
@@ -9335,8 +10433,22 @@ arm_hard_regno_mode_ok (regno, mode)
start of an even numbered register pair. */
return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
+ if (IS_CIRRUS_REGNUM (regno))
+ /* We have outlawed SI values in Cirrus registers because they
+ reside in the lower 32 bits, but SF values reside in the
+ upper 32 bits. This causes gcc all sorts of grief. We can't
+ even split the registers into pairs because Cirrus SI values
+ get sign extended to 64bits-- aldyh. */
+ return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode);
+
+ if (IS_IWMMXT_GR_REGNUM (regno))
+ return mode == SImode;
+
+ if (IS_IWMMXT_REGNUM (regno))
+ return VALID_IWMMXT_REG_MODE (mode);
+
if (regno <= LAST_ARM_REGNUM)
- /* We allow any value to be stored in the general regisetrs. */
+ /* We allow any value to be stored in the general registers. */
return 1;
if ( regno == FRAME_POINTER_REGNUM
@@ -9344,7 +10456,7 @@ arm_hard_regno_mode_ok (regno, mode)
/* We only allow integers in the fake hard registers. */
return GET_MODE_CLASS (mode) == MODE_INT;
- /* The only registers left are the FPU registers
+ /* The only registers left are the FPA registers
which we only allow to hold FP values. */
return GET_MODE_CLASS (mode) == MODE_FLOAT
&& regno >= FIRST_ARM_FP_REGNUM
@@ -9352,8 +10464,7 @@ arm_hard_regno_mode_ok (regno, mode)
}
int
-arm_regno_class (regno)
- int regno;
+arm_regno_class (int regno)
{
if (TARGET_THUMB)
{
@@ -9374,16 +10485,22 @@ arm_regno_class (regno)
if (regno == CC_REGNUM)
return NO_REGS;
- return FPU_REGS;
+ if (IS_CIRRUS_REGNUM (regno))
+ return CIRRUS_REGS;
+
+ if (IS_IWMMXT_REGNUM (regno))
+ return IWMMXT_REGS;
+
+ if (IS_IWMMXT_GR_REGNUM (regno))
+ return IWMMXT_GR_REGS;
+
+ return FPA_REGS;
}
/* Handle a special case when computing the offset
of an argument from the frame pointer. */
-
int
-arm_debugger_arg_offset (value, addr)
- int value;
- rtx addr;
+arm_debugger_arg_offset (int value, rtx addr)
{
rtx insn;
@@ -9434,7 +10551,7 @@ arm_debugger_arg_offset (value, addr)
which is the frame pointer
a constant integer
- then... */
+ then... */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
@@ -9462,30 +10579,568 @@ arm_debugger_arg_offset (value, addr)
return value;
}
+
+#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
+ do \
+ { \
+ if ((MASK) & insn_flags) \
+ builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE); \
+ } \
+ while (0)
+
+struct builtin_description
+{
+ const unsigned int mask;
+ const enum insn_code icode;
+ const char * const name;
+ const enum arm_builtins code;
+ const enum rtx_code comparison;
+ const unsigned int flag;
+};
-#define def_builtin(NAME, TYPE, CODE) \
- builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
+static const struct builtin_description bdesc_2arg[] =
+{
+#define IWMMXT_BUILTIN(code, string, builtin) \
+ { FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \
+ ARM_BUILTIN_##builtin, 0, 0 },
+
+ IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
+ IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
+ IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
+ IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
+ IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
+ IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
+ IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
+ IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
+ IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
+ IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
+ IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
+ IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
+ IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
+ IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
+ IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
+ IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
+ IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
+ IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
+ IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
+ IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsh", WMULSH)
+ IWMMXT_BUILTIN (umulv4hi3_highpart, "wmuluh", WMULUH)
+ IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
+ IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
+ IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
+ IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
+ IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
+ IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
+ IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
+ IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
+ IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
+ IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
+ IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
+ IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
+ IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
+ IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
+ IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
+ IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
+ IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
+ IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
+ IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
+ IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
+ IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
+ IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
+ IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
+ IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
+ IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
+ IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
+ IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
+ IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
+ IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
+ IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
+ IWMMXT_BUILTIN (iwmmxt_wmadds, "wmadds", WMADDS)
+ IWMMXT_BUILTIN (iwmmxt_wmaddu, "wmaddu", WMADDU)
+
+#define IWMMXT_BUILTIN2(code, builtin) \
+ { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, 0, 0 },
+
+ IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
+ IWMMXT_BUILTIN2 (ashlv4hi3_di, WSLLH)
+ IWMMXT_BUILTIN2 (ashlv4hi3, WSLLHI)
+ IWMMXT_BUILTIN2 (ashlv2si3_di, WSLLW)
+ IWMMXT_BUILTIN2 (ashlv2si3, WSLLWI)
+ IWMMXT_BUILTIN2 (ashldi3_di, WSLLD)
+ IWMMXT_BUILTIN2 (ashldi3_iwmmxt, WSLLDI)
+ IWMMXT_BUILTIN2 (lshrv4hi3_di, WSRLH)
+ IWMMXT_BUILTIN2 (lshrv4hi3, WSRLHI)
+ IWMMXT_BUILTIN2 (lshrv2si3_di, WSRLW)
+ IWMMXT_BUILTIN2 (lshrv2si3, WSRLWI)
+ IWMMXT_BUILTIN2 (lshrdi3_di, WSRLD)
+ IWMMXT_BUILTIN2 (lshrdi3, WSRLDI)
+ IWMMXT_BUILTIN2 (ashrv4hi3_di, WSRAH)
+ IWMMXT_BUILTIN2 (ashrv4hi3, WSRAHI)
+ IWMMXT_BUILTIN2 (ashrv2si3_di, WSRAW)
+ IWMMXT_BUILTIN2 (ashrv2si3, WSRAWI)
+ IWMMXT_BUILTIN2 (ashrdi3_di, WSRAD)
+ IWMMXT_BUILTIN2 (ashrdi3, WSRADI)
+ IWMMXT_BUILTIN2 (rorv4hi3_di, WRORH)
+ IWMMXT_BUILTIN2 (rorv4hi3, WRORHI)
+ IWMMXT_BUILTIN2 (rorv2si3_di, WRORW)
+ IWMMXT_BUILTIN2 (rorv2si3, WRORWI)
+ IWMMXT_BUILTIN2 (rordi3_di, WRORD)
+ IWMMXT_BUILTIN2 (rordi3, WRORDI)
+ IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
+ IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
+};
-void
-arm_init_builtins ()
+static const struct builtin_description bdesc_1arg[] =
+{
+ IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
+ IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
+ IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
+ IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
+ IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
+ IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
+};
+
+/* Set up all the iWMMXt builtins. This is
+ not called if TARGET_IWMMXT is zero. */
+
+static void
+arm_init_iwmmxt_builtins (void)
{
+ const struct builtin_description * d;
+ size_t i;
tree endlink = void_list_node;
- tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
- tree pchar_type_node = build_pointer_type (char_type_node);
- tree int_ftype_int, void_ftype_pchar;
+ tree int_ftype_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node, endlink));
+ tree v8qi_ftype_v8qi_v8qi_int
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree v4hi_ftype_v4hi_int
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree v2si_ftype_v2si_int
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree v2si_ftype_di_di
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ endlink)));
+ tree di_ftype_di_int
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree di_ftype_di_int_int
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree int_ftype_v8qi
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink));
+ tree int_ftype_v4hi
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink));
+ tree int_ftype_v2si
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink));
+ tree int_ftype_v8qi_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree int_ftype_v4hi_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree int_ftype_v2si_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree v8qi_ftype_v8qi_int_int
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree v4hi_ftype_v4hi_int_int
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree v2si_ftype_v2si_int_int
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ /* Miscellaneous. */
+ tree v8qi_ftype_v4hi_v4hi
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+ tree v4hi_ftype_v2si_v2si
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink)));
+ tree v2si_ftype_v4hi_v4hi
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+ tree v2si_ftype_v8qi_v8qi
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink)));
+ tree v4hi_ftype_v4hi_di
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE,
+ long_long_integer_type_node,
+ endlink)));
+ tree v2si_ftype_v2si_di
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE,
+ long_long_integer_type_node,
+ endlink)));
+ tree void_ftype_int_int
+ = build_function_type (void_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree di_ftype_void
+ = build_function_type (long_long_unsigned_type_node, endlink);
+ tree di_ftype_v8qi
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink));
+ tree di_ftype_v4hi
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink));
+ tree di_ftype_v2si
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink));
+ tree v2si_ftype_v4hi
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink));
+ tree v4hi_ftype_v8qi
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink));
+
+ tree di_ftype_di_v4hi_v4hi
+ = build_function_type (long_long_unsigned_type_node,
+ tree_cons (NULL_TREE,
+ long_long_unsigned_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE,
+ V4HI_type_node,
+ endlink))));
+
+ tree di_ftype_v4hi_v4hi
+ = build_function_type (long_long_unsigned_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+
+ /* Normal vector binops. */
+ tree v8qi_ftype_v8qi_v8qi
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink)));
+ tree v4hi_ftype_v4hi_v4hi
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+ tree v2si_ftype_v2si_v2si
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink)));
+ tree di_ftype_di_di
+ = build_function_type (long_long_unsigned_type_node,
+ tree_cons (NULL_TREE, long_long_unsigned_type_node,
+ tree_cons (NULL_TREE,
+ long_long_unsigned_type_node,
+ endlink)));
+
+ /* Add all builtins that are more or less simple operations on two
+ operands. */
+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+ {
+ /* Use one of the operands; the target can have a different mode for
+ mask-generating compares. */
+ enum machine_mode mode;
+ tree type;
+
+ if (d->name == 0)
+ continue;
+
+ mode = insn_data[d->icode].operand[1].mode;
+
+ switch (mode)
+ {
+ case V8QImode:
+ type = v8qi_ftype_v8qi_v8qi;
+ break;
+ case V4HImode:
+ type = v4hi_ftype_v4hi_v4hi;
+ break;
+ case V2SImode:
+ type = v2si_ftype_v2si_v2si;
+ break;
+ case DImode:
+ type = di_ftype_di_di;
+ break;
+
+ default:
+ abort ();
+ }
+
+ def_mbuiltin (d->mask, d->name, type, d->code);
+ }
+
+ /* Add the remaining MMX insns with somewhat more complicated types. */
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wzero", di_ftype_void, ARM_BUILTIN_WZERO);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_setwcx", void_ftype_int_int, ARM_BUILTIN_SETWCX);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_getwcx", int_ftype_int, ARM_BUILTIN_GETWCX);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSLLH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllw", v2si_ftype_v2si_di, ARM_BUILTIN_WSLLW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslld", di_ftype_di_di, ARM_BUILTIN_WSLLD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSLLHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSLLWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslldi", di_ftype_di_int, ARM_BUILTIN_WSLLDI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRLH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRLW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrld", di_ftype_di_di, ARM_BUILTIN_WSRLD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRLHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRLWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrldi", di_ftype_di_int, ARM_BUILTIN_WSRLDI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrah", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRAH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsraw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRAW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrad", di_ftype_di_di, ARM_BUILTIN_WSRAD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrahi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRAHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrawi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRAWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsradi", di_ftype_di_int, ARM_BUILTIN_WSRADI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WRORH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorw", v2si_ftype_v2si_di, ARM_BUILTIN_WRORW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrord", di_ftype_di_di, ARM_BUILTIN_WRORD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WRORHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorwi", v2si_ftype_v2si_int, ARM_BUILTIN_WRORWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrordi", di_ftype_di_int, ARM_BUILTIN_WRORDI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wshufh", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSHUFH);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadb", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadh", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadbz", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADBZ);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadhz", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADHZ);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsb", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMSB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMSH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMSW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmub", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMUB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMUH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMUW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrb", v8qi_ftype_v8qi_int_int, ARM_BUILTIN_TINSRB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrh", v4hi_ftype_v4hi_int_int, ARM_BUILTIN_TINSRH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrw", v2si_ftype_v2si_int_int, ARM_BUILTIN_TINSRW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccb", di_ftype_v8qi, ARM_BUILTIN_WACCB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wacch", di_ftype_v4hi, ARM_BUILTIN_WACCH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccw", di_ftype_v2si, ARM_BUILTIN_WACCW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskb", int_ftype_v8qi, ARM_BUILTIN_TMOVMSKB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskh", int_ftype_v4hi, ARM_BUILTIN_TMOVMSKH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskw", int_ftype_v2si, ARM_BUILTIN_TMOVMSKW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhss", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHSS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhus", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHUS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwus", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWUS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwss", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWSS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdus", v2si_ftype_di_di, ARM_BUILTIN_WPACKDUS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdss", v2si_ftype_di_di, ARM_BUILTIN_WPACKDSS);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHUB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHUH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHUW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHSB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHSH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHSW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELUB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELUH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELUW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELSB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELSH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELSW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacs", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacsz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACSZ);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacu", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACU);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacuz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACUZ);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_walign", v8qi_ftype_v8qi_v8qi_int, ARM_BUILTIN_WALIGN);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmia", di_ftype_di_int_int, ARM_BUILTIN_TMIA);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiaph", di_ftype_di_int_int, ARM_BUILTIN_TMIAPH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabb", di_ftype_di_int_int, ARM_BUILTIN_TMIABB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabt", di_ftype_di_int_int, ARM_BUILTIN_TMIABT);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatb", di_ftype_di_int_int, ARM_BUILTIN_TMIATB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatt", di_ftype_di_int_int, ARM_BUILTIN_TMIATT);
+}
+
+static void
+arm_init_builtins (void)
+{
+ if (TARGET_REALLY_IWMMXT)
+ arm_init_iwmmxt_builtins ();
+}
+
+/* Errors in the source file can cause expand_expr to return const0_rtx
+ where we expect a vector. To avoid crashing, use one of the vector
+ clear instructions. */
+
+static rtx
+safe_vector_operand (rtx x, enum machine_mode mode)
+{
+ if (x != const0_rtx)
+ return x;
+ x = gen_reg_rtx (mode);
+
+ emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
+ : gen_rtx_SUBREG (DImode, x, 0)));
+ return x;
+}
+
+/* Subroutine of arm_expand_builtin to take care of binop insns. */
+
+static rtx
+arm_expand_binop_builtin (enum insn_code icode,
+ tree arglist, rtx target)
+{
+ rtx pat;
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+ enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+
+ if (VECTOR_MODE_P (mode0))
+ op0 = safe_vector_operand (op0, mode0);
+ if (VECTOR_MODE_P (mode1))
+ op1 = safe_vector_operand (op1, mode1);
+
+ if (! target
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ /* In case the insn wants input operands in modes different from
+ the result, abort. */
+ if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
+ abort ();
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ pat = GEN_FCN (icode) (target, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+}
- /* void func (char *) */
- void_ftype_pchar
- = build_function_type_list (void_type_node, pchar_type_node, NULL_TREE);
+/* Subroutine of arm_expand_builtin to take care of unop insns. */
- /* int func (int) */
- int_ftype_int
- = build_function_type (integer_type_node, int_endlink);
+static rtx
+arm_expand_unop_builtin (enum insn_code icode,
+ tree arglist, rtx target, int do_load)
+{
+ rtx pat;
+ tree arg0 = TREE_VALUE (arglist);
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+
+ if (! target
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ if (do_load)
+ op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ else
+ {
+ if (VECTOR_MODE_P (mode0))
+ op0 = safe_vector_operand (op0, mode0);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ }
- /* Initialize arm V5 builtins. */
- if (arm_arch5)
- def_builtin ("__builtin_clz", int_ftype_int, ARM_BUILTIN_CLZ);
+ pat = GEN_FCN (icode) (target, op0);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
}
/* Expand an expression EXP that calls a built-in function,
@@ -9494,47 +11149,223 @@ arm_init_builtins ()
SUBTARGET may be used as the target for computing one of EXP's operands.
IGNORE is nonzero if the value is to be ignored. */
-rtx
-arm_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
-{
- enum insn_code icode;
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- tree arglist = TREE_OPERAND (exp, 1);
- tree arg0;
- rtx op0, pat;
- enum machine_mode tmode, mode0;
- int fcode = DECL_FUNCTION_CODE (fndecl);
+static rtx
+arm_expand_builtin (tree exp,
+ rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
+{
+ const struct builtin_description * d;
+ enum insn_code icode;
+ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg0;
+ tree arg1;
+ tree arg2;
+ rtx op0;
+ rtx op1;
+ rtx op2;
+ rtx pat;
+ int fcode = DECL_FUNCTION_CODE (fndecl);
+ size_t i;
+ enum machine_mode tmode;
+ enum machine_mode mode0;
+ enum machine_mode mode1;
+ enum machine_mode mode2;
switch (fcode)
{
- default:
- break;
-
- case ARM_BUILTIN_CLZ:
- icode = CODE_FOR_clz;
+ case ARM_BUILTIN_TEXTRMSB:
+ case ARM_BUILTIN_TEXTRMUB:
+ case ARM_BUILTIN_TEXTRMSH:
+ case ARM_BUILTIN_TEXTRMUH:
+ case ARM_BUILTIN_TEXTRMSW:
+ case ARM_BUILTIN_TEXTRMUW:
+ icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
+ : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
+ : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
+ : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
+ : CODE_FOR_iwmmxt_textrmw);
+
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ tmode = insn_data[icode].operand[0].mode;
+ mode0 = insn_data[icode].operand[1].mode;
+ mode1 = insn_data[icode].operand[2].mode;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ {
+ /* @@@ better error message */
+ error ("selector must be an immediate");
+ return gen_reg_rtx (tmode);
+ }
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ pat = GEN_FCN (icode) (target, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+
+ case ARM_BUILTIN_TINSRB:
+ case ARM_BUILTIN_TINSRH:
+ case ARM_BUILTIN_TINSRW:
+ icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
+ : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
+ : CODE_FOR_iwmmxt_tinsrw);
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
+ tmode = insn_data[icode].operand[0].mode;
+ mode0 = insn_data[icode].operand[1].mode;
+ mode1 = insn_data[icode].operand[2].mode;
+ mode2 = insn_data[icode].operand[3].mode;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+ if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
+ {
+ /* @@@ better error message */
+ error ("selector must be an immediate");
+ return const0_rtx;
+ }
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ pat = GEN_FCN (icode) (target, op0, op1, op2);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+
+ case ARM_BUILTIN_SETWCX:
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ emit_insn (gen_iwmmxt_tmcr (op0, op1));
+ return 0;
+
+ case ARM_BUILTIN_GETWCX:
+ arg0 = TREE_VALUE (arglist);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ target = gen_reg_rtx (SImode);
+ emit_insn (gen_iwmmxt_tmrc (target, op0));
+ return target;
+
+ case ARM_BUILTIN_WSHUFH:
+ icode = CODE_FOR_iwmmxt_wshufh;
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ tmode = insn_data[icode].operand[0].mode;
+ mode1 = insn_data[icode].operand[1].mode;
+ mode2 = insn_data[icode].operand[2].mode;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
+ op0 = copy_to_mode_reg (mode1, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
+ {
+ /* @@@ better error message */
+ error ("mask must be an immediate");
+ return const0_rtx;
+ }
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ pat = GEN_FCN (icode) (target, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+
+ case ARM_BUILTIN_WSADB:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadb, arglist, target);
+ case ARM_BUILTIN_WSADH:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadh, arglist, target);
+ case ARM_BUILTIN_WSADBZ:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, arglist, target);
+ case ARM_BUILTIN_WSADHZ:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, arglist, target);
+
+ /* Several three-argument builtins. */
+ case ARM_BUILTIN_WMACS:
+ case ARM_BUILTIN_WMACU:
+ case ARM_BUILTIN_WALIGN:
+ case ARM_BUILTIN_TMIA:
+ case ARM_BUILTIN_TMIAPH:
+ case ARM_BUILTIN_TMIATT:
+ case ARM_BUILTIN_TMIATB:
+ case ARM_BUILTIN_TMIABT:
+ case ARM_BUILTIN_TMIABB:
+ icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
+ : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
+ : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
+ : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
+ : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
+ : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
+ : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
+ : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
+ : CODE_FOR_iwmmxt_walign);
arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
+ mode1 = insn_data[icode].operand[2].mode;
+ mode2 = insn_data[icode].operand[3].mode;
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+ if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
+ op2 = copy_to_mode_reg (mode2, op2);
if (target == 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
- pat = GEN_FCN (icode) (target, op0);
+ pat = GEN_FCN (icode) (target, op0, op1, op2);
if (! pat)
return 0;
emit_insn (pat);
return target;
+
+ case ARM_BUILTIN_WZERO:
+ target = gen_reg_rtx (DImode);
+ emit_insn (gen_iwmmxt_clrdi (target));
+ return target;
+
+ default:
+ break;
}
+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+ if (d->code == (const enum arm_builtins) fcode)
+ return arm_expand_binop_builtin (d->icode, arglist, target);
+
+ for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
+ if (d->code == (const enum arm_builtins) fcode)
+ return arm_expand_unop_builtin (d->icode, arglist, target, 0);
+
/* @@@ Should really do something sensible here. */
return NULL_RTX;
}
@@ -9543,12 +11374,8 @@ arm_expand_builtin (exp, target, subtarget, mode, ignore)
checking to see if any of the variables created in that
function match the RTX called 'orig'. If they do then
replace them with the RTX called 'new'. */
-
static void
-replace_symbols_in_block (block, orig, new)
- tree block;
- rtx orig;
- rtx new;
+replace_symbols_in_block (tree block, rtx orig, rtx new)
{
for (; block; block = BLOCK_CHAIN (block))
{
@@ -9577,12 +11404,8 @@ replace_symbols_in_block (block, orig, new)
/* Return the number (counting from 0) of
the least significant set bit in MASK. */
-#ifdef __GNUC__
-inline
-#endif
-static int
-number_of_first_bit_set (mask)
- int mask;
+inline static int
+number_of_first_bit_set (int mask)
{
int bit;
@@ -9598,10 +11421,7 @@ number_of_first_bit_set (mask)
If 'reg_containing_return_addr' is -1, then the return address is
actually on the stack, at the stack pointer. */
static void
-thumb_exit (f, reg_containing_return_addr, eh_ofs)
- FILE * f;
- int reg_containing_return_addr;
- rtx eh_ofs;
+thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
{
unsigned regs_available_for_popping;
unsigned regs_to_pop;
@@ -9756,7 +11576,8 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
}
/* Pop as many registers as we can. */
- thumb_pushpop (f, regs_available_for_popping, FALSE);
+ thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
+ regs_available_for_popping);
/* Process the registers we popped. */
if (reg_containing_return_addr == -1)
@@ -9768,7 +11589,7 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
number_of_first_bit_set (regs_available_for_popping);
/* Remove this register for the mask of available registers, so that
- the return address will not be corrupted by futher pops. */
+ the return address will not be corrupted by further pops. */
regs_available_for_popping &= ~(1 << reg_containing_return_addr);
}
@@ -9837,7 +11658,8 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
int popped_into;
int move_to;
- thumb_pushpop (f, regs_available_for_popping, FALSE);
+ thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
+ regs_available_for_popping);
/* We have popped either FP or SP.
Move whichever one it is into the correct register. */
@@ -9857,7 +11679,8 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
{
int popped_into;
- thumb_pushpop (f, regs_available_for_popping, FALSE);
+ thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
+ regs_available_for_popping);
popped_into = number_of_first_bit_set (regs_available_for_popping);
@@ -9887,16 +11710,20 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
}
-/* Emit code to push or pop registers to or from the stack. */
-
+/* Emit code to push or pop registers to or from the stack. F is the
+ assembly file. MASK is the registers to push or pop. PUSH is
+ non-zero if we should push, and zero if we should pop. For debugging
+ output, if pushing, adjust CFA_OFFSET by the amount of space added
+ to the stack. REAL_REGS should have the same number of bits set as
+ MASK, and will be used instead (in the same order) to describe which
+ registers were saved - this is used to mark the save slots when we
+ push high registers after moving them to low registers. */
static void
-thumb_pushpop (f, mask, push)
- FILE * f;
- int mask;
- int push;
+thumb_pushpop (FILE *f, int mask, int push, int *cfa_offset, int real_regs)
{
int regno;
int lo_mask = mask & 0xFF;
+ int pushed_words = 0;
if (lo_mask == 0 && !push && (mask & (1 << 15)))
{
@@ -9917,6 +11744,8 @@ thumb_pushpop (f, mask, push)
if ((lo_mask & ~1) != 0)
fprintf (f, ", ");
+
+ pushed_words++;
}
}
@@ -9927,6 +11756,8 @@ thumb_pushpop (f, mask, push)
fprintf (f, ", ");
asm_fprintf (f, "%r", LR_REGNUM);
+
+ pushed_words++;
}
else if (!push && (mask & (1 << PC_REGNUM)))
{
@@ -9951,11 +11782,27 @@ thumb_pushpop (f, mask, push)
}
fprintf (f, "}\n");
+
+ if (push && pushed_words && dwarf2out_do_frame ())
+ {
+ char *l = dwarf2out_cfi_label ();
+ int pushed_mask = real_regs;
+
+ *cfa_offset += pushed_words * 4;
+ dwarf2out_def_cfa (l, SP_REGNUM, *cfa_offset);
+
+ pushed_words = 0;
+ pushed_mask = real_regs;
+ for (regno = 0; regno <= 14; regno++, pushed_mask >>= 1)
+ {
+ if (pushed_mask & 1)
+ dwarf2out_reg_save (l, regno, 4 * pushed_words++ - *cfa_offset);
+ }
+ }
}
void
-thumb_final_prescan_insn (insn)
- rtx insn;
+thumb_final_prescan_insn (rtx insn)
{
if (flag_print_asm_name)
asm_fprintf (asm_out_file, "%@ 0x%04x\n",
@@ -9963,8 +11810,7 @@ thumb_final_prescan_insn (insn)
}
int
-thumb_shiftable_const (val)
- unsigned HOST_WIDE_INT val;
+thumb_shiftable_const (unsigned HOST_WIDE_INT val)
{
unsigned HOST_WIDE_INT mask = 0xff;
int i;
@@ -9981,10 +11827,8 @@ thumb_shiftable_const (val)
/* Returns nonzero if the current function contains,
or might contain a far jump. */
-
int
-thumb_far_jump_used_p (in_prologue)
- int in_prologue;
+thumb_far_jump_used_p (int in_prologue)
{
rtx insn;
@@ -10039,7 +11883,7 @@ thumb_far_jump_used_p (in_prologue)
&& get_attr_far_jump (insn) == FAR_JUMP_YES
)
{
- /* Record the fact that we have decied that
+ /* Record the fact that we have decided that
the function does use far jumps. */
cfun->machine->far_jump_used = 1;
return 1;
@@ -10050,10 +11894,8 @@ thumb_far_jump_used_p (in_prologue)
}
/* Return nonzero if FUNC must be entered in ARM mode. */
-
int
-is_called_in_ARM_mode (func)
- tree func;
+is_called_in_ARM_mode (tree func)
{
if (TREE_CODE (func) != FUNCTION_DECL)
abort ();
@@ -10069,10 +11911,9 @@ is_called_in_ARM_mode (func)
#endif
}
-/* The bits which aren't usefully expanded as rtl. */
-
+/* The bits which aren't usefully expanded as rtl. */
const char *
-thumb_unexpanded_epilogue ()
+thumb_unexpanded_epilogue (void)
{
int regno;
int live_regs_mask = 0;
@@ -10096,7 +11937,7 @@ thumb_unexpanded_epilogue ()
high_regs_pushed++;
/* The prolog may have pushed some high registers to use as
- work registers. eg the testuite file:
+ work registers. eg the testsuite file:
gcc/testsuite/gcc/gcc.c-torture/execute/complex-2.c
compiles to produce:
push {r4, r5, r6, r7, lr}
@@ -10155,8 +11996,8 @@ thumb_unexpanded_epilogue ()
mask &= (2 << regno) - 1; /* A noop if regno == 8 */
- /* Pop the values into the low register(s). */
- thumb_pushpop (asm_out_file, mask, 0);
+ /* Pop the values into the low register(s). */
+ thumb_pushpop (asm_out_file, mask, 0, NULL, mask);
/* Move the value(s) into the high registers. */
for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
@@ -10183,7 +12024,7 @@ thumb_unexpanded_epilogue ()
{
/* The stack backtrace structure creation code had to
push R7 in order to get a work register, so we pop
- it now. */
+ it now. */
live_regs_mask |= (1 << LAST_LO_REGNUM);
}
@@ -10198,7 +12039,8 @@ thumb_unexpanded_epilogue ()
structure was created which includes an adjusted stack
pointer, so just pop everything. */
if (live_regs_mask)
- thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
+ thumb_pushpop (asm_out_file, live_regs_mask, FALSE, NULL,
+ live_regs_mask);
if (eh_ofs)
thumb_exit (asm_out_file, 2, eh_ofs);
@@ -10218,11 +12060,13 @@ thumb_unexpanded_epilogue ()
live_regs_mask &= ~(1 << PC_REGNUM);
if (live_regs_mask)
- thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
+ thumb_pushpop (asm_out_file, live_regs_mask, FALSE, NULL,
+ live_regs_mask);
if (had_to_push_lr)
/* Get the return address into a temporary register. */
- thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0);
+ thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0, NULL,
+ 1 << LAST_ARG_REGNUM);
/* Remove the argument registers that were pushed onto the stack. */
asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n",
@@ -10240,9 +12084,8 @@ thumb_unexpanded_epilogue ()
}
/* Functions to save and restore machine-specific function data. */
-
static struct machine_function *
-arm_init_machine_status ()
+arm_init_machine_status (void)
{
struct machine_function *machine;
machine = (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
@@ -10255,11 +12098,8 @@ arm_init_machine_status ()
/* Return an RTX indicating where the return address to the
calling function can be found. */
-
rtx
-arm_return_addr (count, frame)
- int count;
- rtx frame ATTRIBUTE_UNUSED;
+arm_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
{
if (count != 0)
return NULL_RTX;
@@ -10275,20 +12115,19 @@ arm_return_addr (count, frame)
}
/* Do anything needed before RTL is emitted for each function. */
-
void
-arm_init_expanders ()
+arm_init_expanders (void)
{
/* Arrange to initialize and mark the machine per-function status. */
init_machine_status = arm_init_machine_status;
}
HOST_WIDE_INT
-thumb_get_frame_size ()
+thumb_get_frame_size (void)
{
int regno;
- int base_size = ROUND_UP (get_frame_size ());
+ int base_size = ROUND_UP_WORD (get_frame_size ());
int count_regs = 0;
int entry_size = 0;
int leaf;
@@ -10370,10 +12209,11 @@ thumb_get_frame_size ()
}
/* Generate the rest of a function's prologue. */
-
void
-thumb_expand_prologue ()
+thumb_expand_prologue (void)
{
+ rtx insn, dwarf;
+
HOST_WIDE_INT amount = (thumb_get_frame_size ()
+ current_function_outgoing_args_size);
unsigned long func_type;
@@ -10391,15 +12231,21 @@ thumb_expand_prologue ()
}
if (frame_pointer_needed)
- emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
+ {
+ insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (amount)
{
- amount = ROUND_UP (amount);
+ amount = ROUND_UP_WORD (amount);
if (amount < 512)
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (- amount)));
+ {
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (- amount)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
else
{
int regno;
@@ -10429,7 +12275,7 @@ thumb_expand_prologue ()
{
rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
- /* Choose an arbitary, non-argument low register. */
+ /* Choose an arbitrary, non-argument low register. */
reg = gen_rtx (REG, SImode, LAST_LO_REGNUM);
/* Save it by copying it into a high, scratch register. */
@@ -10439,8 +12285,16 @@ thumb_expand_prologue ()
/* Decrement the stack. */
emit_insn (gen_movsi (reg, GEN_INT (- amount)));
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- reg));
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, reg));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ dwarf = gen_rtx_SET (SImode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ GEN_INT (- amount)));
+ RTX_FRAME_RELATED_P (dwarf) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
+ REG_NOTES (insn));
/* Restore the low register's original value. */
emit_insn (gen_movsi (reg, spare));
@@ -10456,8 +12310,17 @@ thumb_expand_prologue ()
reg = gen_rtx (REG, SImode, regno);
emit_insn (gen_movsi (reg, GEN_INT (- amount)));
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- reg));
+
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, reg));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ dwarf = gen_rtx_SET (SImode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ GEN_INT (- amount)));
+ RTX_FRAME_RELATED_P (dwarf) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
+ REG_NOTES (insn));
}
}
}
@@ -10467,11 +12330,12 @@ thumb_expand_prologue ()
}
void
-thumb_expand_epilogue ()
+thumb_expand_epilogue (void)
{
HOST_WIDE_INT amount = (thumb_get_frame_size ()
+ current_function_outgoing_args_size);
-
+ int regno;
+
/* Naked functions don't have prologues. */
if (IS_NAKED (arm_current_func_type ()))
return;
@@ -10480,7 +12344,7 @@ thumb_expand_epilogue ()
emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
else if (amount)
{
- amount = ROUND_UP (amount);
+ amount = ROUND_UP_WORD (amount);
if (amount < 512)
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
@@ -10501,15 +12365,23 @@ thumb_expand_epilogue ()
if (current_function_profile || TARGET_NO_SCHED_PRO)
emit_insn (gen_blockage ());
+
+ /* Emit a clobber for each insn that will be restored in the epilogue,
+ so that flow2 will get register lifetimes correct. */
+ for (regno = 0; regno < 13; regno++)
+ if (regs_ever_live[regno] && !call_used_regs[regno])
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, regno)));
+
+ if (! regs_ever_live[LR_REGNUM])
+ emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, LR_REGNUM)));
}
static void
-thumb_output_function_prologue (f, size)
- FILE * f;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
int live_regs_mask = 0;
int high_regs_pushed = 0;
+ int cfa_offset = 0;
int regno;
if (IS_NAKED (arm_current_func_type ()))
@@ -10536,7 +12408,7 @@ thumb_output_function_prologue (f, size)
the assembler to bypass the ARM code when this function
is called from a Thumb encoded function elsewhere in the
same file. Hence the definition of STUB_NAME here must
- agree with the definition in gas/config/tc-arm.c */
+ agree with the definition in gas/config/tc-arm.c. */
#define STUB_NAME ".real_start_of"
@@ -10572,6 +12444,16 @@ thumb_output_function_prologue (f, size)
asm_fprintf (f, "\tsub\t%r, %r, #%d\n",
SP_REGNUM, SP_REGNUM,
current_function_pretend_args_size);
+
+ /* We don't need to record the stores for unwinding (would it
+ help the debugger any if we did?), but record the change in
+ the stack pointer. */
+ if (dwarf2out_do_frame ())
+ {
+ char *l = dwarf2out_cfi_label ();
+ cfa_offset = cfa_offset + current_function_pretend_args_size;
+ dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
+ }
}
for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
@@ -10611,7 +12493,7 @@ thumb_output_function_prologue (f, size)
if (regs_ever_live [LAST_ARG_REGNUM] == 0)
work_register = LAST_ARG_REGNUM;
- else /* We must push a register of our own */
+ else /* We must push a register of our own. */
live_regs_mask |= (1 << LAST_LO_REGNUM);
}
@@ -10627,9 +12509,16 @@ thumb_output_function_prologue (f, size)
asm_fprintf
(f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
SP_REGNUM, SP_REGNUM);
-
+
+ if (dwarf2out_do_frame ())
+ {
+ char *l = dwarf2out_cfi_label ();
+ cfa_offset = cfa_offset + 16;
+ dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
+ }
+
if (live_regs_mask)
- thumb_pushpop (f, live_regs_mask, 1);
+ thumb_pushpop (f, live_regs_mask, 1, &cfa_offset, live_regs_mask);
for (offset = 0, wr = 1 << 15; wr != 0; wr >>= 1)
if (wr & live_regs_mask)
@@ -10673,7 +12562,7 @@ thumb_output_function_prologue (f, size)
ARM_HARD_FRAME_POINTER_REGNUM, work_register);
}
else if (live_regs_mask)
- thumb_pushpop (f, live_regs_mask, 1);
+ thumb_pushpop (f, live_regs_mask, 1, &cfa_offset, live_regs_mask);
for (regno = 8; regno < 13; regno++)
if (THUMB_REG_PUSHED_P (regno))
@@ -10701,6 +12590,8 @@ thumb_output_function_prologue (f, size)
while (high_regs_pushed > 0)
{
+ int real_regs_mask = 0;
+
for (regno = LAST_LO_REGNUM; regno >= 0; regno--)
{
if (mask & (1 << regno))
@@ -10708,6 +12599,7 @@ thumb_output_function_prologue (f, size)
asm_fprintf (f, "\tmov\t%r, %r\n", regno, next_hi_reg);
high_regs_pushed--;
+ real_regs_mask |= (1 << next_hi_reg);
if (high_regs_pushed)
{
@@ -10723,8 +12615,8 @@ thumb_output_function_prologue (f, size)
}
}
}
-
- thumb_pushpop (f, mask, 1);
+
+ thumb_pushpop (f, mask, 1, &cfa_offset, real_regs_mask);
}
if (pushable_regs == 0
@@ -10736,10 +12628,8 @@ thumb_output_function_prologue (f, size)
/* Handle the case of a double word load into a low register from
a computed memory address. The computed address may involve a
register which is overwritten by the load. */
-
const char *
-thumb_load_double_from_address (operands)
- rtx *operands;
+thumb_load_double_from_address (rtx *operands)
{
rtx addr;
rtx base;
@@ -10858,11 +12748,8 @@ thumb_load_double_from_address (operands)
return "";
}
-
const char *
-thumb_output_move_mem_multiple (n, operands)
- int n;
- rtx * operands;
+thumb_output_move_mem_multiple (int n, rtx *operands)
{
rtx tmp;
@@ -10911,10 +12798,8 @@ thumb_output_move_mem_multiple (n, operands)
}
/* Routines for generating rtl. */
-
void
-thumb_expand_movstrqi (operands)
- rtx * operands;
+thumb_expand_movstrqi (rtx *operands)
{
rtx out = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
rtx in = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
@@ -10964,70 +12849,58 @@ thumb_expand_movstrqi (operands)
}
int
-thumb_cmp_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+thumb_cmp_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT
- && (unsigned HOST_WIDE_INT) (INTVAL (op)) < 256)
- || register_operand (op, mode));
+ && INTVAL (op) < 256
+ && INTVAL (op) >= 0)
+ || s_register_operand (op, mode));
}
-static const char *
-thumb_condition_code (x, invert)
- rtx x;
- int invert;
+int
+thumb_cmpneg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- static const char * const conds[] =
- {
- "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le"
- };
- int val;
+ return (GET_CODE (op) == CONST_INT
+ && INTVAL (op) < 0
+ && INTVAL (op) > -256);
+}
- switch (GET_CODE (x))
- {
- case EQ: val = 0; break;
- case NE: val = 1; break;
- case GEU: val = 2; break;
- case LTU: val = 3; break;
- case GTU: val = 8; break;
- case LEU: val = 9; break;
- case GE: val = 10; break;
- case LT: val = 11; break;
- case GT: val = 12; break;
- case LE: val = 13; break;
- default:
- abort ();
- }
+/* Return TRUE if a result can be stored in OP without clobbering the
+ condition code register. Prior to reload we only accept a
+ register. After reload we have to be able to handle memory as
+ well, since a pseudo may not get a hard reg and reload cannot
+ handle output-reloads on jump insns.
+
+ We could possibly handle mem before reload as well, but that might
+ complicate things with the need to handle increment
+ side-effects. */
- return conds[val ^ invert];
+int
+thumb_cbrch_target_operand (rtx op, enum machine_mode mode)
+{
+ return (s_register_operand (op, mode)
+ || ((reload_in_progress || reload_completed)
+ && memory_operand (op, mode)));
}
/* Handle storing a half-word to memory during reload. */
-
void
-thumb_reload_out_hi (operands)
- rtx * operands;
+thumb_reload_out_hi (rtx *operands)
{
emit_insn (gen_thumb_movhi_clobber (operands[0], operands[1], operands[2]));
}
-/* Handle storing a half-word to memory during reload. */
-
+/* Handle reading a half-word from memory during reload. */
void
-thumb_reload_in_hi (operands)
- rtx * operands ATTRIBUTE_UNUSED;
+thumb_reload_in_hi (rtx *operands ATTRIBUTE_UNUSED)
{
abort ();
}
/* Return the length of a function name prefix
that starts with the character 'c'. */
-
static int
-arm_get_strip_length (c)
- int c;
+arm_get_strip_length (int c)
{
switch (c)
{
@@ -11038,10 +12911,8 @@ arm_get_strip_length (c)
/* Return a pointer to a function's name with any
and all prefix encodings stripped from it. */
-
const char *
-arm_strip_name_encoding (name)
- const char * name;
+arm_strip_name_encoding (const char *name)
{
int skip;
@@ -11054,11 +12925,8 @@ arm_strip_name_encoding (name)
/* If there is a '*' anywhere in the name's prefix, then
emit the stripped name verbatim, otherwise prepend an
underscore if leading underscores are being used. */
-
void
-arm_asm_output_labelref (stream, name)
- FILE * stream;
- const char * name;
+arm_asm_output_labelref (FILE *stream, const char *name)
{
int skip;
int verbatim = 0;
@@ -11089,8 +12957,7 @@ struct pic_chain
static struct pic_chain * aof_pic_chain = NULL;
rtx
-aof_pic_entry (x)
- rtx x;
+aof_pic_entry (rtx x)
{
struct pic_chain ** chainp;
int offset;
@@ -11112,8 +12979,7 @@ aof_pic_entry (x)
}
void
-aof_dump_pic_table (f)
- FILE * f;
+aof_dump_pic_table (FILE *f)
{
struct pic_chain * chain;
@@ -11136,7 +13002,7 @@ aof_dump_pic_table (f)
int arm_text_section_count = 1;
char *
-aof_text_section ()
+aof_text_section (void )
{
static char buf[100];
sprintf (buf, "\tAREA |C$$code%d|, CODE, READONLY",
@@ -11149,7 +13015,7 @@ aof_text_section ()
static int arm_data_section_count = 1;
char *
-aof_data_section ()
+aof_data_section (void)
{
static char buf[100];
sprintf (buf, "\tAREA |C$$data%d|, DATA", arm_data_section_count++);
@@ -11175,8 +13041,7 @@ struct import
static struct import * imports_list = NULL;
void
-aof_add_import (name)
- const char * name;
+aof_add_import (const char *name)
{
struct import * new;
@@ -11191,8 +13056,7 @@ aof_add_import (name)
}
void
-aof_delete_import (name)
- const char * name;
+aof_delete_import (const char *name)
{
struct import ** old;
@@ -11208,9 +13072,8 @@ aof_delete_import (name)
int arm_main_function = 0;
-void
-aof_dump_imports (f)
- FILE * f;
+static void
+aof_dump_imports (FILE *f)
{
/* The AOF assembler needs this to cause the startup code to be extracted
from the library. Brining in __main causes the whole thing to work
@@ -11233,14 +13096,52 @@ aof_dump_imports (f)
}
static void
-aof_globalize_label (stream, name)
- FILE *stream;
- const char *name;
+aof_globalize_label (FILE *stream, const char *name)
{
default_globalize_label (stream, name);
if (! strcmp (name, "main"))
arm_main_function = 1;
}
+
+static void
+aof_file_start (void)
+{
+ fputs ("__r0\tRN\t0\n", asm_out_file);
+ fputs ("__a1\tRN\t0\n", asm_out_file);
+ fputs ("__a2\tRN\t1\n", asm_out_file);
+ fputs ("__a3\tRN\t2\n", asm_out_file);
+ fputs ("__a4\tRN\t3\n", asm_out_file);
+ fputs ("__v1\tRN\t4\n", asm_out_file);
+ fputs ("__v2\tRN\t5\n", asm_out_file);
+ fputs ("__v3\tRN\t6\n", asm_out_file);
+ fputs ("__v4\tRN\t7\n", asm_out_file);
+ fputs ("__v5\tRN\t8\n", asm_out_file);
+ fputs ("__v6\tRN\t9\n", asm_out_file);
+ fputs ("__sl\tRN\t10\n", asm_out_file);
+ fputs ("__fp\tRN\t11\n", asm_out_file);
+ fputs ("__ip\tRN\t12\n", asm_out_file);
+ fputs ("__sp\tRN\t13\n", asm_out_file);
+ fputs ("__lr\tRN\t14\n", asm_out_file);
+ fputs ("__pc\tRN\t15\n", asm_out_file);
+ fputs ("__f0\tFN\t0\n", asm_out_file);
+ fputs ("__f1\tFN\t1\n", asm_out_file);
+ fputs ("__f2\tFN\t2\n", asm_out_file);
+ fputs ("__f3\tFN\t3\n", asm_out_file);
+ fputs ("__f4\tFN\t4\n", asm_out_file);
+ fputs ("__f5\tFN\t5\n", asm_out_file);
+ fputs ("__f6\tFN\t6\n", asm_out_file);
+ fputs ("__f7\tFN\t7\n", asm_out_file);
+ text_section ();
+}
+
+static void
+aof_file_end (void)
+{
+ if (flag_pic)
+ aof_dump_pic_table (asm_out_file);
+ aof_dump_imports (asm_out_file);
+ fputs ("\tEND\n", asm_out_file);
+}
#endif /* AOF_ASSEMBLER */
#ifdef OBJECT_FORMAT_ELF
@@ -11252,9 +13153,7 @@ aof_globalize_label (stream, name)
used before the section type. */
static void
-arm_elf_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+arm_elf_asm_named_section (const char *name, unsigned int flags)
{
char flagchars[10], *f = flagchars;
@@ -11309,20 +13208,14 @@ arm_elf_asm_named_section (name, flags)
simplification. */
static void
-arm_encode_section_info (decl, first)
- tree decl;
- int first;
+arm_encode_section_info (tree decl, rtx rtl, int first)
{
/* This doesn't work with AOF syntax, since the string table may be in
a different AREA. */
#ifndef AOF_ASSEMBLER
if (optimize > 0 && TREE_CONSTANT (decl)
&& (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
- {
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
- }
+ SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
#endif
/* If we are referencing a function that is weak then encode a long call
@@ -11338,24 +13231,43 @@ arm_encode_section_info (decl, first)
}
#endif /* !ARM_PE */
+static void
+arm_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
+{
+ if (arm_ccfsm_state == 3 && (unsigned) arm_target_label == labelno
+ && !strcmp (prefix, "L"))
+ {
+ arm_ccfsm_state = 0;
+ arm_target_insn = NULL;
+ }
+ default_internal_label (stream, prefix, labelno);
+}
+
/* Output code to add DELTA to the first argument, and then jump
to FUNCTION. Used for C++ multiple inheritance. */
-
static void
-arm_output_mi_thunk (file, thunk, delta, vcall_offset, function)
- FILE *file;
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
+arm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ tree function)
{
+ static int thunk_label = 0;
+ char label[256];
int mi_delta = delta;
const char *const mi_op = mi_delta < 0 ? "sub" : "add";
int shift = 0;
- int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)))
+ int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
? 1 : 0);
if (mi_delta < 0)
mi_delta = - mi_delta;
+ if (TARGET_THUMB)
+ {
+ int labelno = thunk_label++;
+ ASM_GENERATE_INTERNAL_LABEL (label, "LTHUMBFUNC", labelno);
+ fputs ("\tldr\tr12, ", file);
+ assemble_name (file, label);
+ fputc ('\n', file);
+ }
while (mi_delta != 0)
{
if ((mi_delta & (3 << shift)) == 0)
@@ -11369,10 +13281,78 @@ arm_output_mi_thunk (file, thunk, delta, vcall_offset, function)
shift += 8;
}
}
- fputs ("\tb\t", file);
- assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
- if (NEED_PLT_RELOC)
- fputs ("(PLT)", file);
- fputc ('\n', file);
+ if (TARGET_THUMB)
+ {
+ fprintf (file, "\tbx\tr12\n");
+ ASM_OUTPUT_ALIGN (file, 2);
+ assemble_name (file, label);
+ fputs (":\n", file);
+ assemble_integer (XEXP (DECL_RTL (function), 0), 4, BITS_PER_WORD, 1);
+ }
+ else
+ {
+ fputs ("\tb\t", file);
+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+ if (NEED_PLT_RELOC)
+ fputs ("(PLT)", file);
+ fputc ('\n', file);
+ }
+}
+
+int
+arm_emit_vector_const (FILE *file, rtx x)
+{
+ int i;
+ const char * pattern;
+
+ if (GET_CODE (x) != CONST_VECTOR)
+ abort ();
+
+ switch (GET_MODE (x))
+ {
+ case V2SImode: pattern = "%08x"; break;
+ case V4HImode: pattern = "%04x"; break;
+ case V8QImode: pattern = "%02x"; break;
+ default: abort ();
+ }
+
+ fprintf (file, "0x");
+ for (i = CONST_VECTOR_NUNITS (x); i--;)
+ {
+ rtx element;
+
+ element = CONST_VECTOR_ELT (x, i);
+ fprintf (file, pattern, INTVAL (element));
+ }
+
+ return 1;
}
+const char *
+arm_output_load_gr (rtx *operands)
+{
+ rtx reg;
+ rtx offset;
+ rtx wcgr;
+ rtx sum;
+
+ if (GET_CODE (operands [1]) != MEM
+ || GET_CODE (sum = XEXP (operands [1], 0)) != PLUS
+ || GET_CODE (reg = XEXP (sum, 0)) != REG
+ || GET_CODE (offset = XEXP (sum, 1)) != CONST_INT
+ || ((INTVAL (offset) < 1024) && (INTVAL (offset) > -1024)))
+ return "wldrw%?\t%0, %1";
+
+ /* Fix up an out-of-range load of a GR register. */
+ output_asm_insn ("str%?\t%0, [sp, #-4]!\t@ Start of GR load expansion", & reg);
+ wcgr = operands[0];
+ operands[0] = reg;
+ output_asm_insn ("ldr%?\t%0, %1", operands);
+
+ operands[0] = wcgr;
+ operands[1] = reg;
+ output_asm_insn ("tmcr%?\t%0, %1", operands);
+ output_asm_insn ("ldr%?\t%0, [sp], #4\t@ End of GR load expansion", & reg);
+
+ return "";
+}
diff --git a/contrib/gcc/config/arm/arm.h b/contrib/gcc/config/arm/arm.h
index eda2d47..3a13d91 100644
--- a/contrib/gcc/config/arm/arm.h
+++ b/contrib/gcc/config/arm/arm.h
@@ -1,27 +1,27 @@
/* Definitions of target machine for GNU compiler, for ARM.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com)
Minor hacks by Nick Clifton (nickc@cygnus.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#ifndef GCC_ARM_H
#define GCC_ARM_H
@@ -96,6 +96,12 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
#define TARGET_CPU_xscale 0x0100
+#define TARGET_CPU_ep9312 0x0200
+#define TARGET_CPU_iwmmxt 0x0400
+#define TARGET_CPU_arm926ej_s 0x0800
+#define TARGET_CPU_arm1026ej_s 0x1000
+#define TARGET_CPU_arm1136j_s 0x2000
+#define TARGET_CPU_arm1136jf_s 0x4000
/* Configure didn't specify. */
#define TARGET_CPU_generic 0x8000
@@ -124,12 +130,12 @@ extern GTY(()) rtx arm_compare_op1;
/* The label of the current constant pool. */
extern rtx pool_vector_label;
/* Set to 1 when a return insn is output, this means that the epilogue
- is not needed. */
+ is not needed. */
extern int return_used_this_function;
/* Used to produce AOF syntax assembler. */
extern GTY(()) rtx aof_pic_label;
-/* Just in case configure has failed to define anything. */
+/* Just in case configure has failed to define anything. */
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT TARGET_CPU_generic
#endif
@@ -164,7 +170,21 @@ extern GTY(()) rtx aof_pic_label;
#if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
#else
-Unrecognized value in TARGET_CPU_DEFAULT.
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ep9312
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__ -D__MAVERICK__"
+/* Set TARGET_DEFAULT to the default, but without soft-float. */
+#ifdef TARGET_DEFAULT
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+ (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS | ARM_FLAG_APCS_FRAME)
+#endif
+#else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_iwmmxt
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__ -D__IWMMXT__"
+#else
+#error Unrecognized value in TARGET_CPU_DEFAULT.
+#endif
+#endif
#endif
#endif
#endif
@@ -212,6 +232,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{march=strongarm1100:-D__ARM_ARCH_4__} \
%{march=xscale:-D__ARM_ARCH_5TE__} \
%{march=xscale:-D__XSCALE__} \
+%{march=ep9312:-D__ARM_ARCH_4T__} \
+%{march=ep9312:-D__MAVERICK__} \
%{march=armv2:-D__ARM_ARCH_2__} \
%{march=armv2a:-D__ARM_ARCH_2__} \
%{march=armv3:-D__ARM_ARCH_3__} \
@@ -251,6 +273,11 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
%{mcpu=xscale:-D__ARM_ARCH_5TE__} \
%{mcpu=xscale:-D__XSCALE__} \
+ %{mcpu=ep9312:-D__ARM_ARCH_4T__} \
+ %{mcpu=ep9312:-D__MAVERICK__} \
+ %{mcpu=iwmmxt:-D__ARM_ARCH_5TE__} \
+ %{mcpu=iwmmxt:-D__XSCALE__} \
+ %{mcpu=iwmmxt:-D__IWMMXT__} \
%{!mcpu*:%(cpp_cpu_arch_default)}} \
"
@@ -263,7 +290,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -345,7 +372,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
function tries to return. */
#define ARM_FLAG_ABORT_NORETURN (1 << 13)
-/* Nonzero if function prologues should not load the PIC register. */
+/* Nonzero if function prologues should not load the PIC register. */
#define ARM_FLAG_SINGLE_PIC_BASE (1 << 14)
/* Nonzero if all call instructions should be indirect. */
@@ -376,6 +403,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
/* Nonzero means to use ARM/Thumb Procedure Call Standard conventions. */
#define ARM_FLAG_ATPCS (1 << 22)
+/* Fix invalid Cirrus instruction combinations by inserting NOPs. */
+#define CIRRUS_FIX_INVALID_INSNS (1 << 23)
+
#define TARGET_APCS_FRAME (target_flags & ARM_FLAG_APCS_FRAME)
#define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE)
#define TARGET_FPE (target_flags & ARM_FLAG_FPE)
@@ -387,6 +417,10 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define TARGET_MMU_TRAPS (target_flags & ARM_FLAG_MMU_TRAPS)
#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
+#define TARGET_CIRRUS (arm_is_cirrus)
+#define TARGET_ANY_HARD_FLOAT (TARGET_HARD_FLOAT || TARGET_CIRRUS)
+#define TARGET_IWMMXT (arm_arch_iwmmxt)
+#define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_ARM)
#define TARGET_VFP (target_flags & ARM_FLAG_VFP)
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
#define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK)
@@ -403,6 +437,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define TARGET_BACKTRACE (leaf_function_p () \
? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \
: (target_flags & THUMB_FLAG_BACKTRACE))
+#define TARGET_CIRRUS_FIX_INVALID_INSNS (target_flags & CIRRUS_FIX_INVALID_INSNS)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis. */
#ifndef SUBTARGET_SWITCHES
@@ -421,8 +456,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
{"fpe", ARM_FLAG_FPE, "" }, \
{"apcs-32", ARM_FLAG_APCS_32, \
N_("Use the 32-bit version of the APCS") }, \
- {"apcs-26", -ARM_FLAG_APCS_32, \
- N_("Use the 26-bit version of the APCS") }, \
+ {"apcs-26", -ARM_FLAG_APCS_32, ""}, \
{"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \
{"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \
{"apcs-float", ARM_FLAG_APCS_FLOAT, \
@@ -434,10 +468,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
{"alignment-traps", ARM_FLAG_MMU_TRAPS, \
N_("The MMU will trap on unaligned accesses") }, \
{"no-alignment-traps", -ARM_FLAG_MMU_TRAPS, "" }, \
- {"short-load-bytes", ARM_FLAG_MMU_TRAPS, "" }, \
- {"no-short-load-bytes", -ARM_FLAG_MMU_TRAPS, "" }, \
- {"short-load-words", -ARM_FLAG_MMU_TRAPS, "" }, \
- {"no-short-load-words", ARM_FLAG_MMU_TRAPS, "" }, \
{"soft-float", ARM_FLAG_SOFT_FLOAT, \
N_("Use library calls to perform FP operations") }, \
{"hard-float", -ARM_FLAG_SOFT_FLOAT, \
@@ -481,6 +511,10 @@ Unrecognized value in TARGET_CPU_DEFAULT.
N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \
{"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING, \
"" }, \
+ {"cirrus-fix-invalid-insns", CIRRUS_FIX_INVALID_INSNS, \
+ N_("Cirrus: Place NOPs to avoid invalid instruction combinations") }, \
+ {"no-cirrus-fix-invalid-insns", -CIRRUS_FIX_INVALID_INSNS, \
+ N_("Cirrus: Do not break up invalid instruction combinations with NOPs") },\
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT, "" } \
}
@@ -488,19 +522,33 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define TARGET_OPTIONS \
{ \
{"cpu=", & arm_select[0].string, \
- N_("Specify the name of the target CPU") }, \
+ N_("Specify the name of the target CPU"), 0}, \
{"arch=", & arm_select[1].string, \
- N_("Specify the name of the target architecture") }, \
- {"tune=", & arm_select[2].string, "" }, \
- {"fpe=", & target_fp_name, "" }, \
+ N_("Specify the name of the target architecture"), 0}, \
+ {"tune=", & arm_select[2].string, "", 0}, \
+ {"fpe=", & target_fp_name, "" , 0}, \
{"fp=", & target_fp_name, \
- N_("Specify the version of the floating point emulator") }, \
+ N_("Specify the version of the floating point emulator"), 0},\
{"structure-size-boundary=", & structure_size_string, \
- N_("Specify the minimum bit alignment of structures") }, \
+ N_("Specify the minimum bit alignment of structures"), 0}, \
{"pic-register=", & arm_pic_register_string, \
- N_("Specify the register to be used for PIC addressing") } \
+ N_("Specify the register to be used for PIC addressing"), 0} \
}
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-arch is ignored if -march or -mcpu are specified.
+ --with-cpu is ignored if -march or -mcpu are specified, and is overridden
+ by --with-arch.
+ --with-tune is ignored if -mtune or -mcpu are specified (but not affected
+ by -march).
+ --with-float is ignored if -mhard-float or -msoft-float are
+ specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
+ {"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mcpu=*:%{!mtune=*:-mtune=%(VALUE)}}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
+
struct arm_cpu_select
{
const char * string;
@@ -519,33 +567,45 @@ enum prog_mode_type
prog_mode32
};
-/* Recast the program mode class to be the prog_mode attribute */
+/* Recast the program mode class to be the prog_mode attribute. */
#define arm_prog_mode ((enum attr_prog_mode) arm_prgmode)
extern enum prog_mode_type arm_prgmode;
/* What sort of floating point unit do we have? Hardware or software.
If software, is it issue 2 or issue 3? */
-enum floating_point_type
+enum fputype
{
- FP_HARD,
- FP_SOFT2,
- FP_SOFT3
+ /* Software floating point, FPA style double fmt. */
+ FPUTYPE_SOFT_FPA,
+ /* Full FPA support. */
+ FPUTYPE_FPA,
+ /* Emulated FPA hardware, Issue 2 emulator (no LFM/SFM). */
+ FPUTYPE_FPA_EMU2,
+ /* Emulated FPA hardware, Issue 3 emulator. */
+ FPUTYPE_FPA_EMU3,
+ /* Cirrus Maverick floating point co-processor. */
+ FPUTYPE_MAVERICK
};
/* Recast the floating point class to be the floating point attribute. */
-#define arm_fpu_attr ((enum attr_fpu) arm_fpu)
+#define arm_fpu_attr ((enum attr_fpu) arm_fpu_tune)
/* What type of floating point to tune for */
-extern enum floating_point_type arm_fpu;
+extern enum fputype arm_fpu_tune;
/* What type of floating point instructions are available */
-extern enum floating_point_type arm_fpu_arch;
+extern enum fputype arm_fpu_arch;
/* Default floating point architecture. Override in sub-target if
necessary. */
-#ifndef FP_DEFAULT
-#define FP_DEFAULT FP_SOFT2
+#ifndef FPUTYPE_DEFAULT
+#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU2
+#endif
+
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ep9312
+#undef FPUTYPE_DEFAULT
+#define FPUTYPE_DEFAULT FPUTYPE_MAVERICK
#endif
/* Nonzero if the processor has a fast multiply insn, and one that does
@@ -570,14 +630,23 @@ extern int thumb_code;
/* Nonzero if this chip is a StrongARM. */
extern int arm_is_strong;
+/* Nonzero if this chip is a Cirrus variant. */
+extern int arm_is_cirrus;
+
+/* Nonzero if this chip supports Intel XScale with Wireless MMX technology. */
+extern int arm_arch_iwmmxt;
+
/* Nonzero if this chip is an XScale. */
-extern int arm_is_xscale;
+extern int arm_arch_xscale;
+
+/* Nonzero if tuning for XScale */
+extern int arm_tune_xscale;
/* Nonzero if this chip is an ARM6 or an ARM7. */
extern int arm_is_6_or_7;
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
/* The frame pointer register used in gcc has nothing to do with debugging;
@@ -641,20 +710,6 @@ extern int arm_is_6_or_7;
/* This is required to ensure that push insns always push a word. */
#define PROMOTE_FUNCTION_ARGS
-/* For the ARM:
- I think I have added all the code to make this work. Unfortunately,
- early releases of the floating point emulation code on RISCiX used a
- different format for extended precision numbers. On my RISCiX box there
- is a bug somewhere which causes the machine to lock up when running enquire
- with long doubles. There is the additional aspect that Norcroft C
- treats long doubles as doubles and we ought to remain compatible.
- Perhaps someone with an FPA coprocessor and not running RISCiX would like
- to try this someday. */
-/* #define LONG_DOUBLE_TYPE_SIZE 96 */
-
-/* Disable XFmode patterns in md file */
-#define ENABLE_XF_PATTERNS 0
-
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
#define BITS_BIG_ENDIAN 0
@@ -679,14 +734,16 @@ extern int arm_is_6_or_7;
#endif
/* Define this if most significant word of doubles is the lowest numbered.
- The rules are different based on whether or not we use FPA-format or
- VFP-format doubles. */
+ The rules are different based on whether or not we use FPA-format,
+ VFP-format or some other floating point co-processor's format doubles. */
#define FLOAT_WORDS_BIG_ENDIAN (arm_float_words_big_endian ())
#define UNITS_PER_WORD 4
#define PARM_BOUNDARY 32
+#define IWMMXT_ALIGNMENT 64
+
#define STACK_BOUNDARY 32
#define PREFERRED_STACK_BOUNDARY (TARGET_ATPCS ? 64 : 32)
@@ -700,13 +757,53 @@ extern int arm_is_6_or_7;
#define EMPTY_FIELD_BOUNDARY 32
-#define BIGGEST_ALIGNMENT 32
+#define BIGGEST_ALIGNMENT (TARGET_REALLY_IWMMXT ? 64 : 32)
+
+#define TYPE_NEEDS_IWMMXT_ALIGNMENT(TYPE) \
+ (TARGET_REALLY_IWMMXT \
+ && ((TREE_CODE (TYPE) == VECTOR_TYPE) || (TYPE_MODE (TYPE) == DImode) || (TYPE_MODE (TYPE) == DFmode)))
+
+/* XXX Blah -- this macro is used directly by libobjc. Since it
+ supports no vector modes, cut out the complexity and fall back
+ on BIGGEST_FIELD_ALIGNMENT. */
+#ifdef IN_TARGET_LIBS
+#define BIGGEST_FIELD_ALIGNMENT 64
+#else
+/* An expression for the alignment of a structure field FIELD if the
+ alignment computed in the usual way is COMPUTED. GCC uses this
+ value instead of the value in `BIGGEST_ALIGNMENT' or
+ `BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
+#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ (TYPE_NEEDS_IWMMXT_ALIGNMENT (TREE_TYPE (FIELD)) \
+ ? IWMMXT_ALIGNMENT \
+ : (COMPUTED))
+#endif
+
+/* If defined, a C expression to compute the alignment for a static variable.
+ TYPE is the data type, and ALIGN is the alignment that the object
+ would ordinarily have. The value of this macro is used instead of that
+ alignment to align the object.
+
+ If this macro is not defined, then ALIGN is used. */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ (TYPE_NEEDS_IWMMXT_ALIGNMENT (TYPE) ? IWMMXT_ALIGNMENT : ALIGN)
+
+/* If defined, a C expression to compute the alignment for a
+ variables in the local store. TYPE is the data type, and
+ BASIC-ALIGN is the alignment that the object would ordinarily
+ have. The value of this macro is used instead of that alignment
+ to align the object.
+
+ If this macro is not defined, then BASIC-ALIGN is used. */
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+ (TYPE_NEEDS_IWMMXT_ALIGNMENT (TYPE) ? IWMMXT_ALIGNMENT : ALIGN)
/* Make strings word-aligned so strcpy from constants will be faster. */
-#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2)
+#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_tune_xscale ? 1 : 2)
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- ((TREE_CODE (EXP) == STRING_CST \
+ ((TARGET_REALLY_IWMMXT && TREE_CODE (EXP) == VECTOR_TYPE) ? IWMMXT_ALIGNMENT : \
+ (TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR) \
? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (ALIGN))
@@ -721,7 +818,7 @@ extern int arm_structure_size_boundary;
/* This is the value used to initialize arm_structure_size_boundary. If a
particular arm target wants to change the default value it should change
- the definition of this macro, not STRUCTRUE_SIZE_BOUNDARY. See netbsd.h
+ the definition of this macro, not STRUCTURE_SIZE_BOUNDARY. See netbsd.h
for an example of this. */
#ifndef DEFAULT_STRUCTURE_SIZE_BOUNDARY
#define DEFAULT_STRUCTURE_SIZE_BOUNDARY 32
@@ -770,6 +867,11 @@ extern const char * structure_size_string;
*: See CONDITIONAL_REGISTER_USAGE */
+/*
+ mvf0 Cirrus floating point result
+ mvf1-mvf3 Cirrus floating point scratch
+ mvf4-mvf15 S Cirrus floating point variable. */
+
/* The stack backtrace structure is as follows:
fp points to here: | save code pointer | [fp]
| return link value | [fp, #-4]
@@ -799,7 +901,12 @@ extern const char * structure_size_string;
0,0,0,0,0,0,0,0, \
0,0,0,0,0,1,0,1, \
0,0,0,0,0,0,0,0, \
- 1,1,1 \
+ 1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1 \
}
/* 1 for registers not available across function calls.
@@ -809,13 +916,18 @@ extern const char * structure_size_string;
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like.
The CC is not preserved over function calls on the ARM 6, so it is
- easier to assume this for all. SFP is preserved, since FP is. */
+ easier to assume this for all. SFP is preserved, since FP is. */
#define CALL_USED_REGISTERS \
{ \
1,1,1,1,0,0,0,0, \
0,0,0,0,1,1,1,1, \
1,1,1,1,0,0,0,0, \
- 1,1,1 \
+ 1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1 \
}
#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
@@ -832,7 +944,57 @@ extern const char * structure_size_string;
regno <= LAST_ARM_FP_REGNUM; ++regno) \
fixed_regs[regno] = call_used_regs[regno] = 1; \
} \
- if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
+ \
+ if (TARGET_THUMB && optimize_size) \
+ { \
+ /* When optimizing for size, it's better not to use \
+ the HI regs, because of the overhead of stacking \
+ them. */ \
+ for (regno = FIRST_HI_REGNUM; \
+ regno <= LAST_HI_REGNUM; ++regno) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ } \
+ \
+ /* The link register can be clobbered by any branch insn, \
+ but we have no way to track that at present, so mark \
+ it as unavailable. */ \
+ if (TARGET_THUMB) \
+ fixed_regs[LR_REGNUM] = call_used_regs[LR_REGNUM] = 1; \
+ \
+ if (TARGET_CIRRUS) \
+ { \
+ for (regno = FIRST_ARM_FP_REGNUM; \
+ regno <= LAST_ARM_FP_REGNUM; ++ regno) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ for (regno = FIRST_CIRRUS_FP_REGNUM; \
+ regno <= LAST_CIRRUS_FP_REGNUM; ++ regno) \
+ { \
+ fixed_regs[regno] = 0; \
+ call_used_regs[regno] = regno < FIRST_CIRRUS_FP_REGNUM + 4; \
+ } \
+ } \
+ \
+ if (TARGET_REALLY_IWMMXT) \
+ { \
+ regno = FIRST_IWMMXT_GR_REGNUM; \
+ /* The 2002/10/09 revision of the XScale ABI has wCG0 \
+ and wCG1 as call-preserved registers. The 2002/11/21 \
+ revision changed this so that all wCG registers are \
+ scratch registers. */ \
+ for (regno = FIRST_IWMMXT_GR_REGNUM; \
+ regno <= LAST_IWMMXT_GR_REGNUM; ++ regno) \
+ fixed_regs[regno] = call_used_regs[regno] = 0; \
+ /* The XScale ABI has wR0 - wR9 as scratch registers, \
+ the rest as call-preserved registers. */ \
+ for (regno = FIRST_IWMMXT_REGNUM; \
+ regno <= LAST_IWMMXT_REGNUM; ++ regno) \
+ { \
+ fixed_regs[regno] = 0; \
+ call_used_regs[regno] = regno < FIRST_IWMMXT_REGNUM + 10; \
+ } \
+ } \
+ \
+ if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
@@ -850,7 +1012,7 @@ extern const char * structure_size_string;
SUBTARGET_CONDITIONAL_REGISTER_USAGE \
}
-/* These are a couple of extensions to the formats accecpted
+/* These are a couple of extensions to the formats accepted
by asm_fprintf:
%@ prints out ASM_COMMENT_START
%r prints out REGISTER_PREFIX reg_names[arg] */
@@ -865,7 +1027,7 @@ extern const char * structure_size_string;
break;
/* Round X up to the nearest word. */
-#define ROUND_UP(X) (((X) + 3) & ~3)
+#define ROUND_UP_WORD(X) (((X) + 3) & ~3)
/* Convert fron bytes to ints. */
#define ARM_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
@@ -882,7 +1044,7 @@ extern const char * structure_size_string;
/* The number of (integer) argument register available. */
#define NUM_ARG_REGS 4
-/* Return the regiser number of the N'th (integer) argument. */
+/* Return the register number of the N'th (integer) argument. */
#define ARG_REGISTER(N) (N - 1)
#if 0 /* FIXME: The ARM backend has special code to handle structure
@@ -905,8 +1067,11 @@ extern const char * structure_size_string;
/* The number of the last argument register. */
#define LAST_ARG_REGNUM ARG_REGISTER (NUM_ARG_REGS)
-/* The number of the last "lo" register (thumb). */
+/* The numbers of the Thumb register ranges. */
+#define FIRST_LO_REGNUM 0
#define LAST_LO_REGNUM 7
+#define FIRST_HI_REGNUM 8
+#define LAST_HI_REGNUM 11
/* The register that holds the return address in exception handlers. */
#define EXCEPTION_LR_REGNUM 2
@@ -922,7 +1087,7 @@ extern const char * structure_size_string;
should point to a special register that we will make sure is eliminated.
For the Thumb we have another problem. The TPCS defines the frame pointer
- as r11, and GCC belives that it is always possible to use the frame pointer
+ as r11, and GCC believes that it is always possible to use the frame pointer
as base register for addressing purposes. (See comments in
find_reloads_address()). But - the Thumb does not allow high registers,
including r11, to be used as base address registers. Hence our problem.
@@ -930,7 +1095,7 @@ extern const char * structure_size_string;
The solution used here, and in the old thumb port is to use r7 instead of
r11 as the hard frame pointer and to have special code to generate
backtrace structures on the stack (if required to do so via a command line
- option) using r11. This is the only 'user visable' use of r11 as a frame
+ option) using r11. This is the only 'user visible' use of r11 as a frame
pointer. */
#define ARM_HARD_FRAME_POINTER_REGNUM 11
#define THUMB_HARD_FRAME_POINTER_REGNUM 7
@@ -949,14 +1114,30 @@ extern const char * structure_size_string;
#define FIRST_ARM_FP_REGNUM 16
#define LAST_ARM_FP_REGNUM 23
+#define FIRST_IWMMXT_GR_REGNUM 43
+#define LAST_IWMMXT_GR_REGNUM 46
+#define FIRST_IWMMXT_REGNUM 47
+#define LAST_IWMMXT_REGNUM 62
+#define IS_IWMMXT_REGNUM(REGNUM) \
+ (((REGNUM) >= FIRST_IWMMXT_REGNUM) && ((REGNUM) <= LAST_IWMMXT_REGNUM))
+#define IS_IWMMXT_GR_REGNUM(REGNUM) \
+ (((REGNUM) >= FIRST_IWMMXT_GR_REGNUM) && ((REGNUM) <= LAST_IWMMXT_GR_REGNUM))
+
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 25
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM 26
-/* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP. */
-#define FIRST_PSEUDO_REGISTER 27
+#define FIRST_CIRRUS_FP_REGNUM 27
+#define LAST_CIRRUS_FP_REGNUM 42
+#define IS_CIRRUS_REGNUM(REGNUM) \
+ (((REGNUM) >= FIRST_CIRRUS_FP_REGNUM) && ((REGNUM) <= LAST_CIRRUS_FP_REGNUM))
+
+/* The number of hard registers is 16 ARM + 8 FPA + 1 CC + 1 SFP + 1 AFP. */
+/* + 16 Cirrus registers take us up to 43. */
+/* Intel Wireless MMX Technology registers add 16 + 4 more. */
+#define FIRST_PSEUDO_REGISTER 63
/* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms may be accessed
@@ -973,7 +1154,7 @@ extern const char * structure_size_string;
This is ordinarily the length in words of a value of mode MODE
but can be less for certain modes in special long registers.
- On the ARM regs are UNITS_PER_WORD bits wide; FPU regs can hold any FP
+ On the ARM regs are UNITS_PER_WORD bits wide; FPA regs can hold any FP
mode. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
((TARGET_ARM \
@@ -993,6 +1174,12 @@ extern const char * structure_size_string;
#define MODES_TIEABLE_P(MODE1, MODE2) \
(GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
+#define VECTOR_MODE_SUPPORTED_P(MODE) \
+ ((MODE) == V2SImode || (MODE) == V4HImode || (MODE) == V8QImode)
+
+#define VALID_IWMMXT_REG_MODE(MODE) \
+ (VECTOR_MODE_SUPPORTED_P (MODE) || (MODE) == DImode)
+
/* The order in which register should be allocated. It is good to use ip
since no saving is required (though calls clobber it) and it never contains
function parameters. It is quite good to use lr since other calls may
@@ -1004,6 +1191,11 @@ extern const char * structure_size_string;
3, 2, 1, 0, 12, 14, 4, 5, \
6, 7, 8, 10, 9, 11, 13, 15, \
16, 17, 18, 19, 20, 21, 22, 23, \
+ 27, 28, 29, 30, 31, 32, 33, 34, \
+ 35, 36, 37, 38, 39, 40, 41, 42, \
+ 43, 44, 45, 46, 47, 48, 49, 50, \
+ 51, 52, 53, 54, 55, 56, 57, 58, \
+ 59, 60, 61, 62, \
24, 25, 26 \
}
@@ -1016,12 +1208,15 @@ extern const char * structure_size_string;
/* Register and constant classes. */
-/* Register classes: used to be simple, just all ARM regs or all FPU regs
+/* Register classes: used to be simple, just all ARM regs or all FPA regs
Now that the Thumb is involved it has become more complicated. */
enum reg_class
{
NO_REGS,
- FPU_REGS,
+ FPA_REGS,
+ CIRRUS_REGS,
+ IWMMXT_GR_REGS,
+ IWMMXT_REGS,
LO_REGS,
STACK_REG,
BASE_REGS,
@@ -1034,11 +1229,14 @@ enum reg_class
#define N_REG_CLASSES (int) LIM_REG_CLASSES
-/* Give names of register classes as strings for dump file. */
+/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
{ \
"NO_REGS", \
- "FPU_REGS", \
+ "FPA_REGS", \
+ "CIRRUS_REGS", \
+ "IWMMXT_GR_REGS", \
+ "IWMMXT_REGS", \
"LO_REGS", \
"STACK_REG", \
"BASE_REGS", \
@@ -1053,15 +1251,18 @@ enum reg_class
of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \
{ \
- { 0x0000000 }, /* NO_REGS */ \
- { 0x0FF0000 }, /* FPU_REGS */ \
- { 0x00000FF }, /* LO_REGS */ \
- { 0x0002000 }, /* STACK_REG */ \
- { 0x00020FF }, /* BASE_REGS */ \
- { 0x000FF00 }, /* HI_REGS */ \
- { 0x1000000 }, /* CC_REG */ \
- { 0x200FFFF }, /* GENERAL_REGS */ \
- { 0x2FFFFFF } /* ALL_REGS */ \
+ { 0x00000000, 0x0 }, /* NO_REGS */ \
+ { 0x00FF0000, 0x0 }, /* FPA_REGS */ \
+ { 0xF8000000, 0x000007FF }, /* CIRRUS_REGS */ \
+ { 0x00000000, 0x00007800 }, /* IWMMXT_GR_REGS */\
+ { 0x00000000, 0x7FFF8000 }, /* IWMMXT_REGS */ \
+ { 0x000000FF, 0x0 }, /* LO_REGS */ \
+ { 0x00002000, 0x0 }, /* STACK_REG */ \
+ { 0x000020FF, 0x0 }, /* BASE_REGS */ \
+ { 0x0000FF00, 0x0 }, /* HI_REGS */ \
+ { 0x01000000, 0x0 }, /* CC_REG */ \
+ { 0x0200FFFF, 0x0 }, /* GENERAL_REGS */\
+ { 0xFAFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \
}
/* The same information, inverted:
@@ -1070,12 +1271,18 @@ enum reg_class
or could index an array. */
#define REGNO_REG_CLASS(REGNO) arm_regno_class (REGNO)
+/* FPA registers can't do dubreg as all values are reformatted to internal
+ precision. */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FPA_REGS, (CLASS)) : 0)
+
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
#define BASE_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
/* For the Thumb the high registers cannot be used as base registers
- when addressing quanitities in QI or HI mode; if we don't know the
+ when addressing quantities in QI or HI mode; if we don't know the
mode, then we must be conservative. After reload we must also be
conservative, since we can't support SP+reg addressing, and we
can't fix up any bad substitutions. */
@@ -1086,14 +1293,17 @@ enum reg_class
/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
registers explicitly used in the rtl to be used as spill registers
but prevents the compiler from extending the lifetime of these
- registers. */
+ registers. */
#define SMALL_REGISTER_CLASSES TARGET_THUMB
/* Get reg_class from a letter such as appears in the machine description.
- We only need constraint `f' for FPU_REGS (`r' == GENERAL_REGS) for the
+ We only need constraint `f' for FPA_REGS (`r' == GENERAL_REGS) for the
ARM, but several more letters for the Thumb. */
#define REG_CLASS_FROM_LETTER(C) \
- ( (C) == 'f' ? FPU_REGS \
+ ( (C) == 'f' ? FPA_REGS \
+ : (C) == 'v' ? CIRRUS_REGS \
+ : (C) == 'y' ? IWMMXT_REGS \
+ : (C) == 'z' ? IWMMXT_GR_REGS \
: (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \
: TARGET_ARM ? NO_REGS \
: (C) == 'h' ? HI_REGS \
@@ -1136,11 +1346,11 @@ enum reg_class
(TARGET_ARM ? \
CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C))
-/* Constant letter 'G' for the FPU immediate constants.
+/* Constant letter 'G' for the FPA immediate constants.
'H' means the same constant negated. */
#define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C) \
- ((C) == 'G' ? const_double_rtx_ok_for_fpu (X) : \
- (C) == 'H' ? neg_const_double_rtx_ok_for_fpu (X) : 0)
+ ((C) == 'G' ? const_double_rtx_ok_for_fpa (X) : \
+ (C) == 'H' ? neg_const_double_rtx_ok_for_fpa (X) : 0)
#define CONST_DOUBLE_OK_FOR_LETTER_P(X, C) \
(TARGET_ARM ? \
@@ -1150,15 +1360,16 @@ enum reg_class
an offset from a register.
`S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL
address. This means that the symbol is in the text segment and can be
- accessed without using a load. */
+ accessed without using a load. */
#define EXTRA_CONSTRAINT_ARM(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG : \
(C) == 'R' ? (GET_CODE (OP) == MEM \
&& GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
- (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) \
- : 0)
+ (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \
+ (C) == 'T' ? cirrus_memory_offset (OP) : \
+ 0)
#define EXTRA_CONSTRAINT_THUMB(X, C) \
((C) == 'Q' ? (GET_CODE (X) == MEM \
@@ -1200,15 +1411,23 @@ enum reg_class
? GENERAL_REGS : NO_REGS) \
: THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X))
-/* If we need to load shorts byte-at-a-time, then we need a scratch. */
+/* If we need to load shorts byte-at-a-time, then we need a scratch. */
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
+ /* Cannot load constants into Cirrus registers. */ \
+ ((TARGET_CIRRUS \
+ && (CLASS) == CIRRUS_REGS \
+ && (CONSTANT_P (X) || GET_CODE (X) == SYMBOL_REF)) \
+ ? GENERAL_REGS : \
(TARGET_ARM ? \
+ (((CLASS) == IWMMXT_REGS || (CLASS) == IWMMXT_GR_REGS) \
+ && CONSTANT_P (X)) \
+ ? GENERAL_REGS : \
(((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS \
&& (GET_CODE (X) == MEM \
|| ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG) \
&& true_regnum (X) == -1))) \
? GENERAL_REGS : NO_REGS) \
- : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X))
+ : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)))
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
@@ -1231,6 +1450,9 @@ enum reg_class
\
if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
low = ((val & 0xf) ^ 0x8) - 0x8; \
+ else if (TARGET_CIRRUS) \
+ /* Need to be careful, -256 is not a valid offset. */ \
+ low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
else if (MODE == SImode \
|| (MODE == SFmode && TARGET_SOFT_FLOAT) \
|| ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
@@ -1267,7 +1489,7 @@ enum reg_class
} \
while (0)
-/* ??? If an HImode FP+large_offset address is converted to an HImode
+/* XXX If an HImode FP+large_offset address is converted to an HImode
SP+large_offset address, then reload won't know how to fix it. It sees
only that SP isn't valid for HImode, and so reloads the SP into an index
register, but the resulting address is still invalid because the offset
@@ -1282,7 +1504,7 @@ enum reg_class
&& GET_CODE (XEXP (X, 0)) == REG \
&& XEXP (X, 0) == stack_pointer_rtx \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
+ && ! thumb_legitimate_offset_p (MODE, INTVAL (XEXP (X, 1)))) \
{ \
rtx orig_X = X; \
X = copy_rtx (X); \
@@ -1301,15 +1523,24 @@ enum reg_class
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
- ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
+ ARM regs are UNITS_PER_WORD bits while FPA regs can hold any FP mode */
#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((CLASS) == FPU_REGS ? 1 : ARM_NUM_REGS (MODE))
+ (((CLASS) == FPA_REGS || (CLASS) == CIRRUS_REGS) ? 1 : ARM_NUM_REGS (MODE))
-/* Moves between FPU_REGS and GENERAL_REGS are two memory insns. */
+/* If defined, gives a class of registers that cannot be used as the
+ operand of a SUBREG that changes the mode of the object illegally. */
+
+/* Moves between FPA_REGS and GENERAL_REGS are two memory insns. */
#define REGISTER_MOVE_COST(MODE, FROM, TO) \
(TARGET_ARM ? \
- ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 : \
- (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2) \
+ ((FROM) == FPA_REGS && (TO) != FPA_REGS ? 20 : \
+ (FROM) != FPA_REGS && (TO) == FPA_REGS ? 20 : \
+ (FROM) == IWMMXT_REGS && (TO) != IWMMXT_REGS ? 4 : \
+ (FROM) != IWMMXT_REGS && (TO) == IWMMXT_REGS ? 4 : \
+ (FROM) == IWMMXT_GR_REGS || (TO) == IWMMXT_GR_REGS ? 20 : \
+ (FROM) == CIRRUS_REGS && (TO) != CIRRUS_REGS ? 20 : \
+ (FROM) != CIRRUS_REGS && (TO) == CIRRUS_REGS ? 20 : \
+ 2) \
: \
((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
@@ -1334,8 +1565,8 @@ enum reg_class
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by. */
/* The push insns do not do this rounding implicitly.
- So don't define this. */
-/* #define PUSH_ROUNDING(NPUSHED) ROUND_UP (NPUSHED) */
+ So don't define this. */
+/* #define PUSH_ROUNDING(NPUSHED) ROUND_UP_WORD (NPUSHED) */
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
@@ -1361,6 +1592,10 @@ enum reg_class
#define LIBCALL_VALUE(MODE) \
(TARGET_ARM && TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT \
? gen_rtx_REG (MODE, FIRST_ARM_FP_REGNUM) \
+ : TARGET_ARM && TARGET_CIRRUS && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ ? gen_rtx_REG (MODE, FIRST_CIRRUS_FP_REGNUM) \
+ : TARGET_REALLY_IWMMXT && VECTOR_MODE_SUPPORTED_P (MODE) \
+ ? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM) \
: gen_rtx_REG (MODE, ARG_REGISTER (1)))
/* Define how to find the value returned by a function.
@@ -1372,18 +1607,21 @@ enum reg_class
/* 1 if N is a possible register number for a function value.
On the ARM, only r0 and f0 can return results. */
+/* On a Cirrus chip, mvf0 can return results. */
#define FUNCTION_VALUE_REGNO_P(REGNO) \
((REGNO) == ARG_REGISTER (1) \
+ || (TARGET_ARM && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) && TARGET_CIRRUS) \
+ || (TARGET_ARM && ((REGNO) == FIRST_IWMMXT_REGNUM) && TARGET_IWMMXT) \
|| (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
/* How large values are returned */
/* A C expression which can inhibit the returning of certain function values
- in registers, based on the type of value. */
+ in registers, based on the type of value. */
#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
values must be in memory. On the ARM, they need only do so if larger
- than a word, or if they contain elements offset from zero in the struct. */
+ than a word, or if they contain elements offset from zero in the struct. */
#define DEFAULT_PCC_STRUCT_RETURN 0
/* Flags for the call/call_value rtl operations set up by function_arg. */
@@ -1417,7 +1655,7 @@ enum reg_class
#define ARM_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR and above. */
#define ARM_FT_NAKED (1 << 3) /* No prologue or epilogue. */
#define ARM_FT_VOLATILE (1 << 4) /* Does not return. */
-#define ARM_FT_NESTED (1 << 5) /* Embedded inside another func. */
+#define ARM_FT_NESTED (1 << 5) /* Embedded inside another func. */
/* Some macros to test these flags. */
#define ARM_FUNC_TYPE(t) (t & ARM_FT_TYPE_MASK)
@@ -1430,7 +1668,7 @@ enum reg_class
This is added to the cfun structure. */
typedef struct machine_function GTY(())
{
- /* Additionsl stack adjustment in __builtin_eh_throw. */
+ /* Additional stack adjustment in __builtin_eh_throw. */
rtx eh_epilogue_sp_ofs;
/* Records if LR has to be saved for far jumps. */
int far_jump_used;
@@ -1444,6 +1682,9 @@ typedef struct machine_function GTY(())
unsigned long func_type;
/* Record if the function has a variable argument list. */
int uses_anonymous_args;
+ /* Records if sibcalls are blocked because an argument
+ register is needed to preserve stack alignment. */
+ int sibcall_blocked;
}
machine_function;
@@ -1454,7 +1695,11 @@ typedef struct
{
/* This is the number of registers of arguments scanned so far. */
int nregs;
- /* One of CALL_NORMAL, CALL_LONG or CALL_SHORT . */
+ /* This is the number of iWMMXt register arguments scanned so far. */
+ int iwmmxt_nregs;
+ int named_count;
+ int nargs;
+ /* One of CALL_NORMAL, CALL_LONG or CALL_SHORT. */
int call_cookie;
} CUMULATIVE_ARGS;
@@ -1483,7 +1728,8 @@ typedef struct
this is the number of registers used.
For args passed entirely in registers or entirely in memory, zero. */
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
- ( NUM_ARG_REGS > (CUM).nregs \
+ (VECTOR_MODE_SUPPORTED_P (MODE) ? 0 : \
+ NUM_ARG_REGS > (CUM).nregs \
&& (NUM_ARG_REGS < ((CUM).nregs + ARM_NUM_REGS2 (MODE, TYPE))) \
? NUM_ARG_REGS - (CUM).nregs : 0)
@@ -1499,30 +1745,40 @@ typedef struct
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0.
On the ARM, the offset starts at 0. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
- arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (INDIRECT))
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
+ arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL))
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+ (CUM).nargs += 1; \
+ if (VECTOR_MODE_SUPPORTED_P (MODE)) \
+ if ((CUM).named_count <= (CUM).nargs) \
+ (CUM).nregs += 2; \
+ else \
+ (CUM).iwmmxt_nregs += 1; \
+ else \
(CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)
+/* If defined, a C expression that gives the alignment boundary, in bits, of an
+ argument with the specified mode and type. If it is not defined,
+ `PARM_BOUNDARY' is used for all arguments. */
+#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) \
+ (TARGET_REALLY_IWMMXT && (VALID_IWMMXT_REG_MODE (MODE) || ((MODE) == DFmode)) \
+ ? IWMMXT_ALIGNMENT : PARM_BOUNDARY)
+
/* 1 if N is a possible register number for function argument passing.
On the ARM, r0-r3 are used to pass args. */
-#define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3))
+#define FUNCTION_ARG_REGNO_P(REGNO) \
+ (IN_RANGE ((REGNO), 0, 3) \
+ || (TARGET_REALLY_IWMMXT && IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))
/* Implement `va_arg'. */
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
arm_va_arg (valist, type)
-/* Tail calling. */
-
-/* A C expression that evaluates to true if it is ok to perform a sibling
- call to DECL. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) arm_function_ok_for_sibcall ((DECL))
-
/* Perform any actions needed for a function that is receiving a variable
number of arguments. CUM is as above. MODE and TYPE are the mode and type
of the current parameter. PRETEND_SIZE is a variable that should be set to
@@ -1610,7 +1866,7 @@ typedef struct
/* Determine if the epilogue should be output as RTL.
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
#define USE_RETURN_INSN(ISCOND) \
- (TARGET_ARM ? use_return_insn (ISCOND) : 0)
+ (TARGET_ARM ? use_return_insn (ISCOND, NULL) : 0)
/* Definitions for register eliminations.
@@ -1721,7 +1977,7 @@ typedef struct
ldr pc, [pc]
.word static chain value
.word function's address
- ??? FIXME: When the trampoline returns, r8 will be clobbered. */
+ XXX FIXME: When the trampoline returns, r8 will be clobbered. */
#define ARM_TRAMPOLINE_TEMPLATE(FILE) \
{ \
asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n", \
@@ -1770,20 +2026,30 @@ typedef struct
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-{ \
- emit_move_insn \
- (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 8 : 16)), CXT); \
- emit_move_insn \
- (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 12 : 20)), FNADDR); \
+#ifndef INITIALIZE_TRAMPOLINE
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+{ \
+ emit_move_insn (gen_rtx_MEM (SImode, \
+ plus_constant (TRAMP, \
+ TARGET_ARM ? 8 : 16)), \
+ CXT); \
+ emit_move_insn (gen_rtx_MEM (SImode, \
+ plus_constant (TRAMP, \
+ TARGET_ARM ? 12 : 20)), \
+ FNADDR); \
}
+#endif
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT 1
-#define HAVE_PRE_INCREMENT TARGET_ARM
-#define HAVE_POST_DECREMENT TARGET_ARM
-#define HAVE_PRE_DECREMENT TARGET_ARM
+#define HAVE_POST_INCREMENT 1
+#define HAVE_PRE_INCREMENT TARGET_ARM
+#define HAVE_POST_DECREMENT TARGET_ARM
+#define HAVE_PRE_DECREMENT TARGET_ARM
+#define HAVE_PRE_MODIFY_DISP TARGET_ARM
+#define HAVE_POST_MODIFY_DISP TARGET_ARM
+#define HAVE_PRE_MODIFY_REG TARGET_ARM
+#define HAVE_POST_MODIFY_REG TARGET_ARM
/* Macros to check register numbers against specific register classes. */
@@ -1791,7 +2057,7 @@ typedef struct
They give nonzero only if REGNO is a hard reg of the suitable class
or a pseudo reg currently allocated to a suitable hard reg.
Since they use reg_renumber, they are safe only once reg_renumber
- has been allocated, which happens in local-alloc.c. */
+ has been allocated, which happens in local-alloc.c. */
#define TEST_REGNO(R, TEST, VALUE) \
((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
@@ -1817,7 +2083,7 @@ typedef struct
REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
/* Maximum number of registers that can appear in a valid memory address.
- Shifts in addresses can't be by a register. */
+ Shifts in addresses can't be by a register. */
#define MAX_REGS_PER_ADDRESS 2
/* Recognize any constant value that is a valid address. */
@@ -1872,7 +2138,7 @@ typedef struct
#define SUBTARGET_NAME_ENCODING_LENGTHS
#endif
-/* This is a C fragement for the inside of a switch statement.
+/* This is a C fragment for the inside of a switch statement.
Each case label should return the number of characters to
be stripped from the start of a function's name, if that
name starts with the indicated character. */
@@ -1913,6 +2179,8 @@ typedef struct
|| (X) == hard_frame_pointer_rtx \
|| (X) == arg_pointer_rtx)))
+#define REG_STRICT_P 0
+
#else /* REG_OK_STRICT */
#define ARM_REG_OK_FOR_BASE_P(X) \
@@ -1921,6 +2189,8 @@ typedef struct
#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
+#define REG_STRICT_P 1
+
#endif /* REG_OK_STRICT */
/* Now define some helpers in terms of the above. */
@@ -1948,340 +2218,56 @@ typedef struct
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction.
The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */
+ that wants to use this address. */
-/* --------------------------------arm version----------------------------- */
#define ARM_BASE_REGISTER_RTX_P(X) \
(GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
#define ARM_INDEX_REGISTER_RTX_P(X) \
(GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
-/* A C statement (sans semicolon) to jump to LABEL for legitimate index RTXs
- used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can
- only be small constants. */
-#define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
- do \
- { \
- HOST_WIDE_INT range; \
- enum rtx_code code = GET_CODE (INDEX); \
- \
- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- { \
- if (code == CONST_INT && INTVAL (INDEX) < 1024 \
- && INTVAL (INDEX) > -1024 \
- && (INTVAL (INDEX) & 3) == 0) \
- goto LABEL; \
- } \
- else \
- { \
- if (ARM_INDEX_REGISTER_RTX_P (INDEX) \
- && GET_MODE_SIZE (MODE) <= 4) \
- goto LABEL; \
- if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \
- && (! arm_arch4 || (MODE) != HImode)) \
- { \
- rtx xiop0 = XEXP (INDEX, 0); \
- rtx xiop1 = XEXP (INDEX, 1); \
- if (ARM_INDEX_REGISTER_RTX_P (xiop0) \
- && power_of_two_operand (xiop1, SImode)) \
- goto LABEL; \
- if (ARM_INDEX_REGISTER_RTX_P (xiop1) \
- && power_of_two_operand (xiop0, SImode)) \
- goto LABEL; \
- } \
- if (GET_MODE_SIZE (MODE) <= 4 \
- && (code == LSHIFTRT || code == ASHIFTRT \
- || code == ASHIFT || code == ROTATERT) \
- && (! arm_arch4 || (MODE) != HImode)) \
- { \
- rtx op = XEXP (INDEX, 1); \
- if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \
- && GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \
- && INTVAL (op) <= 31) \
- goto LABEL; \
- } \
- /* NASTY: Since this limits the addressing of unsigned \
- byte loads. */ \
- range = ((MODE) == HImode || (MODE) == QImode) \
- ? (arm_arch4 ? 256 : 4095) : 4096; \
- if (code == CONST_INT && INTVAL (INDEX) < range \
- && INTVAL (INDEX) > -range) \
- goto LABEL; \
- } \
- } \
- while (0)
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \
+ { \
+ if (arm_legitimate_address_p (MODE, X, REG_STRICT_P)) \
+ goto WIN; \
+ }
-/* Jump to LABEL if X is a valid address RTX. This must take
- REG_OK_STRICT into account when deciding about valid registers.
+#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \
+ { \
+ if (thumb_legitimate_address_p (MODE, X, REG_STRICT_P)) \
+ goto WIN; \
+ }
- Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non
- floating SYMBOL_REF to the constant pool. Allow REG-only and
- AUTINC-REG if handling TImode or HImode. Other symbol refs must be
- forced though a static cell to ensure addressability. */
-#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
-{ \
- if (ARM_BASE_REGISTER_RTX_P (X)) \
- goto LABEL; \
- else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
- && GET_CODE (XEXP (X, 0)) == REG \
- && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
- goto LABEL; \
- else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
- && (GET_CODE (X) == LABEL_REF \
- || (GET_CODE (X) == CONST \
- && GET_CODE (XEXP ((X), 0)) == PLUS \
- && GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF \
- && GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT)))\
- goto LABEL; \
- else if ((MODE) == TImode) \
- ; \
- else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode)) \
- { \
- if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0)) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
- if (val == 4 || val == -4 || val == -8) \
- goto LABEL; \
- } \
- } \
- else if (GET_CODE (X) == PLUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (ARM_BASE_REGISTER_RTX_P (xop0)) \
- ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \
- else if (ARM_BASE_REGISTER_RTX_P (xop1)) \
- ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \
- } \
- /* Reload currently can't handle MINUS, so disable this for now */ \
- /* else if (GET_CODE (X) == MINUS) \
- { \
- rtx xop0 = XEXP (X,0); \
- rtx xop1 = XEXP (X,1); \
- \
- if (ARM_BASE_REGISTER_RTX_P (xop0)) \
- ARM_GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \
- } */ \
- else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
- && GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X) \
- && ! (flag_pic \
- && symbol_mentioned_p (get_pool_constant (X)))) \
- goto LABEL; \
- else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \
- && (GET_MODE_SIZE (MODE) <= 4) \
- && GET_CODE (XEXP (X, 0)) == REG \
- && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
- goto LABEL; \
-}
-
-/* ---------------------thumb version----------------------------------*/
-#define THUMB_LEGITIMATE_OFFSET(MODE, VAL) \
- (GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32) \
- : GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \
- && ((VAL) & 1) == 0) \
- : ((VAL) >= 0 && ((VAL) + GET_MODE_SIZE (MODE)) <= 128 \
- && ((VAL) & 3) == 0))
-
-/* The AP may be eliminated to either the SP or the FP, so we use the
- least common denominator, e.g. SImode, and offsets from 0 to 64. */
-
-/* ??? Verify whether the above is the right approach. */
-
-/* ??? Also, the FP may be eliminated to the SP, so perhaps that
- needs special handling also. */
-
-/* ??? Look at how the mips16 port solves this problem. It probably uses
- better ways to solve some of these problems. */
-
-/* Although it is not incorrect, we don't accept QImode and HImode
- addresses based on the frame pointer or arg pointer until the
- reload pass starts. This is so that eliminating such addresses
- into stack based ones won't produce impossible code. */
-#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
-{ \
-/* ??? Not clear if this is right. Experiment. */ \
- if (GET_MODE_SIZE (MODE) < 4 \
- && ! (reload_in_progress || reload_completed) \
- && ( reg_mentioned_p (frame_pointer_rtx, X) \
- || reg_mentioned_p (arg_pointer_rtx, X) \
- || reg_mentioned_p (virtual_incoming_args_rtx, X) \
- || reg_mentioned_p (virtual_outgoing_args_rtx, X) \
- || reg_mentioned_p (virtual_stack_dynamic_rtx, X) \
- || reg_mentioned_p (virtual_stack_vars_rtx, X))) \
- ; \
- /* Accept any base register. SP only in SImode or larger. */ \
- else if (GET_CODE (X) == REG \
- && THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)) \
- goto WIN; \
- /* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \
- else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \
- && GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic) \
- goto WIN; \
- /* This is PC relative data after MACHINE_DEPENDENT_REORG runs. */ \
- else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
- && (GET_CODE (X) == LABEL_REF \
- || (GET_CODE (X) == CONST \
- && GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT))) \
- goto WIN; \
- /* Post-inc indexing only supported for SImode and larger. */ \
- else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \
- && GET_CODE (XEXP (X, 0)) == REG \
- && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
- goto WIN; \
- else if (GET_CODE (X) == PLUS) \
- { \
- /* REG+REG address can be any two index registers. */ \
- /* We disallow FRAME+REG addressing since we know that FRAME \
- will be replaced with STACK, and SP relative addressing only \
- permits SP+OFFSET. */ \
- if (GET_MODE_SIZE (MODE) <= 4 \
- && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == REG \
- && XEXP (X, 0) != frame_pointer_rtx \
- && XEXP (X, 1) != frame_pointer_rtx \
- && XEXP (X, 0) != virtual_stack_vars_rtx \
- && XEXP (X, 1) != virtual_stack_vars_rtx \
- && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
- && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
- goto WIN; \
- /* REG+const has 5-7 bit offset for non-SP registers. */ \
- else if (GET_CODE (XEXP (X, 0)) == REG \
- && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
- || XEXP (X, 0) == arg_pointer_rtx) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
- goto WIN; \
- /* REG+const has 10 bit offset for SP, but only SImode and \
- larger is supported. */ \
- /* ??? Should probably check for DI/DFmode overflow here \
- just like GO_IF_LEGITIMATE_OFFSET does. */ \
- else if (GET_CODE (XEXP (X, 0)) == REG \
- && REGNO (XEXP (X, 0)) == STACK_POINTER_REGNUM \
- && GET_MODE_SIZE (MODE) >= 4 \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (X, 1)) \
- + GET_MODE_SIZE (MODE)) <= 1024 \
- && (INTVAL (XEXP (X, 1)) & 3) == 0) \
- goto WIN; \
- else if (GET_CODE (XEXP (X, 0)) == REG \
- && REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \
- && GET_MODE_SIZE (MODE) >= 4 \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (INTVAL (XEXP (X, 1)) & 3) == 0) \
- goto WIN; \
- } \
- else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
- && GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X) \
- && ! (flag_pic \
- && symbol_mentioned_p (get_pool_constant (X)))) \
- goto WIN; \
-}
-
-/* ------------------------------------------------------------------- */
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
if (TARGET_ARM) \
ARM_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN) \
else /* if (TARGET_THUMB) */ \
THUMB_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
-/* ------------------------------------------------------------------- */
+
/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- OLDX is the address as it was before break_out_memory_refs was called.
- In some cases it is useful to look at this to decide what needs to be done.
-
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output.
-
- On the ARM, try to convert [REG, #BIGCONST]
- into ADD BASE, REG, #UPPERCONST and [BASE, #VALIDCONST],
- where VALIDCONST == 0 in case of TImode. */
-#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ \
- if (GET_CODE (X) == PLUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (CONSTANT_P (xop0) && ! symbol_mentioned_p (xop0)) \
- xop0 = force_reg (SImode, xop0); \
- if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
- xop1 = force_reg (SImode, xop1); \
- if (ARM_BASE_REGISTER_RTX_P (xop0) \
- && GET_CODE (xop1) == CONST_INT) \
- { \
- HOST_WIDE_INT n, low_n; \
- rtx base_reg, val; \
- n = INTVAL (xop1); \
- \
- if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
- { \
- low_n = n & 0x0f; \
- n &= ~0x0f; \
- if (low_n > 4) \
- { \
- n += 16; \
- low_n -= 16; \
- } \
- } \
- else \
- { \
- low_n = ((MODE) == TImode ? 0 \
- : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff)); \
- n -= low_n; \
- } \
- base_reg = gen_reg_rtx (SImode); \
- val = force_operand (gen_rtx_PLUS (SImode, xop0, \
- GEN_INT (n)), NULL_RTX); \
- emit_move_insn (base_reg, val); \
- (X) = (low_n == 0 ? base_reg \
- : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n))); \
- } \
- else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1)) \
- (X) = gen_rtx_PLUS (SImode, xop0, xop1); \
- } \
- else if (GET_CODE (X) == MINUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (CONSTANT_P (xop0)) \
- xop0 = force_reg (SImode, xop0); \
- if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
- xop1 = force_reg (SImode, xop1); \
- if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1)) \
- (X) = gen_rtx_MINUS (SImode, xop0, xop1); \
- } \
- if (flag_pic) \
- (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
+ to be legitimate. If we find one, return the new, valid address. */
+#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ X = arm_legitimize_address (X, OLDX, MODE); \
+ \
+ if (memory_address_p (MODE, X)) \
+ goto WIN; \
+} while (0)
-#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- if (flag_pic) \
- (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- if (TARGET_ARM) \
- ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN) \
- else \
- THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)
+#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ if (flag_pic) \
+ (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
+} while (0)
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ if (TARGET_ARM) \
+ ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
+ else \
+ THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
+} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. */
@@ -2305,7 +2291,7 @@ typedef struct
/* Define as C expression which evaluates to nonzero if the tablejump
instruction expects the table to contain offsets from the address of the
table.
- Do not define this if the table should contain absolute addresses. */
+ Do not define this if the table should contain absolute addresses. */
/* #define CASE_VECTOR_PC_RELATIVE 1 */
/* signed 'char' is most compatible, but RISC OS wants it unsigned.
@@ -2322,7 +2308,7 @@ typedef struct
#define MOVE_MAX 4
#undef MOVE_RATIO
-#define MOVE_RATIO (arm_is_xscale ? 4 : 2)
+#define MOVE_RATIO (arm_tune_xscale ? 4 : 2)
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
@@ -2350,7 +2336,7 @@ typedef struct
/* This is all wrong. Defining SHIFT_COUNT_TRUNCATED tells combine that
code like (X << (Y % 32)) for register X, Y is equivalent to (X << Y).
On the arm, Y in a register is used modulo 256 for the shift. Only for
- rotates is modulo 32 used. */
+ rotates is modulo 32 used. */
/* #define SHIFT_COUNT_TRUNCATED 1 */
/* All integers have the same format so truncation is easy. */
@@ -2370,44 +2356,12 @@ typedef struct
( (X) == frame_pointer_rtx || (X) == stack_pointer_rtx \
|| (X) == arg_pointer_rtx)
-#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
- return arm_rtx_costs (X, CODE, OUTER_CODE);
-
/* Moves to and from memory are quite expensive */
#define MEMORY_MOVE_COST(M, CLASS, IN) \
(TARGET_ARM ? 10 : \
((GET_MODE_SIZE (M) < 4 ? 8 : 2 * GET_MODE_SIZE (M)) \
* (CLASS == LO_REGS ? 1 : 2)))
-/* All address computations that can be done are free, but rtx cost returns
- the same for practically all of them. So we weight the different types
- of address here in the order (most pref first):
- PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
-#define ARM_ADDRESS_COST(X) \
- (10 - ((GET_CODE (X) == MEM || GET_CODE (X) == LABEL_REF \
- || GET_CODE (X) == SYMBOL_REF) \
- ? 0 \
- : ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC \
- || GET_CODE (X) == POST_INC || GET_CODE (X) == POST_DEC) \
- ? 10 \
- : (((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS) \
- ? 6 + (GET_CODE (XEXP (X, 1)) == CONST_INT ? 2 \
- : ((GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == '2' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == 'c' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == '2' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == 'c') \
- ? 1 : 0)) \
- : 4)))))
-
-#define THUMB_ADDRESS_COST(X) \
- ((GET_CODE (X) == REG \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == CONST_INT)) \
- ? 1 : 2)
-
-#define ADDRESS_COST(X) \
- (TARGET_ARM ? ARM_ADDRESS_COST (X) : THUMB_ADDRESS_COST (X))
-
/* Try to generate sequences that don't involve branches, we can then use
conditional instructions */
#define BRANCH_COST \
@@ -2444,13 +2398,13 @@ extern const char * arm_pic_register_string;
extern int making_const_table;
/* Handle pragmas for compatibility with Intel's compilers. */
-#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
- cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \
- cpp_register_pragma (PFILE, 0, "no_long_calls", arm_pr_no_long_calls); \
- cpp_register_pragma (PFILE, 0, "long_calls_off", arm_pr_long_calls_off); \
+#define REGISTER_TARGET_PRAGMAS() do { \
+ c_register_pragma (0, "long_calls", arm_pr_long_calls); \
+ c_register_pragma (0, "no_long_calls", arm_pr_no_long_calls); \
+ c_register_pragma (0, "long_calls_off", arm_pr_long_calls_off); \
} while (0)
-/* Condition code information. */
+/* Condition code information. */
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. */
@@ -2472,54 +2426,33 @@ extern int making_const_table;
} \
while (0)
-#define STORE_FLAG_VALUE 1
-
+/* The arm5 clz instruction returns 32. */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
-
-/* Gcc puts the pool in the wrong place for ARM, since we can only
- load addresses a limited distance around the pc. We do some
- special munging to move the constant pool values to the correct
- point in the code. */
-#define MACHINE_DEPENDENT_REORG(INSN) \
- arm_reorg (INSN); \
-
#undef ASM_APP_OFF
#define ASM_APP_OFF (TARGET_THUMB ? "\t.code\t16\n" : "")
-/* Output an internal label definition. */
-#ifndef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
- do \
- { \
- char * s = (char *) alloca (40 + strlen (PREFIX)); \
- \
- if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \
- && !strcmp (PREFIX, "L")) \
- { \
- arm_ccfsm_state = 0; \
- arm_target_insn = NULL; \
- } \
- ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM)); \
- ASM_OUTPUT_LABEL (STREAM, s); \
- } \
- while (0)
-#endif
-
/* Output a push or a pop instruction (only used when profiling). */
#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
- if (TARGET_ARM) \
- asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n", \
- STACK_POINTER_REGNUM, REGNO); \
- else \
- asm_fprintf (STREAM, "\tpush {%r}\n", REGNO)
+ do \
+ { \
+ if (TARGET_ARM) \
+ asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n", \
+ STACK_POINTER_REGNUM, REGNO); \
+ else \
+ asm_fprintf (STREAM, "\tpush {%r}\n", REGNO); \
+ } while (0)
#define ASM_OUTPUT_REG_POP(STREAM, REGNO) \
- if (TARGET_ARM) \
- asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n", \
- STACK_POINTER_REGNUM, REGNO); \
- else \
- asm_fprintf (STREAM, "\tpop {%r}\n", REGNO)
+ do \
+ { \
+ if (TARGET_ARM) \
+ asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n", \
+ STACK_POINTER_REGNUM, REGNO); \
+ else \
+ asm_fprintf (STREAM, "\tpop {%r}\n", REGNO); \
+ } while (0)
/* This is how to output a label which precedes a jumptable. Since
Thumb instructions are 2 bytes, we may need explicit alignment here. */
@@ -2529,7 +2462,7 @@ extern int making_const_table;
{ \
if (TARGET_THUMB) \
ASM_OUTPUT_ALIGN (FILE, 2); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
} \
while (0)
@@ -2538,10 +2471,11 @@ extern int making_const_table;
{ \
if (TARGET_THUMB) \
{ \
- if (is_called_in_ARM_mode (DECL)) \
+ if (is_called_in_ARM_mode (DECL) \
+ || current_function_is_thunk) \
fprintf (STREAM, "\t.code 32\n") ; \
else \
- fprintf (STREAM, "\t.thumb_func\n") ; \
+ fprintf (STREAM, "\t.code 16\n\t.thumb_func\n") ; \
} \
if (TARGET_POKE_FUNCTION_NAME) \
arm_poke_function_name (STREAM, (char *) NAME); \
@@ -2572,19 +2506,19 @@ extern int making_const_table;
/* To support -falign-* switches we need to use .p2align so
that alignment directives in code sections will be padded
with no-op instructions, rather than zeroes. */
-#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP) \
if ((LOG) != 0) \
{ \
if ((MAX_SKIP) == 0) \
- fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ fprintf ((FILE), "\t.p2align %d\n", (int) (LOG)); \
else \
fprintf ((FILE), "\t.p2align %d,,%d\n", \
- (LOG), (MAX_SKIP)); \
+ (int) (LOG), (int) (MAX_SKIP)); \
}
#endif
/* Only perform branch elimination (by making instructions conditional) if
- we're optimising. Otherwise it's of no use anyway. */
+ we're optimizing. Otherwise it's of no use anyway. */
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
if (TARGET_ARM && optimize) \
arm_final_prescan_insn (INSN); \
@@ -2609,79 +2543,99 @@ extern int making_const_table;
: 0))))
/* Output the address of an operand. */
-#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \
-{ \
- int is_minus = GET_CODE (X) == MINUS; \
- \
- if (GET_CODE (X) == REG) \
- asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \
- else if (GET_CODE (X) == PLUS || is_minus) \
- { \
- rtx base = XEXP (X, 0); \
- rtx index = XEXP (X, 1); \
- HOST_WIDE_INT offset = 0; \
- if (GET_CODE (base) != REG) \
- { \
- /* Ensure that BASE is a register */ \
- /* (one of them must be). */ \
- rtx temp = base; \
- base = index; \
- index = temp; \
- } \
- switch (GET_CODE (index)) \
- { \
- case CONST_INT: \
- offset = INTVAL (index); \
- if (is_minus) \
- offset = -offset; \
- asm_fprintf (STREAM, "[%r, #%d]", \
- REGNO (base), offset); \
- break; \
- \
- case REG: \
- asm_fprintf (STREAM, "[%r, %s%r]", \
- REGNO (base), is_minus ? "-" : "", \
- REGNO (index)); \
- break; \
- \
- case MULT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case ASHIFT: \
- case ROTATERT: \
- { \
- asm_fprintf (STREAM, "[%r, %s%r", \
- REGNO (base), is_minus ? "-" : "", \
- REGNO (XEXP (index, 0))); \
- arm_print_operand (STREAM, index, 'S'); \
- fputs ("]", STREAM); \
- break; \
- } \
- \
- default: \
- abort(); \
- } \
- } \
- else if ( GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC\
- || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC)\
- { \
- extern int output_memory_reference_mode; \
- \
- if (GET_CODE (XEXP (X, 0)) != REG) \
- abort (); \
- \
- if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
- asm_fprintf (STREAM, "[%r, #%s%d]!", \
- REGNO (XEXP (X, 0)), \
- GET_CODE (X) == PRE_DEC ? "-" : "", \
- GET_MODE_SIZE (output_memory_reference_mode));\
- else \
- asm_fprintf (STREAM, "[%r], #%s%d", \
- REGNO (XEXP (X, 0)), \
- GET_CODE (X) == POST_DEC ? "-" : "", \
- GET_MODE_SIZE (output_memory_reference_mode));\
- } \
- else output_addr_const (STREAM, X); \
+#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \
+{ \
+ int is_minus = GET_CODE (X) == MINUS; \
+ \
+ if (GET_CODE (X) == REG) \
+ asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \
+ else if (GET_CODE (X) == PLUS || is_minus) \
+ { \
+ rtx base = XEXP (X, 0); \
+ rtx index = XEXP (X, 1); \
+ HOST_WIDE_INT offset = 0; \
+ if (GET_CODE (base) != REG) \
+ { \
+ /* Ensure that BASE is a register. */ \
+ /* (one of them must be). */ \
+ rtx temp = base; \
+ base = index; \
+ index = temp; \
+ } \
+ switch (GET_CODE (index)) \
+ { \
+ case CONST_INT: \
+ offset = INTVAL (index); \
+ if (is_minus) \
+ offset = -offset; \
+ asm_fprintf (STREAM, "[%r, #%wd]", \
+ REGNO (base), offset); \
+ break; \
+ \
+ case REG: \
+ asm_fprintf (STREAM, "[%r, %s%r]", \
+ REGNO (base), is_minus ? "-" : "", \
+ REGNO (index)); \
+ break; \
+ \
+ case MULT: \
+ case ASHIFTRT: \
+ case LSHIFTRT: \
+ case ASHIFT: \
+ case ROTATERT: \
+ { \
+ asm_fprintf (STREAM, "[%r, %s%r", \
+ REGNO (base), is_minus ? "-" : "", \
+ REGNO (XEXP (index, 0))); \
+ arm_print_operand (STREAM, index, 'S'); \
+ fputs ("]", STREAM); \
+ break; \
+ } \
+ \
+ default: \
+ abort(); \
+ } \
+ } \
+ else if (GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC \
+ || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC) \
+ { \
+ extern enum machine_mode output_memory_reference_mode; \
+ \
+ if (GET_CODE (XEXP (X, 0)) != REG) \
+ abort (); \
+ \
+ if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
+ asm_fprintf (STREAM, "[%r, #%s%d]!", \
+ REGNO (XEXP (X, 0)), \
+ GET_CODE (X) == PRE_DEC ? "-" : "", \
+ GET_MODE_SIZE (output_memory_reference_mode)); \
+ else \
+ asm_fprintf (STREAM, "[%r], #%s%d", \
+ REGNO (XEXP (X, 0)), \
+ GET_CODE (X) == POST_DEC ? "-" : "", \
+ GET_MODE_SIZE (output_memory_reference_mode)); \
+ } \
+ else if (GET_CODE (X) == PRE_MODIFY) \
+ { \
+ asm_fprintf (STREAM, "[%r, ", REGNO (XEXP (X, 0))); \
+ if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT) \
+ asm_fprintf (STREAM, "#%wd]!", \
+ INTVAL (XEXP (XEXP (X, 1), 1))); \
+ else \
+ asm_fprintf (STREAM, "%r]!", \
+ REGNO (XEXP (XEXP (X, 1), 1))); \
+ } \
+ else if (GET_CODE (X) == POST_MODIFY) \
+ { \
+ asm_fprintf (STREAM, "[%r], ", REGNO (XEXP (X, 0))); \
+ if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT) \
+ asm_fprintf (STREAM, "#%wd", \
+ INTVAL (XEXP (XEXP (X, 1), 1))); \
+ else \
+ asm_fprintf (STREAM, "%r", \
+ REGNO (XEXP (XEXP (X, 1), 1))); \
+ } \
+ else output_addr_const (STREAM, X); \
}
#define THUMB_PRINT_OPERAND_ADDRESS(STREAM, X) \
@@ -2692,10 +2646,12 @@ extern int making_const_table;
asm_fprintf (STREAM, "%r!", REGNO (XEXP (X, 0))); \
else if (GET_CODE (X) == PLUS) \
{ \
+ if (GET_CODE (XEXP (X, 0)) != REG) \
+ abort (); \
if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- asm_fprintf (STREAM, "[%r, #%d]", \
+ asm_fprintf (STREAM, "[%r, #%wd]", \
REGNO (XEXP (X, 0)), \
- (int) INTVAL (XEXP (X, 1))); \
+ INTVAL (XEXP (X, 1))); \
else \
asm_fprintf (STREAM, "[%r, %r]", \
REGNO (XEXP (X, 0)), \
@@ -2710,7 +2666,12 @@ extern int making_const_table;
ARM_PRINT_OPERAND_ADDRESS (STREAM, X) \
else \
THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
-
+
+#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
+ if (GET_CODE (X) != CONST_VECTOR \
+ || ! arm_emit_vector_const (FILE, X)) \
+ goto FAIL;
+
/* A C expression whose value is RTL representing the value of the return
address for the frame COUNT steps up from the current frame. */
@@ -2746,13 +2707,16 @@ extern int making_const_table;
{"arm_hard_register_operand", {REG}}, \
{"f_register_operand", {SUBREG, REG}}, \
{"arm_add_operand", {SUBREG, REG, CONST_INT}}, \
- {"fpu_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
- {"fpu_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
+ {"arm_addimm_operand", {CONST_INT}}, \
+ {"fpa_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
+ {"fpa_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
{"arm_rhs_operand", {SUBREG, REG, CONST_INT}}, \
{"arm_not_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_int_operand", {SUBREG, REG, CONST_INT}}, \
{"index_operand", {SUBREG, REG, CONST_INT}}, \
{"thumb_cmp_operand", {SUBREG, REG, CONST_INT}}, \
+ {"thumb_cmpneg_operand", {CONST_INT}}, \
+ {"thumb_cbrch_target_operand", {SUBREG, REG, MEM}}, \
{"offsettable_memory_operand", {MEM}}, \
{"bad_signed_byte_operand", {MEM}}, \
{"alignable_memory_operand", {MEM}}, \
@@ -2774,18 +2738,180 @@ extern int making_const_table;
{"multi_register_push", {PARALLEL}}, \
{"cc_register", {REG}}, \
{"logical_binary_operator", {AND, IOR, XOR}}, \
+ {"cirrus_register_operand", {REG}}, \
+ {"cirrus_fp_register", {REG}}, \
+ {"cirrus_shift_const", {CONST_INT}}, \
{"dominant_cc_register", {REG}},
/* Define this if you have special predicates that know special things
about modes. Genrecog will warn about certain forms of
match_operand without a mode; if the operand predicate is listed in
- SPECIAL_MODE_PREDICATES, the warning will be suppressed. */
+ SPECIAL_MODE_PREDICATES, the warning will be suppressed. */
#define SPECIAL_MODE_PREDICATES \
"cc_register", "dominant_cc_register",
enum arm_builtins
{
- ARM_BUILTIN_CLZ,
+ ARM_BUILTIN_GETWCX,
+ ARM_BUILTIN_SETWCX,
+
+ ARM_BUILTIN_WZERO,
+
+ ARM_BUILTIN_WAVG2BR,
+ ARM_BUILTIN_WAVG2HR,
+ ARM_BUILTIN_WAVG2B,
+ ARM_BUILTIN_WAVG2H,
+
+ ARM_BUILTIN_WACCB,
+ ARM_BUILTIN_WACCH,
+ ARM_BUILTIN_WACCW,
+
+ ARM_BUILTIN_WMACS,
+ ARM_BUILTIN_WMACSZ,
+ ARM_BUILTIN_WMACU,
+ ARM_BUILTIN_WMACUZ,
+
+ ARM_BUILTIN_WSADB,
+ ARM_BUILTIN_WSADBZ,
+ ARM_BUILTIN_WSADH,
+ ARM_BUILTIN_WSADHZ,
+
+ ARM_BUILTIN_WALIGN,
+
+ ARM_BUILTIN_TMIA,
+ ARM_BUILTIN_TMIAPH,
+ ARM_BUILTIN_TMIABB,
+ ARM_BUILTIN_TMIABT,
+ ARM_BUILTIN_TMIATB,
+ ARM_BUILTIN_TMIATT,
+
+ ARM_BUILTIN_TMOVMSKB,
+ ARM_BUILTIN_TMOVMSKH,
+ ARM_BUILTIN_TMOVMSKW,
+
+ ARM_BUILTIN_TBCSTB,
+ ARM_BUILTIN_TBCSTH,
+ ARM_BUILTIN_TBCSTW,
+
+ ARM_BUILTIN_WMADDS,
+ ARM_BUILTIN_WMADDU,
+
+ ARM_BUILTIN_WPACKHSS,
+ ARM_BUILTIN_WPACKWSS,
+ ARM_BUILTIN_WPACKDSS,
+ ARM_BUILTIN_WPACKHUS,
+ ARM_BUILTIN_WPACKWUS,
+ ARM_BUILTIN_WPACKDUS,
+
+ ARM_BUILTIN_WADDB,
+ ARM_BUILTIN_WADDH,
+ ARM_BUILTIN_WADDW,
+ ARM_BUILTIN_WADDSSB,
+ ARM_BUILTIN_WADDSSH,
+ ARM_BUILTIN_WADDSSW,
+ ARM_BUILTIN_WADDUSB,
+ ARM_BUILTIN_WADDUSH,
+ ARM_BUILTIN_WADDUSW,
+ ARM_BUILTIN_WSUBB,
+ ARM_BUILTIN_WSUBH,
+ ARM_BUILTIN_WSUBW,
+ ARM_BUILTIN_WSUBSSB,
+ ARM_BUILTIN_WSUBSSH,
+ ARM_BUILTIN_WSUBSSW,
+ ARM_BUILTIN_WSUBUSB,
+ ARM_BUILTIN_WSUBUSH,
+ ARM_BUILTIN_WSUBUSW,
+
+ ARM_BUILTIN_WAND,
+ ARM_BUILTIN_WANDN,
+ ARM_BUILTIN_WOR,
+ ARM_BUILTIN_WXOR,
+
+ ARM_BUILTIN_WCMPEQB,
+ ARM_BUILTIN_WCMPEQH,
+ ARM_BUILTIN_WCMPEQW,
+ ARM_BUILTIN_WCMPGTUB,
+ ARM_BUILTIN_WCMPGTUH,
+ ARM_BUILTIN_WCMPGTUW,
+ ARM_BUILTIN_WCMPGTSB,
+ ARM_BUILTIN_WCMPGTSH,
+ ARM_BUILTIN_WCMPGTSW,
+
+ ARM_BUILTIN_TEXTRMSB,
+ ARM_BUILTIN_TEXTRMSH,
+ ARM_BUILTIN_TEXTRMSW,
+ ARM_BUILTIN_TEXTRMUB,
+ ARM_BUILTIN_TEXTRMUH,
+ ARM_BUILTIN_TEXTRMUW,
+ ARM_BUILTIN_TINSRB,
+ ARM_BUILTIN_TINSRH,
+ ARM_BUILTIN_TINSRW,
+
+ ARM_BUILTIN_WMAXSW,
+ ARM_BUILTIN_WMAXSH,
+ ARM_BUILTIN_WMAXSB,
+ ARM_BUILTIN_WMAXUW,
+ ARM_BUILTIN_WMAXUH,
+ ARM_BUILTIN_WMAXUB,
+ ARM_BUILTIN_WMINSW,
+ ARM_BUILTIN_WMINSH,
+ ARM_BUILTIN_WMINSB,
+ ARM_BUILTIN_WMINUW,
+ ARM_BUILTIN_WMINUH,
+ ARM_BUILTIN_WMINUB,
+
+ ARM_BUILTIN_WMULUH,
+ ARM_BUILTIN_WMULSH,
+ ARM_BUILTIN_WMULUL,
+
+ ARM_BUILTIN_PSADBH,
+ ARM_BUILTIN_WSHUFH,
+
+ ARM_BUILTIN_WSLLH,
+ ARM_BUILTIN_WSLLW,
+ ARM_BUILTIN_WSLLD,
+ ARM_BUILTIN_WSRAH,
+ ARM_BUILTIN_WSRAW,
+ ARM_BUILTIN_WSRAD,
+ ARM_BUILTIN_WSRLH,
+ ARM_BUILTIN_WSRLW,
+ ARM_BUILTIN_WSRLD,
+ ARM_BUILTIN_WRORH,
+ ARM_BUILTIN_WRORW,
+ ARM_BUILTIN_WRORD,
+ ARM_BUILTIN_WSLLHI,
+ ARM_BUILTIN_WSLLWI,
+ ARM_BUILTIN_WSLLDI,
+ ARM_BUILTIN_WSRAHI,
+ ARM_BUILTIN_WSRAWI,
+ ARM_BUILTIN_WSRADI,
+ ARM_BUILTIN_WSRLHI,
+ ARM_BUILTIN_WSRLWI,
+ ARM_BUILTIN_WSRLDI,
+ ARM_BUILTIN_WRORHI,
+ ARM_BUILTIN_WRORWI,
+ ARM_BUILTIN_WRORDI,
+
+ ARM_BUILTIN_WUNPCKIHB,
+ ARM_BUILTIN_WUNPCKIHH,
+ ARM_BUILTIN_WUNPCKIHW,
+ ARM_BUILTIN_WUNPCKILB,
+ ARM_BUILTIN_WUNPCKILH,
+ ARM_BUILTIN_WUNPCKILW,
+
+ ARM_BUILTIN_WUNPCKEHSB,
+ ARM_BUILTIN_WUNPCKEHSH,
+ ARM_BUILTIN_WUNPCKEHSW,
+ ARM_BUILTIN_WUNPCKEHUB,
+ ARM_BUILTIN_WUNPCKEHUH,
+ ARM_BUILTIN_WUNPCKEHUW,
+ ARM_BUILTIN_WUNPCKELSB,
+ ARM_BUILTIN_WUNPCKELSH,
+ ARM_BUILTIN_WUNPCKELSW,
+ ARM_BUILTIN_WUNPCKELUB,
+ ARM_BUILTIN_WUNPCKELUH,
+ ARM_BUILTIN_WUNPCKELUW,
+
ARM_BUILTIN_MAX
};
#endif /* ! GCC_ARM_H */
diff --git a/contrib/gcc/config/arm/arm.md b/contrib/gcc/config/arm/arm.md
index 0e60712..9f10d10 100644
--- a/contrib/gcc/config/arm/arm.md
+++ b/contrib/gcc/config/arm/arm.md
@@ -1,32 +1,29 @@
;;- Machine description for ARM for GNU compiler
;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
-;; 2001, 2002 Free Software Foundation, Inc.
+;; 2001, 2002, 2003 2004 Free Software Foundation, Inc.
;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
;; and Martin Simmons (@harleqn.co.uk).
;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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 2, or (at your option)
-;; any later version.
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, or (at your
+;; option) any later version.
-;; GNU CC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-;; There are patterns in this file to support XFmode arithmetic.
-;; Unfortunately RISC iX doesn't work well with these so they are disabled.
-;; (See arm.h)
;;---------------------------------------------------------------------------
;; Constants
@@ -41,6 +38,13 @@
(LAST_ARM_REGNUM 15)
]
)
+;; 3rd operand to select_dominance_cc_mode
+(define_constants
+ [(DOM_CC_X_AND_Y 0)
+ (DOM_CC_NX_OR_Y 1)
+ (DOM_CC_X_OR_Y 2)
+ ]
+)
;; UNSPEC Usage:
;; Note: sin and cos are no-longer used.
@@ -65,15 +69,24 @@
; prevent combine from trying to rip it apart.
(UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
; being scheduled before the stack adjustment insn.
- (UNSPEC_CLZ 5) ; `clz' instruction, count leading zeros (SImode):
- ; operand 0 is the result,
- ; operand 1 is the parameter.
(UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
; this unspec is used to prevent the deletion of
; instructions setting registers for EH handling
; and stack frame generation. Operand 0 is the
; register to "use".
(UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
+ (UNSPEC_WSHUFH 8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
+ (UNSPEC_WACC 9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
+ (UNSPEC_TMOVMSK 10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
+ (UNSPEC_WSAD 11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
+ (UNSPEC_WSADZ 12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
+ (UNSPEC_WMACS 13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
+ (UNSPEC_WMACU 14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
+ (UNSPEC_WMACSZ 15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
+ (UNSPEC_WMACUZ 16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
+ (UNSPEC_CLRDI 17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
+ (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
+ (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
]
)
@@ -98,6 +111,12 @@
; a 32-bit object.
(VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
; a 64-bit object.
+ (VUNSPEC_TMRC 8) ; Used by the iWMMXt TMRC instruction.
+ (VUNSPEC_TMCR 9) ; Used by the iWMMXt TMCR instruction.
+ (VUNSPEC_ALIGN8 10) ; 8-byte alignment version of VUNSPEC_ALIGN
+ (VUNSPEC_WCMP_EQ 11) ; Used by the iWMMXt WCMPEQ instructions
+ (VUNSPEC_WCMP_GTU 12) ; Used by the iWMMXt WCMPGTU instructions
+ (VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
]
)
@@ -120,13 +139,14 @@
;; Operand number of an input operand that is shifted. Zero if the
;; given instruction does not shift one of its input operands.
-(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_is_xscale")))
+(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
(define_attr "shift" "" (const_int 0))
; Floating Point Unit. If we only have floating point emulation, then there
; is no point in scheduling the floating point insns. (Well, for best
; performance we should try and group them together).
-(define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
+(define_attr "fpu" "softfpa,fpa,fpe2,fpe3,maverick"
+ (const (symbol_ref "arm_fpu_attr")))
; LENGTH of an instruction (in bytes)
(define_attr "length" "" (const_int 4))
@@ -157,7 +177,6 @@
; mult a multiply instruction
; block blockage insn, this blocks all functional units
; float a floating point arithmetic operation (subject to expansion)
-; fdivx XFmode floating point division
; fdivd DFmode floating point division
; fdivs SFmode floating point division
; fmul Floating point multiply
@@ -178,9 +197,12 @@
; store2 store 2 words
; store3 store 3 words
; store4 store 4 words
+; Additions for Cirrus Maverick co-processor:
+; mav_farith Floating point arithmetic (4 cycle)
+; mav_dmult Double multiplies (7 cycle)
;
(define_attr "type"
- "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
+ "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4,mav_farith,mav_dmult"
(const_string "normal"))
; Load scheduling, set from the arm_ld_sched variable
@@ -221,7 +243,7 @@
; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
; have one. Later ones, such as StrongARM, have write-back caches, so don't
-; suffer blockages enough to warrent modelling this (and it can adversely
+; suffer blockages enough to warrant modelling this (and it can adversely
; affect the schedule).
(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
@@ -245,50 +267,10 @@
;; distant label. Only applicable to Thumb code.
(define_attr "far_jump" "yes,no" (const_string "no"))
-;; (define_function_unit {name} {num-units} {n-users} {test}
-;; {ready-delay} {issue-delay} [{conflict-list}])
-
-;;--------------------------------------------------------------------
-;; Floating point unit (FPA)
-;;--------------------------------------------------------------------
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fdivx")) 71 69)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fdivd")) 59 57)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fdivs")) 31 29)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fmul")) 9 7)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "ffmul")) 6 4)
+(define_automaton "arm")
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "farith")) 4 2)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "ffarith")) 2 2)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "r_2_f")) 5 3)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "f_2_r")) 1 2)
-
-; The fpa10 doesn't really have a memory read unit, but it can start to
-; speculatively execute the instruction in the pipeline, provided the data
-; is already loaded, so pretend reads have a delay of 2 (and that the
-; pipeline is infinite).
-
-(define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "f_load")) 3 1)
-
-;;--------------------------------------------------------------------
;; Write buffer
-;;--------------------------------------------------------------------
+;
; Strictly, we should model a 4-deep write buffer for ARM7xx based chips
;
; The write buffer on some of the arm6 processors is hard to model exactly.
@@ -300,102 +282,101 @@
; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
; cycle to add as well.
+(define_cpu_unit "write_buf" "arm")
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store1,r_mem_f")) 5 3)
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store2")) 7 4)
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store3")) 9 5)
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store4")) 11 6)
-
-;;--------------------------------------------------------------------
;; Write blockage unit
-;;--------------------------------------------------------------------
+;
; The write_blockage unit models (partially), the fact that reads will stall
; until the write buffer empties.
; The f_mem_r and r_mem_f could also block, but they are to the stack,
; so we don't model them here
-(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store1")) 5 5
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store2")) 7 7
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store3")) 9 9
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0
- (and (eq_attr "model_wbuf" "yes") (eq_attr "type" "store4")) 11 11
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "write_conflict" "yes")) 1 1)
-
-;;--------------------------------------------------------------------
-;; Core unit
-;;--------------------------------------------------------------------
-; Everything must spend at least one cycle in the core unit
-(define_function_unit "core" 1 0 (eq_attr "core_cycles" "single") 1 1)
-
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
-
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
-
-;; We do not need to conditionalize the define_function_unit immediately
-;; above. This one will be ignored for anything other than xscale
-;; compiles and for xscale compiles it provides a larger delay
-;; and the scheduler will DTRT.
-;; FIXME: this test needs to be revamped to not depend on this feature
-;; of the scheduler.
-
-(define_function_unit "core" 1 0
- (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
- (eq_attr "is_xscale" "yes"))
- 3 1)
+(define_cpu_unit "write_blockage" "arm")
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1")) 2 2)
+;; Core
+;
+(define_cpu_unit "core" "arm")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load")) 3 3)
+(define_insn_reservation "r_mem_f_wbuf" 5
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "r_mem_f"))
+ "core+write_buf*3")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store")) 4 4)
+(define_insn_reservation "store1_wbuf" 5
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store1"))
+ "core+write_buf*3+write_blockage*5")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")) 6 6)
+(define_insn_reservation "store2_wbuf" 7
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store2"))
+ "core+write_buf*4+write_blockage*7")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
+(define_insn_reservation "store3_wbuf" 9
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store3"))
+ "core+write_buf*5+write_blockage*9")
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "no") (eq_attr "type" "mult")) 16 16)
+(define_insn_reservation "store4_wbuf" 11
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store4"))
+ "core+write_buf*6+write_blockage*11")
-(define_function_unit "core" 1 0
- (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
- (eq_attr "type" "mult")) 4 4)
+(define_insn_reservation "store2" 3
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store2"))
+ "core*3")
-(define_function_unit "core" 1 0
- (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
- (eq_attr "type" "mult")) 3 2)
+(define_insn_reservation "store3" 4
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store3"))
+ "core*4")
-(define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3)
+(define_insn_reservation "store4" 5
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store4"))
+ "core*5")
-(define_function_unit "core" 1 0 (eq_attr "type" "store3") 4 4)
+(define_insn_reservation "store1_ldsched" 1
+ (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1"))
+ "core")
-(define_function_unit "core" 1 0 (eq_attr "type" "store4") 5 5)
+(define_insn_reservation "load_ldsched_xscale" 3
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
+ (eq_attr "is_xscale" "yes"))
+ "core")
+
+(define_insn_reservation "load_ldsched" 2
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
+ (eq_attr "is_xscale" "no"))
+ "core")
+
+(define_insn_reservation "load_or_store" 2
+ (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1"))
+ "core*2")
+
+(define_insn_reservation "mult" 16
+ (and (eq_attr "ldsched" "no") (eq_attr "type" "mult"))
+ "core*16")
+
+(define_insn_reservation "mult_ldsched_strongarm" 3
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
+ (eq_attr "type" "mult"))
+ "core*2")
+
+(define_insn_reservation "mult_ldsched" 4
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
+ (eq_attr "type" "mult"))
+ "core*4")
-(define_function_unit "core" 1 0
+(define_insn_reservation "multi_cycle" 32
(and (eq_attr "core_cycles" "multi")
- (eq_attr "type" "!mult,load,store1,store2,store3,store4")) 32 32)
+ (eq_attr "type" "!mult,load,store1,store2,store3,store4"))
+ "core*32")
+
+(define_insn_reservation "single_cycle" 1
+ (eq_attr "core_cycles" "single")
+ "core")
+
;;---------------------------------------------------------------------------
;; Insn patterns
@@ -405,6 +386,8 @@
;; Note: For DImode insns, there is normally no reason why operands should
;; not be in the same register, what we don't want is for something being
;; written to partially overlap something that is an input.
+;; Cirrus 64bit additions should not be split because we have a native
+;; 64bit addition instructions.
(define_expand "adddi3"
[(parallel
@@ -414,6 +397,16 @@
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[0], DImode))
+ operands[0] = force_reg (DImode, operands[0]);
+ if (!cirrus_fp_register (operands[1], DImode))
+ operands[1] = force_reg (DImode, operands[1]);
+ emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (TARGET_THUMB)
{
if (GET_CODE (operands[1]) != REG)
@@ -440,7 +433,7 @@
(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
(match_operand:DI 2 "s_register_operand" "r, 0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -468,7 +461,7 @@
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -497,7 +490,7 @@
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -534,7 +527,7 @@
"
)
-; If there is a scratch available, this will be faster than synthesising the
+; If there is a scratch available, this will be faster than synthesizing the
; addition.
(define_peephole2
[(match_scratch:SI 3 "r")
@@ -674,6 +667,60 @@
[(set_attr "conds" "set")]
)
+;; This is the canonicalization of addsi3_compare0_for_combiner when the
+;; addend is a constant.
+(define_insn "*cmpsi2_addneg"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC
+ (match_operand:SI 1 "s_register_operand" "r,r")
+ (match_operand:SI 2 "arm_addimm_operand" "I,L")))
+ (set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (plus:SI (match_dup 1)
+ (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
+ "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
+ "@
+ sub%?s\\t%0, %1, %2
+ add%?s\\t%0, %1, #%n2"
+ [(set_attr "conds" "set")]
+)
+
+;; Convert the sequence
+;; sub rd, rn, #1
+;; cmn rd, #1 (equivalent to cmp rd, #-1)
+;; bne dest
+;; into
+;; subs rd, rn, #1
+;; bcs dest ((unsigned)rn >= 1)
+;; similarly for the beq variant using bcc.
+;; This is a common looping idiom (while (n--))
+(define_peephole2
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (plus:SI (match_operand:SI 1 "s_register_operand" "")
+ (const_int -1)))
+ (set (match_operand 2 "cc_register" "")
+ (compare (match_dup 0) (const_int -1)))
+ (set (pc)
+ (if_then_else (match_operator 3 "equality_operator"
+ [(match_dup 2) (const_int 0)])
+ (match_operand 4 "" "")
+ (match_operand 5 "" "")))]
+ "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
+ [(parallel[
+ (set (match_dup 2)
+ (compare:CC
+ (match_dup 1) (const_int 1)))
+ (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
+ (set (pc)
+ (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
+ (match_dup 4)
+ (match_dup 5)))]
+ "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
+ operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
+ ? GEU : LTU),
+ VOIDmode,
+ operands[2], const0_rtx);"
+)
+
;; The next four insns work because they compare the result with one of
;; the operands, and we know that the use of the condition code is
;; either GEU or LTU, so we can use the carry flag from the addition
@@ -745,13 +792,13 @@
)
(define_insn "*addsi3_carryin_shift"
- [(set (match_operand:SI 0 "s_register_operand" "")
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
(plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
(plus:SI
(match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "")
- (match_operand:SI 4 "reg_or_int_operand" "")])
- (match_operand:SI 1 "s_register_operand" ""))))]
+ [(match_operand:SI 3 "s_register_operand" "r")
+ (match_operand:SI 4 "reg_or_int_operand" "rM")])
+ (match_operand:SI 1 "s_register_operand" "r"))))]
"TARGET_ARM"
"adc%?\\t%0, %1, %3%S2"
[(set_attr "conds" "use")]
@@ -800,77 +847,41 @@
(set_attr "length" "4,8")]
)
-(define_insn "addsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
- (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- adf%?s\\t%0, %1, %2
- suf%?s\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "adddf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
- (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- adf%?d\\t%0, %1, %2
- suf%?d\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*adddf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (plus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f,f"))
- (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- adf%?d\\t%0, %1, %2
- suf%?d\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*adddf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (plus:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "adf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
+ (match_operand:SI 2 "s_register_operand" ""))
+ (const_int -1)))
+ (clobber (match_operand:SI 3 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
+ "
+ operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
+")
-(define_insn "*adddf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (plus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "adf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "addsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (plus:SF (match_operand:SF 1 "s_register_operand" "")
+ (match_operand:SF 2 "fpa_add_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+")
-(define_insn "addxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
- (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- adf%?e\\t%0, %1, %2
- suf%?e\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "adddf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "")
+ (match_operand:DF 2 "fpa_add_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+")
(define_expand "subdi3"
[(parallel
@@ -880,6 +891,15 @@
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
+ if (TARGET_CIRRUS
+ && TARGET_ARM
+ && cirrus_fp_register (operands[0], DImode)
+ && cirrus_fp_register (operands[1], DImode))
+ {
+ emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (TARGET_THUMB)
{
if (GET_CODE (operands[1]) != REG)
@@ -1065,76 +1085,36 @@
(set_attr "length" "*,8")]
)
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
- (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- suf%?s\\t%0, %1, %2
- rsf%?s\\t%0, %2, %1"
- [(set_attr "type" "farith")]
-)
-
-(define_insn "subdf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- suf%?d\\t%0, %1, %2
- rsf%?d\\t%0, %2, %1"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*subdf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "suf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*subdf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f,f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- suf%?d\\t%0, %1, %2
- rsf%?d\\t%0, %2, %1"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "subsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (minus:SF (match_operand:SF 1 "fpa_rhs_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[1]);
+ if (!cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+ }
+")
-(define_insn "*subdf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "suf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "subdf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (minus:DF (match_operand:DF 1 "fpa_rhs_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[1]);
+ if (!cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+ }
+")
-(define_insn "subxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
- (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- suf%?e\\t%0, %1, %2
- rsf%?e\\t%0, %2, %1"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
;; Multiplication insns
@@ -1185,7 +1165,7 @@
(const_int 0)))
(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
(mult:SI (match_dup 2) (match_dup 1)))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mul%?s\\t%0, %2, %1"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
@@ -1198,7 +1178,7 @@
(match_operand:SI 1 "s_register_operand" "%?r,0"))
(const_int 0)))
(clobber (match_scratch:SI 0 "=&r,&r"))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mul%?s\\t%0, %2, %1"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
@@ -1229,7 +1209,7 @@
(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
(plus:SI (mult:SI (match_dup 2) (match_dup 1))
(match_dup 3)))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mla%?s\\t%0, %2, %1, %3"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
@@ -1244,13 +1224,13 @@
(match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
(const_int 0)))
(clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mla%?s\\t%0, %2, %1, %3"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
)
-;; Unnamed template to match long long multiply-accumlate (smlal)
+;; Unnamed template to match long long multiply-accumulate (smlal)
(define_insn "*mulsidi3adddi"
[(set (match_operand:DI 0 "s_register_operand" "=&r")
@@ -1287,7 +1267,7 @@
(set_attr "predicable" "yes")]
)
-;; Unnamed template to match long long unsigned multiply-accumlate (umlal)
+;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
(define_insn "*umulsidi3adddi"
[(set (match_operand:DI 0 "s_register_operand" "=&r")
@@ -1338,9 +1318,50 @@
(match_operand:HI 1 "s_register_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "s_register_operand" "r"))))]
- "TARGET_ARM && arm_is_xscale"
+ "TARGET_ARM && arm_arch5e"
"smulbb%?\\t%0, %1, %2"
- [(set_attr "type" "mult")]
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulhisi3tb"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (mult:SI (ashiftrt:SI
+ (match_operand:SI 1 "s_register_operand" "r")
+ (const_int 16))
+ (sign_extend:SI
+ (match_operand:HI 2 "s_register_operand" "r"))))]
+ "TARGET_ARM && arm_arch5e"
+ "smultb%?\\t%0, %1, %2"
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulhisi3bt"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (mult:SI (sign_extend:SI
+ (match_operand:HI 1 "s_register_operand" "r"))
+ (ashiftrt:SI
+ (match_operand:SI 2 "s_register_operand" "r")
+ (const_int 16))))]
+ "TARGET_ARM && arm_arch5e"
+ "smulbt%?\\t%0, %1, %2"
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulhisi3tt"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (mult:SI (ashiftrt:SI
+ (match_operand:SI 1 "s_register_operand" "r")
+ (const_int 16))
+ (ashiftrt:SI
+ (match_operand:SI 2 "s_register_operand" "r")
+ (const_int 16))))]
+ "TARGET_ARM && arm_arch5e"
+ "smultt%?\\t%0, %1, %2"
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
)
(define_insn "*mulhisi3addsi"
@@ -1350,9 +1371,10 @@
(match_operand:HI 2 "s_register_operand" "%r"))
(sign_extend:SI
(match_operand:HI 3 "s_register_operand" "r")))))]
- "TARGET_ARM && arm_is_xscale"
+ "TARGET_ARM && arm_arch5e"
"smlabb%?\\t%0, %2, %3, %1"
- [(set_attr "type" "mult")]
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
)
(define_insn "*mulhidi3adddi"
@@ -1363,210 +1385,64 @@
(match_operand:HI 2 "s_register_operand" "%r"))
(sign_extend:DI
(match_operand:HI 3 "s_register_operand" "r")))))]
- "TARGET_ARM && arm_is_xscale"
+ "TARGET_ARM && arm_arch5e"
"smlalbb%?\\t%Q0, %R0, %2, %3"
-[(set_attr "type" "mult")])
-
-(define_insn "mulsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (mult:SF (match_operand:SF 1 "s_register_operand" "f")
- (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "fml%?s\\t%0, %1, %2"
- [(set_attr "type" "ffmul")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "muldf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (match_operand:DF 1 "s_register_operand" "f")
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*muldf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*muldf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")])
-(define_insn "*muldf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF
- (float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
+(define_expand "mulsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (mult:SF (match_operand:SF 1 "s_register_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+")
-(define_insn "mulxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (mult:XF (match_operand:XF 1 "s_register_operand" "f")
- (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "muf%?e\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
+(define_expand "muldf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (mult:DF (match_operand:DF 1 "s_register_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+")
;; Division insns
-(define_insn "divsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
- (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- fdv%?s\\t%0, %1, %2
- frd%?s\\t%0, %2, %1"
- [(set_attr "type" "fdivs")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "divdf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- dvf%?d\\t%0, %1, %2
- rdf%?d\\t%0, %2, %1"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*divdf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "dvf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*divdf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "divsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (div:SF (match_operand:SF 1 "fpa_rhs_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "rdf%?d\\t%0, %2, %1"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
+ "")
-(define_insn "*divdf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "divdf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (div:DF (match_operand:DF 1 "fpa_rhs_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "dvf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "divxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
- (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- dvf%?e\\t%0, %1, %2
- rdf%?e\\t%0, %2, %1"
- [(set_attr "type" "fdivx")
- (set_attr "predicable" "yes")]
-)
+ "")
;; Modulo insns
-(define_insn "modsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (mod:SF (match_operand:SF 1 "s_register_operand" "f")
- (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?s\\t%0, %1, %2"
- [(set_attr "type" "fdivs")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "moddf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (match_operand:DF 1 "s_register_operand" "f")
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*moddf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*moddf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "modsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (mod:SF (match_operand:SF 1 "s_register_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
+ "")
-(define_insn "*moddf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "moddf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (mod:DF (match_operand:DF 1 "s_register_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "modxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (mod:XF (match_operand:XF 1 "s_register_operand" "f")
- (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
- "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "rmf%?e\\t%0, %1, %2"
- [(set_attr "type" "fdivx")
- (set_attr "predicable" "yes")]
-)
+ "")
;; Boolean and,ior,xor insns
@@ -1579,7 +1455,7 @@
(match_operator:DI 6 "logical_binary_operator"
[(match_operand:DI 1 "s_register_operand" "")
(match_operand:DI 2 "s_register_operand" "")]))]
- "TARGET_ARM && reload_completed"
+ "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
(set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
"
@@ -1656,7 +1532,7 @@
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
(match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_ARM"
+ "TARGET_ARM && ! TARGET_IWMMXT"
"#"
[(set_attr "length" "8")]
)
@@ -1859,6 +1735,83 @@
(set_attr "length" "8")]
)
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")))
+ (clobber (match_operand:SI 4 "s_register_operand" ""))]
+ "TARGET_THUMB"
+ [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[2]);
+
+ operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
+ operands[3] = GEN_INT (32 - temp);
+ }"
+)
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "shiftable_operator"
+ [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operand:SI 5 "s_register_operand" "")]))
+ (clobber (match_operand:SI 6 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(lshiftrt:SI (match_dup 6) (match_dup 4))
+ (match_dup 5)]))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[3]);
+
+ operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
+ operands[4] = GEN_INT (32 - temp);
+ }"
+)
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")))]
+ "TARGET_THUMB"
+ [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[2]);
+
+ operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
+ operands[3] = GEN_INT (32 - temp);
+ }"
+)
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "shiftable_operator"
+ [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operand:SI 5 "s_register_operand" "")]))
+ (clobber (match_operand:SI 6 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(ashiftrt:SI (match_dup 6) (match_dup 4))
+ (match_dup 5)]))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[3]);
+
+ operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
+ operands[4] = GEN_INT (32 - temp);
+ }"
+)
+
;;; ??? This pattern is bogus. If operand3 has bits outside the range
;;; represented by the bitfield, then this will produce incorrect results.
;;; Somewhere, the value needs to be truncated. On targets like the m68k,
@@ -1918,7 +1871,7 @@
/* A Trick, since we are setting the bottom bits in the word,
we can shift operand[3] up, operand[0] down, OR them together
and rotate the result back again. This takes 3 insns, and
- the third might be mergable into another op. */
+ the third might be mergeable into another op. */
/* The shift up copes with the possibility that operand[3] is
wider than the bitfield. */
rtx op0 = gen_reg_rtx (SImode);
@@ -2010,7 +1963,7 @@
(match_operand:DI 2 "s_register_operand" "0,r")))]
"TARGET_ARM"
"#"
- "TARGET_ARM && reload_completed"
+ "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
"
@@ -2136,7 +2089,7 @@
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
(match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_ARM"
+ "TARGET_ARM && ! TARGET_IWMMXT"
"#"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
@@ -2258,7 +2211,7 @@
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
(match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_IWMMXT"
"#"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
@@ -2367,6 +2320,109 @@
(set_attr "predicable" "yes")]
)
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operator:SI 9 "logical_binary_operator"
+ [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(lshiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(match_operator:SI 9 "logical_binary_operator"
+ [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])
+ (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(lshiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operator:SI 9 "logical_binary_operator"
+ [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(ashiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(match_operator:SI 9 "logical_binary_operator"
+ [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])
+ (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(ashiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
;; Minimum and maximum insns
@@ -2596,6 +2652,19 @@
[(set_attr "length" "2")]
)
+(define_expand "ashldi3"
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (ashift:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_ARM && (TARGET_IWMMXT || TARGET_CIRRUS)"
+ "
+ if (! s_register_operand (operands[1], DImode))
+ operands[1] = copy_to_mode_reg (DImode, operands[1]);
+ if (! s_register_operand (operands[2], SImode))
+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
+ "
+)
+
(define_insn "*arm_shiftsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(match_operator:SI 3 "shift_operator"
@@ -2769,49 +2838,33 @@
[(set_attr "length" "2")]
)
-(define_insn "negsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mnf%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "negdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mnf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*negdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (neg:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mnf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
+(define_expand "negsf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ ""
)
-(define_insn "negxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mnf%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "negdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "")
;; abssi2 doesn't really clobber the condition codes if a different register
;; is being set. To keep things simple, assume during rtl manipulations that
;; it does, but tell the final scan operator the truth. Similarly for
;; (neg (abs...))
-(define_insn "abssi2"
+(define_expand "abssi2"
+ [(parallel
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (abs:SI (match_operand:SI 1 "s_register_operand" "")))
+ (clobber (reg:CC CC_REGNUM))])]
+ "TARGET_ARM"
+ "")
+
+(define_insn "*arm_abssi2"
[(set (match_operand:SI 0 "s_register_operand" "=r,&r")
(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
(clobber (reg:CC CC_REGNUM))]
@@ -2839,147 +2892,29 @@
(set_attr "length" "8")]
)
-(define_insn "abssf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "abs%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "absdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "abs%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*absdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (abs:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "abs%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "absxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "abs%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "abssf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "")
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "sqt%?s\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
+(define_expand "absdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "")
-(define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
+(define_expand "sqrtsf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "sqt%?d\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
+ "")
-(define_insn "*sqrtdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (sqrt:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
+(define_expand "sqrtdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "sqt%?d\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "sqrtxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "sqt%?e\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
-
-;; SIN COS TAN and family are always emulated, so it's probably better
-;; to always call a library function.
-;(define_insn "sinsf2"
-; [(set (match_operand:SF 0 "s_register_operand" "=f")
-; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")]
-; UNSPEC_SIN))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "sin%?s\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "sindf2"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")]
-; UNSPEC_SIN))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "sin%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "*sindf_esfdf"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(float_extend:DF
-; (match_operand:SF 1 "s_register_operand" "f"))]
-; UNSPEC_SIN))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "sin%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "sinxf2"
-; [(set (match_operand:XF 0 "s_register_operand" "=f")
-; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")]
-; UNSPEC_SIN))]
-; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
-; "sin%?e\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "cossf2"
-; [(set (match_operand:SF 0 "s_register_operand" "=f")
-; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")]
-; UNSPEC_COS))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "cos%?s\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "cosdf2"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")]
-; UNSPEC_COS))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "cos%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "*cosdf_esfdf"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(float_extend:DF
-; (match_operand:SF 1 "s_register_operand" "f"))]
-; UNSPEC_COS))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "cos%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "cosxf2"
-; [(set (match_operand:XF 0 "s_register_operand" "=f")
-; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")]
-; UNSEPC_COS))]
-; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
-; "cos%?e\\t%0, %1"
-;[(set_attr "type" "float_em")])
+ "")
(define_insn_and_split "one_cmpldi2"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -3046,90 +2981,68 @@
;; Fixed <--> Floating conversion insns
-(define_insn "floatsisf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "flt%?s\\t%0, %1"
- [(set_attr "type" "r_2_f")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "floatsidf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "flt%?d\\t%0, %1"
- [(set_attr "type" "r_2_f")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "floatsixf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "flt%?e\\t%0, %1"
- [(set_attr "type" "r_2_f")
- (set_attr "predicable" "yes")]
-)
+(define_expand "floatsisf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (float:SF (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
+ DONE;
+ }
+")
-(define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "fix%?z\\t%0, %1"
- [(set_attr "type" "f_2_r")
- (set_attr "predicable" "yes")]
-)
+(define_expand "floatsidf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (float:DF (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
+ DONE;
+ }
+")
-(define_insn "fix_truncdfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "fix%?z\\t%0, %1"
- [(set_attr "type" "f_2_r")
- (set_attr "predicable" "yes")]
-)
+(define_expand "fix_truncsfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[0], SImode))
+ operands[0] = force_reg (SImode, operands[0]);
+ if (!cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[0]);
+ emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
+ DONE;
+ }
+")
-(define_insn "fix_truncxfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "fix%?z\\t%0, %1"
- [(set_attr "type" "f_2_r")
- (set_attr "predicable" "yes")]
-)
+(define_expand "fix_truncdfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[0]);
+ emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
+ DONE;
+ }
+")
;; Truncation insns
-(define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (float_truncate:SF
- (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mvf%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "truncxfsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
+(define_expand "truncdfsf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
(float_truncate:SF
- (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "truncxfdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float_truncate:DF
- (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
+ (match_operand:DF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ ""
)
;; Zero and sign extension instructions.
@@ -3632,7 +3545,7 @@
(sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_ARM && arm_arch4"
"*
- /* If the address is invalid, this will split the instruction into two. */
+ /* If the address is invalid, this will split the instruction into two. */
if (bad_signed_byte_operand (operands[1], VOIDmode))
return \"#\";
return \"ldr%?sb\\t%0, %1\";
@@ -3668,7 +3581,7 @@
XEXP (operands[2], 0) = plus_constant (operands[3], low);
operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
}
- /* Ensure the sum is in correct canonical form */
+ /* Ensure the sum is in correct canonical form. */
else if (GET_CODE (operands[1]) == PLUS
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& !s_register_operand (XEXP (operands[1], 1), VOIDmode))
@@ -3730,7 +3643,7 @@
(sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_ARM && arm_arch4"
"*
- /* If the address is invalid, this will split the instruction into two. */
+ /* If the address is invalid, this will split the instruction into two. */
if (bad_signed_byte_operand (operands[1], VOIDmode))
return \"#\";
return \"ldr%?sb\\t%0, %1\";
@@ -3765,7 +3678,7 @@
XEXP (operands[2], 0) = plus_constant (operands[0], low);
operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
}
- /* Ensure the sum is in correct canonical form */
+ /* Ensure the sum is in correct canonical form. */
else if (GET_CODE (operands[1]) == PLUS
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& !s_register_operand (XEXP (operands[1], 1), VOIDmode))
@@ -3854,33 +3767,12 @@
(set_attr "pool_range" "32,32")]
)
-(define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mvf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "extendsfxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "extenddfxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
+(define_expand "extendsfdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ ""
)
-
;; Move insns (including loads and stores)
@@ -3962,7 +3854,7 @@
(define_insn "*arm_movdi"
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
(match_operand:DI 1 "di_operand" "rIK,mi,r"))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS && ! TARGET_IWMMXT"
"*
return (output_move_double (operands));
"
@@ -3980,6 +3872,7 @@
[(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
(match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
"TARGET_THUMB
+ && !TARGET_CIRRUS
&& ( register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
"*
@@ -4025,7 +3918,7 @@
"
if (TARGET_ARM)
{
- /* Everything except mem = const or mem = mem can be done easily */
+ /* Everything except mem = const or mem = mem can be done easily. */
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (SImode, operands[1]);
if (GET_CODE (operands[1]) == CONST_INT
@@ -4039,7 +3932,7 @@
DONE;
}
}
- else /* TARGET_THUMB.... */
+ else /* TARGET_THUMB.... */
{
if (!no_new_pseudos)
{
@@ -4060,7 +3953,7 @@
(define_insn "*arm_movsi_insn"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
(match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
- "TARGET_ARM
+ "TARGET_ARM && ! TARGET_IWMMXT
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
@@ -4174,7 +4067,7 @@
;; This variant is used for AOF assembly, since it needs to mention the
;; pic register in the rtl.
(define_expand "pic_load_addr_based"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
"TARGET_ARM && flag_pic"
"operands[2] = pic_offset_table_rtx;"
@@ -4212,7 +4105,7 @@
(use (label_ref (match_operand 1 "" "")))]
"TARGET_THUMB && flag_pic"
"*
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[1]));
return \"add\\t%0, %|pc\";
"
@@ -4227,7 +4120,7 @@
(use (label_ref (match_operand 1 "" "")))]
"TARGET_ARM && flag_pic"
"*
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[1]));
return \"add%?\\t%0, %|pc, %0\";
"
@@ -4275,7 +4168,7 @@
(set (match_dup 2)
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
;; store the high byte
- (set (match_dup 4) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
+ (set (match_dup 4) (match_dup 5))]
"TARGET_ARM"
"
{
@@ -4291,7 +4184,8 @@
operands[1] = adjust_address (operands[1], QImode, 0);
operands[3] = gen_lowpart (QImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_reg_rtx (SImode);
+ operands[2] = gen_reg_rtx (SImode);
+ operands[5] = gen_lowpart (QImode, operands[2]);
}"
)
@@ -4299,7 +4193,7 @@
[(set (match_dup 4) (match_dup 3))
(set (match_dup 2)
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
- (set (match_operand 1 "" "") (subreg:QI (match_dup 2) 3))]
+ (set (match_operand 1 "" "") (match_dup 5))]
"TARGET_ARM"
"
{
@@ -4316,13 +4210,14 @@
operands[3] = gen_lowpart (QImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[2] = gen_reg_rtx (SImode);
+ operands[5] = gen_lowpart (QImode, operands[2]);
}"
)
;; Subroutine to store a half word integer constant into memory.
(define_expand "storeinthi"
[(set (match_operand 0 "" "")
- (subreg:QI (match_operand 1 "" "") 0))
+ (match_operand 1 "" ""))
(set (match_dup 3) (match_dup 2))]
"TARGET_ARM"
"
@@ -4363,6 +4258,7 @@
operands[3] = adjust_address (op0, QImode, 1);
operands[0] = adjust_address (operands[0], QImode, 0);
operands[2] = gen_lowpart (QImode, operands[2]);
+ operands[1] = gen_lowpart (QImode, operands[1]);
}"
)
@@ -4523,7 +4419,7 @@
}
}
}
- /* Handle loading a large integer during reload */
+ /* Handle loading a large integer during reload. */
else if (GET_CODE (operands[1]) == CONST_INT
&& !const_ok_for_arm (INTVAL (operands[1]))
&& !const_ok_for_arm (~INTVAL (operands[1])))
@@ -4567,7 +4463,7 @@
= replace_equiv_address (operands[1],
copy_to_reg (XEXP (operands[1], 0)));
}
- /* Handle loading a large integer during reload */
+ /* Handle loading a large integer during reload. */
else if (GET_CODE (operands[1]) == CONST_INT
&& !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
{
@@ -4585,8 +4481,8 @@
)
(define_insn "*thumb_movhi_insn"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l, m,*r,*h,l")
- (match_operand:HI 1 "general_operand" "l,mn,l,*h,*r,I"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
+ (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
"TARGET_THUMB
&& ( register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
@@ -4618,8 +4514,7 @@
return \"ldrh %0, %1\";
}"
[(set_attr "length" "2,4,2,2,2,2")
- (set_attr "type" "*,load,store1,*,*,*")
- (set_attr "pool_range" "*,64,*,*,*,*")]
+ (set_attr "type" "*,load,store1,*,*,*")]
)
@@ -4683,11 +4578,12 @@
(set (match_dup 3)
(ashiftrt:SI (match_dup 2) (const_int 16)))
(set (match_operand:HI 0 "s_register_operand" "")
- (subreg:HI (match_dup 3) 0))]
+ (match_dup 4))]
"TARGET_ARM"
"
operands[2] = gen_reg_rtx (SImode);
operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_lowpart (HImode, operands[3]);
"
)
@@ -4871,7 +4767,7 @@
= replace_equiv_address (operands[1],
copy_to_reg (XEXP (operands[1], 0)));
}
- /* Handle loading a large integer during reload */
+ /* Handle loading a large integer during reload. */
else if (GET_CODE (operands[1]) == CONST_INT
&& !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
{
@@ -4959,39 +4855,11 @@
"
)
-(define_insn "*arm_movsf_hard_insn"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
- (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
- "TARGET_ARM
- && TARGET_HARD_FLOAT
- && (GET_CODE (operands[0]) != MEM
- || register_operand (operands[1], SFmode))"
- "@
- mvf%?s\\t%0, %1
- mnf%?s\\t%0, #%N1
- ldf%?s\\t%0, %1
- stf%?s\\t%1, %0
- str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
- stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
- mov%?\\t%0, %1
- ldr%?\\t%0, %1\\t%@ float
- str%?\\t%1, %0\\t%@ float"
- [(set_attr "length" "4,4,4,4,8,8,4,4,4")
- (set_attr "predicable" "yes")
- (set_attr "type"
- "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")
- (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
- (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
-)
-
-;; Exactly the same as above, except that all `f' cases are deleted.
-;; This is necessary to prevent reload from ever trying to use a `f' reg
-;; when -msoft-float.
-
(define_insn "*arm_movsf_soft_insn"
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
(match_operand:SF 1 "general_operand" "r,mE,r"))]
"TARGET_ARM
+ && !TARGET_CIRRUS
&& TARGET_SOFT_FLOAT
&& (GET_CODE (operands[0]) != MEM
|| register_operand (operands[1], SFmode))"
@@ -5090,48 +4958,11 @@
}"
)
-(define_insn "*movdf_hard_insn"
- [(set (match_operand:DF 0 "nonimmediate_operand"
- "=r,Q,r,m,r, f, f,f, m,!f,!r")
- (match_operand:DF 1 "general_operand"
- "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
- "TARGET_ARM
- && TARGET_HARD_FLOAT
- && (GET_CODE (operands[0]) != MEM
- || register_operand (operands[1], DFmode))"
- "*
- {
- switch (which_alternative)
- {
- default:
- case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
- case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
- case 2: case 3: case 4: return output_move_double (operands);
- case 5: return \"mvf%?d\\t%0, %1\";
- case 6: return \"mnf%?d\\t%0, #%N1\";
- case 7: return \"ldf%?d\\t%0, %1\";
- case 8: return \"stf%?d\\t%1, %0\";
- case 9: return output_mov_double_fpu_from_arm (operands);
- case 10: return output_mov_double_arm_from_fpu (operands);
- }
- }
- "
- [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
- (set_attr "predicable" "yes")
- (set_attr "type"
- "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
- (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
-)
-
-;; Software floating point version. This is essentially the same as movdi.
-;; Do not use `f' as a constraint to prevent reload from ever trying to use
-;; an `f' reg.
-
(define_insn "*movdf_soft_insn"
[(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
(match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
"TARGET_ARM && TARGET_SOFT_FLOAT
+ && !TARGET_CIRRUS
"
"* return output_move_double (operands);"
[(set_attr "length" "8,8,8")
@@ -5180,39 +5011,27 @@
(set_attr "pool_range" "*,*,*,1020,*,*")]
)
+;; Vector Moves
+(define_expand "movv2si"
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
+ (match_operand:V2SI 1 "general_operand" ""))]
+ "TARGET_REALLY_IWMMXT"
+{
+})
-(define_expand "movxf"
- [(set (match_operand:XF 0 "general_operand" "")
- (match_operand:XF 1 "general_operand" ""))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "")
-
-;; Even when the XFmode patterns aren't enabled, we enable this after
-;; reloading so that we can push floating point registers in the prologue.
+(define_expand "movv4hi"
+ [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
+ (match_operand:V4HI 1 "general_operand" ""))]
+ "TARGET_REALLY_IWMMXT"
+{
+})
-(define_insn "*movxf_hard_insn"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
- (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
- "TARGET_ARM && TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
- "*
- switch (which_alternative)
- {
- default:
- case 0: return \"mvf%?e\\t%0, %1\";
- case 1: return \"mnf%?e\\t%0, #%N1\";
- case 2: return \"ldf%?e\\t%0, %1\";
- case 3: return \"stf%?e\\t%1, %0\";
- case 4: return output_mov_long_double_fpu_from_arm (operands);
- case 5: return output_mov_long_double_arm_from_fpu (operands);
- case 6: return output_mov_long_double_arm_from_arm (operands);
- }
- "
- [(set_attr "length" "4,4,4,4,8,8,12")
- (set_attr "predicable" "yes")
- (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
- (set_attr "pool_range" "*,*,1024,*,*,*,*")
- (set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
-)
+(define_expand "movv8qi"
+ [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
+ (match_operand:V8QI 1 "general_operand" ""))]
+ "TARGET_REALLY_IWMMXT"
+{
+})
;; load- and store-multiple insns
@@ -5347,7 +5166,7 @@
(use (match_operand:SI 2 "" ""))])]
"TARGET_ARM"
"
- /* Support only fixed point registers */
+ /* Support only fixed point registers. */
if (GET_CODE (operands[2]) != CONST_INT
|| INTVAL (operands[2]) > 14
|| INTVAL (operands[2]) < 2
@@ -5538,7 +5357,7 @@
;; Compare & branch insns
-;; The range calcualations are based as follows:
+;; The range calculations are based as follows:
;; For forward branches, the address calculation returns the address of
;; the next instruction. This is 2 beyond the branch instruction.
;; For backward branches, the address calculation returns the address of
@@ -5554,17 +5373,36 @@
;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
-(define_insn "cbranchsi4"
- [(set (pc)
- (if_then_else
- (match_operator 0 "arm_comparison_operator"
- [(match_operand:SI 1 "register_operand" "l,r")
- (match_operand:SI 2 "nonmemory_operand" "rI,r")])
- (label_ref (match_operand 3 "" ""))
- (pc)))]
+(define_expand "cbranchsi4"
+ [(set (pc) (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_THUMB"
+ "
+ if (thumb_cmpneg_operand (operands[2], SImode))
+ {
+ emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
+ operands[3], operands[0]));
+ DONE;
+ }
+ if (!thumb_cmp_operand (operands[2], SImode))
+ operands[2] = force_reg (SImode, operands[2]);
+ ")
+
+(define_insn "*cbranchsi4_insn"
+ [(set (pc) (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "l,*h")
+ (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
"TARGET_THUMB"
"*
output_asm_insn (\"cmp\\t%1, %2\", operands);
+
switch (get_attr_length (insn))
{
case 4: return \"b%d0\\t%l3\";
@@ -5589,13 +5427,111 @@
(const_int 8))))]
)
+(define_insn "cbranchsi4_scratch"
+ [(set (pc) (if_then_else
+ (match_operator 4 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "l,0")
+ (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l,l"))]
+ "TARGET_THUMB"
+ "*
+ output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
+
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+(define_insn "*movsi_cbranchsi4"
+ [(set (pc)
+ (if_then_else
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
+ (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
+ (match_dup 1))]
+ "TARGET_THUMB"
+ "*{
+ if (which_alternative == 0)
+ output_asm_insn (\"cmp\t%0, #0\", operands);
+ else if (which_alternative == 1)
+ output_asm_insn (\"sub\t%0, %1, #0\", operands);
+ else
+ {
+ output_asm_insn (\"cmp\t%1, #0\", operands);
+ if (which_alternative == 2)
+ output_asm_insn (\"mov\t%0, %1\", operands);
+ else
+ output_asm_insn (\"str\t%1, %0\", operands);
+ }
+ switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
+ {
+ case 4: return \"b%d3\\t%l2\";
+ case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (gt (symbol_ref ("which_alternative"))
+ (const_int 1))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (le (symbol_ref ("which_alternative"))
+ (const_int 1))
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -250))
+ (le (minus (match_dup 2) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
+ (le (minus (match_dup 2) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -248))
+ (le (minus (match_dup 2) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
+ (le (minus (match_dup 2) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
(define_insn "*negated_cbranchsi4"
[(set (pc)
(if_then_else
- (match_operator 0 "arm_comparison_operator"
- [(match_operand:SI 1 "register_operand" "l")
- (neg:SI (match_operand:SI 2 "nonmemory_operand" "l"))])
- (label_ref (match_operand 3 "" ""))
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "l")
+ (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
"TARGET_THUMB"
"*
@@ -5624,6 +5560,836 @@
(const_int 8))))]
)
+(define_insn "*tbit_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "equality_operator"
+ [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
+ (const_int 1)
+ (match_operand:SI 2 "const_int_operand" "i"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 4 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ rtx op[3];
+ op[0] = operands[4];
+ op[1] = operands[1];
+ op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
+
+ output_asm_insn (\"lsl\\t%0, %1, %2\", op);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d0\\t%l3\";
+ case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*tstsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 3 "equality_operator"
+ [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
+ (match_operand:SI 1 "s_register_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"tst\\t%0, %1\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d3\\t%l2\";
+ case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -250))
+ (le (minus (match_dup 2) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
+ (le (minus (match_dup 2) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*andsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (and:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"and\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"and\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"and\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*orrsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "equality_operator"
+ [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
+ (match_operand:SI 2 "s_register_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"orr\\t%0, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*orrsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (ior:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"orr\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"orr\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"orr\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*xorsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "equality_operator"
+ [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
+ (match_operand:SI 2 "s_register_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"eor\\t%0, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*xorsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (xor:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"eor\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"eor\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"eor\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*bicsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "equality_operator"
+ [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
+ (match_operand:SI 1 "s_register_operand" "0"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"bic\\t%0, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*bicsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (match_operand:SI 2 "s_register_operand" "0,1,1,1"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (and:SI (not:SI (match_dup 3)) (match_dup 2)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"bic\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"bic\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"bic\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*cbranchne_decr1"
+ [(set (pc)
+ (if_then_else (match_operator 3 "equality_operator"
+ [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (plus:SI (match_dup 2) (const_int -1)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ rtx cond[2];
+ cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
+ ? GEU : LTU),
+ VOIDmode, operands[2], const1_rtx);
+ cond[1] = operands[4];
+
+ if (which_alternative == 0)
+ output_asm_insn (\"sub\\t%0, %2, #1\", operands);
+ else if (which_alternative == 1)
+ {
+ /* We must provide an alternative for a hi reg because reload
+ cannot handle output reloads on a jump instruction, but we
+ can't subtract into that. Fortunately a mov from lo to hi
+ does not clobber the condition codes. */
+ output_asm_insn (\"sub\\t%1, %2, #1\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ /* Similarly, but the target is memory. */
+ output_asm_insn (\"sub\\t%1, %2, #1\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4:
+ output_asm_insn (\"b%d0\\t%l1\", cond);
+ return \"\";
+ case 6:
+ output_asm_insn (\"b%D0\\t.LCB%=\", cond);
+ return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default:
+ output_asm_insn (\"b%D0\\t.LCB%=\", cond);
+ return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set_attr_alternative "length"
+ [
+ ;; Alternative 0
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ ;; Alternative 1
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))
+ ;; Alternative 2
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))
+ ;; Alternative 3
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))])]
+)
+
+(define_insn "*addsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "comparison_operator"
+ [(plus:SI
+ (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
+ (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
+ (const_int 0)])
+ (label_ref (match_operand 5 "" ""))
+ (pc)))
+ (set
+ (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
+ (plus:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[4]) == EQ
+ || GET_CODE (operands[4]) == NE
+ || GET_CODE (operands[4]) == GE
+ || GET_CODE (operands[4]) == LT)"
+ "*
+ {
+ rtx cond[3];
+
+
+ cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
+ cond[1] = operands[2];
+ cond[2] = operands[3];
+
+ if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
+ output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
+ else
+ output_asm_insn (\"add\\t%0, %1, %2\", cond);
+
+ if (which_alternative >= 3
+ && which_alternative < 4)
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ else if (which_alternative >= 4)
+ output_asm_insn (\"str\\t%1, %0\", operands);
+
+ switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
+ {
+ case 4:
+ return \"b%d4\\t%l5\";
+ case 6:
+ return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
+ default:
+ return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (lt (symbol_ref ("which_alternative"))
+ (const_int 3))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (lt (symbol_ref ("which_alternative"))
+ (const_int 3))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -250))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -248))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*addsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 3 "comparison_operator"
+ [(plus:SI
+ (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
+ (match_operand:SI 2 "reg_or_int_operand" "J,l,I,L"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=X,X,l,l"))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[3]) == EQ
+ || GET_CODE (operands[3]) == NE
+ || GET_CODE (operands[3]) == GE
+ || GET_CODE (operands[3]) == LT)"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ output_asm_insn (\"cmp\t%1, #%n2\", operands);
+ break;
+ case 1:
+ output_asm_insn (\"cmn\t%1, %2\", operands);
+ break;
+ case 3:
+ output_asm_insn (\"add\t%0, %1, %2\", operands);
+ break;
+ case 4:
+ output_asm_insn (\"add\t%0, %0, %2\", operands);
+ break;
+ }
+
+ switch (get_attr_length (insn))
+ {
+ case 4:
+ return \"b%d3\\t%l4\";
+ case 6:
+ return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default:
+ return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*subsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "comparison_operator"
+ [(minus:SI
+ (match_operand:SI 2 "s_register_operand" "l,l,1,l")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 5 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (minus:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[4]) == EQ
+ || GET_CODE (operands[4]) == NE
+ || GET_CODE (operands[4]) == GE
+ || GET_CODE (operands[4]) == LT)"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"sub\\t%0, %2, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ /* We must provide an alternative for a hi reg because reload
+ cannot handle output reloads on a jump instruction, but we
+ can't subtract into that. Fortunately a mov from lo to hi
+ does not clobber the condition codes. */
+ output_asm_insn (\"sub\\t%1, %2, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ /* Similarly, but the target is memory. */
+ output_asm_insn (\"sub\\t%1, %2, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
+ {
+ case 4:
+ return \"b%d4\\t%l5\";
+ case 6:
+ return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
+ default:
+ return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -250))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -248))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*subsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(minus:SI (match_operand:SI 1 "register_operand" "l")
+ (match_operand:SI 2 "nonmemory_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[0]) == EQ
+ || GET_CODE (operands[0]) == NE
+ || GET_CODE (operands[0]) == GE
+ || GET_CODE (operands[0]) == LT)"
+ "*
+ output_asm_insn (\"cmp\\t%1, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d0\\t%l3\";
+ case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
;; Comparison and test insns
@@ -5640,9 +6406,12 @@
(define_expand "cmpsf"
[(match_operand:SF 0 "s_register_operand" "")
- (match_operand:SF 1 "fpu_rhs_operand" "")]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ (match_operand:SF 1 "fpa_rhs_operand" "")]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
"
+ if (TARGET_CIRRUS && !cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[1]);
+
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
@@ -5651,20 +6420,12 @@
(define_expand "cmpdf"
[(match_operand:DF 0 "s_register_operand" "")
- (match_operand:DF 1 "fpu_rhs_operand" "")]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- DONE;
+ (match_operand:DF 1 "fpa_rhs_operand" "")]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
"
-)
+ if (TARGET_CIRRUS && !cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[1]);
-(define_expand "cmpxf"
- [(match_operand:XF 0 "s_register_operand" "")
- (match_operand:XF 1 "fpu_rhs_operand" "")]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
@@ -5721,124 +6482,47 @@
]
)
-(define_insn "*cmpsf_insn"
- [(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
- (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpdf_insn"
- [(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpesfdf_df"
- [(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (float_extend:DF
- (match_operand:SF 0 "s_register_operand" "f,f"))
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpdf_esfdf"
+;; Cirrus SF compare instruction
+(define_insn "*cirrus_cmpsf"
[(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "cmf%?\\t%0, %1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
+ (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
+ (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmps%?\\tr15, %V0, %V1"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "compare")]
)
-(define_insn "*cmpxf_insn"
+;; Cirrus DF compare instruction
+(define_insn "*cirrus_cmpdf"
[(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
- (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpsf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
- (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpdf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmp_esfdf_df_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (float_extend:DF
- (match_operand:SF 0 "s_register_operand" "f,f"))
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmp_df_esfdf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "cmf%?e\\t%0, %1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
+ (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
+ (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmpd%?\\tr15, %V0, %V1"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "compare")]
+)
+
+;; Cirrus DI compare instruction
+(define_expand "cmpdi"
+ [(match_operand:DI 0 "cirrus_fp_register" "")
+ (match_operand:DI 1 "cirrus_fp_register" "")]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "{
+ arm_compare_op0 = operands[0];
+ arm_compare_op1 = operands[1];
+ DONE;
+ }")
-(define_insn "*cmpxf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
- (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
+(define_insn "*cirrus_cmpdi"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
+ (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmp64%?\\tr15, %V0, %V1"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "compare")]
)
; This insn allows redundant compares to be removed by cse, nothing should
@@ -6137,77 +6821,77 @@
; scc insns
(define_expand "seq"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(eq:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sne"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ne:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sgt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(gt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sle"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(le:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sge"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ge:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
)
(define_expand "slt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(lt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sgtu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(gtu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sleu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(leu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sgeu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(geu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sltu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ltu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sunordered"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unordered:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
@@ -6215,7 +6899,7 @@
)
(define_expand "sordered"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ordered:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
@@ -6223,7 +6907,7 @@
)
(define_expand "sungt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ungt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
@@ -6231,7 +6915,7 @@
)
(define_expand "sunge"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unge:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
@@ -6239,7 +6923,7 @@
)
(define_expand "sunlt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unlt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
@@ -6247,7 +6931,7 @@
)
(define_expand "sunle"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unle:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
@@ -6258,14 +6942,14 @@
;;; simple ARM instructions.
;
; (define_expand "suneq"
-; [(set (match_operand:SI 0 "s_register_operand" "=r")
+; [(set (match_operand:SI 0 "s_register_operand" "")
; (uneq:SI (match_dup 1) (const_int 0)))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "abort ();"
; )
;
; (define_expand "sltgt"
-; [(set (match_operand:SI 0 "s_register_operand" "=r")
+; [(set (match_operand:SI 0 "s_register_operand" "")
; (ltgt:SI (match_dup 1) (const_int 0)))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "abort ();"
@@ -6338,9 +7022,9 @@
FAIL;
/* When compiling for SOFT_FLOAT, ensure both arms are in registers.
- Otherwise, ensure it is a valid FP add operand */
+ Otherwise, ensure it is a valid FP add operand. */
if ((!TARGET_HARD_FLOAT)
- || (!fpu_add_operand (operands[3], SFmode)))
+ || (!fpa_add_operand (operands[3], SFmode)))
operands[3] = force_reg (SFmode, operands[3]);
ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
@@ -6352,7 +7036,7 @@
[(set (match_operand:DF 0 "s_register_operand" "")
(if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
(match_operand:DF 2 "s_register_operand" "")
- (match_operand:DF 3 "fpu_add_operand" "")))]
+ (match_operand:DF 3 "fpa_add_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"
{
@@ -6388,28 +7072,6 @@
(set_attr "conds" "use")]
)
-(define_insn "*movsfcc_hard_insn"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
- (if_then_else:SF
- (match_operator 3 "arm_comparison_operator"
- [(match_operand 4 "cc_register" "") (const_int 0)])
- (match_operand:SF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
- (match_operand:SF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- mvf%D3s\\t%0, %2
- mnf%D3s\\t%0, #%N2
- mvf%d3s\\t%0, %1
- mnf%d3s\\t%0, #%N1
- mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
- mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
- mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
- mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
- [(set_attr "length" "4,4,4,4,8,8,8,8")
- (set_attr "type" "ffarith")
- (set_attr "conds" "use")]
-)
-
(define_insn "*movsfcc_soft_insn"
[(set (match_operand:SF 0 "s_register_operand" "=r,r")
(if_then_else:SF (match_operator 3 "arm_comparison_operator"
@@ -6423,28 +7085,6 @@
[(set_attr "conds" "use")]
)
-(define_insn "*movdfcc_insn"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
- (if_then_else:DF
- (match_operator 3 "arm_comparison_operator"
- [(match_operand 4 "cc_register" "") (const_int 0)])
- (match_operand:DF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
- (match_operand:DF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- mvf%D3d\\t%0, %2
- mnf%D3d\\t%0, #%N2
- mvf%d3d\\t%0, %1
- mnf%d3d\\t%0, #%N1
- mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
- mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
- mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
- mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
- [(set_attr "length" "4,4,4,4,8,8,8,8")
- (set_attr "type" "ffarith")
- (set_attr "conds" "use")]
-)
-
;; Jump and linkage insns
@@ -6570,7 +7210,7 @@
)
(define_insn "*call_value_indirect"
- [(set (match_operand 0 "" "=l")
+ [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
@@ -6609,8 +7249,8 @@
)
(define_insn "*call_value_reg"
- [(set (match_operand 0 "" "=r,f")
- (call (mem:SI (match_operand:SI 1 "s_register_operand" "r,r"))
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6623,8 +7263,8 @@
)
(define_insn "*call_value_mem"
- [(set (match_operand 0 "" "=r,f")
- (call (mem:SI (match_operand:SI 1 "memory_operand" "m,m"))
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6640,7 +7280,7 @@
;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
(define_insn "*call_symbol"
- [(call (mem:SI (match_operand:SI 0 "" "X"))
+ [(call (mem:SI (match_operand:SI 0 "" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6655,8 +7295,8 @@
)
(define_insn "*call_value_symbol"
- [(set (match_operand 0 "s_register_operand" "=r,f")
- (call (mem:SI (match_operand:SI 1 "" "X,X"))
+ [(set (match_operand 0 "s_register_operand" "")
+ (call (mem:SI (match_operand:SI 1 "" ""))
(match_operand:SI 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6671,7 +7311,7 @@
)
(define_insn "*call_insn"
- [(call (mem:SI (match_operand:SI 0 "" "X"))
+ [(call (mem:SI (match_operand:SI 0 "" ""))
(match_operand:SI 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6684,8 +7324,8 @@
)
(define_insn "*call_value_insn"
- [(set (match_operand 0 "register_operand" "=l")
- (call (mem:SI (match_operand 1 "" "X"))
+ [(set (match_operand 0 "register_operand" "")
+ (call (mem:SI (match_operand 1 "" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6738,8 +7378,8 @@
)
(define_insn "*sibcall_value_insn"
- [(set (match_operand 0 "s_register_operand" "=r,f")
- (call (mem:SI (match_operand:SI 1 "" "X,X"))
+ [(set (match_operand 0 "s_register_operand" "")
+ (call (mem:SI (match_operand:SI 1 "" "X"))
(match_operand 2 "" "")))
(return)
(use (match_operand 3 "" ""))]
@@ -6764,6 +7404,7 @@
return output_return_instruction (const_true_rtx, TRUE, FALSE);
}"
[(set_attr "type" "load")
+ (set_attr "length" "12")
(set_attr "predicable" "yes")]
)
@@ -6784,6 +7425,7 @@
return output_return_instruction (operands[0], TRUE, FALSE);
}"
[(set_attr "conds" "use")
+ (set_attr "length" "12")
(set_attr "type" "load")]
)
@@ -6821,7 +7463,7 @@
(const_int 67108860)))] ; 0x03fffffc
"TARGET_ARM"
"
- operands[1] = gen_rtx_REG (CC_NOOVmode, 24);
+ operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
")
(define_insn "*check_arch2"
@@ -6997,6 +7639,24 @@
]
)
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "shiftable_operator"
+ [(match_operator:SI 2 "shiftable_operator"
+ [(match_operator:SI 3 "shift_operator"
+ [(match_operand:SI 4 "s_register_operand" "")
+ (match_operand:SI 5 "reg_or_int_operand" "")])
+ (match_operand:SI 6 "s_register_operand" "")])
+ (match_operand:SI 7 "arm_rhs_operand" "")]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 8)
+ (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
+ (match_dup 6)]))
+ (set (match_dup 0)
+ (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
+ "")
+
(define_insn "*arith_shiftsi_compare0"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
@@ -7112,11 +7772,17 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARM"
"*
- if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
- return \"mov\\t%0, %2, lsr #31\";
+ if (operands[3] == const0_rtx)
+ {
+ if (GET_CODE (operands[1]) == LT)
+ return \"mov\\t%0, %2, lsr #31\";
+
+ if (GET_CODE (operands[1]) == GE)
+ return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
- if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
- return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
+ if (GET_CODE (operands[1]) == EQ)
+ return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
+ }
if (GET_CODE (operands[1]) == NE)
{
@@ -7347,6 +8013,192 @@
(set_attr "length" "8")]
)
+(define_insn_and_split "*ior_scc_scc"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (ior:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")])))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
+ != CCmode)"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 7)
+ (compare
+ (ior:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
+ "operands[7]
+ = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
+ DOM_CC_X_OR_Y),
+ CC_REGNUM);"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "16")])
+
+; If the above pattern is followed by a CMP insn, then the compare is
+; redundant, since we can rework the conditional instruction that follows.
+(define_insn_and_split "*ior_scc_scc_cmp"
+ [(set (match_operand 0 "dominant_cc_register" "")
+ (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")]))
+ (const_int 0)))
+ (set (match_operand:SI 7 "s_register_operand" "=r")
+ (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
+ "TARGET_ARM"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 0)
+ (compare
+ (ior:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
+ ""
+ [(set_attr "conds" "set")
+ (set_attr "length" "16")])
+
+(define_insn_and_split "*and_scc_scc"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (and:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")])))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+ != CCmode)"
+ "#"
+ "TARGET_ARM && reload_completed
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+ != CCmode)"
+ [(set (match_dup 7)
+ (compare
+ (and:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
+ "operands[7]
+ = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
+ DOM_CC_X_AND_Y),
+ CC_REGNUM);"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "16")])
+
+; If the above pattern is followed by a CMP insn, then the compare is
+; redundant, since we can rework the conditional instruction that follows.
+(define_insn_and_split "*and_scc_scc_cmp"
+ [(set (match_operand 0 "dominant_cc_register" "")
+ (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")]))
+ (const_int 0)))
+ (set (match_operand:SI 7 "s_register_operand" "=r")
+ (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
+ "TARGET_ARM"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 0)
+ (compare
+ (and:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
+ ""
+ [(set_attr "conds" "set")
+ (set_attr "length" "16")])
+
+;; If there is no dominance in the comparison, then we can still save an
+;; instruction in the AND case, since we can know that the second compare
+;; need only zero the value if false (if true, then the value is already
+;; correct).
+(define_insn_and_split "*and_scc_scc_nodom"
+ [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
+ (and:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r,r,0")
+ (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r,r,r")
+ (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+ == CCmode)"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REGNUM))])
+ (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
+ (set (match_dup 0)
+ (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
+ (match_dup 0)
+ (const_int 0)))]
+ "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
+ operands[4], operands[5]),
+ CC_REGNUM);
+ operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
+ operands[5]);"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "20")])
+
+(define_split
+ [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (ior:SI
+ (and:SI (match_operand:SI 0 "s_register_operand" "")
+ (const_int 1))
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "arm_add_operand" "")]))
+ (const_int 0)))
+ (clobber (match_operand:SI 4 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 4)
+ (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
+ (match_dup 0)))
+ (set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
+ (const_int 0)))]
+ "")
+
+(define_split
+ [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (ior:SI
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "arm_add_operand" "")])
+ (and:SI (match_operand:SI 0 "s_register_operand" "")
+ (const_int 1)))
+ (const_int 0)))
+ (clobber (match_operand:SI 4 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 4)
+ (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
+ (match_dup 0)))
+ (set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
+ (const_int 0)))]
+ "")
+
(define_insn "*negscc"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(neg:SI (match_operator 3 "arm_comparison_operator"
@@ -7399,7 +8251,7 @@
return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
}
/* The only case that falls through to here is when both ops 1 & 2
- are constants */
+ are constants. */
}
if (GET_CODE (operands[5]) == GE
@@ -7418,7 +8270,7 @@
return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
}
/* The only case that falls through to here is when both ops 1 & 2
- are constants */
+ are constants. */
}
if (GET_CODE (operands[4]) == CONST_INT
&& !const_ok_for_arm (INTVAL (operands[4])))
@@ -7555,7 +8407,7 @@
"*
/* If we have an operation where (op x 0) is the identity operation and
the conditional operator is LT or GE and we are comparing against zero and
- everything is in registers then we can do this in two instructions */
+ everything is in registers then we can do this in two instructions. */
if (operands[3] == const0_rtx
&& GET_CODE (operands[7]) != AND
&& GET_CODE (operands[5]) == REG
@@ -8536,6 +9388,9 @@
(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (const_int 0)))]
"TARGET_ARM
+ && (!TARGET_CIRRUS
+ || (!cirrus_fp_register (operands[0], SImode)
+ && !cirrus_fp_register (operands[1], SImode)))
"
[(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
(set (match_dup 0) (match_dup 1))])]
@@ -8699,9 +9554,9 @@
(unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
"TARGET_ARM"
"*
- if (USE_RETURN_INSN (FALSE))
+ if (use_return_insn (FALSE, next_nonnote_insn (insn)))
return output_return_instruction (const_true_rtx, FALSE, FALSE);
- return arm_output_epilogue (FALSE);
+ return arm_output_epilogue (next_nonnote_insn (insn));
"
;; Length is absolute worst case
[(set_attr "length" "44")
@@ -8717,7 +9572,7 @@
"TARGET_EITHER"
"*
if (TARGET_ARM)
- return arm_output_epilogue (TRUE);
+ return arm_output_epilogue (NULL);
else /* TARGET_THUMB */
return thumb_unexpanded_epilogue ();
"
@@ -8731,9 +9586,9 @@
)
(define_expand "eh_epilogue"
- [(use (match_operand:SI 0 "register_operand" "r"))
- (use (match_operand:SI 1 "register_operand" "r"))
- (use (match_operand:SI 2 "register_operand" "r"))]
+ [(use (match_operand:SI 0 "register_operand" ""))
+ (use (match_operand:SI 1 "register_operand" ""))
+ (use (match_operand:SI 2 "register_operand" ""))]
"TARGET_EITHER"
"
{
@@ -9000,6 +9855,15 @@
"
)
+(define_insn "align_8"
+ [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ assemble_align (64);
+ return \"\";
+ "
+)
+
(define_insn "consttable_end"
[(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
"TARGET_EITHER"
@@ -9084,7 +9948,7 @@
;; Miscellaneous Thumb patterns
(define_expand "tablejump"
- [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
+ [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
(use (label_ref (match_operand 1 "" "")))])]
"TARGET_THUMB"
"
@@ -9110,12 +9974,12 @@
;; V5 Instructions,
-(define_insn "clz"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")]
- UNSPEC_CLZ))]
+(define_insn "clzsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_ARM && arm_arch5"
- "clz\\t%0, %1")
+ "clz%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
(define_expand "ffssi2"
[(set (match_operand:SI 0 "s_register_operand" "")
@@ -9131,12 +9995,32 @@
emit_insn (gen_negsi2 (t1, operands[1]));
emit_insn (gen_andsi3 (t2, operands[1], t1));
- emit_insn (gen_clz (t3, t2));
+ emit_insn (gen_clzsi2 (t3, t2));
emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
DONE;
}"
)
+(define_expand "ctzsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_ARM && arm_arch5"
+ "
+ {
+ rtx t1, t2, t3;
+
+ t1 = gen_reg_rtx (SImode);
+ t2 = gen_reg_rtx (SImode);
+ t3 = gen_reg_rtx (SImode);
+
+ emit_insn (gen_negsi2 (t1, operands[1]));
+ emit_insn (gen_andsi3 (t2, operands[1], t1));
+ emit_insn (gen_clzsi2 (t3, t2));
+ emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
+ DONE;
+ }"
+)
+
;; V5E instructions.
(define_insn "prefetch"
@@ -9161,3 +10045,10 @@
""
"%@ %0 needed for prologue"
)
+
+;; Load the FPA co-processor patterns
+(include "fpa.md")
+;; Load the Maverick co-processor patterns
+(include "cirrus.md")
+;; Load the Intel Wireless Multimedia Extension patterns
+(include "iwmmxt.md")
diff --git a/contrib/gcc/config/arm/cirrus.md b/contrib/gcc/config/arm/cirrus.md
new file mode 100644
index 0000000..0da8469
--- /dev/null
+++ b/contrib/gcc/config/arm/cirrus.md
@@ -0,0 +1,478 @@
+;; Cirrus EP9312 "Maverick" ARM floating point co-processor description.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Red Hat.
+;; Written by Aldy Hernandez (aldyh@redhat.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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+
+; Cirrus types for invalid insn combinations
+; not Not a cirrus insn
+; normal Any Cirrus insn not covered by the special cases below
+; double cfldrd, cfldr64, cfstrd, cfstr64
+; compare cfcmps, cfcmpd, cfcmp32, cfcmp64
+; move cfmvdlr, cfmvdhr, cfmvsr, cfmv64lr, cfmv64hr
+(define_attr "cirrus" "not,normal,double,compare,move" (const_string "not"))
+
+
+(define_insn "cirrus_adddi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (plus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:DI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfadd64%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_addsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (plus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfadd32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_addsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (plus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfadds%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_adddf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (plus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfaddd%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_subdi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (minus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:DI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsub64%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_subsi3_insn"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (minus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsub32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_subsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (minus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsubs%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_subdf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (minus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsubd%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_mulsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
+ (match_operand:SI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfmul32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "muldi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (mult:DI (match_operand:DI 2 "cirrus_fp_register" "v")
+ (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmul64%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_dmult")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_mulsi3addsi"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (plus:SI
+ (mult:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v"))
+ (match_operand:SI 3 "cirrus_fp_register" "0")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfmac32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+;; Cirrus SI multiply-subtract
+(define_insn "*cirrus_mulsi3subsi"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (minus:SI
+ (match_operand:SI 1 "cirrus_fp_register" "0")
+ (mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
+ (match_operand:SI 3 "cirrus_fp_register" "v"))))]
+ "0 && TARGET_ARM && TARGET_CIRRUS"
+ "cfmsc32%?\\t%V0, %V2, %V3"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_mulsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (mult:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmuls%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_muldf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (mult:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmuld%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_dmult")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashl_const"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsh32%?\\t%V0, %V1, #%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashiftrt_const"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashiftrt:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsh32%?\\t%V0, %V1, #-%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashlsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfrshl32%?\\t%V1, %V0, %s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "ashldi3_cirrus"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfrshl64%?\\t%V1, %V0, %s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashldi_const"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsh64%?\\t%V0, %V1, #%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashiftrtdi_const"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashiftrt:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsh64%?\\t%V0, %V1, #-%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_absdi2"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (abs:DI (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabs64%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+;; This doesn't really clobber ``cc''. Fixme: aldyh.
+(define_insn "*cirrus_negdi2"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (neg:DI (match_operand:DI 1 "cirrus_fp_register" "v")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfneg64%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_negsi2"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (neg:SI (match_operand:SI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfneg32%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_negsf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (neg:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfnegs%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_negdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (neg:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfnegd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+;; This doesn't really clobber the condition codes either.
+(define_insn "*cirrus_abssi2"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (abs:SI (match_operand:SI 1 "cirrus_fp_register" "v")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfabs32%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_abssf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (abs:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabss%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_absdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (abs:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabsd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+;; Convert Cirrus-SI to Cirrus-SF
+(define_insn "cirrus_floatsisf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float:SF (match_operand:SI 1 "s_register_operand" "r")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmv64lr%?\\t%Z2, %1\;cfcvt32s%?\\t%V0, %Y2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "move")]
+)
+
+(define_insn "cirrus_floatsidf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float:DF (match_operand:SI 1 "s_register_operand" "r")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmv64lr%?\\t%Z2, %1\;cfcvt32d%?\\t%V0, %Y2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "move")]
+)
+
+(define_insn "floatdisf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float:SF (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvt64s%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")])
+
+(define_insn "floatdidf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float:DF (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvt64d%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")])
+
+(define_insn "cirrus_truncsfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:SF (match_operand:SF 1 "cirrus_fp_register" "v"))))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cftruncs32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_truncdfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:DF (match_operand:DF 1 "cirrus_fp_register" "v"))))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cftruncd32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
+ [(set_attr "length" "8")]
+)
+
+(define_insn "*cirrus_truncdfsf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float_truncate:SF
+ (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvtds%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_extendsfdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float_extend:DF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvtsd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_arm_movdi"
+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,m,v")
+ (match_operand:DI 1 "di_operand" "rIK,mi,r,r,v,m,v,v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (output_move_double (operands));
+
+ case 3: return \"cfmv64lr%?\\t%V0, %Q1\;cfmv64hr%?\\t%V0, %R1\";
+ case 4: return \"cfmvr64l%?\\t%Q0, %V1\;cfmvr64h%?\\t%R0, %V1\";
+
+ case 5: return \"cfldr64%?\\t%V0, %1\";
+ case 6: return \"cfstr64%?\\t%V1, %0\";
+
+ /* Shifting by 0 will just copy %1 into %0. */
+ case 7: return \"cfsh64%?\\t%V0, %V1, #0\";
+
+ default: abort ();
+ }
+ }"
+ [(set_attr "length" " 8, 8, 8, 8, 8, 4, 4, 4")
+ (set_attr "type" " *,load,store2, *, *, load,store2, *")
+ (set_attr "pool_range" " *,1020, *, *, *, *, *, *")
+ (set_attr "neg_pool_range" " *,1012, *, *, *, *, *, *")
+ (set_attr "cirrus" "not, not, not,move,normal,double,double,normal")]
+)
+
+;; Cirrus SI values have been outlawed. Look in arm.h for the comment
+;; on HARD_REGNO_MODE_OK.
+
+(define_insn "*cirrus_arm_movsi_insn"
+ [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,*v,r,*v,T,*v")
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,*v,T,*v,*v"))]
+ "TARGET_ARM && TARGET_CIRRUS && 0
+ && (register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode))"
+ "@
+ mov%?\\t%0, %1
+ mvn%?\\t%0, #%B1
+ ldr%?\\t%0, %1
+ str%?\\t%1, %0
+ cfmv64lr%?\\t%Z0, %1
+ cfmvr64l%?\\t%0, %Z1
+ cfldr32%?\\t%V0, %1
+ cfstr32%?\\t%V1, %0
+ cfsh32%?\\t%V0, %V1, #0"
+ [(set_attr "type" "*, *, load,store1, *, *, load,store1, *")
+ (set_attr "pool_range" "*, *, 4096, *, *, *, 1024, *, *")
+ (set_attr "neg_pool_range" "*, *, 4084, *, *, *, 1012, *, *")
+ (set_attr "cirrus" "not,not, not, not,move,normal,normal,normal,normal")]
+)
+
+(define_insn "*cirrus_movsf_hard_insn"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=v,v,v,r,m,r,r,m")
+ (match_operand:SF 1 "general_operand" "v,m,r,v,v,r,mE,r"))]
+ "TARGET_ARM && TARGET_CIRRUS
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], SFmode))"
+ "@
+ cfcpys%?\\t%V0, %V1
+ cfldrs%?\\t%V0, %1
+ cfmvsr%?\\t%V0, %1
+ cfmvrs%?\\t%0, %V1
+ cfstrs%?\\t%V1, %0
+ mov%?\\t%0, %1
+ ldr%?\\t%0, %1\\t%@ float
+ str%?\\t%1, %0\\t%@ float"
+ [(set_attr "length" " *, *, *, *, *, 4, 4, 4")
+ (set_attr "type" " *, load, *, *,store1, *,load,store1")
+ (set_attr "pool_range" " *, *, *, *, *, *,4096, *")
+ (set_attr "neg_pool_range" " *, *, *, *, *, *,4084, *")
+ (set_attr "cirrus" "normal,normal,move,normal,normal,not, not, not")]
+)
+
+(define_insn "*cirrus_movdf_hard_insn"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Q,r,m,r,v,v,v,r,m")
+ (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,v,m,r,v,v"))]
+ "TARGET_ARM
+ && TARGET_CIRRUS
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], DFmode))"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
+ case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
+ case 2: case 3: case 4: return output_move_double (operands);
+ case 5: return \"cfcpyd%?\\t%V0, %V1\";
+ case 6: return \"cfldrd%?\\t%V0, %1\";
+ case 7: return \"cfmvdlr\\t%V0, %Q1\;cfmvdhr%?\\t%V0, %R1\";
+ case 8: return \"cfmvrdl%?\\t%Q0, %V1\;cfmvrdh%?\\t%R0, %V1\";
+ case 9: return \"cfstrd%?\\t%V1, %0\";
+ default: abort ();
+ }
+ }"
+ [(set_attr "type" "load,store2, *,store2,load, *, load, *, *,store2")
+ (set_attr "length" " 4, 4, 8, 8, 8, 4, 4, 8, 8, 4")
+ (set_attr "pool_range" " *, *, *, *, 252, *, *, *, *, *")
+ (set_attr "neg_pool_range" " *, *, *, *, 244, *, *, *, *, *")
+ (set_attr "cirrus" " not, not,not, not, not,normal,double,move,normal,double")]
+)
+
diff --git a/contrib/gcc/config/arm/coff.h b/contrib/gcc/config/arm/coff.h
index 0a78268..d6a6651 100644
--- a/contrib/gcc/config/arm/coff.h
+++ b/contrib/gcc/config/arm/coff.h
@@ -1,28 +1,27 @@
/* Definitions of target machine for GNU compiler.
For ARM with COFF object format.
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003
Free Software Foundation, Inc.
Contributed by Doug Evans (devans@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
-
-/* Note - it is important that this definition matches the one in tcoff.h */
+/* Note - it is important that this definition matches the one in tcoff.h. */
#undef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX "_"
@@ -32,7 +31,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fputs (" (ARM/coff)", stderr)
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \
@@ -44,23 +43,8 @@ Boston, MA 02111-1307, USA. */
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-#include "dbxcoff.h"
-/* A C statement to output assembler commands which will identify the
- object file as having been compiled with GNU CC (or another GNU
- compiler). */
-
-/* This outputs a lot of .req's to define alias for various registers.
- Let's try to avoid this. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
- do \
- { \
- fprintf (STREAM, "%s Generated by gcc %s for ARM/coff\n", \
- ASM_COMMENT_START, version_string); \
- fprintf (STREAM, ASM_APP_OFF); \
- } \
- while (0)
+#define TARGET_ASM_FILE_START_APP_OFF true
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_coff_asm_named_section
diff --git a/contrib/gcc/config/arm/crtn.asm b/contrib/gcc/config/arm/crtn.asm
index 2f4b542..9ad75e3 100644
--- a/contrib/gcc/config/arm/crtn.asm
+++ b/contrib/gcc/config/arm/crtn.asm
@@ -39,7 +39,7 @@
# in crti.asm. If you change this macro you must also change
# that macro match.
#
- # Note - we do not try any fancy optimisations of the return
+ # Note - we do not try any fancy optimizations of the return
# sequences here, it is just not worth it. Instead keep things
# simple. Restore all the save resgisters, including the link
# register and then perform the correct function return instruction.
diff --git a/contrib/gcc/config/arm/ecos-elf.h b/contrib/gcc/config/arm/ecos-elf.h
index f1377a9..d57fe8b 100644
--- a/contrib/gcc/config/arm/ecos-elf.h
+++ b/contrib/gcc/config/arm/ecos-elf.h
@@ -1,22 +1,22 @@
/* Definitions for ecos based ARM systems using ELF
Copyright (C) 1998, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
diff --git a/contrib/gcc/config/arm/elf.h b/contrib/gcc/config/arm/elf.h
index 0ad23f8..cb38264 100644
--- a/contrib/gcc/config/arm/elf.h
+++ b/contrib/gcc/config/arm/elf.h
@@ -5,22 +5,22 @@
Contributed by Philip Blundell <philb@gnu.org> and
Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#ifndef OBJECT_FORMAT_ELF
#error elf.h included before elfos.h
@@ -46,7 +46,7 @@ Boston, MA 02111-1307, USA. */
#ifndef SUBTARGET_ASM_FLOAT_SPEC
#define SUBTARGET_ASM_FLOAT_SPEC "\
-%{mapcs-float:-mfloat} %{msoft-float:-mno-fpu}"
+%{mapcs-float:-mfloat} %{msoft-float:-mfpu=softfpa}"
#endif
#ifndef ASM_SPEC
@@ -106,7 +106,7 @@ Boston, MA 02111-1307, USA. */
#endif
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
#ifndef MULTILIB_DEFAULTS
@@ -114,53 +114,12 @@ Boston, MA 02111-1307, USA. */
{ "marm", "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork", "fno-leading-underscore" }
#endif
-
-/* This outputs a lot of .req's to define alias for various registers.
- Let's try to avoid this. */
-#ifndef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
- do \
- { \
- fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n", \
- ASM_COMMENT_START, version_string); \
- output_file_directive (STREAM, main_input_filename); \
- fprintf (STREAM, ASM_APP_OFF); \
- } \
- while (0)
-#endif
-
-/* Output an internal label definition. */
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
- do \
- { \
- char * s = (char *) alloca (40 + strlen (PREFIX)); \
- extern int arm_target_label, arm_ccfsm_state; \
- extern rtx arm_target_insn; \
- \
- if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \
- && !strcmp (PREFIX, "L")) \
- { \
- arm_ccfsm_state = 0; \
- arm_target_insn = NULL; \
- } \
- ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM)); \
- ASM_OUTPUT_LABEL (STREAM, s); \
- } \
- while (0)
+#define TARGET_ASM_FILE_START_APP_OFF true
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION arm_elf_asm_named_section
-#undef ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_OUTPUT_ALIGNED_COMMON(STREAM, NAME, SIZE, ALIGN) \
- do \
- { \
- fprintf (STREAM, "\t.comm\t"); \
- assemble_name (STREAM, NAME); \
- fprintf (STREAM, ", %d, %d\n", SIZE, ALIGN); \
- } \
- while (0)
/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */
#define NEED_PLT_RELOC flag_pic
diff --git a/contrib/gcc/config/arm/fpa.md b/contrib/gcc/config/arm/fpa.md
new file mode 100644
index 0000000..3b6efbf
--- /dev/null
+++ b/contrib/gcc/config/arm/fpa.md
@@ -0,0 +1,752 @@
+;;- Machine description for FPA co-processor for ARM cpus.
+;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
+;; 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
+;; and Martin Simmons (@harleqn.co.uk).
+;; More major hacks by Richard Earnshaw (rearnsha@arm.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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; FPA automaton.
+(define_automaton "armfp")
+
+;; Floating point unit (FPA)
+(define_cpu_unit "fpa" "armfp")
+
+; The fpa10 doesn't really have a memory read unit, but it can start
+; to speculatively execute the instruction in the pipeline, provided
+; the data is already loaded, so pretend reads have a delay of 2 (and
+; that the pipeline is infinite).
+(define_cpu_unit "fpa_mem" "arm")
+
+(define_insn_reservation "fdivx" 71
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fdivx"))
+ "core+fpa*69")
+
+(define_insn_reservation "fdivd" 59
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fdivd"))
+ "core+fpa*57")
+
+(define_insn_reservation "fdivs" 31
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fdivs"))
+ "core+fpa*29")
+
+(define_insn_reservation "fmul" 9
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fmul"))
+ "core+fpa*7")
+
+(define_insn_reservation "ffmul" 6
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "ffmul"))
+ "core+fpa*4")
+
+(define_insn_reservation "farith" 4
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "farith"))
+ "core+fpa*2")
+
+(define_insn_reservation "ffarith" 2
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "ffarith"))
+ "core+fpa*2")
+
+(define_insn_reservation "r_2_f" 5
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "r_2_f"))
+ "core+fpa*3")
+
+(define_insn_reservation "f_2_r" 1
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "f_2_r"))
+ "core+fpa*2")
+
+(define_insn_reservation "f_load" 3
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load"))
+ "fpa_mem+core*3")
+
+(define_insn_reservation "f_store" 4
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store"))
+ "core*4")
+
+(define_insn_reservation "r_mem_f" 6
+ (and (eq_attr "model_wbuf" "no")
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")))
+ "core*6")
+
+(define_insn_reservation "f_mem_r" 7
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r"))
+ "core*7")
+
+
+(define_insn "*addsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f")
+ (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
+ (match_operand:SF 2 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ adf%?s\\t%0, %1, %2
+ suf%?s\\t%0, %1, #%N2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
+ (match_operand:DF 2 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ adf%?d\\t%0, %1, %2
+ suf%?d\\t%0, %1, #%N2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f,f"))
+ (match_operand:DF 2 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ adf%?d\\t%0, %1, %2
+ suf%?d\\t%0, %1, #%N2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "adf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "adf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f")
+ (minus:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ suf%?s\\t%0, %1, %2
+ rsf%?s\\t%0, %2, %1"
+ [(set_attr "type" "farith")]
+)
+
+(define_insn "*subdf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (minus:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ suf%?d\\t%0, %1, %2
+ rsf%?d\\t%0, %2, %1"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subdf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "suf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subdf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (minus:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f,f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ suf%?d\\t%0, %1, %2
+ rsf%?d\\t%0, %2, %1"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subdf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "suf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (mult:SF (match_operand:SF 1 "s_register_operand" "f")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "fml%?s\\t%0, %1, %2"
+ [(set_attr "type" "ffmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF (match_operand:DF 1 "s_register_operand" "f")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF (match_operand:DF 1 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF
+ (float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+;; Division insns
+
+(define_insn "*divsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ fdv%?s\\t%0, %1, %2
+ frd%?s\\t%0, %2, %1"
+ [(set_attr "type" "fdivs")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ dvf%?d\\t%0, %1, %2
+ rdf%?d\\t%0, %2, %1"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (div:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "dvf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (div:DF (match_operand:DF 1 "fpa_rhs_operand" "fG")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rdf%?d\\t%0, %2, %1"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (div:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "dvf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*modsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (mod:SF (match_operand:SF 1 "s_register_operand" "f")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?s\\t%0, %1, %2"
+ [(set_attr "type" "fdivs")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (match_operand:DF 1 "s_register_operand" "f")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (match_operand:DF 1 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*negsf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mnf%?s\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*negdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mnf%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*negdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (neg:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mnf%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*abssf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "abs%?s\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*absdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "abs%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*absdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (abs:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "abs%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*sqrtsf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "sqt%?s\\t%0, %1"
+ [(set_attr "type" "float_em")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*sqrtdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "sqt%?d\\t%0, %1"
+ [(set_attr "type" "float_em")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*sqrtdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (sqrt:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "sqt%?d\\t%0, %1"
+ [(set_attr "type" "float_em")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*floatsisf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "flt%?s\\t%0, %1"
+ [(set_attr "type" "r_2_f")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*floatsidf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "flt%?d\\t%0, %1"
+ [(set_attr "type" "r_2_f")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*fix_truncsfsi2_fpa"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "fix%?z\\t%0, %1"
+ [(set_attr "type" "f_2_r")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*fix_truncdfsi2_fpa"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "fix%?z\\t%0, %1"
+ [(set_attr "type" "f_2_r")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*truncdfsf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (float_truncate:SF
+ (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mvf%?s\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*extendsfdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mvf%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*movsf_fpa"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
+ (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
+ "TARGET_ARM
+ && TARGET_HARD_FLOAT
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], SFmode))"
+ "@
+ mvf%?s\\t%0, %1
+ mnf%?s\\t%0, #%N1
+ ldf%?s\\t%0, %1
+ stf%?s\\t%1, %0
+ str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
+ stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
+ mov%?\\t%0, %1
+ ldr%?\\t%0, %1\\t%@ float
+ str%?\\t%1, %0\\t%@ float"
+ [(set_attr "length" "4,4,4,4,8,8,4,4,4")
+ (set_attr "predicable" "yes")
+ (set_attr "type"
+ "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")
+ (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
+ (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
+)
+
+(define_insn "*movdf_fpa"
+ [(set (match_operand:DF 0 "nonimmediate_operand"
+ "=r,Q,r,m,r, f, f,f, m,!f,!r")
+ (match_operand:DF 1 "general_operand"
+ "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
+ "TARGET_ARM
+ && TARGET_HARD_FLOAT
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], DFmode))"
+ "*
+ {
+ switch (which_alternative)
+ {
+ default:
+ case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
+ case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
+ case 2: case 3: case 4: return output_move_double (operands);
+ case 5: return \"mvf%?d\\t%0, %1\";
+ case 6: return \"mnf%?d\\t%0, #%N1\";
+ case 7: return \"ldf%?d\\t%0, %1\";
+ case 8: return \"stf%?d\\t%1, %0\";
+ case 9: return output_mov_double_fpa_from_arm (operands);
+ case 10: return output_mov_double_arm_from_fpa (operands);
+ }
+ }
+ "
+ [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
+ (set_attr "predicable" "yes")
+ (set_attr "type"
+ "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
+ (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
+ (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
+)
+
+;; Saving and restoring the floating point registers in the prologue should
+;; be done in XFmode, even though we don't support that for anything else
+;; (Well, strictly it's 'internal representation', but that's effectively
+;; XFmode).
+
+(define_insn "*movxf_fpa"
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
+ (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && reload_completed"
+ "*
+ switch (which_alternative)
+ {
+ default:
+ case 0: return \"mvf%?e\\t%0, %1\";
+ case 1: return \"mnf%?e\\t%0, #%N1\";
+ case 2: return \"ldf%?e\\t%0, %1\";
+ case 3: return \"stf%?e\\t%1, %0\";
+ case 4: return output_mov_long_double_fpa_from_arm (operands);
+ case 5: return output_mov_long_double_arm_from_fpa (operands);
+ case 6: return output_mov_long_double_arm_from_arm (operands);
+ }
+ "
+ [(set_attr "length" "4,4,4,4,8,8,12")
+ (set_attr "predicable" "yes")
+ (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
+ (set_attr "pool_range" "*,*,1024,*,*,*,*")
+ (set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
+)
+
+(define_insn "*cmpsf_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
+ (match_operand:SF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?\\t%0, %1
+ cnf%?\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpdf_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?\\t%0, %1
+ cnf%?\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpesfdf_df_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (float_extend:DF
+ (match_operand:SF 0 "s_register_operand" "f,f"))
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?\\t%0, %1
+ cnf%?\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpdf_esfdf_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "cmf%?\\t%0, %1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpsf_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
+ (match_operand:SF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?e\\t%0, %1
+ cnf%?e\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpdf_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?e\\t%0, %1
+ cnf%?e\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmp_esfdf_df_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (float_extend:DF
+ (match_operand:SF 0 "s_register_operand" "f,f"))
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?e\\t%0, %1
+ cnf%?e\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmp_df_esfdf_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "cmf%?e\\t%0, %1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*movsfcc_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
+ (if_then_else:SF
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand 4 "cc_register" "") (const_int 0)])
+ (match_operand:SF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
+ (match_operand:SF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ mvf%D3s\\t%0, %2
+ mnf%D3s\\t%0, #%N2
+ mvf%d3s\\t%0, %1
+ mnf%d3s\\t%0, #%N1
+ mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
+ mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
+ mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
+ mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
+ [(set_attr "length" "4,4,4,4,8,8,8,8")
+ (set_attr "type" "ffarith")
+ (set_attr "conds" "use")]
+)
+
+(define_insn "*movdfcc_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
+ (if_then_else:DF
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand 4 "cc_register" "") (const_int 0)])
+ (match_operand:DF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
+ (match_operand:DF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ mvf%D3d\\t%0, %2
+ mnf%D3d\\t%0, #%N2
+ mvf%d3d\\t%0, %1
+ mnf%d3d\\t%0, #%N1
+ mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
+ mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
+ mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
+ mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
+ [(set_attr "length" "4,4,4,4,8,8,8,8")
+ (set_attr "type" "ffarith")
+ (set_attr "conds" "use")]
+)
+
diff --git a/contrib/gcc/config/arm/freebsd.h b/contrib/gcc/config/arm/freebsd.h
index 0d417a2..cc3f727 100644
--- a/contrib/gcc/config/arm/freebsd.h
+++ b/contrib/gcc/config/arm/freebsd.h
@@ -1,28 +1,46 @@
/* Definitions for StrongARM running FreeBSD using the ELF format
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
+
#undef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC FBSD_CPP_SPEC
+#undef LINK_SPEC
+#define LINK_SPEC " \
+ %{p:%nconsider using `-pg' instead of `-p' with gprof(1) } \
+ %{Wl,*:%*} \
+ %{v:-V} \
+ %{assert*} %{R*} %{rpath*} %{defsym*} \
+ %{shared:-Bshareable %{h*} %{soname*}} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
+ %{static:-Bstatic}} \
+ %{symbolic:-Bsymbolic}"
+
/************************[ Target stuff ]***********************************/
@@ -47,8 +65,5 @@ Boston, MA 02111-1307, USA. */
#undef SUBTARGET_CPU_DEFAULT
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_strongarm
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "FreeBSD"
-
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (FreeBSD/StrongARM ELF)");
diff --git a/contrib/gcc/config/arm/ieee754-df.S b/contrib/gcc/config/arm/ieee754-df.S
new file mode 100644
index 0000000..6a7aab8
--- /dev/null
+++ b/contrib/gcc/config/arm/ieee754-df.S
@@ -0,0 +1,1224 @@
+/* ieee754-df.S double-precision floating point support for ARM
+
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Nicolas Pitre (nico@cam.org)
+
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combine
+ executable.)
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * Notes:
+ *
+ * The goal of this code is to be as fast as possible. This is
+ * not meant to be easy to understand for the casual reader.
+ * For slightly simpler code please see the single precision version
+ * of this file.
+ *
+ * Only the default rounding mode is intended for best performances.
+ * Exceptions aren't supported yet, but that can be added quite easily
+ * if necessary without impacting performances.
+ */
+
+
+@ For FPA, float words are always big-endian.
+@ For VFP, floats words follow the memory system mode.
+#if defined(__VFP_FP__) && !defined(__ARMEB__)
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#else
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#endif
+
+
+#ifdef L_negdf2
+
+ARM_FUNC_START negdf2
+ @ flip sign bit
+ eor xh, xh, #0x80000000
+ RET
+
+ FUNC_END negdf2
+
+#endif
+
+#ifdef L_addsubdf3
+
+ARM_FUNC_START subdf3
+ @ flip sign bit of second arg
+ eor yh, yh, #0x80000000
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+ b 1f @ Skip Thumb-code prologue
+#endif
+
+ARM_FUNC_START adddf3
+
+1: @ Compare both args, return zero if equal but the sign.
+ teq xl, yl
+ eoreq ip, xh, yh
+ teqeq ip, #0x80000000
+ beq LSYM(Lad_z)
+
+ @ If first arg is 0 or -0, return second arg.
+ @ If second arg is 0 or -0, return first arg.
+ orrs ip, xl, xh, lsl #1
+ moveq xl, yl
+ moveq xh, yh
+ orrnes ip, yl, yh, lsl #1
+ RETc(eq)
+
+ stmfd sp!, {r4, r5, lr}
+
+ @ Mask out exponents.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r4, xh, ip
+ and r5, yh, ip
+
+ @ If either of them is 0x7ff, result will be INF or NAN
+ teq r4, ip
+ teqne r5, ip
+ beq LSYM(Lad_i)
+
+ @ Compute exponent difference. Make largest exponent in r4,
+ @ corresponding arg in xh-xl, and positive exponent difference in r5.
+ subs r5, r5, r4
+ rsblt r5, r5, #0
+ ble 1f
+ add r4, r4, r5
+ eor yl, xl, yl
+ eor yh, xh, yh
+ eor xl, yl, xl
+ eor xh, yh, xh
+ eor yl, xl, yl
+ eor yh, xh, yh
+1:
+
+ @ If exponent difference is too large, return largest argument
+ @ already in xh-xl. We need up to 54 bit to handle proper rounding
+ @ of 0x1p54 - 1.1.
+ cmp r5, #(54 << 20)
+ RETLDM "r4, r5" hi
+
+ @ Convert mantissa to signed integer.
+ tst xh, #0x80000000
+ bic xh, xh, ip, lsl #1
+ orr xh, xh, #0x00100000
+ beq 1f
+ rsbs xl, xl, #0
+ rsc xh, xh, #0
+1:
+ tst yh, #0x80000000
+ bic yh, yh, ip, lsl #1
+ orr yh, yh, #0x00100000
+ beq 1f
+ rsbs yl, yl, #0
+ rsc yh, yh, #0
+1:
+ @ If exponent == difference, one or both args were denormalized.
+ @ Since this is not common case, rescale them off line.
+ teq r4, r5
+ beq LSYM(Lad_d)
+LSYM(Lad_x):
+ @ Scale down second arg with exponent difference.
+ @ Apply shift one bit left to first arg and the rest to second arg
+ @ to simplify things later, but only if exponent does not become 0.
+ mov ip, #0
+ movs r5, r5, lsr #20
+ beq 3f
+ teq r4, #(1 << 20)
+ beq 1f
+ movs xl, xl, lsl #1
+ adc xh, ip, xh, lsl #1
+ sub r4, r4, #(1 << 20)
+ subs r5, r5, #1
+ beq 3f
+
+ @ Shift yh-yl right per r5, keep leftover bits into ip.
+1: rsbs lr, r5, #32
+ blt 2f
+ mov ip, yl, lsl lr
+ mov yl, yl, lsr r5
+ orr yl, yl, yh, lsl lr
+ mov yh, yh, asr r5
+ b 3f
+2: sub r5, r5, #32
+ add lr, lr, #32
+ cmp yl, #1
+ adc ip, ip, yh, lsl lr
+ mov yl, yh, asr r5
+ mov yh, yh, asr #32
+3:
+ @ the actual addition
+ adds xl, xl, yl
+ adc xh, xh, yh
+
+ @ We now have a result in xh-xl-ip.
+ @ Keep absolute value in xh-xl-ip, sign in r5.
+ ands r5, xh, #0x80000000
+ bpl LSYM(Lad_p)
+ rsbs ip, ip, #0
+ rscs xl, xl, #0
+ rsc xh, xh, #0
+
+ @ Determine how to normalize the result.
+LSYM(Lad_p):
+ cmp xh, #0x00100000
+ bcc LSYM(Lad_l)
+ cmp xh, #0x00200000
+ bcc LSYM(Lad_r0)
+ cmp xh, #0x00400000
+ bcc LSYM(Lad_r1)
+
+ @ Result needs to be shifted right.
+ movs xh, xh, lsr #1
+ movs xl, xl, rrx
+ movs ip, ip, rrx
+ orrcs ip, ip, #1
+ add r4, r4, #(1 << 20)
+LSYM(Lad_r1):
+ movs xh, xh, lsr #1
+ movs xl, xl, rrx
+ movs ip, ip, rrx
+ orrcs ip, ip, #1
+ add r4, r4, #(1 << 20)
+
+ @ Our result is now properly aligned into xh-xl, remaining bits in ip.
+ @ Round with MSB of ip. If halfway between two numbers, round towards
+ @ LSB of xl = 0.
+LSYM(Lad_r0):
+ adds xl, xl, ip, lsr #31
+ adc xh, xh, #0
+ teq ip, #0x80000000
+ biceq xl, xl, #1
+
+ @ One extreme rounding case may add a new MSB. Adjust exponent.
+ @ That MSB will be cleared when exponent is merged below.
+ tst xh, #0x00200000
+ addne r4, r4, #(1 << 20)
+
+ @ Make sure we did not bust our exponent.
+ adds ip, r4, #(1 << 20)
+ bmi LSYM(Lad_o)
+
+ @ Pack final result together.
+LSYM(Lad_e):
+ bic xh, xh, #0x00300000
+ orr xh, xh, r4
+ orr xh, xh, r5
+ RETLDM "r4, r5"
+
+LSYM(Lad_l):
+ @ Result must be shifted left and exponent adjusted.
+ @ No rounding necessary since ip will always be 0.
+#if __ARM_ARCH__ < 5
+
+ teq xh, #0
+ movne r3, #-11
+ moveq r3, #21
+ moveq xh, xl
+ moveq xl, #0
+ mov r2, xh
+ movs ip, xh, lsr #16
+ moveq r2, r2, lsl #16
+ addeq r3, r3, #16
+ tst r2, #0xff000000
+ moveq r2, r2, lsl #8
+ addeq r3, r3, #8
+ tst r2, #0xf0000000
+ moveq r2, r2, lsl #4
+ addeq r3, r3, #4
+ tst r2, #0xc0000000
+ moveq r2, r2, lsl #2
+ addeq r3, r3, #2
+ tst r2, #0x80000000
+ addeq r3, r3, #1
+
+#else
+
+ teq xh, #0
+ moveq xh, xl
+ moveq xl, #0
+ clz r3, xh
+ addeq r3, r3, #32
+ sub r3, r3, #11
+
+#endif
+
+ @ determine how to shift the value.
+ subs r2, r3, #32
+ bge 2f
+ adds r2, r2, #12
+ ble 1f
+
+ @ shift value left 21 to 31 bits, or actually right 11 to 1 bits
+ @ since a register switch happened above.
+ add ip, r2, #20
+ rsb r2, r2, #12
+ mov xl, xh, lsl ip
+ mov xh, xh, lsr r2
+ b 3f
+
+ @ actually shift value left 1 to 20 bits, which might also represent
+ @ 32 to 52 bits if counting the register switch that happened earlier.
+1: add r2, r2, #20
+2: rsble ip, r2, #32
+ mov xh, xh, lsl r2
+ orrle xh, xh, xl, lsr ip
+ movle xl, xl, lsl r2
+
+ @ adjust exponent accordingly.
+3: subs r4, r4, r3, lsl #20
+ bgt LSYM(Lad_e)
+
+ @ Exponent too small, denormalize result.
+ @ Find out proper shift value.
+ mvn r4, r4, asr #20
+ subs r4, r4, #30
+ bge 2f
+ adds r4, r4, #12
+ bgt 1f
+
+ @ shift result right of 1 to 20 bits, sign is in r5.
+ add r4, r4, #20
+ rsb r2, r4, #32
+ mov xl, xl, lsr r4
+ orr xl, xl, xh, lsl r2
+ orr xh, r5, xh, lsr r4
+ RETLDM "r4, r5"
+
+ @ shift result right of 21 to 31 bits, or left 11 to 1 bits after
+ @ a register switch from xh to xl.
+1: rsb r4, r4, #12
+ rsb r2, r4, #32
+ mov xl, xl, lsr r2
+ orr xl, xl, xh, lsl r4
+ mov xh, r5
+ RETLDM "r4, r5"
+
+ @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
+ @ from xh to xl.
+2: mov xl, xh, lsr r4
+ mov xh, r5
+ RETLDM "r4, r5"
+
+ @ Adjust exponents for denormalized arguments.
+LSYM(Lad_d):
+ teq r4, #0
+ eoreq xh, xh, #0x00100000
+ addeq r4, r4, #(1 << 20)
+ eor yh, yh, #0x00100000
+ subne r5, r5, #(1 << 20)
+ b LSYM(Lad_x)
+
+ @ Result is x - x = 0, unless x = INF or NAN.
+LSYM(Lad_z):
+ sub ip, ip, #0x00100000 @ ip becomes 0x7ff00000
+ and r2, xh, ip
+ teq r2, ip
+ orreq xh, ip, #0x00080000
+ movne xh, #0
+ mov xl, #0
+ RET
+
+ @ Overflow: return INF.
+LSYM(Lad_o):
+ orr xh, r5, #0x7f000000
+ orr xh, xh, #0x00f00000
+ mov xl, #0
+ RETLDM "r4, r5"
+
+ @ At least one of x or y is INF/NAN.
+ @ if xh-xl != INF/NAN: return yh-yl (which is INF/NAN)
+ @ if yh-yl != INF/NAN: return xh-xl (which is INF/NAN)
+ @ if either is NAN: return NAN
+ @ if opposite sign: return NAN
+ @ return xh-xl (which is INF or -INF)
+LSYM(Lad_i):
+ teq r4, ip
+ movne xh, yh
+ movne xl, yl
+ teqeq r5, ip
+ RETLDM "r4, r5" ne
+
+ orrs r4, xl, xh, lsl #12
+ orreqs r4, yl, yh, lsl #12
+ teqeq xh, yh
+ orrne xh, r5, #0x00080000
+ movne xl, #0
+ RETLDM "r4, r5"
+
+ FUNC_END subdf3
+ FUNC_END adddf3
+
+ARM_FUNC_START floatunsidf
+ teq r0, #0
+ moveq r1, #0
+ RETc(eq)
+ stmfd sp!, {r4, r5, lr}
+ mov r4, #(0x400 << 20) @ initial exponent
+ add r4, r4, #((52-1) << 20)
+ mov r5, #0 @ sign bit is 0
+ mov xl, r0
+ mov xh, #0
+ b LSYM(Lad_l)
+
+ FUNC_END floatunsidf
+
+ARM_FUNC_START floatsidf
+ teq r0, #0
+ moveq r1, #0
+ RETc(eq)
+ stmfd sp!, {r4, r5, lr}
+ mov r4, #(0x400 << 20) @ initial exponent
+ add r4, r4, #((52-1) << 20)
+ ands r5, r0, #0x80000000 @ sign bit in r5
+ rsbmi r0, r0, #0 @ absolute value
+ mov xl, r0
+ mov xh, #0
+ b LSYM(Lad_l)
+
+ FUNC_END floatsidf
+
+ARM_FUNC_START extendsfdf2
+ movs r2, r0, lsl #1
+ beq 1f @ value is 0.0 or -0.0
+ mov xh, r2, asr #3 @ stretch exponent
+ mov xh, xh, rrx @ retrieve sign bit
+ mov xl, r2, lsl #28 @ retrieve remaining bits
+ ands r2, r2, #0xff000000 @ isolate exponent
+ beq 2f @ exponent was 0 but not mantissa
+ teq r2, #0xff000000 @ check if INF or NAN
+ eorne xh, xh, #0x38000000 @ fixup exponent otherwise.
+ RET
+
+1: mov xh, r0
+ mov xl, #0
+ RET
+
+2: @ value was denormalized. We can normalize it now.
+ stmfd sp!, {r4, r5, lr}
+ mov r4, #(0x380 << 20) @ setup corresponding exponent
+ add r4, r4, #(1 << 20)
+ and r5, xh, #0x80000000 @ move sign bit in r5
+ bic xh, xh, #0x80000000
+ b LSYM(Lad_l)
+
+ FUNC_END extendsfdf2
+
+#endif /* L_addsubdf3 */
+
+#ifdef L_muldivdf3
+
+ARM_FUNC_START muldf3
+
+ stmfd sp!, {r4, r5, r6, lr}
+
+ @ Mask out exponents.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r4, xh, ip
+ and r5, yh, ip
+
+ @ Trap any INF/NAN.
+ teq r4, ip
+ teqne r5, ip
+ beq LSYM(Lml_s)
+
+ @ Trap any multiplication by 0.
+ orrs r6, xl, xh, lsl #1
+ orrnes r6, yl, yh, lsl #1
+ beq LSYM(Lml_z)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then add both exponents together.
+ movs r4, r4, lsr #1
+ teqne r5, #0
+ beq LSYM(Lml_d)
+LSYM(Lml_x):
+ add r4, r4, r5, asr #1
+
+ @ Preserve final sign in r4 along with exponent for now.
+ teq xh, yh
+ orrmi r4, r4, #0x8000
+
+ @ Convert mantissa to unsigned integer.
+ bic xh, xh, ip, lsl #1
+ bic yh, yh, ip, lsl #1
+ orr xh, xh, #0x00100000
+ orr yh, yh, #0x00100000
+
+#if __ARM_ARCH__ < 4
+
+ @ Well, no way to make it shorter without the umull instruction.
+ @ We must perform that 53 x 53 bit multiplication by hand.
+ stmfd sp!, {r7, r8, r9, sl, fp}
+ mov r7, xl, lsr #16
+ mov r8, yl, lsr #16
+ mov r9, xh, lsr #16
+ mov sl, yh, lsr #16
+ bic xl, xl, r7, lsl #16
+ bic yl, yl, r8, lsl #16
+ bic xh, xh, r9, lsl #16
+ bic yh, yh, sl, lsl #16
+ mul ip, xl, yl
+ mul fp, xl, r8
+ mov lr, #0
+ adds ip, ip, fp, lsl #16
+ adc lr, lr, fp, lsr #16
+ mul fp, r7, yl
+ adds ip, ip, fp, lsl #16
+ adc lr, lr, fp, lsr #16
+ mul fp, xl, sl
+ mov r5, #0
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, r7, yh
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, xh, r8
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, r9, yl
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, xh, sl
+ mul r6, r9, sl
+ adds r5, r5, fp, lsl #16
+ adc r6, r6, fp, lsr #16
+ mul fp, r9, yh
+ adds r5, r5, fp, lsl #16
+ adc r6, r6, fp, lsr #16
+ mul fp, xl, yh
+ adds lr, lr, fp
+ mul fp, r7, sl
+ adcs r5, r5, fp
+ mul fp, xh, yl
+ adc r6, r6, #0
+ adds lr, lr, fp
+ mul fp, r9, r8
+ adcs r5, r5, fp
+ mul fp, r7, r8
+ adc r6, r6, #0
+ adds lr, lr, fp
+ mul fp, xh, yh
+ adcs r5, r5, fp
+ adc r6, r6, #0
+ ldmfd sp!, {r7, r8, r9, sl, fp}
+
+#else
+
+ @ Here is the actual multiplication: 53 bits * 53 bits -> 106 bits.
+ umull ip, lr, xl, yl
+ mov r5, #0
+ umlal lr, r5, xl, yh
+ umlal lr, r5, xh, yl
+ mov r6, #0
+ umlal r5, r6, xh, yh
+
+#endif
+
+ @ The LSBs in ip are only significant for the final rounding.
+ @ Fold them into one bit of lr.
+ teq ip, #0
+ orrne lr, lr, #1
+
+ @ Put final sign in xh.
+ mov xh, r4, lsl #16
+ bic r4, r4, #0x8000
+
+ @ Adjust result if one extra MSB appeared (one of four times).
+ tst r6, #(1 << 9)
+ beq 1f
+ add r4, r4, #(1 << 19)
+ movs r6, r6, lsr #1
+ movs r5, r5, rrx
+ movs lr, lr, rrx
+ orrcs lr, lr, #1
+1:
+ @ Scale back to 53 bits.
+ @ xh contains sign bit already.
+ orr xh, xh, r6, lsl #12
+ orr xh, xh, r5, lsr #20
+ mov xl, r5, lsl #12
+ orr xl, xl, lr, lsr #20
+
+ @ Apply exponent bias, check range for underflow.
+ sub r4, r4, #0x00f80000
+ subs r4, r4, #0x1f000000
+ ble LSYM(Lml_u)
+
+ @ Round the result.
+ movs lr, lr, lsl #12
+ bpl 1f
+ adds xl, xl, #1
+ adc xh, xh, #0
+ teq lr, #0x80000000
+ biceq xl, xl, #1
+
+ @ Rounding may have produced an extra MSB here.
+ @ The extra bit is cleared before merging the exponent below.
+ tst xh, #0x00200000
+ addne r4, r4, #(1 << 19)
+1:
+ @ Check exponent for overflow.
+ adds ip, r4, #(1 << 19)
+ tst ip, #(1 << 30)
+ bne LSYM(Lml_o)
+
+ @ Add final exponent.
+ bic xh, xh, #0x00300000
+ orr xh, xh, r4, lsl #1
+ RETLDM "r4, r5, r6"
+
+ @ Result is 0, but determine sign anyway.
+LSYM(Lml_z):
+ eor xh, xh, yh
+LSYM(Ldv_z):
+ bic xh, xh, #0x7fffffff
+ mov xl, #0
+ RETLDM "r4, r5, r6"
+
+ @ Check if denormalized result is possible, otherwise return signed 0.
+LSYM(Lml_u):
+ cmn r4, #(53 << 19)
+ movle xl, #0
+ bicle xh, xh, #0x7fffffff
+ RETLDM "r4, r5, r6" le
+
+ @ Find out proper shift value.
+LSYM(Lml_r):
+ mvn r4, r4, asr #19
+ subs r4, r4, #30
+ bge 2f
+ adds r4, r4, #12
+ bgt 1f
+
+ @ shift result right of 1 to 20 bits, preserve sign bit, round, etc.
+ add r4, r4, #20
+ rsb r5, r4, #32
+ mov r3, xl, lsl r5
+ mov xl, xl, lsr r4
+ orr xl, xl, xh, lsl r5
+ movs xh, xh, lsl #1
+ mov xh, xh, lsr r4
+ mov xh, xh, rrx
+ adds xl, xl, r3, lsr #31
+ adc xh, xh, #0
+ teq lr, #0
+ teqeq r3, #0x80000000
+ biceq xl, xl, #1
+ RETLDM "r4, r5, r6"
+
+ @ shift result right of 21 to 31 bits, or left 11 to 1 bits after
+ @ a register switch from xh to xl. Then round.
+1: rsb r4, r4, #12
+ rsb r5, r4, #32
+ mov r3, xl, lsl r4
+ mov xl, xl, lsr r5
+ orr xl, xl, xh, lsl r4
+ bic xh, xh, #0x7fffffff
+ adds xl, xl, r3, lsr #31
+ adc xh, xh, #0
+ teq lr, #0
+ teqeq r3, #0x80000000
+ biceq xl, xl, #1
+ RETLDM "r4, r5, r6"
+
+ @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
+ @ from xh to xl. Leftover bits are in r3-r6-lr for rounding.
+2: rsb r5, r4, #32
+ mov r6, xl, lsl r5
+ mov r3, xl, lsr r4
+ orr r3, r3, xh, lsl r5
+ mov xl, xh, lsr r4
+ bic xh, xh, #0x7fffffff
+ bic xl, xl, xh, lsr r4
+ add xl, xl, r3, lsr #31
+ orrs r6, r6, lr
+ teqeq r3, #0x80000000
+ biceq xl, xl, #1
+ RETLDM "r4, r5, r6"
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Lml_d):
+ mov lr, #0
+ teq r4, #0
+ bne 2f
+ and r6, xh, #0x80000000
+1: movs xl, xl, lsl #1
+ adc xh, lr, xh, lsl #1
+ tst xh, #0x00100000
+ subeq r4, r4, #(1 << 19)
+ beq 1b
+ orr xh, xh, r6
+ teq r5, #0
+ bne LSYM(Lml_x)
+2: and r6, yh, #0x80000000
+3: movs yl, yl, lsl #1
+ adc yh, lr, yh, lsl #1
+ tst yh, #0x00100000
+ subeq r5, r5, #(1 << 20)
+ beq 3b
+ orr yh, yh, r6
+ b LSYM(Lml_x)
+
+ @ One or both args are INF or NAN.
+LSYM(Lml_s):
+ orrs r6, xl, xh, lsl #1
+ orrnes r6, yl, yh, lsl #1
+ beq LSYM(Lml_n) @ 0 * INF or INF * 0 -> NAN
+ teq r4, ip
+ bne 1f
+ orrs r6, xl, xh, lsl #12
+ bne LSYM(Lml_n) @ NAN * <anything> -> NAN
+1: teq r5, ip
+ bne LSYM(Lml_i)
+ orrs r6, yl, yh, lsl #12
+ bne LSYM(Lml_n) @ <anything> * NAN -> NAN
+
+ @ Result is INF, but we need to determine its sign.
+LSYM(Lml_i):
+ eor xh, xh, yh
+
+ @ Overflow: return INF (sign already in xh).
+LSYM(Lml_o):
+ and xh, xh, #0x80000000
+ orr xh, xh, #0x7f000000
+ orr xh, xh, #0x00f00000
+ mov xl, #0
+ RETLDM "r4, r5, r6"
+
+ @ Return NAN.
+LSYM(Lml_n):
+ mov xh, #0x7f000000
+ orr xh, xh, #0x00f80000
+ RETLDM "r4, r5, r6"
+
+ FUNC_END muldf3
+
+ARM_FUNC_START divdf3
+
+ stmfd sp!, {r4, r5, r6, lr}
+
+ @ Mask out exponents.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r4, xh, ip
+ and r5, yh, ip
+
+ @ Trap any INF/NAN or zeroes.
+ teq r4, ip
+ teqne r5, ip
+ orrnes r6, xl, xh, lsl #1
+ orrnes r6, yl, yh, lsl #1
+ beq LSYM(Ldv_s)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then substract divisor exponent from dividend''s.
+ movs r4, r4, lsr #1
+ teqne r5, #0
+ beq LSYM(Ldv_d)
+LSYM(Ldv_x):
+ sub r4, r4, r5, asr #1
+
+ @ Preserve final sign into lr.
+ eor lr, xh, yh
+
+ @ Convert mantissa to unsigned integer.
+ @ Dividend -> r5-r6, divisor -> yh-yl.
+ mov r5, #0x10000000
+ mov yh, yh, lsl #12
+ orr yh, r5, yh, lsr #4
+ orr yh, yh, yl, lsr #24
+ movs yl, yl, lsl #8
+ mov xh, xh, lsl #12
+ teqeq yh, r5
+ beq LSYM(Ldv_1)
+ orr r5, r5, xh, lsr #4
+ orr r5, r5, xl, lsr #24
+ mov r6, xl, lsl #8
+
+ @ Initialize xh with final sign bit.
+ and xh, lr, #0x80000000
+
+ @ Ensure result will land to known bit position.
+ cmp r5, yh
+ cmpeq r6, yl
+ bcs 1f
+ sub r4, r4, #(1 << 19)
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+1:
+ @ Apply exponent bias, check range for over/underflow.
+ add r4, r4, #0x1f000000
+ add r4, r4, #0x00f80000
+ cmn r4, #(53 << 19)
+ ble LSYM(Ldv_z)
+ cmp r4, ip, lsr #1
+ bge LSYM(Lml_o)
+
+ @ Perform first substraction to align result to a nibble.
+ subs r6, r6, yl
+ sbc r5, r5, yh
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ mov xl, #0x00100000
+ mov ip, #0x00080000
+
+ @ The actual division loop.
+1: subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip, lsr #1
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip, lsr #2
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip, lsr #3
+
+ orrs lr, r5, r6
+ beq 2f
+ mov r5, r5, lsl #4
+ orr r5, r5, r6, lsr #28
+ mov r6, r6, lsl #4
+ mov yh, yh, lsl #3
+ orr yh, yh, yl, lsr #29
+ mov yl, yl, lsl #3
+ movs ip, ip, lsr #4
+ bne 1b
+
+ @ We are done with a word of the result.
+ @ Loop again for the low word if this pass was for the high word.
+ tst xh, #0x00100000
+ bne 3f
+ orr xh, xh, xl
+ mov xl, #0
+ mov ip, #0x80000000
+ b 1b
+2:
+ @ Be sure result starts in the high word.
+ tst xh, #0x00100000
+ orreq xh, xh, xl
+ moveq xl, #0
+3:
+ @ Check if denormalized result is needed.
+ cmp r4, #0
+ ble LSYM(Ldv_u)
+
+ @ Apply proper rounding.
+ subs ip, r5, yh
+ subeqs ip, r6, yl
+ adcs xl, xl, #0
+ adc xh, xh, #0
+ teq ip, #0
+ biceq xl, xl, #1
+
+ @ Add exponent to result.
+ bic xh, xh, #0x00100000
+ orr xh, xh, r4, lsl #1
+ RETLDM "r4, r5, r6"
+
+ @ Division by 0x1p*: shortcut a lot of code.
+LSYM(Ldv_1):
+ and lr, lr, #0x80000000
+ orr xh, lr, xh, lsr #12
+ add r4, r4, #0x1f000000
+ add r4, r4, #0x00f80000
+ cmp r4, ip, lsr #1
+ bge LSYM(Lml_o)
+ cmp r4, #0
+ orrgt xh, xh, r4, lsl #1
+ RETLDM "r4, r5, r6" gt
+
+ cmn r4, #(53 << 19)
+ ble LSYM(Ldv_z)
+ orr xh, xh, #0x00100000
+ mov lr, #0
+ b LSYM(Lml_r)
+
+ @ Result must be denormalized: put remainder in lr for
+ @ rounding considerations.
+LSYM(Ldv_u):
+ orr lr, r5, r6
+ b LSYM(Lml_r)
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Ldv_d):
+ mov lr, #0
+ teq r4, #0
+ bne 2f
+ and r6, xh, #0x80000000
+1: movs xl, xl, lsl #1
+ adc xh, lr, xh, lsl #1
+ tst xh, #0x00100000
+ subeq r4, r4, #(1 << 19)
+ beq 1b
+ orr xh, xh, r6
+ teq r5, #0
+ bne LSYM(Ldv_x)
+2: and r6, yh, #0x80000000
+3: movs yl, yl, lsl #1
+ adc yh, lr, yh, lsl #1
+ tst yh, #0x00100000
+ subeq r5, r5, #(1 << 20)
+ beq 3b
+ orr yh, yh, r6
+ b LSYM(Ldv_x)
+
+ @ One or both arguments is either INF, NAN or zero.
+LSYM(Ldv_s):
+ teq r4, ip
+ teqeq r5, ip
+ beq LSYM(Lml_n) @ INF/NAN / INF/NAN -> NAN
+ teq r4, ip
+ bne 1f
+ orrs r4, xl, xh, lsl #12
+ bne LSYM(Lml_n) @ NAN / <anything> -> NAN
+ b LSYM(Lml_i) @ INF / <anything> -> INF
+1: teq r5, ip
+ bne 2f
+ orrs r5, yl, yh, lsl #12
+ bne LSYM(Lml_n) @ <anything> / NAN -> NAN
+ b LSYM(Lml_z) @ <anything> / INF -> 0
+2: @ One or both arguments are 0.
+ orrs r4, xl, xh, lsl #1
+ bne LSYM(Lml_i) @ <non_zero> / 0 -> INF
+ orrs r5, yl, yh, lsl #1
+ bne LSYM(Lml_z) @ 0 / <non_zero> -> 0
+ b LSYM(Lml_n) @ 0 / 0 -> NAN
+
+ FUNC_END divdf3
+
+#endif /* L_muldivdf3 */
+
+#ifdef L_cmpdf2
+
+ARM_FUNC_START gtdf2
+ARM_FUNC_ALIAS gedf2 gtdf2
+ mov ip, #-1
+ b 1f
+
+ARM_FUNC_START ltdf2
+ARM_FUNC_ALIAS ledf2 ltdf2
+ mov ip, #1
+ b 1f
+
+ARM_FUNC_START cmpdf2
+ARM_FUNC_ALIAS nedf2 cmpdf2
+ARM_FUNC_ALIAS eqdf2 cmpdf2
+ mov ip, #1 @ how should we specify unordered here?
+
+1: stmfd sp!, {r4, r5, lr}
+
+ @ Trap any INF/NAN first.
+ mov lr, #0x7f000000
+ orr lr, lr, #0x00f00000
+ and r4, xh, lr
+ and r5, yh, lr
+ teq r4, lr
+ teqne r5, lr
+ beq 3f
+
+ @ Test for equality.
+ @ Note that 0.0 is equal to -0.0.
+2: orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0
+ orreqs ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0
+ teqne xh, yh @ or xh == yh
+ teqeq xl, yl @ and xl == yl
+ moveq r0, #0 @ then equal.
+ RETLDM "r4, r5" eq
+
+ @ Check for sign difference.
+ teq xh, yh
+ movmi r0, xh, asr #31
+ orrmi r0, r0, #1
+ RETLDM "r4, r5" mi
+
+ @ Compare exponents.
+ cmp r4, r5
+
+ @ Compare mantissa if exponents are equal.
+ moveq xh, xh, lsl #12
+ cmpeq xh, yh, lsl #12
+ cmpeq xl, yl
+ movcs r0, yh, asr #31
+ mvncc r0, yh, asr #31
+ orr r0, r0, #1
+ RETLDM "r4, r5"
+
+ @ Look for a NAN.
+3: teq r4, lr
+ bne 4f
+ orrs xl, xl, xh, lsl #12
+ bne 5f @ x is NAN
+4: teq r5, lr
+ bne 2b
+ orrs yl, yl, yh, lsl #12
+ beq 2b @ y is not NAN
+5: mov r0, ip @ return unordered code from ip
+ RETLDM "r4, r5"
+
+ FUNC_END gedf2
+ FUNC_END gtdf2
+ FUNC_END ledf2
+ FUNC_END ltdf2
+ FUNC_END nedf2
+ FUNC_END eqdf2
+ FUNC_END cmpdf2
+
+#endif /* L_cmpdf2 */
+
+#ifdef L_unorddf2
+
+ARM_FUNC_START unorddf2
+ str lr, [sp, #-4]!
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and lr, xh, ip
+ teq lr, ip
+ bne 1f
+ orrs xl, xl, xh, lsl #12
+ bne 3f @ x is NAN
+1: and lr, yh, ip
+ teq lr, ip
+ bne 2f
+ orrs yl, yl, yh, lsl #12
+ bne 3f @ y is NAN
+2: mov r0, #0 @ arguments are ordered.
+ RETLDM
+
+3: mov r0, #1 @ arguments are unordered.
+ RETLDM
+
+ FUNC_END unorddf2
+
+#endif /* L_unorddf2 */
+
+#ifdef L_fixdfsi
+
+ARM_FUNC_START fixdfsi
+ orrs ip, xl, xh, lsl #1
+ beq 1f @ value is 0.
+
+ mov r3, r3, rrx @ preserve C flag (the actual sign)
+
+ @ check exponent range.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r2, xh, ip
+ teq r2, ip
+ beq 2f @ value is INF or NAN
+ bic ip, ip, #0x40000000
+ cmp r2, ip
+ bcc 1f @ value is too small
+ add ip, ip, #(31 << 20)
+ cmp r2, ip
+ bcs 3f @ value is too large
+
+ rsb r2, r2, ip
+ mov ip, xh, lsl #11
+ orr ip, ip, #0x80000000
+ orr ip, ip, xl, lsr #21
+ mov r2, r2, lsr #20
+ tst r3, #0x80000000 @ the sign bit
+ mov r0, ip, lsr r2
+ rsbne r0, r0, #0
+ RET
+
+1: mov r0, #0
+ RET
+
+2: orrs xl, xl, xh, lsl #12
+ bne 4f @ r0 is NAN.
+3: ands r0, r3, #0x80000000 @ the sign bit
+ moveq r0, #0x7fffffff @ maximum signed positive si
+ RET
+
+4: mov r0, #0 @ How should we convert NAN?
+ RET
+
+ FUNC_END fixdfsi
+
+#endif /* L_fixdfsi */
+
+#ifdef L_fixunsdfsi
+
+ARM_FUNC_START fixunsdfsi
+ orrs ip, xl, xh, lsl #1
+ movcss r0, #0 @ value is negative
+ RETc(eq) @ or 0 (xl, xh overlap r0)
+
+ @ check exponent range.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r2, xh, ip
+ teq r2, ip
+ beq 2f @ value is INF or NAN
+ bic ip, ip, #0x40000000
+ cmp r2, ip
+ bcc 1f @ value is too small
+ add ip, ip, #(31 << 20)
+ cmp r2, ip
+ bhi 3f @ value is too large
+
+ rsb r2, r2, ip
+ mov ip, xh, lsl #11
+ orr ip, ip, #0x80000000
+ orr ip, ip, xl, lsr #21
+ mov r2, r2, lsr #20
+ mov r0, ip, lsr r2
+ RET
+
+1: mov r0, #0
+ RET
+
+2: orrs xl, xl, xh, lsl #12
+ bne 4f @ value is NAN.
+3: mov r0, #0xffffffff @ maximum unsigned si
+ RET
+
+4: mov r0, #0 @ How should we convert NAN?
+ RET
+
+ FUNC_END fixunsdfsi
+
+#endif /* L_fixunsdfsi */
+
+#ifdef L_truncdfsf2
+
+ARM_FUNC_START truncdfsf2
+ orrs r2, xl, xh, lsl #1
+ moveq r0, r2, rrx
+ RETc(eq) @ value is 0.0 or -0.0
+
+ @ check exponent range.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r2, ip, xh
+ teq r2, ip
+ beq 2f @ value is INF or NAN
+ bic xh, xh, ip
+ cmp r2, #(0x380 << 20)
+ bls 4f @ value is too small
+
+ @ shift and round mantissa
+1: movs r3, xl, lsr #29
+ adc r3, r3, xh, lsl #3
+
+ @ if halfway between two numbers, round towards LSB = 0.
+ mov xl, xl, lsl #3
+ teq xl, #0x80000000
+ biceq r3, r3, #1
+
+ @ rounding might have created an extra MSB. If so adjust exponent.
+ tst r3, #0x00800000
+ addne r2, r2, #(1 << 20)
+ bicne r3, r3, #0x00800000
+
+ @ check exponent for overflow
+ mov ip, #(0x400 << 20)
+ orr ip, ip, #(0x07f << 20)
+ cmp r2, ip
+ bcs 3f @ overflow
+
+ @ adjust exponent, merge with sign bit and mantissa.
+ movs xh, xh, lsl #1
+ mov r2, r2, lsl #4
+ orr r0, r3, r2, rrx
+ eor r0, r0, #0x40000000
+ RET
+
+2: @ chech for NAN
+ orrs xl, xl, xh, lsl #12
+ movne r0, #0x7f000000
+ orrne r0, r0, #0x00c00000
+ RETc(ne) @ return NAN
+
+3: @ return INF with sign
+ and r0, xh, #0x80000000
+ orr r0, r0, #0x7f000000
+ orr r0, r0, #0x00800000
+ RET
+
+4: @ check if denormalized value is possible
+ subs r2, r2, #((0x380 - 24) << 20)
+ andle r0, xh, #0x80000000 @ too small, return signed 0.
+ RETc(le)
+
+ @ denormalize value so we can resume with the code above afterwards.
+ orr xh, xh, #0x00100000
+ mov r2, r2, lsr #20
+ rsb r2, r2, #25
+ cmp r2, #20
+ bgt 6f
+
+ rsb ip, r2, #32
+ mov r3, xl, lsl ip
+ mov xl, xl, lsr r2
+ orr xl, xl, xh, lsl ip
+ movs xh, xh, lsl #1
+ mov xh, xh, lsr r2
+ mov xh, xh, rrx
+5: teq r3, #0 @ fold r3 bits into the LSB
+ orrne xl, xl, #1 @ for rounding considerations.
+ mov r2, #(0x380 << 20) @ equivalent to the 0 float exponent
+ b 1b
+
+6: rsb r2, r2, #(12 + 20)
+ rsb ip, r2, #32
+ mov r3, xl, lsl r2
+ mov xl, xl, lsr ip
+ orr xl, xl, xh, lsl r2
+ and xh, xh, #0x80000000
+ b 5b
+
+ FUNC_END truncdfsf2
+
+#endif /* L_truncdfsf2 */
diff --git a/contrib/gcc/config/arm/ieee754-sf.S b/contrib/gcc/config/arm/ieee754-sf.S
new file mode 100644
index 0000000..5c97245
--- /dev/null
+++ b/contrib/gcc/config/arm/ieee754-sf.S
@@ -0,0 +1,816 @@
+/* ieee754-sf.S single-precision floating point support for ARM
+
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Nicolas Pitre (nico@cam.org)
+
+ This file is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combine
+ executable.)
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * Notes:
+ *
+ * The goal of this code is to be as fast as possible. This is
+ * not meant to be easy to understand for the casual reader.
+ *
+ * Only the default rounding mode is intended for best performances.
+ * Exceptions aren't supported yet, but that can be added quite easily
+ * if necessary without impacting performances.
+ */
+
+#ifdef L_negsf2
+
+ARM_FUNC_START negsf2
+ eor r0, r0, #0x80000000 @ flip sign bit
+ RET
+
+ FUNC_END negsf2
+
+#endif
+
+#ifdef L_addsubsf3
+
+ARM_FUNC_START subsf3
+ eor r1, r1, #0x80000000 @ flip sign bit of second arg
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+ b 1f @ Skip Thumb-code prologue
+#endif
+
+ARM_FUNC_START addsf3
+
+1: @ Compare both args, return zero if equal but the sign.
+ eor r2, r0, r1
+ teq r2, #0x80000000
+ beq LSYM(Lad_z)
+
+ @ If first arg is 0 or -0, return second arg.
+ @ If second arg is 0 or -0, return first arg.
+ bics r2, r0, #0x80000000
+ moveq r0, r1
+ bicnes r2, r1, #0x80000000
+ RETc(eq)
+
+ @ Mask out exponents.
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ and r3, r1, ip, lsr #1
+
+ @ If either of them is 255, result will be INF or NAN
+ teq r2, ip, lsr #1
+ teqne r3, ip, lsr #1
+ beq LSYM(Lad_i)
+
+ @ Compute exponent difference. Make largest exponent in r2,
+ @ corresponding arg in r0, and positive exponent difference in r3.
+ subs r3, r3, r2
+ addgt r2, r2, r3
+ eorgt r1, r0, r1
+ eorgt r0, r1, r0
+ eorgt r1, r0, r1
+ rsblt r3, r3, #0
+
+ @ If exponent difference is too large, return largest argument
+ @ already in r0. We need up to 25 bit to handle proper rounding
+ @ of 0x1p25 - 1.1.
+ cmp r3, #(25 << 23)
+ RETc(hi)
+
+ @ Convert mantissa to signed integer.
+ tst r0, #0x80000000
+ orr r0, r0, #0x00800000
+ bic r0, r0, #0xff000000
+ rsbne r0, r0, #0
+ tst r1, #0x80000000
+ orr r1, r1, #0x00800000
+ bic r1, r1, #0xff000000
+ rsbne r1, r1, #0
+
+ @ If exponent == difference, one or both args were denormalized.
+ @ Since this is not common case, rescale them off line.
+ teq r2, r3
+ beq LSYM(Lad_d)
+LSYM(Lad_x):
+
+ @ Scale down second arg with exponent difference.
+ @ Apply shift one bit left to first arg and the rest to second arg
+ @ to simplify things later, but only if exponent does not become 0.
+ movs r3, r3, lsr #23
+ teqne r2, #(1 << 23)
+ movne r0, r0, lsl #1
+ subne r2, r2, #(1 << 23)
+ subne r3, r3, #1
+
+ @ Shift second arg into ip, keep leftover bits into r1.
+ mov ip, r1, asr r3
+ rsb r3, r3, #32
+ mov r1, r1, lsl r3
+
+ add r0, r0, ip @ the actual addition
+
+ @ We now have a 64 bit result in r0-r1.
+ @ Keep absolute value in r0-r1, sign in r3.
+ ands r3, r0, #0x80000000
+ bpl LSYM(Lad_p)
+ rsbs r1, r1, #0
+ rsc r0, r0, #0
+
+ @ Determine how to normalize the result.
+LSYM(Lad_p):
+ cmp r0, #0x00800000
+ bcc LSYM(Lad_l)
+ cmp r0, #0x01000000
+ bcc LSYM(Lad_r0)
+ cmp r0, #0x02000000
+ bcc LSYM(Lad_r1)
+
+ @ Result needs to be shifted right.
+ movs r0, r0, lsr #1
+ mov r1, r1, rrx
+ add r2, r2, #(1 << 23)
+LSYM(Lad_r1):
+ movs r0, r0, lsr #1
+ mov r1, r1, rrx
+ add r2, r2, #(1 << 23)
+
+ @ Our result is now properly aligned into r0, remaining bits in r1.
+ @ Round with MSB of r1. If halfway between two numbers, round towards
+ @ LSB of r0 = 0.
+LSYM(Lad_r0):
+ add r0, r0, r1, lsr #31
+ teq r1, #0x80000000
+ biceq r0, r0, #1
+
+ @ Rounding may have added a new MSB. Adjust exponent.
+ @ That MSB will be cleared when exponent is merged below.
+ tst r0, #0x01000000
+ addne r2, r2, #(1 << 23)
+
+ @ Make sure we did not bust our exponent.
+ cmp r2, #(254 << 23)
+ bhi LSYM(Lad_o)
+
+ @ Pack final result together.
+LSYM(Lad_e):
+ bic r0, r0, #0x01800000
+ orr r0, r0, r2
+ orr r0, r0, r3
+ RET
+
+ @ Result must be shifted left.
+ @ No rounding necessary since r1 will always be 0.
+LSYM(Lad_l):
+
+#if __ARM_ARCH__ < 5
+
+ movs ip, r0, lsr #12
+ moveq r0, r0, lsl #12
+ subeq r2, r2, #(12 << 23)
+ tst r0, #0x00ff0000
+ moveq r0, r0, lsl #8
+ subeq r2, r2, #(8 << 23)
+ tst r0, #0x00f00000
+ moveq r0, r0, lsl #4
+ subeq r2, r2, #(4 << 23)
+ tst r0, #0x00c00000
+ moveq r0, r0, lsl #2
+ subeq r2, r2, #(2 << 23)
+ tst r0, #0x00800000
+ moveq r0, r0, lsl #1
+ subeq r2, r2, #(1 << 23)
+ cmp r2, #0
+ bgt LSYM(Lad_e)
+
+#else
+
+ clz ip, r0
+ sub ip, ip, #8
+ mov r0, r0, lsl ip
+ subs r2, r2, ip, lsl #23
+ bgt LSYM(Lad_e)
+
+#endif
+
+ @ Exponent too small, denormalize result.
+ mvn r2, r2, asr #23
+ add r2, r2, #2
+ orr r0, r3, r0, lsr r2
+ RET
+
+ @ Fixup and adjust bit position for denormalized arguments.
+ @ Note that r2 must not remain equal to 0.
+LSYM(Lad_d):
+ teq r2, #0
+ eoreq r0, r0, #0x00800000
+ addeq r2, r2, #(1 << 23)
+ eor r1, r1, #0x00800000
+ subne r3, r3, #(1 << 23)
+ b LSYM(Lad_x)
+
+ @ Result is x - x = 0, unless x is INF or NAN.
+LSYM(Lad_z):
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ teq r2, ip, lsr #1
+ moveq r0, ip, asr #2
+ movne r0, #0
+ RET
+
+ @ Overflow: return INF.
+LSYM(Lad_o):
+ orr r0, r3, #0x7f000000
+ orr r0, r0, #0x00800000
+ RET
+
+ @ At least one of r0/r1 is INF/NAN.
+ @ if r0 != INF/NAN: return r1 (which is INF/NAN)
+ @ if r1 != INF/NAN: return r0 (which is INF/NAN)
+ @ if r0 or r1 is NAN: return NAN
+ @ if opposite sign: return NAN
+ @ return r0 (which is INF or -INF)
+LSYM(Lad_i):
+ teq r2, ip, lsr #1
+ movne r0, r1
+ teqeq r3, ip, lsr #1
+ RETc(ne)
+ movs r2, r0, lsl #9
+ moveqs r2, r1, lsl #9
+ teqeq r0, r1
+ orrne r0, r3, #0x00400000 @ NAN
+ RET
+
+ FUNC_END addsf3
+ FUNC_END subsf3
+
+ARM_FUNC_START floatunsisf
+ mov r3, #0
+ b 1f
+
+ARM_FUNC_START floatsisf
+ ands r3, r0, #0x80000000
+ rsbmi r0, r0, #0
+
+1: teq r0, #0
+ RETc(eq)
+
+ mov r1, #0
+ mov r2, #((127 + 23) << 23)
+ tst r0, #0xfc000000
+ beq LSYM(Lad_p)
+
+ @ We need to scale the value a little before branching to code above.
+ tst r0, #0xf0000000
+ movne r1, r0, lsl #28
+ movne r0, r0, lsr #4
+ addne r2, r2, #(4 << 23)
+ tst r0, #0x0c000000
+ beq LSYM(Lad_p)
+ mov r1, r1, lsr #2
+ orr r1, r1, r0, lsl #30
+ mov r0, r0, lsr #2
+ add r2, r2, #(2 << 23)
+ b LSYM(Lad_p)
+
+ FUNC_END floatsisf
+ FUNC_END floatunsisf
+
+#endif /* L_addsubsf3 */
+
+#ifdef L_muldivsf3
+
+ARM_FUNC_START mulsf3
+
+ @ Mask out exponents.
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ and r3, r1, ip, lsr #1
+
+ @ Trap any INF/NAN.
+ teq r2, ip, lsr #1
+ teqne r3, ip, lsr #1
+ beq LSYM(Lml_s)
+
+ @ Trap any multiplication by 0.
+ bics ip, r0, #0x80000000
+ bicnes ip, r1, #0x80000000
+ beq LSYM(Lml_z)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then add both exponents together.
+ movs r2, r2, lsr #1
+ teqne r3, #0
+ beq LSYM(Lml_d)
+LSYM(Lml_x):
+ add r2, r2, r3, asr #1
+
+ @ Preserve final sign in r2 along with exponent for now.
+ teq r0, r1
+ orrmi r2, r2, #0x8000
+
+ @ Convert mantissa to unsigned integer.
+ bic r0, r0, #0xff000000
+ bic r1, r1, #0xff000000
+ orr r0, r0, #0x00800000
+ orr r1, r1, #0x00800000
+
+#if __ARM_ARCH__ < 4
+
+ @ Well, no way to make it shorter without the umull instruction.
+ @ We must perform that 24 x 24 -> 48 bit multiplication by hand.
+ stmfd sp!, {r4, r5}
+ mov r4, r0, lsr #16
+ mov r5, r1, lsr #16
+ bic r0, r0, #0x00ff0000
+ bic r1, r1, #0x00ff0000
+ mul ip, r4, r5
+ mul r3, r0, r1
+ mul r0, r5, r0
+ mla r0, r4, r1, r0
+ adds r3, r3, r0, lsl #16
+ adc ip, ip, r0, lsr #16
+ ldmfd sp!, {r4, r5}
+
+#else
+
+ umull r3, ip, r0, r1 @ The actual multiplication.
+
+#endif
+
+ @ Put final sign in r0.
+ mov r0, r2, lsl #16
+ bic r2, r2, #0x8000
+
+ @ Adjust result if one extra MSB appeared.
+ @ The LSB may be lost but this never changes the result in this case.
+ tst ip, #(1 << 15)
+ addne r2, r2, #(1 << 22)
+ movnes ip, ip, lsr #1
+ movne r3, r3, rrx
+
+ @ Apply exponent bias, check range for underflow.
+ subs r2, r2, #(127 << 22)
+ ble LSYM(Lml_u)
+
+ @ Scale back to 24 bits with rounding.
+ @ r0 contains sign bit already.
+ orrs r0, r0, r3, lsr #23
+ adc r0, r0, ip, lsl #9
+
+ @ If halfway between two numbers, rounding should be towards LSB = 0.
+ mov r3, r3, lsl #9
+ teq r3, #0x80000000
+ biceq r0, r0, #1
+
+ @ Note: rounding may have produced an extra MSB here.
+ @ The extra bit is cleared before merging the exponent below.
+ tst r0, #0x01000000
+ addne r2, r2, #(1 << 22)
+
+ @ Check for exponent overflow
+ cmp r2, #(255 << 22)
+ bge LSYM(Lml_o)
+
+ @ Add final exponent.
+ bic r0, r0, #0x01800000
+ orr r0, r0, r2, lsl #1
+ RET
+
+ @ Result is 0, but determine sign anyway.
+LSYM(Lml_z):
+ eor r0, r0, r1
+ bic r0, r0, #0x7fffffff
+ RET
+
+ @ Check if denormalized result is possible, otherwise return signed 0.
+LSYM(Lml_u):
+ cmn r2, #(24 << 22)
+ RETc(le)
+
+ @ Find out proper shift value.
+ mvn r1, r2, asr #22
+ subs r1, r1, #7
+ bgt LSYM(Lml_ur)
+
+ @ Shift value left, round, etc.
+ add r1, r1, #32
+ orrs r0, r0, r3, lsr r1
+ rsb r1, r1, #32
+ adc r0, r0, ip, lsl r1
+ mov ip, r3, lsl r1
+ teq ip, #0x80000000
+ biceq r0, r0, #1
+ RET
+
+ @ Shift value right, round, etc.
+ @ Note: r1 must not be 0 otherwise carry does not get set.
+LSYM(Lml_ur):
+ orrs r0, r0, ip, lsr r1
+ adc r0, r0, #0
+ rsb r1, r1, #32
+ mov ip, ip, lsl r1
+ teq r3, #0
+ teqeq ip, #0x80000000
+ biceq r0, r0, #1
+ RET
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Lml_d):
+ teq r2, #0
+ and ip, r0, #0x80000000
+1: moveq r0, r0, lsl #1
+ tsteq r0, #0x00800000
+ subeq r2, r2, #(1 << 22)
+ beq 1b
+ orr r0, r0, ip
+ teq r3, #0
+ and ip, r1, #0x80000000
+2: moveq r1, r1, lsl #1
+ tsteq r1, #0x00800000
+ subeq r3, r3, #(1 << 23)
+ beq 2b
+ orr r1, r1, ip
+ b LSYM(Lml_x)
+
+ @ One or both args are INF or NAN.
+LSYM(Lml_s):
+ teq r0, #0x0
+ teqne r1, #0x0
+ teqne r0, #0x80000000
+ teqne r1, #0x80000000
+ beq LSYM(Lml_n) @ 0 * INF or INF * 0 -> NAN
+ teq r2, ip, lsr #1
+ bne 1f
+ movs r2, r0, lsl #9
+ bne LSYM(Lml_n) @ NAN * <anything> -> NAN
+1: teq r3, ip, lsr #1
+ bne LSYM(Lml_i)
+ movs r3, r1, lsl #9
+ bne LSYM(Lml_n) @ <anything> * NAN -> NAN
+
+ @ Result is INF, but we need to determine its sign.
+LSYM(Lml_i):
+ eor r0, r0, r1
+
+ @ Overflow: return INF (sign already in r0).
+LSYM(Lml_o):
+ and r0, r0, #0x80000000
+ orr r0, r0, #0x7f000000
+ orr r0, r0, #0x00800000
+ RET
+
+ @ Return NAN.
+LSYM(Lml_n):
+ mov r0, #0x7f000000
+ orr r0, r0, #0x00c00000
+ RET
+
+ FUNC_END mulsf3
+
+ARM_FUNC_START divsf3
+
+ @ Mask out exponents.
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ and r3, r1, ip, lsr #1
+
+ @ Trap any INF/NAN or zeroes.
+ teq r2, ip, lsr #1
+ teqne r3, ip, lsr #1
+ bicnes ip, r0, #0x80000000
+ bicnes ip, r1, #0x80000000
+ beq LSYM(Ldv_s)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then substract divisor exponent from dividend''s.
+ movs r2, r2, lsr #1
+ teqne r3, #0
+ beq LSYM(Ldv_d)
+LSYM(Ldv_x):
+ sub r2, r2, r3, asr #1
+
+ @ Preserve final sign into ip.
+ eor ip, r0, r1
+
+ @ Convert mantissa to unsigned integer.
+ @ Dividend -> r3, divisor -> r1.
+ mov r3, #0x10000000
+ movs r1, r1, lsl #9
+ mov r0, r0, lsl #9
+ beq LSYM(Ldv_1)
+ orr r1, r3, r1, lsr #4
+ orr r3, r3, r0, lsr #4
+
+ @ Initialize r0 (result) with final sign bit.
+ and r0, ip, #0x80000000
+
+ @ Ensure result will land to known bit position.
+ cmp r3, r1
+ subcc r2, r2, #(1 << 22)
+ movcc r3, r3, lsl #1
+
+ @ Apply exponent bias, check range for over/underflow.
+ add r2, r2, #(127 << 22)
+ cmn r2, #(24 << 22)
+ RETc(le)
+ cmp r2, #(255 << 22)
+ bge LSYM(Lml_o)
+
+ @ The actual division loop.
+ mov ip, #0x00800000
+1: cmp r3, r1
+ subcs r3, r3, r1
+ orrcs r0, r0, ip
+ cmp r3, r1, lsr #1
+ subcs r3, r3, r1, lsr #1
+ orrcs r0, r0, ip, lsr #1
+ cmp r3, r1, lsr #2
+ subcs r3, r3, r1, lsr #2
+ orrcs r0, r0, ip, lsr #2
+ cmp r3, r1, lsr #3
+ subcs r3, r3, r1, lsr #3
+ orrcs r0, r0, ip, lsr #3
+ movs r3, r3, lsl #4
+ movnes ip, ip, lsr #4
+ bne 1b
+
+ @ Check if denormalized result is needed.
+ cmp r2, #0
+ ble LSYM(Ldv_u)
+
+ @ Apply proper rounding.
+ cmp r3, r1
+ addcs r0, r0, #1
+ biceq r0, r0, #1
+
+ @ Add exponent to result.
+ bic r0, r0, #0x00800000
+ orr r0, r0, r2, lsl #1
+ RET
+
+ @ Division by 0x1p*: let''s shortcut a lot of code.
+LSYM(Ldv_1):
+ and ip, ip, #0x80000000
+ orr r0, ip, r0, lsr #9
+ add r2, r2, #(127 << 22)
+ cmp r2, #(255 << 22)
+ bge LSYM(Lml_o)
+ cmp r2, #0
+ orrgt r0, r0, r2, lsl #1
+ RETc(gt)
+ cmn r2, #(24 << 22)
+ movle r0, ip
+ RETc(le)
+ orr r0, r0, #0x00800000
+ mov r3, #0
+
+ @ Result must be denormalized: prepare parameters to use code above.
+ @ r3 already contains remainder for rounding considerations.
+LSYM(Ldv_u):
+ bic ip, r0, #0x80000000
+ and r0, r0, #0x80000000
+ mvn r1, r2, asr #22
+ add r1, r1, #2
+ b LSYM(Lml_ur)
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Ldv_d):
+ teq r2, #0
+ and ip, r0, #0x80000000
+1: moveq r0, r0, lsl #1
+ tsteq r0, #0x00800000
+ subeq r2, r2, #(1 << 22)
+ beq 1b
+ orr r0, r0, ip
+ teq r3, #0
+ and ip, r1, #0x80000000
+2: moveq r1, r1, lsl #1
+ tsteq r1, #0x00800000
+ subeq r3, r3, #(1 << 23)
+ beq 2b
+ orr r1, r1, ip
+ b LSYM(Ldv_x)
+
+ @ One or both arguments is either INF, NAN or zero.
+LSYM(Ldv_s):
+ mov ip, #0xff000000
+ teq r2, ip, lsr #1
+ teqeq r3, ip, lsr #1
+ beq LSYM(Lml_n) @ INF/NAN / INF/NAN -> NAN
+ teq r2, ip, lsr #1
+ bne 1f
+ movs r2, r0, lsl #9
+ bne LSYM(Lml_n) @ NAN / <anything> -> NAN
+ b LSYM(Lml_i) @ INF / <anything> -> INF
+1: teq r3, ip, lsr #1
+ bne 2f
+ movs r3, r1, lsl #9
+ bne LSYM(Lml_n) @ <anything> / NAN -> NAN
+ b LSYM(Lml_z) @ <anything> / INF -> 0
+2: @ One or both arguments are 0.
+ bics r2, r0, #0x80000000
+ bne LSYM(Lml_i) @ <non_zero> / 0 -> INF
+ bics r3, r1, #0x80000000
+ bne LSYM(Lml_z) @ 0 / <non_zero> -> 0
+ b LSYM(Lml_n) @ 0 / 0 -> NAN
+
+ FUNC_END divsf3
+
+#endif /* L_muldivsf3 */
+
+#ifdef L_cmpsf2
+
+ARM_FUNC_START gtsf2
+ARM_FUNC_ALIAS gesf2 gtsf2
+ mov r3, #-1
+ b 1f
+
+ARM_FUNC_START ltsf2
+ARM_FUNC_ALIAS lesf2 ltsf2
+ mov r3, #1
+ b 1f
+
+ARM_FUNC_START cmpsf2
+ARM_FUNC_ALIAS nesf2 cmpsf2
+ARM_FUNC_ALIAS eqsf2 cmpsf2
+ mov r3, #1 @ how should we specify unordered here?
+
+1: @ Trap any INF/NAN first.
+ mov ip, #0xff000000
+ and r2, r1, ip, lsr #1
+ teq r2, ip, lsr #1
+ and r2, r0, ip, lsr #1
+ teqne r2, ip, lsr #1
+ beq 3f
+
+ @ Test for equality.
+ @ Note that 0.0 is equal to -0.0.
+2: orr r3, r0, r1
+ bics r3, r3, #0x80000000 @ either 0.0 or -0.0
+ teqne r0, r1 @ or both the same
+ moveq r0, #0
+ RETc(eq)
+
+ @ Check for sign difference. The N flag is set if it is the case.
+ @ If so, return sign of r0.
+ movmi r0, r0, asr #31
+ orrmi r0, r0, #1
+ RETc(mi)
+
+ @ Compare exponents.
+ and r3, r1, ip, lsr #1
+ cmp r2, r3
+
+ @ Compare mantissa if exponents are equal
+ moveq r0, r0, lsl #9
+ cmpeq r0, r1, lsl #9
+ movcs r0, r1, asr #31
+ mvncc r0, r1, asr #31
+ orr r0, r0, #1
+ RET
+
+ @ Look for a NAN.
+3: and r2, r1, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 4f
+ movs r2, r1, lsl #9
+ bne 5f @ r1 is NAN
+4: and r2, r0, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 2b
+ movs ip, r0, lsl #9
+ beq 2b @ r0 is not NAN
+5: mov r0, r3 @ return unordered code from r3.
+ RET
+
+ FUNC_END gesf2
+ FUNC_END gtsf2
+ FUNC_END lesf2
+ FUNC_END ltsf2
+ FUNC_END nesf2
+ FUNC_END eqsf2
+ FUNC_END cmpsf2
+
+#endif /* L_cmpsf2 */
+
+#ifdef L_unordsf2
+
+ARM_FUNC_START unordsf2
+ mov ip, #0xff000000
+ and r2, r1, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 1f
+ movs r2, r1, lsl #9
+ bne 3f @ r1 is NAN
+1: and r2, r0, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 2f
+ movs r2, r0, lsl #9
+ bne 3f @ r0 is NAN
+2: mov r0, #0 @ arguments are ordered.
+ RET
+3: mov r0, #1 @ arguments are unordered.
+ RET
+
+ FUNC_END unordsf2
+
+#endif /* L_unordsf2 */
+
+#ifdef L_fixsfsi
+
+ARM_FUNC_START fixsfsi
+ movs r0, r0, lsl #1
+ RETc(eq) @ value is 0.
+
+ mov r1, r1, rrx @ preserve C flag (the actual sign)
+
+ @ check exponent range.
+ and r2, r0, #0xff000000
+ cmp r2, #(127 << 24)
+ movcc r0, #0 @ value is too small
+ RETc(cc)
+ cmp r2, #((127 + 31) << 24)
+ bcs 1f @ value is too large
+
+ mov r0, r0, lsl #7
+ orr r0, r0, #0x80000000
+ mov r2, r2, lsr #24
+ rsb r2, r2, #(127 + 31)
+ tst r1, #0x80000000 @ the sign bit
+ mov r0, r0, lsr r2
+ rsbne r0, r0, #0
+ RET
+
+1: teq r2, #0xff000000
+ bne 2f
+ movs r0, r0, lsl #8
+ bne 3f @ r0 is NAN.
+2: ands r0, r1, #0x80000000 @ the sign bit
+ moveq r0, #0x7fffffff @ the maximum signed positive si
+ RET
+
+3: mov r0, #0 @ What should we convert NAN to?
+ RET
+
+ FUNC_END fixsfsi
+
+#endif /* L_fixsfsi */
+
+#ifdef L_fixunssfsi
+
+ARM_FUNC_START fixunssfsi
+ movs r0, r0, lsl #1
+ movcss r0, #0 @ value is negative...
+ RETc(eq) @ ... or 0.
+
+
+ @ check exponent range.
+ and r2, r0, #0xff000000
+ cmp r2, #(127 << 24)
+ movcc r0, #0 @ value is too small
+ RETc(cc)
+ cmp r2, #((127 + 32) << 24)
+ bcs 1f @ value is too large
+
+ mov r0, r0, lsl #7
+ orr r0, r0, #0x80000000
+ mov r2, r2, lsr #24
+ rsb r2, r2, #(127 + 31)
+ mov r0, r0, lsr r2
+ RET
+
+1: teq r2, #0xff000000
+ bne 2f
+ movs r0, r0, lsl #8
+ bne 3f @ r0 is NAN.
+2: mov r0, #0xffffffff @ maximum unsigned si
+ RET
+
+3: mov r0, #0 @ What should we convert NAN to?
+ RET
+
+ FUNC_END fixunssfsi
+
+#endif /* L_fixunssfsi */
diff --git a/contrib/gcc/config/arm/iwmmxt.md b/contrib/gcc/config/arm/iwmmxt.md
new file mode 100644
index 0000000..f8070a8
--- /dev/null
+++ b/contrib/gcc/config/arm/iwmmxt.md
@@ -0,0 +1,1524 @@
+;; Patterns for the Intel Wireless MMX technology architecture.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Red Hat.
+
+;; 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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+(define_insn "iwmmxt_iordi3"
+ [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
+ (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
+ (match_operand:DI 2 "register_operand" "y,r,r")))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ wor%?\\t%0, %1, %2
+ #
+ #"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4,8,8")])
+
+(define_insn "iwmmxt_xordi3"
+ [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
+ (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
+ (match_operand:DI 2 "register_operand" "y,r,r")))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ wxor%?\\t%0, %1, %2
+ #
+ #"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4,8,8")])
+
+(define_insn "iwmmxt_anddi3"
+ [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
+ (and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
+ (match_operand:DI 2 "register_operand" "y,r,r")))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ wand%?\\t%0, %1, %2
+ #
+ #"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4,8,8")])
+
+(define_insn "iwmmxt_nanddi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (and:DI (match_operand:DI 1 "register_operand" "y")
+ (not:DI (match_operand:DI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wandn%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "*iwmmxt_arm_movdi"
+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>,y,y,yr,y,yrm")
+ (match_operand:DI 1 "di_operand" "rIK,mi,r ,y,yr,y,yrm,y"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+{
+ switch (which_alternative)
+ {
+ default:
+ return output_move_double (operands);
+ case 3:
+ return \"wmov%?\\t%0,%1\";
+ case 4:
+ return \"tmcrr%?\\t%0,%Q1,%R1\";
+ case 5:
+ return \"tmrrc%?\\t%Q0,%R0,%1\";
+ case 6:
+ return \"wldrd%?\\t%0,%1\";
+ case 7:
+ return \"wstrd%?\\t%1,%0\";
+ }
+}"
+ [(set_attr "length" "8,8,8,4,4,4,4,4")
+ (set_attr "type" "*,load,store2,*,*,*,*,*")
+ (set_attr "pool_range" "*,1020,*,*,*,*,*,*")
+ (set_attr "neg_pool_range" "*,1012,*,*,*,*,*,*")]
+)
+
+(define_insn "*iwmmxt_movsi_insn"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r,?z,m,z")
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,z,m,z,z"))]
+ "TARGET_REALLY_IWMMXT
+ && ( register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode))"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"mov\\t%0, %1\";
+ case 1: return \"mvn\\t%0, #%B1\";
+ case 2: return \"ldr\\t%0, %1\";
+ case 3: return \"str\\t%1, %0\";
+ case 4: return \"tmcr\\t%0, %1\";
+ case 5: return \"tmrc\\t%0, %1\";
+ case 6: return arm_output_load_gr (operands);
+ case 7: return \"wstrw\\t%1, %0\";
+ default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\";
+ }"
+ [(set_attr "type" "*,*,load,store1,*,*,load,store1,*")
+ (set_attr "length" "*,*,*, *,*,*, 16, *,8")
+ (set_attr "pool_range" "*,*,4096, *,*,*,1024, *,*")
+ (set_attr "neg_pool_range" "*,*,4084, *,*,*, *, 1012,*")
+ ;; Note - the "predicable" attribute is not allowed to have alternatives.
+ ;; Since the wSTRw wCx instruction is not predicable, we cannot support
+ ;; predicating any of the alternatives in this template. Instead,
+ ;; we do the predication ourselves, in cond_iwmmxt_movsi_insn.
+ (set_attr "predicable" "no")
+ ;; Also - we have to pretend that these insns clobber the condition code
+ ;; bits as otherwise arm_final_prescan_insn() will try to conditionalize
+ ;; them.
+ (set_attr "conds" "clob")]
+)
+
+;; Because iwmmxt_movsi_insn is not predicable, we provide the
+;; cond_exec version explicitly, with appropriate constraints.
+
+(define_insn "*cond_iwmmxt_movsi_insn"
+ [(cond_exec
+ (match_operator 2 "arm_comparison_operator"
+ [(match_operand 3 "cc_register" "")
+ (const_int 0)])
+ (set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r")
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,z")))]
+ "TARGET_REALLY_IWMMXT
+ && ( register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode))"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"mov%?\\t%0, %1\";
+ case 1: return \"mvn%?\\t%0, #%B1\";
+ case 2: return \"ldr%?\\t%0, %1\";
+ case 3: return \"str%?\\t%1, %0\";
+ case 4: return \"tmcr%?\\t%0, %1\";
+ default: return \"tmrc%?\\t%0, %1\";
+ }"
+ [(set_attr "type" "*,*,load,store1,*,*")
+ (set_attr "pool_range" "*,*,4096, *,*,*")
+ (set_attr "neg_pool_range" "*,*,4084, *,*,*")]
+)
+
+(define_insn "movv8qi_internal"
+ [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r")
+ (match_operand:V8QI 1 "general_operand" "y,y,m,y,r,i"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"wmov%?\\t%0, %1\";
+ case 1: return \"wstrd%?\\t%1, %0\";
+ case 2: return \"wldrd%?\\t%0, %1\";
+ case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+ case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+ default: return output_move_double (operands);
+ }"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4, 4, 4,4,4, 8")
+ (set_attr "type" "*,store1,load,*,*,load")
+ (set_attr "pool_range" "*, *, 256,*,*, 256")
+ (set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
+
+(define_insn "movv4hi_internal"
+ [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r")
+ (match_operand:V4HI 1 "general_operand" "y,y,m,y,r,i"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"wmov%?\\t%0, %1\";
+ case 1: return \"wstrd%?\\t%1, %0\";
+ case 2: return \"wldrd%?\\t%0, %1\";
+ case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+ case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+ default: return output_move_double (operands);
+ }"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4, 4, 4,4,4, 8")
+ (set_attr "type" "*,store1,load,*,*,load")
+ (set_attr "pool_range" "*, *, 256,*,*, 256")
+ (set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
+
+(define_insn "movv2si_internal"
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r")
+ (match_operand:V2SI 1 "general_operand" "y,y,m,y,r,i"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"wmov%?\\t%0, %1\";
+ case 1: return \"wstrd%?\\t%1, %0\";
+ case 2: return \"wldrd%?\\t%0, %1\";
+ case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+ case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+ default: return output_move_double (operands);
+ }"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4, 4, 4,4,4, 24")
+ (set_attr "type" "*,store1,load,*,*,load")
+ (set_attr "pool_range" "*, *, 256,*,*, 256")
+ (set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
+
+;; This pattern should not be needed. It is to match a
+;; wierd case generated by GCC when no optimizations are
+;; enabled. (Try compiling gcc/testsuite/gcc.c-torture/
+;; compile/simd-5.c at -O0). The mode for operands[1] is
+;; deliberately omitted.
+(define_insn "movv2si_internal_2"
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=?r")
+ (match_operand 1 "immediate_operand" "i"))]
+ "TARGET_REALLY_IWMMXT"
+ "* return output_move_double (operands);"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "8")
+ (set_attr "type" "load")
+ (set_attr "pool_range" "256")
+ (set_attr "neg_pool_range" "244")])
+
+;; Vector add/subtract
+
+(define_insn "addv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (plus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "addv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (plus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "addv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (plus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ssaddv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddbss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ssaddv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddhss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ssaddv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ss_plus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddwss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "usaddv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddbus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "usaddv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddhus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "usaddv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (us_plus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddwus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "subv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "subv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (minus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "subv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (minus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sssubv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubbss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sssubv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubhss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sssubv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ss_minus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubwss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ussubv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubbus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ussubv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubhus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ussubv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (us_minus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubwus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "mulv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (mult:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmulul%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "smulv4hi3_highpart"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (truncate:V4HI
+ (lshiftrt:V4SI
+ (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+ (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+ (const_int 16))))]
+ "TARGET_REALLY_IWMMXT"
+ "wmulsm%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umulv4hi3_highpart"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (truncate:V4HI
+ (lshiftrt:V4SI
+ (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+ (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+ (const_int 16))))]
+ "TARGET_REALLY_IWMMXT"
+ "wmulum%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacs"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "0")
+ (match_operand:V4HI 2 "register_operand" "y")
+ (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACS))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacs%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacsz"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACSZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacsz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacu"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "0")
+ (match_operand:V4HI 2 "register_operand" "y")
+ (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACU))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacu%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacuz"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACUZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacuz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Same as xordi3, but don't show input operands so that we don't think
+;; they are live.
+(define_insn "iwmmxt_clrdi"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(const_int 0)] UNSPEC_CLRDI))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+;; Seems like cse likes to generate these, so we have to support them.
+
+(define_insn "*iwmmxt_clrv8qi"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (const_vector:V8QI [(const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)]))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "*iwmmxt_clrv4hi"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (const_vector:V4HI [(const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)]))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "*iwmmxt_clrv2si"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (const_vector:V2SI [(const_int 0) (const_int 0)]))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+;; Unsigned averages/sum of absolute differences
+
+(define_insn "iwmmxt_uavgrndv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ashiftrt:V8QI
+ (plus:V8QI (plus:V8QI
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y"))
+ (const_vector:V8QI [(const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2br%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_uavgrndv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI
+ (plus:V4HI (plus:V4HI
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y"))
+ (const_vector:V4HI [(const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2hr%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+
+(define_insn "iwmmxt_uavgv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ashiftrt:V8QI (plus:V8QI
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y"))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2b%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_uavgv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI (plus:V4HI
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y"))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2h%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_psadbw"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "psadbw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+
+;; Insert/extract/shuffle
+
+(define_insn "iwmmxt_tinsrb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_merge:V8QI (match_operand:V8QI 1 "register_operand" "0")
+ (vec_duplicate:V8QI
+ (truncate:QI (match_operand:SI 2 "nonimmediate_operand" "r")))
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "TARGET_REALLY_IWMMXT"
+ "tinsrb%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tinsrh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
+ (vec_duplicate:V4HI
+ (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "r")))
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "TARGET_REALLY_IWMMXT"
+ "tinsrh%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tinsrw"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_merge:V2SI (match_operand:V2SI 1 "register_operand" "0")
+ (vec_duplicate:V2SI
+ (match_operand:SI 2 "nonimmediate_operand" "r"))
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "TARGET_REALLY_IWMMXT"
+ "tinsrw%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmub"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmsb"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmuh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmsh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; There are signed/unsigned variants of this instruction, but they are
+;; pointless.
+(define_insn "iwmmxt_textrmw"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wshufh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_WSHUFH))]
+ "TARGET_REALLY_IWMMXT"
+ "wshufh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Mask-generating comparisons
+;;
+;; Note - you cannot use patterns like these here:
+;;
+;; (set:<vector> (match:<vector>) (<comparator>:<vector> (match:<vector>) (match:<vector>)))
+;;
+;; Because GCC will assume that the truth value (1 or 0) is installed
+;; into the entire destination vector, (with the '1' going into the least
+;; significant element of the vector). This is not how these instructions
+;; behave.
+;;
+;; Unfortunately the current patterns are illegal. They are SET insns
+;; without a SET in them. They work in most cases for ordinary code
+;; generation, but there are circumstances where they can cause gcc to fail.
+;; XXX - FIXME.
+
+(define_insn "eqv8qi3"
+ [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_EQ)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpeqb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "eqv4hi3"
+ [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_EQ)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpeqh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "eqv2si3"
+ [(unspec_volatile:V2SI [(match_operand:V2SI 0 "register_operand" "=y")
+ (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_EQ)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpeqw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtuv8qi3"
+ [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GTU)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtuv4hi3"
+ [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GTU)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtuv2si3"
+ [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y")
+ (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GTU)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtuw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtv8qi3"
+ [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GT)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtv4hi3"
+ [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GT)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtv2si3"
+ [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y")
+ (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GT)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Max/min insns
+
+(define_insn "smaxv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (smax:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umaxv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (umax:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "smaxv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (smax:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umaxv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (umax:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "smaxv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (smax:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umaxv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (umax:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxuw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sminv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (smin:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "uminv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (umin:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sminv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (smin:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "uminv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (umin:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sminv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (smin:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "uminv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (umin:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminuw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Pack/unpack insns.
+
+(define_insn "iwmmxt_wpackhss"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_concat:V8QI
+ (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
+ (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackhss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackwss"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_concat:V4HI
+ (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
+ (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackwss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackdss"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_concat:V2SI
+ (ss_truncate:SI (match_operand:DI 1 "register_operand" "y"))
+ (ss_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackdss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackhus"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_concat:V8QI
+ (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
+ (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackhus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackwus"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_concat:V4HI
+ (us_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
+ (us_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackwus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackdus"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_concat:V2SI
+ (us_truncate:SI (match_operand:DI 1 "register_operand" "y"))
+ (us_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackdus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+
+(define_insn "iwmmxt_wunpckihb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_merge:V8QI
+ (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 4)
+ (const_int 0)
+ (const_int 5)
+ (const_int 1)
+ (const_int 6)
+ (const_int 2)
+ (const_int 7)
+ (const_int 3)]))
+ (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 4)
+ (const_int 1)
+ (const_int 5)
+ (const_int 2)
+ (const_int 6)
+ (const_int 3)
+ (const_int 7)]))
+ (const_int 85)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckihb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckihh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_merge:V4HI
+ (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 2)
+ (const_int 1)
+ (const_int 3)]))
+ (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+ (parallel [(const_int 2)
+ (const_int 0)
+ (const_int 3)
+ (const_int 1)]))
+ (const_int 5)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckihh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckihw"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_merge:V2SI
+ (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 1)]))
+ (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
+ (parallel [(const_int 1)
+ (const_int 0)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckihw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckilb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_merge:V8QI
+ (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 4)
+ (const_int 1)
+ (const_int 5)
+ (const_int 2)
+ (const_int 6)
+ (const_int 3)
+ (const_int 7)]))
+ (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
+ (parallel [(const_int 4)
+ (const_int 0)
+ (const_int 5)
+ (const_int 1)
+ (const_int 6)
+ (const_int 2)
+ (const_int 7)
+ (const_int 3)]))
+ (const_int 85)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckilb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckilh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_merge:V4HI
+ (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 2)
+ (const_int 0)
+ (const_int 3)
+ (const_int 1)]))
+ (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 2)
+ (const_int 1)
+ (const_int 3)]))
+ (const_int 5)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckilh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckilw"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_merge:V2SI
+ (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 1)
+ (const_int 0)]))
+ (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 1)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckilw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehub"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (zero_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 4) (const_int 5)
+ (const_int 6) (const_int 7)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehub%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehuh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (zero_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehuh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehuw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (zero_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehuw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehsb"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (sign_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 4) (const_int 5)
+ (const_int 6) (const_int 7)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehsb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehsh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (sign_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehsh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehsw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (sign_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehsw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelub"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (zero_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelub%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckeluh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (zero_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckeluh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckeluw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (zero_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 0)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckeluw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelsb"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (sign_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelsb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelsh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (sign_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelsh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelsw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (sign_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 0)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelsw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+;; Shifts
+
+(define_insn "rorv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorhg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rorv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorwg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rordi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (rotatert:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrordg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrahg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrawg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrdi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsradg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlhg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlwg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrdi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrldg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashift:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllhg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashift:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllwg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashldi3_iwmmxt"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashift:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wslldg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rorv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rorv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rordi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (rotatert:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrord%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrah%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsraw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrdi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrad%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrdi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrld%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashift:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashift:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashldi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashift:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wslld%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmadds"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDS))]
+ "TARGET_REALLY_IWMMXT"
+ "wmadds%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmaddu"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDU))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaddu%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmia"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (match_operand:SI 2 "register_operand" "r"))
+ (sign_extend:DI
+ (match_operand:SI 3 "register_operand" "r")))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmia%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiaph"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (plus:DI
+ (mult:DI (sign_extend:DI
+ (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+ (sign_extend:DI
+ (truncate:HI (match_operand:SI 3 "register_operand" "r"))))
+ (mult:DI (sign_extend:DI
+ (truncate:HI (ashiftrt:SI (match_dup 2) (const_int 16))))
+ (sign_extend:DI
+ (truncate:HI (ashiftrt:SI (match_dup 3) (const_int 16))))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiaph%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiabb"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+ (sign_extend:DI
+ (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiabb%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiatb"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))
+ (sign_extend:DI
+ (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiatb%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiabt"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+ (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 3 "register_operand" "r")
+ (const_int 16)))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiabt%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiatt"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))
+ (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 3 "register_operand" "r")
+ (const_int 16)))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiatt%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tbcstqi"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_duplicate:V8QI (match_operand:QI 1 "register_operand" "r")))]
+ "TARGET_REALLY_IWMMXT"
+ "tbcstb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tbcsthi"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_duplicate:V4HI (match_operand:HI 1 "register_operand" "r")))]
+ "TARGET_REALLY_IWMMXT"
+ "tbcsth%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tbcstsi"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_duplicate:V2SI (match_operand:SI 1 "register_operand" "r")))]
+ "TARGET_REALLY_IWMMXT"
+ "tbcstw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmovmskb"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
+ "TARGET_REALLY_IWMMXT"
+ "tmovmskb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmovmskh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
+ "TARGET_REALLY_IWMMXT"
+ "tmovmskh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmovmskw"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
+ "TARGET_REALLY_IWMMXT"
+ "tmovmskw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_waccb"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_WACC))]
+ "TARGET_REALLY_IWMMXT"
+ "waccb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wacch"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_WACC))]
+ "TARGET_REALLY_IWMMXT"
+ "wacch%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_waccw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_WACC))]
+ "TARGET_REALLY_IWMMXT"
+ "waccw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_walign"
+ [(set (match_operand:V8QI 0 "register_operand" "=y,y")
+ (subreg:V8QI (ashiftrt:TI
+ (subreg:TI (vec_concat:V16QI
+ (match_operand:V8QI 1 "register_operand" "y,y")
+ (match_operand:V8QI 2 "register_operand" "y,y")) 0)
+ (mult:SI
+ (match_operand:SI 3 "nonmemory_operand" "i,z")
+ (const_int 8))) 0))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ waligni%?\\t%0, %1, %2, %3
+ walignr%U3%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmrc"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")]
+ VUNSPEC_TMRC))]
+ "TARGET_REALLY_IWMMXT"
+ "tmrc%?\\t%0, %w1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmcr"
+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
+ (match_operand:SI 1 "register_operand" "r")]
+ VUNSPEC_TMCR)]
+ "TARGET_REALLY_IWMMXT"
+ "tmcr%?\\t%w0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSAD))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSAD))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadbz"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSADZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadbz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadhz"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSADZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadhz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
diff --git a/contrib/gcc/config/arm/kaos-arm.h b/contrib/gcc/config/arm/kaos-arm.h
new file mode 100644
index 0000000..0d3bf2d
--- /dev/null
+++ b/contrib/gcc/config/arm/kaos-arm.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler.
+ kaOS on arm architecture version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (ARM/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/arm/kaos-strongarm.h b/contrib/gcc/config/arm/kaos-strongarm.h
new file mode 100644
index 0000000..8eb9473
--- /dev/null
+++ b/contrib/gcc/config/arm/kaos-strongarm.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler.
+ kaOS on strongarm architecture version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (StrongARM/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/arm/lib1funcs.asm b/contrib/gcc/config/arm/lib1funcs.asm
index ec706ec..e72af6c 100644
--- a/contrib/gcc/config/arm/lib1funcs.asm
+++ b/contrib/gcc/config/arm/lib1funcs.asm
@@ -1,7 +1,8 @@
@ libgcc routines for ARM cpu.
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
-/* Copyright 1995, 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004
+ Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -51,74 +52,117 @@ Boston, MA 02111-1307, USA. */
#endif
#define TYPE(x) .type SYM(x),function
#define SIZE(x) .size SYM(x), . - SYM(x)
+#define LSYM(x) .x
#else
#define __PLT__
#define TYPE(x)
#define SIZE(x)
+#define LSYM(x) x
#endif
/* Function end macros. Variants for 26 bit APCS and interworking. */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
+ || defined(__ARM_ARCH_4T__)
+/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
+ long multiply instructions. That includes v3M. */
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5TE__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+/* How to return from a function call depends on the architecture variant. */
+
#ifdef __APCS_26__
+
# define RET movs pc, lr
# define RETc(x) mov##x##s pc, lr
-# define RETCOND ^
+
+#elif (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
+
+# define RET bx lr
+# define RETc(x) bx##x lr
+
+# if (__ARM_ARCH__ == 4) \
+ && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
+# define __INTERWORKING__
+# endif
+
+#else
+
+# define RET mov pc, lr
+# define RETc(x) mov##x pc, lr
+
+#endif
+
+/* Don't pass dirn, it's there just to get token pasting right. */
+
+.macro RETLDM regs=, cond=, dirn=ia
+#ifdef __APCS_26__
+ .ifc "\regs",""
+ ldm\cond\dirn sp!, {pc}^
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}^
+ .endif
+#elif defined (__INTERWORKING__)
+ .ifc "\regs",""
+ ldr\cond lr, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, lr}
+ .endif
+ bx\cond lr
+#else
+ .ifc "\regs",""
+ ldr\cond pc, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}
+ .endif
+#endif
+.endm
+
+
.macro ARM_LDIV0
-Ldiv0:
+LSYM(Ldiv0):
str lr, [sp, #-4]!
bl SYM (__div0) __PLT__
mov r0, #0 @ About as wrong as it could be.
- ldmia sp!, {pc}^
+ RETLDM
.endm
-#else
-# ifdef __THUMB_INTERWORK__
-# define RET bx lr
-# define RETc(x) bx##x lr
+
+
.macro THUMB_LDIV0
-Ldiv0:
+LSYM(Ldiv0):
push { lr }
bl SYM (__div0)
mov r0, #0 @ About as wrong as it could be.
+#if defined (__INTERWORKING__)
pop { r1 }
bx r1
-.endm
-.macro ARM_LDIV0
-Ldiv0:
- str lr, [sp, #-4]!
- bl SYM (__div0) __PLT__
- mov r0, #0 @ About as wrong as it could be.
- ldr lr, [sp], #4
- bx lr
-.endm
-# else
-# define RET mov pc, lr
-# define RETc(x) mov##x pc, lr
-.macro THUMB_LDIV0
-Ldiv0:
- push { lr }
- bl SYM (__div0)
- mov r0, #0 @ About as wrong as it could be.
+#else
pop { pc }
-.endm
-.macro ARM_LDIV0
-Ldiv0:
- str lr, [sp, #-4]!
- bl SYM (__div0) __PLT__
- mov r0, #0 @ About as wrong as it could be.
- ldmia sp!, {pc}
-.endm
-# endif
-# define RETCOND
#endif
+.endm
.macro FUNC_END name
-Ldiv0:
+ SIZE (__\name)
+.endm
+
+.macro DIV_FUNC_END name
+LSYM(Ldiv0):
#ifdef __thumb__
THUMB_LDIV0
#else
ARM_LDIV0
#endif
- SIZE (__\name)
+ FUNC_END \name
.endm
.macro THUMB_FUNC_START name
@@ -147,7 +191,37 @@ SYM (\name):
THUMB_FUNC
SYM (__\name):
.endm
-
+
+/* Special function that will always be coded in ARM assembly, even if
+ in Thumb-only compilation. */
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+.macro ARM_FUNC_START name
+ FUNC_START \name
+ bx pc
+ nop
+ .arm
+_L__\name: /* A hook to tell gdb that we've switched to ARM */
+.endm
+#define EQUIV .thumb_set
+#else
+.macro ARM_FUNC_START name
+ .text
+ .globl SYM (__\name)
+ TYPE (__\name)
+ .align 0
+ .arm
+SYM (__\name):
+.endm
+#define EQUIV .set
+#endif
+
+.macro ARM_FUNC_ALIAS new old
+ .globl SYM (__\new)
+ EQUIV SYM (__\new), SYM (__\old)
+.endm
+
+#ifdef __thumb__
/* Register aliases. */
work .req r4 @ XXXX is this safe ?
@@ -156,133 +230,212 @@ divisor .req r1
overdone .req r2
result .req r2
curbit .req r3
+#endif
+#if 0
ip .req r12
sp .req r13
lr .req r14
pc .req r15
+#endif
/* ------------------------------------------------------------------------ */
-/* Bodies of the divsion and modulo routines. */
+/* Bodies of the division and modulo routines. */
/* ------------------------------------------------------------------------ */
-.macro ARM_DIV_MOD_BODY modulo
-Loop1:
+.macro ARM_DIV_BODY dividend, divisor, result, curbit
+
+#if __ARM_ARCH__ >= 5
+
+ clz \curbit, \divisor
+ clz \result, \dividend
+ sub \result, \curbit, \result
+ mov \curbit, #1
+ mov \divisor, \divisor, lsl \result
+ mov \curbit, \curbit, lsl \result
+ mov \result, #0
+
+#else
+
+ @ Initially shift the divisor left 3 bits if possible,
+ @ set curbit accordingly. This allows for curbit to be located
+ @ at the left end of each 4 bit nibbles in the division loop
+ @ to save one loop in most cases.
+ tst \divisor, #0xe0000000
+ moveq \divisor, \divisor, lsl #3
+ moveq \curbit, #8
+ movne \curbit, #1
+
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
- cmp divisor, #0x10000000
- cmplo divisor, dividend
- movlo divisor, divisor, lsl #4
- movlo curbit, curbit, lsl #4
- blo Loop1
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ movlo \curbit, \curbit, lsl #4
+ blo 1b
-Lbignum:
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
- cmp divisor, #0x80000000
- cmplo divisor, dividend
- movlo divisor, divisor, lsl #1
- movlo curbit, curbit, lsl #1
- blo Lbignum
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ movlo \curbit, \curbit, lsl #1
+ blo 1b
+
+ mov \result, #0
+
+#endif
+
+ @ Division loop
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ orrhs \result, \result, \curbit
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ orrhs \result, \result, \curbit, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ orrhs \result, \result, \curbit, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ orrhs \result, \result, \curbit, lsr #3
+ cmp \dividend, #0 @ Early termination?
+ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
+ movne \divisor, \divisor, lsr #4
+ bne 1b
+
+.endm
+/* ------------------------------------------------------------------------ */
+.macro ARM_DIV2_ORDER divisor, order
+
+#if __ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ rsb \order, \order, #31
+
+#else
-Loop3:
- @ Test for possible subtractions. On the final pass, this may
- @ subtract too much from the dividend ...
+ cmp \divisor, #(1 << 16)
+ movhs \divisor, \divisor, lsr #16
+ movhs \order, #16
+ movlo \order, #0
+
+ cmp \divisor, #(1 << 8)
+ movhs \divisor, \divisor, lsr #8
+ addhs \order, \order, #8
+
+ cmp \divisor, #(1 << 4)
+ movhs \divisor, \divisor, lsr #4
+ addhs \order, \order, #4
+
+ cmp \divisor, #(1 << 2)
+ addhi \order, \order, #3
+ addls \order, \order, \divisor, lsr #1
+
+#endif
+
+.endm
+/* ------------------------------------------------------------------------ */
+.macro ARM_MOD_BODY dividend, divisor, order, spare
+
+#if __ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ clz \spare, \dividend
+ sub \order, \order, \spare
+ mov \divisor, \divisor, lsl \order
- .if \modulo
- @ ... so keep track of which subtractions are done in OVERDONE.
- @ We can fix them up afterwards.
- mov overdone, #0
- cmp dividend, divisor
- subhs dividend, dividend, divisor
- cmp dividend, divisor, lsr #1
- subhs dividend, dividend, divisor, lsr #1
- orrhs overdone, overdone, curbit, ror #1
- cmp dividend, divisor, lsr #2
- subhs dividend, dividend, divisor, lsr #2
- orrhs overdone, overdone, curbit, ror #2
- cmp dividend, divisor, lsr #3
- subhs dividend, dividend, divisor, lsr #3
- orrhs overdone, overdone, curbit, ror #3
- mov ip, curbit
- .else
- @ ... so keep track of which subtractions are done in RESULT.
- @ The result will be ok, since the "bit" will have been
- @ shifted out at the bottom.
- cmp dividend, divisor
- subhs dividend, dividend, divisor
- orrhs result, result, curbit
- cmp dividend, divisor, lsr #1
- subhs dividend, dividend, divisor, lsr #1
- orrhs result, result, curbit, lsr #1
- cmp dividend, divisor, lsr #2
- subhs dividend, dividend, divisor, lsr #2
- orrhs result, result, curbit, lsr #2
- cmp dividend, divisor, lsr #3
- subhs dividend, dividend, divisor, lsr #3
- orrhs result, result, curbit, lsr #3
- .endif
+#else
- cmp dividend, #0 @ Early termination?
- movnes curbit, curbit, lsr #4 @ No, any more bits to do?
- movne divisor, divisor, lsr #4
- bne Loop3
+ mov \order, #0
- .if \modulo
-Lfixup_dividend:
- @ Any subtractions that we should not have done will be recorded in
- @ the top three bits of OVERDONE. Exactly which were not needed
- @ are governed by the position of the bit, stored in IP.
- ands overdone, overdone, #0xe0000000
- @ If we terminated early, because dividend became zero, then the
- @ bit in ip will not be in the bottom nibble, and we should not
- @ perform the additions below. We must test for this though
- @ (rather relying upon the TSTs to prevent the additions) since
- @ the bit in ip could be in the top two bits which might then match
- @ with one of the smaller RORs.
- tstne ip, #0x7
- beq Lgot_result
- tst overdone, ip, ror #3
- addne dividend, dividend, divisor, lsr #3
- tst overdone, ip, ror #2
- addne dividend, dividend, divisor, lsr #2
- tst overdone, ip, ror #1
- addne dividend, dividend, divisor, lsr #1
- .endif
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ addlo \order, \order, #4
+ blo 1b
-Lgot_result:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ addlo \order, \order, #1
+ blo 1b
+
+#endif
+
+ @ Perform all needed substractions to keep only the reminder.
+ @ Do comparisons in batch of 4 first.
+ subs \order, \order, #3 @ yes, 3 is intended here
+ blt 2f
+
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ cmp \dividend, #1
+ mov \divisor, \divisor, lsr #4
+ subges \order, \order, #4
+ bge 1b
+
+ tst \order, #3
+ teqne \dividend, #0
+ beq 5f
+
+ @ Either 1, 2 or 3 comparison/substractions are left.
+2: cmn \order, #2
+ blt 4f
+ beq 3f
+ cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+3: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+4: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+5:
.endm
/* ------------------------------------------------------------------------ */
.macro THUMB_DIV_MOD_BODY modulo
@ Load the constant 0x10000000 into our work register.
mov work, #1
lsl work, #28
-Loop1:
+LSYM(Loop1):
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
cmp divisor, work
- bhs Lbignum
+ bhs LSYM(Lbignum)
cmp divisor, dividend
- bhs Lbignum
+ bhs LSYM(Lbignum)
lsl divisor, #4
lsl curbit, #4
- b Loop1
-Lbignum:
+ b LSYM(Loop1)
+LSYM(Lbignum):
@ Set work to 0x80000000
lsl work, #3
-Loop2:
+LSYM(Loop2):
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
cmp divisor, work
- bhs Loop3
+ bhs LSYM(Loop3)
cmp divisor, dividend
- bhs Loop3
+ bhs LSYM(Loop3)
lsl divisor, #1
lsl curbit, #1
- b Loop2
-Loop3:
+ b LSYM(Loop2)
+LSYM(Loop3):
@ Test for possible subtractions ...
.if \modulo
@ ... On the final pass, this may subtract too much from the dividend,
@@ -290,79 +443,79 @@ Loop3:
@ afterwards.
mov overdone, #0
cmp dividend, divisor
- blo Lover1
+ blo LSYM(Lover1)
sub dividend, dividend, divisor
-Lover1:
+LSYM(Lover1):
lsr work, divisor, #1
cmp dividend, work
- blo Lover2
+ blo LSYM(Lover2)
sub dividend, dividend, work
mov ip, curbit
mov work, #1
ror curbit, work
orr overdone, curbit
mov curbit, ip
-Lover2:
+LSYM(Lover2):
lsr work, divisor, #2
cmp dividend, work
- blo Lover3
+ blo LSYM(Lover3)
sub dividend, dividend, work
mov ip, curbit
mov work, #2
ror curbit, work
orr overdone, curbit
mov curbit, ip
-Lover3:
+LSYM(Lover3):
lsr work, divisor, #3
cmp dividend, work
- blo Lover4
+ blo LSYM(Lover4)
sub dividend, dividend, work
mov ip, curbit
mov work, #3
ror curbit, work
orr overdone, curbit
mov curbit, ip
-Lover4:
+LSYM(Lover4):
mov ip, curbit
.else
@ ... and note which bits are done in the result. On the final pass,
@ this may subtract too much from the dividend, but the result will be ok,
@ since the "bit" will have been shifted out at the bottom.
cmp dividend, divisor
- blo Lover1
+ blo LSYM(Lover1)
sub dividend, dividend, divisor
orr result, result, curbit
-Lover1:
+LSYM(Lover1):
lsr work, divisor, #1
cmp dividend, work
- blo Lover2
+ blo LSYM(Lover2)
sub dividend, dividend, work
lsr work, curbit, #1
orr result, work
-Lover2:
+LSYM(Lover2):
lsr work, divisor, #2
cmp dividend, work
- blo Lover3
+ blo LSYM(Lover3)
sub dividend, dividend, work
lsr work, curbit, #2
orr result, work
-Lover3:
+LSYM(Lover3):
lsr work, divisor, #3
cmp dividend, work
- blo Lover4
+ blo LSYM(Lover4)
sub dividend, dividend, work
lsr work, curbit, #3
orr result, work
-Lover4:
+LSYM(Lover4):
.endif
cmp dividend, #0 @ Early termination?
- beq Lover5
+ beq LSYM(Lover5)
lsr curbit, #4 @ No, any more bits to do?
- beq Lover5
+ beq LSYM(Lover5)
lsr divisor, #4
- b Loop3
-Lover5:
+ b LSYM(Loop3)
+LSYM(Lover5):
.if \modulo
@ Any subtractions that we should not have done will be recorded in
@ the top three bits of "overdone". Exactly which were not needed
@@ -370,7 +523,7 @@ Lover5:
mov work, #0xe
lsl work, #28
and overdone, work
- beq Lgot_result
+ beq LSYM(Lgot_result)
@ If we terminated early, because dividend became zero, then the
@ bit in ip will not be in the bottom nibble, and we should not
@@ -381,33 +534,33 @@ Lover5:
mov curbit, ip
mov work, #0x7
tst curbit, work
- beq Lgot_result
+ beq LSYM(Lgot_result)
mov curbit, ip
mov work, #3
ror curbit, work
tst overdone, curbit
- beq Lover6
+ beq LSYM(Lover6)
lsr work, divisor, #3
add dividend, work
-Lover6:
+LSYM(Lover6):
mov curbit, ip
mov work, #2
ror curbit, work
tst overdone, curbit
- beq Lover7
+ beq LSYM(Lover7)
lsr work, divisor, #2
add dividend, work
-Lover7:
+LSYM(Lover7):
mov curbit, ip
mov work, #1
ror curbit, work
tst overdone, curbit
- beq Lgot_result
+ beq LSYM(Lgot_result)
lsr work, divisor, #1
add dividend, work
.endif
-Lgot_result:
+LSYM(Lgot_result):
.endm
/* ------------------------------------------------------------------------ */
/* Start of the Real Functions */
@@ -419,13 +572,13 @@ Lgot_result:
#ifdef __thumb__
cmp divisor, #0
- beq Ldiv0
+ beq LSYM(Ldiv0)
mov curbit, #1
mov result, #0
push { work }
cmp dividend, divisor
- blo Lgot_result
+ blo LSYM(Lgot_result)
THUMB_DIV_MOD_BODY 0
@@ -434,22 +587,32 @@ Lgot_result:
RET
#else /* ARM version. */
+
+ subs r2, r1, #1
+ RETc(eq)
+ bcc LSYM(Ldiv0)
+ cmp r0, r1
+ bls 11f
+ tst r1, r2
+ beq 12f
- cmp divisor, #0
- beq Ldiv0
- mov curbit, #1
- mov result, #0
- cmp dividend, divisor
- blo Lgot_result
-
- ARM_DIV_MOD_BODY 0
+ ARM_DIV_BODY r0, r1, r2, r3
- mov r0, result
+ mov r0, r2
RET
+11: moveq r0, #1
+ movne r0, #0
+ RET
+
+12: ARM_DIV2_ORDER r1, r2
+
+ mov r0, r0, lsr r2
+ RET
+
#endif /* ARM version */
- FUNC_END udivsi3
+ DIV_FUNC_END udivsi3
#endif /* L_udivsi3 */
/* ------------------------------------------------------------------------ */
@@ -460,13 +623,13 @@ Lgot_result:
#ifdef __thumb__
cmp divisor, #0
- beq Ldiv0
+ beq LSYM(Ldiv0)
mov curbit, #1
cmp dividend, divisor
- bhs Lover10
+ bhs LSYM(Lover10)
RET
-Lover10:
+LSYM(Lover10):
push { work }
THUMB_DIV_MOD_BODY 1
@@ -476,21 +639,21 @@ Lover10:
#else /* ARM version. */
- cmp divisor, #0
- beq Ldiv0
- cmp divisor, #1
- cmpne dividend, divisor
- moveq dividend, #0
- RETc(lo)
- mov curbit, #1
+ subs r2, r1, #1 @ compare divisor with 1
+ bcc LSYM(Ldiv0)
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ RETc(ls)
- ARM_DIV_MOD_BODY 1
+ ARM_MOD_BODY r0, r1, r2, r3
RET
#endif /* ARM version. */
- FUNC_END umodsi3
+ DIV_FUNC_END umodsi3
#endif /* L_umodsi3 */
/* ------------------------------------------------------------------------ */
@@ -500,7 +663,7 @@ Lover10:
#ifdef __thumb__
cmp divisor, #0
- beq Ldiv0
+ beq LSYM(Ldiv0)
push { work }
mov work, dividend
@@ -509,50 +672,67 @@ Lover10:
mov curbit, #1
mov result, #0
cmp divisor, #0
- bpl Lover10
+ bpl LSYM(Lover10)
neg divisor, divisor @ Loops below use unsigned.
-Lover10:
+LSYM(Lover10):
cmp dividend, #0
- bpl Lover11
+ bpl LSYM(Lover11)
neg dividend, dividend
-Lover11:
+LSYM(Lover11):
cmp dividend, divisor
- blo Lgot_result
+ blo LSYM(Lgot_result)
THUMB_DIV_MOD_BODY 0
mov r0, result
mov work, ip
cmp work, #0
- bpl Lover12
+ bpl LSYM(Lover12)
neg r0, r0
-Lover12:
+LSYM(Lover12):
pop { work }
RET
#else /* ARM version. */
- eor ip, dividend, divisor @ Save the sign of the result.
- mov curbit, #1
- mov result, #0
- cmp divisor, #0
- rsbmi divisor, divisor, #0 @ Loops below use unsigned.
- beq Ldiv0
- cmp dividend, #0
- rsbmi dividend, dividend, #0
- cmp dividend, divisor
- blo Lgot_result
-
- ARM_DIV_MOD_BODY 0
+ cmp r1, #0
+ eor ip, r0, r1 @ save the sign of the result.
+ beq LSYM(Ldiv0)
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ subs r2, r1, #1 @ division by 1 or -1 ?
+ beq 10f
+ movs r3, r0
+ rsbmi r3, r0, #0 @ positive dividend value
+ cmp r3, r1
+ bls 11f
+ tst r1, r2 @ divisor is power of 2 ?
+ beq 12f
+
+ ARM_DIV_BODY r3, r1, r0, r2
- mov r0, result
cmp ip, #0
rsbmi r0, r0, #0
RET
+10: teq ip, r0 @ same sign ?
+ rsbmi r0, r0, #0
+ RET
+
+11: movlo r0, #0
+ moveq r0, ip, asr #31
+ orreq r0, r0, #1
+ RET
+
+12: ARM_DIV2_ORDER r1, r2
+
+ cmp ip, #0
+ mov r0, r3, lsr r2
+ rsbmi r0, r0, #0
+ RET
+
#endif /* ARM version */
- FUNC_END divsi3
+ DIV_FUNC_END divsi3
#endif /* L_divsi3 */
/* ------------------------------------------------------------------------ */
@@ -564,56 +744,55 @@ Lover12:
mov curbit, #1
cmp divisor, #0
- beq Ldiv0
- bpl Lover10
+ beq LSYM(Ldiv0)
+ bpl LSYM(Lover10)
neg divisor, divisor @ Loops below use unsigned.
-Lover10:
+LSYM(Lover10):
push { work }
@ Need to save the sign of the dividend, unfortunately, we need
@ work later on. Must do this after saving the original value of
@ the work register, because we will pop this value off first.
push { dividend }
cmp dividend, #0
- bpl Lover11
+ bpl LSYM(Lover11)
neg dividend, dividend
-Lover11:
+LSYM(Lover11):
cmp dividend, divisor
- blo Lgot_result
+ blo LSYM(Lgot_result)
THUMB_DIV_MOD_BODY 1
pop { work }
cmp work, #0
- bpl Lover12
+ bpl LSYM(Lover12)
neg dividend, dividend
-Lover12:
+LSYM(Lover12):
pop { work }
RET
#else /* ARM version. */
- cmp divisor, #0
- rsbmi divisor, divisor, #0 @ Loops below use unsigned.
- beq Ldiv0
- @ Need to save the sign of the dividend, unfortunately, we need
- @ ip later on; this is faster than pushing lr and using that.
- str dividend, [sp, #-4]!
- cmp dividend, #0 @ Test dividend against zero
- rsbmi dividend, dividend, #0 @ If negative make positive
- cmp dividend, divisor @ else if zero return zero
- blo Lgot_result @ if smaller return dividend
- mov curbit, #1
-
- ARM_DIV_MOD_BODY 1
-
- ldr ip, [sp], #4
- cmp ip, #0
- rsbmi dividend, dividend, #0
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ movs ip, r0 @ preserve sign of dividend
+ rsbmi r0, r0, #0 @ if negative make positive
+ subs r2, r1, #1 @ compare divisor with 1
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ bls 10f
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+10: cmp ip, #0
+ rsbmi r0, r0, #0
RET
#endif /* ARM version */
- FUNC_END modsi3
+ DIV_FUNC_END modsi3
#endif /* L_modsi3 */
/* ------------------------------------------------------------------------ */
@@ -623,7 +802,7 @@ Lover12:
RET
- SIZE (__div0)
+ FUNC_END div0
#endif /* L_divmodsi_tools */
/* ------------------------------------------------------------------------ */
@@ -636,22 +815,18 @@ Lover12:
#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
#define __NR_kill (__NR_SYSCALL_BASE+ 37)
+ .code 32
FUNC_START div0
stmfd sp!, {r1, lr}
swi __NR_getpid
cmn r0, #1000
- ldmhsfd sp!, {r1, pc}RETCOND @ not much we can do
+ RETLDM r1 hs
mov r1, #SIGFPE
swi __NR_kill
-#ifdef __THUMB_INTERWORK__
- ldmfd sp!, {r1, lr}
- bx lr
-#else
- ldmfd sp!, {r1, pc}RETCOND
-#endif
+ RETLDM r1
- SIZE (__div0)
+ FUNC_END div0
#endif /* L_dvmd_lnx */
/* ------------------------------------------------------------------------ */
@@ -720,24 +895,23 @@ Lover12:
.code 32
.globl _arm_return
-_arm_return:
- ldmia r13!, {r12}
- bx r12
+_arm_return:
+ RETLDM
.code 16
-.macro interwork register
- .code 16
+.macro interwork register
+ .code 16
THUMB_FUNC_START _interwork_call_via_\register
- bx pc
+ bx pc
nop
-
- .code 32
- .globl .Lchange_\register
-.Lchange_\register:
+
+ .code 32
+ .globl LSYM(Lchange_\register)
+LSYM(Lchange_\register):
tst \register, #1
- stmeqdb r13!, {lr}
+ streq lr, [sp, #-4]!
adreq lr, _arm_return
bx \register
@@ -779,3 +953,7 @@ _arm_return:
SIZE (_interwork_call_via_lr)
#endif /* L_interwork_call_via_rX */
+
+#include "ieee754-df.S"
+#include "ieee754-sf.S"
+
diff --git a/contrib/gcc/config/arm/linux-elf.h b/contrib/gcc/config/arm/linux-elf.h
index 8cc812f..9f291c0 100644
--- a/contrib/gcc/config/arm/linux-elf.h
+++ b/contrib/gcc/config/arm/linux-elf.h
@@ -1,24 +1,24 @@
/* Definitions for ARM running Linux-based GNU systems using ELF
- Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by Philip Blundell <philb@gnu.org>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* elfos.h should have already been included. Now just override
any conflicting definitions and add any extras. */
@@ -34,6 +34,8 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
+
#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p"
#undef MULTILIB_DEFAULTS
@@ -47,6 +49,7 @@ Boston, MA 02111-1307, USA. */
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
/* Now we define the strings used to build the spec file. */
+#undef LIB_SPEC
#define LIB_SPEC \
"%{pthread:-lpthread} \
%{shared:-lc} \
@@ -57,7 +60,7 @@ Boston, MA 02111-1307, USA. */
/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
provides part of the support for getting C++ file-scope static
- object constructed before entering `main'. */
+ object constructed before entering `main'. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
@@ -89,15 +92,7 @@ Boston, MA 02111-1307, USA. */
%{mbig-endian:-EB}" \
SUBTARGET_EXTRA_LINK_SPEC
-#define TARGET_OS_CPP_BUILTINS() \
- do { \
- builtin_define_std ("unix"); \
- builtin_define_std ("linux"); \
- builtin_define ("__gnu_linux__"); \
- builtin_define ("__ELF__"); \
- builtin_assert ("system=unix"); \
- builtin_assert ("system=posix"); \
- } while (0)
+#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
/* This is how we tell the assembler that two symbols have the same value. */
#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
@@ -111,8 +106,8 @@ Boston, MA 02111-1307, USA. */
while (0)
/* NWFPE always understands FPA instructions. */
-#undef FP_DEFAULT
-#define FP_DEFAULT FP_SOFT3
+#undef FPUTYPE_DEFAULT
+#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU3
/* Call the function profiler with a given profile label. */
#undef ARM_FUNCTION_PROFILER
@@ -121,6 +116,11 @@ Boston, MA 02111-1307, USA. */
fprintf (STREAM, "\tbl\tmcount%s\n", NEED_PLT_RELOC ? "(PLT)" : ""); \
}
+/* The linux profiler clobbers the link register. Make sure the
+ prologue knows to save it. */
+#define PROFILE_HOOK(X) \
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, LR_REGNUM)))
+
#undef CC1_SPEC
#define CC1_SPEC "%{profile:-p}"
diff --git a/contrib/gcc/config/arm/linux-gas.h b/contrib/gcc/config/arm/linux-gas.h
index 5e8ddf9..6911284 100644
--- a/contrib/gcc/config/arm/linux-gas.h
+++ b/contrib/gcc/config/arm/linux-gas.h
@@ -3,35 +3,31 @@
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* This is how we tell the assembler that a symbol is weak.
GAS always supports weak symbols. */
-/* This is used in ASM_FILE_START. */
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "Linux"
-
/* Unsigned chars produces much better code than signed. */
#define DEFAULT_SIGNED_CHAR 0
#undef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__}"
+#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{fPIC|fPIE:-D__PIC__ -D__pic__} %{fpic|fpie:-D__PIC__ -D__pic__}"
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
diff --git a/contrib/gcc/config/arm/mmintrin.h b/contrib/gcc/config/arm/mmintrin.h
new file mode 100644
index 0000000..4dc1d45
--- /dev/null
+++ b/contrib/gcc/config/arm/mmintrin.h
@@ -0,0 +1,1257 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* As a special exception, if you include this header file into source
+ files compiled by GCC, this header file does not by itself cause
+ the resulting executable to be covered by the GNU General Public
+ License. This exception does not however invalidate any other
+ reasons why the executable file might be covered by the GNU General
+ Public License. */
+
+#ifndef _MMINTRIN_H_INCLUDED
+#define _MMINTRIN_H_INCLUDED
+
+/* The data type intended for user use. */
+typedef unsigned long long __m64, __int64;
+
+/* Internal data types for implementing the intrinsics. */
+typedef int __v2si __attribute__ ((__mode__ (__V2SI__)));
+typedef int __v4hi __attribute__ ((__mode__ (__V4HI__)));
+typedef int __v8qi __attribute__ ((__mode__ (__V8QI__)));
+
+/* "Convert" __m64 and __int64 into each other. */
+static __inline __m64
+_mm_cvtsi64_m64 (__int64 __i)
+{
+ return __i;
+}
+
+static __inline __int64
+_mm_cvtm64_si64 (__m64 __i)
+{
+ return __i;
+}
+
+static __inline int
+_mm_cvtsi64_si32 (__int64 __i)
+{
+ return __i;
+}
+
+static __inline __int64
+_mm_cvtsi32_si64 (int __i)
+{
+ return __i;
+}
+
+/* Pack the four 16-bit values from M1 into the lower four 8-bit values of
+ the result, and the four 16-bit values from M2 into the upper four 8-bit
+ values of the result, all with signed saturation. */
+static __inline __m64
+_mm_packs_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackhss ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Pack the two 32-bit values from M1 in to the lower two 16-bit values of
+ the result, and the two 32-bit values from M2 into the upper two 16-bit
+ values of the result, all with signed saturation. */
+static __inline __m64
+_mm_packs_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackwss ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Copy the 64-bit value from M1 into the lower 32-bits of the result, and
+ the 64-bit value from M2 into the upper 32-bits of the result, all with
+ signed saturation for values that do not fit exactly into 32-bits. */
+static __inline __m64
+_mm_packs_pi64 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackdss ((long long)__m1, (long long)__m2);
+}
+
+/* Pack the four 16-bit values from M1 into the lower four 8-bit values of
+ the result, and the four 16-bit values from M2 into the upper four 8-bit
+ values of the result, all with unsigned saturation. */
+static __inline __m64
+_mm_packs_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackhus ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Pack the two 32-bit values from M1 into the lower two 16-bit values of
+ the result, and the two 32-bit values from M2 into the upper two 16-bit
+ values of the result, all with unsigned saturation. */
+static __inline __m64
+_mm_packs_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackwus ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Copy the 64-bit value from M1 into the lower 32-bits of the result, and
+ the 64-bit value from M2 into the upper 32-bits of the result, all with
+ unsigned saturation for values that do not fit exactly into 32-bits. */
+static __inline __m64
+_mm_packs_pu64 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackdus ((long long)__m1, (long long)__m2);
+}
+
+/* Interleave the four 8-bit values from the high half of M1 with the four
+ 8-bit values from the high half of M2. */
+static __inline __m64
+_mm_unpackhi_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckihb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Interleave the two 16-bit values from the high half of M1 with the two
+ 16-bit values from the high half of M2. */
+static __inline __m64
+_mm_unpackhi_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckihh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Interleave the 32-bit value from the high half of M1 with the 32-bit
+ value from the high half of M2. */
+static __inline __m64
+_mm_unpackhi_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckihw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Interleave the four 8-bit values from the low half of M1 with the four
+ 8-bit values from the low half of M2. */
+static __inline __m64
+_mm_unpacklo_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckilb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Interleave the two 16-bit values from the low half of M1 with the two
+ 16-bit values from the low half of M2. */
+static __inline __m64
+_mm_unpacklo_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckilh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Interleave the 32-bit value from the low half of M1 with the 32-bit
+ value from the low half of M2. */
+static __inline __m64
+_mm_unpacklo_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckilw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Take the four 8-bit values from the low half of M1, sign extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackel_pi8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelsb ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the low half of M1, sign extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackel_pi16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelsh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the low half of M1, and return it sign extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackel_pi32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelsw ((__v2si)__m1);
+}
+
+/* Take the four 8-bit values from the high half of M1, sign extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pi8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehsb ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the high half of M1, sign extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pi16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehsh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the high half of M1, and return it sign extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackeh_pi32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehsw ((__v2si)__m1);
+}
+
+/* Take the four 8-bit values from the low half of M1, zero extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackel_pu8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelub ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the low half of M1, zero extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackel_pu16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckeluh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the low half of M1, and return it zero extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackel_pu32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckeluw ((__v2si)__m1);
+}
+
+/* Take the four 8-bit values from the high half of M1, zero extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pu8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehub ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the high half of M1, zero extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pu16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehuh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the high half of M1, and return it zero extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackeh_pu32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehuw ((__v2si)__m1);
+}
+
+/* Add the 8-bit values in M1 to the 8-bit values in M2. */
+static __inline __m64
+_mm_add_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2. */
+static __inline __m64
+_mm_add_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Add the 32-bit values in M1 to the 32-bit values in M2. */
+static __inline __m64
+_mm_add_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Add the 8-bit values in M1 to the 8-bit values in M2 using signed
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddbss ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2 using signed
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddhss ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Add the 32-bit values in M1 to the 32-bit values in M2 using signed
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddwss ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Add the 8-bit values in M1 to the 8-bit values in M2 using unsigned
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pu8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddbus ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2 using unsigned
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddhus ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Add the 32-bit values in M1 to the 32-bit values in M2 using unsigned
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddwus ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1. */
+static __inline __m64
+_mm_sub_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1. */
+static __inline __m64
+_mm_sub_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Subtract the 32-bit values in M2 from the 32-bit values in M1. */
+static __inline __m64
+_mm_sub_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1 using signed
+ saturating arithmetic. */
+static __inline __m64
+_mm_subs_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubbss ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1 using
+ signed saturating arithmetic. */
+static __inline __m64
+_mm_subs_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubhss ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Subtract the 32-bit values in M2 from the 32-bit values in M1 using
+ signed saturating arithmetic. */
+static __inline __m64
+_mm_subs_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubwss ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1 using
+ unsigned saturating arithmetic. */
+static __inline __m64
+_mm_subs_pu8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubbus ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1 using
+ unsigned saturating arithmetic. */
+static __inline __m64
+_mm_subs_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubhus ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Subtract the 32-bit values in M2 from the 32-bit values in M1 using
+ unsigned saturating arithmetic. */
+static __inline __m64
+_mm_subs_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubwus ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 producing
+ four 32-bit intermediate results, which are then summed by pairs to
+ produce two 32-bit results. */
+static __inline __m64
+_mm_madd_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmadds ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 producing
+ four 32-bit intermediate results, which are then summed by pairs to
+ produce two 32-bit results. */
+static __inline __m64
+_mm_madd_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmaddu ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four signed 16-bit values in M1 by four signed 16-bit values in
+ M2 and produce the high 16 bits of the 32-bit results. */
+static __inline __m64
+_mm_mulhi_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmulsh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four signed 16-bit values in M1 by four signed 16-bit values in
+ M2 and produce the high 16 bits of the 32-bit results. */
+static __inline __m64
+_mm_mulhi_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmuluh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 and produce
+ the low 16 bits of the results. */
+static __inline __m64
+_mm_mullo_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmulul ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Shift four 16-bit values in M left by COUNT. */
+static __inline __m64
+_mm_sll_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsllh ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_slli_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsllhi ((__v4hi)__m, __count);
+}
+
+/* Shift two 32-bit values in M left by COUNT. */
+static __inline __m64
+_mm_sll_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsllw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_slli_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsllwi ((__v2si)__m, __count);
+}
+
+/* Shift the 64-bit value in M left by COUNT. */
+static __inline __m64
+_mm_sll_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wslld (__m, __count);
+}
+
+static __inline __m64
+_mm_slli_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wslldi (__m, __count);
+}
+
+/* Shift four 16-bit values in M right by COUNT; shift in the sign bit. */
+static __inline __m64
+_mm_sra_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrah ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_srai_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrahi ((__v4hi)__m, __count);
+}
+
+/* Shift two 32-bit values in M right by COUNT; shift in the sign bit. */
+static __inline __m64
+_mm_sra_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsraw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_srai_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrawi ((__v2si)__m, __count);
+}
+
+/* Shift the 64-bit value in M right by COUNT; shift in the sign bit. */
+static __inline __m64
+_mm_sra_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrad (__m, __count);
+}
+
+static __inline __m64
+_mm_srai_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsradi (__m, __count);
+}
+
+/* Shift four 16-bit values in M right by COUNT; shift in zeros. */
+static __inline __m64
+_mm_srl_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrlh ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_srli_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrlhi ((__v4hi)__m, __count);
+}
+
+/* Shift two 32-bit values in M right by COUNT; shift in zeros. */
+static __inline __m64
+_mm_srl_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrlw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_srli_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrlwi ((__v2si)__m, __count);
+}
+
+/* Shift the 64-bit value in M left by COUNT; shift in zeros. */
+static __inline __m64
+_mm_srl_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrld (__m, __count);
+}
+
+static __inline __m64
+_mm_srli_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrldi (__m, __count);
+}
+
+/* Rotate four 16-bit values in M right by COUNT. */
+static __inline __m64
+_mm_ror_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wrorh ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_rori_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wrorhi ((__v4hi)__m, __count);
+}
+
+/* Rotate two 32-bit values in M right by COUNT. */
+static __inline __m64
+_mm_ror_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wrorw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_rori_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wrorwi ((__v2si)__m, __count);
+}
+
+/* Rotate two 64-bit values in M right by COUNT. */
+static __inline __m64
+_mm_ror_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wrord (__m, __count);
+}
+
+static __inline __m64
+_mm_rori_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wrordi (__m, __count);
+}
+
+/* Bit-wise AND the 64-bit values in M1 and M2. */
+static __inline __m64
+_mm_and_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wand (__m1, __m2);
+}
+
+/* Bit-wise complement the 64-bit value in M1 and bit-wise AND it with the
+ 64-bit value in M2. */
+static __inline __m64
+_mm_andnot_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wandn (__m1, __m2);
+}
+
+/* Bit-wise inclusive OR the 64-bit values in M1 and M2. */
+static __inline __m64
+_mm_or_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wor (__m1, __m2);
+}
+
+/* Bit-wise exclusive OR the 64-bit values in M1 and M2. */
+static __inline __m64
+_mm_xor_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wxor (__m1, __m2);
+}
+
+/* Compare eight 8-bit values. The result of the comparison is 0xFF if the
+ test is true and zero if false. */
+static __inline __m64
+_mm_cmpeq_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpeqb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtsb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pu8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtub ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Compare four 16-bit values. The result of the comparison is 0xFFFF if
+ the test is true and zero if false. */
+static __inline __m64
+_mm_cmpeq_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpeqh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtsh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtuh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Compare two 32-bit values. The result of the comparison is 0xFFFFFFFF if
+ the test is true and zero if false. */
+static __inline __m64
+_mm_cmpeq_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpeqw ((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtsw ((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtuw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Element-wise multiplication of unsigned 16-bit values __B and __C, followed
+ by accumulate across all elements and __A. */
+static __inline __m64
+_mm_mac_pu16 (__m64 __A, __m64 __B, __m64 __C)
+{
+ return __builtin_arm_wmacu (__A, (__v4hi)__B, (__v4hi)__C);
+}
+
+/* Element-wise multiplication of signed 16-bit values __B and __C, followed
+ by accumulate across all elements and __A. */
+static __inline __m64
+_mm_mac_pi16 (__m64 __A, __m64 __B, __m64 __C)
+{
+ return __builtin_arm_wmacs (__A, (__v4hi)__B, (__v4hi)__C);
+}
+
+/* Element-wise multiplication of unsigned 16-bit values __B and __C, followed
+ by accumulate across all elements. */
+static __inline __m64
+_mm_macz_pu16 (__m64 __A, __m64 __B)
+{
+ return __builtin_arm_wmacuz ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Element-wise multiplication of signed 16-bit values __B and __C, followed
+ by accumulate across all elements. */
+static __inline __m64
+_mm_macz_pi16 (__m64 __A, __m64 __B)
+{
+ return __builtin_arm_wmacsz ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Accumulate across all unsigned 8-bit values in __A. */
+static __inline __m64
+_mm_acc_pu8 (__m64 __A)
+{
+ return __builtin_arm_waccb ((__v8qi)__A);
+}
+
+/* Accumulate across all unsigned 16-bit values in __A. */
+static __inline __m64
+_mm_acc_pu16 (__m64 __A)
+{
+ return __builtin_arm_wacch ((__v4hi)__A);
+}
+
+/* Accumulate across all unsigned 32-bit values in __A. */
+static __inline __m64
+_mm_acc_pu32 (__m64 __A)
+{
+ return __builtin_arm_waccw ((__v2si)__A);
+}
+
+static __inline __m64
+_mm_mia_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmia (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miaph_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiaph (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miabb_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiabb (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miabt_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiabt (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miatb_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiatb (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miatt_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiatt (__A, __B, __C);
+}
+
+/* Extract one of the elements of A and sign extend. The selector N must
+ be immediate. */
+#define _mm_extract_pi8(A, N) __builtin_arm_textrmsb ((__v8qi)(A), (N))
+#define _mm_extract_pi16(A, N) __builtin_arm_textrmsh ((__v4hi)(A), (N))
+#define _mm_extract_pi32(A, N) __builtin_arm_textrmsw ((__v2si)(A), (N))
+
+/* Extract one of the elements of A and zero extend. The selector N must
+ be immediate. */
+#define _mm_extract_pu8(A, N) __builtin_arm_textrmub ((__v8qi)(A), (N))
+#define _mm_extract_pu16(A, N) __builtin_arm_textrmuh ((__v4hi)(A), (N))
+#define _mm_extract_pu32(A, N) __builtin_arm_textrmuw ((__v2si)(A), (N))
+
+/* Inserts word D into one of the elements of A. The selector N must be
+ immediate. */
+#define _mm_insert_pi8(A, D, N) \
+ ((__m64) __builtin_arm_tinsrb ((__v8qi)(A), (D), (N)))
+#define _mm_insert_pi16(A, D, N) \
+ ((__m64) __builtin_arm_tinsrh ((__v4hi)(A), (D), (N)))
+#define _mm_insert_pi32(A, D, N) \
+ ((__m64) __builtin_arm_tinsrw ((__v2si)(A), (D), (N)))
+
+/* Compute the element-wise maximum of signed 8-bit values. */
+static __inline __m64
+_mm_max_pi8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxsb ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise maximum of signed 16-bit values. */
+static __inline __m64
+_mm_max_pi16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxsh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise maximum of signed 32-bit values. */
+static __inline __m64
+_mm_max_pi32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxsw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Compute the element-wise maximum of unsigned 8-bit values. */
+static __inline __m64
+_mm_max_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxub ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise maximum of unsigned 16-bit values. */
+static __inline __m64
+_mm_max_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxuh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise maximum of unsigned 32-bit values. */
+static __inline __m64
+_mm_max_pu32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxuw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Compute the element-wise minimum of signed 16-bit values. */
+static __inline __m64
+_mm_min_pi8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminsb ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise minimum of signed 16-bit values. */
+static __inline __m64
+_mm_min_pi16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminsh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise minimum of signed 32-bit values. */
+static __inline __m64
+_mm_min_pi32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminsw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Compute the element-wise minimum of unsigned 16-bit values. */
+static __inline __m64
+_mm_min_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminub ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise minimum of unsigned 16-bit values. */
+static __inline __m64
+_mm_min_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminuh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise minimum of unsigned 32-bit values. */
+static __inline __m64
+_mm_min_pu32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminuw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Create an 8-bit mask of the signs of 8-bit values. */
+static __inline int
+_mm_movemask_pi8 (__m64 __A)
+{
+ return __builtin_arm_tmovmskb ((__v8qi)__A);
+}
+
+/* Create an 8-bit mask of the signs of 16-bit values. */
+static __inline int
+_mm_movemask_pi16 (__m64 __A)
+{
+ return __builtin_arm_tmovmskh ((__v4hi)__A);
+}
+
+/* Create an 8-bit mask of the signs of 32-bit values. */
+static __inline int
+_mm_movemask_pi32 (__m64 __A)
+{
+ return __builtin_arm_tmovmskw ((__v2si)__A);
+}
+
+/* Return a combination of the four 16-bit values in A. The selector
+ must be an immediate. */
+#define _mm_shuffle_pi16(A, N) \
+ ((__m64) __builtin_arm_wshufh ((__v4hi)(A), (N)))
+
+
+/* Compute the rounded averages of the unsigned 8-bit values in A and B. */
+static __inline __m64
+_mm_avg_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2br ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the rounded averages of the unsigned 16-bit values in A and B. */
+static __inline __m64
+_mm_avg_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2hr ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the averages of the unsigned 8-bit values in A and B. */
+static __inline __m64
+_mm_avg2_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2b ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the averages of the unsigned 16-bit values in A and B. */
+static __inline __m64
+_mm_avg2_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2h ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 8-bit
+ values in A and B. Return the value in the lower 16-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sad_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadb ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 16-bit
+ values in A and B. Return the value in the lower 32-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sad_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 8-bit
+ values in A and B. Return the value in the lower 16-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sadz_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadbz ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 16-bit
+ values in A and B. Return the value in the lower 32-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sadz_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadhz ((__v4hi)__A, (__v4hi)__B);
+}
+
+static __inline __m64
+_mm_align_si64 (__m64 __A, __m64 __B, int __C)
+{
+ return (__m64) __builtin_arm_walign ((__v8qi)__A, (__v8qi)__B, __C);
+}
+
+/* Creates a 64-bit zero. */
+static __inline __m64
+_mm_setzero_si64 (void)
+{
+ return __builtin_arm_wzero ();
+}
+
+/* Set and Get arbitrary iWMMXt Control registers.
+ Note only registers 0-3 and 8-11 are currently defined,
+ the rest are reserved. */
+
+static __inline void
+_mm_setwcx (const int __regno, const int __value)
+{
+ switch (__regno)
+ {
+ case 0: __builtin_arm_setwcx (0, __value); break;
+ case 1: __builtin_arm_setwcx (1, __value); break;
+ case 2: __builtin_arm_setwcx (2, __value); break;
+ case 3: __builtin_arm_setwcx (3, __value); break;
+ case 8: __builtin_arm_setwcx (8, __value); break;
+ case 9: __builtin_arm_setwcx (9, __value); break;
+ case 10: __builtin_arm_setwcx (10, __value); break;
+ case 11: __builtin_arm_setwcx (11, __value); break;
+ default: break;
+ }
+}
+
+static __inline int
+_mm_getwcx (const int __regno)
+{
+ switch (__regno)
+ {
+ case 0: return __builtin_arm_getwcx (0);
+ case 1: return __builtin_arm_getwcx (1);
+ case 2: return __builtin_arm_getwcx (2);
+ case 3: return __builtin_arm_getwcx (3);
+ case 8: return __builtin_arm_getwcx (8);
+ case 9: return __builtin_arm_getwcx (9);
+ case 10: return __builtin_arm_getwcx (10);
+ case 11: return __builtin_arm_getwcx (11);
+ default: return 0;
+ }
+}
+
+/* Creates a vector of two 32-bit values; I0 is least significant. */
+static __inline __m64
+_mm_set_pi32 (int __i1, int __i0)
+{
+ union {
+ __m64 __q;
+ struct {
+ unsigned int __i0;
+ unsigned int __i1;
+ } __s;
+ } __u;
+
+ __u.__s.__i0 = __i0;
+ __u.__s.__i1 = __i1;
+
+ return __u.__q;
+}
+
+/* Creates a vector of four 16-bit values; W0 is least significant. */
+static __inline __m64
+_mm_set_pi16 (short __w3, short __w2, short __w1, short __w0)
+{
+ unsigned int __i1 = (unsigned short)__w3 << 16 | (unsigned short)__w2;
+ unsigned int __i0 = (unsigned short)__w1 << 16 | (unsigned short)__w0;
+ return _mm_set_pi32 (__i1, __i0);
+
+}
+
+/* Creates a vector of eight 8-bit values; B0 is least significant. */
+static __inline __m64
+_mm_set_pi8 (char __b7, char __b6, char __b5, char __b4,
+ char __b3, char __b2, char __b1, char __b0)
+{
+ unsigned int __i1, __i0;
+
+ __i1 = (unsigned char)__b7;
+ __i1 = __i1 << 8 | (unsigned char)__b6;
+ __i1 = __i1 << 8 | (unsigned char)__b5;
+ __i1 = __i1 << 8 | (unsigned char)__b4;
+
+ __i0 = (unsigned char)__b3;
+ __i0 = __i0 << 8 | (unsigned char)__b2;
+ __i0 = __i0 << 8 | (unsigned char)__b1;
+ __i0 = __i0 << 8 | (unsigned char)__b0;
+
+ return _mm_set_pi32 (__i1, __i0);
+}
+
+/* Similar, but with the arguments in reverse order. */
+static __inline __m64
+_mm_setr_pi32 (int __i0, int __i1)
+{
+ return _mm_set_pi32 (__i1, __i0);
+}
+
+static __inline __m64
+_mm_setr_pi16 (short __w0, short __w1, short __w2, short __w3)
+{
+ return _mm_set_pi16 (__w3, __w2, __w1, __w0);
+}
+
+static __inline __m64
+_mm_setr_pi8 (char __b0, char __b1, char __b2, char __b3,
+ char __b4, char __b5, char __b6, char __b7)
+{
+ return _mm_set_pi8 (__b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0);
+}
+
+/* Creates a vector of two 32-bit values, both elements containing I. */
+static __inline __m64
+_mm_set1_pi32 (int __i)
+{
+ return _mm_set_pi32 (__i, __i);
+}
+
+/* Creates a vector of four 16-bit values, all elements containing W. */
+static __inline __m64
+_mm_set1_pi16 (short __w)
+{
+ unsigned int __i = (unsigned short)__w << 16 | (unsigned short)__w;
+ return _mm_set1_pi32 (__i);
+}
+
+/* Creates a vector of four 16-bit values, all elements containing B. */
+static __inline __m64
+_mm_set1_pi8 (char __b)
+{
+ unsigned int __w = (unsigned char)__b << 8 | (unsigned char)__b;
+ unsigned int __i = __w << 16 | __w;
+ return _mm_set1_pi32 (__i);
+}
+
+/* Convert an integer to a __m64 object. */
+static __inline __m64
+_m_from_int (int __a)
+{
+ return (__m64)__a;
+}
+
+#define _m_packsswb _mm_packs_pi16
+#define _m_packssdw _mm_packs_pi32
+#define _m_packuswb _mm_packs_pu16
+#define _m_packusdw _mm_packs_pu32
+#define _m_packssqd _mm_packs_pi64
+#define _m_packusqd _mm_packs_pu64
+#define _mm_packs_si64 _mm_packs_pi64
+#define _mm_packs_su64 _mm_packs_pu64
+#define _m_punpckhbw _mm_unpackhi_pi8
+#define _m_punpckhwd _mm_unpackhi_pi16
+#define _m_punpckhdq _mm_unpackhi_pi32
+#define _m_punpcklbw _mm_unpacklo_pi8
+#define _m_punpcklwd _mm_unpacklo_pi16
+#define _m_punpckldq _mm_unpacklo_pi32
+#define _m_punpckehsbw _mm_unpackeh_pi8
+#define _m_punpckehswd _mm_unpackeh_pi16
+#define _m_punpckehsdq _mm_unpackeh_pi32
+#define _m_punpckehubw _mm_unpackeh_pu8
+#define _m_punpckehuwd _mm_unpackeh_pu16
+#define _m_punpckehudq _mm_unpackeh_pu32
+#define _m_punpckelsbw _mm_unpackel_pi8
+#define _m_punpckelswd _mm_unpackel_pi16
+#define _m_punpckelsdq _mm_unpackel_pi32
+#define _m_punpckelubw _mm_unpackel_pu8
+#define _m_punpckeluwd _mm_unpackel_pu16
+#define _m_punpckeludq _mm_unpackel_pu32
+#define _m_paddb _mm_add_pi8
+#define _m_paddw _mm_add_pi16
+#define _m_paddd _mm_add_pi32
+#define _m_paddsb _mm_adds_pi8
+#define _m_paddsw _mm_adds_pi16
+#define _m_paddsd _mm_adds_pi32
+#define _m_paddusb _mm_adds_pu8
+#define _m_paddusw _mm_adds_pu16
+#define _m_paddusd _mm_adds_pu32
+#define _m_psubb _mm_sub_pi8
+#define _m_psubw _mm_sub_pi16
+#define _m_psubd _mm_sub_pi32
+#define _m_psubsb _mm_subs_pi8
+#define _m_psubsw _mm_subs_pi16
+#define _m_psubuw _mm_subs_pi32
+#define _m_psubusb _mm_subs_pu8
+#define _m_psubusw _mm_subs_pu16
+#define _m_psubusd _mm_subs_pu32
+#define _m_pmaddwd _mm_madd_pi16
+#define _m_pmadduwd _mm_madd_pu16
+#define _m_pmulhw _mm_mulhi_pi16
+#define _m_pmulhuw _mm_mulhi_pu16
+#define _m_pmullw _mm_mullo_pi16
+#define _m_pmacsw _mm_mac_pi16
+#define _m_pmacuw _mm_mac_pu16
+#define _m_pmacszw _mm_macz_pi16
+#define _m_pmacuzw _mm_macz_pu16
+#define _m_paccb _mm_acc_pu8
+#define _m_paccw _mm_acc_pu16
+#define _m_paccd _mm_acc_pu32
+#define _m_pmia _mm_mia_si64
+#define _m_pmiaph _mm_miaph_si64
+#define _m_pmiabb _mm_miabb_si64
+#define _m_pmiabt _mm_miabt_si64
+#define _m_pmiatb _mm_miatb_si64
+#define _m_pmiatt _mm_miatt_si64
+#define _m_psllw _mm_sll_pi16
+#define _m_psllwi _mm_slli_pi16
+#define _m_pslld _mm_sll_pi32
+#define _m_pslldi _mm_slli_pi32
+#define _m_psllq _mm_sll_si64
+#define _m_psllqi _mm_slli_si64
+#define _m_psraw _mm_sra_pi16
+#define _m_psrawi _mm_srai_pi16
+#define _m_psrad _mm_sra_pi32
+#define _m_psradi _mm_srai_pi32
+#define _m_psraq _mm_sra_si64
+#define _m_psraqi _mm_srai_si64
+#define _m_psrlw _mm_srl_pi16
+#define _m_psrlwi _mm_srli_pi16
+#define _m_psrld _mm_srl_pi32
+#define _m_psrldi _mm_srli_pi32
+#define _m_psrlq _mm_srl_si64
+#define _m_psrlqi _mm_srli_si64
+#define _m_prorw _mm_ror_pi16
+#define _m_prorwi _mm_rori_pi16
+#define _m_prord _mm_ror_pi32
+#define _m_prordi _mm_rori_pi32
+#define _m_prorq _mm_ror_si64
+#define _m_prorqi _mm_rori_si64
+#define _m_pand _mm_and_si64
+#define _m_pandn _mm_andnot_si64
+#define _m_por _mm_or_si64
+#define _m_pxor _mm_xor_si64
+#define _m_pcmpeqb _mm_cmpeq_pi8
+#define _m_pcmpeqw _mm_cmpeq_pi16
+#define _m_pcmpeqd _mm_cmpeq_pi32
+#define _m_pcmpgtb _mm_cmpgt_pi8
+#define _m_pcmpgtub _mm_cmpgt_pu8
+#define _m_pcmpgtw _mm_cmpgt_pi16
+#define _m_pcmpgtuw _mm_cmpgt_pu16
+#define _m_pcmpgtd _mm_cmpgt_pi32
+#define _m_pcmpgtud _mm_cmpgt_pu32
+#define _m_pextrb _mm_extract_pi8
+#define _m_pextrw _mm_extract_pi16
+#define _m_pextrd _mm_extract_pi32
+#define _m_pextrub _mm_extract_pu8
+#define _m_pextruw _mm_extract_pu16
+#define _m_pextrud _mm_extract_pu32
+#define _m_pinsrb _mm_insert_pi8
+#define _m_pinsrw _mm_insert_pi16
+#define _m_pinsrd _mm_insert_pi32
+#define _m_pmaxsb _mm_max_pi8
+#define _m_pmaxsw _mm_max_pi16
+#define _m_pmaxsd _mm_max_pi32
+#define _m_pmaxub _mm_max_pu8
+#define _m_pmaxuw _mm_max_pu16
+#define _m_pmaxud _mm_max_pu32
+#define _m_pminsb _mm_min_pi8
+#define _m_pminsw _mm_min_pi16
+#define _m_pminsd _mm_min_pi32
+#define _m_pminub _mm_min_pu8
+#define _m_pminuw _mm_min_pu16
+#define _m_pminud _mm_min_pu32
+#define _m_pmovmskb _mm_movemask_pi8
+#define _m_pmovmskw _mm_movemask_pi16
+#define _m_pmovmskd _mm_movemask_pi32
+#define _m_pshufw _mm_shuffle_pi16
+#define _m_pavgb _mm_avg_pu8
+#define _m_pavgw _mm_avg_pu16
+#define _m_pavg2b _mm_avg2_pu8
+#define _m_pavg2w _mm_avg2_pu16
+#define _m_psadbw _mm_sad_pu8
+#define _m_psadwd _mm_sad_pu16
+#define _m_psadzbw _mm_sadz_pu8
+#define _m_psadzwd _mm_sadz_pu16
+#define _m_paligniq _mm_align_si64
+#define _m_cvt_si2pi _mm_cvtsi64_m64
+#define _m_cvt_pi2si _mm_cvtm64_si64
+
+#endif /* _MMINTRIN_H_INCLUDED */
diff --git a/contrib/gcc/config/arm/netbsd-elf.h b/contrib/gcc/config/arm/netbsd-elf.h
index 0d5b798..a8b43f6 100644
--- a/contrib/gcc/config/arm/netbsd-elf.h
+++ b/contrib/gcc/config/arm/netbsd-elf.h
@@ -1,32 +1,28 @@
/* Definitions of target machine for GNU compiler, NetBSD/arm ELF version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (NetBSD/arm ELF)", stderr);
-/* This is used in ASM_FILE_START. */
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "NetBSD"
-
/* arm.h defaults to ARM6 CPU. */
/* This defaults us to little-endian. */
@@ -59,7 +55,7 @@ Boston, MA 02111-1307, USA. */
#undef SUBTARGET_EXTRA_ASM_SPEC
#define SUBTARGET_EXTRA_ASM_SPEC \
- "-matpcs %{fpic:-k} %{fPIC:-k}"
+ "-matpcs %{fpic|fpie:-k} %{fPIC|fPIE:-k}"
/* Default floating point model is soft-VFP.
FIXME: -mhard-float currently implies FPA. */
@@ -127,7 +123,7 @@ Boston, MA 02111-1307, USA. */
This has several side effects that should be considered.
1. Structures will only be aligned to the size of the largest member.
i.e. structures containing only bytes will be byte aligned.
- structures containing shorts will be half word alinged.
+ structures containing shorts will be half word aligned.
structures containing ints will be word aligned.
This means structures should be padded to a word boundary if
diff --git a/contrib/gcc/config/arm/netbsd.h b/contrib/gcc/config/arm/netbsd.h
index 38ccc3f..71763e6 100644
--- a/contrib/gcc/config/arm/netbsd.h
+++ b/contrib/gcc/config/arm/netbsd.h
@@ -1,32 +1,28 @@
/* NetBSD/arm a.out version.
- Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1997, 1998, 2003 Free Software Foundation, Inc.
Contributed by Mark Brinicombe (amb@physig.ph.kcl.ac.uk)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (ARM/NetBSD)", stderr);
-/* This is used in ASM_FILE_START. */
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "NetBSD"
-
/* Unsigned chars produces much better code than signed. */
#define DEFAULT_SIGNED_CHAR 0
@@ -40,7 +36,7 @@ Boston, MA 02111-1307, USA. */
/* Default is to use APCS-32 mode. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
/* Some defines for CPP.
arm32 is the NetBSD port name, so we always define arm32 and __arm32__. */
@@ -103,7 +99,7 @@ Boston, MA 02111-1307, USA. */
#undef TYPE_OPERAND_FMT
#define TYPE_OPERAND_FMT "%%%s"
-/* NetBSD uses the old PCC style aggregate returning conventions. */
+/* NetBSD uses the old PCC style aggregate returning conventions. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
@@ -130,7 +126,7 @@ Boston, MA 02111-1307, USA. */
This has several side effects that should be considered.
1. Structures will only be aligned to the size of the largest member.
i.e. structures containing only bytes will be byte aligned.
- structures containing shorts will be half word alinged.
+ structures containing shorts will be half word aligned.
structures containing ints will be word aligned.
This means structures should be padded to a word boundary if
diff --git a/contrib/gcc/config/arm/pe.c b/contrib/gcc/config/arm/pe.c
index ee3da8f..d25fd0d 100644
--- a/contrib/gcc/config/arm/pe.c
+++ b/contrib/gcc/config/arm/pe.c
@@ -2,25 +2,27 @@
Copyright (C) 1995, 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "output.h"
#include "flags.h"
@@ -165,7 +167,7 @@ arm_mark_dllimport (decl)
&& !DECL_VIRTUAL_P (decl)
&& DECL_INITIAL (decl))
{
- error_with_decl (decl, "initialized variable `%s' is marked dllimport");
+ error ("%Jinitialized variable '%D' is marked dllimport", decl, decl);
return;
}
/* Nor can they be static. */
@@ -174,7 +176,7 @@ arm_mark_dllimport (decl)
&& !DECL_VIRTUAL_P (decl)
&& 0 /*???*/)
{
- error_with_decl (decl, "static variable `%s' is marked dllimport");
+ error ("%Jstatic variable '%D' is marked dllimport", decl, decl);
return;
}
@@ -205,18 +207,15 @@ arm_mark_dllimport (decl)
}
void
-arm_pe_encode_section_info (decl, first)
+arm_pe_encode_section_info (decl, rtl, first)
tree decl;
+ rtx rtl;
int first ATTRIBUTE_UNUSED;
{
/* This bit is copied from arm_encode_section_info. */
if (optimize > 0 && TREE_CONSTANT (decl)
&& (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
- {
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
- }
+ SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
/* Mark the decl so we can tell from the rtl whether the object is
dllexport'd or dllimport'd. */
diff --git a/contrib/gcc/config/arm/pe.h b/contrib/gcc/config/arm/pe.h
index 38727da..e83f97b 100644
--- a/contrib/gcc/config/arm/pe.h
+++ b/contrib/gcc/config/arm/pe.h
@@ -1,23 +1,23 @@
/* Definitions of target machine for GNU compiler, for ARM with PE obj format.
- Copyright (C) 1995, 1996, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Enable PE specific code. */
#define ARM_PE 1
@@ -65,34 +65,30 @@ Boston, MA 02111-1307, USA. */
N_("Ignore dllimport attribute for functions") }, \
{ "no-nop-fun-dllimport", - TARGET_FLAG_NOP_FUN, "" },
+/* Defaulting to APCS-26 support is a legacy issue. It has been done
+ that way for a long time, so changing it will probably break some
+ people's worlds. Support for APCS-32 is now enabled as a multilib,
+ and at some point in the future APCS-32 may become the default.
+ Possibly when chips that support APCS-26 are no longer made. */
+
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN | ARM_FLAG_MMU_TRAPS)
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS \
+ { "marm", "mlittle-endian", "msoft-float", "mapcs-26", "mno-thumb-interwork" }
#undef WCHAR_TYPE
#define WCHAR_TYPE "short unsigned int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 16
-/* Same as arm.h except r10 is call-saved, not fixed. */
-#undef FIXED_REGISTERS
-#define FIXED_REGISTERS \
-{ \
- 0,0,0,0,0,0,0,0, \
- 0,0,0,1,0,1,0,1, \
- 0,0,0,0,0,0,0,0, \
- 1,1,1 \
-}
+/* r11 is fixed. */
+#undef SUBTARGET_CONDITIONAL_REGISTER_USAGE
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
+ fixed_regs [11] = 1; \
+ call_used_regs [11] = 1;
-/* Same as arm.h except r10 is call-saved, not fixed. */
-#undef CALL_USED_REGISTERS
-#define CALL_USED_REGISTERS \
-{ \
- 1,1,1,1,0,0,0,0, \
- 0,0,0,1,1,1,1,1, \
- 1,1,1,1,0,0,0,0, \
- 1,1,1 \
-}
/* Define this macro if in some cases global symbols from one translation
unit may not be bound to undefined symbols in another translation unit
@@ -105,20 +101,10 @@ Boston, MA 02111-1307, USA. */
#define SUPPORTS_ONE_ONLY 1
/* Switch into a generic section. */
-#undef TARGET_ASM_NAMED_SECTION
+#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION default_pe_asm_named_section
-/* This outputs a lot of .req's to define alias for various registers.
- Let's try to avoid this. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
- do \
- { \
- asm_fprintf (STREAM, "%@ Generated by gcc %s for ARM/pe\n",\
- version_string); \
- output_file_directive ((STREAM), main_input_filename); \
- } \
- while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* Output a reference to a label. */
#undef ASM_OUTPUT_LABELREF
@@ -160,7 +146,7 @@ Boston, MA 02111-1307, USA. */
fprintf ((STREAM), "\t.comm\t"); \
assemble_name ((STREAM), (NAME)); \
asm_fprintf ((STREAM), ", %d\t%@ %d\n", \
- (ROUNDED), (SIZE)); \
+ (int)(ROUNDED), (int)(SIZE)); \
} \
} \
while (0)
@@ -201,7 +187,7 @@ Boston, MA 02111-1307, USA. */
#define DRECTVE_SECTION_FUNCTION \
void \
-drectve_section () \
+drectve_section (void) \
{ \
if (in_section != in_drectve) \
{ \
@@ -217,11 +203,8 @@ drectve_section () \
ASM_DECLARE_OBJECT_NAME and then switch back to the original section
afterwards. */
#define SWITCH_TO_SECTION_FUNCTION \
-static void switch_to_section PARAMS ((enum in_section, tree)); \
static void \
-switch_to_section (section, decl) \
- enum in_section section; \
- tree decl; \
+switch_to_section (enum in_section section, tree decl) \
{ \
switch (section) \
{ \
@@ -235,3 +218,4 @@ switch_to_section (section, decl) \
default: abort (); break; \
} \
}
+
diff --git a/contrib/gcc/config/arm/rtems-elf.h b/contrib/gcc/config/arm/rtems-elf.h
index 27928db..a736ee1 100644
--- a/contrib/gcc/config/arm/rtems-elf.h
+++ b/contrib/gcc/config/arm/rtems-elf.h
@@ -1,22 +1,22 @@
/* Definitions for RTEMS based ARM systems using ELF
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
@@ -27,6 +27,5 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_define ("__rtems__"); \
- builtin_define ("__ELF__"); \
builtin_assert ("system=rtems"); \
} while (0)
diff --git a/contrib/gcc/config/arm/semi.h b/contrib/gcc/config/arm/semi.h
index 2e1abd4..2ab06cb 100644
--- a/contrib/gcc/config/arm/semi.h
+++ b/contrib/gcc/config/arm/semi.h
@@ -2,22 +2,22 @@
Copyright (C) 1994, 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (richard.earnshaw@arm.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#define STARTFILE_SPEC "crt0.o%s"
@@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA. */
#endif
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
#ifndef SUBTARGET_EXTRA_SPECS
@@ -59,12 +59,12 @@ Boston, MA 02111-1307, USA. */
binutils can't. */
#ifndef ASM_SPEC
#define ASM_SPEC "\
-%{fpic: -k} %{fPIC: -k} \
+%{fpic|fpie: -k} %{fPIC|fPIE: -k} \
%{mbig-endian:-EB} \
%{mcpu=*:-mcpu=%*} \
%{march=*:-march=%*} \
%{mapcs-float:-mfloat} \
-%{msoft-float:-mno-fpu} \
+%{msoft-float:-mfpu=softfpa} \
%{mthumb-interwork:-mthumb-interwork} \
%(subtarget_extra_asm_spec)"
#endif
diff --git a/contrib/gcc/config/arm/semiaof.h b/contrib/gcc/config/arm/semiaof.h
index 6ee17ef..19a6cf8 100644
--- a/contrib/gcc/config/arm/semiaof.h
+++ b/contrib/gcc/config/arm/semiaof.h
@@ -3,22 +3,22 @@
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (richard.earnshaw@armltd.co.uk)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
@@ -33,9 +33,9 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fputs (" (ARM/semi-hosted)", stderr);
-#define TARGET_DEFAULT ARM_FLAG_APCS_32
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
-/* The Norcroft C library defines size_t as "unsigned int" */
+/* The Norcroft C library defines size_t as "unsigned int". */
#define SIZE_TYPE "unsigned int"
#undef CPP_APCS_PC_DEFAULT_SPEC
diff --git a/contrib/gcc/config/arm/strongarm-coff.h b/contrib/gcc/config/arm/strongarm-coff.h
index 4d2f292..77dab37 100644
--- a/contrib/gcc/config/arm/strongarm-coff.h
+++ b/contrib/gcc/config/arm/strongarm-coff.h
@@ -2,22 +2,22 @@
Copyright (C) 1999 Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#ifndef SUBTARGET_CPU_DEFAULT
diff --git a/contrib/gcc/config/arm/strongarm-elf.h b/contrib/gcc/config/arm/strongarm-elf.h
index 3fc8487..476b2e4 100644
--- a/contrib/gcc/config/arm/strongarm-elf.h
+++ b/contrib/gcc/config/arm/strongarm-elf.h
@@ -2,22 +2,22 @@
Copyright (C) 1999, 2001 Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#ifndef TARGET_VERSION
diff --git a/contrib/gcc/config/arm/strongarm-pe.h b/contrib/gcc/config/arm/strongarm-pe.h
index 2938d3e..bb123e5 100644
--- a/contrib/gcc/config/arm/strongarm-pe.h
+++ b/contrib/gcc/config/arm/strongarm-pe.h
@@ -2,22 +2,22 @@
Copyright (C) 1999 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (StrongARM/PE)", stderr);
diff --git a/contrib/gcc/config/arm/t-arm-coff b/contrib/gcc/config/arm/t-arm-coff
index bf37a37..8eef976 100644
--- a/contrib/gcc/config/arm/t-arm-coff
+++ b/contrib/gcc/config/arm/t-arm-coff
@@ -28,7 +28,7 @@ EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
-# Currently there is a bug somwehere in GCC's alias analysis
+# Currently there is a bug somewhere in GCC's alias analysis
# or scheduling code that is breaking _fpmul_parts in fp-bit.c.
# Disabling function inlining is a workaround for this problem.
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline
diff --git a/contrib/gcc/config/arm/t-arm-elf b/contrib/gcc/config/arm/t-arm-elf
index 0011b2a..3f48f8b 100644
--- a/contrib/gcc/config/arm/t-arm-elf
+++ b/contrib/gcc/config/arm/t-arm-elf
@@ -1,34 +1,22 @@
LIB1ASMSRC = arm/lib1funcs.asm
-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \
+ _call_via_rX _interwork_call_via_rX \
+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
+ _fixsfsi _fixunssfsi
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- echo '#ifndef __ARMEB__' >> fp-bit.c
- echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
- echo '#endif' >> fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#ifndef __ARMEB__' > dp-bit.c
- echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
- echo '#define FLOAT_WORD_ORDER_MISMATCH' >> dp-bit.c
- echo '#endif' >> dp-bit.c
- cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-
-
MULTILIB_OPTIONS = marm/mthumb
MULTILIB_DIRNAMES = arm thumb
MULTILIB_EXCEPTIONS =
+MULTILIB_MATCHES =
+
+# MULTILIB_OPTIONS += mcpu=ep9312
+# MULTILIB_DIRNAMES += ep9312
+# MULTILIB_EXCEPTIONS += *mthumb/*mcpu=ep9312*
# MULTILIB_OPTIONS += mlittle-endian/mbig-endian
# MULTILIB_DIRNAMES += le be
-# MULTILIB_EXCEPTIONS =
-# MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle
+# MULTILIB_MATCHES += mbig-endian=mbe mlittle-endian=mle
#
# MULTILIB_OPTIONS += mhard-float/msoft-float
# MULTILIB_DIRNAMES += fpu soft
@@ -93,3 +81,4 @@ $(T)crti.o: $(srcdir)/config/arm/crti.asm $(GCC_PASSES)
$(T)crtn.o: $(srcdir)/config/arm/crtn.asm $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/arm/crtn.asm
+
diff --git a/contrib/gcc/config/arm/t-linux b/contrib/gcc/config/arm/t-linux
index 7dbd0c0..1c5f48a 100644
--- a/contrib/gcc/config/arm/t-linux
+++ b/contrib/gcc/config/arm/t-linux
@@ -3,9 +3,6 @@
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
LIBGCC2_DEBUG_CFLAGS = -g0
-# Don't build enquire
-ENQUIRE=
-
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
diff --git a/contrib/gcc/config/arm/t-netbsd b/contrib/gcc/config/arm/t-netbsd
index 76e431b..77e6227 100644
--- a/contrib/gcc/config/arm/t-netbsd
+++ b/contrib/gcc/config/arm/t-netbsd
@@ -19,8 +19,3 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
SHLIB_INSTALL = $(INSTALL_DATA) $(SHLIB_NAME) $$(DESTDIR)$$(slibdir)/$(SHLIB_SONAME); \
rm -f $$(DESTDIR)$$(slibdir)/$(SHLIB_NAME); \
$(LN_S) $(SHLIB_SONAME) $$(DESTDIR)$$(slibdir)/$(SHLIB_NAME)
-
-# Don't build enquire
-ENQUIRE=
-
-
diff --git a/contrib/gcc/config/arm/t-pe b/contrib/gcc/config/arm/t-pe
index f559bd2..4c20b31 100644
--- a/contrib/gcc/config/arm/t-pe
+++ b/contrib/gcc/config/arm/t-pe
@@ -20,12 +20,12 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-pe.o: $(srcdir)/config/arm/pe.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) output.h \
- flags.h $(TREE_H) $(EXPR_H) toplev.h $(TM_P_H)
+pe.o: $(srcdir)/config/arm/pe.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) output.h flags.h $(TREE_H) expr.h toplev.h $(TM_P_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/arm/pe.c
-MULTILIB_OPTIONS = mhard-float mthumb
-MULTILIB_DIRNAMES = fpu thumb
+MULTILIB_OPTIONS = mhard-float mthumb mapcs-32
+MULTILIB_DIRNAMES = fpu thumb apcs32
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
diff --git a/contrib/gcc/config/arm/t-semi b/contrib/gcc/config/arm/t-semi
index ce39460..abd642c 100644
--- a/contrib/gcc/config/arm/t-semi
+++ b/contrib/gcc/config/arm/t-semi
@@ -3,15 +3,9 @@
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer
LIBGCC2_DEBUG_CFLAGS = -g0
-# Don't build enquire
-ENQUIRE=
-
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX _interwork_call_via_rX
-#Don't try to run fixproto
-STMP_FIXPROTO =
-
# We want fine grained libraries, so use the new code to build the
# floating point emulation libraries.
FPBIT = fp-bit.c
diff --git a/contrib/gcc/config/arm/t-strongarm-pe b/contrib/gcc/config/arm/t-strongarm-pe
index 6a44132..e401666 100644
--- a/contrib/gcc/config/arm/t-strongarm-pe
+++ b/contrib/gcc/config/arm/t-strongarm-pe
@@ -20,7 +20,8 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-pe.o: $(srcdir)/config/arm/pe.c
+pe.o: $(srcdir)/config/arm/pe.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) output.h flags.h $(TREE_H) expr.h toplev.h $(TM_P_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/arm/pe.c
MULTILIB_OPTIONS = mhard-float/msoft-float
@@ -31,7 +32,7 @@ EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
-# Currently there is a bug somwehere in GCC's alias analysis
+# Currently there is a bug somewhere in GCC's alias analysis
# or scheduling code that is breaking _fpmul_parts in fp-bit.c.
# Disabling function inlining is a workaround for this problem.
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline
diff --git a/contrib/gcc/config/arm/t-vxworks b/contrib/gcc/config/arm/t-vxworks
new file mode 100644
index 0000000..e620cfd
--- /dev/null
+++ b/contrib/gcc/config/arm/t-vxworks
@@ -0,0 +1,10 @@
+# Multilibs for VxWorks.
+
+MULTILIB_OPTIONS = \
+ t4/t4be/t4t/t4tbe/t5/t5be/t5t/t5tbe/txscale/txscalebe
+
+MULTILIB_DIRNAMES = \
+ ARMARCH4gnu ARMARCH4gnube ARMARCH4_Tgnu ARMARCH4_Tgnube \
+ ARMARCH5gnu ARMARCH5gnube ARMARCH5_Tgnu ARMARCH5_Tgnube \
+ XSCALEgnu XSCALEgnube
+
diff --git a/contrib/gcc/config/arm/t-wince-pe b/contrib/gcc/config/arm/t-wince-pe
new file mode 100644
index 0000000..9537a7f
--- /dev/null
+++ b/contrib/gcc/config/arm/t-wince-pe
@@ -0,0 +1,37 @@
+LIB1ASMSRC = arm/lib1funcs.asm
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX _interwork_call_via_rX
+
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ echo '#ifndef __ARMEB__' >> fp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
+ echo '#endif' >> fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#ifndef __ARMEB__' > dp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
+ echo '#define FLOAT_WORD_ORDER_MISMATCH' >> dp-bit.c
+ echo '#endif' >> dp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+
+pe.o: $(srcdir)/config/arm/pe.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) output.h flags.h $(TREE_H) expr.h toplev.h $(TM_P_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/arm/pe.c
+
+MULTILIB_OPTIONS = mhard-float mapcs-26
+MULTILIB_DIRNAMES = fpu apcs26
+# Note - Thumb multilib omitted because Thumb apcs32 support for
+# arm-wince-pe target does not appear to be working in binutils
+# yet...
+# MULTILIB_OPTIONS += thumb
+# MULTILIB_DIRNAMES += thumb
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc
diff --git a/contrib/gcc/config/arm/t-xscale-elf b/contrib/gcc/config/arm/t-xscale-elf
index 0efc1d5..b72c21c 100644
--- a/contrib/gcc/config/arm/t-xscale-elf
+++ b/contrib/gcc/config/arm/t-xscale-elf
@@ -37,6 +37,10 @@ MULTILIB_EXCEPTIONS += *mhard-float/*mthumb*
MULTILIB_REDUNDANT_DIRS = interwork/thumb=thumb
+MULTILIB_OPTIONS += mcpu=iwmmxt
+MULTILIB_DIRNAMES += iwmmxt
+MULTILIB_REDUNDANT_DIRS += interwork/thumb/iwmmxt=thumb
+
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
LIBGCC = stmp-multilib
diff --git a/contrib/gcc/config/arm/uclinux-elf.h b/contrib/gcc/config/arm/uclinux-elf.h
index cad61b7..e3cd48d 100644
--- a/contrib/gcc/config/arm/uclinux-elf.h
+++ b/contrib/gcc/config/arm/uclinux-elf.h
@@ -2,22 +2,22 @@
Copyright (C) 1999, 2001 Free Software Foundation, Inc.
Contributed by Philip Blundell <pb@nexus.co.uk>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* We don't want a PLT. */
#undef NEED_PLT_RELOC
diff --git a/contrib/gcc/config/arm/unknown-elf.h b/contrib/gcc/config/arm/unknown-elf.h
index 7f9211b..1af7994 100644
--- a/contrib/gcc/config/arm/unknown-elf.h
+++ b/contrib/gcc/config/arm/unknown-elf.h
@@ -1,23 +1,24 @@
/* Definitions for non-Linux based ARM systems using ELF
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* elfos.h should have already been included. Now just override
any conflicting definitions and add any extras. */
@@ -29,7 +30,7 @@ Boston, MA 02111-1307, USA. */
/* Default to using APCS-32 and software floating point. */
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
/* Now we define the strings used to build the spec file. */
@@ -42,7 +43,7 @@ Boston, MA 02111-1307, USA. */
/* The __USES_INITFINI__ define is tested in newlib/libc/sys/arm/crt0.S
to see if it needs to invoked _init() and _fini(). */
#undef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC "-D__ELF__ -D__USES_INITFINI__"
+#define SUBTARGET_CPP_SPEC "-D__USES_INITFINI__"
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
@@ -61,13 +62,11 @@ Boston, MA 02111-1307, USA. */
else \
bss_section (); \
\
- (*targetm.asm_out.globalize_label) (FILE, NAME); \
- \
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
\
last_assemble_variable_decl = DECL; \
ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL); \
- ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1); \
+ ASM_OUTPUT_SKIP (FILE, SIZE ? (int)(SIZE) : 1); \
} \
while (0)
@@ -82,7 +81,7 @@ Boston, MA 02111-1307, USA. */
\
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL (FILE, NAME); \
- fprintf (FILE, "\t.space\t%d\n", SIZE ? SIZE : 1); \
+ fprintf (FILE, "\t.space\t%d\n", SIZE ? (int)(SIZE) : 1); \
} \
while (0)
diff --git a/contrib/gcc/config/arm/vxworks.h b/contrib/gcc/config/arm/vxworks.h
new file mode 100644
index 0000000..afe6b70
--- /dev/null
+++ b/contrib/gcc/config/arm/vxworks.h
@@ -0,0 +1,95 @@
+/* Definitions of target machine for GCC,
+ for ARM with targetting the VXWorks run time environment.
+ Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+
+ Contributed by: Mike Stump <mrs@wrs.com>
+ Brought up to date by CodeSourcery, LLC.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#define TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__vxworks"); \
+ if (TARGET_BIG_END) \
+ builtin_define ("ARMEB"); \
+ else \
+ builtin_define ("ARMEL"); \
+ \
+ if (arm_is_xscale) \
+ builtin_define ("CPU=XSCALE"); \
+ else if (arm_arch5) \
+ builtin_define ("CPU=ARMARCH5"); \
+ else if (arm_arch4) \
+ { \
+ if (thumb_code) \
+ builtin_define ("CPU=ARMARCH4_T"); \
+ else \
+ builtin_define ("CPU=ARMARCH4"); \
+ } \
+ } while (0)
+
+#undef CC1_SPEC
+#define CC1_SPEC \
+"%{t4: -mapcs-32 -mlittle-endian -march=armv4 ; \
+ t4be: -mapcs-32 -mbig-endian -march=armv4 ; \
+ t4t: -mthumb -mthumb-interwork -mlittle-endian -march=armv4t ; \
+ t4tbe: -mthumb -mthumb-interwork -mbig-endian -march=armv4t ; \
+ t5: -mapcs-32 -mlittle-endian -march=armv5 ; \
+ t5be: -mapcs-32 -mbig-endian -march=armv5 ; \
+ t5t: -mthumb -mthumb-interwork -mlittle-endian -march=armv5 ; \
+ t5tbe: -mthumb -mthumb-interwork -mbig-endian -march=armv5 ; \
+ txscale: -mapcs-32 -mlittle-endian -mcpu=xscale ; \
+ txscalebe: -mapcs-32 -mbig-endian -mcpu=xscale ; \
+ : -march=armv4}"
+
+/* The -Q options from svr4.h aren't understood and must be removed. */
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
+
+/* VxWorks does all the library stuff itself. */
+#undef LIB_SPEC
+#define LIB_SPEC ""
+
+/* VxWorks uses object files, not loadable images. make linker just
+ combine objects. */
+#undef LINK_SPEC
+#define LINK_SPEC "-r"
+
+/* VxWorks provides the functionality of crt0.o and friends itself. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC ""
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (ARM/VxWorks)", stderr);
+
+/* There is no default multilib. */
+#undef MULTILIB_DEFAULTS
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(STREAM) \
+ do \
+ { \
+ fprintf (STREAM, "%s Generated by GCC %s for ARM/VxWorks\n", \
+ ASM_COMMENT_START, version_string); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/arm/wince-pe.h b/contrib/gcc/config/arm/wince-pe.h
new file mode 100644
index 0000000..fb47485
--- /dev/null
+++ b/contrib/gcc/config/arm/wince-pe.h
@@ -0,0 +1,29 @@
+/* Definitions of target machine for GNU compiler, for ARM with WINCE-PE obj format.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Nick Clifton <nickc@redhat.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 2, 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 COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Override arm/pe.h's default apcs26 support. */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN | ARM_FLAG_MMU_TRAPS)
+
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS \
+ { "marm", "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork" }
diff --git a/contrib/gcc/config/arm/xscale-elf.h b/contrib/gcc/config/arm/xscale-elf.h
index 8ea3588..aea8360 100644
--- a/contrib/gcc/config/arm/xscale-elf.h
+++ b/contrib/gcc/config/arm/xscale-elf.h
@@ -2,22 +2,22 @@
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#ifndef TARGET_VERSION
@@ -28,7 +28,30 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_xscale
#endif
-#define SUBTARGET_EXTRA_ASM_SPEC "%{!mcpu=*:-mcpu=xscale} %{!mhard-float:-mno-fpu}"
+/* Note - there are three possible -mfpu= arguments that can be passed to
+ the assembler:
+
+ -mfpu=softvfp This is the default. It indicates thats doubles are
+ stored in a format compatible with the VFP
+ specification. This is the newer double format, whereby
+ the endian-ness of the doubles matches the endian-ness
+ of the memory architecture.
+
+ -mfpu=fpa This is when -mhard-float is specified.
+ [It is not known if any XScale's have been made with
+ hardware floating point support, but nevertheless this
+ is what happens].
+
+ -mfpu=softfpa This is when -msoft-float is specified.
+ This is the normal behavior of other arm configurations,
+ which for backwards compatibility purposes default to
+ supporting the old FPA format which was always big
+ endian, regardless of the endian-ness of the memory
+ system. */
+
+#define SUBTARGET_EXTRA_ASM_SPEC "%{!mcpu=*:-mcpu=xscale} \
+ %{mhard-float:-mfpu=fpa} \
+ %{!mhard-float: %{msoft-float:-mfpu=softfpa;:-mfpu=softvfp}}"
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \
diff --git a/contrib/gcc/config/darwin-c.c b/contrib/gcc/config/darwin-c.c
index c04c2b5..fb51455 100644
--- a/contrib/gcc/config/darwin-c.c
+++ b/contrib/gcc/config/darwin-c.c
@@ -1,27 +1,28 @@
/* Darwin support needed only by C/C++ frontends.
- Copyright (C) 2001
- Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "cpplib.h"
#include "tree.h"
#include "c-pragma.h"
@@ -36,8 +37,8 @@ Boston, MA 02111-1307, USA. */
/* Maintain a small stack of alignments. This is similar to pragma
pack's stack, but simpler. */
-static void push_field_alignment PARAMS ((int));
-static void pop_field_alignment PARAMS ((void));
+static void push_field_alignment (int);
+static void pop_field_alignment (void);
typedef struct align_stack
{
@@ -48,8 +49,7 @@ typedef struct align_stack
static struct align_stack * field_align_stack = NULL;
static void
-push_field_alignment (bit_alignment)
- int bit_alignment;
+push_field_alignment (int bit_alignment)
{
align_stack *entry = (align_stack *) xmalloc (sizeof (align_stack));
@@ -61,7 +61,7 @@ push_field_alignment (bit_alignment)
}
static void
-pop_field_alignment ()
+pop_field_alignment (void)
{
if (field_align_stack)
{
@@ -78,8 +78,7 @@ pop_field_alignment ()
/* Handlers for Darwin-specific pragmas. */
void
-darwin_pragma_ignore (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+darwin_pragma_ignore (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
/* Do nothing. */
}
@@ -87,8 +86,7 @@ darwin_pragma_ignore (pfile)
/* #pragma options align={mac68k|power|reset} */
void
-darwin_pragma_options (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+darwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
const char *arg;
tree t, x;
@@ -120,8 +118,7 @@ darwin_pragma_options (pfile)
/* #pragma unused ([var {, var}*]) */
void
-darwin_pragma_unused (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+darwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
tree decl, x;
int tok;
@@ -134,7 +131,7 @@ darwin_pragma_unused (pfile)
tok = c_lex (&decl);
if (tok == CPP_NAME && decl)
{
- tree local = IDENTIFIER_LOCAL_VALUE (decl);
+ tree local = lookup_name (decl);
if (local && (TREE_CODE (local) == PARM_DECL
|| TREE_CODE (local) == VAR_DECL))
TREE_USED (local) = 1;
diff --git a/contrib/gcc/config/darwin-protos.h b/contrib/gcc/config/darwin-protos.h
index 5fea152..41bad64 100644
--- a/contrib/gcc/config/darwin-protos.h
+++ b/contrib/gcc/config/darwin-protos.h
@@ -1,119 +1,123 @@
/* Prototypes.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-extern int name_needs_quotes PARAMS ((const char *));
+extern int name_needs_quotes (const char *);
-extern void machopic_validate_stub_or_non_lazy_ptr PARAMS ((const char *, int));
+extern void machopic_validate_stub_or_non_lazy_ptr (const char *, int);
-extern const char *machopic_function_base_name PARAMS ((void));
-extern const char *machopic_non_lazy_ptr_name PARAMS ((const char*));
-extern const char *machopic_stub_name PARAMS ((const char*));
+extern const char *machopic_function_base_name (void);
+extern void machopic_output_function_base_name (FILE *);
+extern const char *machopic_stub_name (const char*);
-extern void machopic_picsymbol_stub_section PARAMS ((void));
-extern void machopic_symbol_stub_section PARAMS ((void));
-extern void machopic_lazy_symbol_ptr_section PARAMS ((void));
-extern void machopic_nl_symbol_ptr_section PARAMS ((void));
+extern void machopic_picsymbol_stub_section (void);
+extern void machopic_picsymbol_stub1_section (void);
+extern void machopic_symbol_stub_section (void);
+extern void machopic_symbol_stub1_section (void);
+extern void machopic_lazy_symbol_ptr_section (void);
+extern void machopic_nl_symbol_ptr_section (void);
-extern void constructor_section PARAMS ((void));
-extern void destructor_section PARAMS ((void));
-extern void mod_init_section PARAMS ((void));
-extern void mod_term_section PARAMS ((void));
+extern void constructor_section (void);
+extern void destructor_section (void);
+extern void mod_init_section (void);
+extern void mod_term_section (void);
#ifdef RTX_CODE
-extern int machopic_operand_p PARAMS ((rtx));
-extern enum machopic_addr_class machopic_classify_name PARAMS ((const char*));
+extern int machopic_operand_p (rtx);
+extern enum machopic_addr_class machopic_classify_name (const char*);
-extern rtx machopic_indirect_data_reference PARAMS ((rtx, rtx));
-extern rtx machopic_indirect_call_target PARAMS ((rtx));
-extern rtx machopic_legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
+extern rtx machopic_indirect_data_reference (rtx, rtx);
+extern rtx machopic_indirect_call_target (rtx);
+extern rtx machopic_legitimize_pic_address (rtx, enum machine_mode, rtx);
-extern void machopic_asm_out_constructor PARAMS ((rtx, int));
-extern void machopic_asm_out_destructor PARAMS ((rtx, int));
+extern void machopic_asm_out_constructor (rtx, int);
+extern void machopic_asm_out_destructor (rtx, int);
#endif /* RTX_CODE */
#ifdef TREE_CODE
-extern enum machopic_addr_class machopic_classify_ident PARAMS ((tree));
-extern void machopic_define_ident PARAMS ((tree));
-extern void machopic_define_name PARAMS ((const char*));
-extern int machopic_name_defined_p PARAMS ((const char*));
-extern int machopic_ident_defined_p PARAMS ((tree));
-extern void darwin_encode_section_info PARAMS ((tree, int));
-extern const char *darwin_strip_name_encoding PARAMS ((const char *));
+extern enum machopic_addr_class machopic_classify_ident (tree);
+extern void machopic_define_ident (tree);
+extern void machopic_define_name (const char*);
+extern int machopic_name_defined_p (const char*);
+extern int machopic_ident_defined_p (tree);
+extern void darwin_encode_section_info (tree, rtx, int);
+extern const char *darwin_strip_name_encoding (const char *);
#endif /* TREE_CODE */
-extern void machopic_finish PARAMS ((FILE *));
+extern void machopic_finish (FILE *);
-extern void machopic_output_possible_stub_label PARAMS ((FILE *, const char*));
+extern void machopic_output_possible_stub_label (FILE *, const char*);
-extern void darwin_exception_section PARAMS ((void));
-extern void darwin_eh_frame_section PARAMS ((void));
-extern void machopic_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-extern void machopic_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
+extern void darwin_exception_section (void);
+extern void darwin_eh_frame_section (void);
+extern void machopic_select_section (tree, int, unsigned HOST_WIDE_INT);
+extern void machopic_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
-#ifdef GCC_C_PRAGMA_H
-extern void darwin_pragma_ignore PARAMS ((cpp_reader *));
-extern void darwin_pragma_options PARAMS ((cpp_reader *));
-extern void darwin_pragma_unused PARAMS ((cpp_reader *));
-#endif
+extern void darwin_pragma_ignore (struct cpp_reader *);
+extern void darwin_pragma_options (struct cpp_reader *);
+extern void darwin_pragma_unused (struct cpp_reader *);
+
+extern void darwin_file_end (void);
/* Expanded by EXTRA_SECTION_FUNCTIONS into varasm.o. */
-extern void const_section PARAMS ((void));
-extern void const_data_section PARAMS ((void));
-extern void cstring_section PARAMS ((void));
-extern void literal4_section PARAMS ((void));
-extern void literal8_section PARAMS ((void));
-extern void constructor_section PARAMS ((void));
-extern void mod_init_section PARAMS ((void));
-extern void mod_term_section PARAMS ((void));
-extern void destructor_section PARAMS ((void));
-extern void objc_class_section PARAMS ((void));
-extern void objc_meta_class_section PARAMS ((void));
-extern void objc_category_section PARAMS ((void));
-extern void objc_class_vars_section PARAMS ((void));
-extern void objc_instance_vars_section PARAMS ((void));
-extern void objc_cls_meth_section PARAMS ((void));
-extern void objc_inst_meth_section PARAMS ((void));
-extern void objc_cat_cls_meth_section PARAMS ((void));
-extern void objc_cat_inst_meth_section PARAMS ((void));
-extern void objc_selector_refs_section PARAMS ((void));
-extern void objc_selector_fixup_section PARAMS ((void));
-extern void objc_symbols_section PARAMS ((void));
-extern void objc_module_info_section PARAMS ((void));
-extern void objc_protocol_section PARAMS ((void));
-extern void objc_string_object_section PARAMS ((void));
-extern void objc_constant_string_object_section PARAMS ((void));
-extern void objc_class_names_section PARAMS ((void));
-extern void objc_meth_var_names_section PARAMS ((void));
-extern void objc_meth_var_types_section PARAMS ((void));
-extern void objc_cls_refs_section PARAMS ((void));
-extern void machopic_lazy_symbol_ptr_section PARAMS ((void));
-extern void machopic_nl_symbol_ptr_section PARAMS ((void));
-extern void machopic_symbol_stub_section PARAMS ((void));
-extern void machopic_picsymbol_stub_section PARAMS ((void));
-extern void machopic_output_stub PARAMS ((FILE *, const char *, const char *));
-extern void darwin_exception_section PARAMS ((void));
-extern void darwin_eh_frame_section PARAMS ((void));
-extern void darwin_globalize_label PARAMS ((FILE *, const char *));
-extern void darwin_asm_output_dwarf_delta PARAMS ((FILE *, int, const char *, const char *));
+extern void const_section (void);
+extern void const_data_section (void);
+extern void cstring_section (void);
+extern void literal4_section (void);
+extern void literal8_section (void);
+extern void constructor_section (void);
+extern void mod_init_section (void);
+extern void mod_term_section (void);
+extern void destructor_section (void);
+extern void objc_class_section (void);
+extern void objc_meta_class_section (void);
+extern void objc_category_section (void);
+extern void objc_class_vars_section (void);
+extern void objc_instance_vars_section (void);
+extern void objc_cls_meth_section (void);
+extern void objc_inst_meth_section (void);
+extern void objc_cat_cls_meth_section (void);
+extern void objc_cat_inst_meth_section (void);
+extern void objc_selector_refs_section (void);
+extern void objc_selector_fixup_section (void);
+extern void objc_symbols_section (void);
+extern void objc_module_info_section (void);
+extern void objc_image_info_section (void);
+extern void objc_protocol_section (void);
+extern void objc_string_object_section (void);
+extern void objc_constant_string_object_section (void);
+extern void objc_class_names_section (void);
+extern void objc_meth_var_names_section (void);
+extern void objc_meth_var_types_section (void);
+extern void objc_cls_refs_section (void);
+extern void machopic_lazy_symbol_ptr_section (void);
+extern void machopic_nl_symbol_ptr_section (void);
+extern void machopic_symbol_stub_section (void);
+extern void machopic_picsymbol_stub_section (void);
+extern void machopic_output_stub (FILE *, const char *, const char *);
+extern void darwin_exception_section (void);
+extern void darwin_eh_frame_section (void);
+extern void darwin_globalize_label (FILE *, const char *);
+extern void darwin_assemble_visibility (tree, int);
+extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
+ const char *);
diff --git a/contrib/gcc/config/darwin.c b/contrib/gcc/config/darwin.c
index 8efd8cd..8005ecd 100644
--- a/contrib/gcc/config/darwin.c
+++ b/contrib/gcc/config/darwin.c
@@ -1,27 +1,29 @@
/* Functions for generic Darwin as target machine for GNU C compiler.
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -39,23 +41,24 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "langhooks.h"
#include "tm_p.h"
+#include "errors.h"
-static int machopic_data_defined_p PARAMS ((const char *));
-static void update_non_lazy_ptrs PARAMS ((const char *));
-static void update_stubs PARAMS ((const char *));
+static int machopic_data_defined_p (const char *);
+static void update_non_lazy_ptrs (const char *);
+static void update_stubs (const char *);
+static const char *machopic_non_lazy_ptr_name (const char*);
int
-name_needs_quotes (name)
- const char *name;
+name_needs_quotes (const char *name)
{
int c;
while ((c = *name++) != '\0')
- if (! ISIDNUM (c))
+ if (! ISIDNUM (c) && c != '.' && c != '$')
return 1;
return 0;
}
-/*
+/*
* flag_pic = 1 ... generate only indirections
* flag_pic = 2 ... generate indirections and pure code
*/
@@ -66,20 +69,23 @@ name_needs_quotes (name)
static GTY(()) tree machopic_defined_list;
enum machopic_addr_class
-machopic_classify_ident (ident)
- tree ident;
+machopic_classify_ident (tree ident)
{
const char *name = IDENTIFIER_POINTER (ident);
int lprefix = (((name[0] == '*' || name[0] == '&')
&& (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
- || ( name[0] == '_'
- && name[1] == 'O'
- && name[2] == 'B'
+ || ( name[0] == '_'
+ && name[1] == 'O'
+ && name[2] == 'B'
&& name[3] == 'J'
&& name[4] == 'C'
&& name[5] == '_'));
tree temp;
+ /* The PIC base symbol is always defined. */
+ if (! strcmp (name, "<pic base>"))
+ return MACHOPIC_DEFINED_DATA;
+
if (name[0] != '!')
{
/* Here if no special encoding to be found. */
@@ -140,7 +146,7 @@ machopic_classify_ident (ident)
return MACHOPIC_DEFINED_DATA;
}
}
-
+
if (name[1] == 't' || name[1] == 'T')
{
if (lprefix)
@@ -157,17 +163,15 @@ machopic_classify_ident (ident)
}
}
-
+
enum machopic_addr_class
-machopic_classify_name (name)
- const char *name;
+machopic_classify_name (const char *name)
{
return machopic_classify_ident (get_identifier (name));
}
int
-machopic_ident_defined_p (ident)
- tree ident;
+machopic_ident_defined_p (tree ident)
{
switch (machopic_classify_ident (ident))
{
@@ -181,8 +185,7 @@ machopic_ident_defined_p (ident)
}
static int
-machopic_data_defined_p (name)
- const char *name;
+machopic_data_defined_p (const char *name)
{
switch (machopic_classify_ident (get_identifier (name)))
{
@@ -194,63 +197,65 @@ machopic_data_defined_p (name)
}
int
-machopic_name_defined_p (name)
- const char *name;
+machopic_name_defined_p (const char *name)
{
return machopic_ident_defined_p (get_identifier (name));
}
void
-machopic_define_ident (ident)
- tree ident;
+machopic_define_ident (tree ident)
{
if (!machopic_ident_defined_p (ident))
- machopic_defined_list =
+ machopic_defined_list =
tree_cons (NULL_TREE, ident, machopic_defined_list);
}
void
-machopic_define_name (name)
- const char *name;
+machopic_define_name (const char *name)
{
machopic_define_ident (get_identifier (name));
}
-/* This is a static to make inline functions work. The rtx
- representing the PIC base symbol always points to here. */
-
-static char function_base[32];
-
-static int current_pic_label_num;
+static GTY(()) char * function_base;
const char *
-machopic_function_base_name ()
+machopic_function_base_name (void)
{
- static const char *name = NULL;
- static const char *current_name;
+ const char *current_name;
+ /* if dynamic-no-pic is on, we should not get here */
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ abort ();
+ current_name =
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
+
+ if (function_base == NULL)
+ function_base =
+ (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
+
+ current_function_uses_pic_offset_table = 1;
+
+ return function_base;
+}
- current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
+static GTY(()) const char * function_base_func_name;
+static GTY(()) int current_pic_label_num;
- if (name != current_name)
+void
+machopic_output_function_base_name (FILE *file)
+{
+ const char *current_name;
+
+ /* If dynamic-no-pic is on, we should not get here. */
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ abort ();
+ current_name =
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
+ if (function_base_func_name != current_name)
{
- current_function_uses_pic_offset_table = 1;
-
- /* Save mucho space and time. Some of the C++ mangled names are over
- 700 characters long! Note that we produce a label containing a '-'
- if the function we're compiling is an Objective-C method, as evinced
- by the incredibly scientific test below. This is because code in
- rs6000.c makes the same ugly test when loading the PIC reg. */
-
++current_pic_label_num;
- if (*current_name == '+' || *current_name == '-')
- sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
- else
- sprintf (function_base, "*L%d$pb", current_pic_label_num);
-
- name = current_name;
+ function_base_func_name = current_name;
}
-
- return function_base;
+ fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
}
static GTY(()) tree machopic_non_lazy_pointers;
@@ -259,15 +264,14 @@ static GTY(()) tree machopic_non_lazy_pointers;
either by finding it in our list of pointer names, or by generating
a new one. */
-const char *
-machopic_non_lazy_ptr_name (name)
- const char *name;
+static const char *
+machopic_non_lazy_ptr_name (const char *name)
{
const char *temp_name;
tree temp, ident = get_identifier (name);
-
+
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
if (ident == TREE_VALUE (temp))
@@ -278,7 +282,7 @@ machopic_non_lazy_ptr_name (name)
/* Try again, but comparing names this time. */
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
if (TREE_VALUE (temp))
@@ -292,23 +296,31 @@ machopic_non_lazy_ptr_name (name)
{
char *buffer;
+ int namelen = strlen (name);
+ int bufferlen = 0;
tree ptr_name;
- buffer = alloca (strlen (name) + 20);
+ buffer = alloca (namelen + strlen("$non_lazy_ptr") + 5);
strcpy (buffer, "&L");
+ bufferlen = 2;
if (name[0] == '*')
- strcat (buffer, name+1);
+ {
+ memcpy (buffer + bufferlen, name+1, namelen-1+1);
+ bufferlen += namelen-1;
+ }
else
{
- strcat (buffer, "_");
- strcat (buffer, name);
+ buffer[bufferlen] = '_';
+ memcpy (buffer + bufferlen +1, name, namelen+1);
+ bufferlen += namelen +1;
}
-
- strcat (buffer, "$non_lazy_ptr");
+
+ memcpy (buffer + bufferlen, "$non_lazy_ptr", strlen("$non_lazy_ptr")+1);
+ bufferlen += strlen("$non_lazy_ptr");
ptr_name = get_identifier (buffer);
- machopic_non_lazy_pointers
+ machopic_non_lazy_pointers
= tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
TREE_USED (machopic_non_lazy_pointers) = 0;
@@ -322,15 +334,14 @@ static GTY(()) tree machopic_stubs;
/* Return the name of the stub corresponding to the given name,
generating a new stub name if necessary. */
-const char *
-machopic_stub_name (name)
- const char *name;
+const char *
+machopic_stub_name (const char *name)
{
tree temp, ident = get_identifier (name);
const char *tname;
for (temp = machopic_stubs;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
if (ident == TREE_VALUE (temp))
@@ -350,29 +361,46 @@ machopic_stub_name (name)
{
char *buffer;
+ int bufferlen = 0;
+ int namelen = strlen (name);
tree ptr_name;
int needs_quotes = name_needs_quotes (name);
- buffer = alloca (strlen (name) + 20);
+ buffer = alloca (namelen + 20);
if (needs_quotes)
- strcpy (buffer, "&\"L");
+ {
+ strcpy (buffer, "&\"L");
+ bufferlen = strlen("&\"L");
+ }
else
- strcpy (buffer, "&L");
+ {
+ strcpy (buffer, "&L");
+ bufferlen = strlen("&L");
+ }
+
if (name[0] == '*')
{
- strcat (buffer, name+1);
+ memcpy (buffer + bufferlen, name+1, namelen - 1 +1);
+ bufferlen += namelen - 1;
}
else
{
- strcat (buffer, "_");
- strcat (buffer, name);
+ buffer[bufferlen] = '_';
+ memcpy (buffer + bufferlen +1, name, namelen+1);
+ bufferlen += namelen +1;
}
if (needs_quotes)
- strcat (buffer, "$stub\"");
+ {
+ memcpy (buffer + bufferlen, "$stub\"", strlen("$stub\"")+1);
+ bufferlen += strlen("$stub\"");
+ }
else
- strcat (buffer, "$stub");
+ {
+ memcpy (buffer + bufferlen, "$stub", strlen("$stub")+1);
+ bufferlen += strlen("$stub");
+ }
ptr_name = get_identifier (buffer);
machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
@@ -383,9 +411,7 @@ machopic_stub_name (name)
}
void
-machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
- const char *name;
- int validate_stub;
+machopic_validate_stub_or_non_lazy_ptr (const char *name, int validate_stub)
{
const char *real_name;
tree temp, ident = get_identifier (name), id2;
@@ -399,12 +425,12 @@ machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
original symbol as being referenced. */
TREE_USED (temp) = 1;
if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
- TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
+ mark_referenced (TREE_VALUE (temp));
real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
real_name = darwin_strip_name_encoding (real_name);
id2 = maybe_get_identifier (real_name);
if (id2)
- TREE_SYMBOL_REFERENCED (id2) = 1;
+ mark_referenced (id2);
}
}
@@ -412,59 +438,69 @@ machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
source using indirections. */
rtx
-machopic_indirect_data_reference (orig, reg)
- rtx orig, reg;
+machopic_indirect_data_reference (rtx orig, rtx reg)
{
rtx ptr_ref = orig;
-
+
if (! MACHOPIC_INDIRECT)
return orig;
if (GET_CODE (orig) == SYMBOL_REF)
{
const char *name = XSTR (orig, 0);
+ int defined = machopic_data_defined_p (name);
- if (machopic_data_defined_p (name))
+ if (defined && MACHO_DYNAMIC_NO_PIC_P)
+ {
+#if defined (TARGET_TOC)
+ emit_insn (gen_macho_high (reg, orig));
+ emit_insn (gen_macho_low (reg, reg, orig));
+#else
+ /* some other cpu -- writeme! */
+ abort ();
+#endif
+ return reg;
+ }
+ else if (defined)
{
#if defined (TARGET_TOC) || defined (HAVE_lo_sum)
- rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
- machopic_function_base_name ());
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode, orig, pic_base));
+ rtx pic_base = gen_rtx_SYMBOL_REF (Pmode,
+ machopic_function_base_name ());
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode, orig, pic_base));
#endif
#if defined (TARGET_TOC) /* i.e., PowerPC */
- rtx hi_sum_reg = reg;
+ rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
if (reg == NULL)
abort ();
- emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
- gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset))));
- emit_insn (gen_rtx (SET, Pmode, reg,
- gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
+ emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
+ gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ gen_rtx_HIGH (Pmode, offset))));
+ emit_insn (gen_rtx_SET (Pmode, reg,
+ gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
orig = reg;
#else
#if defined (HAVE_lo_sum)
if (reg == 0) abort ();
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (HIGH, Pmode, offset)));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode, reg, offset)));
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_HIGH (Pmode, offset)));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode, reg, offset)));
+ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
- orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
+ orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
#endif
#endif
return orig;
}
- ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
- machopic_non_lazy_ptr_name (name));
+ ptr_ref = gen_rtx_SYMBOL_REF (Pmode,
+ machopic_non_lazy_ptr_name (name));
ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
RTX_UNCHANGING_P (ptr_ref) = 1;
@@ -483,13 +519,13 @@ machopic_indirect_data_reference (orig, reg)
orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
(base == reg ? 0 : reg));
}
- else
+ else
return orig;
if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
result = plus_constant (base, INTVAL (orig));
else
- result = gen_rtx (PLUS, Pmode, base, orig);
+ result = gen_rtx_PLUS (Pmode, base, orig);
if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
{
@@ -533,14 +569,13 @@ machopic_indirect_data_reference (orig, reg)
corresponding symbol_stub if necessary. Return a new MEM. */
rtx
-machopic_indirect_call_target (target)
- rtx target;
+machopic_indirect_call_target (rtx target)
{
if (GET_CODE (target) != MEM)
return target;
if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
- {
+ {
enum machine_mode mode = GET_MODE (XEXP (target, 0));
const char *name = XSTR (XEXP (target, 0), 0);
@@ -552,22 +587,20 @@ machopic_indirect_call_target (target)
{
const char *stub_name = machopic_stub_name (name);
- XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
+ XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
RTX_UNCHANGING_P (target) = 1;
- }
+ }
}
return target;
}
rtx
-machopic_legitimize_pic_address (orig, mode, reg)
- rtx orig, reg;
- enum machine_mode mode;
+machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{
rtx pic_ref = orig;
- if (! MACHOPIC_PURE)
+ if (! MACHOPIC_INDIRECT)
return orig;
/* First handle a simple SYMBOL_REF or LABEL_REF */
@@ -580,7 +613,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
orig = machopic_indirect_data_reference (orig, reg);
- if (GET_CODE (orig) == PLUS
+ if (GET_CODE (orig) == PLUS
&& GET_CODE (XEXP (orig, 0)) == REG)
{
if (reg == 0)
@@ -588,9 +621,13 @@ machopic_legitimize_pic_address (orig, mode, reg)
emit_move_insn (reg, orig);
return reg;
- }
+ }
- pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
+ /* if dynamic-no-pic then use 0 as the pic base */
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ pic_base = CONST0_RTX (Pmode);
+ else
+ pic_base = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
if (GET_CODE (orig) == MEM)
{
@@ -601,42 +638,73 @@ machopic_legitimize_pic_address (orig, mode, reg)
else
reg = gen_reg_rtx (Pmode);
}
-
+
#ifdef HAVE_lo_sum
- if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
+ if (MACHO_DYNAMIC_NO_PIC_P
+ && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
+ {
+#if defined (TARGET_TOC) /* ppc */
+ rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
+ rtx asym = XEXP (orig, 0);
+ rtx mem;
+
+ emit_insn (gen_macho_high (temp_reg, asym));
+ mem = gen_rtx_MEM (GET_MODE (orig),
+ gen_rtx_LO_SUM (Pmode, temp_reg, asym));
+ RTX_UNCHANGING_P (mem) = 1;
+ emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
+#else
+ /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
+ abort ();
+#endif
+ pic_ref = reg;
+ }
+ else
+ if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (orig, 0)) == LABEL_REF)
{
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode,
- XEXP (orig, 0), pic_base));
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ XEXP (orig, 0),
+ pic_base));
#if defined (TARGET_TOC) /* i.e., PowerPC */
/* Generating a new reg may expose opportunities for
common subexpression elimination. */
- rtx hi_sum_reg =
- (reload_in_progress ? reg : gen_reg_rtx (SImode));
-
- emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
- gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset))));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (MEM, GET_MODE (orig),
- gen_rtx (LO_SUM, Pmode,
- hi_sum_reg, offset))));
- pic_ref = reg;
+ rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (SImode);
+ rtx mem;
+ rtx insn;
+ rtx sum;
+
+ sum = gen_rtx_HIGH (Pmode, offset);
+ if (! MACHO_DYNAMIC_NO_PIC_P)
+ sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
+
+ emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
+
+ mem = gen_rtx_MEM (GET_MODE (orig),
+ gen_rtx_LO_SUM (Pmode,
+ hi_sum_reg, offset));
+ RTX_UNCHANGING_P (mem) = 1;
+ insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
+ REG_NOTES (insn));
+ pic_ref = reg;
#else
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
-
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (HIGH, Pmode,
- gen_rtx (CONST, Pmode, offset))));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode, reg,
- gen_rtx (CONST, Pmode, offset))));
- pic_ref = gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx, reg);
+ emit_insn (gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (Pmode,
+ PIC_OFFSET_TABLE_REGNUM)));
+
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_HIGH (Pmode,
+ gen_rtx_CONST (Pmode,
+ offset))));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode, reg,
+ gen_rtx_CONST (Pmode, offset))));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx, reg);
#endif
}
else
@@ -649,21 +717,22 @@ machopic_legitimize_pic_address (orig, mode, reg)
pic = reg;
}
#if 0
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
+ emit_insn (gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (Pmode,
+ PIC_OFFSET_TABLE_REGNUM)));
#endif
- pic_ref = gen_rtx (PLUS, Pmode,
- pic,
- gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode,
- XEXP (orig, 0),
- pic_base)));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic,
+ gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ XEXP (orig, 0),
+ pic_base)));
}
-
+
#if !defined (TARGET_TOC)
emit_move_insn (reg, pic_ref);
- pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
+ pic_ref = gen_rtx_MEM (GET_MODE (orig), reg);
#endif
RTX_UNCHANGING_P (pic_ref) = 1;
}
@@ -671,11 +740,12 @@ machopic_legitimize_pic_address (orig, mode, reg)
{
#ifdef HAVE_lo_sum
- if (GET_CODE (orig) == SYMBOL_REF
+ if (GET_CODE (orig) == SYMBOL_REF
|| GET_CODE (orig) == LABEL_REF)
{
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode, orig, pic_base));
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ orig, pic_base));
#if defined (TARGET_TOC) /* i.e., PowerPC */
rtx hi_sum_reg;
@@ -686,25 +756,28 @@ machopic_legitimize_pic_address (orig, mode, reg)
else
reg = gen_reg_rtx (SImode);
}
-
+
hi_sum_reg = reg;
- emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
- gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset))));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode,
- hi_sum_reg, offset)));
+ emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
+ (MACHO_DYNAMIC_NO_PIC_P)
+ ? gen_rtx_HIGH (Pmode, offset)
+ : gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx,
+ gen_rtx_HIGH (Pmode,
+ offset))));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode,
+ hi_sum_reg, offset)));
pic_ref = reg;
RTX_UNCHANGING_P (pic_ref) = 1;
#else
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (HIGH, Pmode, offset)));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode, reg, offset)));
- pic_ref = gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx, reg);
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_HIGH (Pmode, offset)));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode, reg, offset)));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx, reg);
RTX_UNCHANGING_P (pic_ref) = 1;
#endif
}
@@ -724,14 +797,14 @@ machopic_legitimize_pic_address (orig, mode, reg)
pic = reg;
}
#if 0
- emit_insn (gen_rtx (USE, VOIDmode,
- pic_offset_table_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode,
+ pic_offset_table_rtx));
#endif
- pic_ref = gen_rtx (PLUS, Pmode,
- pic,
- gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode,
- orig, pic_base)));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic,
+ gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ orig, pic_base)));
}
}
}
@@ -763,7 +836,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
|| GET_CODE (XEXP (orig, 0)) == LABEL_REF)
&& XEXP (orig, 0) != pic_offset_table_rtx
&& GET_CODE (XEXP (orig, 1)) != REG)
-
+
{
rtx base;
int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
@@ -777,7 +850,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
is_complex = 1;
}
else
- pic_ref = gen_rtx (PLUS, Pmode, base, orig);
+ pic_ref = gen_rtx_PLUS (Pmode, base, orig);
if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
RTX_UNCHANGING_P (pic_ref) = 1;
@@ -800,7 +873,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
{
rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
- addr = gen_rtx (MEM, GET_MODE (orig), addr);
+ addr = gen_rtx_MEM (GET_MODE (orig), addr);
RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
emit_move_insn (reg, addr);
pic_ref = reg;
@@ -811,8 +884,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
void
-machopic_finish (asm_out_file)
- FILE *asm_out_file;
+machopic_finish (FILE *asm_out_file)
{
tree temp;
@@ -838,7 +910,7 @@ machopic_finish (asm_out_file)
if (sym_name[0] == '*' || sym_name[0] == '&')
strcpy (sym, sym_name + 1);
else if (sym_name[0] == '-' || sym_name[0] == '+')
- strcpy (sym, sym_name);
+ strcpy (sym, sym_name);
else
sym[0] = '_', strcpy (sym + 1, sym_name);
@@ -852,7 +924,7 @@ machopic_finish (asm_out_file)
}
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
@@ -866,18 +938,18 @@ machopic_finish (asm_out_file)
data_section ();
assemble_align (GET_MODE_ALIGNMENT (Pmode));
assemble_label (lazy_name);
- assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
+ assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
GET_MODE_SIZE (Pmode),
GET_MODE_ALIGNMENT (Pmode), 1);
}
else
{
machopic_nl_symbol_ptr_section ();
- assemble_name (asm_out_file, lazy_name);
+ assemble_name (asm_out_file, lazy_name);
fprintf (asm_out_file, ":\n");
fprintf (asm_out_file, "\t.indirect_symbol ");
- assemble_name (asm_out_file, sym_name);
+ assemble_name (asm_out_file, sym_name);
fprintf (asm_out_file, "\n");
assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
@@ -886,9 +958,8 @@ machopic_finish (asm_out_file)
}
}
-int
-machopic_operand_p (op)
- rtx op;
+int
+machopic_operand_p (rtx op)
{
if (MACHOPIC_JUST_INDIRECT)
{
@@ -919,9 +990,7 @@ machopic_operand_p (op)
use later. */
void
-darwin_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
{
char code = '\0';
int defined = 0;
@@ -930,12 +999,18 @@ darwin_encode_section_info (decl, first)
char *new_str;
size_t len, new_len;
+ /* Do the standard encoding things first. */
+ default_encode_section_info (decl, rtl, first);
+
+ /* With the introduction of symbol_ref flags, some of the following
+ code has become redundant and should be removed at some point. */
+
if ((TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !DECL_EXTERNAL (decl)
&& ((TREE_STATIC (decl)
&& (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
- || (DECL_INITIAL (decl)
+ || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node)))
defined = 1;
@@ -947,7 +1022,7 @@ darwin_encode_section_info (decl, first)
if (code == '\0')
return;
- sym_ref = XEXP (DECL_RTL (decl), 0);
+ sym_ref = XEXP (rtl, 0);
orig_str = XSTR (sym_ref, 0);
len = strlen (orig_str) + 1;
@@ -985,8 +1060,7 @@ darwin_encode_section_info (decl, first)
/* Undo the effects of the above. */
const char *
-darwin_strip_name_encoding (str)
- const char *str;
+darwin_strip_name_encoding (const char *str)
{
return str[0] == '!' ? str + 4 : str;
}
@@ -995,8 +1069,7 @@ darwin_strip_name_encoding (str)
stripped name matches the argument. */
static void
-update_non_lazy_ptrs (name)
- const char *name;
+update_non_lazy_ptrs (const char *name)
{
const char *name1, *name2;
tree temp;
@@ -1004,7 +1077,7 @@ update_non_lazy_ptrs (name)
name1 = darwin_strip_name_encoding (name);
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
@@ -1014,7 +1087,9 @@ update_non_lazy_ptrs (name)
name2 = darwin_strip_name_encoding (sym_name);
if (strcmp (name1, name2) == 0)
{
- IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
+ /* FIXME: This breaks the identifier hash table. */
+ IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
+ = (unsigned char *) name;
break;
}
}
@@ -1026,13 +1101,10 @@ update_non_lazy_ptrs (name)
just emit the stub label now and we don't bother emitting the stub later. */
void
-machopic_output_possible_stub_label (file, name)
- FILE *file;
- const char *name;
+machopic_output_possible_stub_label (FILE *file, const char *name)
{
tree temp;
-
/* Ensure we're looking at a section-encoded name. */
if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
return;
@@ -1044,7 +1116,7 @@ machopic_output_possible_stub_label (file, name)
const char *sym_name;
sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
- if (sym_name[0] == '!' && sym_name[1] == 'T'
+ if (sym_name[0] == '!' && (sym_name[1] == 'T' || sym_name[1] == 't')
&& ! strcmp (name+2, sym_name+2))
{
ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
@@ -1059,8 +1131,7 @@ machopic_output_possible_stub_label (file, name)
stripped name matches the argument. */
static void
-update_stubs (name)
- const char *name;
+update_stubs (const char *name)
{
const char *name1, *name2;
tree temp;
@@ -1068,7 +1139,7 @@ update_stubs (name)
name1 = darwin_strip_name_encoding (name);
for (temp = machopic_stubs;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
@@ -1078,7 +1149,9 @@ update_stubs (name)
name2 = darwin_strip_name_encoding (sym_name);
if (strcmp (name1, name2) == 0)
{
- IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
+ /* FIXME: This breaks the identifier hash table. */
+ IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
+ = (unsigned char *) name;
break;
}
}
@@ -1086,14 +1159,12 @@ update_stubs (name)
}
void
-machopic_select_section (exp, reloc, align)
- tree exp;
- int reloc;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+machopic_select_section (tree exp, int reloc,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
void (*base_function)(void);
-
- if (decl_readonly_section (exp, reloc))
+
+ if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
base_function = readonly_data_section;
else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
base_function = const_data_section;
@@ -1101,7 +1172,8 @@ machopic_select_section (exp, reloc, align)
base_function = data_section;
if (TREE_CODE (exp) == STRING_CST
- && TREE_STRING_LENGTH (exp) == strlen (TREE_STRING_POINTER (exp)) + 1
+ && ((size_t) TREE_STRING_LENGTH (exp)
+ == strlen (TREE_STRING_POINTER (exp)) + 1)
&& ! flag_writable_strings)
cstring_section ();
else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
@@ -1132,7 +1204,7 @@ machopic_select_section (exp, reloc, align)
objc_constant_string_object_section ();
else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
objc_string_object_section ();
- else
+ else
base_function ();
}
else if (TREE_CODE (exp) == VAR_DECL &&
@@ -1179,6 +1251,8 @@ machopic_select_section (exp, reloc, align)
objc_symbols_section ();
else if (!strncmp (name, "_OBJC_MODULES", 13))
objc_module_info_section ();
+ else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
+ objc_image_info_section ();
else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
objc_cat_inst_meth_section ();
else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
@@ -1187,10 +1261,10 @@ machopic_select_section (exp, reloc, align)
objc_cat_cls_meth_section ();
else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
objc_protocol_section ();
- else
+ else
base_function ();
}
- else
+ else
base_function ();
}
@@ -1198,10 +1272,8 @@ machopic_select_section (exp, reloc, align)
They must go in "const". */
void
-machopic_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+machopic_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (GET_MODE_SIZE (mode) == 8)
literal8_section ();
@@ -1209,51 +1281,73 @@ machopic_select_rtx_section (mode, x, align)
&& (GET_CODE (x) == CONST_INT
|| GET_CODE (x) == CONST_DOUBLE))
literal4_section ();
+ else if (MACHOPIC_INDIRECT
+ && (GET_CODE (x) == SYMBOL_REF
+ || GET_CODE (x) == CONST
+ || GET_CODE (x) == LABEL_REF))
+ const_data_section ();
else
const_section ();
}
void
-machopic_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
mod_init_section ();
else
constructor_section ();
assemble_align (POINTER_SIZE);
assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
- if (!flag_pic)
+ if (! MACHOPIC_INDIRECT)
fprintf (asm_out_file, ".reference .constructors_used\n");
}
void
-machopic_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
mod_term_section ();
else
destructor_section ();
assemble_align (POINTER_SIZE);
assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
- if (!flag_pic)
+ if (! MACHOPIC_INDIRECT)
fprintf (asm_out_file, ".reference .destructors_used\n");
}
void
-darwin_globalize_label (stream, name)
- FILE *stream;
- const char *name;
+darwin_globalize_label (FILE *stream, const char *name)
{
if (!!strncmp (name, "_OBJC_", 6))
default_globalize_label (stream, name);
}
+/* Emit an assembler directive to set visibility for a symbol. The
+ only supported visibilities are VISIBILITY_DEFAULT and
+ VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
+ extern". There is no MACH-O equivalent of ELF's
+ VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
+
+void
+darwin_assemble_visibility (tree decl, int vis)
+{
+ if (vis == VISIBILITY_DEFAULT)
+ ;
+ else if (vis == VISIBILITY_HIDDEN)
+ {
+ fputs ("\t.private_extern ", asm_out_file);
+ assemble_name (asm_out_file,
+ (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
+ fputs ("\n", asm_out_file);
+ }
+ else
+ warning ("internal and protected visibility attributes not supported"
+ "in this configuration; ignored");
+}
+
/* Output a difference of two labels that will be an assembly time
constant if the two labels are local. (.long lab1-lab2 will be
very different if lab1 is at the boundary between two sections; it
@@ -1264,10 +1358,8 @@ darwin_globalize_label (stream, name)
static int darwin_dwarf_label_counter;
void
-darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
- FILE *file;
- int size ATTRIBUTE_UNUSED;
- const char *lab1, *lab2;
+darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
+ const char *lab1, const char *lab2)
{
const char *p = lab1 + (lab1[0] == '*');
int islocaldiff = (p[0] == 'L');
@@ -1283,5 +1375,16 @@ darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
}
-#include "gt-darwin.h"
+void
+darwin_file_end (void)
+{
+ machopic_finish (asm_out_file);
+ if (strcmp (lang_hooks.name, "GNU C++") == 0)
+ {
+ constructor_section ();
+ destructor_section ();
+ ASM_OUTPUT_ALIGN (asm_out_file, 1);
+ }
+}
+#include "gt-darwin.h"
diff --git a/contrib/gcc/config/darwin.h b/contrib/gcc/config/darwin.h
index c4b7526..045091a 100644
--- a/contrib/gcc/config/darwin.h
+++ b/contrib/gcc/config/darwin.h
@@ -1,22 +1,22 @@
/* Target definitions for Darwin (Mac OS X) systems.
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -186,13 +186,16 @@ Boston, MA 02111-1307, USA. */
#define LINK_COMMAND_SPEC "\
%{!fdump=*:%{!fsyntax-only:%{!precomp:%{!c:%{!M:%{!MM:%{!E:%{!S:\
%{!Zdynamiclib:%(linker)}%{Zdynamiclib:/usr/bin/libtool} \
+ %{!Zdynamiclib:-arch %(darwin_arch)} \
+ %{Zdynamiclib:-arch_only %(darwin_arch)} \
%l %X %{d} %{s} %{t} %{Z} \
%{!Zdynamiclib:%{A} %{e*} %{m} %{N} %{n} %{r} %{u*} %{x} %{z}} \
%{@:-o %f%u.out}%{!@:%{o*}%{!o:-o a.out}} \
%{!Zdynamiclib:%{!A:%{!nostdlib:%{!nostartfiles:%S}}}} \
- %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%G %L}} \
+ %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate:-lgcov} \
+ %{!nostdlib:%{!nodefaultlibs:%G %L}} \
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} %{F*} \
- %{!--help:%{!no-c++filt|c++filt:| c++filt3 }} }}}}}}}}"
+ %{!--help:%{!no-c++filt|c++filt:| c++filt }} }}}}}}}}"
/* Please keep the random linker options in alphabetical order (modulo
'Z' and 'no' prefixes). Options that can only go to one of libtool
@@ -243,7 +246,7 @@ Boston, MA 02111-1307, USA. */
%{Zmulti_module:-multi_module} %{Zsingle_module:-single_module} \
%{Zmultiply_defined*:-multiply_defined %*} \
%{Zmultiplydefinedunused*:-multiply_defined_unused %*} \
- %{prebind} %{noprebind} %{prebind_all_twolevel_modules} \
+ %{prebind} %{noprebind} %{nofixprebinding} %{prebind_all_twolevel_modules} \
%{read_only_relocs} \
%{sectcreate*} %{sectorder*} %{seg1addr*} %{segprot*} %{seg_addr_table*} \
%{Zseg_addr_table_filename*:-seg_addr_table_filename %*} \
@@ -286,9 +289,6 @@ Boston, MA 02111-1307, USA. */
to put anything in ENDFILE_SPEC. */
/* #define ENDFILE_SPEC "" */
-#undef DOLLARS_IN_IDENTIFIERS
-#define DOLLARS_IN_IDENTIFIERS 2
-
/* We use Dbx symbol format. */
#define DBX_DEBUGGING_INFO 1
@@ -312,7 +312,7 @@ do { text_section (); \
/* Our profiling scheme doesn't LP labels and counter words. */
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP
@@ -328,24 +328,14 @@ do { text_section (); \
/* Don't output a .file directive. That is only used by the assembler for
error reporting. */
+#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE false
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE)
-
-#undef ASM_FILE_END
-#define ASM_FILE_END(FILE) \
- do { \
- machopic_finish (asm_out_file); \
- if (strcmp (lang_hooks.name, "GNU C++") == 0) \
- { \
- constructor_section (); \
- destructor_section (); \
- ASM_OUTPUT_ALIGN (FILE, 1); \
- } \
- } while (0)
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END darwin_file_end
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.space %d\n", SIZE)
+ fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", SIZE)
/* Give ObjC methods pretty symbol names. */
@@ -368,19 +358,19 @@ do { text_section (); \
#undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
- const char *xname = NAME; \
- if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
- xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
- if ((TREE_STATIC (DECL) \
- && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
- || DECL_INITIAL (DECL)) \
- machopic_define_name (xname); \
- if ((TREE_STATIC (DECL) \
- && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
- || DECL_INITIAL (DECL)) \
- (* targetm.encode_section_info) (DECL, false); \
- ASM_OUTPUT_LABEL (FILE, xname); \
- /* Darwin doesn't support zero-size objects, so give them a \
+ const char *xname = NAME; \
+ if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
+ xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
+ if ((TREE_STATIC (DECL) \
+ && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
+ || DECL_INITIAL (DECL)) \
+ machopic_define_name (xname); \
+ if ((TREE_STATIC (DECL) \
+ && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
+ || DECL_INITIAL (DECL)) \
+ (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
+ ASM_OUTPUT_LABEL (FILE, xname); \
+ /* Darwin doesn't support zero-size objects, so give them a \
byte. */ \
if (tree_low_cst (DECL_SIZE_UNIT (DECL), 1) == 0) \
assemble_zeros (1); \
@@ -398,7 +388,7 @@ do { text_section (); \
if ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL)) \
- (* targetm.encode_section_info) (DECL, false); \
+ (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
ASM_OUTPUT_LABEL (FILE, xname); \
/* Avoid generating stubs for functions we've just defined by \
outputting any required stub name label now. */ \
@@ -421,7 +411,9 @@ do { text_section (); \
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
do { \
const char *xname = darwin_strip_name_encoding (NAME); \
- if (xname[0] == '&' || xname[0] == '*') \
+ if (! strcmp (xname, "<pic base>")) \
+ machopic_output_function_base_name(FILE); \
+ else if (xname[0] == '&' || xname[0] == '*') \
{ \
int len = strlen (xname); \
if (len > 6 && !strcmp ("$stub", xname + len - 5)) \
@@ -466,12 +458,12 @@ do { text_section (); \
do { \
fputs (".lcomm ", (FILE)); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \
floor_log2 ((ALIGN) / BITS_PER_UNIT)); \
if ((DECL) && ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL))) \
- (* targetm.encode_section_info) (DECL, false); \
+ (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
if ((DECL) && ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL))) \
@@ -488,9 +480,9 @@ do { text_section (); \
#undef SECTION_FUNCTION
#define SECTION_FUNCTION(FUNCTION, SECTION, DIRECTIVE, OBJC) \
-extern void FUNCTION PARAMS ((void)); \
+extern void FUNCTION (void); \
void \
-FUNCTION () \
+FUNCTION (void) \
{ \
if (in_section != SECTION) \
{ \
@@ -518,18 +510,21 @@ FUNCTION () \
in_objc_symbols, in_objc_module_info, \
in_objc_protocol, in_objc_string_object, \
in_objc_constant_string_object, \
+ in_objc_image_info, \
in_objc_class_names, in_objc_meth_var_names, \
- in_objc_meth_var_types, in_objc_cls_refs, \
+ in_objc_meth_var_types, in_objc_cls_refs, \
in_machopic_nl_symbol_ptr, \
in_machopic_lazy_symbol_ptr, \
in_machopic_symbol_stub, \
+ in_machopic_symbol_stub1, \
in_machopic_picsymbol_stub, \
+ in_machopic_picsymbol_stub1, \
in_darwin_exception, in_darwin_eh_frame, \
num_sections
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
-static void objc_section_init PARAMS ((void)); \
+static void objc_section_init (void); \
SECTION_FUNCTION (const_section, \
in_const, \
".const", 0) \
@@ -605,6 +600,10 @@ SECTION_FUNCTION (objc_string_object_section, \
SECTION_FUNCTION (objc_constant_string_object_section, \
in_objc_constant_string_object, \
".section __OBJC, __cstring_object", 1) \
+/* Fix-and-Continue image marker. */ \
+SECTION_FUNCTION (objc_image_info_section, \
+ in_objc_image_info, \
+ ".section __OBJC, __image_info", 1) \
SECTION_FUNCTION (objc_class_names_section, \
in_objc_class_names, \
".objc_class_names", 1) \
@@ -620,16 +619,22 @@ SECTION_FUNCTION (objc_cls_refs_section, \
\
SECTION_FUNCTION (machopic_lazy_symbol_ptr_section, \
in_machopic_lazy_symbol_ptr, \
- ".lazy_symbol_pointer", 0) \
+ ".lazy_symbol_pointer", 0) \
SECTION_FUNCTION (machopic_nl_symbol_ptr_section, \
in_machopic_nl_symbol_ptr, \
- ".non_lazy_symbol_pointer", 0) \
+ ".non_lazy_symbol_pointer", 0) \
SECTION_FUNCTION (machopic_symbol_stub_section, \
in_machopic_symbol_stub, \
- ".symbol_stub", 0) \
+ ".symbol_stub", 0) \
+SECTION_FUNCTION (machopic_symbol_stub1_section, \
+ in_machopic_symbol_stub1, \
+ ".section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16", 0)\
SECTION_FUNCTION (machopic_picsymbol_stub_section, \
in_machopic_picsymbol_stub, \
- ".picsymbol_stub", 0) \
+ ".picsymbol_stub", 0) \
+SECTION_FUNCTION (machopic_picsymbol_stub1_section, \
+ in_machopic_picsymbol_stub1, \
+ ".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32", 0)\
SECTION_FUNCTION (darwin_exception_section, \
in_darwin_exception, \
".section __DATA,__gcc_except_tab", 0) \
@@ -638,7 +643,7 @@ SECTION_FUNCTION (darwin_eh_frame_section, \
".section __TEXT,__eh_frame", 0) \
\
static void \
-objc_section_init () \
+objc_section_init (void) \
{ \
static int been_here = 0; \
\
@@ -655,7 +660,7 @@ objc_section_init () \
objc_cls_refs_section (); \
objc_class_section (); \
objc_meta_class_section (); \
- /* shared, hot -> cold */ \
+ /* shared, hot -> cold */ \
objc_cls_meth_section (); \
objc_inst_meth_section (); \
objc_protocol_section (); \
@@ -678,9 +683,9 @@ objc_section_init () \
#define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section
#define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME) \
- do { \
+ do { \
if (FILE) { \
- if (flag_pic) \
+ if (MACHOPIC_INDIRECT) \
fprintf (FILE, "\t.lazy_reference "); \
else \
fprintf (FILE, "\t.reference "); \
@@ -693,7 +698,7 @@ objc_section_init () \
do { \
if (FILE) { \
fprintf (FILE, "\t"); \
- assemble_name (FILE, NAME); \
+ assemble_name (FILE, NAME); \
fprintf (FILE, "=0\n"); \
(*targetm.asm_out.globalize_label) (FILE, NAME); \
} \
@@ -703,17 +708,17 @@ objc_section_init () \
#define GLOBAL_ASM_OP ".globl "
#define TARGET_ASM_GLOBALIZE_LABEL darwin_globalize_label
+/* Emit an assembler directive to set visibility for a symbol. Used
+ to support visibility attribute and Darwin's private extern
+ feature. */
+#undef TARGET_ASM_ASSEMBLE_VISIBILITY
+#define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
+
+
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM))
-/* This is how to output an internal numbered label where PREFIX is
- the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%d:\n", PREFIX, NUM)
-
/* Since we have a separate readonly data section, define this so that
jump tables end up in text rather than data. */
@@ -733,9 +738,10 @@ enum machopic_addr_class {
/* Macros defining the various PIC cases. */
-#define MACHOPIC_INDIRECT (flag_pic)
-#define MACHOPIC_JUST_INDIRECT (flag_pic == 1)
-#define MACHOPIC_PURE (flag_pic == 2)
+#define MACHO_DYNAMIC_NO_PIC_P (TARGET_DYNAMIC_NO_PIC)
+#define MACHOPIC_INDIRECT (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+#define MACHOPIC_JUST_INDIRECT (flag_pic == 1 || MACHO_DYNAMIC_NO_PIC_P)
+#define MACHOPIC_PURE (flag_pic == 2 && ! MACHO_DYNAMIC_NO_PIC_P)
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO darwin_encode_section_info
@@ -801,7 +807,7 @@ enum machopic_addr_class {
#define TARGET_ASM_EXCEPTION_SECTION darwin_exception_section
#define TARGET_ASM_EH_FRAME_SECTION darwin_eh_frame_section
-
+
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
(((CODE) == 2 && (GLOBAL) == 1) \
@@ -813,12 +819,12 @@ enum machopic_addr_class {
#define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
-#define DARWIN_REGISTER_TARGET_PRAGMAS(PFILE) \
- do { \
- cpp_register_pragma (PFILE, 0, "mark", darwin_pragma_ignore); \
- cpp_register_pragma (PFILE, 0, "options", darwin_pragma_options); \
- cpp_register_pragma (PFILE, 0, "segment", darwin_pragma_ignore); \
- cpp_register_pragma (PFILE, 0, "unused", darwin_pragma_unused); \
+#define DARWIN_REGISTER_TARGET_PRAGMAS() \
+ do { \
+ c_register_pragma (0, "mark", darwin_pragma_ignore); \
+ c_register_pragma (0, "options", darwin_pragma_options); \
+ c_register_pragma (0, "segment", darwin_pragma_ignore); \
+ c_register_pragma (0, "unused", darwin_pragma_unused); \
} while (0)
#undef ASM_APP_ON
diff --git a/contrib/gcc/config/dbx.h b/contrib/gcc/config/dbx.h
index a9feded..eb20452 100644
--- a/contrib/gcc/config/dbx.h
+++ b/contrib/gcc/config/dbx.h
@@ -1,20 +1,20 @@
/* Prefer DBX (stabs) debugging information.
Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/dbxcoff.h b/contrib/gcc/config/dbxcoff.h
index b955932..76a910f 100644
--- a/contrib/gcc/config/dbxcoff.h
+++ b/contrib/gcc/config/dbxcoff.h
@@ -1,20 +1,20 @@
/* Definitions needed when using stabs embedded in COFF sections.
Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -55,23 +55,21 @@ Boston, MA 02111-1307, USA. */
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE, COUNTER) \
{ if (write_symbols == SDB_DEBUG) { \
fprintf ((FILE), "\t.ln\t%d\n", \
((sdb_begin_function_line > -1) \
? (LINE) - sdb_begin_function_line : 1)); \
} else if (write_symbols == DBX_DEBUG) { \
- static int sym_lineno = 1; \
char buffer[256]; \
- ASM_GENERATE_INTERNAL_LABEL (buffer, "LM", sym_lineno); \
+ ASM_GENERATE_INTERNAL_LABEL (buffer, "LM", COUNTER); \
fprintf (FILE, ".stabn 68,0,%d,", LINE); \
assemble_name (FILE, buffer); \
putc ('-', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
putc ('\n', FILE); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
- sym_lineno++; \
+ (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER); \
} }
/* When generating stabs debugging, use N_BINCL entries. */
diff --git a/contrib/gcc/config/dbxelf.h b/contrib/gcc/config/dbxelf.h
index 9f8f56a..e636dad 100644
--- a/contrib/gcc/config/dbxelf.h
+++ b/contrib/gcc/config/dbxelf.h
@@ -1,20 +1,20 @@
/* Definitions needed when using stabs embedded in ELF sections.
Copyright (C) 1999 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -57,20 +57,18 @@ Boston, MA 02111-1307, USA. */
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE, COUNTER) \
do \
{ \
- static int sym_lineno = 1; \
char temp[256]; \
- ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
+ ASM_GENERATE_INTERNAL_LABEL (temp, "LM", COUNTER); \
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
putc ('-', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
putc ('\n', FILE); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
- sym_lineno += 1; \
+ (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER); \
} \
while (0)
diff --git a/contrib/gcc/config/elfos.h b/contrib/gcc/config/elfos.h
index 25a44af..6a138f9 100644
--- a/contrib/gcc/config/elfos.h
+++ b/contrib/gcc/config/elfos.h
@@ -1,26 +1,32 @@
/* elfos.h -- operating system specific defines to be used when
targeting GCC for some generic ELF system
- Copyright (C) 1991, 1994, 1995, 1999, 2000, 2001, 2002
+ Copyright (C) 1991, 1994, 1995, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#define TARGET_OBJFMT_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__ELF__"); \
+ } \
+ while (0)
/* Define a symbol indicating that we are using elfos.h.
Some CPU specific configuration files use this. */
@@ -60,10 +66,6 @@ Boston, MA 02111-1307, USA. */
#define HANDLE_SYSV_PRAGMA 1
-/* System V Release 4 uses DWARF debugging info. */
-
-#define DWARF_DEBUGGING_INFO 1
-
/* All ELF targets can support DWARF-2. */
#define DWARF2_DEBUGGING_INFO 1
@@ -90,16 +92,9 @@ Boston, MA 02111-1307, USA. */
#undef SET_ASM_OP
#define SET_ASM_OP "\t.set\t"
-/* This is how to begin an assembly language file. Most svr4 assemblers want
- at least a .file directive to come first, and some want to see a .version
- directive come right after that. Here we just establish a default
- which generates only the .file directive. If you need a .version
- directive for any specific target, you should override this definition
- in the target-specific file which includes this one. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- output_file_directive ((FILE), main_input_filename)
+/* Most svr4 assemblers want a .file directive at the beginning of
+ their input file. */
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* This is how to allocate empty space in some section. The .zero
pseudo-op is used for this on most svr4 assemblers. */
@@ -108,21 +103,8 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
- fprintf (FILE, "%s%u\n", SKIP_ASM_OP, (SIZE))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class.
-
- For most svr4 systems, the convention is that any symbol which begins
- with a period is not put into the linker symbol table by the assembler. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \
- do \
- { \
- fprintf (FILE, ".%s%u:\n", PREFIX, (unsigned) (NUM)); \
- } \
- while (0)
+ fprintf ((FILE), "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
+ SKIP_ASM_OP, (SIZE))
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
@@ -161,7 +143,7 @@ Boston, MA 02111-1307, USA. */
do \
{ \
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
} \
while (0)
@@ -185,7 +167,8 @@ Boston, MA 02111-1307, USA. */
{ \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
+ (SIZE), (ALIGN) / BITS_PER_UNIT); \
} \
while (0)
@@ -234,7 +217,7 @@ Boston, MA 02111-1307, USA. */
#endif
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
-
+
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
@@ -254,11 +237,11 @@ Boston, MA 02111-1307, USA. */
/* This is how we tell the assembler that a symbol is weak. */
-#define ASM_WEAKEN_LABEL(FILE, NAME) \
+#define ASM_WEAKEN_LABEL(FILE, NAME) \
do \
{ \
fputs ("\t.weak\t", (FILE)); \
- assemble_name ((FILE), (NAME)); \
+ assemble_name ((FILE), (NAME)); \
fputc ('\n', (FILE)); \
} \
while (0)
@@ -327,12 +310,13 @@ Boston, MA 02111-1307, USA. */
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
+#undef ASM_FINISH_DECLARE_OBJECT
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)\
do \
{ \
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
HOST_WIDE_INT size; \
- \
+ \
if (!flag_inhibit_size_directive \
&& DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \
@@ -410,13 +394,13 @@ Boston, MA 02111-1307, USA. */
register const unsigned char *_limited_str = \
(const unsigned char *) (STR); \
register unsigned ch; \
- \
+ \
fprintf ((FILE), "%s\"", STRING_ASM_OP); \
- \
+ \
for (; (ch = *_limited_str); _limited_str++) \
{ \
register int escape; \
- \
+ \
switch (escape = ESCAPES[ch]) \
{ \
case 0: \
@@ -431,7 +415,7 @@ Boston, MA 02111-1307, USA. */
break; \
} \
} \
- \
+ \
fprintf ((FILE), "\"\n"); \
} \
while (0)
@@ -455,16 +439,16 @@ Boston, MA 02111-1307, USA. */
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
register const unsigned char *p; \
- \
+ \
if (bytes_in_chunk >= 60) \
{ \
fprintf ((FILE), "\"\n"); \
bytes_in_chunk = 0; \
} \
- \
+ \
for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \
continue; \
- \
+ \
if (p < limit && (p - _ascii_bytes) <= (long)STRING_LIMIT) \
{ \
if (bytes_in_chunk > 0) \
@@ -472,7 +456,7 @@ Boston, MA 02111-1307, USA. */
fprintf ((FILE), "\"\n"); \
bytes_in_chunk = 0; \
} \
- \
+ \
ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \
_ascii_bytes = p; \
} \
@@ -480,10 +464,10 @@ Boston, MA 02111-1307, USA. */
{ \
register int escape; \
register unsigned ch; \
- \
+ \
if (bytes_in_chunk == 0) \
fprintf ((FILE), "%s\"", ASCII_DATA_ASM_OP); \
- \
+ \
switch (escape = ESCAPES[ch = *_ascii_bytes]) \
{ \
case 0: \
@@ -502,7 +486,7 @@ Boston, MA 02111-1307, USA. */
} \
} \
} \
- \
+ \
if (bytes_in_chunk > 0) \
fprintf ((FILE), "\"\n"); \
} \
diff --git a/contrib/gcc/config/fp-bit.c b/contrib/gcc/config/fp-bit.c
index e609760..e7556c4 100644
--- a/contrib/gcc/config/fp-bit.c
+++ b/contrib/gcc/config/fp-bit.c
@@ -1,6 +1,6 @@
/* This is a software floating point library which can be used
for targets without hardware floating point.
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
@@ -44,7 +44,9 @@ Boston, MA 02111-1307, USA. */
to one copy, then compile both copies and add them to libgcc.a. */
#include "tconfig.h"
-#include "fp-bit.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "config/fp-bit.h"
/* The following macros can be defined to change the behavior of this file:
FLOAT: Implement a `float', aka SFmode, fp library. If this is not
@@ -208,7 +210,11 @@ pack_d ( fp_number_type * src)
exp = EXPMAX;
if (src->class == CLASS_QNAN || 1)
{
+#ifdef QUIET_NAN_NEGATED
+ fraction |= QUIET_NAN - 1;
+#else
fraction |= QUIET_NAN;
+#endif
}
}
else if (isinf (src))
@@ -324,58 +330,76 @@ pack_d ( fp_number_type * src)
#else
# if defined TFLOAT && defined HALFFRACBITS
{
- halffractype high, low;
-
- high = (fraction >> (FRACBITS - HALFFRACBITS));
- high &= (((fractype)1) << HALFFRACBITS) - 1;
- high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
- high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
-
- low = (halffractype)fraction &
- ((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1);
+ halffractype high, low, unity;
+ int lowsign, lowexp;
+
+ unity = (halffractype) 1 << HALFFRACBITS;
+
+ /* Set HIGH to the high double's significand, masking out the implicit 1.
+ Set LOW to the low double's full significand. */
+ high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
+ low = fraction & (unity * 2 - 1);
+
+ /* Get the initial sign and exponent of the low double. */
+ lowexp = exp - HALFFRACBITS - 1;
+ lowsign = sign;
+
+ /* HIGH should be rounded like a normal double, making |LOW| <=
+ 0.5 ULP of HIGH. Assume round-to-nearest. */
+ if (exp < EXPMAX)
+ if (low > unity || (low == unity && (high & 1) == 1))
+ {
+ /* Round HIGH up and adjust LOW to match. */
+ high++;
+ if (high == unity)
+ {
+ /* May make it infinite, but that's OK. */
+ high = 0;
+ exp++;
+ }
+ low = unity * 2 - low;
+ lowsign ^= 1;
+ }
+
+ high |= (halffractype) exp << HALFFRACBITS;
+ high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
if (exp == EXPMAX || exp == 0 || low == 0)
low = 0;
else
{
- exp -= HALFFRACBITS + 1;
-
- while (exp > 0
- && low < ((halffractype)1 << HALFFRACBITS))
+ while (lowexp > 0 && low < unity)
{
low <<= 1;
- exp--;
+ lowexp--;
}
- if (exp <= 0)
+ if (lowexp <= 0)
{
halffractype roundmsb, round;
+ int shift;
- exp = -exp + 1;
-
- roundmsb = (1 << (exp - 1));
+ shift = 1 - lowexp;
+ roundmsb = (1 << (shift - 1));
round = low & ((roundmsb << 1) - 1);
- low >>= exp;
- exp = 0;
+ low >>= shift;
+ lowexp = 0;
- if (round > roundmsb || (round == roundmsb && (low & 1)))
+ if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
{
low++;
- if (low >= ((halffractype)1 << HALFFRACBITS))
- /* We don't shift left, since it has just become the
- smallest normal number, whose implicit 1 bit is
- now indicated by the non-zero exponent. */
- exp++;
+ if (low == unity)
+ /* LOW rounds up to the smallest normal number. */
+ lowexp++;
}
}
- low &= ((halffractype)1 << HALFFRACBITS) - 1;
- low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
- low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
+ low &= unity - 1;
+ low |= (halffractype) lowexp << HALFFRACBITS;
+ low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
}
-
- dst.value_raw = (((fractype) high) << HALFSHIFT) | low;
+ dst.value_raw = ((fractype) high << HALFSHIFT) | low;
}
# else
dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
@@ -469,8 +493,16 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
xlow >>= -shift;
if (sign == lowsign)
fraction += xlow;
- else
+ else if (fraction >= xlow)
fraction -= xlow;
+ else
+ {
+ /* The high part is a power of two but the full number is lower.
+ This code will leave the implicit 1 in FRACTION, but we'd
+ have added that below anyway. */
+ fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
+ exp--;
+ }
}
}
# else
@@ -523,7 +555,11 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
else
{
/* Nonzero fraction, means nan */
+#ifdef QUIET_NAN_NEGATED
+ if ((fraction & QUIET_NAN) == 0)
+#else
if (fraction & QUIET_NAN)
+#endif
{
dst->class = CLASS_QNAN;
}
diff --git a/contrib/gcc/config/fp-bit.h b/contrib/gcc/config/fp-bit.h
index 0e8509e..6221c9e 100644
--- a/contrib/gcc/config/fp-bit.h
+++ b/contrib/gcc/config/fp-bit.h
@@ -2,20 +2,20 @@
/* Copyright (C) 2000, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/freebsd-nthr.h b/contrib/gcc/config/freebsd-nthr.h
index 2f1d65f..65add9b 100644
--- a/contrib/gcc/config/freebsd-nthr.h
+++ b/contrib/gcc/config/freebsd-nthr.h
@@ -2,20 +2,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Loren J. Rittle <ljrittle@acm.org>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/frv/cmovd.c b/contrib/gcc/config/frv/cmovd.c
index 11b50ba..8ce986e 100644
--- a/contrib/gcc/config/frv/cmovd.c
+++ b/contrib/gcc/config/frv/cmovd.c
@@ -1,24 +1,31 @@
/* Move double-word library function.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
void
__cmovd (long long *dest, const long long *src, unsigned len)
{
diff --git a/contrib/gcc/config/frv/cmovh.c b/contrib/gcc/config/frv/cmovh.c
index 018a0b4..97e1f11 100644
--- a/contrib/gcc/config/frv/cmovh.c
+++ b/contrib/gcc/config/frv/cmovh.c
@@ -1,24 +1,31 @@
/* Move half-word library function.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
void
__cmovh (short *dest, const short *src, unsigned len)
{
diff --git a/contrib/gcc/config/frv/cmovw.c b/contrib/gcc/config/frv/cmovw.c
index 5509e06..8bc5801 100644
--- a/contrib/gcc/config/frv/cmovw.c
+++ b/contrib/gcc/config/frv/cmovw.c
@@ -1,24 +1,31 @@
/* Move word library function.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
void
__cmovw (int *dest, const int *src, unsigned len)
{
diff --git a/contrib/gcc/config/frv/frv-abi.h b/contrib/gcc/config/frv/frv-abi.h
index 68fd32f..a38dd16 100644
--- a/contrib/gcc/config/frv/frv-abi.h
+++ b/contrib/gcc/config/frv/frv-abi.h
@@ -2,20 +2,20 @@
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/frv/frv-asm.h b/contrib/gcc/config/frv/frv-asm.h
index e8447a6..b4305a4 100644
--- a/contrib/gcc/config/frv/frv-asm.h
+++ b/contrib/gcc/config/frv/frv-asm.h
@@ -1,21 +1,21 @@
/* Assembler Support.
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-
- This file is part of GNU CC.
-
- GNU CC is free software ; you can redistribute it and/or modify
+
+ 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 2, or (at your option)
any later version.
-
- GNU CC is distributed in the hope that it will be useful,
+
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,7 +23,7 @@
P2(INSN): Emit INSN.P on the FR500 and above, otherwise emit plain INSN. */
#ifdef __FRV_VLIW__
#ifdef __STDC__
-#define P(A) A##.p
+#define P(A) A.p
#else
#define P(A) A/**/.p
#endif
diff --git a/contrib/gcc/config/frv/frv-modes.def b/contrib/gcc/config/frv/frv-modes.def
index ca7818c..3985099 100644
--- a/contrib/gcc/config/frv/frv-modes.def
+++ b/contrib/gcc/config/frv/frv-modes.def
@@ -1,20 +1,20 @@
/* Definitions of target machine for GNU compiler for FRV.
Copyright (C) 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,6 +25,6 @@ Boston, MA 02111-1307, USA. */
CC_FPmode set FCC's from comparing floating point
CC_CCRmode set CCR's to do conditional execution */
-CC (CC_UNS)
-CC (CC_FP)
-CC (CC_CCR)
+CC_MODE (CC_UNS);
+CC_MODE (CC_FP);
+CC_MODE (CC_CCR);
diff --git a/contrib/gcc/config/frv/frv-protos.h b/contrib/gcc/config/frv/frv-protos.h
index 4f5a422..90292b1 100644
--- a/contrib/gcc/config/frv/frv-protos.h
+++ b/contrib/gcc/config/frv/frv-protos.h
@@ -1,21 +1,21 @@
/* Frv prototypes.
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,7 +23,7 @@ Boston, MA 02111-1307, USA. */
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
-/* Define global data defined in frv.c */
+/* Define global data defined in frv.c. */
extern const char *frv_branch_cost_string; /* -mbranch-cost option */
extern int frv_branch_cost_int; /* value of -mbranch_cost */
@@ -52,196 +52,187 @@ typedef enum frv_cpu
extern frv_cpu_t frv_cpu_type; /* value of -mcpu= */
/* Define functions defined in frv.c */
-extern void frv_expand_prologue PARAMS ((void));
-extern void frv_expand_epilogue PARAMS ((int));
-extern void frv_override_options PARAMS ((void));
-extern void frv_optimization_options PARAMS ((int, int));
-extern void frv_conditional_register_usage PARAMS ((void));
-extern frv_stack_t *frv_stack_info PARAMS ((void));
-extern void frv_debug_stack PARAMS ((frv_stack_t *));
-extern int frv_frame_pointer_required PARAMS ((void));
-extern int frv_initial_elimination_offset PARAMS ((int, int));
+extern void frv_expand_prologue (void);
+extern void frv_expand_epilogue (int);
+extern void frv_override_options (void);
+extern void frv_optimization_options (int, int);
+extern void frv_conditional_register_usage (void);
+extern frv_stack_t *frv_stack_info (void);
+extern void frv_debug_stack (frv_stack_t *);
+extern int frv_frame_pointer_required (void);
+extern int frv_initial_elimination_offset (int, int);
#ifdef RTX_CODE
-extern int frv_legitimate_address_p PARAMS ((enum machine_mode, rtx,
- int, int));
-extern rtx frv_legitimize_address PARAMS ((rtx, rtx,
- enum machine_mode));
+extern int frv_legitimate_address_p (enum machine_mode, rtx,
+ int, int);
+extern rtx frv_legitimize_address (rtx, rtx, enum machine_mode);
#ifdef TREE_CODE
-extern void frv_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree,
- rtx, int, int));
+extern void frv_init_cumulative_args (CUMULATIVE_ARGS *, tree,
+ rtx, tree, int);
-extern int frv_function_arg_boundary PARAMS ((enum machine_mode, tree));
-extern rtx frv_function_arg PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int, int));
+extern int frv_function_arg_boundary (enum machine_mode, tree);
+extern rtx frv_function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int, int);
-extern void frv_function_arg_advance PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern void frv_function_arg_advance (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_callee_copies PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_callee_copies (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_keep_as_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_keep_as_reference (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern rtx frv_expand_builtin_saveregs PARAMS ((void));
-extern void frv_setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int *, int));
+extern rtx frv_expand_builtin_saveregs (void);
+extern void frv_setup_incoming_varargs (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int *, int);
-extern void frv_expand_builtin_va_start PARAMS ((tree, rtx));
-extern rtx frv_expand_builtin_va_arg PARAMS ((tree, tree));
+extern void frv_expand_builtin_va_start (tree, rtx);
+extern rtx frv_expand_builtin_va_arg (tree, tree);
#endif /* TREE_CODE */
-extern int frv_expand_block_move PARAMS ((rtx *));
-extern int frv_expand_block_clear PARAMS ((rtx *));
-extern rtx frv_dynamic_chain_address PARAMS ((rtx));
-extern rtx frv_return_addr_rtx PARAMS ((int, rtx));
-extern rtx frv_index_memory PARAMS ((rtx,
- enum machine_mode,
- int));
+extern int frv_expand_block_move (rtx *);
+extern int frv_expand_block_clear (rtx *);
+extern rtx frv_dynamic_chain_address (rtx);
+extern rtx frv_return_addr_rtx (int, rtx);
+extern rtx frv_index_memory (rtx, enum machine_mode, int);
extern const char *frv_asm_output_opcode
- PARAMS ((FILE *, const char *));
-extern void frv_final_prescan_insn PARAMS ((rtx, rtx *, int));
-extern void frv_print_operand PARAMS ((FILE *, rtx, int));
-extern void frv_print_operand_address PARAMS ((FILE *, rtx));
-extern int frv_emit_movsi PARAMS ((rtx, rtx));
-extern const char *output_move_single PARAMS ((rtx *, rtx));
-extern const char *output_move_double PARAMS ((rtx *, rtx));
+ (FILE *, const char *);
+extern void frv_final_prescan_insn (rtx, rtx *, int);
+extern void frv_print_operand (FILE *, rtx, int);
+extern void frv_print_operand_address (FILE *, rtx);
+extern int frv_emit_movsi (rtx, rtx);
+extern const char *output_move_single (rtx *, rtx);
+extern const char *output_move_double (rtx *, rtx);
extern const char *output_condmove_single
- PARAMS ((rtx *, rtx));
-extern int frv_emit_cond_branch PARAMS ((enum rtx_code, rtx));
-extern int frv_emit_scc PARAMS ((enum rtx_code, rtx));
-extern rtx frv_split_scc PARAMS ((rtx, rtx, rtx, rtx,
- HOST_WIDE_INT));
-extern int frv_emit_cond_move PARAMS ((rtx, rtx, rtx, rtx));
-extern rtx frv_split_cond_move PARAMS ((rtx *));
-extern rtx frv_split_minmax PARAMS ((rtx *));
-extern rtx frv_split_abs PARAMS ((rtx *));
-extern void frv_split_double_load PARAMS ((rtx, rtx));
-extern void frv_split_double_store PARAMS ((rtx, rtx));
+ (rtx *, rtx);
+extern int frv_emit_cond_branch (enum rtx_code, rtx);
+extern int frv_emit_scc (enum rtx_code, rtx);
+extern rtx frv_split_scc (rtx, rtx, rtx, rtx, HOST_WIDE_INT);
+extern int frv_emit_cond_move (rtx, rtx, rtx, rtx);
+extern rtx frv_split_cond_move (rtx *);
+extern rtx frv_split_minmax (rtx *);
+extern rtx frv_split_abs (rtx *);
+extern void frv_split_double_load (rtx, rtx);
+extern void frv_split_double_store (rtx, rtx);
#ifdef BLOCK_HEAD
-extern void frv_ifcvt_init_extra_fields PARAMS ((ce_if_block_t *));
-extern void frv_ifcvt_modify_tests PARAMS ((ce_if_block_t *,
- rtx *, rtx *));
+extern void frv_ifcvt_init_extra_fields (ce_if_block_t *);
+extern void frv_ifcvt_modify_tests (ce_if_block_t *, rtx *, rtx *);
extern void frv_ifcvt_modify_multiple_tests
- PARAMS ((ce_if_block_t *,
- basic_block,
- rtx *, rtx *));
-extern rtx frv_ifcvt_modify_insn PARAMS ((ce_if_block_t *,
- rtx, rtx));
-extern void frv_ifcvt_modify_final PARAMS ((ce_if_block_t *));
-extern void frv_ifcvt_modify_cancel PARAMS ((ce_if_block_t *));
+ (ce_if_block_t *, basic_block,
+ rtx *, rtx *);
+extern rtx frv_ifcvt_modify_insn (ce_if_block_t *, rtx, rtx);
+extern void frv_ifcvt_modify_final (ce_if_block_t *);
+extern void frv_ifcvt_modify_cancel (ce_if_block_t *);
#endif
-extern int frv_trampoline_size PARAMS ((void));
-extern void frv_initialize_trampoline PARAMS ((rtx, rtx, rtx));
+extern int frv_trampoline_size (void);
+extern void frv_initialize_trampoline (rtx, rtx, rtx);
extern enum reg_class frv_secondary_reload_class
- PARAMS ((enum reg_class class,
- enum machine_mode mode,
- rtx x, int));
-extern int frv_class_likely_spilled_p PARAMS ((enum reg_class class));
-extern int frv_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
-extern int frv_hard_regno_nregs PARAMS ((int, enum machine_mode));
-extern int frv_class_max_nregs PARAMS ((enum reg_class class,
- enum machine_mode mode));
-extern int frv_legitimate_constant_p PARAMS ((rtx));
+ (enum reg_class class,
+ enum machine_mode mode,
+ rtx x, int);
+extern int frv_class_likely_spilled_p (enum reg_class class);
+extern int frv_hard_regno_mode_ok (int, enum machine_mode);
+extern int frv_hard_regno_nregs (int, enum machine_mode);
+extern int frv_class_max_nregs (enum reg_class class,
+ enum machine_mode mode);
+extern int frv_legitimate_constant_p (rtx);
#endif /* RTX_CODE */
-extern int direct_return_p PARAMS ((void));
-extern int frv_register_move_cost PARAMS ((enum reg_class, enum reg_class));
+extern int direct_return_p (void);
+extern int frv_register_move_cost (enum reg_class, enum reg_class);
#ifdef TREE_CODE
-extern int frv_adjust_field_align PARAMS ((tree, int));
+extern int frv_adjust_field_align (tree, int);
#endif
-extern void fixup_section PARAMS ((void));
-extern void sdata_section PARAMS ((void));
-extern void sbss_section PARAMS ((void));
-extern void const_section PARAMS ((void));
-extern void data_section PARAMS ((void));
+extern void fixup_section (void);
+extern void sdata_section (void);
+extern void sbss_section (void);
+extern void data_section (void);
#ifdef RTX_CODE
-extern int integer_register_operand PARAMS ((rtx, enum machine_mode));
-extern int frv_load_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_no_subreg_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int6_operand PARAMS ((rtx, enum machine_mode));
-extern int fpr_or_int6_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int12_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_fpr_or_int12_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int10_operand PARAMS ((rtx, enum machine_mode));
-extern int move_source_operand PARAMS ((rtx, enum machine_mode));
-extern int move_destination_operand PARAMS ((rtx, enum machine_mode));
-extern int condexec_source_operand PARAMS ((rtx, enum machine_mode));
-extern int condexec_dest_operand PARAMS ((rtx, enum machine_mode));
-extern int lr_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int fpr_or_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
-extern int fcc_operand PARAMS ((rtx, enum machine_mode));
-extern int icc_operand PARAMS ((rtx, enum machine_mode));
-extern int cc_operand PARAMS ((rtx, enum machine_mode));
-extern int fcr_operand PARAMS ((rtx, enum machine_mode));
-extern int icr_operand PARAMS ((rtx, enum machine_mode));
-extern int cr_operand PARAMS ((rtx, enum machine_mode));
-extern int call_operand PARAMS ((rtx, enum machine_mode));
-extern int fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int even_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int odd_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int even_gpr_operand PARAMS ((rtx, enum machine_mode));
-extern int odd_gpr_operand PARAMS ((rtx, enum machine_mode));
-extern int quad_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int even_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int odd_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int dbl_memory_one_insn_operand PARAMS ((rtx, enum machine_mode));
-extern int dbl_memory_two_insn_operand PARAMS ((rtx, enum machine_mode));
-extern int int12_operand PARAMS ((rtx, enum machine_mode));
-extern int int6_operand PARAMS ((rtx, enum machine_mode));
-extern int int5_operand PARAMS ((rtx, enum machine_mode));
-extern int uint5_operand PARAMS ((rtx, enum machine_mode));
-extern int uint4_operand PARAMS ((rtx, enum machine_mode));
-extern int uint1_operand PARAMS ((rtx, enum machine_mode));
-extern int int_2word_operand PARAMS ((rtx, enum machine_mode));
-extern int pic_register_operand PARAMS ((rtx, enum machine_mode));
-extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int small_data_register_operand PARAMS ((rtx, enum machine_mode));
-extern int small_data_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int upper_int16_operand PARAMS ((rtx, enum machine_mode));
-extern int uint16_operand PARAMS ((rtx, enum machine_mode));
-extern int relational_operator PARAMS ((rtx, enum machine_mode));
-extern int signed_relational_operator PARAMS ((rtx, enum machine_mode));
-extern int unsigned_relational_operator PARAMS ((rtx, enum machine_mode));
-extern int float_relational_operator PARAMS ((rtx, enum machine_mode));
-extern int ccr_eqne_operator PARAMS ((rtx, enum machine_mode));
-extern int minmax_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_binary_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_media_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_divide_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_unary_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_sf_conv_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_sf_add_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int intop_compare_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_intop_cmp_operator PARAMS ((rtx, enum machine_mode));
-extern int acc_operand PARAMS ((rtx, enum machine_mode));
-extern int even_acc_operand PARAMS ((rtx, enum machine_mode));
-extern int quad_acc_operand PARAMS ((rtx, enum machine_mode));
-extern int accg_operand PARAMS ((rtx, enum machine_mode));
-extern rtx frv_matching_accg_for_acc PARAMS ((rtx));
-extern void frv_machine_dependent_reorg PARAMS ((rtx));
+extern int integer_register_operand (rtx, enum machine_mode);
+extern int frv_load_operand (rtx, enum machine_mode);
+extern int gpr_or_fpr_operand (rtx, enum machine_mode);
+extern int gpr_no_subreg_operand (rtx, enum machine_mode);
+extern int gpr_or_int6_operand (rtx, enum machine_mode);
+extern int fpr_or_int6_operand (rtx, enum machine_mode);
+extern int gpr_or_int_operand (rtx, enum machine_mode);
+extern int gpr_or_int12_operand (rtx, enum machine_mode);
+extern int gpr_fpr_or_int12_operand (rtx, enum machine_mode);
+extern int gpr_or_int10_operand (rtx, enum machine_mode);
+extern int move_source_operand (rtx, enum machine_mode);
+extern int move_destination_operand (rtx, enum machine_mode);
+extern int condexec_source_operand (rtx, enum machine_mode);
+extern int condexec_dest_operand (rtx, enum machine_mode);
+extern int lr_operand (rtx, enum machine_mode);
+extern int gpr_or_memory_operand (rtx, enum machine_mode);
+extern int fpr_or_memory_operand (rtx, enum machine_mode);
+extern int reg_or_0_operand (rtx, enum machine_mode);
+extern int fcc_operand (rtx, enum machine_mode);
+extern int icc_operand (rtx, enum machine_mode);
+extern int cc_operand (rtx, enum machine_mode);
+extern int fcr_operand (rtx, enum machine_mode);
+extern int icr_operand (rtx, enum machine_mode);
+extern int cr_operand (rtx, enum machine_mode);
+extern int call_operand (rtx, enum machine_mode);
+extern int fpr_operand (rtx, enum machine_mode);
+extern int even_reg_operand (rtx, enum machine_mode);
+extern int odd_reg_operand (rtx, enum machine_mode);
+extern int even_gpr_operand (rtx, enum machine_mode);
+extern int odd_gpr_operand (rtx, enum machine_mode);
+extern int quad_fpr_operand (rtx, enum machine_mode);
+extern int even_fpr_operand (rtx, enum machine_mode);
+extern int odd_fpr_operand (rtx, enum machine_mode);
+extern int dbl_memory_one_insn_operand (rtx, enum machine_mode);
+extern int dbl_memory_two_insn_operand (rtx, enum machine_mode);
+extern int int12_operand (rtx, enum machine_mode);
+extern int int6_operand (rtx, enum machine_mode);
+extern int int5_operand (rtx, enum machine_mode);
+extern int uint5_operand (rtx, enum machine_mode);
+extern int uint4_operand (rtx, enum machine_mode);
+extern int uint1_operand (rtx, enum machine_mode);
+extern int int_2word_operand (rtx, enum machine_mode);
+extern int pic_register_operand (rtx, enum machine_mode);
+extern int pic_symbolic_operand (rtx, enum machine_mode);
+extern int small_data_register_operand (rtx, enum machine_mode);
+extern int small_data_symbolic_operand (rtx, enum machine_mode);
+extern int upper_int16_operand (rtx, enum machine_mode);
+extern int uint16_operand (rtx, enum machine_mode);
+extern int relational_operator (rtx, enum machine_mode);
+extern int signed_relational_operator (rtx, enum machine_mode);
+extern int unsigned_relational_operator (rtx, enum machine_mode);
+extern int float_relational_operator (rtx, enum machine_mode);
+extern int ccr_eqne_operator (rtx, enum machine_mode);
+extern int minmax_operator (rtx, enum machine_mode);
+extern int condexec_si_binary_operator (rtx, enum machine_mode);
+extern int condexec_si_media_operator (rtx, enum machine_mode);
+extern int condexec_si_divide_operator (rtx, enum machine_mode);
+extern int condexec_si_unary_operator (rtx, enum machine_mode);
+extern int condexec_sf_conv_operator (rtx, enum machine_mode);
+extern int condexec_sf_add_operator (rtx, enum machine_mode);
+extern int condexec_memory_operand (rtx, enum machine_mode);
+extern int intop_compare_operator (rtx, enum machine_mode);
+extern int condexec_intop_cmp_operator (rtx, enum machine_mode);
+extern int acc_operand (rtx, enum machine_mode);
+extern int even_acc_operand (rtx, enum machine_mode);
+extern int quad_acc_operand (rtx, enum machine_mode);
+extern int accg_operand (rtx, enum machine_mode);
+extern rtx frv_matching_accg_for_acc (rtx);
#endif
diff --git a/contrib/gcc/config/frv/frv.c b/contrib/gcc/config/frv/frv.c
index d09533a..1a75042 100644
--- a/contrib/gcc/config/frv/frv.c
+++ b/contrib/gcc/config/frv/frv.c
@@ -1,25 +1,28 @@
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004
+ Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "regs.h"
@@ -72,7 +75,7 @@ frv_tmp_reg_t;
/* conditional expression used */
#define REGSTATE_IF_EITHER (REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)
-/* the following is not sure in the reg_state bytes, so can have a larger value
+/* The following is not sure in the reg_state bytes, so can have a larger value
than 0xff. */
#define REGSTATE_CONDJUMP 0x100 /* conditional jump done in VLIW insn */
@@ -108,7 +111,7 @@ typedef struct
rtx frv_compare_op0;
rtx frv_compare_op1;
-/* Conditional execution support gathered together in one structure */
+/* Conditional execution support gathered together in one structure. */
typedef struct
{
/* Linked list of insns to add if the conditional execution conversion was
@@ -136,20 +139,20 @@ typedef struct
/* Current number of temp registers available. */
int cur_scratch_regs;
- /* Number of nested conditional execution blocks */
+ /* Number of nested conditional execution blocks. */
int num_nested_cond_exec;
/* Map of insns that set up constants in scratch registers. */
bitmap scratch_insns_bitmap;
- /* Conditional execution test register (CC0..CC7) */
+ /* Conditional execution test register (CC0..CC7). */
rtx cr_reg;
/* Conditional execution compare register that is paired with cr_reg, so that
nested compares can be done. The csubcc and caddcc instructions don't
have enough bits to specify both a CC register to be set and a CR register
to do the test on, so the same bit number is used for both. Needless to
- say, this is rather inconvient for GCC. */
+ say, this is rather inconvenient for GCC. */
rtx nested_cc_reg;
/* Extra CR registers used for &&, ||. */
@@ -157,7 +160,7 @@ typedef struct
rtx extra_fp_cr;
/* Previous CR used in nested if, to make sure we are dealing with the same
- nested if as the previous statement. */
+ nested if as the previous statement. */
rtx last_nested_if_cr;
}
frv_ifcvt_t;
@@ -167,10 +170,10 @@ static /* GTY(()) */ frv_ifcvt_t frv_ifcvt;
/* Map register number to smallest register class. */
enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
-/* Map class letter into register class */
+/* Map class letter into register class. */
enum reg_class reg_class_from_letter[256];
-/* Cached value of frv_stack_info */
+/* Cached value of frv_stack_info. */
static frv_stack_t *frv_stack_cache = (frv_stack_t *)0;
/* -mbranch-cost= support */
@@ -194,93 +197,75 @@ const char *frv_sched_lookahead_str; /* -msched-lookahead=n */
int frv_sched_lookahead = 4; /* -msched-lookahead=n */
/* Forward references */
-static int frv_default_flags_for_cpu PARAMS ((void));
-static int frv_string_begins_with PARAMS ((tree, const char *));
-static FRV_INLINE int symbol_ref_small_data_p PARAMS ((rtx));
-static FRV_INLINE int const_small_data_p PARAMS ((rtx));
-static FRV_INLINE int plus_small_data_p PARAMS ((rtx, rtx));
+static int frv_default_flags_for_cpu (void);
+static int frv_string_begins_with (tree, const char *);
+static FRV_INLINE int const_small_data_p (rtx);
+static FRV_INLINE int plus_small_data_p (rtx, rtx);
static void frv_print_operand_memory_reference_reg
- PARAMS ((FILE *, rtx));
-static void frv_print_operand_memory_reference PARAMS ((FILE *, rtx, int));
-static int frv_print_operand_jump_hint PARAMS ((rtx));
-static FRV_INLINE int frv_regno_ok_for_base_p PARAMS ((int, int));
-static rtx single_set_pattern PARAMS ((rtx));
-static int frv_function_contains_far_jump PARAMS ((void));
-static rtx frv_alloc_temp_reg PARAMS ((frv_tmp_reg_t *,
- enum reg_class,
- enum machine_mode,
- int, int));
-static rtx frv_frame_offset_rtx PARAMS ((int));
-static rtx frv_frame_mem PARAMS ((enum machine_mode,
- rtx, int));
-static rtx frv_dwarf_store PARAMS ((rtx, int));
-static void frv_frame_insn PARAMS ((rtx, rtx));
-static void frv_frame_access PARAMS ((frv_frame_accessor_t*,
- rtx, int));
-static void frv_frame_access_multi PARAMS ((frv_frame_accessor_t*,
- frv_stack_t *, int));
-static void frv_frame_access_standard_regs PARAMS ((enum frv_stack_op,
- frv_stack_t *));
-static struct machine_function *frv_init_machine_status PARAMS ((void));
-static int frv_legitimate_memory_operand PARAMS ((rtx,
- enum machine_mode,
- int));
-static rtx frv_int_to_acc PARAMS ((enum insn_code,
- int, rtx));
-static enum machine_mode frv_matching_accg_mode PARAMS ((enum machine_mode));
-static rtx frv_read_argument PARAMS ((tree *));
-static int frv_check_constant_argument PARAMS ((enum insn_code,
- int, rtx));
-static rtx frv_legitimize_target PARAMS ((enum insn_code, rtx));
-static rtx frv_legitimize_argument PARAMS ((enum insn_code,
- int, rtx));
-static rtx frv_expand_set_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_unop_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_binop_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_cut_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_binopimm_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_voidbinop_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_voidtriop_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_voidaccop_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_mclracc_builtin PARAMS ((tree));
-static rtx frv_expand_mrdacc_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_mwtacc_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_noargs_builtin PARAMS ((enum insn_code));
-static rtx frv_emit_comparison PARAMS ((enum rtx_code, rtx,
- rtx));
-static int frv_clear_registers_used PARAMS ((rtx *, void *));
-static void frv_ifcvt_add_insn PARAMS ((rtx, rtx, int));
-static rtx frv_ifcvt_rewrite_mem PARAMS ((rtx,
- enum machine_mode,
- rtx));
-static rtx frv_ifcvt_load_value PARAMS ((rtx, rtx));
-static void frv_registers_update PARAMS ((rtx, unsigned char [],
- int [], int *, int));
-static int frv_registers_used_p PARAMS ((rtx, unsigned char [],
- int));
-static int frv_registers_set_p PARAMS ((rtx, unsigned char [],
- int));
-static void frv_pack_insns PARAMS ((void));
-static void frv_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void frv_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static bool frv_assemble_integer PARAMS ((rtx, unsigned, int));
-static const char * frv_strip_name_encoding PARAMS ((const char *));
-static void frv_encode_section_info PARAMS ((tree, int));
-static void frv_init_builtins PARAMS ((void));
-static rtx frv_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
-static bool frv_in_small_data_p PARAMS ((tree));
+ (FILE *, rtx);
+static void frv_print_operand_memory_reference (FILE *, rtx, int);
+static int frv_print_operand_jump_hint (rtx);
+static FRV_INLINE int frv_regno_ok_for_base_p (int, int);
+static rtx single_set_pattern (rtx);
+static int frv_function_contains_far_jump (void);
+static rtx frv_alloc_temp_reg (frv_tmp_reg_t *,
+ enum reg_class,
+ enum machine_mode,
+ int, int);
+static rtx frv_frame_offset_rtx (int);
+static rtx frv_frame_mem (enum machine_mode, rtx, int);
+static rtx frv_dwarf_store (rtx, int);
+static void frv_frame_insn (rtx, rtx);
+static void frv_frame_access (frv_frame_accessor_t*,
+ rtx, int);
+static void frv_frame_access_multi (frv_frame_accessor_t*,
+ frv_stack_t *, int);
+static void frv_frame_access_standard_regs (enum frv_stack_op,
+ frv_stack_t *);
+static struct machine_function *frv_init_machine_status (void);
+static int frv_legitimate_memory_operand (rtx, enum machine_mode, int);
+static rtx frv_int_to_acc (enum insn_code, int, rtx);
+static enum machine_mode frv_matching_accg_mode (enum machine_mode);
+static rtx frv_read_argument (tree *);
+static int frv_check_constant_argument (enum insn_code, int, rtx);
+static rtx frv_legitimize_target (enum insn_code, rtx);
+static rtx frv_legitimize_argument (enum insn_code, int, rtx);
+static rtx frv_expand_set_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_unop_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_cut_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_binopimm_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_voidbinop_builtin (enum insn_code, tree);
+static rtx frv_expand_voidtriop_builtin (enum insn_code, tree);
+static rtx frv_expand_voidaccop_builtin (enum insn_code, tree);
+static rtx frv_expand_mclracc_builtin (tree);
+static rtx frv_expand_mrdacc_builtin (enum insn_code, tree);
+static rtx frv_expand_mwtacc_builtin (enum insn_code, tree);
+static rtx frv_expand_noargs_builtin (enum insn_code);
+static rtx frv_emit_comparison (enum rtx_code, rtx, rtx);
+static int frv_clear_registers_used (rtx *, void *);
+static void frv_ifcvt_add_insn (rtx, rtx, int);
+static rtx frv_ifcvt_rewrite_mem (rtx, enum machine_mode, rtx);
+static rtx frv_ifcvt_load_value (rtx, rtx);
+static void frv_registers_update (rtx, unsigned char [],
+ int [], int *, int);
+static int frv_registers_used_p (rtx, unsigned char [], int);
+static int frv_registers_set_p (rtx, unsigned char [], int);
+static int frv_issue_rate (void);
+static int frv_use_dfa_pipeline_interface (void);
+static void frv_pack_insns (void);
+static void frv_function_prologue (FILE *, HOST_WIDE_INT);
+static void frv_function_epilogue (FILE *, HOST_WIDE_INT);
+static bool frv_assemble_integer (rtx, unsigned, int);
+static void frv_init_builtins (void);
+static rtx frv_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void frv_init_libfuncs (void);
+static bool frv_in_small_data_p (tree);
static void frv_asm_output_mi_thunk
- PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
+ (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
+static bool frv_rtx_costs (rtx, int, int, int*);
+static void frv_asm_out_constructor (rtx, int);
+static void frv_asm_out_destructor (rtx, int);
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
@@ -289,38 +274,37 @@ static void frv_asm_output_mi_thunk
#define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue
#undef TARGET_ASM_INTEGER
#define TARGET_ASM_INTEGER frv_assemble_integer
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING frv_strip_name_encoding
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO frv_encode_section_info
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS frv_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN frv_expand_builtin
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS frv_init_libfuncs
#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS frv_rtx_costs
+#undef TARGET_ASM_CONSTRUCTOR
+#define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor
+#undef TARGET_ASM_DESTRUCTOR
+#define TARGET_ASM_DESTRUCTOR frv_asm_out_destructor
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE frv_issue_rate
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE frv_use_dfa_pipeline_interface
+
struct gcc_target targetm = TARGET_INITIALIZER;
-/* Given a SYMBOL_REF, return true if it points to small data. */
-
-static FRV_INLINE int
-symbol_ref_small_data_p (x)
- rtx x;
-{
- return SDATA_NAME_P (XSTR (x, 0));
-}
-
/* Given a CONST, return true if the symbol_ref points to small data. */
static FRV_INLINE int
-const_small_data_p (x)
- rtx x;
+const_small_data_p (rtx x)
{
rtx x0, x1;
@@ -328,7 +312,7 @@ const_small_data_p (x)
return FALSE;
x0 = XEXP (XEXP (x, 0), 0);
- if (GET_CODE (x0) != SYMBOL_REF || !SDATA_NAME_P (XSTR (x0, 0)))
+ if (GET_CODE (x0) != SYMBOL_REF || !SYMBOL_REF_SMALL_P (x0))
return FALSE;
x1 = XEXP (XEXP (x, 0), 1);
@@ -342,16 +326,14 @@ const_small_data_p (x)
/* Given a PLUS, return true if this is a small data reference. */
static FRV_INLINE int
-plus_small_data_p (op0, op1)
- rtx op0;
- rtx op1;
+plus_small_data_p (rtx op0, rtx op1)
{
if (GET_MODE (op0) == SImode
&& GET_CODE (op0) == REG
&& REGNO (op0) == SDA_BASE_REG)
{
if (GET_CODE (op1) == SYMBOL_REF)
- return symbol_ref_small_data_p (op1);
+ return SYMBOL_REF_SMALL_P (op1);
if (GET_CODE (op1) == CONST)
return const_small_data_p (op1);
@@ -362,7 +344,7 @@ plus_small_data_p (op0, op1)
static int
-frv_default_flags_for_cpu ()
+frv_default_flags_for_cpu (void)
{
switch (frv_cpu_type)
{
@@ -393,11 +375,11 @@ frv_default_flags_for_cpu ()
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
void
-frv_override_options ()
+frv_override_options (void)
{
int regno, i;
- /* Set the cpu type */
+ /* Set the cpu type. */
if (frv_cpu_string)
{
if (strcmp (frv_cpu_string, "simple") == 0)
@@ -450,26 +432,26 @@ frv_override_options ()
if (write_symbols == DWARF_DEBUG && flag_pic)
error ("-fpic and -gdwarf are incompatible (-fpic and -g/-gdwarf-2 are fine)");
- /* Change the branch cost value */
+ /* Change the branch cost value. */
if (frv_branch_cost_string)
frv_branch_cost_int = atoi (frv_branch_cost_string);
- /* Change the # of insns to be converted to conditional execution */
+ /* Change the # of insns to be converted to conditional execution. */
if (frv_condexec_insns_str)
frv_condexec_insns = atoi (frv_condexec_insns_str);
- /* Change # of temporary registers used to hold integer constants */
+ /* Change # of temporary registers used to hold integer constants. */
if (frv_condexec_temps_str)
frv_condexec_temps = atoi (frv_condexec_temps_str);
- /* Change scheduling look ahead. */
+ /* Change scheduling look ahead. */
if (frv_sched_lookahead_str)
frv_sched_lookahead = atoi (frv_sched_lookahead_str);
/* A C expression whose value is a register class containing hard
register REGNO. In general there is more than one such class;
choose a class which is "minimal", meaning that no smaller class
- also contains the register. */
+ also contains the register. */
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
{
@@ -615,9 +597,7 @@ frv_override_options ()
/* On the FRV, possibly disable VLIW packing which is done by the 2nd
scheduling pass at the current time. */
void
-frv_optimization_options (level, size)
- int level;
- int size ATTRIBUTE_UNUSED;
+frv_optimization_options (int level, int size ATTRIBUTE_UNUSED)
{
if (level >= 2)
{
@@ -634,9 +614,7 @@ frv_optimization_options (level, size)
/* Return true if NAME (a STRING_CST node) begins with PREFIX. */
static int
-frv_string_begins_with (name, prefix)
- tree name;
- const char *prefix;
+frv_string_begins_with (tree name, const char *prefix)
{
int prefix_len = strlen (prefix);
@@ -644,64 +622,6 @@ frv_string_begins_with (name, prefix)
return (TREE_STRING_LENGTH (name) > prefix_len
&& strncmp (TREE_STRING_POINTER (name), prefix, prefix_len) == 0);
}
-
-/* Encode section information of DECL, which is either a VAR_DECL,
- FUNCTION_DECL, STRING_CST, CONSTRUCTOR, or ???.
-
- For the FRV we want to record:
-
- - whether the object lives in .sdata/.sbss.
- objects living in .sdata/.sbss are prefixed with SDATA_FLAG_CHAR
-
-*/
-
-static void
-frv_encode_section_info (decl, first)
- tree decl;
- int first;
-{
- if (! first)
- return;
- if (TREE_CODE (decl) == VAR_DECL)
- {
- int size = int_size_in_bytes (TREE_TYPE (decl));
- tree section_name = DECL_SECTION_NAME (decl);
- int is_small = 0;
-
- /* Don't apply the -G flag to internal compiler structures. We
- should leave such structures in the main data section, partly
- for efficiency and partly because the size of some of them
- (such as C++ typeinfos) is not known until later. */
- if (!DECL_ARTIFICIAL (decl) && size > 0 && size <= g_switch_value)
- is_small = 1;
-
- /* If we already know which section the decl should be in, see if
- it's a small data section. */
- if (section_name)
- {
- if (TREE_CODE (section_name) == STRING_CST)
- {
- if (frv_string_begins_with (section_name, ".sdata"))
- is_small = 1;
- if (frv_string_begins_with (section_name, ".sbss"))
- is_small = 1;
- }
- else
- abort ();
- }
-
- if (is_small)
- {
- rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- char * str = xmalloc (2 + strlen (XSTR (sym_ref, 0)));
-
- str[0] = SDATA_FLAG_CHAR;
- strcpy (&str[1], XSTR (sym_ref, 0));
- XSTR (sym_ref, 0) = str;
- }
- }
-}
-
/* Zero or more C statements that may conditionally modify two variables
`fixed_regs' and `call_used_regs' (both of type `char []') after they have
@@ -724,7 +644,7 @@ frv_encode_section_info (decl, first)
target switches are opposed to them.) */
void
-frv_conditional_register_usage ()
+frv_conditional_register_usage (void)
{
int i;
@@ -931,7 +851,7 @@ frv_conditional_register_usage ()
*/
frv_stack_t *
-frv_stack_info ()
+frv_stack_info (void)
{
static frv_stack_t info, zero_info;
frv_stack_t *info_ptr = &info;
@@ -943,14 +863,15 @@ frv_stack_info ()
int alignment;
int offset;
- /* If we've already calculated the values and reload is complete, just return now */
+ /* If we've already calculated the values and reload is complete,
+ just return now. */
if (frv_stack_cache)
return frv_stack_cache;
- /* Zero all fields */
+ /* Zero all fields. */
info = zero_info;
- /* Set up the register range information */
+ /* Set up the register range information. */
info_ptr->regs[STACK_REGS_GPR].name = "gpr";
info_ptr->regs[STACK_REGS_GPR].first = LAST_ARG_REGNUM + 1;
info_ptr->regs[STACK_REGS_GPR].last = GPR_LAST;
@@ -1013,7 +934,7 @@ frv_stack_info ()
}
}
- /* Iterate over all of the register ranges */
+ /* Iterate over all of the register ranges. */
for (range = 0; range < STACK_REGS_MAX; range++)
{
frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
@@ -1023,7 +944,7 @@ frv_stack_info ()
int size_2words = 0;
int regno;
- /* Calculate which registers need to be saved & save area size */
+ /* Calculate which registers need to be saved & save area size. */
switch (range)
{
default:
@@ -1059,9 +980,9 @@ frv_stack_info ()
case STACK_REGS_STDARG:
if (varargs_p)
{
- /* If this is a stdarg function with an non varardic argument split
- between registers and the stack, adjust the saved registers
- downward */
+ /* If this is a stdarg function with a non varardic
+ argument split between registers and the stack,
+ adjust the saved registers downward. */
last -= (ADDR_ALIGN (cfun->pretend_args_size, UNITS_PER_WORD)
/ UNITS_PER_WORD);
@@ -1087,11 +1008,11 @@ frv_stack_info ()
if (size_1word)
{
- /* If this is a field, it only takes one word */
+ /* If this is a field, it only takes one word. */
if (reg_ptr->field_p)
size_1word = UNITS_PER_WORD;
- /* Determine which register pairs can be saved together */
+ /* Determine which register pairs can be saved together. */
else if (reg_ptr->dword_p && TARGET_DWORD)
{
for (regno = first; regno < last; regno += 2)
@@ -1150,7 +1071,7 @@ frv_stack_info ()
info_ptr->header_size = 4 * UNITS_PER_WORD;
info_ptr->total_size += 4 * UNITS_PER_WORD;
- /* Calculate the offsets to save normal register pairs */
+ /* Calculate the offsets to save normal register pairs. */
for (range = 0; range < STACK_REGS_MAX; range++)
{
frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
@@ -1172,7 +1093,7 @@ frv_stack_info ()
}
}
- /* Calculate the offsets to save normal single registers */
+ /* Calculate the offsets to save normal single registers. */
for (range = 0; range < STACK_REGS_MAX; range++)
{
frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
@@ -1256,11 +1177,10 @@ frv_stack_info ()
}
-/* Print the information about the frv stack offsets, etc. when debugging. */
+/* Print the information about the frv stack offsets, etc. when debugging. */
void
-frv_debug_stack (info)
- frv_stack_t *info;
+frv_debug_stack (frv_stack_t *info)
{
int range;
@@ -1319,14 +1239,14 @@ frv_debug_stack (info)
/* The following variable value is TRUE if the next output insn should
finish cpu cycle. In order words the insn will have packing bit
- (which means absence of asm code suffix `.p' on assembler. */
+ (which means absence of asm code suffix `.p' on assembler. */
static int frv_insn_packing_flag;
/* True if the current function contains a far jump. */
static int
-frv_function_contains_far_jump ()
+frv_function_contains_far_jump (void)
{
rtx insn = get_insns ();
while (insn != NULL
@@ -1343,9 +1263,7 @@ frv_function_contains_far_jump ()
will return correctly. It also does the VLIW packing. */
static void
-frv_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+frv_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
/* If no frame was created, check whether the function uses a call
instruction to implement a far jump. If so, save the link in gr3 and
@@ -1392,12 +1310,12 @@ frv_function_prologue (file, size)
/* Return the next available temporary register in a given class. */
static rtx
-frv_alloc_temp_reg (info, class, mode, mark_as_used, no_abort)
- frv_tmp_reg_t *info; /* which registers are available */
- enum reg_class class; /* register class desired */
- enum machine_mode mode; /* mode to allocate register with */
- int mark_as_used; /* register not available after allocation */
- int no_abort; /* return NULL instead of aborting */
+frv_alloc_temp_reg (
+ frv_tmp_reg_t *info, /* which registers are available */
+ enum reg_class class, /* register class desired */
+ enum machine_mode mode, /* mode to allocate register with */
+ int mark_as_used, /* register not available after allocation */
+ int no_abort) /* return NULL instead of aborting */
{
int regno = info->next_reg[ (int)class ];
int orig_regno = regno;
@@ -1439,8 +1357,7 @@ frv_alloc_temp_reg (info, class, mode, mark_as_used, no_abort)
The function returns a constant rtx if OFFSET is small enough, otherwise
it loads the constant into register OFFSET_REGNO and returns that. */
static rtx
-frv_frame_offset_rtx (offset)
- int offset;
+frv_frame_offset_rtx (int offset)
{
rtx offset_rtx = GEN_INT (offset);
if (IN_RANGE_P (offset, -2048, 2047))
@@ -1462,10 +1379,7 @@ frv_frame_offset_rtx (offset)
/* Generate (mem:MODE (plus:Pmode BASE (frv_frame_offset OFFSET)))). The
prologue and epilogue uses such expressions to access the stack. */
static rtx
-frv_frame_mem (mode, base, offset)
- enum machine_mode mode;
- rtx base;
- int offset;
+frv_frame_mem (enum machine_mode mode, rtx base, int offset)
{
return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode,
base,
@@ -1482,9 +1396,7 @@ frv_frame_mem (mode, base, offset)
or SEQUENCE that has several sets, each set must be individually marked
as frame-related. */
static rtx
-frv_dwarf_store (reg, offset)
- rtx reg;
- int offset;
+frv_dwarf_store (rtx reg, int offset)
{
rtx set = gen_rtx_SET (VOIDmode,
gen_rtx_MEM (GET_MODE (reg),
@@ -1501,9 +1413,7 @@ frv_dwarf_store (reg, offset)
frame-related and has a REG_FRAME_RELATED_EXPR note containing
DWARF_PATTERN. */
static void
-frv_frame_insn (pattern, dwarf_pattern)
- rtx pattern;
- rtx dwarf_pattern;
+frv_frame_insn (rtx pattern, rtx dwarf_pattern)
{
rtx insn = emit_insn (pattern);
RTX_FRAME_RELATED_P (insn) = 1;
@@ -1522,7 +1432,7 @@ frv_frame_insn (pattern, dwarf_pattern)
simply be the stack pointer, but if several accesses are being made to a
region far away from the stack pointer, it may be more efficient to set
up a temporary instead.
-
+
Store instructions will be frame-related and will be annotated with the
overall effect of the store. Load instructions will be followed by a
(use) to prevent later optimizations from zapping them.
@@ -1530,10 +1440,7 @@ frv_frame_insn (pattern, dwarf_pattern)
The function takes care of the moves to and from SPRs, using TEMP_REGNO
as a temporary in such cases. */
static void
-frv_frame_access (accessor, reg, stack_offset)
- frv_frame_accessor_t *accessor;
- rtx reg;
- int stack_offset;
+frv_frame_access (frv_frame_accessor_t *accessor, rtx reg, int stack_offset)
{
enum machine_mode mode = GET_MODE (reg);
rtx mem = frv_frame_mem (mode,
@@ -1584,10 +1491,9 @@ frv_frame_access (accessor, reg, stack_offset)
is the stack information generated by frv_stack_info, and REG_SET is the
number of the register set to transfer. */
static void
-frv_frame_access_multi (accessor, info, reg_set)
- frv_frame_accessor_t *accessor;
- frv_stack_t *info;
- int reg_set;
+frv_frame_access_multi (frv_frame_accessor_t *accessor,
+ frv_stack_t *info,
+ int reg_set)
{
frv_stack_regs_t *regs_info;
int regno;
@@ -1607,9 +1513,7 @@ frv_frame_access_multi (accessor, info, reg_set)
them if OP is FRV_LOAD. INFO is the stack information generated by
frv_stack_info. */
static void
-frv_frame_access_standard_regs (op, info)
- enum frv_stack_op op;
- frv_stack_t *info;
+frv_frame_access_standard_regs (enum frv_stack_op op, frv_stack_t *info)
{
frv_frame_accessor_t accessor;
@@ -1619,7 +1523,7 @@ frv_frame_access_standard_regs (op, info)
frv_frame_access_multi (&accessor, info, STACK_REGS_GPR);
frv_frame_access_multi (&accessor, info, STACK_REGS_FPR);
frv_frame_access_multi (&accessor, info, STACK_REGS_LCR);
-}
+}
/* Called after register allocation to add any instructions needed for the
@@ -1632,7 +1536,7 @@ frv_frame_access_standard_regs (op, info)
Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
so that the debug info generation code can handle them properly. */
void
-frv_expand_prologue ()
+frv_expand_prologue (void)
{
frv_stack_t *info = frv_stack_info ();
rtx sp = stack_pointer_rtx;
@@ -1733,7 +1637,7 @@ frv_expand_prologue ()
if (info->stdarg_size > 0)
emit_insn (gen_blockage ());
- /* Set up pic register/small data register for this function. */
+ /* Set up pic register/small data register for this function. */
if (flag_pic && cfun->uses_pic_offset_table)
emit_insn (gen_pic_prologue (gen_rtx_REG (Pmode, PIC_REGNO),
gen_rtx_REG (Pmode, LR_REGNO),
@@ -1742,19 +1646,18 @@ frv_expand_prologue ()
/* Under frv, all of the work is done via frv_expand_epilogue, but
- this function provides a convient place to do cleanup. */
+ this function provides a convenient place to do cleanup. */
static void
-frv_function_epilogue (file, size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+frv_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
frv_stack_cache = (frv_stack_t *)0;
- /* zap last used registers for conditional execution. */
- memset ((PTR) &frv_ifcvt.tmp_reg, 0, sizeof (frv_ifcvt.tmp_reg));
+ /* Zap last used registers for conditional execution. */
+ memset (&frv_ifcvt.tmp_reg, 0, sizeof (frv_ifcvt.tmp_reg));
- /* release the bitmap of created insns. */
+ /* Release the bitmap of created insns. */
BITMAP_XFREE (frv_ifcvt.scratch_insns_bitmap);
}
@@ -1772,8 +1675,7 @@ frv_function_epilogue (file, size)
slots for arguments passed to the current function. */
void
-frv_expand_epilogue (sibcall_p)
- int sibcall_p;
+frv_expand_epilogue (int sibcall_p)
{
frv_stack_t *info = frv_stack_info ();
rtx fp = frame_pointer_rtx;
@@ -1874,30 +1776,27 @@ frv_expand_epilogue (sibcall_p)
varargs. */
static void
-frv_asm_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
- FILE *file;
- tree thunk_fndecl ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
+frv_asm_output_mi_thunk (FILE *file,
+ tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ tree function)
{
const char *name_func = XSTR (XEXP (DECL_RTL (function), 0), 0);
const char *name_arg0 = reg_names[FIRST_ARG_REGNUM];
const char *name_jmp = reg_names[JUMP_REGNO];
const char *parallel = ((PACKING_FLAG_USED_P ()) ? ".p" : "");
- /* Do the add using an addi if possible */
+ /* Do the add using an addi if possible. */
if (IN_RANGE_P (delta, -2048, 2047))
fprintf (file, "\taddi %s,#%d,%s\n", name_arg0, (int) delta, name_arg0);
else
{
- const char *name_add = reg_names[TEMP_REGNO];
- fprintf (file, "\tsethi%s #hi(", parallel);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
- fprintf (file, "),%s\n", name_add);
- fprintf (file, "\tsetlo #lo(");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
- fprintf (file, "),%s\n", name_add);
+ const char *const name_add = reg_names[TEMP_REGNO];
+ fprintf (file, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
+ parallel, delta, name_add);
+ fprintf (file, "\tsetlo #lo(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
+ delta, name_add);
fprintf (file, "\tadd %s,%s,%s\n", name_add, name_arg0, name_arg0);
}
@@ -1937,7 +1836,7 @@ frv_asm_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
fprintf (file, "\tadd %s,%s,%s\n", name_gppic, name_tmp, name_jmp);
}
- /* Jump to the function address */
+ /* Jump to the function address. */
fprintf (file, "\tjmpl @(%s,%s)\n", name_jmp, reg_names[GPR_FIRST+0]);
}
@@ -1961,10 +1860,10 @@ frv_asm_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
register can be allocated for ordinary usage, unless you mark it as a fixed
register. See `FIXED_REGISTERS' for more information. */
-/* On frv, create a frame whenever we need to create stack */
+/* On frv, create a frame whenever we need to create stack. */
int
-frv_frame_pointer_required ()
+frv_frame_pointer_required (void)
{
if (! current_function_is_leaf)
return TRUE;
@@ -1998,9 +1897,7 @@ frv_frame_pointer_required ()
/* See frv_stack_info for more details on the frv stack frame. */
int
-frv_initial_elimination_offset (from, to)
- int from;
- int to;
+frv_initial_elimination_offset (int from, int to)
{
frv_stack_t *info = frv_stack_info ();
int ret = 0;
@@ -2009,7 +1906,7 @@ frv_initial_elimination_offset (from, to)
ret = info->total_size - info->pretend_size;
else if (to == STACK_POINTER_REGNUM && from == FRAME_POINTER_REGNUM)
- ret = - info->reg_offset[FRAME_POINTER_REGNUM];
+ ret = info->reg_offset[FRAME_POINTER_REGNUM];
else if (to == FRAME_POINTER_REGNUM && from == ARG_POINTER_REGNUM)
ret = (info->total_size
@@ -2057,12 +1954,11 @@ frv_initial_elimination_offset (from, to)
this case. */
void
-frv_setup_incoming_varargs (cum, mode, type, pretend_size, second_time)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int *pretend_size;
- int second_time;
+frv_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int *pretend_size,
+ int second_time)
{
if (TARGET_DEBUG_ARG)
fprintf (stderr,
@@ -2081,7 +1977,7 @@ frv_setup_incoming_varargs (cum, mode, type, pretend_size, second_time)
the library function `__builtin_saveregs'. */
rtx
-frv_expand_builtin_saveregs ()
+frv_expand_builtin_saveregs (void)
{
int offset = UNITS_PER_WORD * FRV_NUM_ARG_REGS;
@@ -2096,9 +1992,7 @@ frv_expand_builtin_saveregs ()
/* Expand __builtin_va_start to do the va_start macro. */
void
-frv_expand_builtin_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+frv_expand_builtin_va_start (tree valist, rtx nextarg)
{
tree t;
int num = cfun->args_info - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS;
@@ -2125,9 +2019,7 @@ frv_expand_builtin_va_start (valist, nextarg)
/* Expand __builtin_va_arg to do the va_arg macro. */
rtx
-frv_expand_builtin_va_arg(valist, type)
- tree valist;
- tree type;
+frv_expand_builtin_va_arg (tree valist, tree type)
{
rtx addr;
rtx mem;
@@ -2172,8 +2064,7 @@ frv_expand_builtin_va_arg(valist, type)
#endif
int
-frv_expand_block_move (operands)
- rtx operands[];
+frv_expand_block_move (rtx operands[])
{
rtx orig_dest = operands[0];
rtx orig_src = operands[1];
@@ -2196,11 +2087,11 @@ frv_expand_block_move (operands)
int move_bytes;
enum machine_mode mode;
- /* If this is not a fixed size move, just call memcpy */
+ /* If this is not a fixed size move, just call memcpy. */
if (! constp)
return FALSE;
- /* If this is not a fixed size alignment, abort */
+ /* If this is not a fixed size alignment, abort. */
if (GET_CODE (align_rtx) != CONST_INT)
abort ();
@@ -2222,7 +2113,7 @@ frv_expand_block_move (operands)
num_reg = offset = 0;
for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
{
- /* Calculate the correct offset for src/dest */
+ /* Calculate the correct offset for src/dest. */
if (offset == 0)
{
src_addr = src_reg;
@@ -2273,8 +2164,7 @@ frv_expand_block_move (operands)
operands[2] is the alignment */
int
-frv_expand_block_clear (operands)
- rtx operands[];
+frv_expand_block_clear (rtx operands[])
{
rtx orig_dest = operands[0];
rtx bytes_rtx = operands[1];
@@ -2290,11 +2180,11 @@ frv_expand_block_clear (operands)
int clear_bytes;
enum machine_mode mode;
- /* If this is not a fixed size move, just call memcpy */
+ /* If this is not a fixed size move, just call memcpy. */
if (! constp)
return FALSE;
- /* If this is not a fixed size alignment, abort */
+ /* If this is not a fixed size alignment, abort. */
if (GET_CODE (align_rtx) != CONST_INT)
abort ();
@@ -2315,12 +2205,12 @@ frv_expand_block_clear (operands)
num_reg = offset = 0;
for ( ; bytes > 0; (bytes -= clear_bytes), (offset += clear_bytes))
{
- /* Calculate the correct offset for src/dest */
+ /* Calculate the correct offset for src/dest. */
dest_addr = ((offset == 0)
? dest_reg
: plus_constant (dest_reg, offset));
- /* Generate the appropriate store of gr0 */
+ /* Generate the appropriate store of gr0. */
if (bytes >= 4 && align >= 4)
mode = SImode;
else if (bytes >= 2 && align >= 2)
@@ -2338,17 +2228,15 @@ frv_expand_block_clear (operands)
/* The following variable is used to output modifiers of assembler
- code of the current output insn.. */
+ code of the current output insn. */
static rtx *frv_insn_operands;
/* The following function is used to add assembler insn code suffix .p
- if it is necessary. */
+ if it is necessary. */
const char *
-frv_asm_output_opcode (f, ptr)
- FILE *f;
- const char *ptr;
+frv_asm_output_opcode (FILE *f, const char *ptr)
{
int c;
@@ -2380,18 +2268,15 @@ frv_asm_output_opcode (f, ptr)
/* The following function sets up the packing bit for the current
output insn. Remember that the function is not called for asm
- insns. */
+ insns. */
void
-frv_final_prescan_insn (insn, opvec, noperands)
- rtx insn;
- rtx *opvec;
- int noperands ATTRIBUTE_UNUSED;
+frv_final_prescan_insn (rtx insn, rtx *opvec, int noperands ATTRIBUTE_UNUSED)
{
if (! PACKING_FLAG_USED_P())
return;
- if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ if (!INSN_P (insn))
return;
frv_insn_operands = opvec;
@@ -2403,8 +2288,8 @@ frv_final_prescan_insn (insn, opvec, noperands)
Printable instructions will be asm_operands or match one of the .md
patterns. Since asm instructions cannot be packed -- and will
- therefore have TImode -- this loop terminates on any recognisable
- instruction, and on any unrecognisable instruction with TImode. */
+ therefore have TImode -- this loop terminates on any recognizable
+ instruction, and on any unrecognizable instruction with TImode. */
for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
{
if (NOTE_P (insn))
@@ -2417,7 +2302,7 @@ frv_final_prescan_insn (insn, opvec, noperands)
/* Set frv_insn_packing_flag to FALSE if the next instruction should
be packed with this one. Set it to TRUE otherwise. If the next
- instruction is an asm insntruction, this statement will set the
+ instruction is an asm instruction, this statement will set the
flag to TRUE, and that value will still hold when the asm operands
themselves are printed. */
frv_insn_packing_flag = ! (insn && INSN_P (insn)
@@ -2436,8 +2321,7 @@ frv_final_prescan_insn (insn, opvec, noperands)
/* The default is correct, but we need to make sure the frame gets created. */
rtx
-frv_dynamic_chain_address (frame)
- rtx frame;
+frv_dynamic_chain_address (rtx frame)
{
cfun->machine->frame_needed = 1;
return frame;
@@ -2455,9 +2339,7 @@ frv_dynamic_chain_address (frame)
address of other frames. */
rtx
-frv_return_addr_rtx (count, frame)
- int count ATTRIBUTE_UNUSED;
- rtx frame;
+frv_return_addr_rtx (int count ATTRIBUTE_UNUSED, rtx frame)
{
cfun->machine->frame_needed = 1;
return gen_rtx_MEM (Pmode, plus_constant (frame, 8));
@@ -2472,10 +2354,7 @@ frv_return_addr_rtx (count, frame)
GO_IF_LEGITIMATE_ADDRESS forbids register+register addresses, which
this function cannot handle. */
rtx
-frv_index_memory (memref, mode, index)
- rtx memref;
- enum machine_mode mode;
- int index;
+frv_index_memory (rtx memref, enum machine_mode mode, int index)
{
rtx base = XEXP (memref, 0);
if (GET_CODE (base) == PRE_MODIFY)
@@ -2487,9 +2366,7 @@ frv_index_memory (memref, mode, index)
/* Print a memory address as an operand to reference that memory location. */
void
-frv_print_operand_address (stream, x)
- FILE * stream;
- rtx x;
+frv_print_operand_address (FILE * stream, rtx x)
{
if (GET_CODE (x) == MEM)
x = XEXP (x, 0);
@@ -2522,9 +2399,7 @@ frv_print_operand_address (stream, x)
static void
-frv_print_operand_memory_reference_reg (stream, x)
- FILE *stream;
- rtx x;
+frv_print_operand_memory_reference_reg (FILE * stream, rtx x)
{
int regno = true_regnum (x);
if (GPR_P (regno))
@@ -2536,10 +2411,7 @@ frv_print_operand_memory_reference_reg (stream, x)
/* Print a memory reference suitable for the ld/st instructions. */
static void
-frv_print_operand_memory_reference (stream, x, addr_offset)
- FILE *stream;
- rtx x;
- int addr_offset;
+frv_print_operand_memory_reference (FILE * stream, rtx x, int addr_offset)
{
rtx x0 = NULL_RTX;
rtx x1 = NULL_RTX;
@@ -2611,7 +2483,7 @@ frv_print_operand_memory_reference (stream, x, addr_offset)
case SYMBOL_REF:
if (x0 && GET_CODE (x0) == REG && REGNO (x0) == SDA_BASE_REG
- && symbol_ref_small_data_p (x1))
+ && SYMBOL_REF_SMALL_P (x1))
{
fputs ("#gprel12(", stream);
assemble_name (stream, XSTR (x1, 0));
@@ -2627,7 +2499,8 @@ frv_print_operand_memory_reference (stream, x, addr_offset)
{
fputs ("#gprel12(", stream);
assemble_name (stream, XSTR (XEXP (XEXP (x1, 0), 0), 0));
- fprintf (stream, "+%d)", INTVAL (XEXP (XEXP (x1, 0), 1)));
+ fprintf (stream, "+"HOST_WIDE_INT_PRINT_DEC")",
+ INTVAL (XEXP (XEXP (x1, 0), 1)));
}
else
fatal_insn ("Bad insn to frv_print_operand_memory_reference:", x);
@@ -2648,8 +2521,7 @@ frv_print_operand_memory_reference (stream, x, addr_offset)
#define FRV_JUMP_NOT_LIKELY 0
static int
-frv_print_operand_jump_hint (insn)
- rtx insn;
+frv_print_operand_jump_hint (rtx insn)
{
rtx note;
rtx labelref;
@@ -2746,10 +2618,7 @@ frv_print_operand_jump_hint (insn)
are valid with the `PRINT_OPERAND_PUNCT_VALID_P' macro. */
void
-frv_print_operand (file, x, code)
- FILE * file;
- rtx x;
- int code;
+frv_print_operand (FILE * file, rtx x, int code)
{
HOST_WIDE_INT value;
int offset;
@@ -2786,7 +2655,7 @@ frv_print_operand (file, x, code)
{
case '.':
- /* Output r0 */
+ /* Output r0. */
fputs (reg_names[GPR_R0], file);
break;
@@ -2794,30 +2663,30 @@ frv_print_operand (file, x, code)
fprintf (file, "%d", frv_print_operand_jump_hint (current_output_insn));
break;
- case SDATA_FLAG_CHAR:
- /* Output small data area base register (gr16). */
+ case '@':
+ /* Output small data area base register (gr16). */
fputs (reg_names[SDA_BASE_REG], file);
break;
case '~':
- /* Output pic register (gr17). */
+ /* Output pic register (gr17). */
fputs (reg_names[PIC_REGNO], file);
break;
case '*':
- /* Output the temporary integer CCR register */
+ /* Output the temporary integer CCR register. */
fputs (reg_names[ICR_TEMP], file);
break;
case '&':
- /* Output the temporary integer CC register */
+ /* Output the temporary integer CC register. */
fputs (reg_names[ICC_TEMP], file);
break;
- /* case 'a': print an address */
+ /* case 'a': print an address. */
case 'C':
- /* Print appropriate test for integer branch false operation */
+ /* Print appropriate test for integer branch false operation. */
switch (GET_CODE (x))
{
default:
@@ -2840,7 +2709,7 @@ frv_print_operand (file, x, code)
CONSTANT_ADDRESS_P(x) is not true, PRINT_OPERAND is called. */
case 'c':
- /* Print appropriate test for integer branch true operation */
+ /* Print appropriate test for integer branch true operation. */
switch (GET_CODE (x))
{
default:
@@ -2873,7 +2742,7 @@ frv_print_operand (file, x, code)
break;
case 'F':
- /* Print appropriate test for floating point branch false operation */
+ /* Print appropriate test for floating point branch false operation. */
switch (GET_CODE (x))
{
default:
@@ -2889,7 +2758,7 @@ frv_print_operand (file, x, code)
break;
case 'f':
- /* Print appropriate test for floating point branch true operation */
+ /* Print appropriate test for floating point branch true operation. */
switch (GET_CODE (x))
{
default:
@@ -2906,7 +2775,7 @@ frv_print_operand (file, x, code)
case 'I':
/* Print 'i' if the operand is a constant, or is a memory reference that
- adds a constant */
+ adds a constant. */
if (GET_CODE (x) == MEM)
x = ((GET_CODE (XEXP (x, 0)) == PLUS)
? XEXP (XEXP (x, 0), 1)
@@ -2927,7 +2796,7 @@ frv_print_operand (file, x, code)
case 'i':
/* For jump instructions, print 'i' if the operand is a constant or
- is an expression that adds a constant */
+ is an expression that adds a constant. */
if (GET_CODE (x) == CONST_INT)
fputs ("i", file);
@@ -2949,7 +2818,7 @@ frv_print_operand (file, x, code)
fatal_insn ("Bad insn to frv_print_operand, 'L' modifier:", x);
break;
- /* case 'l': print a LABEL_REF */
+ /* case 'l': print a LABEL_REF. */
case 'M':
case 'N':
@@ -2993,7 +2862,7 @@ frv_print_operand (file, x, code)
}
break;
- /* case 'n': negate and print a constant int */
+ /* case 'n': negate and print a constant int. */
case 'P':
/* Print PIC label using operand as the number. */
@@ -3004,13 +2873,13 @@ frv_print_operand (file, x, code)
break;
case 'U':
- /* Print 'u' if the operand is a update load/store */
+ /* Print 'u' if the operand is a update load/store. */
if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
fputs ("u", file);
break;
case 'z':
- /* If value is 0, print gr0, otherwise it must be a register */
+ /* If value is 0, print gr0, otherwise it must be a register. */
if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
fputs (reg_names[GPR_R0], file);
@@ -3022,14 +2891,14 @@ frv_print_operand (file, x, code)
break;
case 'x':
- /* Print constant in hex */
+ /* Print constant in hex. */
if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
{
fprintf (file, "%s0x%.4lx", IMMEDIATE_PREFIX, (long) value);
break;
}
- /* fall through */
+ /* Fall through. */
case '\0':
if (GET_CODE (x) == REG)
@@ -3076,19 +2945,18 @@ frv_print_operand (file, x, code)
FNTYPE is nonzero, but never both of them at once. */
void
-frv_init_cumulative_args (cum, fntype, libname, indirect, incoming)
- CUMULATIVE_ARGS *cum;
- tree fntype;
- rtx libname;
- int indirect;
- int incoming;
+frv_init_cumulative_args (CUMULATIVE_ARGS *cum,
+ tree fntype,
+ rtx libname,
+ tree fndecl,
+ int incoming)
{
*cum = FIRST_ARG_REGNUM;
if (TARGET_DEBUG_ARG)
{
fprintf (stderr, "\ninit_cumulative_args:");
- if (indirect)
+ if (!fndecl && fntype)
fputs (" indirect", stderr);
if (incoming)
@@ -3117,9 +2985,8 @@ frv_init_cumulative_args (cum, fntype, libname, indirect, incoming)
`PARM_BOUNDARY' is used for all arguments. */
int
-frv_function_arg_boundary (mode, type)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
+frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED)
{
return BITS_PER_WORD;
}
@@ -3156,12 +3023,11 @@ frv_function_arg_boundary (mode, type)
stack and then loaded into a register. */
rtx
-frv_function_arg (cum, mode, type, named, incoming)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named;
- int incoming ATTRIBUTE_UNUSED;
+frv_function_arg (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int named,
+ int incoming ATTRIBUTE_UNUSED)
{
enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
int arg_num = *cum;
@@ -3206,11 +3072,10 @@ frv_function_arg (cum, mode, type, named, incoming)
for arguments without any special help. */
void
-frv_function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named;
+frv_function_arg_advance (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int named)
{
enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
int bytes = GET_MODE_SIZE (xmode);
@@ -3243,11 +3108,10 @@ frv_function_arg_advance (cum, mode, type, named)
the called function. */
int
-frv_function_arg_partial_nregs (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_partial_nregs (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int named ATTRIBUTE_UNUSED)
{
enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
int bytes = GET_MODE_SIZE (xmode);
@@ -3280,11 +3144,10 @@ frv_function_arg_partial_nregs (cum, mode, type, named)
MUST_PASS_IN_STACK (MODE, TYPE) */
int
-frv_function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode,
+ tree type,
+ int named ATTRIBUTE_UNUSED)
{
return MUST_PASS_IN_STACK (mode, type);
}
@@ -3299,11 +3162,10 @@ frv_function_arg_pass_by_reference (cum, mode, type, named)
otherwise a copy must be made. */
int
-frv_function_arg_callee_copies (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ int named ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -3313,11 +3175,10 @@ frv_function_arg_callee_copies (cum, mode, type, named)
copying it to a pseudo register. */
int
-frv_function_arg_keep_as_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_keep_as_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ int named ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -3326,9 +3187,7 @@ frv_function_arg_keep_as_reference (cum, mode, type, named)
/* Return true if a register is ok to use as a base or index register. */
static FRV_INLINE int
-frv_regno_ok_for_base_p (regno, strict_p)
- int regno;
- int strict_p;
+frv_regno_ok_for_base_p (int regno, int strict_p)
{
if (GPR_P (regno))
return TRUE;
@@ -3400,11 +3259,10 @@ frv_regno_ok_for_base_p (regno, strict_p)
`PRINT_OPERAND_ADDRESS'. */
int
-frv_legitimate_address_p (mode, x, strict_p, condexec_p)
- enum machine_mode mode;
- rtx x;
- int strict_p;
- int condexec_p;
+frv_legitimate_address_p (enum machine_mode mode,
+ rtx x,
+ int strict_p,
+ int condexec_p)
{
rtx x0, x1;
int ret = 0;
@@ -3421,7 +3279,7 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
if (GET_CODE (x) != REG)
break;
- /* fall through */
+ /* Fall through. */
case REG:
ret = frv_regno_ok_for_base_p (REGNO (x), strict_p);
@@ -3481,11 +3339,11 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
if (GET_CODE (x1) != REG)
break;
- /* fall through */
+ /* Fall through. */
case REG:
- /* Do not allow reg+reg addressing for modes > 1 word if we can't depend
- on having move double instructions */
+ /* Do not allow reg+reg addressing for modes > 1 word if we
+ can't depend on having move double instructions. */
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
ret = FALSE;
else
@@ -3511,7 +3369,7 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
case SYMBOL_REF:
if (!condexec_p
&& regno0 == SDA_BASE_REG
- && symbol_ref_small_data_p (x1))
+ && SYMBOL_REF_SMALL_P (x1))
ret = TRUE;
break;
@@ -3557,10 +3415,9 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
can generate better code. */
rtx
-frv_legitimize_address (x, oldx, mode)
- rtx x;
- rtx oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+frv_legitimize_address (rtx x,
+ rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx ret = NULL_RTX;
@@ -3569,7 +3426,7 @@ frv_legitimize_address (x, oldx, mode)
things up when force_reg is called to try and put it in a register because
we aren't optimizing. */
if (optimize
- && ((GET_CODE (x) == SYMBOL_REF && symbol_ref_small_data_p (x))
+ && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
|| (GET_CODE (x) == CONST && const_small_data_p (x))))
{
ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, SDA_BASE_REG), x);
@@ -3591,10 +3448,7 @@ frv_legitimize_address (x, oldx, mode)
the operand is used by a predicated instruction. */
static int
-frv_legitimate_memory_operand (op, mode, condexec_p)
- rtx op;
- enum machine_mode mode;
- int condexec_p;
+frv_legitimate_memory_operand (rtx op, enum machine_mode mode, int condexec_p)
{
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& GET_CODE (op) == MEM
@@ -3606,9 +3460,8 @@ frv_legitimate_memory_operand (op, mode, condexec_p)
/* Return 1 is OP is a memory operand, or will be turned into one by
reload. */
-int frv_load_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+frv_load_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -3629,9 +3482,8 @@ int frv_load_operand (op, mode)
/* Return 1 if operand is a GPR register or a FPR register. */
-int gpr_or_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -3658,9 +3510,8 @@ int gpr_or_fpr_operand (op, mode)
/* Return 1 if operand is a GPR register or 12 bit signed immediate. */
-int gpr_or_int12_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_int12_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return IN_RANGE_P (INTVAL (op), -2048, 2047);
@@ -3685,9 +3536,8 @@ int gpr_or_int12_operand (op, mode)
/* Return 1 if operand is a GPR register, or a FPR register, or a 12 bit
signed immediate. */
-int gpr_fpr_or_int12_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_fpr_or_int12_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -3717,9 +3567,8 @@ int gpr_fpr_or_int12_operand (op, mode)
/* Return 1 if operand is a register or 6 bit signed immediate. */
-int fpr_or_int6_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+fpr_or_int6_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return IN_RANGE_P (INTVAL (op), -32, 31);
@@ -3743,9 +3592,8 @@ int fpr_or_int6_operand (op, mode)
/* Return 1 if operand is a register or 10 bit signed immediate. */
-int gpr_or_int10_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_int10_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return IN_RANGE_P (INTVAL (op), -512, 511);
@@ -3769,9 +3617,8 @@ int gpr_or_int10_operand (op, mode)
/* Return 1 if operand is a register or an integer immediate. */
-int gpr_or_int_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_int_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return TRUE;
@@ -3795,9 +3642,8 @@ int gpr_or_int_operand (op, mode)
/* Return 1 if operand is a 12 bit signed immediate. */
-int int12_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int12_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -3807,9 +3653,8 @@ int int12_operand (op, mode)
/* Return 1 if operand is a 6 bit signed immediate. */
-int int6_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int6_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -3819,36 +3664,32 @@ int int6_operand (op, mode)
/* Return 1 if operand is a 5 bit signed immediate. */
-int int5_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), -16, 15);
}
/* Return 1 if operand is a 5 bit unsigned immediate. */
-int uint5_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 31);
}
/* Return 1 if operand is a 4 bit unsigned immediate. */
-int uint4_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint4_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 15);
}
/* Return 1 if operand is a 1 bit unsigned immediate (0 or 1). */
-int uint1_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 1);
}
@@ -3856,9 +3697,8 @@ int uint1_operand (op, mode)
/* Return 1 if operand is an integer constant that takes 2 instructions
to load up and can be split into sethi/setlo instructions.. */
-int int_2word_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int_2word_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT value;
REAL_VALUE_TYPE rv;
@@ -3878,7 +3718,7 @@ int int_2word_operand (op, mode)
case SYMBOL_REF:
/* small data references are already 1 word */
- return (flag_pic == 0) && (! symbol_ref_small_data_p (op));
+ return (flag_pic == 0) && (! SYMBOL_REF_SMALL_P (op));
case CONST_INT:
return ! IN_RANGE_P (INTVAL (op), -32768, 32767);
@@ -3904,9 +3744,7 @@ int int_2word_operand (op, mode)
/* Return 1 if operand is the pic address register. */
int
-pic_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+pic_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (! flag_pic)
return FALSE;
@@ -3921,11 +3759,10 @@ pic_register_operand (op, mode)
}
/* Return 1 if operand is a symbolic reference when a PIC option is specified
- that takes 3 seperate instructions to form. */
+ that takes 3 separate instructions to form. */
-int pic_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+pic_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (! flag_pic)
return FALSE;
@@ -3940,7 +3777,7 @@ int pic_symbolic_operand (op, mode)
case SYMBOL_REF:
/* small data references are already 1 word */
- return ! symbol_ref_small_data_p (op);
+ return ! SYMBOL_REF_SMALL_P (op);
case CONST:
/* small data references are already 1 word */
@@ -3952,9 +3789,7 @@ int pic_symbolic_operand (op, mode)
/* Return 1 if operand is the small data register. */
int
-small_data_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_data_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != REG)
return FALSE;
@@ -3968,9 +3803,8 @@ small_data_register_operand (op, mode)
/* Return 1 if operand is a symbolic reference to a small data area static or
global object. */
-int small_data_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+small_data_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -3981,17 +3815,16 @@ int small_data_symbolic_operand (op, mode)
return const_small_data_p (op);
case SYMBOL_REF:
- return symbol_ref_small_data_p (op);
+ return SYMBOL_REF_SMALL_P (op);
}
return FALSE;
}
-/* Return 1 if operand is a 16 bit unsigned immediate */
+/* Return 1 if operand is a 16 bit unsigned immediate. */
-int uint16_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -3999,11 +3832,11 @@ int uint16_operand (op, mode)
return IN_RANGE_P (INTVAL (op), 0, 0xffff);
}
-/* Return 1 if operand is an integer constant with the bottom 16 bits clear */
+/* Return 1 if operand is an integer constant with the bottom 16 bits
+ clear. */
-int upper_int16_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+upper_int16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -4011,12 +3844,10 @@ int upper_int16_operand (op, mode)
return ((INTVAL (op) & 0xffff) == 0);
}
-/* Return true if operand is a GPR register. */
+/* Return true if operand is a GPR register. */
int
-integer_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+integer_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -4039,9 +3870,7 @@ integer_register_operand (op, mode)
here, in order to prevent a combine bug. */
int
-gpr_no_subreg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gpr_no_subreg_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -4052,12 +3881,10 @@ gpr_no_subreg_operand (op, mode)
return GPR_OR_PSEUDO_P (REGNO (op));
}
-/* Return true if operand is a FPR register. */
+/* Return true if operand is a FPR register. */
int
-fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpr_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -4076,12 +3903,10 @@ fpr_operand (op, mode)
return FPR_OR_PSEUDO_P (REGNO (op));
}
-/* Return true if operand is an even GPR or FPR register. */
+/* Return true if operand is an even GPR or FPR register. */
int
-even_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_reg_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4112,12 +3937,10 @@ even_reg_operand (op, mode)
return FALSE;
}
-/* Return true if operand is an odd GPR register. */
+/* Return true if operand is an odd GPR register. */
int
-odd_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+odd_reg_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4136,7 +3959,7 @@ odd_reg_operand (op, mode)
return FALSE;
regno = REGNO (op);
- /* assume that reload will give us an even register */
+ /* Assume that reload will give us an even register. */
if (regno >= FIRST_PSEUDO_REGISTER)
return FALSE;
@@ -4149,12 +3972,10 @@ odd_reg_operand (op, mode)
return FALSE;
}
-/* Return true if operand is an even GPR register. */
+/* Return true if operand is an even GPR register. */
int
-even_gpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_gpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4182,12 +4003,10 @@ even_gpr_operand (op, mode)
return (((regno - GPR_FIRST) & 1) == 0);
}
-/* Return true if operand is an odd GPR register. */
+/* Return true if operand is an odd GPR register. */
int
-odd_gpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+odd_gpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4206,7 +4025,7 @@ odd_gpr_operand (op, mode)
return FALSE;
regno = REGNO (op);
- /* assume that reload will give us an even register */
+ /* Assume that reload will give us an even register. */
if (regno >= FIRST_PSEUDO_REGISTER)
return FALSE;
@@ -4216,12 +4035,10 @@ odd_gpr_operand (op, mode)
return (((regno - GPR_FIRST) & 1) != 0);
}
-/* Return true if operand is a quad aligned FPR register. */
+/* Return true if operand is a quad aligned FPR register. */
int
-quad_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+quad_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4249,12 +4066,10 @@ quad_fpr_operand (op, mode)
return (((regno - FPR_FIRST) & 3) == 0);
}
-/* Return true if operand is an even FPR register. */
+/* Return true if operand is an even FPR register. */
int
-even_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4282,12 +4097,10 @@ even_fpr_operand (op, mode)
return (((regno - FPR_FIRST) & 1) == 0);
}
-/* Return true if operand is an odd FPR register. */
+/* Return true if operand is an odd FPR register. */
int
-odd_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+odd_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4306,7 +4119,7 @@ odd_fpr_operand (op, mode)
return FALSE;
regno = REGNO (op);
- /* assume that reload will give us an even register */
+ /* Assume that reload will give us an even register. */
if (regno >= FIRST_PSEUDO_REGISTER)
return FALSE;
@@ -4324,9 +4137,7 @@ odd_fpr_operand (op, mode)
the stack and the address taken and passed through to another function. */
int
-dbl_memory_one_insn_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+dbl_memory_one_insn_operand (rtx op, enum machine_mode mode)
{
rtx addr;
rtx addr_reg;
@@ -4377,9 +4188,7 @@ dbl_memory_one_insn_operand (op, mode)
use two instructions to load or store. */
int
-dbl_memory_two_insn_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+dbl_memory_two_insn_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
return FALSE;
@@ -4397,9 +4206,7 @@ dbl_memory_two_insn_operand (op, mode)
operation. */
int
-move_destination_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_destination_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4441,9 +4248,7 @@ move_destination_operand (op, mode)
operation. */
int
-move_source_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_source_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4492,9 +4297,7 @@ move_source_operand (op, mode)
move operation. */
int
-condexec_dest_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_dest_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4536,9 +4339,7 @@ condexec_dest_operand (op, mode)
move operation. */
int
-condexec_source_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_source_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4584,9 +4385,7 @@ condexec_source_operand (op, mode)
appropriate type. */
int
-reg_or_0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_0_operand (rtx op, enum machine_mode mode)
{
switch (GET_CODE (op))
{
@@ -4608,12 +4407,10 @@ reg_or_0_operand (op, mode)
return FALSE;
}
-/* Return true if operand is the link register */
+/* Return true if operand is the link register. */
int
-lr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+lr_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != REG)
return FALSE;
@@ -4630,9 +4427,7 @@ lr_operand (op, mode)
/* Return true if operand is a gpr register or a valid memory operation. */
int
-gpr_or_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gpr_or_memory_operand (rtx op, enum machine_mode mode)
{
return (integer_register_operand (op, mode)
|| frv_legitimate_memory_operand (op, mode, FALSE));
@@ -4641,20 +4436,16 @@ gpr_or_memory_operand (op, mode)
/* Return true if operand is a fpr register or a valid memory operation. */
int
-fpr_or_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpr_or_memory_operand (rtx op, enum machine_mode mode)
{
return (fpr_operand (op, mode)
|| frv_legitimate_memory_operand (op, mode, FALSE));
}
-/* Return true if operand is an icc register */
+/* Return true if operand is an icc register. */
int
-icc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+icc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4668,12 +4459,10 @@ icc_operand (op, mode)
return ICC_OR_PSEUDO_P (regno);
}
-/* Return true if operand is an fcc register */
+/* Return true if operand is an fcc register. */
int
-fcc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4687,12 +4476,10 @@ fcc_operand (op, mode)
return FCC_OR_PSEUDO_P (regno);
}
-/* Return true if operand is either an fcc or icc register */
+/* Return true if operand is either an fcc or icc register. */
int
-cc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4709,12 +4496,10 @@ cc_operand (op, mode)
return FALSE;
}
-/* Return true if operand is an integer CCR register */
+/* Return true if operand is an integer CCR register. */
int
-icr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+icr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4728,12 +4513,10 @@ icr_operand (op, mode)
return ICR_OR_PSEUDO_P (regno);
}
-/* Return true if operand is an fcc register */
+/* Return true if operand is an fcc register. */
int
-fcr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4747,12 +4530,10 @@ fcr_operand (op, mode)
return FCR_OR_PSEUDO_P (regno);
}
-/* Return true if operand is either an fcc or icc register */
+/* Return true if operand is either an fcc or icc register. */
int
-cr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4772,9 +4553,7 @@ cr_operand (op, mode)
/* Return true if operand is a memory reference suitable for a call. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
return FALSE;
@@ -4789,12 +4568,10 @@ call_operand (op, mode)
return gpr_or_int12_operand (op, mode);
}
-/* Return true if operator is an kind of relational operator */
+/* Return true if operator is a kind of relational operator. */
int
-relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4849,12 +4626,10 @@ relational_operator (op, mode)
return FALSE;
}
-/* Return true if operator is a signed integer relational operator */
+/* Return true if operator is a signed integer relational operator. */
int
-signed_relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+signed_relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4895,12 +4670,10 @@ signed_relational_operator (op, mode)
return FALSE;
}
-/* Return true if operator is a signed integer relational operator */
+/* Return true if operator is a signed integer relational operator. */
int
-unsigned_relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+unsigned_relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4939,12 +4712,10 @@ unsigned_relational_operator (op, mode)
return FALSE;
}
-/* Return true if operator is a floating point relational operator */
+/* Return true if operator is a floating point relational operator. */
int
-float_relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+float_relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4992,9 +4763,7 @@ float_relational_operator (op, mode)
/* Return true if operator is EQ/NE of a conditional execution register. */
int
-ccr_eqne_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+ccr_eqne_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
rtx op0;
@@ -5033,9 +4802,7 @@ ccr_eqne_operator (op, mode)
unsigned). */
int
-minmax_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+minmax_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && mode != GET_MODE (op))
return FALSE;
@@ -5065,9 +4832,7 @@ minmax_operator (op, mode)
conditionally and takes 1 cycle. */
int
-condexec_si_binary_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_binary_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5095,9 +4860,7 @@ condexec_si_binary_operator (op, mode)
executed conditionally by a media instruction. */
int
-condexec_si_media_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_media_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5120,9 +4883,7 @@ condexec_si_media_operator (op, mode)
conditionally. */
int
-condexec_si_divide_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_divide_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5144,9 +4905,7 @@ condexec_si_divide_operator (op, mode)
conditionally. */
int
-condexec_si_unary_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_unary_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5168,9 +4927,7 @@ condexec_si_unary_operator (op, mode)
evaluated conditionally by floating-point instructions. */
int
-condexec_sf_conv_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_sf_conv_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5193,9 +4950,7 @@ condexec_sf_conv_operator (op, mode)
instructions. */
int
-condexec_sf_add_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_sf_add_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5217,9 +4972,7 @@ condexec_sf_add_operator (op, mode)
executed. */
int
-condexec_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_memory_operand (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
rtx addr;
@@ -5256,9 +5009,7 @@ condexec_memory_operand (op, mode)
register. */
int
-intop_compare_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+intop_compare_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5291,9 +5042,7 @@ intop_compare_operator (op, mode)
with a setcc operation inside of a conditional execution. */
int
-condexec_intop_cmp_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_intop_cmp_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5322,12 +5071,10 @@ condexec_intop_cmp_operator (op, mode)
return TRUE;
}
-/* Return 1 if operand is a valid ACC register number */
+/* Return 1 if operand is a valid ACC register number. */
int
-acc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+acc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -5349,12 +5096,10 @@ acc_operand (op, mode)
return ACC_OR_PSEUDO_P (regno);
}
-/* Return 1 if operand is a valid even ACC register number */
+/* Return 1 if operand is a valid even ACC register number. */
int
-even_acc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_acc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -5376,12 +5121,10 @@ even_acc_operand (op, mode)
return (ACC_OR_PSEUDO_P (regno) && ((regno - ACC_FIRST) & 1) == 0);
}
-/* Return 1 if operand is zero or four */
+/* Return 1 if operand is zero or four. */
int
-quad_acc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+quad_acc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -5403,12 +5146,10 @@ quad_acc_operand (op, mode)
return (ACC_OR_PSEUDO_P (regno) && ((regno - ACC_FIRST) & 3) == 0);
}
-/* Return 1 if operand is a valid ACCG register number */
+/* Return 1 if operand is a valid ACCG register number. */
int
-accg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+accg_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -5432,7 +5173,7 @@ accg_operand (op, mode)
epilog code. For frv, we only do it if there was no stack allocation. */
int
-direct_return_p ()
+direct_return_p (void)
{
frv_stack_t *info;
@@ -5449,9 +5190,7 @@ direct_return_p ()
instructions are emitted. */
int
-frv_emit_movsi (dest, src)
- rtx dest;
- rtx src;
+frv_emit_movsi (rtx dest, rtx src)
{
int base_regno = -1;
@@ -5461,7 +5200,7 @@ frv_emit_movsi (dest, src)
&& (!reg_or_0_operand (src, SImode)
/* Virtual registers will almost always be replaced by an
add instruction, so expose this to CSE by copying to
- an intermediate register */
+ an intermediate register. */
|| (GET_CODE (src) == REG
&& IN_RANGE_P (REGNO (src),
FIRST_VIRTUAL_REGISTER,
@@ -5493,7 +5232,7 @@ frv_emit_movsi (dest, src)
break;
case SYMBOL_REF:
- if (symbol_ref_small_data_p (src))
+ if (SYMBOL_REF_SMALL_P (src))
base_regno = SDA_BASE_REG;
else if (flag_pic)
@@ -5522,9 +5261,7 @@ frv_emit_movsi (dest, src)
/* Return a string to output a single word move. */
const char *
-output_move_single (operands, insn)
- rtx operands[];
- rtx insn;
+output_move_single (rtx operands[], rtx insn)
{
rtx dest = operands[0];
rtx src = operands[1];
@@ -5742,9 +5479,7 @@ output_move_single (operands, insn)
/* Return a string to output a double word move. */
const char *
-output_move_double (operands, insn)
- rtx operands[];
- rtx insn;
+output_move_double (rtx operands[], rtx insn)
{
rtx dest = operands[0];
rtx src = operands[1];
@@ -5875,9 +5610,7 @@ output_move_double (operands, insn)
Operand3 -- source */
const char *
-output_condmove_single (operands, insn)
- rtx operands[];
- rtx insn;
+output_condmove_single (rtx operands[], rtx insn)
{
rtx dest = operands[2];
rtx src = operands[3];
@@ -6016,15 +5749,12 @@ output_condmove_single (operands, insn)
comparison was done it. */
static rtx
-frv_emit_comparison (test, op0, op1)
- enum rtx_code test;
- rtx op0;
- rtx op1;
+frv_emit_comparison (enum rtx_code test, rtx op0, rtx op1)
{
enum machine_mode cc_mode;
rtx cc_reg;
- /* Floating point doesn't have comparison against a constant */
+ /* Floating point doesn't have comparison against a constant. */
if (GET_MODE (op0) == CC_FPmode && GET_CODE (op1) != REG)
op1 = force_reg (GET_MODE (op0), op1);
@@ -6050,9 +5780,7 @@ frv_emit_comparison (test, op0, op1)
conditional execution, but that confuses the rest of the compiler. */
int
-frv_emit_cond_branch (test, label)
- enum rtx_code test;
- rtx label;
+frv_emit_cond_branch (enum rtx_code test, rtx label)
{
rtx test_rtx;
rtx label_ref;
@@ -6077,9 +5805,7 @@ frv_emit_cond_branch (test, label)
operands were previously stored in frv_compare_op0 and frv_compare_op1. */
int
-frv_emit_scc (test, target)
- enum rtx_code test;
- rtx target;
+frv_emit_scc (enum rtx_code test, rtx target)
{
rtx set;
rtx test_rtx;
@@ -6107,15 +5833,10 @@ frv_emit_scc (test, target)
/* Split a SCC instruction into component parts, returning a SEQUENCE to hold
- the seperate insns. */
+ the separate insns. */
rtx
-frv_split_scc (dest, test, cc_reg, cr_reg, value)
- rtx dest;
- rtx test;
- rtx cc_reg;
- rtx cr_reg;
- HOST_WIDE_INT value;
+frv_split_scc (rtx dest, rtx test, rtx cc_reg, rtx cr_reg, HOST_WIDE_INT value)
{
rtx ret;
@@ -6150,11 +5871,7 @@ frv_split_scc (dest, test, cc_reg, cr_reg, value)
move. */
int
-frv_emit_cond_move (dest, test_rtx, src1, src2)
- rtx dest;
- rtx test_rtx;
- rtx src1;
- rtx src2;
+frv_emit_cond_move (rtx dest, rtx test_rtx, rtx src1, rtx src2)
{
rtx set;
rtx clobber_cc;
@@ -6178,7 +5895,7 @@ frv_emit_cond_move (dest, test_rtx, src1, src2)
HOST_WIDE_INT value1 = INTVAL (src1);
HOST_WIDE_INT value2 = INTVAL (src2);
- /* having 0 as one of the constants can be done by loading the other
+ /* Having 0 as one of the constants can be done by loading the other
constant, and optionally moving in gr0. */
if (value1 == 0 || value2 == 0)
;
@@ -6227,12 +5944,11 @@ frv_emit_cond_move (dest, test_rtx, src1, src2)
}
-/* Split a conditonal move into constituent parts, returning a SEQUENCE
+/* Split a conditional move into constituent parts, returning a SEQUENCE
containing all of the insns. */
rtx
-frv_split_cond_move (operands)
- rtx operands[];
+frv_split_cond_move (rtx operands[])
{
rtx dest = operands[0];
rtx test = operands[1];
@@ -6259,7 +5975,7 @@ frv_split_cond_move (operands)
HOST_WIDE_INT value1 = INTVAL (src1);
HOST_WIDE_INT value2 = INTVAL (src2);
- /* having 0 as one of the constants can be done by loading the other
+ /* Having 0 as one of the constants can be done by loading the other
constant, and optionally moving in gr0. */
if (value1 == 0)
{
@@ -6327,9 +6043,7 @@ frv_split_cond_move (operands)
/* Split (set DEST SOURCE), where DEST is a double register and SOURCE is a
memory location that is not known to be dword-aligned. */
void
-frv_split_double_load (dest, source)
- rtx dest;
- rtx source;
+frv_split_double_load (rtx dest, rtx source)
{
int regno = REGNO (dest);
rtx dest1 = gen_highpart (SImode, dest);
@@ -6365,9 +6079,7 @@ frv_split_double_load (dest, source)
/* Split (set DEST SOURCE), where DEST refers to a dword memory location
and SOURCE is either a double register or the constant zero. */
void
-frv_split_double_store (dest, source)
- rtx dest;
- rtx source;
+frv_split_double_store (rtx dest, rtx source)
{
rtx dest1 = change_address (dest, SImode, NULL);
rtx dest2 = frv_index_memory (dest, SImode, 1);
@@ -6388,8 +6100,7 @@ frv_split_double_store (dest, source)
insns. */
rtx
-frv_split_minmax (operands)
- rtx operands[];
+frv_split_minmax (rtx operands[])
{
rtx dest = operands[0];
rtx minmax = operands[1];
@@ -6403,7 +6114,7 @@ frv_split_minmax (operands)
start_sequence ();
- /* Figure out which test to use */
+ /* Figure out which test to use. */
switch (GET_CODE (minmax))
{
default:
@@ -6469,8 +6180,7 @@ frv_split_minmax (operands)
insns. */
rtx
-frv_split_abs (operands)
- rtx operands[];
+frv_split_abs (rtx operands[])
{
rtx dest = operands[0];
rtx src = operands[1];
@@ -6490,7 +6200,7 @@ frv_split_abs (operands)
cr_reg,
gen_rtx_fmt_ee (LT, CC_CCRmode, cc_reg, const0_rtx)));
- /* Emit the conditional negate if the value is negative */
+ /* Emit the conditional negate if the value is negative. */
emit_insn (gen_rtx_COND_EXEC (VOIDmode,
gen_rtx_NE (CC_CCRmode, cr_reg, const0_rtx),
gen_negsi2 (dest, src)));
@@ -6512,9 +6222,7 @@ frv_split_abs (operands)
register used in an insn. */
static int
-frv_clear_registers_used (ptr, data)
- rtx *ptr;
- void *data;
+frv_clear_registers_used (rtx *ptr, void *data)
{
if (GET_CODE (*ptr) == REG)
{
@@ -6542,8 +6250,7 @@ frv_clear_registers_used (ptr, data)
/* On the FR-V, we don't have any extra fields per se, but it is useful hook to
initialize the static storage. */
void
-frv_ifcvt_init_extra_fields (ce_info)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
+frv_ifcvt_init_extra_fields (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
{
frv_ifcvt.added_insns_list = NULL_RTX;
frv_ifcvt.cur_scratch_regs = 0;
@@ -6560,14 +6267,11 @@ frv_ifcvt_init_extra_fields (ce_info)
if the conditional execution conversion is successful. */
static void
-frv_ifcvt_add_insn (pattern, insn, before_p)
- rtx pattern;
- rtx insn;
- int before_p;
+frv_ifcvt_add_insn (rtx pattern, rtx insn, int before_p)
{
rtx link = alloc_EXPR_LIST (VOIDmode, pattern, insn);
- link->jump = before_p; /* mark to add this before or after insn */
+ link->jump = before_p; /* Mark to add this before or after insn. */
frv_ifcvt.added_insns_list = alloc_EXPR_LIST (VOIDmode, link,
frv_ifcvt.added_insns_list);
@@ -6590,10 +6294,7 @@ frv_ifcvt_add_insn (pattern, insn, before_p)
tests cannot be converted. */
void
-frv_ifcvt_modify_tests (ce_info, p_true, p_false)
- ce_if_block_t *ce_info;
- rtx *p_true;
- rtx *p_false;
+frv_ifcvt_modify_tests (ce_if_block_t *ce_info, rtx *p_true, rtx *p_false)
{
basic_block test_bb = ce_info->test_bb; /* test basic block */
basic_block then_bb = ce_info->then_bb; /* THEN */
@@ -6628,8 +6329,8 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
/* Figure out which registers we can allocate for our own purposes. Only
consider registers that are not preserved across function calls and are
not fixed. However, allow the ICC/ICR temporary registers to be allocated
- if we did not need to use them in reloading other registers. */
- memset ((PTR) &tmp_reg->regs, 0, sizeof (tmp_reg->regs));
+ if we did not need to use them in reloading other registers. */
+ memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs));
COPY_HARD_REG_SET (tmp_reg->regs, call_used_reg_set);
AND_COMPL_HARD_REG_SET (tmp_reg->regs, fixed_reg_set);
SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP);
@@ -6704,16 +6405,16 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
/* Scan all of the blocks for registers that must not be allocated. */
for (j = 0; j < num_bb; j++)
{
- rtx last_insn = bb[j]->end;
- rtx insn = bb[j]->head;
+ rtx last_insn = BB_END (bb[j]);
+ rtx insn = BB_HEAD (bb[j]);
int regno;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Scanning %s block %d, start %d, end %d\n",
(bb[j] == else_bb) ? "else" : ((bb[j] == then_bb) ? "then" : "test"),
(int) bb[j]->index,
- (int) INSN_UID (bb[j]->head),
- (int) INSN_UID (bb[j]->end));
+ (int) INSN_UID (BB_HEAD (bb[j])),
+ (int) INSN_UID (BB_END (bb[j])));
/* Anything live at the beginning of the block is obviously unavailable
for allocation. */
@@ -6723,7 +6424,7 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
});
- /* loop through the insns in the block. */
+ /* Loop through the insns in the block. */
for (;;)
{
/* Mark any new registers that are created as being unavailable for
@@ -6913,7 +6614,7 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
gen_rtx_fmt_ee (code, CC_CCRmode, cc, const0_rtx));
/* Record the check insn to be inserted later. */
- frv_ifcvt_add_insn (check_insn, test_bb->end, TRUE);
+ frv_ifcvt_add_insn (check_insn, BB_END (test_bb), TRUE);
/* Update the tests. */
frv_ifcvt.cr_reg = cr;
@@ -6947,11 +6648,10 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
(const_int 0))) */
void
-frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
- ce_if_block_t *ce_info;
- basic_block bb;
- rtx *p_true;
- rtx *p_false;
+frv_ifcvt_modify_multiple_tests (ce_if_block_t *ce_info,
+ basic_block bb,
+ rtx *p_true,
+ rtx *p_false)
{
rtx old_true = XEXP (*p_true, 0);
rtx old_false = XEXP (*p_false, 0);
@@ -6987,7 +6687,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
if (GET_CODE (cr) != REG)
goto fail;
-
+
if (mode == CCmode || mode == CC_UNSmode)
{
cr_class = ICR_REGS;
@@ -7032,7 +6732,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
/* First add the andcr/andncr/orcr/orncr, which will be added after the
conditional check instruction, due to frv_ifcvt_add_insn being a LIFO
stack. */
- frv_ifcvt_add_insn ((*logical_func) (cr, cr, new_cr), bb->end, TRUE);
+ frv_ifcvt_add_insn ((*logical_func) (cr, cr, new_cr), BB_END (bb), TRUE);
/* Now add the conditional check insn. */
cc = XEXP (test_expr, 0);
@@ -7041,9 +6741,9 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
check_insn = gen_rtx_SET (VOIDmode, new_cr, if_else);
- /* add the new check insn to the list of check insns that need to be
+ /* Add the new check insn to the list of check insns that need to be
inserted. */
- frv_ifcvt_add_insn (check_insn, bb->end, TRUE);
+ frv_ifcvt_add_insn (check_insn, BB_END (bb), TRUE);
if (TARGET_DEBUG_COND_EXEC)
{
@@ -7061,7 +6761,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
fail:
*p_true = *p_false = NULL_RTX;
- /* If we allocated a CR register, release it. */
+ /* If we allocated a CR register, release it. */
if (new_cr)
{
CLEAR_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, REGNO (new_cr));
@@ -7080,9 +6780,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
that use constants to ones that just use registers. */
static rtx
-frv_ifcvt_load_value (value, insn)
- rtx value;
- rtx insn ATTRIBUTE_UNUSED;
+frv_ifcvt_load_value (rtx value, rtx insn ATTRIBUTE_UNUSED)
{
int num_alloc = frv_ifcvt.cur_scratch_regs;
int i;
@@ -7104,7 +6802,7 @@ frv_ifcvt_load_value (value, insn)
}
}
- /* Have we exhausted the number of registers available? */
+ /* Have we exhausted the number of registers available? */
if (num_alloc >= GPR_TEMP_NUM)
{
if (rtl_dump_file)
@@ -7152,10 +6850,7 @@ frv_ifcvt_load_value (value, insn)
into a temporary register, or the new MEM if we were successful. */
static rtx
-frv_ifcvt_rewrite_mem (mem, mode, insn)
- rtx mem;
- enum machine_mode mode;
- rtx insn;
+frv_ifcvt_rewrite_mem (rtx mem, enum machine_mode mode, rtx insn)
{
rtx addr = XEXP (mem, 0);
@@ -7203,8 +6898,7 @@ frv_ifcvt_rewrite_mem (mem, mode, insn)
SET, possibly conditionally executed. It may also have CLOBBERs, USEs. */
static rtx
-single_set_pattern (pattern)
- rtx pattern;
+single_set_pattern (rtx pattern)
{
rtx set;
int i;
@@ -7251,10 +6945,9 @@ single_set_pattern (pattern)
insn cannot be converted to be executed conditionally. */
rtx
-frv_ifcvt_modify_insn (ce_info, pattern, insn)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
- rtx pattern;
- rtx insn;
+frv_ifcvt_modify_insn (ce_if_block_t *ce_info,
+ rtx pattern,
+ rtx insn)
{
rtx orig_ce_pattern = pattern;
rtx set;
@@ -7316,7 +7009,7 @@ frv_ifcvt_modify_insn (ce_info, pattern, insn)
rtx src = SET_SRC (set);
enum machine_mode mode = GET_MODE (dest);
- /* Check for normal binary operators */
+ /* Check for normal binary operators. */
if (mode == SImode
&& (GET_RTX_CLASS (GET_CODE (src)) == '2'
|| GET_RTX_CLASS (GET_CODE (src)) == 'c'))
@@ -7378,7 +7071,16 @@ frv_ifcvt_modify_insn (ce_info, pattern, insn)
other registers. */
else if (frv_ifcvt.scratch_insns_bitmap
&& bitmap_bit_p (frv_ifcvt.scratch_insns_bitmap,
- INSN_UID (insn)))
+ INSN_UID (insn))
+ /* We must not unconditionally set a reg set used as
+ scratch in the THEN branch if the same reg is live
+ in the ELSE branch. */
+ && REG_P (SET_DEST (set))
+ && (! ce_info->else_bb
+ || BLOCK_FOR_INSN (insn) == ce_info->else_bb
+ || ! (REGNO_REG_SET_P
+ (ce_info->else_bb->global_live_at_start,
+ REGNO (SET_DEST (set))))))
pattern = set;
else if (mode == QImode || mode == HImode || mode == SImode
@@ -7506,8 +7208,7 @@ frv_ifcvt_modify_insn (ce_info, pattern, insn)
conditional if information CE_INFO. */
void
-frv_ifcvt_modify_final (ce_info)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
+frv_ifcvt_modify_final (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
{
rtx existing_insn;
rtx check_insn;
@@ -7563,8 +7264,7 @@ frv_ifcvt_modify_final (ce_info)
information CE_INFO. */
void
-frv_ifcvt_modify_cancel (ce_info)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
+frv_ifcvt_modify_cancel (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
{
int i;
rtx p = frv_ifcvt.added_insns_list;
@@ -7599,7 +7299,7 @@ frv_ifcvt_modify_cancel (ce_info)
jmpl @(gr0,<jmp_reg>) */
int
-frv_trampoline_size ()
+frv_trampoline_size (void)
{
return 5 /* instructions */ * 4 /* instruction size */;
}
@@ -7619,10 +7319,7 @@ frv_trampoline_size ()
jmpl @(gr0,<jmp_reg>) */
void
-frv_initialize_trampoline (addr, fnaddr, static_chain)
- rtx addr;
- rtx fnaddr;
- rtx static_chain;
+frv_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain)
{
rtx sc_reg = force_reg (Pmode, static_chain);
@@ -7688,11 +7385,10 @@ frv_initialize_trampoline (addr, fnaddr, static_chain)
This case often occurs between floating-point and general registers. */
enum reg_class
-frv_secondary_reload_class (class, mode, x, in_p)
- enum reg_class class;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx x;
- int in_p ATTRIBUTE_UNUSED;
+frv_secondary_reload_class (enum reg_class class,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x,
+ int in_p ATTRIBUTE_UNUSED)
{
enum reg_class ret;
@@ -7768,8 +7464,7 @@ frv_secondary_reload_class (class, mode, x, in_p)
register allocation. */
int
-frv_class_likely_spilled_p (class)
- enum reg_class class;
+frv_class_likely_spilled_p (enum reg_class class)
{
switch (class)
{
@@ -7797,7 +7492,7 @@ frv_class_likely_spilled_p (class)
/* An expression for the alignment of a structure field FIELD if the
- alignment computed in the usual way is COMPUTED. GNU CC uses this
+ alignment computed in the usual way is COMPUTED. GCC uses this
value instead of the value in `BIGGEST_ALIGNMENT' or
`BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
@@ -7844,19 +7539,16 @@ frv_class_likely_spilled_p (class)
*/
int
-frv_adjust_field_align (field, computed)
- tree field;
- int computed;
+frv_adjust_field_align (tree field, int computed)
{
- /* C++ provides a null DECL_CONTEXT if the bit field is wider than its
- type. */
- if (DECL_BIT_FIELD (field) && DECL_CONTEXT (field))
+ /* Make sure that the bitfield is not wider than the type. */
+ if (DECL_BIT_FIELD (field)
+ && !DECL_ARTIFICIAL (field))
{
tree parent = DECL_CONTEXT (field);
tree prev = NULL_TREE;
tree cur;
- /* Loop finding the previous field to the current one */
for (cur = TYPE_FIELDS (parent); cur && cur != field; cur = TREE_CHAIN (cur))
{
if (TREE_CODE (cur) != FIELD_DECL)
@@ -7870,7 +7562,7 @@ frv_adjust_field_align (field, computed)
/* If this isn't a :0 field and if the previous element is a bitfield
also, see if the type is different, if so, we will need to align the
- bit-field to the next boundary */
+ bit-field to the next boundary. */
if (prev
&& ! DECL_PACKED (field)
&& ! integer_zerop (DECL_SIZE (field))
@@ -7941,9 +7633,7 @@ frv_adjust_field_align (field, computed)
pattern's constraint asks for one. */
int
-frv_hard_regno_mode_ok (regno, mode)
- int regno;
- enum machine_mode mode;
+frv_hard_regno_mode_ok (int regno, enum machine_mode mode)
{
int base;
int mask;
@@ -7979,8 +7669,8 @@ frv_hard_regno_mode_ok (regno, mode)
}
else
{
- /* The other registers store one word. */
- if (GPR_P (regno))
+ /* The other registers store one word. */
+ if (GPR_P (regno) || regno == AP_FIRST)
base = GPR_FIRST;
else if (FPR_P (regno))
@@ -7989,6 +7679,10 @@ frv_hard_regno_mode_ok (regno, mode)
else if (ACC_P (regno))
base = ACC_FIRST;
+ else if (SPR_P (regno))
+ return mode == SImode;
+
+ /* Fill in the table. */
else
return 0;
@@ -8021,9 +7715,7 @@ frv_hard_regno_mode_ok (regno, mode)
for each byte. */
int
-frv_hard_regno_nregs (regno, mode)
- int regno;
- enum machine_mode mode;
+frv_hard_regno_nregs (int regno, enum machine_mode mode)
{
if (ACCG_P (regno))
return GET_MODE_SIZE (mode);
@@ -8045,9 +7737,7 @@ frv_hard_regno_nregs (regno, mode)
This declaration is required. */
int
-frv_class_max_nregs (class, mode)
- enum reg_class class;
- enum machine_mode mode;
+frv_class_max_nregs (enum reg_class class, enum machine_mode mode)
{
if (class == ACCG_REGS)
/* An N-byte value requires N accumulator guards. */
@@ -8063,25 +7753,24 @@ frv_class_max_nregs (class, mode)
definition for this macro on machines where anything `CONSTANT_P' is valid. */
int
-frv_legitimate_constant_p (x)
- rtx x;
+frv_legitimate_constant_p (rtx x)
{
enum machine_mode mode = GET_MODE (x);
- /* All of the integer constants are ok */
+ /* All of the integer constants are ok. */
if (GET_CODE (x) != CONST_DOUBLE)
return TRUE;
- /* double integer constants are ok */
+ /* double integer constants are ok. */
if (mode == VOIDmode || mode == DImode)
return TRUE;
- /* 0 is always ok */
+ /* 0 is always ok. */
if (x == CONST0_RTX (mode))
return TRUE;
/* If floating point is just emulated, allow any constant, since it will be
- constructed in the GPRs */
+ constructed in the GPRs. */
if (!TARGET_HAS_FPRS)
return TRUE;
@@ -8113,9 +7802,7 @@ frv_legitimate_constant_p (x)
#define LOW_COST 1
int
-frv_register_move_cost (from, to)
- enum reg_class from;
- enum reg_class to;
+frv_register_move_cost (enum reg_class from, enum reg_class to)
{
switch (from)
{
@@ -8204,10 +7891,7 @@ frv_register_move_cost (from, to)
need a fixup entry for aligned (non-debugging) code. */
static bool
-frv_assemble_integer (value, size, aligned_p)
- rtx value;
- unsigned int size;
- int aligned_p;
+frv_assemble_integer (rtx value, unsigned int size, int aligned_p)
{
if (flag_pic && size == UNITS_PER_WORD)
{
@@ -8246,22 +7930,54 @@ frv_assemble_integer (value, size, aligned_p)
/* Function to set up the backend function structure. */
static struct machine_function *
-frv_init_machine_status ()
+frv_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (struct machine_function));
}
+
+/* Implement TARGET_SCHED_ISSUE_RATE. */
+
+static int
+frv_issue_rate (void)
+{
+ if (!TARGET_PACK)
+ return 1;
+
+ switch (frv_cpu_type)
+ {
+ default:
+ case FRV_CPU_FR300:
+ case FRV_CPU_SIMPLE:
+ return 1;
+
+ case FRV_CPU_FR400:
+ return 2;
+
+ case FRV_CPU_GENERIC:
+ case FRV_CPU_FR500:
+ case FRV_CPU_TOMCAT:
+ return 4;
+ }
+}
+
+/* Implement TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE. */
+
+static int
+frv_use_dfa_pipeline_interface (void)
+{
+ return true;
+}
/* Update the register state information, to know about which registers are set
or clobbered. */
static void
-frv_registers_update (x, reg_state, modified, p_num_mod, flag)
- rtx x;
- unsigned char reg_state[];
- int modified[];
- int *p_num_mod;
- int flag;
+frv_registers_update (rtx x,
+ unsigned char reg_state[],
+ int modified[],
+ int *p_num_mod,
+ int flag)
{
int regno, reg_max;
rtx reg;
@@ -8333,7 +8049,7 @@ frv_registers_update (x, reg_state, modified, p_num_mod, flag)
case REG:
regno = REGNO (x);
reg_max = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- /* fall through */
+ /* Fall through. */
reg_common:
if (flag & REGSTATE_MODIFIED)
@@ -8404,10 +8120,7 @@ frv_registers_update (x, reg_state, modified, p_num_mod, flag)
/* Return if any registers in a hard register set were used an insn. */
static int
-frv_registers_used_p (x, reg_state, flag)
- rtx x;
- unsigned char reg_state[];
- int flag;
+frv_registers_used_p (rtx x, unsigned char reg_state[], int flag)
{
int regno, reg_max;
rtx reg;
@@ -8423,7 +8136,7 @@ frv_registers_used_p (x, reg_state, flag)
default:
break;
- /* Skip clobber, that doesn't use the previous value */
+ /* Skip clobber, that doesn't use the previous value. */
case CLOBBER:
return FALSE;
@@ -8488,7 +8201,7 @@ frv_registers_used_p (x, reg_state, flag)
case REG:
regno = REGNO (x);
reg_max = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- /* fall through */
+ /* Fall through. */
reg_common:
while (regno < reg_max)
@@ -8509,7 +8222,7 @@ frv_registers_used_p (x, reg_state, flag)
expression that governs this expression (ie, true vs. false
for the same CC register). If this isn't two halves of the
same conditional expression, consider the register
- modified. */
+ modified. */
if (((rs_if == REGSTATE_IF_TRUE && flag_if == REGSTATE_IF_FALSE)
|| (rs_if == REGSTATE_IF_FALSE && flag_if == REGSTATE_IF_TRUE))
&& ((rs & REGSTATE_CC_MASK) == (flag & REGSTATE_CC_MASK)))
@@ -8564,10 +8277,7 @@ frv_registers_used_p (x, reg_state, flag)
/* Return if any registers in a hard register set were set in an insn. */
static int
-frv_registers_set_p (x, reg_state, modify_p)
- rtx x;
- unsigned char reg_state[];
- int modify_p;
+frv_registers_set_p (rtx x, unsigned char reg_state[], int modify_p)
{
int regno, reg_max;
rtx reg;
@@ -8591,7 +8301,7 @@ frv_registers_set_p (x, reg_state, modify_p)
case COND_EXEC:
cond = XEXP (x, 0);
- /* just to be sure, make sure it is the type of cond_exec we
+ /* Just to be sure, make sure it is the type of cond_exec we
expect. */
if ((GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
&& GET_CODE (XEXP (cond, 0)) == REG
@@ -8622,7 +8332,7 @@ frv_registers_set_p (x, reg_state, modify_p)
case REG:
regno = REGNO (x);
reg_max = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- /* fall through */
+ /* Fall through. */
reg_common:
if (modify_p)
@@ -8672,18 +8382,13 @@ frv_registers_set_p (x, reg_state, modify_p)
}
-/* In rare cases, correct code generation requires extra machine dependent
- processing between the second jump optimization pass and delayed branch
- scheduling. On those machines, define this macro as a C statement to act on
- the code starting at INSN. */
-
/* On the FR-V, this pass is used to rescan the insn chain, and pack
conditional branches/calls/jumps, etc. with previous insns where it can. It
does not reorder the instructions. We assume the scheduler left the flow
information in a reasonable state. */
static void
-frv_pack_insns ()
+frv_pack_insns (void)
{
state_t frv_state; /* frv state machine */
int cur_start_vliw_p; /* current insn starts a VLIW insn */
@@ -8699,27 +8404,16 @@ frv_pack_insns ()
unsigned char reg_state[FIRST_PSEUDO_REGISTER];
/* If we weren't going to pack the insns, don't bother with this pass. */
- if (!optimize || !flag_schedule_insns_after_reload || TARGET_NO_VLIW_BRANCH)
+ if (!optimize
+ || !flag_schedule_insns_after_reload
+ || TARGET_NO_VLIW_BRANCH
+ || frv_issue_rate () == 1)
return;
- switch (frv_cpu_type)
- {
- default:
- case FRV_CPU_FR300: /* FR300/simple are single issue */
- case FRV_CPU_SIMPLE:
- return;
-
- case FRV_CPU_GENERIC: /* FR-V and FR500 are multi-issue */
- case FRV_CPU_FR400:
- case FRV_CPU_FR500:
- case FRV_CPU_TOMCAT:
- break;
- }
-
/* Set up the instruction and register states. */
dfa_start ();
frv_state = (state_t) xmalloc (state_size ());
- memset ((PTR) reg_state, REGSTATE_DEAD, sizeof (reg_state));
+ memset (reg_state, REGSTATE_DEAD, sizeof (reg_state));
/* Go through the insns, and repack the insns. */
state_reset (frv_state);
@@ -8754,7 +8448,7 @@ frv_pack_insns ()
continue;
}
- /* things like labels reset everything. */
+ /* Things like labels reset everything. */
if (GET_RTX_CLASS (code) != 'i')
{
next_start_vliw_p = TRUE;
@@ -8762,7 +8456,7 @@ frv_pack_insns ()
}
/* Clear the VLIW start flag on random USE and CLOBBER insns, which is
- set on the USE insn that preceeds the return, and potentially on
+ set on the USE insn that precedes the return, and potentially on
CLOBBERs for setting multiword variables. Also skip the ADDR_VEC
holding the case table labels. */
pattern_code = GET_CODE (PATTERN (insn));
@@ -8808,7 +8502,7 @@ frv_pack_insns ()
partnering sethi instruction, with which it can be packed.
Although output dependencies are rare they are still
- possible. So check output dependencies in VLIW insn. */
+ possible. So check output dependencies in VLIW insn. */
|| (get_attr_type (insn) != TYPE_SETLO
&& (frv_registers_used_p (PATTERN (insn),
reg_state,
@@ -8835,7 +8529,7 @@ frv_pack_insns ()
/* Record which registers are modified. */
frv_registers_update (PATTERN (insn), reg_state, modified, &num_mod, 0);
- /* Process the death notices */
+ /* Process the death notices. */
for (link = REG_NOTES (insn);
link != NULL_RTX;
link = XEXP (link, 1))
@@ -8852,7 +8546,7 @@ frv_pack_insns ()
}
}
- free ((PTR) frv_state);
+ free (frv_state);
dfa_finish ();
return;
}
@@ -8877,7 +8571,7 @@ static struct builtin_description bdesc_set[] =
{ CODE_FOR_mhdsets, "__MHDSETS", FRV_BUILTIN_MHDSETS, 0, 0 }
};
-/* Media intrinsics that take just one argument. */
+/* Media intrinsics that take just one argument. */
static struct builtin_description bdesc_1arg[] =
{
@@ -8888,7 +8582,7 @@ static struct builtin_description bdesc_1arg[] =
{ CODE_FOR_mabshs, "__MABSHS", FRV_BUILTIN_MABSHS, 0, 0 }
};
-/* Media intrinsics that take two arguments. */
+/* Media intrinsics that take two arguments. */
static struct builtin_description bdesc_2arg[] =
{
@@ -8923,7 +8617,7 @@ static struct builtin_description bdesc_cut[] =
{ CODE_FOR_mdcutssi, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI, 0, 0 }
};
-/* Two-argument media intrinsics with an immediate second argument. */
+/* Two-argument media intrinsics with an immediate second argument. */
static struct builtin_description bdesc_2argimm[] =
{
@@ -8945,7 +8639,7 @@ static struct builtin_description bdesc_2argimm[] =
};
/* Media intrinsics that take two arguments and return void, the first argument
- being a pointer to 4 words in memory. */
+ being a pointer to 4 words in memory. */
static struct builtin_description bdesc_void2arg[] =
{
@@ -8954,7 +8648,7 @@ static struct builtin_description bdesc_void2arg[] =
};
/* Media intrinsics that take three arguments, the first being a const_int that
- denotes an accumulator, and that return void. */
+ denotes an accumulator, and that return void. */
static struct builtin_description bdesc_void3arg[] =
{
@@ -8998,10 +8692,10 @@ static struct builtin_description bdesc_voidacc[] =
{ CODE_FOR_mdasaccs, "__MDASACCS", FRV_BUILTIN_MDASACCS, 0, 0 }
};
-/* Initialize media builtins. */
+/* Initialize media builtins. */
static void
-frv_init_builtins ()
+frv_init_builtins (void)
{
tree endlink = void_list_node;
tree accumulator = integer_type_node;
@@ -9112,7 +8806,7 @@ frv_init_builtins ()
def_builtin ("__MPACKH", uw1_ftype_uh_uh, FRV_BUILTIN_MPACKH);
def_builtin ("__MUNPACKH", uw2_ftype_uw1, FRV_BUILTIN_MUNPACKH);
def_builtin ("__MDPACKH", uw2_ftype_uw2_uw2, FRV_BUILTIN_MDPACKH);
- def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2, FRV_BUILTIN_MDUNPACKH);
+ def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2, FRV_BUILTIN_MDUNPACKH);
def_builtin ("__MBTOH", uw2_ftype_uw1, FRV_BUILTIN_MBTOH);
def_builtin ("__MHTOB", uw1_ftype_uw2, FRV_BUILTIN_MHTOB);
def_builtin ("__MBTOHE", void_ftype_uw4_uw1, FRV_BUILTIN_MBTOHE);
@@ -9152,6 +8846,54 @@ frv_init_builtins ()
#undef TRINARY
}
+/* Set the names for various arithmetic operations according to the
+ FRV ABI. */
+static void
+frv_init_libfuncs (void)
+{
+ set_optab_libfunc (smod_optab, SImode, "__modi");
+ set_optab_libfunc (umod_optab, SImode, "__umodi");
+
+ set_optab_libfunc (add_optab, DImode, "__addll");
+ set_optab_libfunc (sub_optab, DImode, "__subll");
+ set_optab_libfunc (smul_optab, DImode, "__mulll");
+ set_optab_libfunc (sdiv_optab, DImode, "__divll");
+ set_optab_libfunc (smod_optab, DImode, "__modll");
+ set_optab_libfunc (umod_optab, DImode, "__umodll");
+ set_optab_libfunc (and_optab, DImode, "__andll");
+ set_optab_libfunc (ior_optab, DImode, "__orll");
+ set_optab_libfunc (xor_optab, DImode, "__xorll");
+ set_optab_libfunc (one_cmpl_optab, DImode, "__notll");
+
+ set_optab_libfunc (add_optab, SFmode, "__addf");
+ set_optab_libfunc (sub_optab, SFmode, "__subf");
+ set_optab_libfunc (smul_optab, SFmode, "__mulf");
+ set_optab_libfunc (sdiv_optab, SFmode, "__divf");
+
+ set_optab_libfunc (add_optab, DFmode, "__addd");
+ set_optab_libfunc (sub_optab, DFmode, "__subd");
+ set_optab_libfunc (smul_optab, DFmode, "__muld");
+ set_optab_libfunc (sdiv_optab, DFmode, "__divd");
+
+ set_conv_libfunc (sext_optab, DFmode, SFmode, "__ftod");
+ set_conv_libfunc (trunc_optab, SFmode, DFmode, "__dtof");
+
+ set_conv_libfunc (sfix_optab, SImode, SFmode, "__ftoi");
+ set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftoll");
+ set_conv_libfunc (sfix_optab, SImode, DFmode, "__dtoi");
+ set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtoll");
+
+ set_conv_libfunc (ufix_optab, SImode, SFmode, "__ftoui");
+ set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoull");
+ set_conv_libfunc (ufix_optab, SImode, DFmode, "__dtoui");
+ set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoull");
+
+ set_conv_libfunc (sfloat_optab, SFmode, SImode, "__itof");
+ set_conv_libfunc (sfloat_optab, SFmode, DImode, "__lltof");
+ set_conv_libfunc (sfloat_optab, DFmode, SImode, "__itod");
+ set_conv_libfunc (sfloat_optab, DFmode, DImode, "__lltod");
+}
+
/* Convert an integer constant to an accumulator register. ICODE is the
code of the target instruction, OPNUM is the number of the
accumulator operand and OPVAL is the constant integer. Try both
@@ -9159,10 +8901,7 @@ frv_init_builtins ()
instruction. */
static rtx
-frv_int_to_acc (icode, opnum, opval)
- enum insn_code icode;
- int opnum;
- rtx opval;
+frv_int_to_acc (enum insn_code icode, int opnum, rtx opval)
{
rtx reg;
@@ -9194,8 +8933,7 @@ frv_int_to_acc (icode, opnum, opval)
should have. */
static enum machine_mode
-frv_matching_accg_mode (mode)
- enum machine_mode mode;
+frv_matching_accg_mode (enum machine_mode mode)
{
switch (mode)
{
@@ -9218,8 +8956,7 @@ frv_matching_accg_mode (mode)
class as ACC, but is four times smaller. */
rtx
-frv_matching_accg_for_acc (acc)
- rtx acc;
+frv_matching_accg_for_acc (rtx acc)
{
return gen_rtx_REG (frv_matching_accg_mode (GET_MODE (acc)),
REGNO (acc) - ACC_FIRST + ACCG_FIRST);
@@ -9230,8 +8967,7 @@ frv_matching_accg_for_acc (acc)
list. */
static rtx
-frv_read_argument (arglistptr)
- tree *arglistptr;
+frv_read_argument (tree *arglistptr)
{
tree next = TREE_VALUE (*arglistptr);
*arglistptr = TREE_CHAIN (*arglistptr);
@@ -9243,10 +8979,7 @@ frv_read_argument (arglistptr)
function prints an error if OPVAL is not valid. */
static int
-frv_check_constant_argument (icode, opnum, opval)
- enum insn_code icode;
- int opnum;
- rtx opval;
+frv_check_constant_argument (enum insn_code icode, int opnum, rtx opval)
{
if (GET_CODE (opval) != CONST_INT)
{
@@ -9266,9 +8999,7 @@ frv_check_constant_argument (icode, opnum, opval)
predicate. */
static rtx
-frv_legitimize_target (icode, target)
- enum insn_code icode;
- rtx target;
+frv_legitimize_target (enum insn_code icode, rtx target)
{
enum machine_mode mode = insn_data[icode].operand[0].mode;
@@ -9281,15 +9012,12 @@ frv_legitimize_target (icode, target)
}
/* Given that ARG is being passed as operand OPNUM to instruction ICODE,
- check whether ARG satisfies the operand's contraints. If it doesn't,
+ check whether ARG satisfies the operand's constraints. If it doesn't,
copy ARG to a temporary register and return that. Otherwise return ARG
itself. */
static rtx
-frv_legitimize_argument (icode, opnum, arg)
- enum insn_code icode;
- int opnum;
- rtx arg;
+frv_legitimize_argument (enum insn_code icode, int opnum, rtx arg)
{
enum machine_mode mode = insn_data[icode].operand[opnum].mode;
@@ -9303,10 +9031,7 @@ frv_legitimize_argument (icode, opnum, arg)
only MHDSETS falls into this category. */
static rtx
-frv_expand_set_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_set_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9323,13 +9048,10 @@ frv_expand_set_builtin (icode, arglist, target)
return target;
}
-/* Expand builtins that take one operand. */
+/* Expand builtins that take one operand. */
static rtx
-frv_expand_unop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9344,13 +9066,10 @@ frv_expand_unop_builtin (icode, arglist, target)
return target;
}
-/* Expand builtins that take two operands. */
+/* Expand builtins that take two operands. */
static rtx
-frv_expand_binop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9368,13 +9087,10 @@ frv_expand_binop_builtin (icode, arglist, target)
}
/* Expand cut-style builtins, which take two operands and an implicit ACCG
- one. */
+ one. */
static rtx
-frv_expand_cut_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_cut_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9403,13 +9119,10 @@ frv_expand_cut_builtin (icode, arglist, target)
return target;
}
-/* Expand builtins that take two operands and the second is immediate. */
+/* Expand builtins that take two operands and the second is immediate. */
static rtx
-frv_expand_binopimm_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_binopimm_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9429,12 +9142,10 @@ frv_expand_binopimm_builtin (icode, arglist, target)
}
/* Expand builtins that take two operands, the first operand being a pointer to
- ints and return void. */
+ ints and return void. */
static rtx
-frv_expand_voidbinop_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_voidbinop_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9475,9 +9186,7 @@ frv_expand_voidbinop_builtin (icode, arglist)
corresponds to the accumulator. */
static rtx
-frv_expand_voidtriop_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_voidtriop_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9505,9 +9214,7 @@ frv_expand_voidtriop_builtin (icode, arglist)
void. */
static rtx
-frv_expand_voidaccop_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_voidaccop_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9537,8 +9244,7 @@ frv_expand_voidaccop_builtin (icode, arglist)
number as argument. */
static rtx
-frv_expand_mclracc_builtin (arglist)
- tree arglist;
+frv_expand_mclracc_builtin (tree arglist)
{
enum insn_code icode = CODE_FOR_mclracc;
rtx pat;
@@ -9558,8 +9264,7 @@ frv_expand_mclracc_builtin (arglist)
/* Expand builtins that take no arguments. */
static rtx
-frv_expand_noargs_builtin (icode)
- enum insn_code icode;
+frv_expand_noargs_builtin (enum insn_code icode)
{
rtx pat = GEN_FCN (icode) (GEN_INT (0));
if (pat)
@@ -9572,9 +9277,7 @@ frv_expand_noargs_builtin (icode)
number or accumulator guard number as argument and return an SI integer. */
static rtx
-frv_expand_mrdacc_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_mrdacc_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx target = gen_reg_rtx (SImode);
@@ -9597,9 +9300,7 @@ frv_expand_mrdacc_builtin (icode, arglist)
second. */
static rtx
-frv_expand_mwtacc_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_mwtacc_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9617,15 +9318,14 @@ frv_expand_mwtacc_builtin (icode, arglist)
return NULL_RTX;
}
-/* Expand builtins. */
+/* Expand builtins. */
static rtx
-frv_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+frv_expand_builtin (tree exp,
+ rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
tree arglist = TREE_OPERAND (exp, 1);
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
@@ -9684,7 +9384,7 @@ frv_expand_builtin (exp, target, subtarget, mode, ignore)
break;
}
- /* Expand unique builtins. */
+ /* Expand unique builtins. */
switch (fcode)
{
@@ -9716,73 +9416,151 @@ frv_expand_builtin (exp, target, subtarget, mode, ignore)
break;
}
- /* Expand groups of builtins. */
+ /* Expand groups of builtins. */
- for (i = 0, d = bdesc_set; i < sizeof (bdesc_set) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_set; i < ARRAY_SIZE (bdesc_set); i++, d++)
if (d->code == fcode)
return frv_expand_set_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_1arg; i < sizeof (bdesc_1arg) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
if (d->code == fcode)
return frv_expand_unop_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
if (d->code == fcode)
return frv_expand_binop_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_cut; i < sizeof (bdesc_cut) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_cut; i < ARRAY_SIZE (bdesc_cut); i++, d++)
if (d->code == fcode)
return frv_expand_cut_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_2argimm;
- i < sizeof (bdesc_2argimm) / sizeof *d;
- i++, d++)
- {
- if (d->code == fcode)
- return frv_expand_binopimm_builtin (d->icode, arglist, target);
- }
+ for (i = 0, d = bdesc_2argimm; i < ARRAY_SIZE (bdesc_2argimm); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_binopimm_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_void2arg;
- i < sizeof (bdesc_void2arg) / sizeof *d;
- i++, d++)
- {
- if (d->code == fcode)
- return frv_expand_voidbinop_builtin (d->icode, arglist);
- }
+ for (i = 0, d = bdesc_void2arg; i < ARRAY_SIZE (bdesc_void2arg); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_voidbinop_builtin (d->icode, arglist);
+
+ for (i = 0, d = bdesc_void3arg; i < ARRAY_SIZE (bdesc_void3arg); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_voidtriop_builtin (d->icode, arglist);
+
+ for (i = 0, d = bdesc_voidacc; i < ARRAY_SIZE (bdesc_voidacc); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_voidaccop_builtin (d->icode, arglist);
+
+ return 0;
+}
- for (i = 0, d = bdesc_void3arg;
- i < sizeof (bdesc_void3arg) / sizeof *d;
- i++, d++)
+static bool
+frv_in_small_data_p (tree decl)
+{
+ HOST_WIDE_INT size;
+ tree section_name;
+
+ /* Don't apply the -G flag to internal compiler structures. We
+ should leave such structures in the main data section, partly
+ for efficiency and partly because the size of some of them
+ (such as C++ typeinfos) is not known until later. */
+ if (TREE_CODE (decl) != VAR_DECL || DECL_ARTIFICIAL (decl))
+ return false;
+
+ /* If we already know which section the decl should be in, see if
+ it's a small data section. */
+ section_name = DECL_SECTION_NAME (decl);
+ if (section_name)
{
- if (d->code == fcode)
- return frv_expand_voidtriop_builtin (d->icode, arglist);
+ if (TREE_CODE (section_name) != STRING_CST)
+ abort ();
+ if (frv_string_begins_with (section_name, ".sdata"))
+ return true;
+ if (frv_string_begins_with (section_name, ".sbss"))
+ return true;
+ return false;
}
- for (i = 0, d = bdesc_voidacc;
- i < sizeof (bdesc_voidacc) / sizeof *d;
- i++, d++)
+ size = int_size_in_bytes (TREE_TYPE (decl));
+ if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
+ return true;
+
+ return false;
+}
+
+static bool
+frv_rtx_costs (rtx x,
+ int code ATTRIBUTE_UNUSED,
+ int outer_code ATTRIBUTE_UNUSED,
+ int *total)
+{
+ switch (code)
{
- if (d->code == fcode)
- return frv_expand_voidaccop_builtin (d->icode, arglist);
+ case CONST_INT:
+ /* Make 12 bit integers really cheap. */
+ if (IN_RANGE_P (INTVAL (x), -2048, 2047))
+ {
+ *total = 0;
+ return true;
+ }
+ /* Fall through. */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case NOT:
+ case NEG:
+ case COMPARE:
+ if (GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (1);
+ else if (GET_MODE (x) == DImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case MULT:
+ if (GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (6); /* guess */
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (18);
+ return true;
+
+ default:
+ return false;
}
- return 0;
}
-
-static const char *
-frv_strip_name_encoding (str)
- const char *str;
+
+static void
+frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- while (*str == '*' || *str == SDATA_FLAG_CHAR)
- str++;
- return str;
+ ctors_section ();
+ assemble_align (POINTER_SIZE);
+ assemble_integer_with_op ("\t.picptr\t", symbol);
}
-static bool
-frv_in_small_data_p (decl)
- tree decl;
+static void
+frv_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
-
- return symbol_ref_small_data_p (XEXP (DECL_RTL (decl), 0))
- && size > 0 && size <= g_switch_value;
+ dtors_section ();
+ assemble_align (POINTER_SIZE);
+ assemble_integer_with_op ("\t.picptr\t", symbol);
}
diff --git a/contrib/gcc/config/frv/frv.h b/contrib/gcc/config/frv/frv.h
index f9900b2..0b87404 100644
--- a/contrib/gcc/config/frv/frv.h
+++ b/contrib/gcc/config/frv/frv.h
@@ -1,5 +1,6 @@
/* Target macros for the FRV port of GCC.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Red Hat Inc.
This file is part of GCC.
@@ -22,10 +23,6 @@
#ifndef __FRV_H__
#define __FRV_H__
-/* Set up System V.4 (aka ELF) defaults. */
-#include "svr4.h"
-
-
/* Frv general purpose macros. */
/* Align an address. */
#define ADDR_ALIGN(addr,align) (((addr) + (align) - 1) & ~((align) - 1))
@@ -65,9 +62,9 @@
Defined in svr4.h. */
#undef WORD_SWITCH_TAKES_ARG
-/* A C string constant that tells the GNU CC driver program options to pass to
+/* A C string constant that tells the GCC driver program options to pass to
the assembler. It can also specify how to translate options you give to GNU
- CC into options for GNU CC to pass to the assembler. See the file `sun3.h'
+ CC into options for GCC to pass to the assembler. See the file `sun3.h'
for an example of this.
Do not define this macro if it does not need to do anything.
@@ -86,7 +83,7 @@
%{mmedia} %{mno-media} \
%{mmuladd} %{mno-muladd} \
%{mpack} %{mno-pack} \
- %{fpic: -mpic} %{fPIC: -mPIC} %{mlibrary-pic}}"
+ %{fpic|fpie: -mpic} %{fPIC|fPIE: -mPIC} %{mlibrary-pic}}"
/* Another C string constant used much like `LINK_SPEC'. The difference
between the two is that `STARTFILE_SPEC' is used at the very beginning of
@@ -109,9 +106,9 @@
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "frvend%O%s"
-/* A C string constant that tells the GNU CC driver program options to pass to
- CPP. It can also specify how to translate options you give to GNU CC into
- options for GNU CC to pass to the CPP.
+/* A C string constant that tells the GCC driver program options to pass to
+ CPP. It can also specify how to translate options you give to GCC into
+ options for GCC to pass to the CPP.
Do not define this macro if it does not need to do anything. */
@@ -204,17 +201,17 @@
#define MASK_DEFAULT_SIMPLE \
(MASK_GPR_32 | MASK_SOFT_FLOAT)
-/* A C string constant that tells the GNU CC driver program options to pass to
- `cc1'. It can also specify how to translate options you give to GNU CC into
- options for GNU CC to pass to the `cc1'.
+/* A C string constant that tells the GCC driver program options to pass to
+ `cc1'. It can also specify how to translate options you give to GCC into
+ options for GCC to pass to the `cc1'.
Do not define this macro if it does not need to do anything. */
/* For ABI compliance, we need to put bss data into the normal data section. */
#define CC1_SPEC "%{G*}"
-/* A C string constant that tells the GNU CC driver program options to pass to
- the linker. It can also specify how to translate options you give to GNU CC
- into options for GNU CC to pass to the linker.
+/* A C string constant that tells the GCC driver program options to pass to
+ the linker. It can also specify how to translate options you give to GCC
+ into options for GCC to pass to the linker.
Do not define this macro if it does not need to do anything.
@@ -249,7 +246,7 @@
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -280,16 +277,13 @@
/* Run-time target specifications */
-/* Define this to be a string constant containing `-D' options to define the
- predefined macros that identify this machine and system. These macros will
- be predefined unless the `-ansi' option is specified.
-
- In addition, a parallel set of macros are predefined, whose names are made
- by appending `__' at the beginning and at the end. These `__' macros are
- permitted by the ANSI standard, so they are predefined regardless of whether
- `-ansi' is specified. */
-
-#define CPP_PREDEFINES "-D__frv__ -Amachine(frv)"
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__frv__"); \
+ builtin_assert ("machine=frv"); \
+ } \
+ while (0)
/* This declaration should be present. */
@@ -489,13 +483,13 @@ extern int target_flags;
"Specify the size of the short data section" } }
This declaration is optional. */
-#define TARGET_OPTIONS \
-{ \
- { "cpu=", &frv_cpu_string, "Set cpu type" }, \
- { "branch-cost=", &frv_branch_cost_string, "Internal debug switch" }, \
- { "cond-exec-insns=", &frv_condexec_insns_str, "Internal debug switch" }, \
- { "cond-exec-temps=", &frv_condexec_temps_str, "Internal debug switch" }, \
- { "sched-lookahead=", &frv_sched_lookahead_str,"Internal debug switch" }, \
+#define TARGET_OPTIONS \
+{ \
+ { "cpu=", &frv_cpu_string, "Set cpu type", 0}, \
+ { "branch-cost=", &frv_branch_cost_string, "Internal debug switch", 0}, \
+ { "cond-exec-insns=", &frv_condexec_insns_str, "Internal debug switch", 0}, \
+ { "cond-exec-temps=", &frv_condexec_temps_str, "Internal debug switch", 0}, \
+ { "sched-lookahead=", &frv_sched_lookahead_str,"Internal debug switch", 0}, \
}
/* This macro is a C statement to print on `stderr' a string describing the
@@ -543,9 +537,9 @@ extern int target_flags;
/* Define this macro if debugging can be performed even without a frame
- pointer. If this macro is defined, GNU CC will turn on the
+ pointer. If this macro is defined, GCC will turn on the
`-fomit-frame-pointer' option whenever `-O' is specified. */
-/* Frv needs a specific frame layout that includes the frame pointer */
+/* Frv needs a specific frame layout that includes the frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
@@ -557,9 +551,6 @@ extern int target_flags;
#define SDATA_DEFAULT_SIZE 8
#endif
-extern int g_switch_value; /* value of the -G xx switch */
-extern int g_switch_set; /* whether -G xx was passed. */
-
/* Storage Layout */
@@ -580,7 +571,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
/* Define this macro to have the value 1 if, in a multiword object, the most
significant word has the lowest number. This applies to both memory
- locations and registers; GNU CC fundamentally assumes that the order of
+ locations and registers; GCC fundamentally assumes that the order of
words in memory is the same as the order in registers. This macro need not
be a constant. */
#define WORDS_BIG_ENDIAN 1
@@ -643,7 +634,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
#define BIGGEST_FIELD_ALIGNMENT 64
#else
/* An expression for the alignment of a structure field FIELD if the
- alignment computed in the usual way is COMPUTED. GNU CC uses this
+ alignment computed in the usual way is COMPUTED. GCC uses this
value instead of the value in `BIGGEST_ALIGNMENT' or
`BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
@@ -715,7 +706,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
`STRUCTURE_SIZE_BOUNDARY' that way, you must define
`PCC_BITFIELD_TYPE_MATTERS' to have a nonzero value.
- If your aim is to make GNU CC use the same conventions for laying out
+ If your aim is to make GCC use the same conventions for laying out
bitfields as are used by another compiler, here is how to investigate what
the other compiler does. Compile and run this program:
@@ -1045,7 +1036,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
/* Order of allocation of registers. */
/* If defined, an initializer for a vector of integers, containing the numbers
- of hard registers in the order in which GNU CC should prefer to use them
+ of hard registers in the order in which GCC should prefer to use them
(from most preferred to least).
If this macro is not defined, registers are used lowest numbered first (all
@@ -1895,7 +1886,7 @@ struct machine_function GTY(())
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
frv_function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
-/* extern int frv_function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS, int, Tree, int)); */
+/* extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS, int, Tree, int); */
/* A C expression that indicates when an argument must be passed by reference.
If nonzero for an argument, a copy of that argument is made in memory and a
@@ -1955,19 +1946,19 @@ struct machine_function GTY(())
being processed. Thus, each time this macro is called, either LIBNAME or
FNTYPE is nonzero, but never both of them at once. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
- frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, INDIRECT, FALSE)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
+ frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, FALSE)
/* Like `INIT_CUMULATIVE_ARGS' but overrides it for the purposes of finding the
arguments for the function being compiled. If this macro is undefined,
`INIT_CUMULATIVE_ARGS' is used instead.
The value passed for LIBNAME is always 0, since library routines with
- special calling conventions are never compiled with GNU CC. The argument
+ special calling conventions are never compiled with GCC. The argument
LIBNAME exists for symmetry with `INIT_CUMULATIVE_ARGS'. */
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
- frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, TRUE)
+ frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, NULL, TRUE)
/* A C statement (sans semicolon) to update the summarizer variable CUM to
advance past an argument in the argument list. The values MODE, TYPE and
@@ -2079,14 +2070,14 @@ struct machine_function GTY(())
`fprintf'.
The details of how the address should be passed to `mcount' are determined
- by your operating system environment, not by GNU CC. To figure them out,
+ by your operating system environment, not by GCC. To figure them out,
compile a small program for profiling using the system's installed C
compiler and look at the assembler code that results.
This declaration must be present, but it can be an abort if profiling is
not implemented. */
-#define FUNCTION_PROFILER(FILE, LABELNO) abort ()
+#define FUNCTION_PROFILER(FILE, LABELNO)
/* Implementing the Varargs Macros. */
@@ -2170,7 +2161,7 @@ struct machine_function GTY(())
/* Define this macro if trampolines need a special subroutine to do their work.
The macro should expand to a series of `asm' statements which will be
- compiled with GNU CC. They go in a library function named
+ compiled with GCC. They go in a library function named
`__transfer_from_trampoline'.
If you need to avoid executing the ordinary prologue code of a compiled C
@@ -2190,11 +2181,7 @@ struct machine_function GTY(())
extern int _write (int, const void *, unsigned); \
\
void \
-__trampoline_setup (addr, size, fnaddr, sc) \
- short * addr; \
- int size; \
- int fnaddr; \
- int sc; \
+__trampoline_setup (short * addr, int size, int fnaddr, int sc) \
{ \
extern short __trampoline_template[]; \
short * to = addr; \
@@ -2234,101 +2221,6 @@ __asm__("\n" \
"\tjmpl @(gr0,gr6)\n");
-/* Implicit Calls to Library Routines. */
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one signed full-word by another. If you do not
- define this macro, the default name is used, which is `__modsi3', a function
- defined in `libgcc.a'. */
-#define MODSI3_LIBCALL "__modi"
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one unsigned full-word by another. If you do not
- define this macro, the default name is used, which is `__umodsi3', a
- function defined in `libgcc.a'. */
-#define UMODSI3_LIBCALL "__umodi"
-
-/* A C string constant giving the name of the function to call for
- multiplication of one signed double-word by another. If you do not define
- this macro, the default name is used, which is `__muldi3', a function
- defined in `libgcc.a'. */
-#define MULDI3_LIBCALL "__mulll"
-
-/* A C string constant giving the name of the function to call for division of
- one signed double-word by another. If you do not define this macro, the
- default name is used, which is `__divdi3', a function defined in `libgcc.a'. */
-#define DIVDI3_LIBCALL "__divll"
-
-/* A C string constant giving the name of the function to call for division of
- one unsigned full-word by another. If you do not define this macro, the
- default name is used, which is `__udivdi3', a function defined in
- `libgcc.a'. */
-#define UDIVDI3_LIBCALL "__udivll"
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one signed double-word by another. If you do not
- define this macro, the default name is used, which is `__moddi3', a function
- defined in `libgcc.a'. */
-#define MODDI3_LIBCALL "__modll"
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one unsigned full-word by another. If you do not
- define this macro, the default name is used, which is `__umoddi3', a
- function defined in `libgcc.a'. */
-#define UMODDI3_LIBCALL "__umodll"
-
-/* Define this macro as a C statement that declares additional library routines
- renames existing ones. `init_optabs' calls this macro after initializing all
- the normal library routines. */
-#define INIT_TARGET_OPTABS \
- do \
- { \
- add_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__addll"); \
- sub_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__subll"); \
- and_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__andll"); \
- ior_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__orll"); \
- xor_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__xorll"); \
- one_cmpl_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__notll"); \
- add_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__addf"); \
- sub_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__subf"); \
- smul_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__mulf"); \
- sdiv_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__divf"); \
- add_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__addd"); \
- sub_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__subd"); \
- smul_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__muld"); \
- sdiv_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__divd"); \
- fixsfsi_libfunc = init_one_libfunc ("__ftoi"); \
- fixunssfsi_libfunc = init_one_libfunc ("__ftoui"); \
- fixsfdi_libfunc = init_one_libfunc ("__ftoll"); \
- fixunssfdi_libfunc = init_one_libfunc ("__ftoull"); \
- fixdfsi_libfunc = init_one_libfunc ("__dtoi"); \
- fixunsdfsi_libfunc = init_one_libfunc ("__dtoui"); \
- fixdfdi_libfunc = init_one_libfunc ("__dtoll"); \
- fixunsdfdi_libfunc = init_one_libfunc ("__dtoull"); \
- floatsisf_libfunc = init_one_libfunc ("__itof"); \
- floatdisf_libfunc = init_one_libfunc ("__lltof"); \
- floatsidf_libfunc = init_one_libfunc ("__itod"); \
- floatdidf_libfunc = init_one_libfunc ("__lltod"); \
- extendsfdf2_libfunc = init_one_libfunc ("__ftod"); \
- truncdfsf2_libfunc = init_one_libfunc ("__dtof"); \
- } \
- while (0)
-
-
/* Addressing Modes. */
/* A C expression that is 1 if the RTX X is a constant which is a valid
@@ -2532,7 +2424,7 @@ __asm__("\n" \
#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode) */
/* On frv, don't consider floating point comparisons to be reversible. In
- theory, fp equality comparisons can be reversible */
+ theory, fp equality comparisons can be reversible. */
#define REVERSIBLE_CC_MODE(MODE) ((MODE) == CCmode || (MODE) == CC_UNSmode)
/* Frv CCR_MODE's are not reversible. */
@@ -2541,65 +2433,6 @@ __asm__("\n" \
/* Describing Relative Costs of Operations. */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. It must contain `case' labels for expression
- codes `const_int', `const', `symbol_ref', `label_ref' and `const_double'.
- Each case must ultimately reach a `return' statement to return the relative
- cost of the use of that kind of constant value in an expression. The cost
- may depend on the precise value of the constant, which is available for
- examination in X, and the rtx code of the expression in which it is
- contained, found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained with
- `GET_CODE (X)'. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS (2); \
- \
- case CONST_INT: \
- /* Make 12 bit integers really cheap */ \
- return IN_RANGE_P (INTVAL (X), -2048, 2047) ? 0 : COSTS_N_INSNS (2); \
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. This can be
- used, for example, to indicate how costly a multiply instruction is. In
- writing this macro, you can use the construct `COSTS_N_INSNS (N)' to specify
- a cost equal to N fast instructions. OUTER_CODE is the code of the
- expression in which X is contained.
-
- This macro is optional; do not define it if the default cost assumptions are
- adequate for the target machine. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case PLUS: \
- case MINUS: \
- case AND: \
- case IOR: \
- case XOR: \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case NOT: \
- case NEG: \
- case COMPARE: \
- if (GET_MODE (X) == SImode) \
- return COSTS_N_INSNS (1); \
- else if (GET_MODE (X) == DImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (3); /* guess */ \
- \
- case MULT: \
- if (GET_MODE (X) == SImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (6); /* guess */ \
- \
- case DIV: \
- case UDIV: \
- return COSTS_N_INSNS (18);
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO. The classes are expressed using the enumeration values
such as `GENERAL_REGS'. A value of 4 is the default; other values are
@@ -2629,7 +2462,7 @@ __asm__("\n" \
default; other values are interpreted relative to that. */
/* Here are additional macros which do not specify precise relative costs, but
- only that certain actions are more expensive than GNU CC would ordinarily
+ only that certain actions are more expensive than GCC would ordinarily
expect. */
/* We used to default the branch cost to 2, but I changed it to 1, to avoid
@@ -2686,7 +2519,6 @@ __asm__("\n" \
/* Short Data Support */
#define SDATA_SECTION_ASM_OP "\t.section .sdata,\"aw\""
-#define SBSS_SECTION_ASM_OP "\t.section .sbss,\"aw\""
/* On svr4, we *do* have support for the .init and .fini sections, and we
can put stuff in there to be executed before and after `main'. We let
@@ -2702,6 +2534,11 @@ __asm__("\n" \
#define INIT_SECTION_ASM_OP "\t.section .init,\"ax\""
#define FINI_SECTION_ASM_OP "\t.section .fini,\"ax\""
+#undef CTORS_SECTION_ASM_OP
+#undef DTORS_SECTION_ASM_OP
+#define CTORS_SECTION_ASM_OP "\t.section\t.ctors,\"a\""
+#define DTORS_SECTION_ASM_OP "\t.section\t.dtors,\"a\""
+
/* A C expression whose value is a string containing the assembler operation to
switch to the fixup section that records all initialized pointers in a -fpic
program so they can be changed program startup time if the program is loaded
@@ -2712,7 +2549,7 @@ __asm__("\n" \
`in_text' and `in_data'. You need not define this macro
on a system with no other sections (that GCC needs to use). */
#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_sdata, in_sbss, in_const, in_fixup
+#define EXTRA_SECTIONS in_sdata, in_const, in_fixup
/* One or more functions to be defined in "varasm.c". These
functions should do jobs analogous to those of `text_section' and
@@ -2720,47 +2557,30 @@ __asm__("\n" \
macro if you do not define `EXTRA_SECTIONS'. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
-SDATA_SECTION_FUNCTION \
-SBSS_SECTION_FUNCTION \
-FIXUP_SECTION_FUNCTION
-
+ SDATA_SECTION_FUNCTION \
+ FIXUP_SECTION_FUNCTION
#define SDATA_SECTION_FUNCTION \
void \
-sdata_section () \
+sdata_section (void) \
{ \
if (in_section != in_sdata) \
{ \
fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
in_section = in_sdata; \
} \
-} \
-
-#define SBSS_SECTION_FUNCTION \
-void \
-sbss_section () \
-{ \
- if (in_section != in_sbss) \
- { \
- fprintf (asm_out_file, "%s\n", SBSS_SECTION_ASM_OP); \
- in_section = in_sbss; \
- } \
-} \
+}
#define FIXUP_SECTION_FUNCTION \
void \
-fixup_section () \
+fixup_section (void) \
{ \
if (in_section != in_fixup) \
{ \
fprintf (asm_out_file, "%s\n", FIXUP_SECTION_ASM_OP); \
in_section = in_fixup; \
} \
-} \
-
-#define SDATA_FLAG_CHAR '@'
-
-#define SDATA_NAME_P(NAME) (*(NAME) == SDATA_FLAG_CHAR)
+}
/* Position Independent Code. */
@@ -2845,10 +2665,10 @@ extern int size_directive_output;
#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
do { \
- if (SDATA_NAME_P (NAME)) \
- sbss_section (); \
+ if ((SIZE) > 0 && (SIZE) <= g_switch_value) \
+ named_section (0, ".sbss", 0); \
else \
- bss_section (); \
+ bss_section (); \
ASM_OUTPUT_ALIGN (STREAM, floor_log2 ((ALIGN) / BITS_PER_UNIT)); \
ASM_DECLARE_OBJECT_NAME (STREAM, NAME, DECL); \
ASM_OUTPUT_SKIP (STREAM, (SIZE) ? (SIZE) : 1); \
@@ -2871,24 +2691,11 @@ do { \
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP "\t.globl "
-/* A C statement (sans semicolon) to output to the stdio stream STREAM a
- reference in assembler syntax to a label named NAME. This should add `_' to
- the front of the name, if that is customary on your operating system, as it
- is in most Berkeley Unix systems. This macro is used in `assemble_name'. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
-do { \
- const char *_name = (NAME); \
- while (*_name == '*' || *_name == SDATA_FLAG_CHAR) \
- _name++; \
- asm_fprintf (STREAM, "%U%s", _name); \
-} while (0)
-
/* A C statement to store into the string STRING a label whose name is made
from the string PREFIX and the number NUM.
This string, when output subsequently by `assemble_name', should produce the
- output that `ASM_OUTPUT_INTERNAL_LABEL' would produce with the same PREFIX
+ output that `(*targetm.asm_out.internal_label)' would produce with the same PREFIX
and NUM.
If the string begins with `*', then `assemble_name' will output the rest of
@@ -2905,32 +2712,11 @@ do { \
sprintf (LABEL, "*.%s%ld", PREFIX, (long)NUM); \
} while (0)
-/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
- newly allocated string made from the string NAME and the number NUMBER, with
- some suitable punctuation added. Use `alloca' to get space for the string.
-
- The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
- an assembler label for an internal static variable whose name is NAME.
- Therefore, the string must be such as to result in valid assembler code.
- The argument NUMBER is different each time this macro is executed; it
- prevents conflicts between similarly-named internal static variables in
- different scopes.
-
- Ideally this string should not be a valid C identifier, to prevent any
- conflict with the user's own symbols. Most assemblers allow periods or
- percent signs in assembler symbols; putting at least one of these between
- the name and the number will suffice. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
-do { \
- (OUTVAR) = (char *) alloca (strlen ((NAME)) + 12); \
- sprintf ((OUTVAR), "%s.%ld", (NAME), (long)(NUMBER)); \
-} while (0)
-
/* Macros Controlling Initialization Routines. */
/* If defined, a C string constant for the assembler operation to identify the
- following data as initialization code. If not defined, GNU CC will assume
+ following data as initialization code. If not defined, GCC will assume
such a section does not exist. When you are using special sections for
initialization and termination functions, this macro also controls how
`crtstuff.c' and `libgcc2.c' arrange to run the initialization functions.
@@ -2943,27 +2729,6 @@ do { \
init section is not actually run automatically, but is still useful for
collecting the lists of constructors and destructors. */
#define INVOKE__main
-
-/* Output appropriate code tp call a static constructor. */
-#undef ASM_OUTPUT_CONSTRUCTOR
-#define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
-do { \
- ctors_section (); \
- fprintf (STREAM, "\t.picptr\t"); \
- assemble_name (STREAM, NAME); \
- fprintf (STREAM, "\n"); \
-} while (0)
-
-/* Output appropriate code tp call a static destructor. */
-#undef ASM_OUTPUT_DESTRUCTOR
-#define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
-do { \
- dtors_section (); \
- fprintf (STREAM, "\t.picptr\t"); \
- assemble_name (STREAM, NAME); \
- fprintf (STREAM, "\n"); \
-} while (0)
-
/* Output of Assembler Instructions. */
@@ -3079,7 +2844,7 @@ do { \
* == temporary integer CCR register (cr3)
& == temporary integer ICC register (icc3) */
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
-((CODE) == '.' || (CODE) == '#' || (CODE) == SDATA_FLAG_CHAR || (CODE) == '~' \
+((CODE) == '.' || (CODE) == '#' || (CODE) == '@' || (CODE) == '~' \
|| (CODE) == '*' || (CODE) == '&')
/* A C compound statement to output to stdio stream STREAM the assembler syntax
@@ -3115,7 +2880,7 @@ do { \
The definition should be a C statement to output to the stdio stream STREAM
an assembler pseudo-instruction to generate a difference between two labels.
VALUE and REL are the numbers of two internal labels. The definitions of
- these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
+ these labels are output using `(*targetm.asm_out.internal_label)', and they must be
printed in the same way here. For example,
fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
@@ -3128,14 +2893,14 @@ fprintf (STREAM, "\t.word .L%d-.L%d\n", VALUE, REL)
The definition should be a C statement to output to the stdio stream STREAM
an assembler pseudo-instruction to generate a reference to a label. VALUE
is the number of an internal label whose definition is output using
- `ASM_OUTPUT_INTERNAL_LABEL'. For example,
+ `(*targetm.asm_out.internal_label)'. For example,
fprintf (STREAM, "\t.word L%d\n", VALUE) */
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
fprintf (STREAM, "\t.word .L%d\n", VALUE)
/* Define this if the label before a jump-table needs to be output specially.
- The first three arguments are the same as for `ASM_OUTPUT_INTERNAL_LABEL';
+ The first three arguments are the same as for `(*targetm.asm_out.internal_label)';
the fourth argument is the jump-table which follows (a `jump_insn'
containing an `addr_vec' or `addr_diff_vec').
@@ -3143,7 +2908,7 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE)
table.
If this macro is not defined, these labels are output with
- `ASM_OUTPUT_INTERNAL_LABEL'.
+ `(*targetm.asm_out.internal_label)'.
Defined in svr4.h. */
/* When generating embedded PIC or mips16 code we want to put the jump
@@ -3158,7 +2923,7 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE)
do { \
if (flag_pic) \
function_section (current_function_decl); \
- ASM_OUTPUT_INTERNAL_LABEL (STREAM, PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) (STREAM, PREFIX, NUM); \
} while (0)
/* Define this to determine whether case statement labels are relative to
@@ -3194,7 +2959,7 @@ do { \
Defined in svr4.h. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
- fprintf (STREAM, "\t.zero\t%u\n", (NBYTES))
+ fprintf (STREAM, "\t.zero\t%u\n", (int)(NBYTES))
/* A C statement to output to the stdio stream STREAM an assembler command to
advance the location counter to a multiple of 2 to the POWER bytes. POWER
@@ -3202,6 +2967,9 @@ do { \
#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
fprintf ((STREAM), "\t.p2align %d\n", (POWER))
+/* Inside the text section, align with unpacked nops rather than zeros. */
+#define ASM_OUTPUT_ALIGN_WITH_NOP(STREAM, POWER) \
+ fprintf ((STREAM), "\t.p2alignl %d,0x80880000\n", (POWER))
/* Macros Affecting all Debug Formats. */
@@ -3211,7 +2979,7 @@ do { \
knows about and DBX does not, or vice versa. In such cases, some register
may need to have one number in the compiler and another for DBX.
- If two registers have consecutive numbers inside GNU CC, and they can be
+ If two registers have consecutive numbers inside GCC, and they can be
used as a pair to hold a multiword value, then they *must* have consecutive
numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
will be unable to access such a pair, because they expect register pairs to
@@ -3224,9 +2992,9 @@ do { \
This declaration is required. */
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
-/* A C expression that returns the type of debugging output GNU CC produces
+/* A C expression that returns the type of debugging output GCC produces
when the user specifies `-g' or `-ggdb'. Define this if you have arranged
- for GNU CC to support more than one format of debugging output. Currently,
+ for GCC to support more than one format of debugging output. Currently,
the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
`DWARF2_DEBUG', and `XCOFF_DEBUG'.
@@ -3314,10 +3082,11 @@ do { \
{ "minmax_operator", { SMIN, SMAX, UMIN, UMAX }}, \
{ "condexec_si_binary_operator", { PLUS, MINUS, AND, IOR, XOR, \
ASHIFT, ASHIFTRT, LSHIFTRT }}, \
+ { "condexec_si_media_operator", { AND, IOR, XOR }}, \
{ "condexec_si_divide_operator", { DIV, UDIV }}, \
{ "condexec_si_unary_operator", { NOT, NEG }}, \
- { "condexec_sf_binary_operator", { PLUS, MINUS, MULT, DIV }}, \
- { "condexec_sf_unary_operator", { ABS, NEG, SQRT }}, \
+ { "condexec_sf_add_operator", { PLUS, MINUS }}, \
+ { "condexec_sf_conv_operator", { ABS, NEG }}, \
{ "intop_compare_operator", { PLUS, MINUS, AND, IOR, XOR, \
ASHIFT, ASHIFTRT, LSHIFTRT }}, \
{ "condexec_intop_cmp_operator", { PLUS, MINUS, AND, IOR, XOR, \
@@ -3492,9 +3261,6 @@ frv_ifcvt_modify_multiple_tests (CE_INFO, BB, &TRUE_EXPR, &FALSE_EXPR)
scheduling. */
#define FIRST_CYCLE_MULTIPASS_SCHEDULING_LOOKAHEAD frv_sched_lookahead
-/* Return true if a function is ok to be called as a sibcall. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) 0
-
enum frv_builtins
{
FRV_BUILTIN_MAND,
diff --git a/contrib/gcc/config/frv/frv.md b/contrib/gcc/config/frv/frv.md
index a5e82ee..aef10bc 100644
--- a/contrib/gcc/config/frv/frv.md
+++ b/contrib/gcc/config/frv/frv.md
@@ -1,21 +1,21 @@
;; Frv Machine Description
-;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
;; Contributed by Red Hat, Inc.
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -304,7 +304,7 @@
;; Instruction type
-;; The table below summarises the types of media instruction and their
+;; The table below summarizes the types of media instruction and their
;; scheduling classification. Headings are:
;; Type: the name of the define_attr type
@@ -463,7 +463,7 @@
first regular expression *and* the reservation described by
the second regular expression *and* etc.
- 4. "*" is used for convinience and simply means sequence in
+ 4. "*" is used for convenience and simply means sequence in
which the regular expression are repeated NUMBER times with
cycle advancing (see ",").
@@ -1118,7 +1118,7 @@
;; Note - it is the backend's responsibility to fill any unfilled delay slots
;; at assembler generation time. This is usually done by adding a special print
-;; operand to the delayed insrtuction, and then in the PRINT_OPERAND function
+;; operand to the delayed instruction, and then in the PRINT_OPERAND function
;; calling dbr_sequence_length() to determine how many delay slots were filled.
;; For example:
;;
@@ -1364,7 +1364,7 @@
;; Note - it is best to only have one movsi pattern and to handle
;; all the various contingencies by the use of alternatives. This
-;; allows reload the greatest amount of flexability (since reload will
+;; allows reload the greatest amount of flexibility (since reload will
;; only choose amoungst alternatives for a selected insn, it will not
;; replace the insn with another one).
@@ -1374,7 +1374,7 @@
;; constants into memory when the destination is a floating-point register.
;; That may make a function use a PIC pointer when it didn't before, and we
;; cannot change PIC usage (and hence stack layout) so late in the game.
-;; The resulting sequences for loading cosntants into FPRs are preferable
+;; The resulting sequences for loading constants into FPRs are preferable
;; even when we're not generating PIC code.
(define_insn "*movsi_load"
@@ -2754,22 +2754,11 @@
;; Subtraction No need to worry about constants, since the compiler
;; canonicalizes them into adddi3's.
-(define_expand "subdi3"
- [(parallel [(set (match_operand:DI 0 "integer_register_operand" "")
- (minus:DI (match_operand:DI 1 "integer_register_operand" "")
- (match_operand:DI 2 "integer_register_operand" "")))
- (clobber (match_dup 3))])]
- ""
- "
-{
- operands[3] = gen_reg_rtx (CCmode);
-}")
-
-(define_insn_and_split "*subdi3_internal"
+(define_insn_and_split "subdi3"
[(set (match_operand:DI 0 "integer_register_operand" "=&e,e,e")
(minus:DI (match_operand:DI 1 "integer_register_operand" "e,0,e")
(match_operand:DI 2 "integer_register_operand" "e,e,0")))
- (clobber (match_operand:CC 3 "icc_operand" "=t,t,t"))]
+ (clobber (match_scratch:CC 3 "=t,t,t"))]
""
"#"
"reload_completed"
@@ -2842,6 +2831,31 @@
[(set_attr "length" "4")
(set_attr "type" "int")])
+(define_insn_and_split "negdi2"
+ [(set (match_operand:DI 0 "integer_register_operand" "=&e,e")
+ (neg:DI (match_operand:DI 1 "integer_register_operand" "e,0")))
+ (clobber (match_scratch:CC 2 "=t,t"))]
+ ""
+ "#"
+ "reload_completed"
+ [(match_dup 3)
+ (match_dup 4)]
+ "
+{
+ rtx op0_high = gen_highpart (SImode, operands[0]);
+ rtx op1_high = gen_rtx_REG (SImode, GPR_FIRST);
+ rtx op2_high = gen_highpart (SImode, operands[1]);
+ rtx op0_low = gen_lowpart (SImode, operands[0]);
+ rtx op1_low = op1_high;
+ rtx op2_low = gen_lowpart (SImode, operands[1]);
+ rtx op3 = operands[2];
+
+ operands[3] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3);
+ operands[4] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3);
+}"
+ [(set_attr "length" "8")
+ (set_attr "type" "multi")])
+
;; Multiplication (same size)
;; (define_insn "muldi3"
;; [(set (match_operand:DI 0 "register_operand" "=r")
@@ -3314,7 +3328,7 @@
;; "anddi3 %0,%1,%2"
;; [(set_attr "length" "4")])
-;; Includive OR, 64 bit integers
+;; Inclusive OR, 64 bit integers
;; (define_insn "iordi3"
;; [(set (match_operand:DI 0 "register_operand" "=r")
;; (ior:DI (match_operand:DI 1 "register_operand" "%r")
@@ -5456,7 +5470,7 @@
if (GET_CODE (operands[2]) != CONST_INT)
abort ();
- /* If we can't generate an immediate instruction, promote to register */
+ /* If we can't generate an immediate instruction, promote to register. */
if (! IN_RANGE_P (INTVAL (range), -2048, 2047))
range = force_reg (SImode, range);
@@ -5482,11 +5496,11 @@
emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail);
- /* Move the table address to a register */
+ /* Move the table address to a register. */
treg = gen_reg_rtx (Pmode);
emit_insn (gen_movsi (treg, gen_rtx_LABEL_REF (VOIDmode, table)));
- /* scale index-low by wordsize */
+ /* Scale index-low by wordsize. */
scale = gen_reg_rtx (SImode);
emit_insn (gen_ashlsi3 (scale, indx, GEN_INT (2)));
@@ -7379,7 +7393,7 @@
[(set_attr "length" "4")
(set_attr "type" "mqsath")])
-;; Set hi/lo instrctions: type "mset"
+;; Set hi/lo instructions: type "mset"
(define_insn "mhsetlos"
[(set (match_operand:SI 0 "fpr_operand" "=f")
diff --git a/contrib/gcc/config/frv/frvbegin.c b/contrib/gcc/config/frv/frvbegin.c
index a5f5b1f..d021b35 100644
--- a/contrib/gcc/config/frv/frvbegin.c
+++ b/contrib/gcc/config/frv/frvbegin.c
@@ -1,26 +1,33 @@
/* Frv initialization file linked before all user modules
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
This file was originally taken from the file crtstuff.c in the
- main compiler directory, and simplified. */
+ main compiler directory, and simplified. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
#include "defaults.h"
#include <stddef.h>
@@ -74,7 +81,7 @@ extern void __frv_deregister_eh(void) __attribute__((__destructor__));
extern func_ptr __EH_FRAME_BEGIN__[];
-/* Register the exeception handling table as the first constructor */
+/* Register the exception handling table as the first constructor. */
void
__frv_register_eh (void)
{
@@ -86,7 +93,7 @@ __frv_register_eh (void)
/* Note, do not declare __{,de}register_frame_info weak as it seems
to interfere with the pic support. */
-/* Unregister the exeception handling table as a deconstructor */
+/* Unregister the exception handling table as a deconstructor. */
void
__frv_deregister_eh (void)
{
@@ -101,9 +108,9 @@ __frv_deregister_eh (void)
completed = 1;
}
-/* Run the global destructors */
+/* Run the global destructors. */
void
-__do_global_dtors ()
+__do_global_dtors (void)
{
static func_ptr *p = __DTOR_LIST__ + 1;
while (*p)
@@ -113,9 +120,9 @@ __do_global_dtors ()
}
}
-/* Run the global constructors */
+/* Run the global constructors. */
void
-__do_global_ctors ()
+__do_global_ctors (void)
{
unsigned long nptrs = (unsigned long) __CTOR_LIST__[0];
unsigned i;
@@ -138,7 +145,7 @@ __do_global_ctors ()
to run __do_global_ctors, so we need not do anything here. */
void
-__main ()
+__main (void)
{
/* Support recursive calls to `main': run initializers just once. */
static int initialized;
diff --git a/contrib/gcc/config/frv/frvend.c b/contrib/gcc/config/frv/frvend.c
index f1635cc..6709cdb 100644
--- a/contrib/gcc/config/frv/frvend.c
+++ b/contrib/gcc/config/frv/frvend.c
@@ -1,23 +1,30 @@
/* Frv initialization file linked after all user modules
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
#include "defaults.h"
#include <stddef.h>
diff --git a/contrib/gcc/config/frv/lib1funcs.asm b/contrib/gcc/config/frv/lib1funcs.asm
index 18a8142..87666f4 100644
--- a/contrib/gcc/config/frv/lib1funcs.asm
+++ b/contrib/gcc/config/frv/lib1funcs.asm
@@ -1,24 +1,31 @@
/* Library functions.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
#include <frv-asm.h>
diff --git a/contrib/gcc/config/frv/t-frv b/contrib/gcc/config/frv/t-frv
index a92f63b..a9130ff 100644
--- a/contrib/gcc/config/frv/t-frv
+++ b/contrib/gcc/config/frv/t-frv
@@ -19,11 +19,11 @@ TARGET_LIBGCC2_CFLAGS =
fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
- echo '#include "frv/frv-abi.h"' >> fp-bit.c
+ echo '#include "config/frv/frv-abi.h"' >> fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
dp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#include "frv/frv-abi.h"' > dp-bit.c
+ echo '#include "config/frv/frv-abi.h"' > dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
cmovh.c: $(srcdir)/config/frv/cmovh.c
@@ -90,4 +90,4 @@ MULTILIB_EXCEPTIONS = mcpu=frv/mno-pack* mcpu=simple/mno-pack*
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
-EXTRA_HEADERS = $(srcdir)/config/frv/frv-asm.h $(srcdir)/config/frv/media.h
+EXTRA_HEADERS = $(srcdir)/config/frv/frv-asm.h
diff --git a/contrib/gcc/config/gnu.h b/contrib/gcc/config/gnu.h
index f5f4184..23a8a73 100644
--- a/contrib/gcc/config/gnu.h
+++ b/contrib/gcc/config/gnu.h
@@ -18,3 +18,15 @@
/* The system headers under GNU are C++-aware. */
#define NO_IMPLICIT_EXTERN_C
+
+#define HURD_TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__gnu_hurd__"); \
+ builtin_define ("__GNU__"); \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("MACH"); \
+ builtin_assert ("system=gnu"); \
+ builtin_assert ("system=mach"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } while (0)
diff --git a/contrib/gcc/config/gofast.h b/contrib/gcc/config/gofast.h
index 84e9018..81dd9f6 100644
--- a/contrib/gcc/config/gofast.h
+++ b/contrib/gcc/config/gofast.h
@@ -1,108 +1,80 @@
/* US Software GOFAST floating point library support.
- Copyright (C) 1994, 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* This is used by fp-bit.c. */
-#define US_SOFTWARE_GOFAST
-
/* The US Software GOFAST library requires special optabs support.
- There is no negation libcall, and several others have names different
- from gcc. This file consolidates the support in one place.
+ This file is intended to be included by config/ARCH/ARCH.c. It
+ defines one function, gofast_maybe_init_libfuncs, which should be
+ called from the TARGET_INIT_LIBFUNCS hook. When tm.h has defined
+ US_SOFTWARE_GOFAST, this function will adjust all the optabs and
+ libfuncs appropriately. Otherwise it will do nothing. */
+
+static void
+gofast_maybe_init_libfuncs (void)
+{
+#ifdef US_SOFTWARE_GOFAST
+ int mode;
+
+ set_optab_libfunc (add_optab, SFmode, "fpadd");
+ set_optab_libfunc (add_optab, DFmode, "dpadd");
+ set_optab_libfunc (sub_optab, SFmode, "fpsub");
+ set_optab_libfunc (sub_optab, DFmode, "dpsub");
+ set_optab_libfunc (smul_optab, SFmode, "fpmul");
+ set_optab_libfunc (smul_optab, DFmode, "dpmul");
+ set_optab_libfunc (sdiv_optab, SFmode, "fpdiv");
+ set_optab_libfunc (sdiv_optab, DFmode, "dpdiv");
+ set_optab_libfunc (cmp_optab, SFmode, "fpcmp");
+ set_optab_libfunc (cmp_optab, DFmode, "dpcmp");
+
+ /* GOFAST does not provide libfuncs for negation, so we use the
+ standard names. */
+
+ /* GCC does not use fpcmp/dpcmp for gt or ge because its own
+ FP-emulation library returns +1 for both > and unord. So we
+ leave gt and ge unset, such that, instead of fpcmp(a,b) >[=], we
+ generate fpcmp(b,a) <[=] 0, which is unambiguous. For unord
+ libfuncs, we use our own functions, since GOFAST doesn't supply
+ them. */
- The basic plan is to leave gcc proper alone and via some hook fix things
- after the optabs have been set up. Our main entry point is
- INIT_GOFAST_OPTABS. */
+ set_optab_libfunc (eq_optab, SFmode, "fpcmp");
+ set_optab_libfunc (ne_optab, SFmode, "fpcmp");
+ set_optab_libfunc (gt_optab, SFmode, 0);
+ set_optab_libfunc (ge_optab, SFmode, 0);
+ set_optab_libfunc (lt_optab, SFmode, "fpcmp");
+ set_optab_libfunc (le_optab, SFmode, "fpcmp");
-#define INIT_GOFAST_OPTABS \
- do { \
- GOFAST_CLEAR_NEG_FLOAT_OPTAB; \
- GOFAST_RENAME_LIBCALLS; \
- } while (0)
+ set_optab_libfunc (eq_optab, DFmode, "dpcmp");
+ set_optab_libfunc (ne_optab, DFmode, "dpcmp");
+ set_optab_libfunc (gt_optab, DFmode, 0);
+ set_optab_libfunc (ge_optab, DFmode, 0);
+ set_optab_libfunc (lt_optab, DFmode, "dpcmp");
+ set_optab_libfunc (le_optab, DFmode, "dpcmp");
-#define GOFAST_CLEAR_NEG_FLOAT_OPTAB \
- do { \
- int mode; \
- for (mode = SFmode; (int) mode <= (int) TFmode; \
- mode = (enum machine_mode) ((int) mode + 1)) \
- neg_optab->handlers[(int) mode].libfunc = NULL_RTX; \
- } while (0)
+ set_conv_libfunc (sext_optab, DFmode, SFmode, "fptodp");
+ set_conv_libfunc (trunc_optab, SFmode, DFmode, "dptofp");
-/* GCC does not use fpcmp/dpcmp for gt or ge because its own
- FP-emulation library returns +1 for both > and unord. So we leave
- gt and ge unset, such that, instead of fpcmp(a,b) >[=], we generate
- fpcmp(b,a) <[=] 0, which is unambiguous. For unord libfuncs, we
- use our own functions, since GOFAST doesn't supply them. */
-#define GOFAST_RENAME_LIBCALLS \
- add_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpadd"); \
- add_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpadd"); \
- sub_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpsub"); \
- sub_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpsub"); \
- smul_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpmul"); \
- smul_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpmul"); \
- sdiv_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpdiv"); \
- sdiv_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpdiv"); \
- cmp_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpcmp"); \
- cmp_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpcmp"); \
-\
- extendsfdf2_libfunc = init_one_libfunc ("fptodp"); \
- truncdfsf2_libfunc = init_one_libfunc ("dptofp"); \
-\
- eqhf2_libfunc = NULL_RTX; \
- nehf2_libfunc = NULL_RTX; \
- gthf2_libfunc = NULL_RTX; \
- gehf2_libfunc = NULL_RTX; \
- lthf2_libfunc = NULL_RTX; \
- lehf2_libfunc = NULL_RTX; \
-\
- eqsf2_libfunc = init_one_libfunc ("fpcmp"); \
- nesf2_libfunc = init_one_libfunc ("fpcmp"); \
- gtsf2_libfunc = NULL_RTX; \
- gesf2_libfunc = NULL_RTX; \
- ltsf2_libfunc = init_one_libfunc ("fpcmp"); \
- lesf2_libfunc = init_one_libfunc ("fpcmp"); \
-\
- eqdf2_libfunc = init_one_libfunc ("dpcmp"); \
- nedf2_libfunc = init_one_libfunc ("dpcmp"); \
- gtdf2_libfunc = NULL_RTX; \
- gedf2_libfunc = NULL_RTX; \
- ltdf2_libfunc = init_one_libfunc ("dpcmp"); \
- ledf2_libfunc = init_one_libfunc ("dpcmp"); \
-\
- eqxf2_libfunc = NULL_RTX; \
- nexf2_libfunc = NULL_RTX; \
- gtxf2_libfunc = NULL_RTX; \
- gexf2_libfunc = NULL_RTX; \
- ltxf2_libfunc = NULL_RTX; \
- lexf2_libfunc = NULL_RTX; \
-\
- eqtf2_libfunc = NULL_RTX; \
- netf2_libfunc = NULL_RTX; \
- gttf2_libfunc = NULL_RTX; \
- getf2_libfunc = NULL_RTX; \
- lttf2_libfunc = NULL_RTX; \
- letf2_libfunc = NULL_RTX; \
-\
- floatsisf_libfunc = init_one_libfunc ("sitofp"); \
- floatsidf_libfunc = init_one_libfunc ("litodp"); \
- fixsfsi_libfunc = init_one_libfunc ("fptosi"); \
- fixdfsi_libfunc = init_one_libfunc ("dptoli"); \
- fixunssfsi_libfunc = init_one_libfunc ("fptoui"); \
- fixunsdfsi_libfunc = init_one_libfunc ("dptoul"); \
+ set_conv_libfunc (sfix_optab, SImode, SFmode, "fptosi");
+ set_conv_libfunc (sfix_optab, SImode, DFmode, "dptoli");
+ set_conv_libfunc (ufix_optab, SImode, SFmode, "fptoui");
+ set_conv_libfunc (ufix_optab, SImode, DFmode, "dptoul");
-/* End of GOFAST_RENAME_LIBCALLS */
+ set_conv_libfunc (sfloat_optab, SFmode, SImode, "sitofp");
+ set_conv_libfunc (sfloat_optab, DFmode, SImode, "litodp");
+#endif
+}
diff --git a/contrib/gcc/config/i386/athlon.md b/contrib/gcc/config/i386/athlon.md
index 548f2ad..4ce9a38 100644
--- a/contrib/gcc/config/i386/athlon.md
+++ b/contrib/gcc/config/i386/athlon.md
@@ -1,34 +1,5 @@
;; AMD Athlon Scheduling
-;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
-;;
-;; GNU CC 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 2, or (at your option)
-;; any later version.
-;;
-;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA. */
-(define_attr "athlon_decode" "direct,vector"
- (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
- (const_string "vector")
- (and (eq_attr "type" "push")
- (match_operand 1 "memory_operand" ""))
- (const_string "vector")
- (and (eq_attr "type" "fmov")
- (and (eq_attr "memory" "load,store")
- (eq_attr "mode" "XF")))
- (const_string "vector")]
- (const_string "direct")))
-
;; The Athlon does contain three pipelined FP units, three integer units and
;; three address generation units.
;;
@@ -46,161 +17,853 @@
;; The load/store queue unit is not attached to the schedulers but
;; communicates with all the execution units separately instead.
-(define_function_unit "athlon_vectordec" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_decode" "vector"))
- 1 1)
-
-(define_function_unit "athlon_directdec" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_decode" "direct"))
- 1 1)
-
-(define_function_unit "athlon_vectordec" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_decode" "direct"))
- 1 1 [(eq_attr "athlon_decode" "vector")])
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ishift1,rotate,rotate1,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
- 1 1)
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "str"))
- 15 15)
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "imul"))
- 5 0)
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "idiv"))
- 42 0)
-
-(define_function_unit "athlon_muldiv" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "imul"))
- 5 0)
-
-(define_function_unit "athlon_muldiv" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "idiv"))
- 42 42)
-
-(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
- (cond [(eq_attr "type" "fop,fcmp,fistp")
- (const_string "add")
- (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
- (const_string "mul")
- (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
- (const_string "store")
- (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
- (const_string "any")
+(define_attr "athlon_decode" "direct,vector,double"
+ (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,leave")
+ (const_string "vector")
+ (and (eq_attr "type" "push")
+ (match_operand 1 "memory_operand" ""))
+ (const_string "vector")
(and (eq_attr "type" "fmov")
- (ior (match_operand:SI 1 "register_operand" "")
- (match_operand 1 "immediate_operand" "")))
- (const_string "store")
- (eq_attr "type" "fmov")
- (const_string "muladd")]
- (const_string "none")))
-
-;; We use latencies 1 for definitions. This is OK to model colisions
-;; in execution units. The real latencies are modeled in the "fp" pipeline.
-
-;; fsin, fcos: 96-192
-;; fsincos: 107-211
-;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fpspc"))
- 100 1)
-
-;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fdiv"))
- 24 1)
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fop,fmul,fistp"))
- 4 1)
-
-;; XFmode loads are slow.
-;; XFmode store is slow too (8 cycles), but we don't need to model it, because
-;; there are no dependent instructions.
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (and (eq_attr "type" "fmov")
- (and (eq_attr "memory" "load")
- (eq_attr "mode" "XF"))))
- 10 1)
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fmov,fsgn"))
- 2 1)
-
-;; fcmp and ftst instructions
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (and (eq_attr "type" "fcmp")
- (eq_attr "athlon_decode" "direct")))
- 3 1)
-
-;; fcmpi instructions.
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (and (eq_attr "type" "fcmp")
- (eq_attr "athlon_decode" "vector")))
- 3 1)
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fcmov"))
- 7 1)
-
-(define_function_unit "athlon_fp_mul" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "mul"))
- 1 1)
-
-(define_function_unit "athlon_fp_add" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "add"))
- 1 1)
-
-(define_function_unit "athlon_fp_muladd" 2 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "muladd,mul,add"))
- 1 1)
-
-(define_function_unit "athlon_fp_store" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "store"))
- 1 1)
-
-;; We don't need to model the Address Generation Unit, since we don't model
-;; the re-order buffer yet and thus we never schedule more than three operations
-;; at time. Later we may want to experiment with MD_SCHED macros modeling the
-;; decoders independently on the functional units.
-
-;(define_function_unit "athlon_agu" 3 0
-; (and (eq_attr "cpu" "athlon")
-; (and (eq_attr "memory" "!none")
-; (eq_attr "athlon_fpunits" "none")))
-; 1 1)
-
-;; Model load unit to avoid too long sequences of loads. We don't need to
-;; model store queue, since it is hardly going to be bottleneck.
-
-(define_function_unit "athlon_load" 2 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "memory" "load,both"))
- 1 1)
+ (and (eq_attr "memory" "load,store")
+ (eq_attr "mode" "XF")))
+ (const_string "vector")]
+ (const_string "direct")))
+
+;;
+;; decode0 decode1 decode2
+;; \ | /
+;; instruction control unit (72 entry scheduler)
+;; | |
+;; integer scheduler (18) stack map
+;; / | | | | \ stack rename
+;; ieu0 agu0 ieu1 agu1 ieu2 agu2 scheduler
+;; | agu0 | agu1 agu2 register file
+;; | \ | | / | | |
+;; \ /\ | / fadd fmul fstore
+;; \ / \ | / fadd fmul fstore
+;; imul load/store (2x) fadd fmul fstore
+
+(define_automaton "athlon,athlon_load,athlon_mult,athlon_fp")
+(define_cpu_unit "athlon-decode0" "athlon")
+(define_cpu_unit "athlon-decode1" "athlon")
+(define_cpu_unit "athlon-decode2" "athlon")
+(define_cpu_unit "athlon-decodev" "athlon")
+;; Model the fact that double decoded instruction may take 2 cycles
+;; to decode when decoder2 and decoder0 in next cycle
+;; is used (this is needed to allow troughput of 1.5 double decoded
+;; instructions per cycle).
+;;
+;; In order to avoid dependence between reservation of decoder
+;; and other units, we model decoder as two stage fully pipelined unit
+;; and only double decoded instruction may occupy unit in the first cycle.
+;; With this scheme however two double instructions can be issued cycle0.
+;;
+;; Avoid this by using presence set requiring decoder0 to be allocated
+;; too. Vector decoded instructions then can't be issued when
+;; modeled as consuming decoder0+decoder1+decoder2.
+;; We solve that by specialized vector decoder unit and exclusion set.
+(presence_set "athlon-decode2" "athlon-decode0")
+(exclusion_set "athlon-decodev" "athlon-decode0,athlon-decode1,athlon-decode2")
+(define_reservation "athlon-vector" "nothing,athlon-decodev")
+(define_reservation "athlon-direct0" "nothing,athlon-decode0")
+(define_reservation "athlon-direct" "nothing,
+ (athlon-decode0 | athlon-decode1
+ | athlon-decode2)")
+;; Double instructions behaves like two direct instructions.
+(define_reservation "athlon-double" "((athlon-decode2, athlon-decode0)
+ | (nothing,(athlon-decode0 + athlon-decode1))
+ | (nothing,(athlon-decode1 + athlon-decode2)))")
+
+;; Agu and ieu unit results in extremely large automatons and
+;; in our approximation they are hardly filled in. Only ieu
+;; unit can, as issue rate is 3 and agu unit is always used
+;; first in the insn reservations. Skip the models.
+
+;(define_cpu_unit "athlon-ieu0" "athlon_ieu")
+;(define_cpu_unit "athlon-ieu1" "athlon_ieu")
+;(define_cpu_unit "athlon-ieu2" "athlon_ieu")
+;(define_reservation "athlon-ieu" "(athlon-ieu0 | athlon-ieu1 | athlon-ieu2)")
+(define_reservation "athlon-ieu" "nothing")
+(define_cpu_unit "athlon-ieu0" "athlon")
+;(define_cpu_unit "athlon-agu0" "athlon_agu")
+;(define_cpu_unit "athlon-agu1" "athlon_agu")
+;(define_cpu_unit "athlon-agu2" "athlon_agu")
+;(define_reservation "athlon-agu" "(athlon-agu0 | athlon-agu1 | athlon-agu2)")
+(define_reservation "athlon-agu" "nothing")
+
+(define_cpu_unit "athlon-mult" "athlon_mult")
+
+(define_cpu_unit "athlon-load0" "athlon_load")
+(define_cpu_unit "athlon-load1" "athlon_load")
+(define_reservation "athlon-load" "athlon-agu,
+ (athlon-load0 | athlon-load1),nothing")
+;; 128bit SSE instructions issue two loads at once
+(define_reservation "athlon-load2" "athlon-agu,
+ (athlon-load0 + athlon-load1),nothing")
+
+(define_reservation "athlon-store" "(athlon-load0 | athlon-load1)")
+;; 128bit SSE instructions issue two stores at once
+(define_reservation "athlon-store2" "(athlon-load0 + athlon-load1)")
+
+
+;; The FP operations start to execute at stage 12 in the pipeline, while
+;; integer operations start to execute at stage 9 for Athlon and 11 for K8
+;; Compensate the difference for Athlon because it results in significantly
+;; smaller automata.
+(define_reservation "athlon-fpsched" "nothing,nothing,nothing")
+;; The floating point loads.
+(define_reservation "athlon-fpload" "(athlon-fpsched + athlon-load)")
+(define_reservation "athlon-fpload2" "(athlon-fpsched + athlon-load2)")
+(define_reservation "athlon-fploadk8" "(athlon-fpsched + athlon-load)")
+(define_reservation "athlon-fpload2k8" "(athlon-fpsched + athlon-load2)")
+
+
+;; The three fp units are fully pipelined with latency of 3
+(define_cpu_unit "athlon-fadd" "athlon_fp")
+(define_cpu_unit "athlon-fmul" "athlon_fp")
+(define_cpu_unit "athlon-fstore" "athlon_fp")
+(define_reservation "athlon-fany" "(athlon-fstore | athlon-fmul | athlon-fadd)")
+(define_reservation "athlon-faddmul" "(athlon-fmul | athlon-fadd)")
+
+;; Vector operations usually consume many of pipes.
+(define_reservation "athlon-fvector" "(athlon-fadd + athlon-fmul + athlon-fstore)")
+
+
+;; Jump instructions are executed in the branch unit completely transparent to us
+(define_insn_reservation "athlon_branch" 0
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "ibr"))
+ "athlon-direct,athlon-ieu")
+(define_insn_reservation "athlon_call" 0
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "call,callv"))
+ "athlon-vector,athlon-ieu")
+
+;; Latency of push operation is 3 cycles, but ESP value is available
+;; earlier
+(define_insn_reservation "athlon_push" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "push"))
+ "athlon-direct,athlon-agu,athlon-store")
+(define_insn_reservation "athlon_pop" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "pop"))
+ "athlon-vector,athlon-load,athlon-ieu")
+(define_insn_reservation "athlon_pop_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "pop"))
+ "athlon-double,(athlon-ieu+athlon-load)")
+(define_insn_reservation "athlon_leave" 3
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "leave"))
+ "athlon-vector,(athlon-ieu+athlon-load)")
+(define_insn_reservation "athlon_leave_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "leave"))
+ "athlon-double,(athlon-ieu+athlon-load)")
+
+;; Lea executes in AGU unit with 2 cycles latency.
+(define_insn_reservation "athlon_lea" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "lea"))
+ "athlon-direct,athlon-agu,nothing")
+
+;; Mul executes in special multiplier unit attached to IEU0
+(define_insn_reservation "athlon_imul" 5
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "none,unknown")))
+ "athlon-vector,athlon-ieu0,athlon-mult,nothing,nothing,athlon-ieu0")
+;; ??? Widening multiply is vector or double.
+(define_insn_reservation "athlon_imul_k8_DI" 4
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "mode" "DI")
+ (eq_attr "memory" "none,unknown"))))
+ "athlon-direct0,athlon-ieu0,athlon-mult,nothing,athlon-ieu0")
+(define_insn_reservation "athlon_imul_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "none,unknown")))
+ "athlon-direct0,athlon-ieu0,athlon-mult,athlon-ieu0")
+(define_insn_reservation "athlon_imul_mem" 8
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "load,both")))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-mult,nothing,nothing,athlon-ieu")
+(define_insn_reservation "athlon_imul_mem_k8_DI" 7
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "mode" "DI")
+ (eq_attr "memory" "load,both"))))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-mult,nothing,athlon-ieu")
+(define_insn_reservation "athlon_imul_mem_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "load,both")))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-mult,athlon-ieu")
+
+;; Idiv can not execute in parallel with other instructions. Dealing with it
+;; as with short latency vector instruction is good approximation avoiding
+;; scheduler from trying too hard to can hide it's latency by overlap with
+;; other instructions.
+;; ??? Experiments show that the idiv can overlap with roughly 6 cycles
+;; of the other code
+
+(define_insn_reservation "athlon_idiv" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "memory" "none,unknown")))
+ "athlon-vector,(athlon-ieu0*6+(athlon-fpsched,athlon-fvector))")
+(define_insn_reservation "athlon_idiv_mem" 9
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "memory" "load,both")))
+ "athlon-vector,((athlon-load,athlon-ieu0*6)+(athlon-fpsched,athlon-fvector))")
+;; The parallelism of string instructions is not documented. Model it same way
+;; as idiv to create smaller automata. This probably does not matter much.
+(define_insn_reservation "athlon_str" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "str")
+ (eq_attr "memory" "load,both,store")))
+ "athlon-vector,athlon-load,athlon-ieu0*6")
+
+(define_insn_reservation "athlon_idirect" 1
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "none,unknown"))))
+ "athlon-direct,athlon-ieu")
+(define_insn_reservation "athlon_ivector" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "none,unknown"))))
+ "athlon-vector,athlon-ieu,athlon-ieu")
+(define_insn_reservation "athlon_idirect_loadmov" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-load")
+(define_insn_reservation "athlon_idirect_load" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-load,athlon-ieu")
+(define_insn_reservation "athlon_ivector_load" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-ieu")
+(define_insn_reservation "athlon_idirect_movstore" 1
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "store")))
+ "athlon-direct,athlon-agu,athlon-store")
+(define_insn_reservation "athlon_idirect_both" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "both"))))
+ "athlon-direct,athlon-load,
+ athlon-ieu,athlon-store,
+ athlon-store")
+(define_insn_reservation "athlon_ivector_both" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "both"))))
+ "athlon-vector,athlon-load,
+ athlon-ieu,
+ athlon-ieu,
+ athlon-store")
+(define_insn_reservation "athlon_idirect_store" 1
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "store"))))
+ "athlon-direct,(athlon-ieu+athlon-agu),
+ athlon-store")
+(define_insn_reservation "athlon_ivector_store" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "store"))))
+ "athlon-vector,(athlon-ieu+athlon-agu),athlon-ieu,
+ athlon-store")
+
+;; Athlon floatin point unit
+(define_insn_reservation "athlon_fldxf" 12
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "load")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,athlon-fpload2,athlon-fvector*9")
+(define_insn_reservation "athlon_fldxf_k8" 13
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "load")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,athlon-fpload2k8,athlon-fvector*9")
+;; Assume superforwarding to take place so effective latency of fany op is 0.
+(define_insn_reservation "athlon_fld" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fany")
+(define_insn_reservation "athlon_fld_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+
+(define_insn_reservation "athlon_fstxf" 10
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "store,both")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,(athlon-fpsched+athlon-agu),(athlon-store2+(athlon-fvector*7))")
+(define_insn_reservation "athlon_fstxf_k8" 8
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "store,both")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,(athlon-fpsched+athlon-agu),(athlon-store2+(athlon-fvector*6))")
+(define_insn_reservation "athlon_fst" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "store,both")))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_fst_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "store,both")))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_fist" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fistp"))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_fmov" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fmov"))
+ "athlon-direct,athlon-fpsched,athlon-faddmul")
+(define_insn_reservation "athlon_fadd_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fop")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_fadd_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fop")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_fadd" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fop"))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_fmul_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmul")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_fmul_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmul")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fmul")
+(define_insn_reservation "athlon_fmul" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fmul"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fsgn" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fsgn"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fdiv_load" 24
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fdiv")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_fdiv_load_k8" 13
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fdiv")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fmul")
+(define_insn_reservation "athlon_fdiv" 24
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "fdiv"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fdiv_k8" 11
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "fdiv"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fpspc_load" 103
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "fpspc")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload,athlon-fvector")
+(define_insn_reservation "athlon_fpspc" 100
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fpspc"))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+(define_insn_reservation "athlon_fcmov_load" 7
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmov")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload,athlon-fvector")
+(define_insn_reservation "athlon_fcmov" 7
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "fcmov"))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+(define_insn_reservation "athlon_fcmov_load_k8" 17
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fcmov")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fploadk8,athlon-fvector")
+(define_insn_reservation "athlon_fcmov_k8" 15
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "fcmov"))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+;; fcomi is vector decoded by uses only one pipe.
+(define_insn_reservation "athlon_fcomi_load" 3
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmp")
+ (and (eq_attr "athlon_decode" "vector")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_fcomi_load_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fcmp")
+ (and (eq_attr "athlon_decode" "vector")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_fcomi" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (eq_attr "type" "fcmp")))
+ "athlon-vector,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_fcom_load" 2
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmp")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_fcom_load_k8" 4
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fcmp")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_fcom" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fcmp"))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+;; Never seen by the scheduler because we still don't do post reg-stack
+;; scheduling.
+;(define_insn_reservation "athlon_fxch" 2
+; (and (eq_attr "cpu" "athlon,k8")
+; (eq_attr "type" "fxch"))
+; "athlon-direct,athlon-fpsched,athlon-fany")
+
+;; Athlon handle MMX operations in the FPU unit with shorter latencies
+
+(define_insn_reservation "athlon_movlpd_load" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (match_operand:DF 1 "memory_operand" "")))
+ "athlon-direct,athlon-fpload,athlon-fany")
+(define_insn_reservation "athlon_movlpd_load_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (match_operand:DF 1 "memory_operand" "")))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+(define_insn_reservation "athlon_movaps_load_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "load"))))
+ "athlon-double,athlon-fpload2k8,athlon-fstore,athlon-fstore")
+(define_insn_reservation "athlon_movaps_load" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fpload2,(athlon-fany+athlon-fany)")
+(define_insn_reservation "athlon_movss_load" 1
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "SF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fpload,(athlon-fany*2)")
+(define_insn_reservation "athlon_movss_load_k8" 1
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "SF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-double,athlon-fploadk8,(athlon-fstore+athlon-fany)")
+(define_insn_reservation "athlon_mmxsseld" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fany")
+(define_insn_reservation "athlon_mmxsseld_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+(define_insn_reservation "athlon_mmxssest" 3
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "store,both"))))
+ "athlon-vector,(athlon-fpsched+athlon-agu),((athlon-fstore+athlon-store2)*2)")
+(define_insn_reservation "athlon_mmxssest_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "store,both"))))
+ "athlon-double,(athlon-fpsched+athlon-agu),((athlon-fstore+athlon-store2)*2)")
+(define_insn_reservation "athlon_mmxssest_short" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (eq_attr "memory" "store,both")))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_movaps" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "mode" "V4SF,V2DF,TI")))
+ "athlon-double,athlon-fpsched,(athlon-faddmul+athlon-faddmul)")
+(define_insn_reservation "athlon_movaps_k8" 2
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "mode" "V4SF,V2DF,TI")))
+ "athlon-vector,athlon-fpsched,(athlon-faddmul+athlon-faddmul)")
+(define_insn_reservation "athlon_mmxssemov" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "mmxmov,ssemov"))
+ "athlon-direct,athlon-fpsched,athlon-faddmul")
+(define_insn_reservation "athlon_mmxmul_load" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "mmxmul")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_mmxmul" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "mmxmul"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_mmx_load" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "unit" "mmx")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-faddmul")
+(define_insn_reservation "athlon_mmx" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "unit" "mmx"))
+ "athlon-direct,athlon-fpsched,athlon-faddmul")
+;; SSE operations are handled by the i387 unit as well. The latency
+;; is same as for i387 operations for scalar operations
+
+(define_insn_reservation "athlon_sselog_load" 3
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fmul*2)")
+(define_insn_reservation "athlon_sselog_load_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fmul*2)")
+(define_insn_reservation "athlon_sselog" 3
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "sselog"))
+ "athlon-vector,athlon-fpsched,athlon-fmul*2")
+(define_insn_reservation "athlon_sselog_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "sselog"))
+ "athlon-double,athlon-fpsched,athlon-fmul")
+;; ??? pcmp executes in addmul, probably not wortwhile to brother about that.
+(define_insn_reservation "athlon_ssecmp_load" 2
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssecmp")
+ (and (eq_attr "mode" "SF,DF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_ssecmp_load_k8" 4
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssecmp")
+ (and (eq_attr "mode" "SF,DF,DI,TI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_ssecmp" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "mode" "SF,DF,DI,TI")))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_ssecmpvector_load" 3
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecmpvector_load_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecmpvector" 3
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "ssecmp"))
+ "athlon-vector,athlon-fpsched,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecmpvector_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "ssecmp"))
+ "athlon-double,athlon-fpsched,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecomi_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_ssecomi_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_ssecomi" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "ssecmp"))
+ "athlon-vector,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_sseadd_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "mode" "SF,DF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_sseadd_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "mode" "SF,DF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_sseadd" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "mode" "SF,DF,DI")))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_sseaddvector_load" 5
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fadd*2)")
+(define_insn_reservation "athlon_sseaddvector_load_k8" 7
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fadd*2)")
+(define_insn_reservation "athlon_sseaddvector" 5
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "sseadd"))
+ "athlon-vector,athlon-fpsched,(athlon-fadd*2)")
+(define_insn_reservation "athlon_sseaddvector_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "sseadd"))
+ "athlon-double,athlon-fpsched,(athlon-fadd*2)")
+
+;; Conversions behaves very irregularly and the scheduling is critical here.
+;; Take each instruction separately. Assume that the mode is always set to the
+;; destination one and athlon_decode is set to the K8 versions.
+
+;; cvtss2sd
+(define_insn_reservation "athlon_ssecvt_cvtss2sd_load_k8" 4
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "mode" "DF")
+ (eq_attr "memory" "load")))))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+(define_insn_reservation "athlon_ssecvt_cvtss2sd" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "direct")
+ (eq_attr "mode" "DF"))))
+ "athlon-direct,athlon-fpsched,athlon-fstore")
+;; cvtps2pd. Model same way the other double decoded FP conversions.
+(define_insn_reservation "athlon_ssecvt_cvtps2pd_load_k8" 5
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "V2DF,V4SF,TI")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fpload2k8,(athlon-fstore*2)")
+(define_insn_reservation "athlon_ssecvt_cvtps2pd_k8" 3
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "double")
+ (eq_attr "mode" "V2DF,V4SF,TI"))))
+ "athlon-double,athlon-fpsched,athlon-fstore,athlon-fstore")
+;; cvtsi2sd mem,reg is directpath path (cvtsi2sd reg,reg is doublepath)
+;; cvtsi2sd has troughput 1 and is executed in store unit with latency of 6
+(define_insn_reservation "athlon_sseicvt_cvtsi2sd_load" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load")))))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+;; cvtsi2ss mem, reg is doublepath
+(define_insn_reservation "athlon_sseicvt_cvtsi2ss_load" 9
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load")))))
+ "athlon-vector,athlon-fpload,(athlon-fstore*2)")
+(define_insn_reservation "athlon_sseicvt_cvtsi2ss_load_k8" 9
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fploadk8,(athlon-fstore*2)")
+;; cvtsi2sd reg,reg is double decoded (vector on Athlon)
+(define_insn_reservation "athlon_sseicvt_cvtsi2sd_k8" 11
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "none")))))
+ "athlon-double,athlon-fploadk8,athlon-fstore")
+;; cvtsi2ss reg, reg is doublepath
+(define_insn_reservation "athlon_sseicvt_cvtsi2ss" 14
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fploadk8,(athlon-fvector*2)")
+;; cvtsd2ss mem,reg is doublepath, troughput unknown, latency 9
+(define_insn_reservation "athlon_ssecvt_cvtsd2ss_load_k8" 9
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fploadk8,(athlon-fstore*3)")
+;; cvtsd2ss reg,reg is vectorpath, troughput unknown, latency 12
+(define_insn_reservation "athlon_ssecvt_cvtsd2ss" 12
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fpsched,(athlon-fvector*3)")
+(define_insn_reservation "athlon_ssecvt_cvtpd2ps_load_k8" 8
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fpload2k8,(athlon-fstore*3)")
+;; cvtpd2ps mem,reg is vectorpath, troughput unknown, latency 10
+;; ??? Why it is fater than cvtsd2ss?
+(define_insn_reservation "athlon_ssecvt_cvtpd2ps" 8
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fpsched,athlon-fvector*2")
+;; cvtsd2si mem,reg is doublepath, troughput 1, latency 9
+(define_insn_reservation "athlon_secvt_cvtsX2si_load" 9
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "memory" "load")))))
+ "athlon-vector,athlon-fploadk8,athlon-fvector")
+;; cvtsd2si reg,reg is doublepath, troughput 1, latency 9
+(define_insn_reservation "athlon_ssecvt_cvtsX2si" 9
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+(define_insn_reservation "athlon_ssecvt_cvtsX2si_k8" 9
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "memory" "none")))))
+ "athlon-double,athlon-fpsched,athlon-fstore")
+
+(define_insn_reservation "athlon_ssemul_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemul")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_ssemul_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemul")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fmul")
+(define_insn_reservation "athlon_ssemul" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "mode" "SF,DF")))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_ssemulvector_load" 5
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fmul*2)")
+(define_insn_reservation "athlon_ssemulvector_load_k8" 7
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fmul*2)")
+(define_insn_reservation "athlon_ssemulvector" 5
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "ssemul"))
+ "athlon-vector,athlon-fpsched,(athlon-fmul*2)")
+(define_insn_reservation "athlon_ssemulvector_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "ssemul"))
+ "athlon-double,athlon-fpsched,(athlon-fmul*2)")
+;; divsd timings. divss is faster
+(define_insn_reservation "athlon_ssediv_load" 20
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssediv")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fmul*17")
+(define_insn_reservation "athlon_ssediv_load_k8" 22
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssediv")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fmul*17")
+(define_insn_reservation "athlon_ssediv" 20
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "mode" "SF,DF")))
+ "athlon-direct,athlon-fpsched,athlon-fmul*17")
+(define_insn_reservation "athlon_ssedivvector_load" 39
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,athlon-fmul*34")
+(define_insn_reservation "athlon_ssedivvector_load_k8" 35
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,athlon-fmul*34")
+(define_insn_reservation "athlon_ssedivvector" 39
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "ssediv"))
+ "athlon-vector,athlon-fmul*34")
+(define_insn_reservation "athlon_ssedivvector_k8" 39
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "ssediv"))
+ "athlon-double,athlon-fmul*34")
diff --git a/contrib/gcc/config/i386/att.h b/contrib/gcc/config/i386/att.h
index 70ae164..4ee85ae 100644
--- a/contrib/gcc/config/i386/att.h
+++ b/contrib/gcc/config/i386/att.h
@@ -2,20 +2,20 @@
Copyright (C) 1988, 1996, 2000, 2001, 2002
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -45,18 +45,7 @@ do \
} while (0)
/* Output at beginning of assembler file. */
-/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- output_file_directive (FILE, main_input_filename); \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- } while (0)
-
-/* Do use .optim by default on this machine. */
-#undef ASM_FILE_START_1
-#define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.optim\n")
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* This is how to output an assembler line
that says to advance the location counter
@@ -69,7 +58,7 @@ do \
that says to advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf ((FILE), "\t.set .,.+%u\n", (SIZE))
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(SIZE))
/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */
@@ -90,13 +79,6 @@ do \
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), "%s%s%ld", LOCAL_LABEL_PREFIX, (PREFIX), (long)(NUMBER))
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%s%d:\n", LOCAL_LABEL_PREFIX, PREFIX, NUM)
-
/* The prefix to add to user-visible assembler symbols. */
#undef USER_LABEL_PREFIX
diff --git a/contrib/gcc/config/i386/beos-elf.h b/contrib/gcc/config/i386/beos-elf.h
index b84519f..50c3926 100644
--- a/contrib/gcc/config/i386/beos-elf.h
+++ b/contrib/gcc/config/i386/beos-elf.h
@@ -1,20 +1,20 @@
/* Definitions for Intel x86 running BeOS
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -58,7 +58,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define ("__ELF__"); \
builtin_define ("__BEOS__"); \
builtin_define ("__INTEL__"); \
builtin_define ("_X86_"); \
@@ -79,7 +78,7 @@ Boston, MA 02111-1307, USA. */
CC1_SPEC is used for both cc1 and cc1plus. */
#undef CC1_SPEC
-#define CC1_SPEC "%{!no-fpic:%{!fPIC:-fpic}} %{!Wmultichar: -Wno-multichar} %(cc1_cpu) %{profile:-p}"
+#define CC1_SPEC "%{!no-fpic:%{!fno-pic:%{!fno-pie:%{!fpie:%{!fPIC:%{!fPIE:-fpic}}}}}} %{!Wmultichar: -Wno-multichar} %(cc1_cpu) %{profile:-p}"
#undef CC1PLUS_SPEC
#define CC1PLUS_SPEC "%{!Wctor-dtor-privacy:-Wno-ctor-dtor-privacy}"
diff --git a/contrib/gcc/config/i386/biarch64.h b/contrib/gcc/config/i386/biarch64.h
index 2d34698..532cfe7 100644
--- a/contrib/gcc/config/i386/biarch64.h
+++ b/contrib/gcc/config/i386/biarch64.h
@@ -4,20 +4,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Bo Thorsen <bo@suse.de>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/bsd.h b/contrib/gcc/config/i386/bsd.h
index 69ad168..905b232e 100644
--- a/contrib/gcc/config/i386/bsd.h
+++ b/contrib/gcc/config/i386/bsd.h
@@ -3,20 +3,20 @@
adapted to BSD conventions for symbol names and debugging.)
Copyright (C) 1988, 1996, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -36,13 +36,6 @@ Boston, MA 02111-1307, USA. */
#define ASM_LONG "\t.long\t"
#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */
-/* Output at beginning of assembler file.
- ??? I am skeptical of this -- RMS. */
-
-#define ASM_FILE_START(FILE) \
- do { output_file_directive (FILE, main_input_filename); \
- } while (0)
-
/* This was suggested, but it shouldn't be right for DBX output. -- RMS
#define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */
@@ -53,7 +46,7 @@ Boston, MA 02111-1307, USA. */
that says to advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.space %u\n", (SIZE))
+ fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* Define the syntax of labels and symbol definitions/declarations. */
@@ -63,7 +56,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -71,7 +64,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
( fputs (".lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
/* This is how to output an assembler line
that says to advance the location counter
@@ -88,12 +81,6 @@ Boston, MA 02111-1307, USA. */
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), "*%s%ld", (PREFIX), (long)(NUMBER))
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%d:\n", PREFIX, NUM)
-
/* The prefix to add to user-visible assembler symbols. */
#define USER_LABEL_PREFIX "_"
diff --git a/contrib/gcc/config/i386/crtdll.h b/contrib/gcc/config/i386/crtdll.h
index dab60c1..afdae58 100644
--- a/contrib/gcc/config/i386/crtdll.h
+++ b/contrib/gcc/config/i386/crtdll.h
@@ -1,34 +1,43 @@
/* Operating system specific defines to be used when targeting GCC for
hosting on Windows32, using GNU tools and the Windows32 API Library.
- This variant uses CRTDLL.DLL insted of MSVCRTDLL.DLL.
+ This variant uses CRTDLL.DLL instead of MSVCRTDLL.DLL.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef EXTRA_OS_CPP_BUILTINS
-#define EXTRA_OS_CPP_BUILTINS() \
- do { builtin_define ("__MINGW32__=0.2"); } while (0)
+#define EXTRA_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__CRTDLL__"); \
+ builtin_define ("__MINGW32__"); \
+ builtin_define ("_WIN32"); \
+ builtin_define_std ("WIN32"); \
+ builtin_define_std ("WINNT"); \
+ } \
+ while (0)
#undef LIBGCC_SPEC
#define LIBGCC_SPEC \
- "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lcrtdll"
+ "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lcoldname -libmingwex -lcrtdll"
/* Specify a different entry point when linking a DLL */
#undef STARTFILE_SPEC
-#define STARTFILE_SPEC "%{mdll:dllcrt1%O%s} %{!mdll:crt1%O%s} %{pg:gcrt1%O%s}"
+#define STARTFILE_SPEC "%{shared|mdll:dllcrt1%O%s} \
+ %{!shared:%{!mdll:crt1%O%s}} %{pg:gcrt1%O%s}"
diff --git a/contrib/gcc/config/i386/cygming.h b/contrib/gcc/config/i386/cygming.h
new file mode 100644
index 0000000..f67e048
--- /dev/null
+++ b/contrib/gcc/config/i386/cygming.h
@@ -0,0 +1,391 @@
+/* Operating system specific defines to be used when targeting GCC for
+ hosting on Windows32, using a Unix style C library and tools.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#define TARGET_EXECUTABLE_SUFFIX ".exe"
+
+#define TARGET_IS_PE_COFF 1
+
+#include <stdio.h>
+
+/* Masks for subtarget switches used by other files. */
+#define MASK_NOP_FUN_DLLIMPORT 0x08000000 /* Ignore dllimport for functions */
+
+/* Used in winnt.c. */
+#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT)
+
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+{ "cygwin", 0, N_("Use the Cygwin interface") }, \
+{ "no-cygwin", 0, N_("Use the Mingw32 interface") }, \
+{ "windows", 0, N_("Create GUI application") }, \
+{ "no-win32", 0, N_("Don't set Windows defines") }, \
+{ "win32", 0, N_("Set Windows defines") }, \
+{ "console", 0, N_("Create console application") },\
+{ "dll", 0, N_("Generate code for a DLL") }, \
+{ "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, \
+ N_("Ignore dllimport for functions") }, \
+{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" }, \
+{ "threads", 0, N_("Use Mingw-specific thread support") },
+
+#define MAYBE_UWIN_CPP_BUILTINS() /* Nothing. */
+
+/* Support the __declspec keyword by turning them into attributes.
+ We currently only support: dllimport and dllexport.
+ Note that the current way we do this may result in a collision with
+ predefined attributes later on. This can be solved by using one attribute,
+ say __declspec__, and passing args to it. The problem with that approach
+ is that args are not accumulated: each new appearance would clobber any
+ existing args. */
+
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("_X86_=1"); \
+ builtin_assert ("system=winnt"); \
+ builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
+ builtin_define ("__fastcall=__attribute__((__fastcall__))"); \
+ builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
+ builtin_define ("__declspec(x)=__attribute__((x))"); \
+ if (!flag_iso) \
+ { \
+ builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
+ builtin_define ("_fastcall=__attribute__((__fastcall__))"); \
+ builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
+ } \
+ MAYBE_UWIN_CPP_BUILTINS (); \
+ EXTRA_OS_CPP_BUILTINS (); \
+ } \
+ while (0)
+
+/* Get tree.c to declare a target-specific specialization of
+ merge_decl_attributes. */
+#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+
+/* This macro defines names of additional specifications to put in the specs
+ that can be used in various specifications like CC1_SPEC. Its definition
+ is an initializer with a subgrouping for each command option.
+
+ Each subgrouping contains a string constant, that defines the
+ specification name, and a string constant that used by the GCC driver
+ program.
+
+ Do not define this macro if it does not need to do anything. */
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "mingw_include_path", DEFAULT_TARGET_MACHINE }
+
+#undef MATH_LIBRARY
+#define MATH_LIBRARY ""
+
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+#define WCHAR_TYPE_SIZE 16
+#define WCHAR_TYPE "short unsigned int"
+
+
+/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
+#define HANDLE_PRAGMA_PACK_PUSH_POP 1
+
+union tree_node;
+#define TREE union tree_node *
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_drectve
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ DRECTVE_SECTION_FUNCTION \
+ SWITCH_TO_SECTION_FUNCTION
+
+#define DRECTVE_SECTION_FUNCTION \
+void \
+drectve_section (void) \
+{ \
+ if (in_section != in_drectve) \
+ { \
+ fprintf (asm_out_file, "%s\n", "\t.section .drectve\n"); \
+ in_section = in_drectve; \
+ } \
+}
+void drectve_section (void);
+
+/* Older versions of gas don't handle 'r' as data.
+ Explicitly set data flag with 'd'. */
+#define READONLY_DATA_SECTION_ASM_OP "\t.section .rdata,\"dr\""
+
+/* Switch to SECTION (an `enum in_section').
+
+ ??? This facility should be provided by GCC proper.
+ The problem is that we want to temporarily switch sections in
+ ASM_DECLARE_OBJECT_NAME and then switch back to the original section
+ afterwards. */
+#define SWITCH_TO_SECTION_FUNCTION \
+void switch_to_section (enum in_section, tree); \
+void \
+switch_to_section (enum in_section section, tree decl) \
+{ \
+ switch (section) \
+ { \
+ case in_text: text_section (); break; \
+ case in_data: data_section (); break; \
+ case in_readonly_data: readonly_data_section (); break; \
+ case in_named: named_section (decl, NULL, 0); break; \
+ case in_drectve: drectve_section (); break; \
+ default: abort (); break; \
+ } \
+}
+
+/* Don't allow flag_pic to propagate since gas may produce invalid code
+ otherwise. */
+
+#undef SUBTARGET_OVERRIDE_OPTIONS
+#define SUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ if (flag_pic) \
+ { \
+ warning ("-f%s ignored for target (all code is position independent)",\
+ (flag_pic > 1) ? "PIC" : "pic"); \
+ flag_pic = 0; \
+ } \
+} while (0) \
+
+/* Define this macro if references to a symbol must be treated
+ differently depending on something about the variable or
+ function named by the symbol (such as what section it is in).
+
+ On i386 running Windows NT, modify the assembler name with a suffix
+ consisting of an atsign (@) followed by string of digits that represents
+ the number of bytes of arguments passed to the function, if it has the
+ attribute STDCALL.
+
+ In addition, we must mark dll symbols specially. Definitions of
+ dllexport'd objects install some info in the .drectve section.
+ References to dllimport'd objects are fetched indirectly via
+ _imp__. If both are declared, dllexport overrides. This is also
+ needed to implement one-only vtables: they go into their own
+ section and we need to set DECL_SECTION_NAME so we do that here.
+ Note that we can be called twice on the same decl. */
+
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
+#undef TARGET_STRIP_NAME_ENCODING
+#define TARGET_STRIP_NAME_ENCODING i386_pe_strip_name_encoding_full
+
+/* Output a reference to a label. */
+#undef ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF i386_pe_output_labelref
+
+/* Output a common block. */
+#undef ASM_OUTPUT_COMMON
+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
+do { \
+ if (i386_pe_dllexport_name_p (NAME)) \
+ i386_pe_record_exported_symbol (NAME, 1); \
+ if (! i386_pe_dllimport_name_p (NAME)) \
+ { \
+ fprintf ((STREAM), "\t.comm\t"); \
+ assemble_name ((STREAM), (NAME)); \
+ fprintf ((STREAM), ", %d\t%s %d\n", \
+ (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)); \
+ } \
+} while (0)
+
+/* Output the label for an initialized variable. */
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
+do { \
+ if (i386_pe_dllexport_name_p (NAME)) \
+ i386_pe_record_exported_symbol (NAME, 1); \
+ ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
+} while (0)
+
+
+/* Emit code to check the stack when allocating more that 4000
+ bytes in one go. */
+
+#define CHECK_STACK_LIMIT 4000
+
+/* By default, target has a 80387, uses IEEE compatible arithmetic,
+ returns float values in the 387 and needs stack probes.
+ We also align doubles to 64-bits for MSVC default compatibility. */
+
+#undef TARGET_SUBTARGET_DEFAULT
+#define TARGET_SUBTARGET_DEFAULT \
+ (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE \
+ | MASK_ALIGN_DOUBLE)
+
+/* This is how to output an assembler line
+ that says to advance the location counter
+ to a multiple of 2**LOG bytes. */
+
+#undef ASM_OUTPUT_ALIGN
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
+
+/* Define this macro if in some cases global symbols from one translation
+ unit may not be bound to undefined symbols in another translation unit
+ without user intervention. For instance, under Microsoft Windows
+ symbols must be explicitly imported from shared libraries (DLLs). */
+#define MULTIPLE_SYMBOL_SPACES
+
+extern void i386_pe_unique_section (TREE, int);
+#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
+
+#define SUPPORTS_ONE_ONLY 1
+
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION i386_pe_asm_named_section
+
+/* Select attributes for named sections. */
+#define TARGET_SECTION_TYPE_FLAGS i386_pe_section_type_flags
+
+/* Write the extra assembler code needed to declare a function
+ properly. If we are generating SDB debugging information, this
+ will happen automatically, so we only need to handle other cases. */
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ if (i386_pe_dllexport_name_p (NAME)) \
+ i386_pe_record_exported_symbol (NAME, 0); \
+ if (write_symbols != SDB_DEBUG) \
+ i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ } \
+ while (0)
+
+/* Add an external function to the list of functions to be declared at
+ the end of the file. */
+#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
+ do \
+ { \
+ if (TREE_CODE (DECL) == FUNCTION_DECL) \
+ i386_pe_record_external_function (NAME); \
+ } \
+ while (0)
+
+/* Declare the type properly for any external libcall. */
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+ i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
+
+/* This says out to put a global symbol in the BSS section. */
+#undef ASM_OUTPUT_ALIGNED_BSS
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
+
+/* Output function declarations at the end of the file. */
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END i386_pe_file_end
+
+#undef ASM_COMMENT_START
+#define ASM_COMMENT_START " #"
+
+/* DWARF2 Unwinding doesn't work with exception handling yet. To make
+ it work, we need to build a libgcc_s.dll, and dcrt0.o should be
+ changed to call __register_frame_info/__deregister_frame_info. */
+#define DWARF2_UNWIND_INFO 0
+
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+#undef PROFILE_HOOK
+#define PROFILE_HOOK(LABEL) \
+ if (MAIN_NAME_P (DECL_NAME (current_function_decl))) \
+ { \
+ emit_call_insn (gen_rtx (CALL, VOIDmode, \
+ gen_rtx_MEM (FUNCTION_MODE, \
+ gen_rtx_SYMBOL_REF (Pmode, "_monstartup")), \
+ const0_rtx)); \
+ }
+
+/* Java Native Interface (JNI) methods on Win32 are invoked using the
+ stdcall calling convention. */
+#undef MODIFY_JNI_METHOD_CALL
+#define MODIFY_JNI_METHOD_CALL(MDECL) \
+ build_type_attribute_variant ((MDECL), \
+ build_tree_list (get_identifier ("stdcall"), \
+ NULL))
+
+/* External function declarations. */
+
+extern void i386_pe_record_external_function (const char *);
+extern void i386_pe_declare_function_type (FILE *, const char *, int);
+extern void i386_pe_record_exported_symbol (const char *, int);
+extern void i386_pe_file_end (void);
+extern int i386_pe_dllexport_name_p (const char *);
+extern int i386_pe_dllimport_name_p (const char *);
+
+/* For Win32 ABI compatibility */
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* MSVC returns aggregate types of up to 8 bytes via registers.
+ See i386.c:ix86_return_in_memory. */
+#undef MS_AGGREGATE_RETURN
+#define MS_AGGREGATE_RETURN 1
+
+/* No data type wants to be aligned rounder than this. */
+#undef BIGGEST_ALIGNMENT
+#define BIGGEST_ALIGNMENT 128
+
+/* Native complier aligns internal doubles in structures on dword boundaries. */
+#undef BIGGEST_FIELD_ALIGNMENT
+#define BIGGEST_FIELD_ALIGNMENT 64
+
+/* A bit-field declared as `int' forces `int' alignment for the struct. */
+#undef PCC_BITFIELD_TYPE_MATTERS
+#define PCC_BITFIELD_TYPE_MATTERS 1
+#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
+
+/* Enable alias attribute support. */
+#ifndef SET_ASM_OP
+#define SET_ASM_OP "\t.set\t"
+#endif
+/* This implements the `alias' attribute, keeping any stdcall or
+ fastcall decoration. */
+#undef ASM_OUTPUT_DEF_FROM_DECLS
+#define ASM_OUTPUT_DEF_FROM_DECLS(STREAM, DECL, TARGET) \
+ do \
+ { \
+ const char *alias; \
+ rtx rtlname = XEXP (DECL_RTL (DECL), 0); \
+ if (GET_CODE (rtlname) == SYMBOL_REF) \
+ alias = XSTR (rtlname, 0); \
+ else \
+ abort (); \
+ if (TREE_CODE (DECL) == FUNCTION_DECL) \
+ i386_pe_declare_function_type (STREAM, alias, \
+ TREE_PUBLIC (DECL)); \
+ ASM_OUTPUT_DEF (STREAM, alias, IDENTIFIER_POINTER (TARGET)); \
+ } while (0)
+
+#undef TREE
+
+#ifndef BUFSIZ
+# undef FILE
+#endif
diff --git a/contrib/gcc/config/i386/cygwin.asm b/contrib/gcc/config/i386/cygwin.asm
index a27af31..c8378fa 100644
--- a/contrib/gcc/config/i386/cygwin.asm
+++ b/contrib/gcc/config/i386/cygwin.asm
@@ -1,7 +1,45 @@
-/* stuff needed for libgcc on win32. */
+/* stuff needed for libgcc on win32.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2003 Free Software Foundation, Inc.
+ * Written By Steve Chamberlain
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * In addition to the permissions in the GNU General Public License, the
+ * Free Software Foundation gives you unlimited permission to link the
+ * compiled version of this file with other programs, and to distribute
+ * those programs without any restriction coming from the use of this
+ * file. (The General Public License restrictions do apply in other
+ * respects; for example, they cover modification of the file, and
+ * distribution when not linked into another program.)
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * As a special exception, if you link this library with files
+ * compiled with GCC to produce an executable, this does not cause
+ * the resulting executable to be covered by the GNU General Public License.
+ * This exception does not however invalidate any other reasons why
+ * the executable file might be covered by the GNU General Public License.
+ */
#ifdef L_chkstk
+/* Function prologue calls _alloca to probe the stack when allocating more
+ than CHECK_STACK_LIMIT bytes in one go. Touching the stack at 4K
+ increments is necessary to ensure that the guard pages used
+ by the OS virtual memory manger are allocated in correct sequence. */
+
.global ___chkstk
.global __alloca
___chkstk:
@@ -27,6 +65,4 @@ done: subl %eax,%ecx
movl (%eax),%ecx /* recover saved temp */
movl 4(%eax),%eax /* get return address */
jmp *%eax
-
-
#endif
diff --git a/contrib/gcc/config/i386/cygwin.h b/contrib/gcc/config/i386/cygwin.h
index 03e372e..def39f4 100644
--- a/contrib/gcc/config/i386/cygwin.h
+++ b/contrib/gcc/config/i386/cygwin.h
@@ -3,153 +3,52 @@
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define DBX_DEBUGGING_INFO 1
-#define SDB_DEBUGGING_INFO 1
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-#define TARGET_VERSION fprintf (stderr, " (x86 Cygwin)");
-#define TARGET_EXECUTABLE_SUFFIX ".exe"
-
-#include <stdio.h>
-#include "i386/i386.h"
-#include "i386/unix.h"
-#include "i386/bsd.h"
-#include "i386/gas.h"
-#include "dbxcoff.h"
-
-/* Masks for subtarget switches used by other files. */
-#define MASK_NOP_FUN_DLLIMPORT 0x08000000 /* Ignore dllimport for functions */
-
-/* Used in winnt.c. */
-#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT)
-
-#undef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES \
-{ "cygwin", 0, N_("Use the Cygwin interface") }, \
-{ "no-cygwin", 0, N_("Use the Mingw32 interface") }, \
-{ "windows", 0, N_("Create GUI application") }, \
-{ "no-win32", 0, N_("Don't set Windows defines") }, \
-{ "win32", 0, N_("Set Windows defines") }, \
-{ "console", 0, N_("Create console application") },\
-{ "dll", 0, N_("Generate code for a DLL") }, \
-{ "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, \
- N_("Ignore dllimport for functions") }, \
-{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" }, \
-{ "threads", 0, N_("Use Mingw-specific thread support") },
-
-#define MAYBE_UWIN_CPP_BUILTINS() /* Nothing. */
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("_X86_=1"); \
- builtin_assert ("system=winnt"); \
- builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
- builtin_define ("__declspec(x)=__attribute__((x))"); \
- if (!flag_iso) \
- { \
- builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
- } \
- MAYBE_UWIN_CPP_BUILTINS (); \
- } \
- while (0)
-
-#ifdef CROSS_COMPILE
-#define CYGWIN_INCLUDES "%{!nostdinc:-idirafter " CYGWIN_CROSS_DIR "/include}"
-#define W32API_INC "%{!nostdinc:-idirafter " CYGWIN_CROSS_DIR "/include/w32api}"
-#define W32API_LIB "-L" CYGWIN_CROSS_DIR "/lib/w32api/"
-#define CYGWIN_LIB CYGWIN_CROSS_DIR "/lib"
-#define MINGW_LIBS "-L" CYGWIN_CROSS_DIR "/lib/mingw"
-#define MINGW_INCLUDES "%{!nostdinc:-isystem " CYGWIN_CROSS_DIR "/include/mingw/g++-3 "\
- "-isystem " CYGWIN_CROSS_DIR "/include/mingw/g++ "\
- "-idirafter " CYGWIN_CROSS_DIR "/include/mingw}"
-#else
-#define CYGWIN_INCLUDES "%{!nostdinc:-isystem /usr/local/include "\
- "-idirafter " CYGWIN_CROSS_DIR "/include "\
- "-idirafter /usr/include}"
-#define W32API_INC "%{!nostdinc:"\
- "-idirafter " CYGWIN_CROSS_DIR "/include/w32api "\
- "-idirafter /usr/include/w32api}"
-#define W32API_LIB "-L" CYGWIN_CROSS_DIR "/lib/w32api/ -L/usr/lib/w32api/"
-#define CYGWIN_LIB "/usr/lib"
-#define MINGW_LIBS "-L/usr/local/lib/mingw -L/usr/lib/mingw"
-#define MINGW_INCLUDES "%{!nostdinc:-isystem /usr/include/mingw/g++-3 "\
- "-isystem /usr/include/mingw/g++ "\
- "-isystem /usr/local/include/mingw "\
- "-idirafter " CYGWIN_CROSS_DIR "/include/mingw "\
- "-idirafter /usr/include/mingw}"
-#endif
-
-/* Get tree.c to declare a target-specific specialization of
- merge_decl_attributes. */
-#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#define TARGET_VERSION fprintf (stderr, " (x86 Cygwin)");
-/* Support the __declspec keyword by turning them into attributes.
- We currently only support: dllimport and dllexport.
- Note that the current way we do this may result in a collision with
- predefined attributes later on. This can be solved by using one attribute,
- say __declspec__, and passing args to it. The problem with that approach
- is that args are not accumulated: each new appearance would clobber any
- existing args. */
+#define EXTRA_OS_CPP_BUILTINS() /* Nothing. */
#undef CPP_SPEC
-#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} \
+#define CPP_SPEC "%(cpp_cpu) %{posix:-D_POSIX_SOURCE} \
%{mno-win32:%{mno-cygwin: %emno-cygwin and mno-win32 are not compatible}} \
- %{mno-cygwin:-D__MSVCRT__ -D__MINGW32__ %{mthreads:-D_MT} "\
- MINGW_INCLUDES "} \
- %{!mno-cygwin:-D__CYGWIN32__ -D__CYGWIN__ %{!ansi:-Dunix} -D__unix__ -D__unix "\
- CYGWIN_INCLUDES "}\
+ %{mno-cygwin:-D__MSVCRT__ -D__MINGW32__ %{!ansi:%{mthreads:-D_MT}}}\
+ %{!mno-cygwin:-D__CYGWIN32__ -D__CYGWIN__ %{!ansi:-Dunix} -D__unix__ -D__unix }\
%{mwin32|mno-cygwin:-DWIN32 -D_WIN32 -D__WIN32 -D__WIN32__ %{!ansi:-DWINNT}}\
- %{!mno-win32:" W32API_INC "}\
+ %{!nostdinc:%{!mno-win32|mno-cygwin:-idirafter ../include/w32api%s -idirafter ../../include/w32api%s}}\
"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "\
- %{shared|mdll: %{mno-cygwin:" MINGW_LIBS " dllcrt2%O%s}}\
- %{!shared: %{!mdll: %{!mno-cygwin:crt0%O%s} %{mno-cygwin:" MINGW_LIBS " crt2%O%s}\
+ %{shared|mdll: %{mno-cygwin:dllcrt2%O%s}}\
+ %{!shared: %{!mdll: %{!mno-cygwin:crt0%O%s} %{mno-cygwin:crt2%O%s}\
%{pg:gcrt0%O%s}}}\
"
/* Normally, -lgcc is not needed since everything in it is in the DLL, but we
want to allow things to be added to it when installing new versions of
GCC without making a new CYGWIN.DLL, so we leave it. Profiling is handled
- by calling the init function from the prologue. */
+ by calling the init function from main. */
#undef LIBGCC_SPEC
-#define LIBGCC_SPEC "%{mno-cygwin: %{mthreads:-lmingwthrd} -lmingw32} \
- -lgcc %{mno-cygwin:-lmoldname -lmingwex -lmsvcrt}"
-
-/* This macro defines names of additional specifications to put in the specs
- that can be used in various specifications like CC1_SPEC. Its definition
- is an initializer with a subgrouping for each command option.
-
- Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
- program.
-
- Do not define this macro if it does not need to do anything. */
-
-#undef SUBTARGET_EXTRA_SPECS
-#define SUBTARGET_EXTRA_SPECS \
- { "mingw_include_path", DEFAULT_TARGET_MACHINE }
+#define LIBGCC_SPEC \
+ "%{mno-cygwin: %{mthreads:-lmingwthrd} -lmingw32} -lgcc \
+ %{mno-cygwin:-lmoldname -lmingwex -lmsvcrt}"
/* We have to dynamic link to get to the system DLLs. All of libc, libm and
the Unix stuff is in cygwin.dll. The import library is called
@@ -165,7 +64,7 @@ Boston, MA 02111-1307, USA. */
%{mwindows:-lgdi32 -lcomdlg32} \
-luser32 -lkernel32 -ladvapi32 -lshell32"
-#define LINK_SPEC W32API_LIB "\
+#define LINK_SPEC "\
%{mwindows:--subsystem windows} \
%{mconsole:--subsystem console} \
%{shared: %{mdll: %eshared and mdll are not compatible}} \
@@ -174,293 +73,158 @@ Boston, MA 02111-1307, USA. */
%{shared|mdll: -e \
%{mno-cygwin:_DllMainCRTStartup@12} \
%{!mno-cygwin:__cygwin_dll_entry@12}}\
- --dll-search-prefix=cyg"
-
-#undef MATH_LIBRARY
-#define MATH_LIBRARY ""
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-#define WCHAR_TYPE_SIZE 16
-#define WCHAR_TYPE "short unsigned int"
-
-
-/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
-#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-
-union tree_node;
-#define TREE union tree_node *
-
-#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_drectve
-
-#undef EXTRA_SECTION_FUNCTIONS
-#define EXTRA_SECTION_FUNCTIONS \
- DRECTVE_SECTION_FUNCTION \
- SWITCH_TO_SECTION_FUNCTION
-
-#define DRECTVE_SECTION_FUNCTION \
-void \
-drectve_section () \
-{ \
- if (in_section != in_drectve) \
- { \
- fprintf (asm_out_file, "%s\n", "\t.section .drectve\n"); \
- in_section = in_drectve; \
- } \
-}
-void drectve_section PARAMS ((void));
-
-/* Switch to SECTION (an `enum in_section').
-
- ??? This facility should be provided by GCC proper.
- The problem is that we want to temporarily switch sections in
- ASM_DECLARE_OBJECT_NAME and then switch back to the original section
- afterwards. */
-#define SWITCH_TO_SECTION_FUNCTION \
-void switch_to_section PARAMS ((enum in_section, tree)); \
-void \
-switch_to_section (section, decl) \
- enum in_section section; \
- tree decl; \
-{ \
- switch (section) \
- { \
- case in_text: text_section (); break; \
- case in_data: data_section (); break; \
- case in_named: named_section (decl, NULL, 0); break; \
- case in_drectve: drectve_section (); break; \
- default: abort (); break; \
- } \
-}
-
-/* Don't allow flag_pic to propagate since gas may produce invalid code
- otherwise. */
-
-#undef SUBTARGET_OVERRIDE_OPTIONS
-#define SUBTARGET_OVERRIDE_OPTIONS \
-do { \
- if (flag_pic) \
- { \
- warning ("-f%s ignored for target (all code is position independent)",\
- (flag_pic > 1) ? "PIC" : "pic"); \
- flag_pic = 0; \
- } \
-} while (0) \
-
-/* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or
- function named by the symbol (such as what section it is in).
-
- On i386 running Windows NT, modify the assembler name with a suffix
- consisting of an atsign (@) followed by string of digits that represents
- the number of bytes of arguments passed to the function, if it has the
- attribute STDCALL.
-
- In addition, we must mark dll symbols specially. Definitions of
- dllexport'd objects install some info in the .drectve section.
- References to dllimport'd objects are fetched indirectly via
- _imp__. If both are declared, dllexport overrides. This is also
- needed to implement one-only vtables: they go into their own
- section and we need to set DECL_SECTION_NAME so we do that here.
- Note that we can be called twice on the same decl. */
-
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING i386_pe_strip_name_encoding_full
-
-/* Output a reference to a label. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
- fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, \
- i386_pe_strip_name_encoding (NAME)) \
-
-/* Output a common block. */
-#undef ASM_OUTPUT_COMMON
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
-do { \
- if (i386_pe_dllexport_name_p (NAME)) \
- i386_pe_record_exported_symbol (NAME, 1); \
- if (! i386_pe_dllimport_name_p (NAME)) \
- { \
- fprintf ((STREAM), "\t.comm\t"); \
- assemble_name ((STREAM), (NAME)); \
- fprintf ((STREAM), ", %d\t%s %d\n", \
- (ROUNDED), ASM_COMMENT_START, (SIZE)); \
- } \
-} while (0)
-
-/* Output the label for an initialized variable. */
-#undef ASM_DECLARE_OBJECT_NAME
-#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
-do { \
- if (i386_pe_dllexport_name_p (NAME)) \
- i386_pe_record_exported_symbol (NAME, 1); \
- ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
-} while (0)
-
-
-/* Emit code to check the stack when allocating more that 4000
- bytes in one go. */
-
-#define CHECK_STACK_LIMIT 4000
-
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
- returns float values in the 387 and needs stack probes.
- We also align doubles to 64-bits for MSVC default compatibility. */
-
-#undef TARGET_SUBTARGET_DEFAULT
-#define TARGET_SUBTARGET_DEFAULT \
- (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE \
- | MASK_ALIGN_DOUBLE)
-
-/* This is how to output an assembler line
- that says to advance the location counter
- to a multiple of 2**LOG bytes. */
-
-#undef ASM_OUTPUT_ALIGN
-#define ASM_OUTPUT_ALIGN(FILE,LOG) \
- if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
-
-/* Define this macro if in some cases global symbols from one translation
- unit may not be bound to undefined symbols in another translation unit
- without user intervention. For instance, under Microsoft Windows
- symbols must be explicitly imported from shared libraries (DLLs). */
-#define MULTIPLE_SYMBOL_SPACES
-
-extern void i386_pe_unique_section PARAMS ((TREE, int));
-#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
-
-#define SUPPORTS_ONE_ONLY 1
-
-/* Switch into a generic section. */
-#define TARGET_ASM_NAMED_SECTION i386_pe_asm_named_section
-
-/* Select attributes for named sections. */
-#define TARGET_SECTION_TYPE_FLAGS i386_pe_section_type_flags
-
-/* Write the extra assembler code needed to declare a function
- properly. If we are generating SDB debugging information, this
- will happen automatically, so we only need to handle other cases. */
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do \
- { \
- if (i386_pe_dllexport_name_p (NAME)) \
- i386_pe_record_exported_symbol (NAME, 0); \
- if (write_symbols != SDB_DEBUG) \
- i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
- ASM_OUTPUT_LABEL (FILE, NAME); \
- } \
- while (0)
-
-/* Add an external function to the list of functions to be declared at
- the end of the file. */
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
- do \
- { \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- i386_pe_record_external_function (NAME); \
- } \
- while (0)
-
-/* Declare the type properly for any external libcall. */
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
- i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
-
-/* This says out to put a global symbol in the BSS section. */
-#undef ASM_OUTPUT_ALIGNED_BSS
-#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
- asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-
-/* Output function declarations at the end of the file. */
-#undef ASM_FILE_END
-#define ASM_FILE_END(FILE) \
- i386_pe_asm_file_end (FILE)
-
-#undef ASM_COMMENT_START
-#define ASM_COMMENT_START " #"
-
-/* DWARF2 Unwinding doesn't work with exception handling yet. To make
- it work, we need to build a libgcc_s.dll, and dcrt0.o should be
- changed to call __register_frame_info/__deregister_frame_info. */
-#define DWARF2_UNWIND_INFO 0
-
-/* Don't assume anything about the header files. */
-#define NO_IMPLICIT_EXTERN_C
-
-#undef PROFILE_HOOK
-#define PROFILE_HOOK(LABEL) \
- if (MAIN_NAME_P (DECL_NAME (current_function_decl))) \
- { \
- emit_call_insn (gen_rtx (CALL, VOIDmode, \
- gen_rtx_MEM (FUNCTION_MODE, \
- gen_rtx_SYMBOL_REF (Pmode, "_monstartup")), \
- const0_rtx)); \
- }
-
-/* Java Native Interface (JNI) methods on Win32 are invoked using the
- stdcall calling convention. */
-#undef MODIFY_JNI_METHOD_CALL
-#define MODIFY_JNI_METHOD_CALL(MDECL) \
- build_type_attribute_variant ((MDECL), \
- build_tree_list (get_identifier ("stdcall"), \
- NULL))
-
-
-/* External function declarations. */
-
-extern void i386_pe_record_external_function PARAMS ((const char *));
-extern void i386_pe_declare_function_type PARAMS ((FILE *, const char *, int));
-extern void i386_pe_record_exported_symbol PARAMS ((const char *, int));
-extern void i386_pe_asm_file_end PARAMS ((FILE *));
-extern int i386_pe_dllexport_name_p PARAMS ((const char *));
-extern int i386_pe_dllimport_name_p PARAMS ((const char *));
-
-/* For Win32 ABI compatibility */
-#undef DEFAULT_PCC_STRUCT_RETURN
-#define DEFAULT_PCC_STRUCT_RETURN 0
-
-/* No data type wants to be aligned rounder than this. */
-#undef BIGGEST_ALIGNMENT
-#define BIGGEST_ALIGNMENT 128
-
-/* Native complier aligns internal doubles in structures on dword boundaries. */
-#undef BIGGEST_FIELD_ALIGNMENT
-#define BIGGEST_FIELD_ALIGNMENT 64
-
-/* A bit-field declared as `int' forces `int' alignment for the struct. */
-#undef PCC_BITFIELD_TYPE_MATTERS
-#define PCC_BITFIELD_TYPE_MATTERS 1
-#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
-
-
-/* Enable alias attribute support. */
-#ifndef SET_ASM_OP
-#define SET_ASM_OP "\t.set\t"
+ %{!mno-cygwin:--dll-search-prefix=cyg}"
+
+/* Allocate space for all of the machine-spec-specific stuff.
+ Allocate enough space for cygwin -> mingw32 munging plus
+ possible addition of "/mingw". */
+
+#ifndef CYGWIN_MINGW_SUBDIR
+#define CYGWIN_MINGW_SUBDIR "/mingw"
+#endif
+#define CYGWIN_MINGW_SUBDIR_LEN (sizeof (CYGWIN_MINGW_SUBDIR) - 1)
+
+#ifdef GPLUSPLUS_INCLUDE_DIR
+char cygwin_gplusplus_include_dir[sizeof (GPLUSPLUS_INCLUDE_DIR) + 1
+ + (CYGWIN_MINGW_SUBDIR_LEN)]
+ = GPLUSPLUS_INCLUDE_DIR;
+#undef GPLUSPLUS_INCLUDE_DIR
+#define GPLUSPLUS_INCLUDE_DIR ((const char *) cygwin_gplusplus_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
#endif
-/* Override GCC's relative pathname lookup (ie., relocatability) unless
- otherwise told by other subtargets. */
-#ifndef WIN32_NO_ABSOLUTE_INST_DIRS
-#undef MD_STARTFILE_PREFIX
-#define MD_STARTFILE_PREFIX "/usr/lib/"
+#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
+char cygwin_gplusplus_tool_include_dir[sizeof (GPLUSPLUS_TOOL_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = GPLUSPLUS_TOOL_INCLUDE_DIR;
+#undef GPLUSPLUS_TOOL_INCLUDE_DIR
+#define GPLUSPLUS_TOOL_INCLUDE_DIR ((const char *) cygwin_gplusplus_tool_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
-#undef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX "/usr/lib/mingw/"
+#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+char cygwin_gplusplus_backward_include_dir[sizeof (GPLUSPLUS_BACKWARD_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = GPLUSPLUS_BACKWARD_INCLUDE_DIR;
+#undef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+#define GPLUSPLUS_BACKWARD_INCLUDE_DIR ((const char *) cygwin_gplusplus_backward_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
-#ifndef CROSS_COMPILE
+#ifdef LOCAL_INCLUDE_DIR
+char cygwin_local_include_dir[sizeof (LOCAL_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = LOCAL_INCLUDE_DIR;
#undef LOCAL_INCLUDE_DIR
+#define LOCAL_INCLUDE_DIR ((const char *) cygwin_local_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
+
+#ifdef CROSS_INCLUDE_DIR
+char cygwin_cross_include_dir[sizeof (CROSS_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = CROSS_INCLUDE_DIR;
+#undef CROSS_INCLUDE_DIR
+#define CROSS_INCLUDE_DIR ((const char *) cygwin_cross_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
+
+#ifdef TOOL_INCLUDE_DIR
+char cygwin_tool_include_dir[sizeof (TOOL_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = TOOL_INCLUDE_DIR;
#undef TOOL_INCLUDE_DIR
-#undef SYSTEM_INCLUDE_DIR
+#define TOOL_INCLUDE_DIR ((const char *) cygwin_tool_include_dir)
+
+#ifndef CROSS_COMPILE
+#undef STANDARD_INCLUDE_DIR
+#define STANDARD_INCLUDE_DIR "/usr/include"
+char cygwin_standard_include_dir[sizeof (STANDARD_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = STANDARD_INCLUDE_DIR;
#undef STANDARD_INCLUDE_DIR
-#define STANDARD_INCLUDE_DIR 0
-#endif /* not CROSS_COMPILE */
-#endif /* not WIN32_NO_ABSOLUTE_INST_DIRS */
+#define STANDARD_INCLUDE_DIR ((const char *) cygwin_standard_include_dir)
+#endif
+
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
+
+#ifndef GEN_CVT_ARRAY
+extern char *cvt_to_mingw[];
+#else
+char *cvt_to_mingw[] =
+ {
+#ifdef GPLUSPLUS_INCLUDE_DIR
+ cygwin_gplusplus_include_dir,
+#endif
+
+#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
+ cygwin_gplusplus_tool_include_dir,
+#endif
+
+#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+ cygwin_gplusplus_backward_include_dir,
+#endif
-#undef TREE
+#ifdef LOCAL_INCLUDE_DIR
+ cygwin_local_include_dir,
+#endif
+
+#ifdef CROSS_INCLUDE_DIR
+ cygwin_cross_include_dir,
+#endif
-#ifndef BUFSIZ
-# undef FILE
+#ifdef TOOL_INCLUDE_DIR
+ cygwin_tool_include_dir,
+#endif
+
+#ifdef STANDARD_INCLUDE_DIR
+ cygwin_standard_include_dir,
+#endif
+
+ NULL
+ };
+#undef GEN_CVT_ARRAY
+#endif /*GEN_CVT_ARRAY*/
+
+void mingw_scan (int, const char * const *, char **);
+#if 1
+#define GCC_DRIVER_HOST_INITIALIZATION \
+do \
+{ \
+ mingw_scan(argc, argv, (char **) &spec_machine); \
+ } \
+while (0)
+#else
+#define GCC_DRIVER_HOST_INITIALIZATION \
+do \
+{ \
+ char *cprefix = concat (tooldir_base_prefix, spec_machine, \
+ dir_separator_str, NULL); \
+ if (!IS_ABSOLUTE_PATH (cprefix)) \
+ cprefix = concat (standard_exec_prefix, spec_machine, dir_separator_str, \
+ spec_version, dir_separator_str, tooldir_prefix, NULL); \
+ add_prefix (&exec_prefixes,\
+ concat (cprefix, "../../../../", spec_machine, "/bin/", NULL), \
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); \
+ add_prefix (&exec_prefixes, cprefix, \
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); \
+ add_prefix (&startfile_prefixes,\
+ concat (standard_startfile_prefix, "w32api", NULL),\
+ "GCC", PREFIX_PRIORITY_LAST, 0, NULL);\
+ mingw_scan(argc, argv, &spec_machine); \
+ } \
+while (0)
#endif
diff --git a/contrib/gcc/config/i386/cygwin1.c b/contrib/gcc/config/i386/cygwin1.c
new file mode 100644
index 0000000..2cab96c
--- /dev/null
+++ b/contrib/gcc/config/i386/cygwin1.c
@@ -0,0 +1,54 @@
+/* Helper routines for cygwin-specific command-line parsing.
+ Contributed by Christopher Faylor (cgf@redhat.com)
+ Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include <string.h>
+
+void
+mingw_scan (int argc ATTRIBUTE_UNUSED,
+ const char *const *argv,
+ char **spec_machine)
+{
+ putenv ("GCC_CYGWIN_MINGW=0");
+
+ while (*++argv)
+ if (strcmp (*argv, "-mno-win32") == 0)
+ putenv ("GCC_CYGWIN_WIN32=0");
+ else if (strcmp (*argv, "-mwin32") == 0)
+ putenv ("GCC_CYGWIN_WIN32=1");
+ else if (strcmp (*argv, "-mno-cygwin") == 0)
+ {
+ char *p = strstr (*spec_machine, "-cygwin");
+ if (p)
+ {
+ int len = p - *spec_machine;
+ char *s = xmalloc (strlen (*spec_machine) + 3);
+ memcpy (s, *spec_machine, len);
+ strcpy (s + len, "-mingw32");
+ *spec_machine = s;
+ }
+ putenv ("GCC_CYGWIN_MINGW=1");
+ }
+ return;
+}
diff --git a/contrib/gcc/config/i386/cygwin2.c b/contrib/gcc/config/i386/cygwin2.c
new file mode 100644
index 0000000..2947f5a
--- /dev/null
+++ b/contrib/gcc/config/i386/cygwin2.c
@@ -0,0 +1,67 @@
+/* Helper routines for cygwin-specific command-line parsing.
+ Contributed by Christopher Faylor (cgf@redhat.com)
+ Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+#include "safe-ctype.h"
+#include <string.h>
+
+/*
+static void remove_w32api (void);
+*/
+static void add_mingw (void);
+static void set_mingw (void) __attribute__ ((constructor));
+
+static void
+add_mingw (void)
+{
+ char **av;
+ char *p;
+ for (av = cvt_to_mingw; *av; av++)
+ {
+ int sawcygwin = 0;
+ while ((p = strstr (*av, "-cygwin")))
+ {
+ char *over = p + sizeof ("-cygwin") - 1;
+ memmove (over + 1, over, strlen (over));
+ memcpy (p, "-mingw32", sizeof("-mingw32") - 1);
+ p = ++over;
+ while (ISALNUM (*p))
+ p++;
+ strcpy (over, p);
+ sawcygwin = 1;
+ }
+ if (!sawcygwin && !strstr (*av, "mingw"))
+ strcat (*av, CYGWIN_MINGW_SUBDIR);
+ }
+}
+
+
+static void
+set_mingw (void)
+{
+ char *env = getenv ("GCC_CYGWIN_MINGW");
+ if (env && *env == '1')
+ add_mingw ();
+}
diff --git a/contrib/gcc/config/i386/darwin.h b/contrib/gcc/config/i386/darwin.h
index 55c29fd..fd501bf 100644
--- a/contrib/gcc/config/i386/darwin.h
+++ b/contrib/gcc/config/i386/darwin.h
@@ -2,20 +2,20 @@
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,6 +41,16 @@ Boston, MA 02111-1307, USA. */
#undef CC1_SPEC
#define CC1_SPEC "%{!static:-fPIC}"
+#define ASM_SPEC "-arch i386 \
+ %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
+ %{!Zforce_cpusubtype_ALL:%{mmmx:-force_cpusubtype_ALL}\
+ %{msse:-force_cpusubtype_ALL}\
+ %{msse2:-force_cpusubtype_ALL}}"
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "darwin_arch", "i386" },
+
/* The Darwin assembler mostly follows AT&T syntax. */
#undef ASSEMBLER_DIALECT
#define ASSEMBLER_DIALECT ASM_ATT
@@ -68,6 +78,11 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEEP_BRANCH_PREDICTION
#define TARGET_DEEP_BRANCH_PREDICTION 0
+/* For now, disable dynamic-no-pic. We'll need to go through i386.c
+ with a fine-tooth comb looking for refs to flag_pic! */
+#define MASK_MACHO_DYNAMIC_NO_PIC 0
+#define TARGET_DYNAMIC_NO_PIC (target_flags & MASK_MACHO_DYNAMIC_NO_PIC)
+
/* Define the syntax of pseudo-ops, labels and comments. */
#define LPREFIX "L"
@@ -96,7 +111,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ",%lu\n", (unsigned long)(ROUNDED)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -104,7 +119,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
( fputs (".lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (ROUNDED)))
/* Darwin profiling -- call mcount. */
#undef FUNCTION_PROFILER
diff --git a/contrib/gcc/config/i386/djgpp.h b/contrib/gcc/config/i386/djgpp.h
index 6780780..cee9480 100644
--- a/contrib/gcc/config/i386/djgpp.h
+++ b/contrib/gcc/config/i386/djgpp.h
@@ -1,21 +1,21 @@
/* Configuration for an i386 running MS-DOS with DJGPP.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -30,10 +30,6 @@ Boston, MA 02111-1307, USA. */
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-#include "i386/unix.h"
-#include "i386/bsd.h"
-#include "i386/gas.h"
-
/* If defined, a C expression whose value is a string containing the
assembler operation to identify the following data as
uninitialized global data. If not defined, and neither
@@ -61,9 +57,9 @@ Boston, MA 02111-1307, USA. */
#undef TEXT_SECTION_ASM_OP
#define TEXT_SECTION_ASM_OP "\t.section .text"
-/* Define standard DJGPP installation paths. */
+/* Define standard DJGPP installation paths. */
/* We override default /usr or /usr/local part with /dev/env/DJDIR which */
-/* points to actual DJGPP instalation directory. */
+/* points to actual DJGPP installation directory. */
/* Standard include directory */
#undef STANDARD_INCLUDE_DIR
@@ -130,17 +126,6 @@ Boston, MA 02111-1307, USA. */
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_coff_asm_named_section
-/* Output at beginning of assembler file. */
-/* The .file command should always begin the output. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- output_file_directive (FILE, main_input_filename); \
- } while (0)
-
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
diff --git a/contrib/gcc/config/i386/emmintrin.h b/contrib/gcc/config/i386/emmintrin.h
index 7007fc5..abe450a 100644
--- a/contrib/gcc/config/i386/emmintrin.h
+++ b/contrib/gcc/config/i386/emmintrin.h
@@ -1,19 +1,19 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -115,15 +115,7 @@ _mm_set_pd1 (double __F)
static __inline __m128d
_mm_set_pd (double __Z, double __Y)
{
- union {
- double __a[2];
- __m128d __v;
- } __u;
-
- __u.__a[0] = __Y;
- __u.__a[1] = __Z;
-
- return __u.__v;
+ return (__v2df) {__Y, __Z};
}
/* Create the vector [Y Z]. */
@@ -147,7 +139,7 @@ _mm_store_sd (double *__P, __m128d __A)
__builtin_ia32_storesd (__P, (__v2df)__A);
}
-/* Store the lower DPFP value acrosd two words. */
+/* Store the lower DPFP value across two words. */
static __inline void
_mm_store1_pd (double *__P, __m128d __A)
{
diff --git a/contrib/gcc/config/i386/freebsd-aout.h b/contrib/gcc/config/i386/freebsd-aout.h
index 85e2703..663ed8d 100644
--- a/contrib/gcc/config/i386/freebsd-aout.h
+++ b/contrib/gcc/config/i386/freebsd-aout.h
@@ -5,20 +5,20 @@
Contributed by Poul-Henning Kamp <phk@login.dkuug.dk>
Continued development by David O'Brien <obrien@NUXI.org>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -185,6 +185,7 @@ Boston, MA 02111-1307, USA. */
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
+#undef ASM_FINISH_DECLARE_OBJECT
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
@@ -208,7 +209,8 @@ do { \
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
} while (0)
-#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+#define ASM_SPEC "%{fpic|fpie|fPIC|fPIE:-k}"
#define LINK_SPEC \
"%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
%{shared:-Bshareable} \
diff --git a/contrib/gcc/config/i386/gas.h b/contrib/gcc/config/i386/gas.h
index 075d749..78195b9 100644
--- a/contrib/gcc/config/i386/gas.h
+++ b/contrib/gcc/config/i386/gas.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 using GAS.
Copyright (C) 1988, 1993, 1994, 1996, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -121,12 +121,4 @@ Boston, MA 02111-1307, USA. */
/* Print opcodes the way that GAS expects them. */
#define GAS_MNEMONICS 1
-/* Output at beginning of assembler file. */
-/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- output_file_directive (FILE, main_input_filename); \
- } while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
diff --git a/contrib/gcc/config/i386/gnu.h b/contrib/gcc/config/i386/gnu.h
index acf2d3f..cc9994b 100644
--- a/contrib/gcc/config/i386/gnu.h
+++ b/contrib/gcc/config/i386/gnu.h
@@ -7,15 +7,7 @@
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("MACH"); \
- builtin_define_std ("unix"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__GNU__"); \
- builtin_define ("__gnu_hurd__"); \
- builtin_assert ("system=gnu"); \
- builtin_assert ("system=mach"); \
- builtin_assert ("system=posix"); \
- builtin_assert ("system=unix"); \
+ HURD_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
diff --git a/contrib/gcc/config/i386/gthr-win32.c b/contrib/gcc/config/i386/gthr-win32.c
index 5510f10..4e2b282 100644
--- a/contrib/gcc/config/i386/gthr-win32.c
+++ b/contrib/gcc/config/i386/gthr-win32.c
@@ -1,7 +1,7 @@
/* Implementation of W32-specific threads compatibility routines for
- libgcc2. */
+ libgcc2. */
-/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
Modified and moved to separate file by Danny Smith
<dannysmith@users.sourceforge.net>.
diff --git a/contrib/gcc/config/i386/i386-aout.h b/contrib/gcc/config/i386/i386-aout.h
index ca0cb25..3b89788 100644
--- a/contrib/gcc/config/i386/i386-aout.h
+++ b/contrib/gcc/config/i386/i386-aout.h
@@ -3,20 +3,20 @@
Copyright (C) 1994, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/i386-coff.h b/contrib/gcc/config/i386/i386-coff.h
index e8c5de9..85a5193 100644
--- a/contrib/gcc/config/i386/i386-coff.h
+++ b/contrib/gcc/config/i386/i386-coff.h
@@ -3,20 +3,20 @@
Copyright (C) 1994, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -60,11 +60,4 @@ Boston, MA 02111-1307, USA. */
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), ".%s%ld", (PREFIX), (long)(NUMBER))
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
-
/* end of i386-coff.h */
diff --git a/contrib/gcc/config/i386/i386-interix.h b/contrib/gcc/config/i386/i386-interix.h
index d309087..2a99ce5 100644
--- a/contrib/gcc/config/i386/i386-interix.h
+++ b/contrib/gcc/config/i386/i386-interix.h
@@ -1,5 +1,6 @@
-/* Target definitions for GNU compiler for Intel 80386 running Interix
- Parts Copyright (C) 1991, 1999, 2000, 2002 Free Software Foundation, Inc.
+/* Target definitions for GCC for Intel 80386 running Interix
+ Parts Copyright (C) 1991, 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Parts:
by Douglas B. Rupp (drupp@cs.washington.edu).
@@ -7,20 +8,20 @@
by Donn Terry (donn@softway.com).
by Mumit Khan (khan@xraylith.wisc.edu).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -35,11 +36,12 @@ Boston, MA 02111-1307, USA. */
/* By default, target has a 80387, uses IEEE compatible arithmetic,
and returns float values in the 387 and needs stack probes
- We also align doubles to 64-bits for MSVC default compatibility */
+ We also align doubles to 64-bits for MSVC default compatibility
+ We do bitfields MSVC-compatibly by default, too. */
#undef TARGET_SUBTARGET_DEFAULT
#define TARGET_SUBTARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE | \
- MASK_ALIGN_DOUBLE)
+ MASK_ALIGN_DOUBLE | MASK_MS_BITFIELD_LAYOUT)
#undef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT 2 /* 486 */
@@ -70,9 +72,9 @@ Boston, MA 02111-1307, USA. */
else \
{ \
builtin_define_std ("LANGUAGE_C"); \
- if (c_language == clk_cplusplus) \
+ if (c_dialect_cxx ()) \
builtin_define_std ("LANGUAGE_C_PLUS_PLUS"); \
- if (flag_objc) \
+ if (c_dialect_objc ()) \
builtin_define_std ("LANGUAGE_OBJECTIVE_C"); \
} \
} \
@@ -91,16 +93,8 @@ Boston, MA 02111-1307, USA. */
/* The global __fltused is necessary to cause the printf/scanf routines
for outputting/inputting floating point numbers to be loaded. Since this
is kind of hard to detect, we just do it all the time. */
-
-#ifdef ASM_FILE_START
-#undef ASM_FILE_START
-#endif
-#define ASM_FILE_START(FILE) \
- do { fprintf (FILE, "\t.file\t"); \
- output_quoted_string (FILE, dump_base_name); \
- fprintf (FILE, "\n"); \
- fprintf (FILE, ".global\t__fltused\n"); \
- } while (0)
+#undef X86_FILE_START_FLTUSED
+#define X86_FILE_START_FLTUSED 1
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
@@ -147,18 +141,18 @@ Boston, MA 02111-1307, USA. */
generated assembly code more compact (and thus faster to assemble)
as well as more readable, especially for targets like the i386
(where the only alternative is to output character sequences as
- comma separated lists of numbers). */
+ comma separated lists of numbers). */
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
do \
{ \
- register const unsigned char *_limited_str = \
+ const unsigned char *_limited_str = \
(const unsigned char *) (STR); \
- register unsigned ch; \
+ unsigned ch; \
fprintf ((FILE), "%s\"", STRING_ASM_OP); \
for (; (ch = *_limited_str); _limited_str++) \
{ \
- register int escape = ESCAPES[ch]; \
+ int escape = ESCAPES[ch]; \
switch (escape) \
{ \
case 0: \
@@ -188,13 +182,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
@@ -243,6 +237,28 @@ Boston, MA 02111-1307, USA. */
#define TARGET_NOP_FUN_DLLIMPORT 1
#define drectve_section() /* nothing */
+/* Objective-C has its own packing rules...
+ Objc tries to parallel the code in stor-layout.c at runtime
+ (see libobjc/encoding.c). This (compile-time) packing info isn't
+ available at runtime, so it's hopeless to try.
+
+ And if the user tries to set the flag for objc, give an error
+ so he has some clue. */
+
+#undef SUBTARGET_OVERRIDE_OPTIONS
+#define SUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ if (strcmp (lang_hooks.name, "GNU Objective-C") == 0) \
+ { \
+ if ((target_flags & MASK_MS_BITFIELD_LAYOUT) != 0 \
+ && (target_flags_explicit & MASK_MS_BITFIELD_LAYOUT) != 0) \
+ { \
+ error ("ms-bitfields not supported for objc"); \
+ } \
+ target_flags &= ~MASK_MS_BITFIELD_LAYOUT; \
+ } \
+} while (0)
+
#define EH_FRAME_IN_DATA_SECTION
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rdata,\"r\""
@@ -273,8 +289,6 @@ while (0)
#define HOST_PTR_AS_INT unsigned long
#define PCC_BITFIELD_TYPE_MATTERS 1
-#define PCC_BITFIELD_TYPE_TEST TYPE_NATIVE(rec)
-#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
/* The following two flags are usually "off" for i386, because some non-gnu
tools (for the i386) don't handle them. However, we don't have that
@@ -328,7 +342,7 @@ while (0)
symbols must be explicitly imported from shared libraries (DLLs). */
#define MULTIPLE_SYMBOL_SPACES
-extern void i386_pe_unique_section PARAMS ((tree, int));
+extern void i386_pe_unique_section (tree, int);
#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
#define SUPPORTS_ONE_ONLY 1
@@ -343,7 +357,7 @@ extern void i386_pe_unique_section PARAMS ((tree, int));
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* MSVC returns structs of up to 8 bytes via registers. */
+/* MSVC returns structs of up to 8 bytes via registers. */
#define DEFAULT_PCC_STRUCT_RETURN 0
diff --git a/contrib/gcc/config/i386/i386-interix3.h b/contrib/gcc/config/i386/i386-interix3.h
index aafe57f..7ade70a 100644
--- a/contrib/gcc/config/i386/i386-interix3.h
+++ b/contrib/gcc/config/i386/i386-interix3.h
@@ -1,21 +1,21 @@
-/* Target definitions for GNU compiler for Intel 80386 running Interix V3.
+/* Target definitions for GCC for Intel 80386 running Interix V3.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/i386-modes.def b/contrib/gcc/config/i386/i386-modes.def
index 5ef800f..89c83c4 100644
--- a/contrib/gcc/config/i386/i386-modes.def
+++ b/contrib/gcc/config/i386/i386-modes.def
@@ -1,23 +1,39 @@
-/* Definitions of target machine for GNU compiler for IA-32.
+/* Definitions of target machine for GCC for IA-32.
Copyright (C) 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* x86_64 ABI specifies both XF and TF modes.
+ XFmode is __float80 is IEEE extended; TFmode is __float128
+ is IEEE quad.
+
+ IEEE extended is 128 bits wide, except in ILP32 mode, but we
+ have to say it's 12 bytes so that the bitsize and wider_mode
+ tables are correctly set up. We correct its size below. */
+
+FLOAT_MODE (XF, 12, ieee_extended_intel_96_format);
+ADJUST_FLOAT_FORMAT (XF, (TARGET_128BIT_LONG_DOUBLE
+ ? &ieee_extended_intel_128_format
+ : &ieee_extended_intel_96_format));
+ADJUST_BYTESIZE (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 12);
+ADJUST_ALIGNMENT (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 4);
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
/* Add any extra modes needed to represent the condition code.
For the i386, we need separate modes when floating-point
@@ -27,20 +43,20 @@ Boston, MA 02111-1307, USA. */
Overflow flag to be unset. Sign bit test is used instead and
thus can be used to form "a&b>0" type of tests.
- Add CCGC to indicate comparisons agains zero that allows
+ Add CCGC to indicate comparisons against zero that allows
unspecified garbage in the Carry flag. This mode is used
by inc/dec instructions.
- Add CCGOC to indicate comparisons agains zero that allows
+ Add CCGOC to indicate comparisons against zero that allows
unspecified garbage in the Carry and Overflow flag. This
mode is used to simulate comparisons of (a-b) and (a+b)
against zero using sub/cmp/add operations.
Add CCZ to indicate that only the Zero flag is valid. */
-CC (CCGC)
-CC (CCGOC)
-CC (CCNO)
-CC (CCZ)
-CC (CCFP)
-CC (CCFPU)
+CC_MODE (CCGC);
+CC_MODE (CCGOC);
+CC_MODE (CCNO);
+CC_MODE (CCZ);
+CC_MODE (CCFP);
+CC_MODE (CCFPU);
diff --git a/contrib/gcc/config/i386/i386-protos.h b/contrib/gcc/config/i386/i386-protos.h
index b5ddb37..cc1bb81 100644
--- a/contrib/gcc/config/i386/i386-protos.h
+++ b/contrib/gcc/config/i386/i386-protos.h
@@ -1,235 +1,231 @@
-/* Definitions of target machine for GNU compiler for IA-32.
+/* Definitions of target machine for GCC for IA-32.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Functions in i386.c */
-extern void override_options PARAMS ((void));
-extern void optimization_options PARAMS ((int, int));
+extern void override_options (void);
+extern void optimization_options (int, int);
-extern int ix86_can_use_return_insn_p PARAMS ((void));
-extern int ix86_frame_pointer_required PARAMS ((void));
-extern void ix86_setup_frame_addresses PARAMS ((void));
+extern int ix86_can_use_return_insn_p (void);
+extern int ix86_frame_pointer_required (void);
+extern void ix86_setup_frame_addresses (void);
-extern void ix86_asm_file_end PARAMS ((FILE *));
-extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
-extern void ix86_expand_prologue PARAMS ((void));
-extern void ix86_expand_epilogue PARAMS ((int));
+extern void ix86_file_end (void);
+extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int);
+extern void ix86_expand_prologue (void);
+extern void ix86_expand_epilogue (int);
-extern void ix86_output_addr_vec_elt PARAMS ((FILE *, int));
-extern void ix86_output_addr_diff_elt PARAMS ((FILE *, int, int));
+extern void ix86_output_addr_vec_elt (FILE *, int);
+extern void ix86_output_addr_diff_elt (FILE *, int, int);
#ifdef RTX_CODE
-extern int ix86_aligned_p PARAMS ((rtx));
-
-extern int standard_80387_constant_p PARAMS ((rtx));
-extern int standard_sse_constant_p PARAMS ((rtx));
-extern int symbolic_reference_mentioned_p PARAMS ((rtx));
-
-extern int any_fp_register_operand PARAMS ((rtx, enum machine_mode));
-extern int register_and_not_any_fp_reg_operand PARAMS ((rtx, enum machine_mode));
-
-extern int fp_register_operand PARAMS ((rtx, enum machine_mode));
-extern int register_and_not_fp_reg_operand PARAMS ((rtx, enum machine_mode));
-
-extern int x86_64_general_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_szext_general_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_nonmemory_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_szext_nonmemory_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_immediate_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_zext_immediate_operand PARAMS ((rtx, enum machine_mode));
-extern int const_int_1_operand PARAMS ((rtx, enum machine_mode));
-extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int tls_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int global_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int local_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int initial_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int local_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
-extern int constant_call_address_operand PARAMS ((rtx, enum machine_mode));
-extern int const0_operand PARAMS ((rtx, enum machine_mode));
-extern int const1_operand PARAMS ((rtx, enum machine_mode));
-extern int const248_operand PARAMS ((rtx, enum machine_mode));
-extern int incdec_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_no_sp_operand PARAMS ((rtx, enum machine_mode));
-extern int mmx_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int general_no_elim_operand PARAMS ((rtx, enum machine_mode));
-extern int nonmemory_no_elim_operand PARAMS ((rtx, enum machine_mode));
-extern int q_regs_operand PARAMS ((rtx, enum machine_mode));
-extern int non_q_regs_operand PARAMS ((rtx, enum machine_mode));
-extern int sse_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int fcmov_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int cmp_fp_expander_operand PARAMS ((rtx, enum machine_mode));
-extern int ix86_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int ext_register_operand PARAMS ((rtx, enum machine_mode));
-extern int binary_fp_operator PARAMS ((rtx, enum machine_mode));
-extern int mult_operator PARAMS ((rtx, enum machine_mode));
-extern int div_operator PARAMS ((rtx, enum machine_mode));
-extern int arith_or_logical_operator PARAMS ((rtx, enum machine_mode));
-extern int promotable_binary_operator PARAMS ((rtx, enum machine_mode));
-extern int memory_displacement_operand PARAMS ((rtx, enum machine_mode));
-extern int cmpsi_operand PARAMS ((rtx, enum machine_mode));
-extern int long_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int aligned_operand PARAMS ((rtx, enum machine_mode));
-extern enum machine_mode ix86_cc_mode PARAMS ((enum rtx_code, rtx, rtx));
-
-extern int ix86_expand_movstr PARAMS ((rtx, rtx, rtx, rtx));
-extern int ix86_expand_clrstr PARAMS ((rtx, rtx, rtx));
-extern int ix86_expand_strlen PARAMS ((rtx, rtx, rtx, rtx));
-
-extern bool legitimate_constant_p PARAMS ((rtx));
-extern bool constant_address_p PARAMS ((rtx));
-extern bool legitimate_pic_operand_p PARAMS ((rtx));
-extern int legitimate_pic_address_disp_p PARAMS ((rtx));
-extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
-extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
-extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-
-extern void print_reg PARAMS ((rtx, int, FILE*));
-extern void print_operand PARAMS ((FILE*, rtx, int));
-extern void print_operand_address PARAMS ((FILE*, rtx));
-extern bool output_addr_const_extra PARAMS ((FILE*, rtx));
-
-extern void split_di PARAMS ((rtx[], int, rtx[], rtx[]));
-extern void split_ti PARAMS ((rtx[], int, rtx[], rtx[]));
-
-extern const char *output_set_got PARAMS ((rtx));
-extern const char *output_387_binary_op PARAMS ((rtx, rtx*));
-extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
-extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
-
-extern void i386_dwarf_output_addr_const PARAMS ((FILE*, rtx));
-extern void i386_output_dwarf_dtprel PARAMS ((FILE*, int, rtx));
-extern rtx i386_simplify_dwarf_addr PARAMS ((rtx));
-
-extern void ix86_expand_clear PARAMS ((rtx));
-extern void ix86_expand_move PARAMS ((enum machine_mode, rtx[]));
-extern void ix86_expand_vector_move PARAMS ((enum machine_mode, rtx[]));
-extern void ix86_expand_binary_operator PARAMS ((enum rtx_code,
- enum machine_mode, rtx[]));
-extern int ix86_binary_operator_ok PARAMS ((enum rtx_code, enum machine_mode,
- rtx[]));
-extern void ix86_expand_unary_operator PARAMS ((enum rtx_code, enum machine_mode,
- rtx[]));
-extern int ix86_unary_operator_ok PARAMS ((enum rtx_code, enum machine_mode,
- rtx[]));
-extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode));
-extern rtx ix86_expand_compare PARAMS ((enum rtx_code, rtx *, rtx *));
-extern int ix86_use_fcomi_compare PARAMS ((enum rtx_code));
-extern void ix86_expand_branch PARAMS ((enum rtx_code, rtx));
-extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
-extern int ix86_expand_int_movcc PARAMS ((rtx[]));
-extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
-extern void ix86_expand_call PARAMS ((rtx, rtx, rtx, rtx, rtx));
-extern void x86_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern rtx ix86_zero_extend_to_Pmode PARAMS ((rtx));
-extern void ix86_split_long_move PARAMS ((rtx[]));
-extern void ix86_split_ashldi PARAMS ((rtx *, rtx));
-extern void ix86_split_ashrdi PARAMS ((rtx *, rtx));
-extern void ix86_split_lshrdi PARAMS ((rtx *, rtx));
-extern int ix86_address_cost PARAMS ((rtx));
-extern rtx ix86_find_base_term PARAMS ((rtx));
-extern int ix86_check_movabs PARAMS ((rtx, int));
-
-extern rtx assign_386_stack_local PARAMS ((enum machine_mode, int));
-extern int ix86_attr_length_immediate_default PARAMS ((rtx, int));
-extern int ix86_attr_length_address_default PARAMS ((rtx));
-
-extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
-
-extern int x86_64_sign_extended_value PARAMS ((rtx));
-extern int x86_64_zero_extended_value PARAMS ((rtx));
-extern rtx ix86_libcall_value PARAMS ((enum machine_mode));
-extern bool ix86_function_value_regno_p PARAMS ((int));
-extern bool ix86_function_arg_regno_p PARAMS ((int));
-extern int ix86_function_arg_boundary PARAMS ((enum machine_mode, tree));
-extern int ix86_return_in_memory PARAMS ((tree));
-extern void ix86_va_start PARAMS ((tree, rtx));
-extern rtx ix86_va_arg PARAMS ((tree, tree));
-extern void ix86_setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int *, int));
-
-extern rtx ix86_force_to_memory PARAMS ((enum machine_mode, rtx));
-extern void ix86_free_from_memory PARAMS ((enum machine_mode));
-extern void ix86_split_fp_branch PARAMS ((enum rtx_code code, rtx,
- rtx, rtx, rtx, rtx));
-extern int ix86_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
-extern int ix86_register_move_cost PARAMS ((enum machine_mode, enum reg_class,
- enum reg_class));
-extern int ix86_secondary_memory_needed PARAMS ((enum reg_class,
- enum reg_class,
- enum machine_mode, int));
-extern enum reg_class ix86_preferred_reload_class PARAMS ((rtx,
- enum reg_class));
-extern int ix86_memory_move_cost PARAMS ((enum machine_mode, enum reg_class,
- int));
-extern void ix86_set_move_mem_attrs PARAMS ((rtx, rtx, rtx, rtx, rtx));
-extern void emit_i387_cw_initialization PARAMS ((rtx, rtx));
-extern bool ix86_fp_jump_nontrivial_p PARAMS ((enum rtx_code));
-extern void x86_order_regs_for_local_alloc PARAMS ((void));
-extern void x86_function_profiler PARAMS ((FILE *, int));
+extern int ix86_aligned_p (rtx);
+
+extern int standard_80387_constant_p (rtx);
+extern const char *standard_80387_constant_opcode (rtx);
+extern rtx standard_80387_constant_rtx (int);
+extern int standard_sse_constant_p (rtx);
+extern int symbolic_reference_mentioned_p (rtx);
+extern bool extended_reg_mentioned_p (rtx);
+extern bool x86_extended_QIreg_mentioned_p (rtx);
+extern bool x86_extended_reg_mentioned_p (rtx);
+
+extern int any_fp_register_operand (rtx, enum machine_mode);
+extern int register_and_not_any_fp_reg_operand (rtx, enum machine_mode);
+
+extern int fp_register_operand (rtx, enum machine_mode);
+extern int register_and_not_fp_reg_operand (rtx, enum machine_mode);
+
+extern int x86_64_general_operand (rtx, enum machine_mode);
+extern int x86_64_szext_general_operand (rtx, enum machine_mode);
+extern int x86_64_nonmemory_operand (rtx, enum machine_mode);
+extern int x86_64_szext_nonmemory_operand (rtx, enum machine_mode);
+extern int x86_64_immediate_operand (rtx, enum machine_mode);
+extern int x86_64_zext_immediate_operand (rtx, enum machine_mode);
+extern int symbolic_operand (rtx, enum machine_mode);
+extern int tls_symbolic_operand (rtx, enum machine_mode);
+extern int global_dynamic_symbolic_operand (rtx, enum machine_mode);
+extern int local_dynamic_symbolic_operand (rtx, enum machine_mode);
+extern int initial_exec_symbolic_operand (rtx, enum machine_mode);
+extern int local_exec_symbolic_operand (rtx, enum machine_mode);
+extern int pic_symbolic_operand (rtx, enum machine_mode);
+extern int call_insn_operand (rtx, enum machine_mode);
+extern int sibcall_insn_operand (rtx, enum machine_mode);
+extern int constant_call_address_operand (rtx, enum machine_mode);
+extern int const0_operand (rtx, enum machine_mode);
+extern int const1_operand (rtx, enum machine_mode);
+extern int const248_operand (rtx, enum machine_mode);
+extern int incdec_operand (rtx, enum machine_mode);
+extern int reg_no_sp_operand (rtx, enum machine_mode);
+extern int mmx_reg_operand (rtx, enum machine_mode);
+extern int general_no_elim_operand (rtx, enum machine_mode);
+extern int nonmemory_no_elim_operand (rtx, enum machine_mode);
+extern int q_regs_operand (rtx, enum machine_mode);
+extern int non_q_regs_operand (rtx, enum machine_mode);
+extern int sse_comparison_operator (rtx, enum machine_mode);
+extern int fcmov_comparison_operator (rtx, enum machine_mode);
+extern int cmp_fp_expander_operand (rtx, enum machine_mode);
+extern int ix86_comparison_operator (rtx, enum machine_mode);
+extern int ext_register_operand (rtx, enum machine_mode);
+extern int binary_fp_operator (rtx, enum machine_mode);
+extern int mult_operator (rtx, enum machine_mode);
+extern int div_operator (rtx, enum machine_mode);
+extern int arith_or_logical_operator (rtx, enum machine_mode);
+extern int promotable_binary_operator (rtx, enum machine_mode);
+extern int memory_displacement_operand (rtx, enum machine_mode);
+extern int cmpsi_operand (rtx, enum machine_mode);
+extern int long_memory_operand (rtx, enum machine_mode);
+extern int aligned_operand (rtx, enum machine_mode);
+extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
+
+extern int ix86_expand_movstr (rtx, rtx, rtx, rtx);
+extern int ix86_expand_clrstr (rtx, rtx, rtx);
+extern int ix86_expand_strlen (rtx, rtx, rtx, rtx);
+
+extern bool legitimate_constant_p (rtx);
+extern bool constant_address_p (rtx);
+extern bool legitimate_pic_operand_p (rtx);
+extern int legitimate_pic_address_disp_p (rtx);
+extern int legitimate_address_p (enum machine_mode, rtx, int);
+extern rtx legitimize_pic_address (rtx, rtx);
+extern rtx legitimize_address (rtx, rtx, enum machine_mode);
+
+extern void print_reg (rtx, int, FILE*);
+extern void print_operand (FILE*, rtx, int);
+extern void print_operand_address (FILE*, rtx);
+extern bool output_addr_const_extra (FILE*, rtx);
+
+extern void split_di (rtx[], int, rtx[], rtx[]);
+extern void split_ti (rtx[], int, rtx[], rtx[]);
+
+extern const char *output_set_got (rtx);
+extern const char *output_387_binary_op (rtx, rtx*);
+extern const char *output_fix_trunc (rtx, rtx*);
+extern const char *output_fp_compare (rtx, rtx*, int, int);
+
+extern void i386_dwarf_output_addr_const (FILE*, rtx);
+extern void i386_output_dwarf_dtprel (FILE*, int, rtx);
+
+extern void ix86_expand_clear (rtx);
+extern void ix86_expand_move (enum machine_mode, rtx[]);
+extern void ix86_expand_vector_move (enum machine_mode, rtx[]);
+extern void ix86_expand_binary_operator (enum rtx_code,
+ enum machine_mode, rtx[]);
+extern int ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
+extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
+ rtx[]);
+extern int ix86_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
+extern int ix86_match_ccmode (rtx, enum machine_mode);
+extern rtx ix86_expand_compare (enum rtx_code, rtx *, rtx *);
+extern int ix86_use_fcomi_compare (enum rtx_code);
+extern void ix86_expand_branch (enum rtx_code, rtx);
+extern int ix86_expand_setcc (enum rtx_code, rtx);
+extern int ix86_expand_int_movcc (rtx[]);
+extern int ix86_expand_fp_movcc (rtx[]);
+extern int ix86_expand_int_addcc (rtx[]);
+extern void ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int);
+extern void x86_initialize_trampoline (rtx, rtx, rtx);
+extern rtx ix86_zero_extend_to_Pmode (rtx);
+extern void ix86_split_long_move (rtx[]);
+extern void ix86_split_ashldi (rtx *, rtx);
+extern void ix86_split_ashrdi (rtx *, rtx);
+extern void ix86_split_lshrdi (rtx *, rtx);
+extern rtx ix86_find_base_term (rtx);
+extern int ix86_check_movabs (rtx, int);
+
+extern rtx assign_386_stack_local (enum machine_mode, int);
+extern int ix86_attr_length_immediate_default (rtx, int);
+extern int ix86_attr_length_address_default (rtx);
+
+extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
+
+extern int x86_64_sign_extended_value (rtx);
+extern int x86_64_zero_extended_value (rtx);
+extern rtx ix86_libcall_value (enum machine_mode);
+extern bool ix86_function_value_regno_p (int);
+extern bool ix86_function_arg_regno_p (int);
+extern int ix86_function_arg_boundary (enum machine_mode, tree);
+extern int ix86_return_in_memory (tree);
+extern void ix86_va_start (tree, rtx);
+extern rtx ix86_va_arg (tree, tree);
+extern void ix86_setup_incoming_varargs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int *, int);
+
+extern rtx ix86_force_to_memory (enum machine_mode, rtx);
+extern void ix86_free_from_memory (enum machine_mode);
+extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, rtx, rtx, rtx);
+extern int ix86_hard_regno_mode_ok (int, enum machine_mode);
+extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
+ enum reg_class);
+extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
+ enum machine_mode, int);
+extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
+extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
+extern void emit_i387_cw_initialization (rtx, rtx);
+extern bool ix86_fp_jump_nontrivial_p (enum rtx_code);
+extern void x86_order_regs_for_local_alloc (void);
+extern void x86_function_profiler (FILE *, int);
+extern void x86_emit_floatuns (rtx [2]);
#ifdef TREE_CODE
-extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
-extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
-extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
- tree, int));
-extern rtx ix86_function_value PARAMS ((tree));
-extern void ix86_init_builtins PARAMS ((void));
-extern rtx ix86_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
+extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
+extern rtx ix86_function_value (tree);
+extern void ix86_init_builtins (void);
+extern rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
#endif
#endif
#ifdef TREE_CODE
-extern int ix86_return_pops_args PARAMS ((tree, tree, int));
-extern tree ix86_build_va_list PARAMS ((void));
-
-extern int ix86_data_alignment PARAMS ((tree, int));
-extern int ix86_local_alignment PARAMS ((tree, int));
-extern int ix86_constant_alignment PARAMS ((tree, int));
-extern tree ix86_handle_dll_attribute PARAMS ((tree *, tree, tree, int, bool *));
-extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool *));
-
-extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
- int));
-extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
-extern int x86_field_alignment PARAMS ((tree, int));
+extern int ix86_return_pops_args (tree, tree, int);
+
+extern int ix86_data_alignment (tree, int);
+extern int ix86_local_alignment (tree, int);
+extern int ix86_constant_alignment (tree, int);
+extern tree ix86_handle_dll_attribute (tree *, tree, tree, int, bool *);
+extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
+
+extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
+extern void i386_pe_asm_named_section (const char *, unsigned int);
+extern int x86_field_alignment (tree, int);
#endif
-extern rtx ix86_tls_get_addr PARAMS ((void));
-extern void x86_machine_dependent_reorg PARAMS ((rtx));
+extern rtx ix86_tls_get_addr (void);
+extern bool ix86_must_pass_in_stack (enum machine_mode mode, tree);
+extern void ix86_expand_vector_init (rtx, rtx);
/* In winnt.c */
-extern int i386_pe_dllexport_name_p PARAMS ((const char *));
-extern int i386_pe_dllimport_name_p PARAMS ((const char *));
-extern void i386_pe_unique_section PARAMS ((tree, int));
-extern void i386_pe_declare_function_type PARAMS ((FILE *, const char *, int));
-extern void i386_pe_record_external_function PARAMS ((const char *));
-extern void i386_pe_record_exported_symbol PARAMS ((const char *, int));
-extern void i386_pe_asm_file_end PARAMS ((FILE *));
-extern void i386_pe_encode_section_info PARAMS ((tree, int));
-extern const char *i386_pe_strip_name_encoding PARAMS ((const char *));
-extern const char *i386_pe_strip_name_encoding_full PARAMS ((const char *));
+extern int i386_pe_dllexport_name_p (const char *);
+extern int i386_pe_dllimport_name_p (const char *);
+extern void i386_pe_unique_section (tree, int);
+extern void i386_pe_declare_function_type (FILE *, const char *, int);
+extern void i386_pe_record_external_function (const char *);
+extern void i386_pe_record_exported_symbol (const char *, int);
+extern void i386_pe_asm_file_end (FILE *);
+extern void i386_pe_encode_section_info (tree, rtx, int);
+extern const char *i386_pe_strip_name_encoding (const char *);
+extern const char *i386_pe_strip_name_encoding_full (const char *);
+extern void i386_pe_output_labelref (FILE *, const char *);
diff --git a/contrib/gcc/config/i386/i386elf.h b/contrib/gcc/config/i386/i386elf.h
index cd01db2..ed6b41a 100644
--- a/contrib/gcc/config/i386/i386elf.h
+++ b/contrib/gcc/config/i386/i386elf.h
@@ -1,23 +1,23 @@
-/* Target definitions for GNU compiler for Intel 80386 using ELF
+/* Target definitions for GCC for Intel 80386 using ELF
Copyright (C) 1988, 1991, 1995, 2000, 2001, 2002
Free Software Foundation, Inc.
Derived from sysv4.h written by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -65,13 +65,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
diff --git a/contrib/gcc/config/i386/k6.md b/contrib/gcc/config/i386/k6.md
index af128bf..edd12f6 100644
--- a/contrib/gcc/config/i386/k6.md
+++ b/contrib/gcc/config/i386/k6.md
@@ -1,20 +1,20 @@
;; AMD K6/K6-2 Scheduling
;; Copyright (C) 2002 ;; Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. */
;;
@@ -31,7 +31,7 @@
;; fpu describes FPU unit
;; load describes load unit.
;; branch describes branch unit.
-;; store decsribes store unit. This unit is not modelled completely and only
+;; store describes store unit. This unit is not modelled completely and only
;; used to model lea operation. Otherwise it lie outside of the critical
;; path.
;;
@@ -49,7 +49,7 @@
(define_function_unit "k6_alux" 1 0
(and (eq_attr "cpu" "k6")
(and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
- (match_operand:QI 0 "general_operand" "")))
+ (eq_attr "mode" "QI")))
1 1)
(define_function_unit "k6_alu" 2 0
@@ -71,7 +71,7 @@
;; Load unit have two cycle latency, but we take care for it in adjust_cost
(define_function_unit "k6_load" 1 0
(and (eq_attr "cpu" "k6")
- (ior (eq_attr "type" "pop")
+ (ior (eq_attr "type" "pop,leave")
(eq_attr "memory" "load,both")))
1 1)
diff --git a/contrib/gcc/config/i386/kaos-i386.h b/contrib/gcc/config/i386/kaos-i386.h
new file mode 100644
index 0000000..3fdf883
--- /dev/null
+++ b/contrib/gcc/config/i386/kaos-i386.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GCC.
+ kaOS on ia32 architecture version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (i386/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/i386/kfreebsdgnu.h b/contrib/gcc/config/i386/kfreebsdgnu.h
new file mode 100644
index 0000000..66b231d
--- /dev/null
+++ b/contrib/gcc/config/i386/kfreebsdgnu.h
@@ -0,0 +1,35 @@
+/* Definitions for Intel 386 running GNU/KFreeBSD systems with ELF format.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Bruno Haible.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (i386 KFreeBSD/ELF)");
+
+/* FIXME: Is a KFreeBSD-specific fallback mechanism necessary? */
+#undef MD_FALLBACK_FRAME_STATE_FOR
+
+#undef LINK_SPEC
+#define LINK_SPEC "-m elf_i386_fbsd %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
+ %{static:-static}}}"
diff --git a/contrib/gcc/config/i386/linux-aout.h b/contrib/gcc/config/i386/linux-aout.h
index 783b8a9..d7be93c 100644
--- a/contrib/gcc/config/i386/linux-aout.h
+++ b/contrib/gcc/config/i386/linux-aout.h
@@ -3,20 +3,20 @@
Free Software Foundation, Inc.
Contributed by H.J. Lu (hjl@nynexst.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,10 +26,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_define ("__gnu_linux__"); \
- builtin_assert ("system=posix"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
diff --git a/contrib/gcc/config/i386/linux.h b/contrib/gcc/config/i386/linux.h
index 6b553cd..e7d19ec 100644
--- a/contrib/gcc/config/i386/linux.h
+++ b/contrib/gcc/config/i386/linux.h
@@ -4,34 +4,26 @@
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
-
/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- output_file_directive (FILE, main_input_filename); \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- } while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
#define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)");
@@ -40,6 +32,10 @@ Boston, MA 02111-1307, USA. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
+/* We arrange for the whole %gs segment to map the tls area. */
+#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT
+#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS
+
#undef ASM_COMMENT_START
#define ASM_COMMENT_START "#"
@@ -51,7 +47,7 @@ Boston, MA 02111-1307, USA. */
To the best of my knowledge, no Linux libc has required the label
argument to mcount. */
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
#undef MCOUNT_NAME
#define MCOUNT_NAME "mcount"
@@ -77,11 +73,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__gnu_linux__"); \
- builtin_assert ("system=posix"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
@@ -118,15 +110,6 @@ Boston, MA 02111-1307, USA. */
#undef LINK_SPEC
#ifdef USE_GNULIBC_1
-#ifndef LINUX_DEFAULT_ELF
-#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
- %{!shared: \
- %{!ibcs: \
- %{!static: \
- %{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \
- %{!rpath:-rpath /lib/elf/}} %{static:-static}}}"
-#else
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
%{!shared: \
%{!ibcs: \
@@ -134,7 +117,6 @@ Boston, MA 02111-1307, USA. */
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \
%{static:-static}}}"
-#endif
#else
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
%{!shared: \
@@ -220,6 +202,9 @@ Boston, MA 02111-1307, USA. */
: "=d"(BASE))
#endif
+#undef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK 1
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
@@ -228,7 +213,7 @@ Boston, MA 02111-1307, USA. */
signal-turned-exceptions for them. There's also no configure-run for
the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
target libc1 macro should be enough. */
-#ifndef USE_GNULIBC_1
+#if !(defined (USE_GNULIBC_1) || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
#include <signal.h>
#include <sys/ucontext.h>
diff --git a/contrib/gcc/config/i386/linux64.h b/contrib/gcc/config/i386/linux64.h
index 7a9e0ba..98536c1 100644
--- a/contrib/gcc/config/i386/linux64.h
+++ b/contrib/gcc/config/i386/linux64.h
@@ -1,46 +1,35 @@
/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format.
- Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
-
#define TARGET_VERSION fprintf (stderr, " (x86-64 Linux/ELF)");
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_define ("__gnu_linux__"); \
- builtin_define ("__ELF__"); \
- builtin_assert ("system=posix"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
builtin_define ("__pic__"); \
} \
- if (TARGET_64BIT) \
- { \
- builtin_define ("__LP64__"); \
- builtin_define ("_LP64"); \
- } \
} \
while (0)
@@ -53,6 +42,10 @@ Boston, MA 02111-1307, USA. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
+/* We arrange for the whole %fs segment to map the tls area. */
+#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT
+#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS
+
/* Provide a LINK_SPEC. Here we provide support for the special GCC
options -static and -shared, which allow us to link things in one
of these three modes by applying the appropriate combinations of
@@ -71,19 +64,11 @@ Boston, MA 02111-1307, USA. */
%{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \
%{static:-static}}"
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
- %{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \
- crti.o%s %{static:crtbeginT.o%s} \
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
-
#define MULTILIB_DEFAULTS { "m64" }
+#undef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK 1
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs.
Don't use this at all if inhibit_libc is used. */
diff --git a/contrib/gcc/config/i386/lynx-ng.h b/contrib/gcc/config/i386/lynx-ng.h
index 08fa60f..536aa7a 100644
--- a/contrib/gcc/config/i386/lynx-ng.h
+++ b/contrib/gcc/config/i386/lynx-ng.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running LynxOS, using Lynx's old as and ld.
Copyright (C) 1993, 1995, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -68,10 +68,3 @@ Boston, MA 02111-1307, USA. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), ".%s%ld", (PREFIX), (long)(NUMBER))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
diff --git a/contrib/gcc/config/i386/lynx.h b/contrib/gcc/config/i386/lynx.h
index 7835f27..a926d14 100644
--- a/contrib/gcc/config/i386/lynx.h
+++ b/contrib/gcc/config/i386/lynx.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running LynxOS.
Copyright (C) 1993, 1995, 1996, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -69,10 +69,3 @@ Boston, MA 02111-1307, USA. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), ".%s%ld", (PREFIX), (long)(NUMBER))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
diff --git a/contrib/gcc/config/i386/mingw32.h b/contrib/gcc/config/i386/mingw32.h
index 7f62fbd..4bf0dda 100644
--- a/contrib/gcc/config/i386/mingw32.h
+++ b/contrib/gcc/config/i386/mingw32.h
@@ -3,69 +3,42 @@
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Most of this is the same as for cygwin, except for changing some
- specs. */
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (x86 MinGW)");
-/* Mingw GCC, unlike Cygwin's, must be relocatable. This macro must
- be defined before any other files are included. */
-#ifndef WIN32_NO_ABSOLUTE_INST_DIRS
-#define WIN32_NO_ABSOLUTE_INST_DIRS 1
-#endif
-
-#include "i386/cygwin.h"
-
-#define TARGET_EXECUTABLE_SUFFIX ".exe"
-
-/* See i386/crtdll.h for an altervative definition. */
+/* See i386/crtdll.h for an alternative definition. */
#define EXTRA_OS_CPP_BUILTINS() \
do \
{ \
builtin_define ("__MSVCRT__"); \
builtin_define ("__MINGW32__"); \
+ builtin_define ("_WIN32"); \
+ builtin_define_std ("WIN32"); \
+ builtin_define_std ("WINNT"); \
} \
while (0)
-#undef TARGET_OS_CPP_BUILTINS /* From cygwin.h. */
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("_WIN32"); \
- builtin_define_std ("WIN32"); \
- builtin_define_std ("WINNT"); \
- builtin_define ("_X86_=1"); \
- builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
- builtin_define ("__declspec(x)=__attribute__((x))"); \
- if (!flag_iso) \
- { \
- builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
- } \
- EXTRA_OS_CPP_BUILTINS (); \
- builtin_assert ("system=winnt"); \
- } \
- while (0)
-
-/* Specific a different directory for the standard include files. */
+/* Override the standard choice of /usr/include as the default prefix
+ to try when searching for header files. */
#undef STANDARD_INCLUDE_DIR
-#define STANDARD_INCLUDE_DIR "/usr/local/mingw32/include"
+#define STANDARD_INCLUDE_DIR "/mingw/include"
#undef STANDARD_INCLUDE_COMPONENT
#define STANDARD_INCLUDE_COMPONENT "MINGW"
@@ -96,12 +69,12 @@ Boston, MA 02111-1307, USA. */
#define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
%{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s}"
-/* MS runtime does not need a separate math library. */
-#undef MATH_LIBRARY
-#define MATH_LIBRARY ""
+/* An additional prefix to try after the standard prefixes. */
+#undef MD_STARTFILE_PREFIX
+#define MD_STARTFILE_PREFIX "/mingw/lib/"
/* Output STRING, a string representing a filename, to FILE.
- We canonicalize it to be in Unix format (backslashe are replaced
+ We canonicalize it to be in Unix format (backslashes are replaced
forward slashes. */
#undef OUTPUT_QUOTED_STRING
#define OUTPUT_QUOTED_STRING(FILE, STRING) \
@@ -128,6 +101,6 @@ do { \
putc ('\"', asm_file); \
} while (0)
-/* Define as short unsigned for compatability with MS runtime. */
+/* Define as short unsigned for compatibility with MS runtime. */
#undef WINT_TYPE
#define WINT_TYPE "short unsigned int"
diff --git a/contrib/gcc/config/i386/mmintrin.h b/contrib/gcc/config/i386/mmintrin.h
index 00e77e4..bd775e8 100644
--- a/contrib/gcc/config/i386/mmintrin.h
+++ b/contrib/gcc/config/i386/mmintrin.h
@@ -1,19 +1,19 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/moss.h b/contrib/gcc/config/i386/moss.h
index 642c625..3b748cf 100644
--- a/contrib/gcc/config/i386/moss.h
+++ b/contrib/gcc/config/i386/moss.h
@@ -2,20 +2,20 @@
Copyright (C) 1996, 2001 Free Software Foundation, Inc.
Contributed by Bryan Ford <baford@cs.utah.edu>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
builtin_define_std ("moss"); \
- builtin_define ("__ELF__"); \
builtin_assert ("system=posix"); \
if (flag_pic) \
{ \
diff --git a/contrib/gcc/config/i386/netbsd-elf.h b/contrib/gcc/config/i386/netbsd-elf.h
index 4f49bd3..bd2e9de 100644
--- a/contrib/gcc/config/i386/netbsd-elf.h
+++ b/contrib/gcc/config/i386/netbsd-elf.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler,
+/* Definitions of target machine for GCC,
for i386/ELF NetBSD systems.
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Contributed by matthew green <mrg@eterna.com.au>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -64,8 +64,6 @@ Boston, MA 02111-1307, USA. */
#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
-#undef ASM_FINAL_SPEC
-
#undef ASM_COMMENT_START
#define ASM_COMMENT_START "#"
@@ -76,7 +74,7 @@ Boston, MA 02111-1307, USA. */
/* Output assembler code to FILE to call the profiler. */
#undef NO_PROFILE_COUNTERS
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
@@ -122,6 +120,6 @@ Boston, MA 02111-1307, USA. */
#define DEFAULT_PCC_STRUCT_RETURN 1
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#define TARGET_VERSION fprintf (stderr, " (NetBSD/i386 ELF)");
diff --git a/contrib/gcc/config/i386/netbsd.h b/contrib/gcc/config/i386/netbsd.h
index 45ae893..dd7eae1 100644
--- a/contrib/gcc/config/i386/netbsd.h
+++ b/contrib/gcc/config/i386/netbsd.h
@@ -69,4 +69,4 @@
#define GOT_SYMBOL_NAME "GLOBAL_OFFSET_TABLE_"
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
diff --git a/contrib/gcc/config/i386/netbsd64.h b/contrib/gcc/config/i386/netbsd64.h
index 341b6d1..66f31e0 100644
--- a/contrib/gcc/config/i386/netbsd64.h
+++ b/contrib/gcc/config/i386/netbsd64.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler,
+/* Definitions of target machine for GCC,
for x86-64/ELF NetBSD systems.
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,8 +24,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
NETBSD_OS_CPP_BUILTINS_ELF(); \
- if (TARGET_64BIT) \
- NETBSD_OS_CPP_BUILTINS_LP64(); \
} \
while (0)
@@ -70,6 +68,6 @@ Boston, MA 02111-1307, USA. */
}
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#define TARGET_VERSION fprintf (stderr, " (NetBSD/x86_64 ELF)");
diff --git a/contrib/gcc/config/i386/nto.h b/contrib/gcc/config/i386/nto.h
new file mode 100644
index 0000000..8860c8b
--- /dev/null
+++ b/contrib/gcc/config/i386/nto.h
@@ -0,0 +1,99 @@
+/* Definitions for Intel 386 running QNX/Neutrino.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 1
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (QNX/Neutrino/i386 ELF)");
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("__X86__"); \
+ builtin_define_std ("__QNXNTO__"); \
+ builtin_define_std ("__QNX__"); \
+ builtin_define_std ("__ELF__"); \
+ builtin_define_std ("__LITTLEENDIAN__");\
+ builtin_assert ("system=qnx"); \
+ builtin_assert ("system=qnxnto"); \
+ builtin_assert ("system=nto"); \
+ builtin_assert ("system=unix"); \
+ if (flag_pic) \
+ { \
+ builtin_define ("__PIC__"); \
+ builtin_define ("__pic__"); \
+ } \
+ } \
+ while (0)
+
+#undef THREAD_MODEL_SPEC
+#define THREAD_MODEL_SPEC "posix"
+
+#ifdef CROSS_COMPILE
+#define SYSROOT_SUFFIX_SPEC "x86"
+#endif
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+"%{!shared: \
+ %{!symbolic: \
+ %{pg:mcrt1.o%s} \
+ %{!pg:%{p:mcrt1.o%s} \
+ %{!p:crt1.o%s}}}} \
+crti.o%s \
+%{fexceptions: crtbegin.o%s} \
+%{!fexceptions: %R/lib/crtbegin.o}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "crtend.o%s crtn.o%s"
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "%{h*} %{v:-V} \
+ %{b} \
+ %{static:-dn -Bstatic} \
+ %{shared:-G -dy -z text} \
+ %{symbolic:-Bsymbolic -G -dy -z text} \
+ %{G:-G} \
+ %{YP,*} \
+ %{!YP,*:%{p:-Y P,%R/lib} \
+ %{!p:-Y P,%R/lib}} \
+ %{Qy:} %{!Qn:-Qy} \
+ -m i386nto \
+ %{!shared: --dynamic-linker /usr/lib/ldqnx.so.2}"
+
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long unsigned int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#define NO_IMPLICIT_EXTERN_C 1
+
diff --git a/contrib/gcc/config/i386/openbsd.h b/contrib/gcc/config/i386/openbsd.h
index 60f1657..14de018 100644
--- a/contrib/gcc/config/i386/openbsd.h
+++ b/contrib/gcc/config/i386/openbsd.h
@@ -1,20 +1,20 @@
/* Configuration for an OpenBSD i386 target.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -90,8 +90,7 @@ Boston, MA 02111-1307, USA. */
/* Assembler format: exception region output. */
/* All configurations that don't use elf must be explicit about not using
- dwarf unwind information. egcs doesn't try too hard to check internal
- configuration files... */
+ dwarf unwind information. */
#define DWARF2_UNWIND_INFO 0
#undef ASM_PREFERRED_EH_DATA_FORMAT
diff --git a/contrib/gcc/config/i386/pentium.md b/contrib/gcc/config/i386/pentium.md
index b4c5ece..5fec811 100644
--- a/contrib/gcc/config/i386/pentium.md
+++ b/contrib/gcc/config/i386/pentium.md
@@ -1,20 +1,20 @@
;; Pentium Scheduling
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. */
;;
@@ -34,7 +34,7 @@
;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
;; rules, because it results in noticeably better code on non-MMX Pentium
;; and doesn't hurt much on MMX. (Prefixed instructions are not very
-;; common, so the scheduler usualy has a non-prefixed insn to pair).
+;; common, so the scheduler usually has a non-prefixed insn to pair).
(define_attr "pent_pair" "uv,pu,pv,np"
(cond [(eq_attr "imm_disp" "true")
@@ -51,13 +51,13 @@
(match_operand 2 "const_int_operand" ""))
(const_string "pu")
(and (eq_attr "type" "rotate")
- (match_operand 2 "const_int_1_operand" ""))
+ (match_operand 2 "const1_operand" ""))
(const_string "pu")
(and (eq_attr "type" "ishift1")
(match_operand 1 "const_int_operand" ""))
(const_string "pu")
(and (eq_attr "type" "rotate1")
- (match_operand 1 "const_int_1_operand" ""))
+ (match_operand 1 "const1_operand" ""))
(const_string "pu")
(and (eq_attr "type" "call")
(match_operand 0 "constant_call_address_operand" ""))
@@ -71,7 +71,7 @@
(define_automaton "pentium,pentium_fpu")
;; Pentium do have U and V pipes. Instruction to both pipes
-;; are alwyas issued together, much like on VLIW.
+;; are always issued together, much like on VLIW.
;;
;; predecode
;; / \
@@ -194,7 +194,7 @@
(define_insn_reservation "pent_pop" 1
(and (eq_attr "cpu" "pentium")
- (eq_attr "type" "pop"))
+ (eq_attr "type" "pop,leave"))
"pentium-firstuv")
;; Call and branch instruction can execute in either pipe, but
@@ -210,7 +210,7 @@
"pentium-firstv")
;; Floating point instruction dispatch in U pipe, but continue
-;; in FP pipeline allowing other isntructions to be executed.
+;; in FP pipeline allowing other instructions to be executed.
(define_insn_reservation "pent_fp" 3
(and (eq_attr "cpu" "pentium")
(eq_attr "type" "fop,fistp"))
diff --git a/contrib/gcc/config/i386/pmmintrin.h b/contrib/gcc/config/i386/pmmintrin.h
index 5649c00..3b18e2a 100644
--- a/contrib/gcc/config/i386/pmmintrin.h
+++ b/contrib/gcc/config/i386/pmmintrin.h
@@ -1,19 +1,19 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -30,7 +30,7 @@
#ifndef _PMMINTRIN_H_INCLUDED
#define _PMMINTRIN_H_INCLUDED
-#ifdef __PNI__
+#ifdef __SSE3__
#include <xmmintrin.h>
#include <emmintrin.h>
@@ -127,6 +127,6 @@ _mm_mwait (unsigned int __E, unsigned int __H)
#define _mm_mwait(E, H) __builtin_ia32_mwait ((E), (H))
#endif
-#endif /* __PNI__ */
+#endif /* __SSE3__ */
#endif /* _PMMINTRIN_H_INCLUDED */
diff --git a/contrib/gcc/config/i386/ppro.md b/contrib/gcc/config/i386/ppro.md
index 8690685..911bf3b 100644
--- a/contrib/gcc/config/i386/ppro.md
+++ b/contrib/gcc/config/i386/ppro.md
@@ -1,20 +1,20 @@
;; Pentium Pro/PII Scheduling
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. */
@@ -29,7 +29,7 @@
(define_attr "ppro_uops" "one,few,many"
(cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
(const_string "many")
- (eq_attr "type" "icmov,fcmov,str,cld")
+ (eq_attr "type" "icmov,fcmov,str,cld,leave")
(const_string "few")
(eq_attr "type" "imov")
(if_then_else (eq_attr "memory" "store,both")
@@ -118,7 +118,7 @@
(define_function_unit "ppro_p2" 1 0
(and (eq_attr "cpu" "pentiumpro")
- (ior (eq_attr "type" "pop")
+ (ior (eq_attr "type" "pop,leave")
(eq_attr "memory" "load,both")))
3 1)
diff --git a/contrib/gcc/config/i386/ptx4-i.h b/contrib/gcc/config/i386/ptx4-i.h
index a7d5710..5fcd074 100644
--- a/contrib/gcc/config/i386/ptx4-i.h
+++ b/contrib/gcc/config/i386/ptx4-i.h
@@ -1,24 +1,24 @@
-/* Target definitions for GNU compiler for Intel 80386 running Dynix/ptx v4
+/* Target definitions for GCC for Intel 80386 running Dynix/ptx v4
Copyright (C) 1996, 2002 Free Software Foundation, Inc.
Modified from sysv4.h
Originally written by Ron Guilmette (rfg@netcom.com).
Modified by Tim Wright (timw@sequent.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -57,13 +57,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
diff --git a/contrib/gcc/config/i386/rtemself.h b/contrib/gcc/config/i386/rtemself.h
index 0967178..6f5299d 100644
--- a/contrib/gcc/config/i386/rtemself.h
+++ b/contrib/gcc/config/i386/rtemself.h
@@ -2,20 +2,20 @@
Copyright (C) 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,7 +25,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
builtin_define ("__rtems__"); \
- builtin_define ("__ELF__"); \
builtin_define ("__USE_INIT_FINI__"); \
builtin_assert ("system=rtems"); \
if (!TARGET_80387) \
diff --git a/contrib/gcc/config/i386/sco5.h b/contrib/gcc/config/i386/sco5.h
index 2a28e54..bb872d5 100644
--- a/contrib/gcc/config/i386/sco5.h
+++ b/contrib/gcc/config/i386/sco5.h
@@ -3,29 +3,26 @@
Free Software Foundation, Inc.
Contributed by Kean Johnston (jkj@sco.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386, SCO OpenServer 5 Syntax)");
-/* The native link editor does not support linkonce stuff */
-#define SUPPORTS_ONE_ONLY 0
-
#undef ASM_QUAD
#undef GLOBAL_ASM_OP
@@ -63,7 +60,6 @@ Boston, MA 02111-1307, USA. */
#define DBX_REGISTER_NUMBER(n) svr4_dbx_register_map[n]
#define DWARF2_DEBUGGING_INFO 1
-#define DWARF_DEBUGGING_INFO 1
#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
@@ -149,7 +145,7 @@ Boston, MA 02111-1307, USA. */
assume that /usr/gnu is the prefix for the GNU tools, because thats
where the SCO provided ones go. This is especially important for
include and library search path ordering. We want to look in /usr/gnu
- first, becuase frequently people are linking against -lintl, and they
+ first because frequently people are linking against -lintl, and they
MEAN to link with gettext. What they get is the SCO intl library. Its
a REAL pity that GNU gettext chose that name; perhaps in a future
version they can be persuaded to change it to -lgnuintl and have a
@@ -238,7 +234,6 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SPEC
#define CPP_SPEC "\
-isystem /usr/gnu/include \
- %{pthread:-D_REENTRANT} \
%{!Xods30:-D_STRICT_NAMES} \
%{!ansi:%{!posix:%{!Xods30:-D_SCO_XPG_VERS=4}}} \
%{ansi:-isystem include/ansi%s -isystem /usr/include/ansi} \
@@ -282,7 +277,7 @@ Boston, MA 02111-1307, USA. */
%{G:%{!shared:pic/libgcc.a%s}} \
%{shared:%{G:pic/libgcc.a%s}} \
%{p:%{!pp:-lelfprof -lelf}} %{pp:%{!p:-lelfprof -lelf}} \
- %{!shared:%{!symbolic:%{!G:-lcrypt -lgen -lc %{pthread:-lpthread}}}}"
+ %{!shared:%{!symbolic:%{!G:-lcrypt -lgen -lc}}}"
#undef LIBGCC_SPEC
#define LIBGCC_SPEC \
diff --git a/contrib/gcc/config/i386/sol2.h b/contrib/gcc/config/i386/sol2.h
index 9089a1d..78b2985 100644
--- a/contrib/gcc/config/i386/sol2.h
+++ b/contrib/gcc/config/i386/sol2.h
@@ -1,22 +1,22 @@
-/* Target definitions for GNU compiler for Intel 80386 running Solaris 2
+/* Target definitions for GCC for Intel 80386 running Solaris 2
Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Fred Fish (fnf@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -64,3 +64,18 @@ Boston, MA 02111-1307, USA. */
/* The Solaris assembler does not support .quad. Do not use it. */
#undef ASM_QUAD
+
+/* The Solaris assembler wants a .local for non-exported aliases. */
+#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \
+ do { \
+ const char *declname = \
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
+ ASM_OUTPUT_DEF ((FILE), declname, \
+ IDENTIFIER_POINTER (TARGET)); \
+ if (! TREE_PUBLIC (DECL)) \
+ { \
+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
+ assemble_name ((FILE), declname); \
+ fprintf ((FILE), "\n"); \
+ } \
+ } while (0)
diff --git a/contrib/gcc/config/i386/svr3dbx.h b/contrib/gcc/config/i386/svr3dbx.h
index 4be7a70..d06d911 100644
--- a/contrib/gcc/config/i386/svr3dbx.h
+++ b/contrib/gcc/config/i386/svr3dbx.h
@@ -1,20 +1,20 @@
-/* Definitions for Intel 385 running system V, using dbx-in-coff encapsulation.
+/* Definitions for Intel 386 running system V, using dbx-in-coff encapsulation.
Copyright (C) 1992, 1995, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/svr3gas.h b/contrib/gcc/config/i386/svr3gas.h
index b9d94b7..81428ae 100644
--- a/contrib/gcc/config/i386/svr3gas.h
+++ b/contrib/gcc/config/i386/svr3gas.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running system V, using gas.
Copyright (C) 1992, 1996, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -52,13 +52,13 @@ Boston, MA 02111-1307, USA. */
data_section (); \
ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(ROUNDED)); \
} \
else \
{ \
fputs (".lcomm ", (FILE)); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u\n", (ROUNDED)); \
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)); \
} \
} while (0)
diff --git a/contrib/gcc/config/i386/sysv3.h b/contrib/gcc/config/i386/sysv3.h
index 93f9445..b2643b1 100644
--- a/contrib/gcc/config/i386/sysv3.h
+++ b/contrib/gcc/config/i386/sysv3.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running system V.
Copyright (C) 1988, 1996, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -46,11 +46,6 @@ Boston, MA 02111-1307, USA. */
#define PCC_BITFIELD_TYPE_MATTERS 1
-/* Don't write a `.optim' pseudo; this assembler doesn't handle them. */
-
-#undef ASM_FILE_START_1
-#define ASM_FILE_START_1(FILE)
-
/* We want to be able to get DBX debugging information via -gstabs. */
#define DBX_DEBUGGING_INFO 1
@@ -89,7 +84,7 @@ Boston, MA 02111-1307, USA. */
bss_section (); \
ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(ROUNDED));\
} while (0)
/* Define a few machine-specific details of the implementation of
diff --git a/contrib/gcc/config/i386/sysv4-cpp.h b/contrib/gcc/config/i386/sysv4-cpp.h
index 5b46bf1..6ec751a 100644
--- a/contrib/gcc/config/i386/sysv4-cpp.h
+++ b/contrib/gcc/config/i386/sysv4-cpp.h
@@ -1,22 +1,22 @@
-/* Target definitions for GNU compiler for Intel 80386 running System V.4
+/* Target definitions for GCC for Intel 80386 running System V.4
Copyright (C) 1991, 2001, 2002 Free Software Foundation, Inc.
Written by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/sysv4.h b/contrib/gcc/config/i386/sysv4.h
index 6b3335e..2447006 100644
--- a/contrib/gcc/config/i386/sysv4.h
+++ b/contrib/gcc/config/i386/sysv4.h
@@ -1,22 +1,22 @@
-/* Target definitions for GNU compiler for Intel 80386 running System V.4
+/* Target definitions for GCC for Intel 80386 running System V.4
Copyright (C) 1991, 2001, 2002 Free Software Foundation, Inc.
Written by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -34,12 +34,9 @@ Boston, MA 02111-1307, USA. */
/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- output_file_directive (FILE, main_input_filename); \
- fprintf (FILE, "\t.version\t\"01.01\"\n"); \
- } while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
+#undef X86_FILE_START_VERSION_DIRECTIVE
+#define X86_FILE_START_VERSION_DIRECTIVE true
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) svr4_dbx_register_map[n]
@@ -55,13 +52,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
diff --git a/contrib/gcc/config/i386/sysv5.h b/contrib/gcc/config/i386/sysv5.h
index 9b759f4..c4edd71 100644
--- a/contrib/gcc/config/i386/sysv5.h
+++ b/contrib/gcc/config/i386/sysv5.h
@@ -2,20 +2,20 @@
Copyright (C) 1999 Free Software Foundation, Inc.
Contributed by Robert Lipe (robertlipe@usa.net)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/t-beos b/contrib/gcc/config/i386/t-beos
index e545abd..b5c8ec2 100644
--- a/contrib/gcc/config/i386/t-beos
+++ b/contrib/gcc/config/i386/t-beos
@@ -2,6 +2,3 @@
# we are most likely to want to apply any fixes to.
SYSTEM_HEADER_DIR = /boot/develop/headers/posix
CROSS_SYSTEM_HEADER_DIR = $(tooldir)/sys-include/posix
-
-# Don't run fixproto
-STMP_FIXPROTO =
diff --git a/contrib/gcc/config/i386/t-cygming b/contrib/gcc/config/i386/t-cygming
new file mode 100644
index 0000000..aa6ff61
--- /dev/null
+++ b/contrib/gcc/config/i386/t-cygming
@@ -0,0 +1,19 @@
+LIB1ASMSRC = i386/cygwin.asm
+LIB1ASMFUNCS = _chkstk
+
+# cygwin and mingw always have a limits.h, but, depending upon how we are
+# doing the build, it may not be installed yet.
+LIMITS_H_TEST = true
+
+# If we are building next to winsup, this will let us find the real
+# limits.h when building libgcc2. Otherwise, winsup must be installed
+# first.
+LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/w32api/include
+
+winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
+ $(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/winnt.c
+
+STMP_FIXINC=stmp-fixinc
diff --git a/contrib/gcc/config/i386/t-cygwin b/contrib/gcc/config/i386/t-cygwin
index 6fcb834..c6e7773 100644
--- a/contrib/gcc/config/i386/t-cygwin
+++ b/contrib/gcc/config/i386/t-cygwin
@@ -1,21 +1,16 @@
-LIB1ASMSRC = i386/cygwin.asm
-LIB1ASMFUNCS = _chkstk
-
-# cygwin always has a limits.h, but, depending upon how we are doing
-# the build, it may not be installed yet.
-LIMITS_H_TEST = true
-
-T_CPPFLAGS=-DCYGWIN_CROSS_DIR=\"$(build_tooldir)\"
-
# If we are building next to winsup, this will let us find the real
# limits.h when building libgcc2. Otherwise, winsup must be installed
# first.
-LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/include \
- -I$(srcdir)/../winsup/cygwin/include \
- -I$(srcdir)/../winsup/w32api/include
+LIBGCC2_INCLUDES += -I$(srcdir)/../winsup/include \
+ -I$(srcdir)/../winsup/cygwin/include
+
+cygwin1.o: $(srcdir)/config/i386/cygwin1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(TM_P_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/cygwin1.c
-winnt.o: $(srcdir)/config/i386/winnt.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c
+cygwin2.o: $(srcdir)/config/i386/cygwin2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(TM_P_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/cygwin2.c
-# Don't run fixproto
-STMP_FIXPROTO =
diff --git a/contrib/gcc/config/i386/t-interix b/contrib/gcc/config/i386/t-interix
index 710de8b..d5fff61 100644
--- a/contrib/gcc/config/i386/t-interix
+++ b/contrib/gcc/config/i386/t-interix
@@ -1,6 +1,7 @@
LIB1ASMSRC = i386/cygwin.asm
LIB1ASMFUNCS = _chkstk
-winnt.o: $(srcdir)/config/i386/winnt.c $(TM_P_H)
+winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
+ $(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c
-
diff --git a/contrib/gcc/config/i386/t-nto b/contrib/gcc/config/i386/t-nto
new file mode 100644
index 0000000..b80ff80
--- /dev/null
+++ b/contrib/gcc/config/i386/t-nto
@@ -0,0 +1,4 @@
+CRTSTUFF_T_CFLAGS = -fno-omit-frame-pointer -fPIC
+TARGET_LIBGCC2_CFLAGS = -fPIC -fexceptions
+
+EXTRA_PARTS = crtbegin.o
diff --git a/contrib/gcc/config/i386/t-sco5 b/contrib/gcc/config/i386/t-sco5
index f92a624..c615593 100644
--- a/contrib/gcc/config/i386/t-sco5
+++ b/contrib/gcc/config/i386/t-sco5
@@ -5,7 +5,6 @@ CRTSTUFF_T_CFLAGS = -fPIC -fno-omit-frame-pointer
MULTILIB_OPTIONS = fPIC
MULTILIB_DIRNAMES = pic
-MUTLILIB_EXCEPTIONS =
MULTILIB_MATCHES = fPIC=fpic
MULTILIB_EXTRA_OPTS =
diff --git a/contrib/gcc/config/i386/t-vxworks b/contrib/gcc/config/i386/t-vxworks
new file mode 100644
index 0000000..6093995
--- /dev/null
+++ b/contrib/gcc/config/i386/t-vxworks
@@ -0,0 +1,8 @@
+# Multilibs for VxWorks.
+
+#GCC does not have an arch=pentium3 setting, so we cannot build PENTIUM3gnu
+MULTILIB_OPTIONS = \
+ march=i486/march=pentium/march=pentiumpro/march=pentium4
+MULTILIB_DIRNAMES = \
+ I80486 PENTIUMgnu PENTIUM2gnu PENTIUM4gnu
+
diff --git a/contrib/gcc/config/i386/unix.h b/contrib/gcc/config/i386/unix.h
index e69f26d..102afe0 100644
--- a/contrib/gcc/config/i386/unix.h
+++ b/contrib/gcc/config/i386/unix.h
@@ -1,20 +1,20 @@
/* Definitions for Unix assembler syntax for the Intel 80386.
Copyright (C) 1988, 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -22,8 +22,6 @@ Boston, MA 02111-1307, USA. */
that are the same for all the i386 Unix systems
(though they may differ in non-Unix systems). */
-#define DEFAULT_ASSEMBLER_DIALECT 0
-
/* Define macro used to output shift-double opcodes when the shift
count is in %cl. Some assemblers require %cl as an argument;
some don't. This macro controls what to do: by default, don't
diff --git a/contrib/gcc/config/i386/uwin.h b/contrib/gcc/config/i386/uwin.h
index 1210510..d2553c9 100644
--- a/contrib/gcc/config/i386/uwin.h
+++ b/contrib/gcc/config/i386/uwin.h
@@ -2,23 +2,23 @@
hosting on U/WIN (Windows32), using GNU tools and the Windows32 API
Library, as distinct from winnt.h, which is used to build GCC for use
with a windows style library and tool set and uses the Microsoft tools.
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -92,7 +92,3 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_EXTERNAL
#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-/* Override Cygwin's definition. This is necessary now due to the way
- Cygwin profiling code is written. Once "fixed", we can remove this. */
-#undef SUBTARGET_PROLOGUE
-
diff --git a/contrib/gcc/config/i386/vsta.h b/contrib/gcc/config/i386/vsta.h
index 9388329..f9c4710 100644
--- a/contrib/gcc/config/i386/vsta.h
+++ b/contrib/gcc/config/i386/vsta.h
@@ -2,20 +2,20 @@
Copyright (C) 1994, 2002 Free Software Foundation, Inc.
Contributed by Rob Savoye (rob@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/vxworks.h b/contrib/gcc/config/i386/vxworks.h
new file mode 100644
index 0000000..5ded098
--- /dev/null
+++ b/contrib/gcc/config/i386/vxworks.h
@@ -0,0 +1,74 @@
+/* Definitions of target machine for GCC. VxWorks i586 version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#define HANDLE_SYSV_PRAGMA 1
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (80586, VxWorks syntax)");
+
+/* Prefix for internally generated assembler labels. If we aren't using
+ underscores, we are using prefix `.'s to identify labels that should
+ be ignored, as in `i386/gas.h' --karl@cs.umb.edu */
+
+#define LPREFIX "L"
+
+/* Assembler pseudos to introduce constants of various size. */
+
+#define ASM_SHORT "\t.word\t"
+#define ASM_LONG "\t.long\t"
+#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */
+
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG)!=0) fprintf ((FILE), "\t.balign %d\n", 1<<(LOG))
+
+#undef ASM_SPEC
+#define ASM_SPEC "%{v:-V} %{Qy:} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
+
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__vxworks"); \
+ builtin_assert ("system=unix"); \
+ \
+ if (TARGET_386) \
+ builtin_define ("CPU=I80386"); \
+ else if (TARGET_486) \
+ builtin_define ("CPU=I80486"); \
+ else if (TARGET_PENTIUM) \
+ { \
+ builtin_define ("CPU=PENTIUM"); \
+ builtin_define ("CPU_VARIANT=PENTIUM"); \
+ } \
+ else if (TARGET_PENTIUMPRO) \
+ { \
+ builtin_define ("CPU=PENTIUM2"); \
+ builtin_define ("CPU_VARIANT=PENTIUMPRO"); \
+ } \
+ else if (TARGET_PENTIUM4) \
+ { \
+ builtin_define ("CPU=PENTIUM4"); \
+ builtin_define ("CPU_VARIANT=PENTIUM4"); \
+ } \
+ } \
+ while (0)
+
+
diff --git a/contrib/gcc/config/i386/winnt.c b/contrib/gcc/config/i386/winnt.c
index 01493a2..f8621b4 100644
--- a/contrib/gcc/config/i386/winnt.c
+++ b/contrib/gcc/config/i386/winnt.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for Windows NT.
Contributed by Douglas Rupp (drupp@cs.washington.edu)
- Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -44,22 +46,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
multiple times.
*/
-static tree associated_type PARAMS ((tree));
-const char * gen_stdcall_suffix PARAMS ((tree));
-int i386_pe_dllexport_p PARAMS ((tree));
-int i386_pe_dllimport_p PARAMS ((tree));
-void i386_pe_mark_dllexport PARAMS ((tree));
-void i386_pe_mark_dllimport PARAMS ((tree));
+static tree associated_type (tree);
+static const char * gen_stdcall_suffix (tree);
+static const char * gen_fastcall_suffix (tree);
+static int i386_pe_dllexport_p (tree);
+static int i386_pe_dllimport_p (tree);
+static void i386_pe_mark_dllexport (tree);
+static void i386_pe_mark_dllimport (tree);
+
+/* This is we how mark internal identifiers with dllimport or dllexport
+ attributes. */
+#ifndef DLL_IMPORT_PREFIX
+#define DLL_IMPORT_PREFIX "#i."
+#endif
+#ifndef DLL_EXPORT_PREFIX
+#define DLL_EXPORT_PREFIX "#e."
+#endif
/* Handle a "dllimport" or "dllexport" attribute;
arguments as in struct attribute_spec.handler. */
tree
-ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
- tree * pnode;
- tree name;
- tree args;
- int flags;
- bool *no_add_attrs;
+ix86_handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
+ bool *no_add_attrs)
{
tree node = *pnode;
@@ -93,7 +101,7 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node)
&& !DECL_INLINE (node))
{
- error_with_decl (node, "function `%s' definition is marked dllimport.");
+ error ("%Jfunction `%D' definition is marked dllimport.", node, node);
*no_add_attrs = true;
}
@@ -101,27 +109,28 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
{
if (DECL_INITIAL (node))
{
- error_with_decl (node,"variable `%s' definition is marked dllimport.");
+ error ("%Jvariable `%D' definition is marked dllimport.",
+ node, node);
*no_add_attrs = true;
}
/* `extern' needn't be specified with dllimport.
Specify `extern' now and hope for the best. Sigh. */
- DECL_EXTERNAL (node) = 1;
+ DECL_EXTERNAL (node) = 1;
/* Also, implicitly give dllimport'd variables declared within
a function global scope, unless declared static. */
if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
- TREE_PUBLIC (node) = 1;
+ TREE_PUBLIC (node) = 1;
}
}
- /* Report error if symbol is not accessible at global scope. */
+ /* Report error if symbol is not accessible at global scope. */
if (!TREE_PUBLIC (node)
&& (TREE_CODE (node) == VAR_DECL
- || TREE_CODE (node) == FUNCTION_DECL))
+ || TREE_CODE (node) == FUNCTION_DECL))
{
- error_with_decl (node, "external linkage required for symbol '%s' because of '%s' attribute.",
- IDENTIFIER_POINTER (name));
+ error ("%Jexternal linkage required for symbol '%D' because of "
+ "'%s' attribute.", node, node, IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
@@ -131,12 +140,9 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
/* Handle a "shared" attribute;
arguments as in struct attribute_spec.handler. */
tree
-ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+ix86_handle_shared_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != VAR_DECL)
{
@@ -152,8 +158,7 @@ ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
imported or exported. */
static tree
-associated_type (decl)
- tree decl;
+associated_type (tree decl)
{
tree t = NULL_TREE;
@@ -161,10 +166,13 @@ associated_type (decl)
to the containing class. So we look at the 'this' arg. */
if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
{
- /* Artificial methods are not affected by the import/export status of
- their class unless they are virtual. */
- if (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))
- t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
+ /* Artificial methods are not affected by the import/export status
+ of their class unless they are COMDAT. Implicit copy ctor's and
+ dtor's are not affected by class status but virtual and
+ non-virtual thunks are. */
+ if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl))
+ t = TYPE_MAIN_VARIANT
+ (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
}
else if (DECL_CONTEXT (decl)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
@@ -175,9 +183,8 @@ associated_type (decl)
/* Return nonzero if DECL is a dllexport'd object. */
-int
-i386_pe_dllexport_p (decl)
- tree decl;
+static int
+i386_pe_dllexport_p (tree decl)
{
tree exp;
@@ -202,9 +209,8 @@ i386_pe_dllexport_p (decl)
/* Return nonzero if DECL is a dllimport'd object. */
-int
-i386_pe_dllimport_p (decl)
- tree decl;
+static int
+i386_pe_dllimport_p (tree decl)
{
tree imp;
int context_imp = 0;
@@ -239,17 +245,19 @@ i386_pe_dllimport_p (decl)
{
/* Don't warn about artificial methods. */
if (!DECL_ARTIFICIAL (decl))
- warning_with_decl (decl,"function '%s' is defined after prior declaration as dllimport: attribute ignored.");
+ warning ("%Jfunction '%D' is defined after prior declaration "
+ "as dllimport: attribute ignored", decl, decl);
return 0;
}
/* We ignore the dllimport attribute for inline member functions.
- This differs from MSVC behaviour which treats it like GNUC
- 'extern inline' extension. */
+ This differs from MSVC behavior which treats it like GNUC
+ 'extern inline' extension. */
else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
{
if (extra_warnings)
- warning_with_decl (decl, "inline function '%s' is declared as dllimport: attribute ignored.");
+ warning ("%Jinline function '%D' is declared as dllimport: "
+ "attribute ignored.", decl, decl);
return 0;
}
@@ -260,16 +268,19 @@ i386_pe_dllimport_p (decl)
&& !DECL_EXTERNAL (decl) && context_imp)
{
if (!DECL_VIRTUAL_P (decl))
- error_with_decl (decl, "definition of static data member '%s' of dllimport'd class.");
- return 0;
+ error ("%Jdefinition of static data member '%D' of "
+ "dllimport'd class.", decl, decl);
+ return 0;
}
/* Since we can't treat a pointer to a dllimport'd symbol as a
constant address, we turn off the attribute on C++ virtual
- methods to allow creation of vtables using thunks. */
+ methods to allow creation of vtables using thunks. Don't mark
+ artificial methods either (in associated_type, only COMDAT
+ artificial method get import status from class context). */
else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
- && (DECL_VIRTUAL_P (decl)))
- return 0;
+ && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
+ return 0;
return 1;
}
@@ -280,29 +291,26 @@ i386_pe_dllimport_p (decl)
/* Return nonzero if SYMBOL is marked as being dllexport'd. */
int
-i386_pe_dllexport_name_p (symbol)
- const char *symbol;
+i386_pe_dllexport_name_p (const char *symbol)
{
- return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
- && symbol[1] == 'e' && symbol[2] == '.';
+ return (strncmp (DLL_EXPORT_PREFIX, symbol,
+ strlen (DLL_EXPORT_PREFIX)) == 0);
}
/* Return nonzero if SYMBOL is marked as being dllimport'd. */
int
-i386_pe_dllimport_name_p (symbol)
- const char *symbol;
+i386_pe_dllimport_name_p (const char *symbol)
{
- return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
- && symbol[1] == 'i' && symbol[2] == '.';
+ return (strncmp (DLL_IMPORT_PREFIX, symbol,
+ strlen (DLL_IMPORT_PREFIX)) == 0);
}
/* Mark a DECL as being dllexport'd.
Note that we override the previous setting (eg: dllimport). */
-void
-i386_pe_mark_dllexport (decl)
- tree decl;
+static void
+i386_pe_mark_dllexport (tree decl)
{
const char *oldname;
char *newname;
@@ -319,16 +327,17 @@ i386_pe_mark_dllexport (decl)
abort ();
if (i386_pe_dllimport_name_p (oldname))
{
- warning_with_decl (decl,"inconsistent dll linkage for '%s': dllexport assumed.");
+ warning ("%Jinconsistent dll linkage for '%D', dllexport assumed.",
+ decl, decl);
/* Remove DLL_IMPORT_PREFIX. */
- oldname += 9;
+ oldname += strlen (DLL_IMPORT_PREFIX);
DECL_NON_ADDR_CONST_P (decl) = 0;
}
else if (i386_pe_dllexport_name_p (oldname))
- return; /* already done */
+ return; /* already done */
- newname = alloca (strlen (oldname) + 4);
- sprintf (newname, "%ce.%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
+ newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
+ sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
@@ -342,9 +351,8 @@ i386_pe_mark_dllexport (decl)
/* Mark a DECL as being dllimport'd. */
-void
-i386_pe_mark_dllimport (decl)
- tree decl;
+static void
+i386_pe_mark_dllimport (tree decl)
{
const char *oldname;
char *newname;
@@ -367,17 +375,18 @@ i386_pe_mark_dllimport (decl)
}
else if (i386_pe_dllimport_name_p (oldname))
{
- /* Already done, but do a sanity check to prevent assembler errors. */
+ /* Already done, but do a sanity check to prevent assembler errors. */
if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
{
- error_with_decl (decl, "failure in redeclaration of '%s': dllimport'd symbol lacks external linkage.");
+ error ("%Jfailure in redeclaration of '%D': dllimport'd "
+ "symbol lacks external linkage.", decl, decl);
abort();
}
- return;
+ return;
}
- newname = alloca (strlen (oldname) + 11);
- sprintf (newname, "%ci._imp__%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
+ newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
+ sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
@@ -394,13 +403,51 @@ i386_pe_mark_dllimport (decl)
DECL_NON_ADDR_CONST_P (decl) = 1;
}
-/* Return string which is the former assembler name modified with a
- suffix consisting of an atsign (@) followed by the number of bytes of
+/* Return string which is the former assembler name modified with a
+ prefix consisting of FASTCALL_PREFIX and a suffix consisting of an
+ atsign (@) followed by the number of bytes of arguments. */
+
+static const char *
+gen_fastcall_suffix (tree decl)
+{
+ int total = 0;
+ const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ char *newsym;
+
+ if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ == void_type_node)
+ {
+ tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
+
+ /* Quit if we hit an incomplete type. Error is reported
+ by convert_arguments in c-typeck.c or cp/typeck.c. */
+ while (TREE_VALUE (formal_type) != void_type_node
+ && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
+ {
+ int parm_size
+ = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
+ /* Must round up to include padding. This is done the same
+ way as in store_one_arg. */
+ parm_size = ((parm_size + PARM_BOUNDARY - 1)
+ / PARM_BOUNDARY * PARM_BOUNDARY);
+ total += parm_size;
+ formal_type = TREE_CHAIN (formal_type);
+ }
+ }
+
+ /* Assume max of 8 base 10 digits in the suffix. */
+ newsym = xmalloc (1 + strlen (asmname) + 1 + 8 + 1);
+ sprintf (newsym, "%c%s@%d", FASTCALL_PREFIX, asmname, total/BITS_PER_UNIT);
+ return IDENTIFIER_POINTER (get_identifier (newsym));
+}
+
+/* Return string which is the former assembler name modified with a
+ suffix consisting of an atsign (@) followed by the number of bytes of
arguments */
-const char *
-gen_stdcall_suffix (decl)
- tree decl;
+static const char *
+gen_stdcall_suffix (tree decl)
{
int total = 0;
/* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
@@ -409,12 +456,15 @@ gen_stdcall_suffix (decl)
char *newsym;
if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
- if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
== void_type_node)
{
tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
- while (TREE_VALUE (formal_type) != void_type_node)
+ /* Quit if we hit an incomplete type. Error is reported
+ by convert_arguments in c-typeck.c or cp/typeck.c. */
+ while (TREE_VALUE (formal_type) != void_type_node
+ && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
{
int parm_size
= TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
@@ -427,30 +477,28 @@ gen_stdcall_suffix (decl)
}
}
- newsym = xmalloc (strlen (asmname) + 10);
+ /* Assume max of 8 base 10 digits in the suffix. */
+ newsym = xmalloc (strlen (asmname) + 1 + 8 + 1);
sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
return IDENTIFIER_POINTER (get_identifier (newsym));
}
void
-i386_pe_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
- /* This bit is copied from i386.h. */
- if (optimize > 0 && TREE_CONSTANT (decl)
- && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
- {
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
- }
+ default_encode_section_info (decl, rtl, first);
if (TREE_CODE (decl) == FUNCTION_DECL)
- if (lookup_attribute ("stdcall",
- TYPE_ATTRIBUTES (TREE_TYPE (decl))))
- XEXP (DECL_RTL (decl), 0) =
- gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
+ {
+ if (lookup_attribute ("stdcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ XEXP (DECL_RTL (decl), 0) =
+ gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
+ else if (lookup_attribute ("fastcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ XEXP (DECL_RTL (decl), 0) =
+ gen_rtx (SYMBOL_REF, Pmode, gen_fastcall_suffix (decl));
+ }
/* Mark the decl so we can tell from the rtl whether the object is
dllexport'd or dllimport'd. This also handles dllexport/dllimport
@@ -462,8 +510,8 @@ i386_pe_encode_section_info (decl, first)
i386_pe_mark_dllimport (decl);
/* It might be that DECL has already been marked as dllimport, but a
subsequent definition nullified that. The attribute is gone but
- DECL_RTL still has (DLL_IMPORT_EXPORT_PREFIX)i._imp__foo. We need
- to remove that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
+ DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
+ that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
else if ((TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& DECL_RTL (decl) != NULL_RTX
@@ -473,12 +521,17 @@ i386_pe_encode_section_info (decl, first)
&& i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
{
const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
- tree idp = get_identifier (oldname + 9);
+
+ /* Remove DLL_IMPORT_PREFIX. */
+ tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
- warning_with_decl (decl, "'%s' %s after being referenced with dllimport linkage.",
- (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
- ? "defined locally" : "redeclared without dllimport attribute");
+ if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
+ warning ("%J'%D' defined locally after being "
+ "referenced with dllimport linkage", decl, decl);
+ else
+ warning ("%J'%D' redeclared without dllimport attribute "
+ "after being referenced with dllimport linkage", decl, decl);
XEXP (DECL_RTL (decl), 0) = newrtl;
@@ -489,14 +542,18 @@ i386_pe_encode_section_info (decl, first)
}
}
-/* Strip only the leading encoding, leaving the stdcall suffix. */
+/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
+ prefix if it exists. */
const char *
-i386_pe_strip_name_encoding (str)
- const char *str;
+i386_pe_strip_name_encoding (const char *str)
{
- if (*str == DLL_IMPORT_EXPORT_PREFIX)
- str += 3;
+ if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
+ == 0)
+ str += strlen (DLL_IMPORT_PREFIX);
+ else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
+ == 0)
+ str += strlen (DLL_EXPORT_PREFIX);
if (*str == '*')
str += 1;
return str;
@@ -505,12 +562,11 @@ i386_pe_strip_name_encoding (str)
/* Also strip the stdcall suffix. */
const char *
-i386_pe_strip_name_encoding_full (str)
- const char *str;
+i386_pe_strip_name_encoding_full (const char *str)
{
const char *p;
const char *name = i386_pe_strip_name_encoding (str);
-
+
p = strchr (name, '@');
if (p)
return ggc_alloc_string (name, p - name);
@@ -518,10 +574,48 @@ i386_pe_strip_name_encoding_full (str)
return name;
}
+/* Output a reference to a label. Fastcall symbols are prefixed with @,
+ whereas symbols for functions using other calling conventions don't
+ have a prefix (unless they are marked dllimport or dllexport). */
+
+void i386_pe_output_labelref (FILE *stream, const char *name)
+{
+ if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
+ == 0)
+ /* A dll import */
+ {
+ if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
+ /* A dllimport fastcall symbol. */
+ {
+ fprintf (stream, "__imp_%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ else
+ /* A dllimport non-fastcall symbol. */
+ {
+ fprintf (stream, "__imp__%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ }
+ else if ((name[0] == FASTCALL_PREFIX)
+ || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX)
+ == 0
+ && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX)))
+ /* A fastcall symbol. */
+ {
+ fprintf (stream, "%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ else
+ /* Everything else. */
+ {
+ fprintf (stream, "%s%s", USER_LABEL_PREFIX,
+ i386_pe_strip_name_encoding (name));
+ }
+}
+
void
-i386_pe_unique_section (decl, reloc)
- tree decl;
- int reloc;
+i386_pe_unique_section (tree decl, int reloc)
{
int len;
const char *name, *prefix;
@@ -533,7 +627,7 @@ i386_pe_unique_section (decl, reloc)
/* The object is put in, for example, section .text$foo.
The linker will then ultimately place them in .text
(everything from the $ on is stripped). Don't put
- read-only data in .rdata section to avoid a PE linker
+ read-only data in .rdata section to avoid a PE linker
bug when .rdata$* grouped sections are used in code
without a .rdata section. */
if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -559,7 +653,7 @@ i386_pe_unique_section (decl, reloc)
If the section has already been defined, to not allow it to have
different attributes, as (1) this is ambiguous since we're not seeing
all the declarations up front and (2) some assemblers (e.g. SVR4)
- do not recoginize section redefinitions. */
+ do not recognize section redefinitions. */
/* ??? This differs from the "standard" PE implementation in that we
handle the SHARED variable attribute. Should this be done for all
PE targets? */
@@ -567,10 +661,7 @@ i386_pe_unique_section (decl, reloc)
#define SECTION_PE_SHARED SECTION_MACH_DEP
unsigned int
-i386_pe_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+i386_pe_section_type_flags (tree decl, const char *name, int reloc)
{
static htab_t htab;
unsigned int flags;
@@ -608,25 +699,33 @@ i386_pe_section_type_flags (decl, name, reloc)
else
{
if (decl && **slot != flags)
- error_with_decl (decl, "%s causes a section type conflict");
+ error ("%J'%D' causes a section type conflict", decl, decl);
}
return flags;
}
void
-i386_pe_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+i386_pe_asm_named_section (const char *name, unsigned int flags)
{
char flagchars[8], *f = flagchars;
- if (flags & SECTION_CODE)
- *f++ = 'x';
- if (flags & SECTION_WRITE)
- *f++ = 'w';
- if (flags & SECTION_PE_SHARED)
- *f++ = 's';
+ if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
+ /* readonly data */
+ {
+ *f++ ='d'; /* This is necessary for older versions of gas. */
+ *f++ ='r';
+ }
+ else
+ {
+ if (flags & SECTION_CODE)
+ *f++ = 'x';
+ if (flags & SECTION_WRITE)
+ *f++ = 'w';
+ if (flags & SECTION_PE_SHARED)
+ *f++ = 's';
+ }
+
*f = '\0';
fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
@@ -654,10 +753,7 @@ i386_pe_asm_named_section (name, flags)
visible. */
void
-i386_pe_declare_function_type (file, name, public)
- FILE *file;
- const char *name;
- int public;
+i386_pe_declare_function_type (FILE *file, const char *name, int public)
{
fprintf (file, "\t.def\t");
assemble_name (file, name);
@@ -683,8 +779,7 @@ static struct extern_list *extern_head;
for it then. */
void
-i386_pe_record_external_function (name)
- const char *name;
+i386_pe_record_external_function (const char *name)
{
struct extern_list *p;
@@ -708,13 +803,11 @@ static struct export_list *export_head;
/* Assemble an export symbol entry. We need to keep a list of
these, so that we can output the export list at the end of the
assembly. We used to output these export symbols in each function,
- but that causes problems with GNU ld when the sections are
+ but that causes problems with GNU ld when the sections are
linkonce. */
void
-i386_pe_record_exported_symbol (name, is_data)
- const char *name;
- int is_data;
+i386_pe_record_exported_symbol (const char *name, int is_data)
{
struct export_list *p;
@@ -730,12 +823,11 @@ i386_pe_record_exported_symbol (name, is_data)
output the .drectve section. */
void
-i386_pe_asm_file_end (file)
- FILE *file;
+i386_pe_file_end (void)
{
struct extern_list *p;
- ix86_asm_file_end (file);
+ ix86_file_end ();
for (p = extern_head; p != NULL; p = p->next)
{
@@ -747,7 +839,8 @@ i386_pe_asm_file_end (file)
if (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl))
{
TREE_ASM_WRITTEN (decl) = 1;
- i386_pe_declare_function_type (file, p->name, TREE_PUBLIC (decl));
+ i386_pe_declare_function_type (asm_out_file, p->name,
+ TREE_PUBLIC (decl));
}
}
@@ -757,7 +850,7 @@ i386_pe_asm_file_end (file)
drectve_section ();
for (q = export_head; q != NULL; q = q->next)
{
- fprintf (file, "\t.ascii \" -export:%s%s\"\n",
+ fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
i386_pe_strip_name_encoding (q->name),
(q->is_data) ? ",data" : "");
}
diff --git a/contrib/gcc/config/i386/x-mingw32 b/contrib/gcc/config/i386/x-mingw32
new file mode 100644
index 0000000..04593aa
--- /dev/null
+++ b/contrib/gcc/config/i386/x-mingw32
@@ -0,0 +1,4 @@
+#
+# Make local_includedir relative to EXEC_PREFIX
+#
+local_includedir=$(libsubdir)/$(unlibsubdir)/..`echo $(exec_prefix) | sed -e 's|^$(prefix)||' -e 's|/[^/]*|/..|g'`/include
diff --git a/contrib/gcc/config/i386/xm-cygwin.h b/contrib/gcc/config/i386/xm-cygwin.h
index 721c435..1ecb00c 100644
--- a/contrib/gcc/config/i386/xm-cygwin.h
+++ b/contrib/gcc/config/i386/xm-cygwin.h
@@ -1,35 +1,22 @@
-/* Configuration for GNU C-compiler for hosting on Windows NT.
+/* Configuration for GCC for hosting on Windows NT.
using a unix style C library.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define HOST_EXECUTABLE_SUFFIX ".exe"
-
-/* Even though Cygwin tries to hide the DOS based filesystem, it
- still shows though at times. */
-#define HAVE_DOS_BASED_FILE_SYSTEM
-
-/* We support both "/" and "\" since everybody tests both but we
- default to "/". This is important because if gcc produces Win32
- paths containing backslashes, make and configure may treat the
- backslashes as escape characters. Many Win32 programs use forward
- slashes so using a forward slash shouldn't be problematic from the
- perspective of wanting gcc to produce native Win32 paths. */
-#undef DIR_SEPARATOR_2
-#define DIR_SEPARATOR_2 '\\'
diff --git a/contrib/gcc/config/i386/xm-djgpp.h b/contrib/gcc/config/i386/xm-djgpp.h
index 71cb116..9bb520d 100644
--- a/contrib/gcc/config/i386/xm-djgpp.h
+++ b/contrib/gcc/config/i386/xm-djgpp.h
@@ -1,20 +1,20 @@
-/* Configuration for GNU C-compiler for Intel 80386 running DJGPP.
+/* Configuration for GCC for Intel 80386 running DJGPP.
Copyright (C) 1988, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,13 +23,6 @@ Boston, MA 02111-1307, USA. */
#define HOST_EXECUTABLE_SUFFIX ".exe"
-/* Even though we support "/", allow "\" since everybody tests both. */
-#define DIR_SEPARATOR '/'
-#define DIR_SEPARATOR_2 '\\'
-
-/* Allow test for DOS drive names. */
-#define HAVE_DOS_BASED_FILE_SYSTEM
-
/* System dependent initialization for collect2
to tell system() to act like Unix. */
#define COLLECT2_HOST_INITIALIZATION \
@@ -50,9 +43,6 @@ Boston, MA 02111-1307, USA. */
strcat (xref_file, xref_ext); \
} while (0)
-/* Change /dev/env/DJDIR/prefix/dir/ to canonical form so gcc_exec_prefix
- is set properly in 'gcc.c'. It also helps to cut down the number of times
- the value of the DJGPP environment variable 'DJDIR' is evaluated. */
#undef GCC_DRIVER_HOST_INITIALIZATION
#define GCC_DRIVER_HOST_INITIALIZATION \
do { \
@@ -76,9 +66,6 @@ Boston, MA 02111-1307, USA. */
fatal ("environment variable DJGPP points to corrupt file '%s'", \
djgpp); \
} \
- standard_exec_prefix = update_path (standard_exec_prefix, NULL); \
- standard_bindir_prefix = update_path (standard_bindir_prefix, NULL); \
- standard_startfile_prefix = update_path (standard_startfile_prefix, NULL); \
} while (0)
/* Canonicalize paths containing '/dev/env/'; used in prefix.c.
diff --git a/contrib/gcc/config/i386/xm-mingw32.h b/contrib/gcc/config/i386/xm-mingw32.h
index 19b102d..8881966 100644
--- a/contrib/gcc/config/i386/xm-mingw32.h
+++ b/contrib/gcc/config/i386/xm-mingw32.h
@@ -1,33 +1,29 @@
-/* Configuration for GNU C-compiler for hosting on Windows32.
+/* Configuration for GCC for hosting on Windows32.
using GNU tools and the Windows32 API Library.
- Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* Even though we support "/", allow "\" since everybody tests both. */
-#define DIR_SEPARATOR '\\'
-#define DIR_SEPARATOR_2 '/'
-
-/* Mingw32 does not try to hide the underlying DOS-based file system
- like Cygwin does. */
-#define HAVE_DOS_BASED_FILE_SYSTEM
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#define HOST_EXECUTABLE_SUFFIX ".exe"
#undef PATH_SEPARATOR
#define PATH_SEPARATOR ';'
+
+/* This is the name of the null device on windows. */
+#define HOST_BIT_BUCKET "nul"
diff --git a/contrib/gcc/config/i386/xmmintrin.h b/contrib/gcc/config/i386/xmmintrin.h
index 1829ab0..1bc8878 100644
--- a/contrib/gcc/config/i386/xmmintrin.h
+++ b/contrib/gcc/config/i386/xmmintrin.h
@@ -1,19 +1,19 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -37,12 +37,11 @@
/* We need type definitions from the MMX header file. */
#include <mmintrin.h>
-/* The data type indended for user use. */
+/* The data type intended for user use. */
typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
-/* Internal data types for implementing the instrinsics. */
+/* Internal data types for implementing the intrinsics. */
typedef int __v4sf __attribute__ ((__mode__(__V4SF__)));
-typedef int __v4si __attribute__ ((__mode__(__V4SI__)));
/* Create a selector for use with the SHUFPS instruction. */
#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \
@@ -890,19 +889,9 @@ _mm_set_ps1 (float __F)
/* Create the vector [Z Y X W]. */
static __inline __m128
-_mm_set_ps (float __Z, float __Y, float __X, float __W)
+_mm_set_ps (const float __Z, const float __Y, const float __X, const float __W)
{
- union {
- float __a[4];
- __m128 __v;
- } __u;
-
- __u.__a[0] = __W;
- __u.__a[1] = __X;
- __u.__a[2] = __Y;
- __u.__a[3] = __Z;
-
- return __u.__v;
+ return (__v4sf) {__W, __X, __Y, __Z};
}
/* Create the vector [W X Y Z]. */
@@ -1192,7 +1181,7 @@ _mm_stream_ps (float *__P, __m128 __A)
__builtin_ia32_movntps (__P, (__v4sf)__A);
}
-/* Guarantees that every preceeding store is globally visible before
+/* Guarantees that every preceding store is globally visible before
any subsequent store. */
static __inline void
_mm_sfence (void)
diff --git a/contrib/gcc/config/ia64/crtbegin.asm b/contrib/gcc/config/ia64/crtbegin.asm
index cb49e10..494def7 100644
--- a/contrib/gcc/config/ia64/crtbegin.asm
+++ b/contrib/gcc/config/ia64/crtbegin.asm
@@ -33,33 +33,34 @@ __DTOR_LIST__:
__JCR_LIST__:
.section .sdata
- .type dtor_ptr#,@object
- .size dtor_ptr#,8
+ .type dtor_ptr,@object
+ .size dtor_ptr,8
dtor_ptr:
- data8 @gprel(__DTOR_LIST__# + 8)
+ data8 @gprel(__DTOR_LIST__ + 8)
/* A handle for __cxa_finalize to manage c++ local destructors. */
- .global __dso_handle#
- .type __dso_handle#,@object
- .size __dso_handle#,8
+ .global __dso_handle
+ .type __dso_handle,@object
+ .size __dso_handle,8
#ifdef SHARED
.section .data
__dso_handle:
- data8 __dso_handle#
+ data8 __dso_handle
#else
.section .bss
+ .align 8
__dso_handle:
- data8 0
+ .skip 8
#endif
- .hidden __dso_handle#
+ .hidden __dso_handle
#ifdef HAVE_INITFINI_ARRAY
-.section .fini_array,"a","progbits"
+.section .fini_array, "a"
data8 @fptr(__do_global_dtors_aux)
-.section .init_array,"a","progbits"
+.section .init_array, "a"
data8 @fptr(__do_jv_register_classes)
data8 @fptr(__do_global_ctors_aux)
@@ -79,7 +80,7 @@ __dso_handle:
*/
.section .fini,"ax","progbits"
{ .mlx
- movl r2 = @pcrel(__do_global_dtors_aux# - 16)
+ movl r2 = @pcrel(__do_global_dtors_aux - 16)
}
{ .mii
mov r3 = ip
@@ -88,16 +89,16 @@ __dso_handle:
;;
}
{ .mib
+ nop 0
mov b6 = r2
br.call.sptk.many b0 = b6
- ;;
}
/* Likewise for _init. */
.section .init,"ax","progbits"
{ .mlx
- movl r2 = @pcrel(__do_jv_register_classes# - 16)
+ movl r2 = @pcrel(__do_jv_register_classes - 16)
}
{ .mii
mov r3 = ip
@@ -106,63 +107,64 @@ __dso_handle:
;;
}
{ .mib
+ nop 0
mov b6 = r2
br.call.sptk.many b0 = b6
- ;;
}
#endif /* !HAVE_INITFINI_ARRAY */
.section .text
- .align 16
- .proc __do_global_dtors_aux#
+ .align 32
+ .proc __do_global_dtors_aux
__do_global_dtors_aux:
+ .prologue
#ifndef SHARED
- { .mii
- alloc loc3 = ar.pfs, 0, 4, 1, 0
- addl loc0 = @gprel(dtor_ptr#), gp
- mov loc1 = b0
- }
- { .mib
- mov loc2 = gp
- br.sptk.few 1f
- ;;
- }
+ .save ar.pfs, r35
+ alloc loc3 = ar.pfs, 0, 4, 1, 0
+ addl loc0 = @gprel(dtor_ptr), gp
+ .save rp, loc1
+ mov loc1 = rp
+ .body
+
+ mov loc2 = gp
+ nop 0
+ br.sptk.many .entry
#else
/*
if (__cxa_finalize)
__cxa_finalize(__dso_handle)
*/
- { .mii
- alloc loc3 = ar.pfs, 0, 4, 1, 0
- addl loc0 = @gprel(dtor_ptr#), gp
- addl r16 = @ltoff(@fptr(__cxa_finalize#)), gp
- ;;
- }
- { .mmi
- ld8 r16 = [r16]
- ;;
- addl out0 = @ltoff(__dso_handle#), gp
- cmp.ne p7, p0 = r0, r16
- ;;
- }
- { .mmi
- ld8 out0 = [out0]
-(p7) ld8 r18 = [r16], 8
- mov loc1 = b0
- ;;
- }
- { .mfi
- mov loc2 = gp
-(p7) mov b6 = r18
- }
- {
- .mfb
-(p7) ld8 gp = [r16]
-(p7) br.call.sptk.many b0 = b6
- }
- { .mfb
- br.sptk.few 1f
- }
+ .save ar.pfs, r35
+ alloc loc3 = ar.pfs, 0, 4, 1, 0
+ addl loc0 = @gprel(dtor_ptr), gp
+ addl r16 = @ltoff(@fptr(__cxa_finalize)), gp
+ ;;
+
+ ld8 r16 = [r16]
+ ;;
+ addl out0 = @ltoff(__dso_handle), gp
+ cmp.ne p7, p0 = r0, r16
+ ;;
+
+ ld8 out0 = [out0]
+(p7) ld8 r18 = [r16], 8
+ .save rp, loc1
+ mov loc1 = rp
+ .body
+ ;;
+
+ mov loc2 = gp
+(p7) ld8 gp = [r16]
+(p7) mov b6 = r18
+
+ nop 0
+ nop 0
+(p7) br.call.sptk.many rp = b6
+ ;;
+
+ nop 0
+ nop 0
+ br.sptk.many .entry
#endif
/*
do {
@@ -170,90 +172,77 @@ __do_global_dtors_aux:
(*(dtor_ptr-1)) ();
} while (dtor_ptr);
*/
-0:
- { .mmi
- st8 [loc0] = r15
- ld8 r17 = [r16], 8
- ;;
- }
- { .mib
- ld8 gp = [r16]
- mov b6 = r17
- br.call.sptk.many b0 = b6
- }
-1:
- { .mmi
- ld8 r15 = [loc0]
- ;;
- add r16 = r15, loc2
- adds r15 = 8, r15
- ;;
- }
- { .mmi
- ld8 r16 = [r16]
- mov gp = loc2
- mov b0 = loc1
- ;;
- }
- { .mib
- cmp.ne p6, p0 = r0, r16
- mov ar.pfs = loc3
-(p6) br.cond.sptk.few 0b
- }
- { .bbb
- br.ret.sptk.many b0
- ;;
- }
- .endp __do_global_dtors_aux#
-
- .align 16
- .proc __do_jv_register_classes#
+.loop:
+ st8 [loc0] = r15 // update dtor_ptr (in memory)
+ ld8 r17 = [r16], 8 // r17 <- dtor's entry-point
+ nop 0
+ ;;
+
+ ld8 gp = [r16] // gp <- dtor's gp
+ mov b6 = r17
+ br.call.sptk.many rp = b6
+
+.entry: ld8 r15 = [loc0] // r15 <- dtor_ptr (gp-relative)
+ ;;
+ add r16 = r15, loc2 // r16 <- dtor_ptr (absolute)
+ adds r15 = 8, r15
+ ;;
+
+ ld8 r16 = [r16] // r16 <- pointer to dtor's fdesc
+ mov rp = loc1
+ mov ar.pfs = loc3
+ ;;
+
+ cmp.ne p6, p0 = r0, r16
+(p6) br.cond.sptk.few .loop
+ br.ret.sptk.many rp
+ .endp __do_global_dtors_aux
+
+ .align 32
+ .proc __do_jv_register_classes
__do_jv_register_classes:
- { .mlx
- alloc loc2 = ar.pfs, 0, 3, 1, 0
- movl out0 = @gprel(__JCR_LIST__)
- ;;
- }
- { .mmi
- addl r14 = @ltoff(@fptr(_Jv_RegisterClasses)), gp
- add out0 = out0, gp
- ;;
- }
- { .mmi
- ld8 r14 = [r14]
- ld8 r15 = [out0]
- cmp.ne p6, p0 = r0, r0
- ;;
- }
- { .mib
- cmp.eq.or p6, p0 = r0, r14
- cmp.eq.or p6, p0 = r0, r15
-(p6) br.ret.sptk.many b0
- }
- { .mii
- ld8 r15 = [r14], 8
- mov loc0 = b0
- mov loc1 = gp
- ;;
- }
- { .mib
- ld8 gp = [r14]
- mov b6 = r15
- br.call.sptk.many b0 = b6
- ;;
- }
- { .mii
- mov gp = loc1
- mov b0 = loc0
- mov ar.pfs = loc2
- }
- { .bbb
- br.ret.sptk.many b0
- ;;
- }
- .endp __do_jv_register_classes#
+ .prologue
+ .save ar.pfs, r33
+ alloc loc1 = ar.pfs, 0, 3, 1, 0
+ movl out0 = @gprel(__JCR_LIST__)
+ ;;
+
+ addl r14 = @ltoff(@fptr(_Jv_RegisterClasses)), gp
+ add out0 = out0, gp
+ .save rp, loc0
+ mov loc0 = rp
+ .body
+ ;;
+
+ ld8 r14 = [r14]
+ ld8 r15 = [out0]
+ cmp.ne p6, p0 = r0, r0
+ ;;
+
+ cmp.eq.or p6, p0 = r0, r14
+ cmp.eq.or p6, p0 = r0, r15
+(p6) br.ret.sptk.many rp
+
+ ld8 r15 = [r14], 8
+ ;;
+ nop 0
+ mov b6 = r15
+
+ mov loc2 = gp
+ ld8 gp = [r14]
+ br.call.sptk.many rp = b6
+ ;;
+
+ mov gp = loc2
+ mov rp = loc0
+ mov ar.pfs = loc1
+
+ nop 0
+ nop 0
+ br.ret.sptk.many rp
+ .endp __do_jv_register_classes
#ifdef SHARED
-.weak __cxa_finalize#
+.weak __cxa_finalize
#endif
.weak _Jv_RegisterClasses
diff --git a/contrib/gcc/config/ia64/crtend.asm b/contrib/gcc/config/ia64/crtend.asm
index 303f30c..8984d88 100644
--- a/contrib/gcc/config/ia64/crtend.asm
+++ b/contrib/gcc/config/ia64/crtend.asm
@@ -33,7 +33,10 @@ __DTOR_END__:
__JCR_END__:
data8 0
-#ifndef HAVE_INITFINI_ARRAY
+#ifdef HAVE_INITFINI_ARRAY
+ .global __do_global_ctors_aux
+ .hidden __do_global_ctors_aux
+#else /* !HAVE_INITFINI_ARRAY */
/*
* Fragment of the ELF _init routine that invokes our dtor cleanup.
*
@@ -49,7 +52,7 @@ __JCR_END__:
*/
.section .init,"ax","progbits"
{ .mlx
- movl r2 = @pcrel(__do_global_ctors_aux# - 16)
+ movl r2 = @pcrel(__do_global_ctors_aux - 16)
}
{ .mii
mov r3 = ip
@@ -65,63 +68,48 @@ __JCR_END__:
#endif /* !HAVE_INITFINI_ARRAY */
.text
- .align 16
-#ifdef HAVE_INITFINI_ARRAY
- /* This is referenced from crtbegin.o. */
- .globl __do_global_ctors_aux#
- .type __do_global_ctors_aux#,@function
- .hidden __do_global_ctors_aux#
-#endif
- .proc __do_global_ctors_aux#
+ .align 32
+ .proc __do_global_ctors_aux
__do_global_ctors_aux:
+ .prologue
/*
for (loc0 = __CTOR_END__-1; *p != -1; --p)
(*p) ();
*/
- { .mlx
- alloc loc4 = ar.pfs, 0, 5, 0, 0
- movl loc0 = @gprel(__CTOR_END__# - 8)
- ;;
- }
- { .mmi
- add loc0 = loc0, gp
- mov loc1 = b0
- ;;
- }
- {
- .mmi
- ld8 loc3 = [loc0], -8
- mov loc2 = gp
- ;;
- }
- { .mfb
- cmp.eq p6, p0 = -1, loc3
-(p6) br.cond.spnt.few 2f
- }
-0:
- { .mmi
- ld8 r15 = [loc3], 8
- ;;
- ld8 gp = [loc3]
- mov b6 = r15
- }
- { .mfb
- ld8 loc3 = [loc0], -8
- br.call.sptk.many b0 = b6
- ;;
- }
- { .mfb
- cmp.ne p6, p0 = -1, loc3
-(p6) br.cond.sptk.few 0b
- }
-2:
- { .mii
- mov gp = loc2
- mov b0 = loc1
- mov ar.pfs = loc4
- }
- { .bbb
- br.ret.sptk.many b0
- ;;
- }
- .endp __do_global_ctors_aux#
+ .save ar.pfs, r34
+ alloc loc2 = ar.pfs, 0, 5, 0, 0
+ movl loc0 = @gprel(__CTOR_END__ - 8)
+ ;;
+
+ add loc0 = loc0, gp
+ ;;
+ ld8 loc3 = [loc0], -8
+ .save rp, loc1
+ mov loc1 = rp
+ .body
+ ;;
+
+ cmp.eq p6, p0 = -1, loc3
+ mov loc4 = gp
+(p6) br.cond.spnt.few .exit
+
+.loop: ld8 r15 = [loc3], 8
+ ;;
+ ld8 gp = [loc3]
+ mov b6 = r15
+
+ ld8 loc3 = [loc0], -8
+ nop 0
+ br.call.sptk.many rp = b6
+ ;;
+
+ cmp.ne p6, p0 = -1, loc3
+ nop 0
+(p6) br.cond.sptk.few .loop
+
+.exit: mov gp = loc3
+ mov rp = loc1
+ mov ar.pfs = loc2
+
+ br.ret.sptk.many rp
+ .endp __do_global_ctors_aux
diff --git a/contrib/gcc/config/ia64/crti.asm b/contrib/gcc/config/ia64/crti.asm
index 4b94b7f..4b48e3d 100644
--- a/contrib/gcc/config/ia64/crti.asm
+++ b/contrib/gcc/config/ia64/crti.asm
@@ -1,11 +1,11 @@
# Copyright (C) 2000, 2001 Free Software Foundation, Inc.
# Written By Timothy Wall
-#
+#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
-#
+#
# In addition to the permissions in the GNU General Public License, the
# Free Software Foundation gives you unlimited permission to link the
# compiled version of this file with other programs, and to distribute
@@ -13,23 +13,23 @@
# file. (The General Public License restrictions do apply in other
# respects; for example, they cover modification of the file, and
# distribution when not linked into another program.)
-#
+#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-#
+#
# As a special exception, if you link this library with files
# compiled with GCC to produce an executable, this does not cause
# the resulting executable to be covered by the GNU General Public License.
# This exception does not however invalidate any other reasons why
# the executable file might be covered by the GNU General Public License.
-#
+#
# This file just make a stack frame for the contents of the .fini and
# .init sections. Users may put any desired instructions in those
@@ -39,7 +39,7 @@
.section ".init"
.align 16
- .global _init#
+ .global _init
_init:
.prologue 14, 33
.save ar.pfs, r34
@@ -49,10 +49,10 @@ _init:
.save rp, r33
mov r33 = b0
.body
-
+
.section ".fini"
.align 16
- .global _fini#
+ .global _fini
_fini:
.prologue 14, 33
.save ar.pfs, r34
@@ -62,5 +62,5 @@ _fini:
.save rp, r33
mov r33 = b0
.body
-
+
# end of crti.asm
diff --git a/contrib/gcc/config/ia64/crtn.asm b/contrib/gcc/config/ia64/crtn.asm
index 0b45d38..48a9a03 100644
--- a/contrib/gcc/config/ia64/crtn.asm
+++ b/contrib/gcc/config/ia64/crtn.asm
@@ -1,11 +1,11 @@
# Copyright (C) 2000, 2001 Free Software Foundation, Inc.
# Written By Timothy Wall
-#
+#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
-#
+#
# In addition to the permissions in the GNU General Public License, the
# Free Software Foundation gives you unlimited permission to link the
# compiled version of this file with other programs, and to distribute
@@ -13,23 +13,23 @@
# file. (The General Public License restrictions do apply in other
# respects; for example, they cover modification of the file, and
# distribution when not linked into another program.)
-#
+#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-#
+#
# As a special exception, if you link this library with files
# compiled with GCC to produce an executable, this does not cause
# the resulting executable to be covered by the GNU General Public License.
# This exception does not however invalidate any other reasons why
# the executable file might be covered by the GNU General Public License.
-#
+#
# This file just makes sure that the .fini and .init sections do in
# fact return. Users may put any desired instructions in those sections.
@@ -44,7 +44,7 @@
.restore sp
mov r12 = r35
br.ret.sptk.many b0
-
+
.section ".fini"
;;
mov ar.pfs = r34
diff --git a/contrib/gcc/config/ia64/elf.h b/contrib/gcc/config/ia64/elf.h
index e30090d..6886ea0 100644
--- a/contrib/gcc/config/ia64/elf.h
+++ b/contrib/gcc/config/ia64/elf.h
@@ -5,9 +5,9 @@
#define TARGET_VERSION fprintf (stderr, " (IA-64) ELF");
-/* A C string constant that tells the GNU CC driver program options to pass to
+/* A C string constant that tells the GCC driver program options to pass to
the assembler. It can also specify how to translate options you give to GNU
- CC into options for GNU CC to pass to the assembler. */
+ CC into options for GCC to pass to the assembler. */
#if ((TARGET_CPU_DEFAULT | TARGET_DEFAULT) & MASK_GNU_AS) != 0
/* GNU AS. */
@@ -22,9 +22,9 @@
%{mauto-pic:-M no_plabel}"
#endif
-/* A C string constant that tells the GNU CC driver program options to pass to
- the linker. It can also specify how to translate options you give to GNU CC
- into options for GNU CC to pass to the linker. */
+/* A C string constant that tells the GCC driver program options to pass to
+ the linker. It can also specify how to translate options you give to GCC
+ into options for GCC to pass to the linker. */
/* The Intel linker does not support dynamic linking, so we need -dn.
The Intel linker gives annoying messages unless -N so is used. */
diff --git a/contrib/gcc/config/ia64/fde-glibc.c b/contrib/gcc/config/ia64/fde-glibc.c
index 83cc93a..15e1927 100644
--- a/contrib/gcc/config/ia64/fde-glibc.c
+++ b/contrib/gcc/config/ia64/fde-glibc.c
@@ -1,20 +1,20 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@cygnus.com>.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -29,7 +29,7 @@
to avoid register/deregister calls at DSO load/unload. */
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include "config.h"
#include <stddef.h>
@@ -121,7 +121,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
if (p_dynamic)
{
- /* For dynamicly linked executables and shared libraries,
+ /* For dynamically linked executables and shared libraries,
DT_PLTGOT is the gp value for that object. */
Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base);
for (; dyn->d_tag != DT_NULL ; dyn++)
diff --git a/contrib/gcc/config/ia64/freebsd.h b/contrib/gcc/config/ia64/freebsd.h
index 34dc885..d5977ff 100644
--- a/contrib/gcc/config/ia64/freebsd.h
+++ b/contrib/gcc/config/ia64/freebsd.h
@@ -1,26 +1,29 @@
/* Definitions for Intel IA-64 running FreeBSD using the ELF format
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
-#define LINK_SPEC \
- "%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
+#define LINK_SPEC " \
+ %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
@@ -28,7 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
%{static:-Bstatic}}"
diff --git a/contrib/gcc/config/ia64/hpux.h b/contrib/gcc/config/ia64/hpux.h
index 90303ea..f76cbd2 100644
--- a/contrib/gcc/config/ia64/hpux.h
+++ b/contrib/gcc/config/ia64/hpux.h
@@ -1,22 +1,22 @@
/* Definitions of target machine GNU compiler. IA-64 version.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Steve Ellcey <sje@cup.hp.com> and
Reva Cuthbertson <reva@cup.hp.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,10 +25,11 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fprintf (stderr, " (IA-64) HP-UX");
+/* Enable HPUX ABI quirks. */
+#undef TARGET_HPUX
+#define TARGET_HPUX 1
+
/* Target OS builtins. */
-/* -D__fpreg=long double is needed to compensate for
- the lack of __fpreg which is a primative type in
- HP C but does not exist in GNU C. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_assert("system=hpux"); \
@@ -38,15 +39,16 @@ do { \
builtin_define_std("unix"); \
builtin_define("__IA64__"); \
builtin_define("_LONGLONG"); \
+ builtin_define("_INCLUDE_LONGLONG"); \
builtin_define("_UINT128_T"); \
- builtin_define("__fpreg=long double"); \
- builtin_define("__float80=long double"); \
- builtin_define("__float128=long double"); \
- if (c_language == clk_cplusplus || !flag_iso) \
+ if (c_dialect_cxx () || !flag_iso) \
{ \
builtin_define("_HPUX_SOURCE"); \
builtin_define("__STDC_EXT__"); \
+ builtin_define("__STDCPP__"); \
} \
+ if (TARGET_ILP32) \
+ builtin_define("_ILP32"); \
} while (0)
#undef CPP_SPEC
@@ -85,7 +87,7 @@ do { \
#ifndef CROSS_COMPILE
#undef LIBGCC_SPEC
#define LIBGCC_SPEC \
- "%{shared-libgcc:%{!mlp64:-lgcc_s_hpux32}%{mlp64:-lgcc_s_hpux64} -lgcc} \
+ "%{shared-libgcc:%{!mlp64:-lgcc_s}%{mlp64:-lgcc_s_hpux64} -lgcc} \
%{!shared-libgcc:-lgcc}"
#endif
@@ -94,6 +96,8 @@ do { \
{ "ilp32", MASK_ILP32, "Generate ILP32 code" }, \
{ "lp64", -MASK_ILP32, "Generate LP64 code" },
+#define MULTILIB_DEFAULTS { "milp32" }
+
/* A C expression whose value is zero if pointers that need to be extended
from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and
greater then zero if they are zero-extended and less then zero if the
@@ -107,12 +111,13 @@ do { \
#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32)
/* This needs to be set to force structure arguments with a single
- field to be treated as structures and not as the type of their
- field. Without this a structure with a single char will be
- returned just like a char variable and that is wrong on HP-UX
- IA64. */
+ integer field to be treated as structures and not as the type of
+ their field. Without this a structure with a single char will be
+ returned just like a char variable, instead of being returned at the
+ top of the register as specified for big-endian IA64. */
-#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (TREE_CODE (TREE_TYPE (FIELD)) != REAL_TYPE || (MODE == TFmode && !INTEL_EXTENDED_IEEE_FORMAT))
+#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
+ (!FLOAT_MODE_P (MODE) || (MODE) == TFmode)
/* ASM_OUTPUT_EXTERNAL_LIBCALL defaults to just a globalize_label call,
but that doesn't put out the @function type information which causes
@@ -132,8 +137,8 @@ do { \
#undef PAD_VARARGS_DOWN
#define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type))
-#define REGISTER_TARGET_PRAGMAS(PFILE) \
- cpp_register_pragma (PFILE, 0, "builtin", ia64_hpux_handle_builtin_pragma)
+#define REGISTER_TARGET_PRAGMAS() \
+ c_register_pragma (0, "builtin", ia64_hpux_handle_builtin_pragma)
/* Tell ia64.c that we are using the HP linker and we should delay output of
function extern declarations so that we don't output them for functions
@@ -148,7 +153,7 @@ do { \
/* Put out the needed function declarations at the end. */
-#define ASM_FILE_END(STREAM) ia64_hpux_asm_file_end(STREAM)
+#define TARGET_ASM_FILE_END ia64_hpux_file_end
#undef CTORS_SECTION_ASM_OP
#define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\t\"aw\",\"init_array\""
@@ -188,3 +193,11 @@ do { \
#define TARGET_ASM_SELECT_RTX_SECTION ia64_rwreloc_select_rtx_section
#undef TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS ia64_rwreloc_section_type_flags
+
+/* ia64 HPUX has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
+#define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
+
+#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
diff --git a/contrib/gcc/config/ia64/ia64-c.c b/contrib/gcc/config/ia64/ia64-c.c
index e44c80b..422fc86 100644
--- a/contrib/gcc/config/ia64/ia64-c.c
+++ b/contrib/gcc/config/ia64/ia64-c.c
@@ -1,26 +1,28 @@
/* Definitions of C specific functions for GNU compiler.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Steve Ellcey <sje@cup.hp.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cpplib.h"
#include "c-common.h"
@@ -28,11 +30,10 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "tm_p.h"
-static void ia64_hpux_add_pragma_builtin PARAMS ((tree func));
+static void ia64_hpux_add_pragma_builtin (tree func);
void
-ia64_hpux_handle_builtin_pragma (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+ia64_hpux_handle_builtin_pragma (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
/* #pragma builtin name, name, name */
@@ -171,8 +172,7 @@ static const c89_mathlib_names c89_mathlib_name_list [] =
};
static void
-ia64_hpux_add_pragma_builtin (func)
- tree func;
+ia64_hpux_add_pragma_builtin (tree func)
{
size_t i;
diff --git a/contrib/gcc/config/ia64/ia64-modes.def b/contrib/gcc/config/ia64/ia64-modes.def
index 0c3eb12..17688bd 100644
--- a/contrib/gcc/config/ia64/ia64-modes.def
+++ b/contrib/gcc/config/ia64/ia64-modes.def
@@ -1,29 +1,68 @@
/* Definitions of target machine GNU compiler. IA-64 version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by James E. Wilson <wilson@cygnus.com> and
David Mosberger <davidm@hpl.hp.com>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* IA64 requires both XF and TF modes.
+ XFmode is __float80 is IEEE extended; TFmode is __float128
+ is IEEE quad.
+
+ IEEE extended is 128 bits wide, except in ILP32 mode, but we
+ have to say it's 12 bytes so that the bitsize and wider_mode
+ tables are correctly set up. We correct its size below. */
+
+FLOAT_MODE (XF, 12, ieee_extended_intel_128_format);
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
+/* The above produces:
+
+ mode ILP32 size/align LP64 size/align
+ XF 12/4 12/4
+ TF 16/16 16/16
+
+ psABI expectations:
+
+ mode ILP32 size/align LP64 size/align
+ XF - 16/16
+ TF - -
+
+ HPUX expectations:
+
+ mode ILP32 size/align LP64 size/align
+ XF 16/16 16/16
+ TF 16/8 -
+
+ We fix this up here. */
+
+ADJUST_BYTESIZE (XF, (TARGET_ILP32 && !TARGET_HPUX) ? 12 : 16);
+ADJUST_ALIGNMENT (XF, (TARGET_ILP32 && !TARGET_HPUX) ? 4 : 16);
+
+ADJUST_ALIGNMENT (TF, (TARGET_ILP32 && TARGET_HPUX) ? 8 : 16);
+
+/* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */
+INT_MODE (OI, 32);
+
/* Add any extra modes needed to represent the condition code.
CCImode is used to mark a single predicate register instead
of a register pair. This is currently only used in reg_raw_mode
so that flow doesn't do something stupid. */
-CC (CCI)
+CC_MODE (CCI);
diff --git a/contrib/gcc/config/ia64/ia64-protos.h b/contrib/gcc/config/ia64/ia64-protos.h
index f25bb02..7825616 100644
--- a/contrib/gcc/config/ia64/ia64-protos.h
+++ b/contrib/gcc/config/ia64/ia64-protos.h
@@ -1,20 +1,21 @@
/* Definitions of target machine for GNU compiler for IA-64.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,132 +28,127 @@ extern GTY(()) rtx ia64_compare_op1;
/* Functions defined in ia64.c */
+extern int bundling_p;
#ifdef RTX_CODE
-extern int call_operand PARAMS((rtx, enum machine_mode));
-extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int tls_symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int function_operand PARAMS((rtx, enum machine_mode));
-extern int setjmp_operand PARAMS((rtx, enum machine_mode));
-extern int move_operand PARAMS((rtx, enum machine_mode));
-extern int gr_register_operand PARAMS((rtx, enum machine_mode));
-extern int fr_register_operand PARAMS((rtx, enum machine_mode));
-extern int grfr_register_operand PARAMS((rtx, enum machine_mode));
-extern int gr_nonimmediate_operand PARAMS((rtx, enum machine_mode));
-extern int fr_nonimmediate_operand PARAMS((rtx, enum machine_mode));
-extern int grfr_nonimmediate_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_0_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_5bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_6bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_8bit_operand PARAMS((rtx, enum machine_mode));
-extern int grfr_reg_or_8bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_8bit_adjusted_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_8bit_and_adjusted_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_14bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_22bit_operand PARAMS((rtx, enum machine_mode));
-extern int shift_count_operand PARAMS((rtx, enum machine_mode));
-extern int shift_32bit_count_operand PARAMS((rtx, enum machine_mode));
-extern int shladd_operand PARAMS((rtx, enum machine_mode));
-extern int fetchadd_operand PARAMS((rtx, enum machine_mode));
-extern int fr_reg_or_fp01_operand PARAMS((rtx, enum machine_mode));
-extern int normal_comparison_operator PARAMS((rtx, enum machine_mode));
-extern int adjusted_comparison_operator PARAMS((rtx, enum machine_mode));
-extern int signed_inequality_operator PARAMS((rtx, enum machine_mode));
-extern int destination_operand PARAMS((rtx, enum machine_mode));
-extern int not_postinc_memory_operand PARAMS((rtx, enum machine_mode));
-extern int predicate_operator PARAMS((rtx, enum machine_mode));
-extern int ar_lc_reg_operand PARAMS((rtx, enum machine_mode));
-extern int ar_ccv_reg_operand PARAMS((rtx, enum machine_mode));
-extern int ar_pfs_reg_operand PARAMS((rtx, enum machine_mode));
-extern int general_tfmode_operand PARAMS((rtx, enum machine_mode));
-extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode));
-extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode));
-extern int basereg_operand PARAMS((rtx, enum machine_mode));
-
-extern rtx ia64_expand_move PARAMS ((rtx, rtx));
-extern int ia64_move_ok PARAMS((rtx, rtx));
-extern int addp4_optimize_ok PARAMS((rtx, rtx));
-extern int ia64_depz_field_mask PARAMS((rtx, rtx));
-extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
-extern rtx spill_tfmode_operand PARAMS((rtx, int));
-extern rtx ia64_expand_compare PARAMS((enum rtx_code, enum machine_mode));
-extern void ia64_expand_call PARAMS((rtx, rtx, rtx, int));
-extern void ia64_split_call PARAMS((rtx, rtx, rtx, rtx, rtx, int, int));
-extern void ia64_reload_gp PARAMS((void));
-
-extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
-extern void ia64_expand_prologue PARAMS((void));
-extern void ia64_expand_epilogue PARAMS((int));
-
-extern int ia64_direct_return PARAMS((void));
-extern void ia64_expand_load_address PARAMS((rtx, rtx, rtx));
-extern int ia64_hard_regno_rename_ok PARAMS((int, int));
-
-extern void ia64_initialize_trampoline PARAMS((rtx, rtx, rtx));
-extern void ia64_print_operand_address PARAMS((FILE *, rtx));
-extern void ia64_print_operand PARAMS((FILE *, rtx, int));
-extern enum reg_class ia64_secondary_reload_class PARAMS((enum reg_class,
- enum machine_mode,
- rtx));
-extern void ia64_reorg PARAMS((rtx));
-extern void process_for_unwind_directive PARAMS ((FILE *, rtx));
-extern const char *get_bundle_name PARAMS ((int));
+extern int ia64_st_address_bypass_p (rtx, rtx);
+extern int ia64_ld_address_bypass_p (rtx, rtx);
+extern int ia64_produce_address_p (rtx);
+extern int call_operand (rtx, enum machine_mode);
+extern int sdata_symbolic_operand (rtx, enum machine_mode);
+extern int got_symbolic_operand (rtx, enum machine_mode);
+extern int symbolic_operand (rtx, enum machine_mode);
+extern int tls_symbolic_operand (rtx, enum machine_mode);
+extern int function_operand (rtx, enum machine_mode);
+extern int setjmp_operand (rtx, enum machine_mode);
+extern int move_operand (rtx, enum machine_mode);
+extern int gr_register_operand (rtx, enum machine_mode);
+extern int fr_register_operand (rtx, enum machine_mode);
+extern int grfr_register_operand (rtx, enum machine_mode);
+extern int gr_nonimmediate_operand (rtx, enum machine_mode);
+extern int fr_nonimmediate_operand (rtx, enum machine_mode);
+extern int grfr_nonimmediate_operand (rtx, enum machine_mode);
+extern int gr_reg_or_0_operand (rtx, enum machine_mode);
+extern int gr_reg_or_5bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_6bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_8bit_operand (rtx, enum machine_mode);
+extern int grfr_reg_or_8bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_8bit_adjusted_operand (rtx, enum machine_mode);
+extern int gr_reg_or_8bit_and_adjusted_operand (rtx, enum machine_mode);
+extern int gr_reg_or_14bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_22bit_operand (rtx, enum machine_mode);
+extern int shift_count_operand (rtx, enum machine_mode);
+extern int shift_32bit_count_operand (rtx, enum machine_mode);
+extern int shladd_operand (rtx, enum machine_mode);
+extern int fetchadd_operand (rtx, enum machine_mode);
+extern int fr_reg_or_fp01_operand (rtx, enum machine_mode);
+extern int normal_comparison_operator (rtx, enum machine_mode);
+extern int adjusted_comparison_operator (rtx, enum machine_mode);
+extern int signed_inequality_operator (rtx, enum machine_mode);
+extern int destination_operand (rtx, enum machine_mode);
+extern int not_postinc_memory_operand (rtx, enum machine_mode);
+extern int predicate_operator (rtx, enum machine_mode);
+extern int ar_lc_reg_operand (rtx, enum machine_mode);
+extern int ar_ccv_reg_operand (rtx, enum machine_mode);
+extern int ar_pfs_reg_operand (rtx, enum machine_mode);
+extern int general_xfmode_operand (rtx, enum machine_mode);
+extern int destination_xfmode_operand (rtx, enum machine_mode);
+extern int xfreg_or_fp01_operand (rtx, enum machine_mode);
+extern int basereg_operand (rtx, enum machine_mode);
+
+extern rtx ia64_expand_move (rtx, rtx);
+extern int ia64_move_ok (rtx, rtx);
+extern int addp4_optimize_ok (rtx, rtx);
+extern void ia64_emit_cond_move (rtx, rtx, rtx);
+extern int ia64_depz_field_mask (rtx, rtx);
+extern void ia64_split_tmode_move (rtx[]);
+extern rtx spill_xfmode_operand (rtx, int);
+extern rtx ia64_expand_compare (enum rtx_code, enum machine_mode);
+extern void ia64_expand_call (rtx, rtx, rtx, int);
+extern void ia64_split_call (rtx, rtx, rtx, rtx, rtx, int, int);
+extern void ia64_reload_gp (void);
+
+extern HOST_WIDE_INT ia64_initial_elimination_offset (int, int);
+extern void ia64_expand_prologue (void);
+extern void ia64_expand_epilogue (int);
+
+extern int ia64_direct_return (void);
+extern void ia64_expand_load_address (rtx, rtx);
+extern int ia64_hard_regno_rename_ok (int, int);
+
+extern void ia64_initialize_trampoline (rtx, rtx, rtx);
+extern void ia64_print_operand_address (FILE *, rtx);
+extern void ia64_print_operand (FILE *, rtx, int);
+extern enum reg_class ia64_secondary_reload_class (enum reg_class,
+ enum machine_mode, rtx);
+extern void ia64_output_dwarf_dtprel (FILE*, int, rtx);
+extern void process_for_unwind_directive (FILE *, rtx);
+extern const char *get_bundle_name (int);
#endif /* RTX_CODE */
#ifdef TREE_CODE
#ifdef RTX_CODE
-extern rtx ia64_function_arg PARAMS((CUMULATIVE_ARGS *, enum machine_mode,
- tree, int, int));
-extern rtx ia64_expand_builtin PARAMS((tree, rtx, rtx,
- enum machine_mode, int));
-extern rtx ia64_va_arg PARAMS((tree, tree));
-extern rtx ia64_function_value PARAMS((tree, tree));
+extern rtx ia64_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int, int);
+extern rtx ia64_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+extern rtx ia64_va_arg (tree, tree);
+extern rtx ia64_function_value (tree, tree);
#endif /* RTX_CODE */
-extern void ia64_setup_incoming_varargs PARAMS((CUMULATIVE_ARGS, int, tree,
- int *, int));
-extern int ia64_function_arg_partial_nregs PARAMS((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern void ia64_function_arg_advance PARAMS((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern int ia64_function_arg_pass_by_reference PARAMS((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern int ia64_return_in_memory PARAMS((tree));
-extern void ia64_asm_output_external PARAMS((FILE *, tree, const char *));
+extern void ia64_setup_incoming_varargs (CUMULATIVE_ARGS, int, tree,
+ int *, int);
+extern int ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
+extern int ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int ia64_return_in_memory (tree);
+extern void ia64_asm_output_external (FILE *, tree, const char *);
#endif /* TREE_CODE */
-extern int ia64_register_move_cost PARAMS((enum machine_mode, enum reg_class,
- enum reg_class));
-extern int ia64_epilogue_uses PARAMS((int));
-extern int ia64_eh_uses PARAMS((int));
-extern void emit_safe_across_calls PARAMS((FILE *));
-extern void ia64_init_builtins PARAMS((void));
-extern void ia64_override_options PARAMS((void));
-extern int ia64_dbx_register_number PARAMS((int));
-extern bool ia64_function_ok_for_sibcall PARAMS ((tree));
+extern int ia64_register_move_cost (enum machine_mode, enum reg_class,
+ enum reg_class);
+extern int ia64_epilogue_uses (int);
+extern int ia64_eh_uses (int);
+extern void emit_safe_across_calls (void);
+extern void ia64_init_builtins (void);
+extern void ia64_override_options (void);
+extern int ia64_dbx_register_number (int);
-extern rtx ia64_return_addr_rtx PARAMS ((HOST_WIDE_INT, rtx));
-extern void ia64_split_return_addr_rtx PARAMS ((rtx));
+extern rtx ia64_return_addr_rtx (HOST_WIDE_INT, rtx);
+extern void ia64_split_return_addr_rtx (rtx);
#ifdef SDATA_SECTION_ASM_OP
-extern void sdata_section PARAMS ((void));
+extern void sdata_section (void);
#endif
#ifdef SBSS_SECTION_ASM_OP
-extern void sbss_section PARAMS ((void));
+extern void sbss_section (void);
#endif
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction'. */
-extern enum direction ia64_hpux_function_arg_padding PARAMS ((enum machine_mode, tree));
+extern enum direction ia64_hpux_function_arg_padding (enum machine_mode, tree);
#endif /* ARGS_SIZE_RTX */
-#ifdef GCC_C_PRAGMA_H
-extern void ia64_hpux_handle_builtin_pragma PARAMS ((cpp_reader *));
-#endif
-
-extern void ia64_hpux_asm_file_end PARAMS ((FILE *));
+extern void ia64_hpux_handle_builtin_pragma (struct cpp_reader *);
diff --git a/contrib/gcc/config/ia64/ia64.c b/contrib/gcc/config/ia64/ia64.c
index 12f3204..19c5e92 100644
--- a/contrib/gcc/config/ia64/ia64.c
+++ b/contrib/gcc/config/ia64/ia64.c
@@ -1,27 +1,30 @@
/* Definitions of target machine for GNU compiler.
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by James E. Wilson <wilson@cygnus.com> and
- David Mosberger <davidm@hpl.hp.com>.
+ David Mosberger <davidm@hpl.hp.com>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "regs.h"
@@ -45,7 +48,9 @@ Boston, MA 02111-1307, USA. */
#include "target.h"
#include "target-def.h"
#include "tm_p.h"
+#include "hashtab.h"
#include "langhooks.h"
+#include "cfglayout.h"
/* This is used for communication between ASM_OUTPUT_LABEL and
ASM_OUTPUT_LABELREF. */
@@ -102,6 +107,12 @@ int ia64_tls_size = 22;
/* String used with the -mtls-size= option. */
const char *ia64_tls_size_string;
+/* Which cpu are we scheduling for. */
+enum processor_type ia64_tune;
+
+/* String used with the -tune= option. */
+const char *ia64_tune_string;
+
/* Determines whether we run our final scheduling pass or not. We always
avoid the normal second scheduling pass. */
static int ia64_flag_schedule_insns2;
@@ -111,6 +122,10 @@ static int ia64_flag_schedule_insns2;
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;
+
/* Structure to be filled in by ia64_compute_frame_size with register
save masks and offsets for the current function. */
@@ -122,7 +137,7 @@ struct ia64_frame_info
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
+ 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 reg_fp; /* register for fp. */
@@ -144,84 +159,118 @@ struct ia64_frame_info
/* Current frame information calculated by ia64_compute_frame_size. */
static struct ia64_frame_info current_frame_info;
-static rtx gen_tls_get_addr PARAMS ((void));
-static rtx gen_thread_pointer PARAMS ((void));
-static int find_gr_spill PARAMS ((int));
-static int next_scratch_gr_reg PARAMS ((void));
-static void mark_reg_gr_used_mask PARAMS ((rtx, void *));
-static void ia64_compute_frame_size PARAMS ((HOST_WIDE_INT));
-static void setup_spill_pointers PARAMS ((int, rtx, HOST_WIDE_INT));
-static void finish_spill_pointers PARAMS ((void));
-static rtx spill_restore_mem PARAMS ((rtx, HOST_WIDE_INT));
-static void do_spill PARAMS ((rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT, rtx));
-static void do_restore PARAMS ((rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT));
-static rtx gen_movdi_x PARAMS ((rtx, rtx, rtx));
-static rtx gen_fr_spill_x PARAMS ((rtx, rtx, rtx));
-static rtx gen_fr_restore_x PARAMS ((rtx, rtx, rtx));
-
-static enum machine_mode hfa_element_mode PARAMS ((tree, int));
-static void fix_range PARAMS ((const char *));
-static struct machine_function * ia64_init_machine_status PARAMS ((void));
-static void emit_insn_group_barriers PARAMS ((FILE *, rtx));
-static void emit_all_insn_group_barriers PARAMS ((FILE *, rtx));
-static void emit_predicate_relation_info PARAMS ((void));
-static bool ia64_in_small_data_p PARAMS ((tree));
-static void ia64_encode_section_info PARAMS ((tree, int));
-static const char *ia64_strip_name_encoding PARAMS ((const char *));
-static void process_epilogue PARAMS ((void));
-static int process_set PARAMS ((FILE *, rtx));
-
-static rtx ia64_expand_fetch_and_op PARAMS ((optab, enum machine_mode,
- tree, rtx));
-static rtx ia64_expand_op_and_fetch PARAMS ((optab, enum machine_mode,
- tree, rtx));
-static rtx ia64_expand_compare_and_swap PARAMS ((enum machine_mode,
- enum machine_mode,
- int, tree, rtx));
-static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode,
- tree, rtx));
-static rtx ia64_expand_lock_release PARAMS ((enum machine_mode, tree, rtx));
-static bool ia64_assemble_integer PARAMS ((rtx, unsigned int, int));
-static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void ia64_output_function_end_prologue PARAMS ((FILE *));
-
-static int ia64_issue_rate PARAMS ((void));
-static int ia64_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static void ia64_sched_init PARAMS ((FILE *, int, int));
-static void ia64_sched_finish PARAMS ((FILE *, int));
-static int ia64_internal_sched_reorder PARAMS ((FILE *, int, rtx *,
- int *, int, int));
-static int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
-static int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
-static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
-
-static void ia64_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
-
-static void ia64_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static void ia64_rwreloc_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT))
+static int ia64_use_dfa_pipeline_interface (void);
+static int ia64_first_cycle_multipass_dfa_lookahead (void);
+static void ia64_dependencies_evaluation_hook (rtx, rtx);
+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);
+static int ia64_dfa_new_cycle (FILE *, int, rtx, int, int, int *);
+static rtx gen_tls_get_addr (void);
+static rtx gen_thread_pointer (void);
+static rtx ia64_expand_tls_address (enum tls_model, rtx, rtx);
+static int find_gr_spill (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 enum machine_mode hfa_element_mode (tree, int);
+static bool ia64_function_ok_for_sibcall (tree, tree);
+static bool ia64_rtx_costs (rtx, int, int, int *);
+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 (tree);
+static void process_epilogue (void);
+static int process_set (FILE *, rtx);
+
+static rtx ia64_expand_fetch_and_op (optab, enum machine_mode, tree, rtx);
+static rtx ia64_expand_op_and_fetch (optab, enum machine_mode, tree, rtx);
+static rtx ia64_expand_compare_and_swap (enum machine_mode, enum machine_mode,
+ int, tree, rtx);
+static rtx ia64_expand_lock_test_and_set (enum machine_mode, tree, rtx);
+static rtx ia64_expand_lock_release (enum machine_mode, tree, rtx);
+static bool ia64_assemble_integer (rtx, unsigned int, int);
+static void ia64_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void ia64_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void ia64_output_function_end_prologue (FILE *);
+
+static int ia64_issue_rate (void);
+static int ia64_adjust_cost (rtx, rtx, rtx, int);
+static void ia64_sched_init (FILE *, int, int);
+static void ia64_sched_finish (FILE *, int);
+static int ia64_dfa_sched_reorder (FILE *, int, rtx *, int *, int, int);
+static int ia64_sched_reorder (FILE *, int, rtx *, int *, int);
+static int ia64_sched_reorder2 (FILE *, int, rtx *, int *, int);
+static int ia64_variable_issue (FILE *, int, rtx, int);
+
+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 unsigned bundle_state_hash (const void *);
+static int bundle_state_eq_p (const void *, const 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, int, int);
+static int get_max_pos (state_t);
+static int get_template (state_t, int);
+
+static rtx get_next_important_insn (rtx, rtx);
+static void bundling (FILE *, int, rtx, rtx);
+
+static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+static void ia64_file_start (void);
+
+static void ia64_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static void ia64_rwreloc_select_section (tree, int, unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static void ia64_rwreloc_unique_section PARAMS ((tree, int))
+static void ia64_rwreloc_unique_section (tree, int)
ATTRIBUTE_UNUSED;
-static void ia64_rwreloc_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT))
+static void ia64_rwreloc_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static unsigned int ia64_rwreloc_section_type_flags
- PARAMS ((tree, const char *, int))
+static unsigned int ia64_rwreloc_section_type_flags (tree, const char *, int)
ATTRIBUTE_UNUSED;
-static void ia64_hpux_add_extern_decl PARAMS ((const char *name))
+static void ia64_hpux_add_extern_decl (tree decl)
+ ATTRIBUTE_UNUSED;
+static void ia64_hpux_file_end (void)
+ ATTRIBUTE_UNUSED;
+static void ia64_hpux_init_libfuncs (void)
ATTRIBUTE_UNUSED;
+static void ia64_vms_init_libfuncs (void)
+ ATTRIBUTE_UNUSED;
+
+static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
+static void ia64_encode_section_info (tree, rtx, int);
+static rtx ia64_struct_value_rtx (tree, int);
+
/* 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, handler } */
{ "syscall_linkage", 0, 0, false, true, true, NULL },
- { NULL, 0, 0, false, false, false, NULL }
+ { "model", 1, 1, true, false, false, ia64_handle_model_attribute },
+ { NULL, 0, 0, false, false, false, NULL }
};
/* Initialize the GCC target structure. */
@@ -260,10 +309,6 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P ia64_in_small_data_p
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING ia64_strip_name_encoding
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST ia64_adjust_cost
@@ -280,24 +325,58 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_SCHED_REORDER2
#define TARGET_SCHED_REORDER2 ia64_sched_reorder2
-#ifdef HAVE_AS_TLS
-#undef TARGET_HAVE_TLS
-#define TARGET_HAVE_TLS true
-#endif
+#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
+#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK ia64_dependencies_evaluation_hook
+
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ia64_use_dfa_pipeline_interface
+
+#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_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall
#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_tree_hwi_hwi_tree_true
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START ia64_file_start
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ia64_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
+#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_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
@@ -309,9 +388,7 @@ call_operand (op, mode)
/* Return 1 if OP refers to a symbol in the sdata section. */
int
-sdata_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+sdata_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -326,10 +403,7 @@ sdata_symbolic_operand (op, mode)
if (CONSTANT_POOL_ADDRESS_P (op))
return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
else
- {
- const char *str = XSTR (op, 0);
- return (str[0] == ENCODE_SECTION_INFO_CHAR && str[1] == 's');
- }
+ return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op);
default:
break;
@@ -338,12 +412,16 @@ sdata_symbolic_operand (op, mode)
return 0;
}
+int
+small_addr_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return SYMBOL_REF_SMALL_ADDR_P (op);
+}
+
/* Return 1 if OP refers to a symbol, and is appropriate for a GOT load. */
int
-got_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+got_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -374,6 +452,8 @@ got_symbolic_operand (op, mode)
return (INTVAL (op) & 0x3fff) == 0;
case SYMBOL_REF:
+ if (SYMBOL_REF_SMALL_ADDR_P (op))
+ return 0;
case LABEL_REF:
return 1;
@@ -386,9 +466,7 @@ got_symbolic_operand (op, mode)
/* Return 1 if OP refers to a symbol. */
int
-symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -406,40 +484,20 @@ symbolic_operand (op, mode)
/* Return tls_model if OP refers to a TLS symbol. */
int
-tls_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- const char *str;
-
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- str = XSTR (op, 0);
- if (str[0] != ENCODE_SECTION_INFO_CHAR)
- return 0;
- switch (str[1])
- {
- case 'G':
- return TLS_MODEL_GLOBAL_DYNAMIC;
- case 'L':
- return TLS_MODEL_LOCAL_DYNAMIC;
- case 'i':
- return TLS_MODEL_INITIAL_EXEC;
- case 'l':
- return TLS_MODEL_LOCAL_EXEC;
- }
- return 0;
+ return SYMBOL_REF_TLS_MODEL (op);
}
/* Return 1 if OP refers to a function. */
int
-function_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+function_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- if (GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FLAG (op))
+ if (GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (op))
return 1;
else
return 0;
@@ -450,9 +508,7 @@ function_operand (op, mode)
/* ??? This is an unsatisfying solution. Should rethink. */
int
-setjmp_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+setjmp_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
const char *name;
int retval = 0;
@@ -495,29 +551,18 @@ setjmp_operand (op, mode)
return retval;
}
-/* Return 1 if OP is a general operand, but when pic exclude symbolic
- operands. */
-
-/* ??? If we drop no-pic support, can delete SYMBOL_REF, CONST, and LABEL_REF
- from PREDICATE_CODES. */
+/* Return 1 if OP is a general operand, excluding tls symbolic operands. */
int
-move_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_operand (rtx op, enum machine_mode mode)
{
- if (! TARGET_NO_PIC && symbolic_operand (op, mode))
- return 0;
-
- return general_operand (op, mode);
+ return general_operand (op, mode) && !tls_symbolic_operand (op, mode);
}
/* Return 1 if OP is a register operand that is (or could be) a GR reg. */
int
-gr_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -535,9 +580,7 @@ gr_register_operand (op, mode)
/* Return 1 if OP is a register operand that is (or could be) an FR reg. */
int
-fr_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fr_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -555,9 +598,7 @@ fr_register_operand (op, mode)
/* Return 1 if OP is a register operand that is (or could be) a GR/FR reg. */
int
-grfr_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+grfr_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -575,9 +616,7 @@ grfr_register_operand (op, mode)
/* Return 1 if OP is a nonimmediate operand that is (or could be) a GR reg. */
int
-gr_nonimmediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_nonimmediate_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -595,9 +634,7 @@ gr_nonimmediate_operand (op, mode)
/* Return 1 if OP is a nonimmediate operand that is (or could be) a FR reg. */
int
-fr_nonimmediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fr_nonimmediate_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -615,9 +652,7 @@ fr_nonimmediate_operand (op, mode)
/* Return 1 if OP is a nonimmediate operand that is a GR/FR reg. */
int
-grfr_nonimmediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+grfr_nonimmediate_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -635,9 +670,7 @@ grfr_nonimmediate_operand (op, mode)
/* Return 1 if OP is a GR register operand, or zero. */
int
-gr_reg_or_0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_0_operand (rtx op, enum machine_mode mode)
{
return (op == const0_rtx || gr_register_operand (op, mode));
}
@@ -645,9 +678,7 @@ gr_reg_or_0_operand (op, mode)
/* Return 1 if OP is a GR register operand, or a 5 bit immediate operand. */
int
-gr_reg_or_5bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_5bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 32)
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -657,9 +688,7 @@ gr_reg_or_5bit_operand (op, mode)
/* Return 1 if OP is a GR register operand, or a 6 bit immediate operand. */
int
-gr_reg_or_6bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_6bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -669,9 +698,7 @@ gr_reg_or_6bit_operand (op, mode)
/* Return 1 if OP is a GR register operand, or an 8 bit immediate operand. */
int
-gr_reg_or_8bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -681,9 +708,7 @@ gr_reg_or_8bit_operand (op, mode)
/* Return 1 if OP is a GR/FR register operand, or an 8 bit immediate. */
int
-grfr_reg_or_8bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+grfr_reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -694,9 +719,7 @@ grfr_reg_or_8bit_operand (op, mode)
operand. */
int
-gr_reg_or_8bit_adjusted_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_8bit_adjusted_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_L (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -709,9 +732,7 @@ gr_reg_or_8bit_adjusted_operand (op, mode)
so we need the union of the immediates accepted by GT and LT. */
int
-gr_reg_or_8bit_and_adjusted_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_8bit_and_adjusted_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op))
&& CONST_OK_FOR_L (INTVAL (op)))
@@ -722,9 +743,7 @@ gr_reg_or_8bit_and_adjusted_operand (op, mode)
/* Return 1 if OP is a register operand, or a 14 bit immediate operand. */
int
-gr_reg_or_14bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_14bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_I (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -734,9 +753,7 @@ gr_reg_or_14bit_operand (op, mode)
/* Return 1 if OP is a register operand, or a 22 bit immediate operand. */
int
-gr_reg_or_22bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_22bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -746,9 +763,7 @@ gr_reg_or_22bit_operand (op, mode)
/* Return 1 if OP is a 6 bit immediate operand. */
int
-shift_count_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+shift_count_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX);
@@ -757,9 +772,7 @@ shift_count_operand (op, mode)
/* Return 1 if OP is a 5 bit immediate operand. */
int
-shift_32bit_count_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+shift_32bit_count_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT
&& (INTVAL (op) >= 0 && INTVAL (op) < 32))
@@ -769,9 +782,7 @@ shift_32bit_count_operand (op, mode)
/* Return 1 if OP is a 2, 4, 8, or 16 immediate operand. */
int
-shladd_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+shladd_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) == 2 || INTVAL (op) == 4
@@ -781,9 +792,7 @@ shladd_operand (op, mode)
/* Return 1 if OP is a -16, -8, -4, -1, 1, 4, 8, or 16 immediate operand. */
int
-fetchadd_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+fetchadd_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) == -16 || INTVAL (op) == -8 ||
@@ -795,9 +804,7 @@ fetchadd_operand (op, mode)
/* Return 1 if OP is a floating-point constant zero, one, or a register. */
int
-fr_reg_or_fp01_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fr_reg_or_fp01_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (op))
|| fr_register_operand (op, mode));
@@ -807,9 +814,7 @@ fr_reg_or_fp01_operand (op, mode)
POST_MODIFY with a REG as displacement. */
int
-destination_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+destination_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -823,21 +828,17 @@ destination_operand (op, mode)
/* Like memory_operand, but don't allow post-increments. */
int
-not_postinc_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+not_postinc_memory_operand (rtx op, enum machine_mode mode)
{
return (memory_operand (op, mode)
&& GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != 'a');
}
-/* Return 1 if this is a comparison operator, which accepts an normal 8-bit
+/* Return 1 if this is a comparison operator, which accepts a normal 8-bit
signed immediate operand. */
int
-normal_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+normal_comparison_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((mode == VOIDmode || GET_MODE (op) == mode)
@@ -849,9 +850,7 @@ normal_comparison_operator (op, mode)
signed immediate operand. */
int
-adjusted_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+adjusted_comparison_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((mode == VOIDmode || GET_MODE (op) == mode)
@@ -861,9 +860,7 @@ adjusted_comparison_operator (op, mode)
/* Return 1 if this is a signed inequality operator. */
int
-signed_inequality_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+signed_inequality_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((mode == VOIDmode || GET_MODE (op) == mode)
@@ -874,9 +871,7 @@ signed_inequality_operator (op, mode)
/* Return 1 if this operator is valid for predication. */
int
-predicate_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+predicate_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((GET_MODE (op) == mode || mode == VOIDmode)
@@ -886,9 +881,7 @@ predicate_operator (op, mode)
/* Return 1 if this operator can be used in a conditional operation. */
int
-condop_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+condop_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((GET_MODE (op) == mode || mode == VOIDmode)
@@ -899,9 +892,7 @@ condop_operator (op, mode)
/* Return 1 if this is the ar.lc register. */
int
-ar_lc_reg_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+ar_lc_reg_operand (register rtx op, enum machine_mode mode)
{
return (GET_MODE (op) == DImode
&& (mode == DImode || mode == VOIDmode)
@@ -912,9 +903,7 @@ ar_lc_reg_operand (op, mode)
/* Return 1 if this is the ar.ccv register. */
int
-ar_ccv_reg_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+ar_ccv_reg_operand (register rtx op, enum machine_mode mode)
{
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& GET_CODE (op) == REG
@@ -924,9 +913,7 @@ ar_ccv_reg_operand (op, mode)
/* Return 1 if this is the ar.pfs register. */
int
-ar_pfs_reg_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+ar_pfs_reg_operand (register rtx op, enum machine_mode mode)
{
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& GET_CODE (op) == REG
@@ -936,9 +923,7 @@ ar_pfs_reg_operand (op, mode)
/* Like general_operand, but don't allow (mem (addressof)). */
int
-general_tfmode_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+general_xfmode_operand (rtx op, enum machine_mode mode)
{
if (! general_operand (op, mode))
return 0;
@@ -950,9 +935,7 @@ general_tfmode_operand (op, mode)
/* Similarly. */
int
-destination_tfmode_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+destination_xfmode_operand (rtx op, enum machine_mode mode)
{
if (! destination_operand (op, mode))
return 0;
@@ -964,9 +947,7 @@ destination_tfmode_operand (op, mode)
/* Similarly. */
int
-tfreg_or_fp01_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+xfreg_or_fp01_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == SUBREG)
return 0;
@@ -976,9 +957,7 @@ tfreg_or_fp01_operand (op, mode)
/* Return 1 if OP is valid as a base register in a reg + offset address. */
int
-basereg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+basereg_operand (rtx op, enum machine_mode mode)
{
/* ??? Should I copy the flag_omit_frame_pointer and cse_not_expected
checks from pa.c basereg_operand as well? Seems to be OK without them
@@ -988,11 +967,133 @@ basereg_operand (op, mode)
REG_POINTER ((GET_CODE (op) == SUBREG) ? SUBREG_REG (op) : op));
}
+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 ("invalid argument of `%s' attribute",
+ IDENTIFIER_POINTER (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 ("%Jan address area attribute cannot be specified for "
+ "local variables", decl, decl);
+ *no_add_attrs = true;
+ }
+ area = ia64_get_addr_area (decl);
+ if (area != ADDR_AREA_NORMAL && addr_area != area)
+ {
+ error ("%Jaddress area of '%s' conflicts with previous "
+ "declaration", decl, decl);
+ *no_add_attrs = true;
+ }
+ break;
+
+ case FUNCTION_DECL:
+ error ("%Jaddress area attribute cannot be specified for functions",
+ decl, decl);
+ *no_add_attrs = true;
+ break;
+
+ default:
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+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: abort ();
+ }
+ 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));
+}
+
/* Return 1 if the operands of a move are ok. */
int
-ia64_move_ok (dst, src)
- rtx dst, src;
+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
@@ -1012,27 +1113,18 @@ ia64_move_ok (dst, src)
return GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src);
}
-/* Return 0 if we are doing C++ code. This optimization fails with
- C++ because of GNAT c++/6685. */
-
int
-addp4_optimize_ok (op1, op2)
- rtx op1, op2;
+addp4_optimize_ok (rtx op1, rtx op2)
{
-
- if (!strcmp (lang_hooks.name, "GNU C++"))
- return 0;
-
return (basereg_operand (op1, GET_MODE(op1)) !=
basereg_operand (op2, GET_MODE(op2)));
}
-/* Check if OP is a mask suitible for use with SHIFT in a dep.z instruction.
+/* 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 (rop, rshift)
- rtx rop, rshift;
+ia64_depz_field_mask (rtx rop, rtx rshift)
{
unsigned HOST_WIDE_INT op = INTVAL (rop);
unsigned HOST_WIDE_INT shift = INTVAL (rshift);
@@ -1045,40 +1137,48 @@ ia64_depz_field_mask (rop, rshift)
}
/* Expand a symbolic constant load. */
-/* ??? Should generalize this, so that we can also support 32 bit pointers. */
void
-ia64_expand_load_address (dest, src, scratch)
- rtx dest, src, scratch;
-{
- rtx temp;
-
- /* The destination could be a MEM during initial rtl generation,
- which isn't a valid destination for the PIC load address patterns. */
- if (! register_operand (dest, DImode))
- if (! scratch || ! register_operand (scratch, DImode))
- temp = gen_reg_rtx (DImode);
- else
- temp = scratch;
- else
- temp = dest;
-
- if (tls_symbolic_operand (src, Pmode))
+ia64_expand_load_address (rtx dest, rtx src)
+{
+ if (tls_symbolic_operand (src, VOIDmode))
+ abort ();
+ if (GET_CODE (dest) != REG)
abort ();
- if (TARGET_AUTO_PIC)
- emit_insn (gen_load_gprel64 (temp, src));
- else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
- emit_insn (gen_load_fptr (temp, src));
- else if ((GET_MODE (src) == Pmode || GET_MODE (src) == ptr_mode)
- && sdata_symbolic_operand (src, VOIDmode))
- emit_insn (gen_load_gprel (temp, src));
- else if (GET_CODE (src) == CONST
- && GET_CODE (XEXP (src, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (src, 0), 1)) == CONST_INT
- && (INTVAL (XEXP (XEXP (src, 0), 1)) & 0x1fff) != 0)
- {
- rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
+ /* 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 (Pmode, REGNO (dest));
+
+ if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_SMALL_ADDR_P (src))
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, dest, src));
+ return;
+ }
+ else if (TARGET_AUTO_PIC)
+ {
+ emit_insn (gen_load_gprel64 (dest, src));
+ return;
+ }
+ else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (src))
+ {
+ emit_insn (gen_load_fptr (dest, src));
+ return;
+ }
+ else if (sdata_symbolic_operand (src, VOIDmode))
+ {
+ emit_insn (gen_load_gprel (dest, src));
+ return;
+ }
+
+ if (GET_CODE (src) == CONST
+ && GET_CODE (XEXP (src, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (src, 0), 1)) == CONST_INT
+ && (INTVAL (XEXP (XEXP (src, 0), 1)) & 0x1fff) != 0)
+ {
rtx sym = XEXP (XEXP (src, 0), 0);
HOST_WIDE_INT ofs, hi, lo;
@@ -1088,49 +1188,34 @@ ia64_expand_load_address (dest, src, scratch)
lo = ((ofs & 0x3fff) ^ 0x2000) - 0x2000;
hi = ofs - lo;
- if (! scratch)
- scratch = no_new_pseudos ? subtarget : gen_reg_rtx (DImode);
-
- emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi),
- scratch));
- emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
+ ia64_expand_load_address (dest, plus_constant (sym, hi));
+ emit_insn (gen_adddi3 (dest, dest, GEN_INT (lo)));
}
else
{
- rtx insn;
- if (! scratch)
- scratch = no_new_pseudos ? temp : gen_reg_rtx (DImode);
+ rtx tmp;
- insn = emit_insn (gen_load_symptr (temp, src, scratch));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (temp) != GET_MODE (src))
- src = convert_memory_address (GET_MODE (temp), src);
-#endif
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, src, REG_NOTES (insn));
- }
+ tmp = gen_rtx_HIGH (Pmode, src);
+ tmp = gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
- if (temp != dest)
- {
- if (GET_MODE (dest) != GET_MODE (temp))
- temp = convert_to_mode (GET_MODE (dest), temp, 0);
- emit_move_insn (dest, temp);
+ tmp = gen_rtx_LO_SUM (GET_MODE (dest), dest, src);
+ emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
}
}
static GTY(()) rtx gen_tls_tga;
static rtx
-gen_tls_get_addr ()
+gen_tls_get_addr (void)
{
if (!gen_tls_tga)
- {
- gen_tls_tga = init_one_libfunc ("__tls_get_addr");
- }
+ gen_tls_tga = init_one_libfunc ("__tls_get_addr");
return gen_tls_tga;
}
static GTY(()) rtx thread_pointer_rtx;
static rtx
-gen_thread_pointer ()
+gen_thread_pointer (void)
{
if (!thread_pointer_rtx)
{
@@ -1140,153 +1225,128 @@ gen_thread_pointer ()
return thread_pointer_rtx;
}
-rtx
-ia64_expand_move (op0, op1)
- rtx op0, op1;
+static rtx
+ia64_expand_tls_address (enum tls_model tls_kind, rtx op0, rtx op1)
{
- enum machine_mode mode = GET_MODE (op0);
+ rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
+ rtx orig_op0 = op0;
- if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
- op1 = force_reg (mode, op1);
-
- if (mode == Pmode || mode == ptr_mode)
+ switch (tls_kind)
{
- enum tls_model tls_kind;
- if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
- {
- rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
- rtx orig_op0 = op0;
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ start_sequence ();
- switch (tls_kind)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- start_sequence ();
-
- tga_op1 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
- tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
- RTX_UNCHANGING_P (tga_op1) = 1;
-
- tga_op2 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_dtprel (tga_op2, op1));
- tga_op2 = gen_rtx_MEM (Pmode, tga_op2);
- RTX_UNCHANGING_P (tga_op2) = 1;
-
- tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
- LCT_CONST, Pmode, 2, 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;
+ tga_op1 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
+ RTX_UNCHANGING_P (tga_op1) = 1;
- 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_op2 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtprel (tga_op2, op1));
+ tga_op2 = gen_rtx_MEM (Pmode, tga_op2);
+ RTX_UNCHANGING_P (tga_op2) = 1;
- tga_op1 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
- tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
- RTX_UNCHANGING_P (tga_op1) = 1;
+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ LCT_CONST, Pmode, 2, tga_op1,
+ Pmode, tga_op2, Pmode);
- tga_op2 = const0_rtx;
+ insns = get_insns ();
+ end_sequence ();
- tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
- LCT_CONST, Pmode, 2, tga_op1,
- Pmode, tga_op2, Pmode);
+ if (GET_MODE (op0) != Pmode)
+ op0 = tga_ret;
+ emit_libcall_block (insns, op0, tga_ret, op1);
+ break;
- insns = get_insns ();
- end_sequence ();
+ 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_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);
+ tga_op1 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
+ RTX_UNCHANGING_P (tga_op1) = 1;
- 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, tmp, op1));
- break;
+ tga_op2 = const0_rtx;
- case TLS_MODEL_INITIAL_EXEC:
- tmp = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_tprel (tmp, op1));
- tmp = gen_rtx_MEM (Pmode, tmp);
- RTX_UNCHANGING_P (tmp) = 1;
- tmp = force_reg (Pmode, tmp);
+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ LCT_CONST, Pmode, 2, tga_op1,
+ Pmode, tga_op2, Pmode);
- if (!register_operand (op0, Pmode))
- op0 = gen_reg_rtx (Pmode);
- emit_insn (gen_adddi3 (op0, tmp, gen_thread_pointer ()));
- break;
+ insns = get_insns ();
+ end_sequence ();
- case TLS_MODEL_LOCAL_EXEC:
- if (!register_operand (op0, Pmode))
- op0 = gen_reg_rtx (Pmode);
- if (TARGET_TLS64)
- {
- emit_insn (gen_load_tprel (op0, op1));
- emit_insn (gen_adddi3 (op0, gen_thread_pointer (), op0));
- }
- else
- emit_insn (gen_add_tprel (op0, gen_thread_pointer (), op1));
- break;
+ 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);
- default:
- abort ();
- }
+ 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, tmp, op1));
+ break;
- if (orig_op0 == op0)
- return NULL_RTX;
- if (GET_MODE (orig_op0) == Pmode)
- return op0;
- return gen_lowpart (GET_MODE (orig_op0), op0);
+ case TLS_MODEL_INITIAL_EXEC:
+ tmp = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_tprel (tmp, op1));
+ tmp = gen_rtx_MEM (Pmode, tmp);
+ RTX_UNCHANGING_P (tmp) = 1;
+ tmp = force_reg (Pmode, tmp);
+
+ 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);
+ if (TARGET_TLS64)
+ {
+ emit_insn (gen_load_tprel (op0, op1));
+ emit_insn (gen_adddi3 (op0, gen_thread_pointer (), op0));
}
- else if (!TARGET_NO_PIC &&
- (symbolic_operand (op1, Pmode) ||
- symbolic_operand (op1, ptr_mode)))
+ else
+ emit_insn (gen_add_tprel (op0, gen_thread_pointer (), op1));
+ break;
+
+ default:
+ abort ();
+ }
+
+ 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)
+{
+ enum 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))
+ {
+ enum tls_model tls_kind;
+ if ((tls_kind = tls_symbolic_operand (op1, VOIDmode)))
+ return ia64_expand_tls_address (tls_kind, op0, op1);
+
+ if (!TARGET_NO_PIC && reload_completed)
{
- /* Before optimization starts, delay committing to any particular
- type of PIC address load. If this function gets deferred, we
- may acquire information that changes the value of the
- sdata_symbolic_operand predicate.
-
- But don't delay for function pointers. Loading a function address
- actually loads the address of the descriptor not the function.
- If we represent these as SYMBOL_REFs, then they get cse'd with
- calls, and we end up with calls to the descriptor address instead
- of calls to the function address. Functions are not candidates
- for sdata anyways.
-
- Don't delay for LABEL_REF because the splitter loses REG_LABEL
- notes. Don't delay for pool addresses on general principals;
- they'll never become non-local behind our back. */
-
- if (rtx_equal_function_value_matters
- && GET_CODE (op1) != LABEL_REF
- && ! (GET_CODE (op1) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (op1)
- || CONSTANT_POOL_ADDRESS_P (op1)
- || STRING_POOL_ADDRESS_P (op1))))
- if (GET_MODE (op1) == DImode)
- emit_insn (gen_movdi_symbolic (op0, op1));
- else
- emit_insn (gen_movsi_symbolic (op0, op1));
- else
- ia64_expand_load_address (op0, op1, NULL_RTX);
+ ia64_expand_load_address (op0, op1);
return NULL_RTX;
}
}
@@ -1294,102 +1354,272 @@ ia64_expand_move (op0, op1)
return op1;
}
-/* Split a post-reload TImode reference into two DImode components. */
+/* Split a move from OP1 to OP0 conditional on COND. */
-rtx
-ia64_split_timode (out, in, scratch)
- rtx out[2];
- rtx in, scratch;
+void
+ia64_emit_cond_move (rtx op0, rtx op1, rtx cond)
+{
+ rtx 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[0] = gen_rtx_REG (DImode, REGNO (in));
- out[1] = gen_rtx_REG (DImode, REGNO (in) + 1);
- return NULL_RTX;
+ 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. */
+ if (reversed) abort ();
+
+ 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. */
+ {
+ REAL_VALUE_TYPE r;
+ unsigned HOST_WIDE_INT p[2];
+ long l[4]; /* TFmode is 128 bits */
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, in);
+ real_to_target (l, &r, 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[3]) << 32) + l[2];
+ p[1] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
+ }
+ 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:
- out[0] = adjust_address (in, DImode, 0);
- break;
- case POST_MODIFY:
- base = XEXP (base, 0);
- out[0] = adjust_address (in, DImode, 0);
+ 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;
- /* Since we're changing the mode, we need to change to POST_MODIFY
- as well to preserve the size of the increment. Either that or
- do the update in two steps, but we've already got this scratch
- register handy so let's use it. */
case POST_INC:
- base = XEXP (base, 0);
- out[0]
- = change_address (in, DImode,
- gen_rtx_POST_MODIFY
- (Pmode, base, plus_constant (base, 16)));
+ if (reversed || dead) abort ();
+ /* 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:
+ if (reversed || dead) abort ();
+ /* Add 8, subtract 24. */
base = XEXP (base, 0);
- out[0]
- = change_address (in, DImode,
- gen_rtx_POST_MODIFY
- (Pmode, base, plus_constant (base, -16)));
+ 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 (base, -24)),
+ 8);
+ break;
+
+ case POST_MODIFY:
+ if (reversed || dead) abort ();
+ /* 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 if (GET_CODE (XEXP (offset, 1)) != CONST_INT)
+ abort ();
+ else 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:
abort ();
}
-
- if (scratch == NULL_RTX)
- abort ();
- out[1] = change_address (in, DImode, scratch);
- return gen_adddi3 (scratch, base, GEN_INT (8));
+ break;
}
- case CONST_INT:
- case CONST_DOUBLE:
- split_double (in, &out[0], &out[1]);
- return NULL_RTX;
-
default:
abort ();
}
+
+ return fixup;
}
-/* ??? Fixing GR->FR TFmode moves during reload is hard. You need to go
+/* 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 abort. */
+ 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;
+ 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)) \
+ REG_NOTES (INSN) = gen_rtx_EXPR_LIST (REG_INC, \
+ XEXP (XEXP (EXP, 0), 0), \
+ REG_NOTES (INSN))
+
+ insn = emit_insn (gen_rtx_SET (VOIDmode, 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 (VOIDmode, 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 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:TF (reg:TI)), which we got from a union containing a long double.
+ (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. */
rtx
-spill_tfmode_operand (in, force)
- rtx in;
- int force;
+spill_xfmode_operand (rtx in, int force)
{
if (GET_CODE (in) == SUBREG
&& GET_MODE (SUBREG_REG (in)) == TImode
&& GET_CODE (SUBREG_REG (in)) == REG)
{
- rtx mem = gen_mem_addressof (SUBREG_REG (in), NULL_TREE, true);
- return gen_rtx_MEM (TFmode, copy_to_reg (XEXP (mem, 0)));
+ rtx mem = gen_mem_addressof (SUBREG_REG (in), NULL_TREE, /*rescan=*/true);
+ return gen_rtx_MEM (XFmode, copy_to_reg (XEXP (mem, 0)));
}
else if (force && GET_CODE (in) == REG)
{
- rtx mem = gen_mem_addressof (in, NULL_TREE, true);
- return gen_rtx_MEM (TFmode, copy_to_reg (XEXP (mem, 0)));
+ rtx mem = gen_mem_addressof (in, NULL_TREE, /*rescan=*/true);
+ return gen_rtx_MEM (XFmode, copy_to_reg (XEXP (mem, 0)));
}
else if (GET_CODE (in) == MEM
&& GET_CODE (XEXP (in, 0)) == ADDRESSOF)
- return change_address (in, TFmode, copy_to_reg (XEXP (in, 0)));
+ return change_address (in, XFmode, copy_to_reg (XEXP (in, 0)));
else
return in;
}
@@ -1397,10 +1627,10 @@ spill_tfmode_operand (in, force)
/* Emit comparison instruction if necessary, returning the expression
that holds the compare result in the proper mode. */
+static GTY(()) rtx cmptf_libfunc;
+
rtx
-ia64_expand_compare (code, mode)
- enum rtx_code code;
- enum machine_mode mode;
+ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
{
rtx op0 = ia64_compare_op0, op1 = ia64_compare_op1;
rtx cmp;
@@ -1414,6 +1644,59 @@ ia64_expand_compare (code, mode)
else
abort ();
}
+ /* 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 SNaN as a side effect. */
+ QCMP_UNORD = 2,
+ QCMP_EQ = 4,
+ QCMP_LT = 8,
+ QCMP_GT = 16
+ } magic;
+ enum rtx_code ncode;
+ rtx ret, insns;
+ if (GET_MODE (op1) != TFmode)
+ abort ();
+ switch (code)
+ {
+ /* 1 = equal, 0 = not equal. Equality operators do
+ not raise FP_INVALID when given an SNaN 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;
+ /* Relational operators raise FP_INVALID when given
+ an SNaN 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;
+ /* FUTURE: Implement UNEQ, UNLT, UNLE, UNGT, UNGE, LTGT.
+ Expanders for buneq etc. weuld have to be added to ia64.md
+ for this to be useful. */
+ default: abort ();
+ }
+
+ start_sequence ();
+
+ ret = emit_library_call_value (cmptf_libfunc, 0, LCT_CONST, DImode, 3,
+ op0, TFmode, op1, TFmode,
+ GEN_INT (magic), DImode);
+ cmp = gen_reg_rtx (BImode);
+ emit_insn (gen_rtx_SET (VOIDmode, cmp,
+ gen_rtx_fmt_ee (ncode, BImode,
+ ret, const0_rtx)));
+
+ 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);
@@ -1426,16 +1709,15 @@ ia64_expand_compare (code, mode)
}
/* Emit the appropriate sequence for a call. */
+
void
-ia64_expand_call (retval, addr, nextarg, sibcall_p)
- rtx retval;
- rtx addr;
- rtx nextarg ATTRIBUTE_UNUSED;
- int sibcall_p;
+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. */
@@ -1465,8 +1747,9 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
if (sibcall_p)
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), b0);
}
+
void
-ia64_reload_gp ()
+ia64_reload_gp (void)
{
rtx tmp;
@@ -1506,10 +1789,8 @@ ia64_reload_gp ()
}
void
-ia64_split_call (retval, addr, retaddr, scratch_r, scratch_b,
- noreturn_p, sibcall_p)
- rtx retval, addr, retaddr, scratch_r, scratch_b;
- int noreturn_p, sibcall_p;
+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;
@@ -1522,8 +1803,8 @@ ia64_split_call (retval, addr, retaddr, scratch_r, scratch_b,
bool addr_dead_p;
/* ??? We are currently constrained to *not* use peep2, because
- we can legitimiately change the global lifetime of the GP
- (in the form of killing where previously live). This is
+ 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.
@@ -1571,9 +1852,15 @@ ia64_split_call (retval, addr, retaddr, scratch_r, scratch_b,
/* Begin the assembly file. */
+static void
+ia64_file_start (void)
+{
+ default_file_start ();
+ emit_safe_across_calls ();
+}
+
void
-emit_safe_across_calls (f)
- FILE *f;
+emit_safe_across_calls (void)
{
unsigned int rs, re;
int out_state;
@@ -1590,19 +1877,19 @@ emit_safe_across_calls (f)
continue;
if (out_state == 0)
{
- fputs ("\t.pred.safe_across_calls ", f);
+ fputs ("\t.pred.safe_across_calls ", asm_out_file);
out_state = 1;
}
else
- fputc (',', f);
+ fputc (',', asm_out_file);
if (re == rs + 1)
- fprintf (f, "p%u", rs);
+ fprintf (asm_out_file, "p%u", rs);
else
- fprintf (f, "p%u-p%u", rs, re - 1);
+ fprintf (asm_out_file, "p%u-p%u", rs, re - 1);
rs = re + 1;
}
if (out_state)
- fputc ('\n', f);
+ fputc ('\n', asm_out_file);
}
/* Helper function for ia64_compute_frame_size: find an appropriate general
@@ -1611,8 +1898,7 @@ emit_safe_across_calls (f)
TRY_LOCALS is true if we should attempt to locate a local regnum. */
static int
-find_gr_spill (try_locals)
- int try_locals;
+find_gr_spill (int try_locals)
{
int regno;
@@ -1661,7 +1947,7 @@ find_gr_spill (try_locals)
static int last_scratch_gr_reg;
static int
-next_scratch_gr_reg ()
+next_scratch_gr_reg (void)
{
int i, regno;
@@ -1686,9 +1972,7 @@ next_scratch_gr_reg ()
diddle_return_value. Mark REG in current_frame_info.gr_used_mask. */
static void
-mark_reg_gr_used_mask (reg, data)
- rtx reg;
- void *data ATTRIBUTE_UNUSED;
+mark_reg_gr_used_mask (rtx reg, void *data ATTRIBUTE_UNUSED)
{
unsigned int regno = REGNO (reg);
if (regno < 32)
@@ -1704,8 +1988,7 @@ mark_reg_gr_used_mask (reg, data)
needed for local variables. */
static void
-ia64_compute_frame_size (size)
- HOST_WIDE_INT size;
+ia64_compute_frame_size (HOST_WIDE_INT size)
{
HOST_WIDE_INT total_size;
HOST_WIDE_INT spill_size = 0;
@@ -1767,7 +2050,7 @@ ia64_compute_frame_size (size)
i = regno - OUT_REG (0) + 1;
/* When -p profiling, we need one output register for the mcount argument.
- Likwise for -a profiling for the bb_init_func argument. For -ax
+ 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 (current_function_profile)
@@ -1778,7 +2061,7 @@ ia64_compute_frame_size (size)
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,
+ 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++)
@@ -1809,7 +2092,7 @@ ia64_compute_frame_size (size)
/* Now come all special registers that might get saved in other
general registers. */
-
+
if (frame_pointer_needed)
{
current_frame_info.reg_fp = find_gr_spill (1);
@@ -1971,8 +2254,7 @@ ia64_compute_frame_size (size)
/* Compute the initial difference between the specified pair of registers. */
HOST_WIDE_INT
-ia64_initial_elimination_offset (from, to)
- int from, to;
+ia64_initial_elimination_offset (int from, int to)
{
HOST_WIDE_INT offset;
@@ -2044,10 +2326,7 @@ struct spill_fill_data
static struct spill_fill_data spill_fill_data;
static void
-setup_spill_pointers (n_spills, init_reg, cfa_off)
- int n_spills;
- rtx init_reg;
- HOST_WIDE_INT cfa_off;
+setup_spill_pointers (int n_spills, rtx init_reg, HOST_WIDE_INT cfa_off)
{
int i;
@@ -2073,15 +2352,13 @@ setup_spill_pointers (n_spills, init_reg, cfa_off)
}
static void
-finish_spill_pointers ()
+finish_spill_pointers (void)
{
current_frame_info.gr_used_mask = spill_fill_data.save_gr_used_mask;
}
static rtx
-spill_restore_mem (reg, cfa_off)
- rtx reg;
- HOST_WIDE_INT cfa_off;
+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;
@@ -2194,10 +2471,8 @@ spill_restore_mem (reg, cfa_off)
}
static void
-do_spill (move_fn, reg, cfa_off, frame_reg)
- rtx (*move_fn) PARAMS ((rtx, rtx, rtx));
- rtx reg, frame_reg;
- HOST_WIDE_INT cfa_off;
+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, insn;
@@ -2213,7 +2488,7 @@ do_spill (move_fn, reg, cfa_off, frame_reg)
RTX_FRAME_RELATED_P (insn) = 1;
- /* Don't even pretend that the unwind code can intuit its way
+ /* 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. */
@@ -2239,10 +2514,7 @@ do_spill (move_fn, reg, cfa_off, frame_reg)
}
static void
-do_restore (move_fn, reg, cfa_off)
- rtx (*move_fn) PARAMS ((rtx, rtx, rtx));
- rtx reg;
- HOST_WIDE_INT cfa_off;
+do_restore (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off)
{
int iter = spill_fill_data.next_iter;
rtx insn;
@@ -2254,28 +2526,22 @@ do_restore (move_fn, reg, cfa_off)
/* 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 consistant function interface. */
+ use a consistent function interface. */
static rtx
-gen_movdi_x (dest, src, offset)
- rtx dest, src;
- rtx offset ATTRIBUTE_UNUSED;
+gen_movdi_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
return gen_movdi (dest, src);
}
static rtx
-gen_fr_spill_x (dest, src, offset)
- rtx dest, src;
- rtx offset ATTRIBUTE_UNUSED;
+gen_fr_spill_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
return gen_fr_spill (dest, src);
}
static rtx
-gen_fr_restore_x (dest, src, offset)
- rtx dest, src;
- rtx offset ATTRIBUTE_UNUSED;
+gen_fr_restore_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
return gen_fr_restore (dest, src);
}
@@ -2303,7 +2569,7 @@ gen_fr_restore_x (dest, src, offset)
adds instruction. */
void
-ia64_expand_prologue ()
+ia64_expand_prologue (void)
{
rtx insn, ar_pfs_save_reg, ar_unat_save_reg;
int i, epilogue_p, regno, alt_regno, cfa_off, n_varargs;
@@ -2382,7 +2648,7 @@ ia64_expand_prologue ()
regno = next_scratch_gr_reg ();
ar_pfs_save_reg = gen_rtx_REG (DImode, regno);
- insn = emit_insn (gen_alloc (ar_pfs_save_reg,
+ 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),
@@ -2412,7 +2678,7 @@ ia64_expand_prologue ()
else
{
regno = next_scratch_gr_reg ();
- offset = gen_rtx_REG (DImode, regno);
+ offset = gen_rtx_REG (DImode, regno);
emit_move_insn (offset, frame_size_rtx);
}
@@ -2630,7 +2896,7 @@ ia64_expand_prologue ()
{
if (cfa_off & 15)
abort ();
- reg = gen_rtx_REG (TFmode, regno);
+ reg = gen_rtx_REG (XFmode, regno);
do_spill (gen_fr_spill_x, reg, cfa_off, reg);
cfa_off -= 16;
}
@@ -2649,8 +2915,7 @@ ia64_expand_prologue ()
insn to prevent such scheduling. */
void
-ia64_expand_epilogue (sibcall_p)
- int sibcall_p;
+ia64_expand_epilogue (int sibcall_p)
{
rtx insn, reg, alt_reg, ar_unat_save_reg;
int regno, alt_regno, cfa_off;
@@ -2664,7 +2929,7 @@ ia64_expand_epilogue (sibcall_p)
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,
+ setup_spill_pointers (current_frame_info.n_spilled, stack_pointer_rtx,
current_frame_info.total_size);
if (current_frame_info.total_size != 0)
@@ -2716,7 +2981,7 @@ ia64_expand_epilogue (sibcall_p)
}
else
ar_unat_save_reg = NULL_RTX;
-
+
if (current_frame_info.reg_save_ar_pfs != 0)
{
alt_reg = gen_rtx_REG (DImode, current_frame_info.reg_save_ar_pfs);
@@ -2766,7 +3031,7 @@ ia64_expand_epilogue (sibcall_p)
do_restore (gen_gr_restore, reg, cfa_off);
cfa_off -= 8;
}
-
+
/* Restore the branch registers. Handle B0 specially, as it may
have gotten stored in some GR register. */
if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
@@ -2783,7 +3048,7 @@ ia64_expand_epilogue (sibcall_p)
reg = gen_rtx_REG (DImode, BR_REG (0));
emit_move_insn (reg, alt_reg);
}
-
+
for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
{
@@ -2801,7 +3066,7 @@ ia64_expand_epilogue (sibcall_p)
{
if (cfa_off & 15)
abort ();
- reg = gen_rtx_REG (TFmode, regno);
+ reg = gen_rtx_REG (XFmode, regno);
do_restore (gen_fr_restore_x, reg, cfa_off);
cfa_off -= 16;
}
@@ -2867,17 +3132,17 @@ ia64_expand_epilogue (sibcall_p)
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,
+ 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 assmbler. */
+ the register name for the assembler. */
if (current_frame_info.reg_fp && current_frame_info.reg_fp == GR_REG (2))
fp = HARD_FRAME_POINTER_REGNUM;
@@ -2900,7 +3165,7 @@ ia64_expand_epilogue (sibcall_p)
function. */
int
-ia64_direct_return ()
+ia64_direct_return (void)
{
if (reload_completed && ! frame_pointer_needed)
{
@@ -2921,9 +3186,7 @@ ia64_direct_return ()
during early compilation. */
rtx
-ia64_return_addr_rtx (count, frame)
- HOST_WIDE_INT count;
- rtx frame ATTRIBUTE_UNUSED;
+ia64_return_addr_rtx (HOST_WIDE_INT count, rtx frame ATTRIBUTE_UNUSED)
{
if (count != 0)
return NULL;
@@ -2934,8 +3197,7 @@ ia64_return_addr_rtx (count, frame)
address is saved. */
void
-ia64_split_return_addr_rtx (dest)
- rtx dest;
+ia64_split_return_addr_rtx (rtx dest)
{
rtx src;
@@ -2984,9 +3246,7 @@ ia64_split_return_addr_rtx (dest)
}
int
-ia64_hard_regno_rename_ok (from, to)
- int from;
- int to;
+ia64_hard_regno_rename_ok (int from, int to)
{
/* Don't clobber any of the registers we reserved for the prologue. */
if (to == current_frame_info.reg_fp
@@ -3020,18 +3280,15 @@ ia64_hard_regno_rename_ok (from, to)
aligned objects and detect the cases when @fptr is needed. */
static bool
-ia64_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+ia64_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
- if (size == (TARGET_ILP32 ? 4 : 8)
+ if (size == POINTER_SIZE / BITS_PER_UNIT
&& aligned_p
&& !(TARGET_NO_PIC || TARGET_AUTO_PIC)
&& GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_FLAG (x))
+ && SYMBOL_REF_FUNCTION_P (x))
{
- if (TARGET_ILP32)
+ if (POINTER_SIZE == 32)
fputs ("\tdata4\t@fptr(", asm_out_file);
else
fputs ("\tdata8\t@fptr(", asm_out_file);
@@ -3045,9 +3302,7 @@ ia64_assemble_integer (x, size, aligned_p)
/* Emit the function prologue. */
static void
-ia64_output_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+ia64_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
int mask, grsave, grsave_prev;
@@ -3097,7 +3352,7 @@ ia64_output_function_prologue (file, size)
grsave = current_frame_info.reg_save_pr;
}
- if (mask)
+ if (mask && TARGET_GNU_AS)
fprintf (file, "\t.prologue %d, %d\n", mask,
ia64_dbx_register_number (grsave));
else
@@ -3114,8 +3369,7 @@ ia64_output_function_prologue (file, size)
/* Emit the .body directive at the scheduled end of the prologue. */
static void
-ia64_output_function_end_prologue (file)
- FILE *file;
+ia64_output_function_end_prologue (FILE *file)
{
if (!flag_unwind_tables && (!flag_exceptions || USING_SJLJ_EXCEPTIONS))
return;
@@ -3126,9 +3380,8 @@ ia64_output_function_end_prologue (file)
/* Emit the function epilogue. */
static void
-ia64_output_function_epilogue (file, size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+ia64_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
int i;
@@ -3153,8 +3406,7 @@ ia64_output_function_epilogue (file, size)
}
int
-ia64_dbx_register_number (regno)
- int regno;
+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
@@ -3179,11 +3431,24 @@ ia64_dbx_register_number (regno)
}
void
-ia64_initialize_trampoline (addr, fnaddr, static_chain)
- rtx addr, fnaddr, static_chain;
+ia64_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain)
{
rtx addr_reg, 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");
+ }
+ }
+
/* Load up our iterator. */
addr_reg = gen_reg_rtx (Pmode);
emit_move_insn (addr_reg, addr);
@@ -3212,12 +3477,9 @@ ia64_initialize_trampoline (addr, fnaddr, static_chain)
We generate the actual spill instructions during prologue generation. */
void
-ia64_setup_incoming_varargs (cum, int_mode, type, pretend_size, second_time)
- CUMULATIVE_ARGS cum;
- int int_mode;
- tree type;
- int * pretend_size;
- int second_time ATTRIBUTE_UNUSED;
+ia64_setup_incoming_varargs (CUMULATIVE_ARGS cum, int int_mode, tree type,
+ int * pretend_size,
+ int second_time ATTRIBUTE_UNUSED)
{
/* Skip the current argument. */
ia64_function_arg_advance (&cum, int_mode, type, 1);
@@ -3239,9 +3501,7 @@ ia64_setup_incoming_varargs (cum, int_mode, type, pretend_size, second_time)
SFmode). 128-bit quad-precision floats are excluded. */
static enum machine_mode
-hfa_element_mode (type, nested)
- tree type;
- int nested;
+hfa_element_mode (tree type, int nested)
{
enum machine_mode element_mode = VOIDmode;
enum machine_mode mode;
@@ -3263,16 +3523,15 @@ hfa_element_mode (type, nested)
types though. */
case COMPLEX_TYPE:
if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT
- && (TYPE_MODE (type) != TCmode || INTEL_EXTENDED_IEEE_FORMAT))
- return mode_for_size (GET_MODE_UNIT_SIZE (TYPE_MODE (type))
- * BITS_PER_UNIT, MODE_FLOAT, 0);
+ && 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 || INTEL_EXTENDED_IEEE_FORMAT))
+ if (nested && TYPE_MODE (type) != TFmode)
return TYPE_MODE (type);
else
return VOIDmode;
@@ -3315,40 +3574,62 @@ hfa_element_mode (type, nested)
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 (tree type, enum 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 (CUMULATIVE_ARGS *cum, tree type, int words)
+{
+ if ((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. */
rtx
-ia64_function_arg (cum, mode, type, named, incoming)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
- int incoming;
+ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
+ int named, int incoming)
{
int basereg = (incoming ? GR_ARG_FIRST : AR_ARG_FIRST);
- int words = (((mode == BLKmode ? int_size_in_bytes (type)
- : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
- / UNITS_PER_WORD);
- int offset = 0;
+ int words = ia64_function_arg_words (type, mode);
+ int offset = ia64_function_arg_offset (cum, type, words);
enum machine_mode hfa_mode = VOIDmode;
- /* 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. Net effect is that types with
- alignment greater than 8 start at the next even boundary. */
- /* ??? 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. */
- if ((type ? (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
- : (words > 1))
- && (cum->words & 1))
- offset = 1;
-
/* If all argument slots are used, then it must go on the stack. */
if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
return 0;
@@ -3408,6 +3689,7 @@ ia64_function_arg (cum, mode, type, named, incoming)
for (; offset < byte_size && int_regs < MAX_ARGUMENT_SLOTS; i++)
{
enum 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
@@ -3421,22 +3703,25 @@ ia64_function_arg (cum, mode, type, named, incoming)
adjusted/little endian. */
else if (byte_size - offset == 4)
gr_mode = SImode;
- /* Complex floats need to have float mode. */
- if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
- gr_mode = hfa_mode;
loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (gr_mode, (basereg
+ int_regs)),
GEN_INT (offset));
- offset += GET_MODE_SIZE (gr_mode);
- int_regs += GET_MODE_SIZE (gr_mode) <= UNITS_PER_WORD
- ? 1 : GET_MODE_SIZE (gr_mode) / UNITS_PER_WORD;
+
+ 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;
}
- /* If we ended up using just one location, just return that one loc. */
+ /* If we ended up using just one location, just return that one loc, but
+ change the mode back to the argument mode. */
if (i == 1)
- return XEXP (loc[0], 0);
+ return gen_rtx_REG (mode, REGNO (XEXP (loc[0], 0)));
else
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
@@ -3444,8 +3729,8 @@ ia64_function_arg (cum, mode, type, named, incoming)
/* 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 (((mode == TFmode) && ! INTEL_EXTENDED_IEEE_FORMAT)
- || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
+ else if (mode == TFmode || mode == TCmode
+ || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
{
int byte_size = ((mode == BLKmode)
? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
@@ -3467,24 +3752,37 @@ ia64_function_arg (cum, mode, type, named, incoming)
}
/* If there is a prototype, then FP values go in a FR register when
- named, and in a GR registeer when unnamed. */
+ named, and in a GR register when unnamed. */
else if (cum->prototype)
{
- if (! named)
- return gen_rtx_REG (mode, basereg + cum->words + offset);
- else
+ if (named)
return gen_rtx_REG (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 && mode == SFmode)
+ return gen_rtx_PARALLEL (mode,
+ gen_rtvec (1,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (DImode, basereg + cum->words + offset),
+ const0_rtx)));
+ else
+ return gen_rtx_REG (mode, basereg + cum->words + offset);
}
/* If there is no prototype, then FP values go in both FR and GR
registers. */
else
{
+ /* See comment above. */
+ enum machine_mode inner_mode =
+ (BYTES_BIG_ENDIAN && mode == SFmode) ? DImode : mode;
+
rtx fp_reg = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (mode, (FR_ARG_FIRST
+ cum->fp_regs)),
const0_rtx);
rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode,
+ gen_rtx_REG (inner_mode,
(basereg + cum->words
+ offset)),
const0_rtx);
@@ -3498,23 +3796,11 @@ ia64_function_arg (cum, mode, type, named, incoming)
in memory. */
int
-ia64_function_arg_partial_nregs (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
-{
- int words = (((mode == BLKmode ? int_size_in_bytes (type)
- : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
- / UNITS_PER_WORD);
- int offset = 0;
-
- /* Arguments with alignment larger than 8 bytes start at the next even
- boundary. */
- if ((type ? (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
- : (words > 1))
- && (cum->words & 1))
- offset = 1;
+ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named ATTRIBUTE_UNUSED)
+{
+ int words = ia64_function_arg_words (type, mode);
+ int offset = ia64_function_arg_offset (cum, type, words);
/* If all argument slots are used, then it must go on the stack. */
if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
@@ -3535,29 +3821,17 @@ ia64_function_arg_partial_nregs (cum, mode, type, named)
ia64_function_arg. */
void
-ia64_function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
-{
- int words = (((mode == BLKmode ? int_size_in_bytes (type)
- : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
- / UNITS_PER_WORD);
- int offset = 0;
+ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
+{
+ int words = ia64_function_arg_words (type, mode);
+ int offset = ia64_function_arg_offset (cum, type, words);
enum machine_mode hfa_mode = VOIDmode;
/* If all arg slots are already full, then there is nothing to do. */
if (cum->words >= MAX_ARGUMENT_SLOTS)
return;
- /* Arguments with alignment larger than 8 bytes start at the next even
- boundary. */
- if ((type ? (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
- : (words > 1))
- && (cum->words & 1))
- offset = 1;
-
cum->words += words + offset;
/* Check for and handle homogeneous FP aggregates. */
@@ -3607,7 +3881,7 @@ ia64_function_arg_advance (cum, mode, type, named)
cum->int_regs = cum->words;
/* If there is a prototype, then FP values go in a FR register when
- named, and in a GR registeer when unnamed. */
+ named, and in a GR register when unnamed. */
else if (cum->prototype)
{
if (! named)
@@ -3619,7 +3893,7 @@ ia64_function_arg_advance (cum, mode, type, named)
/* 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 (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
cum->int_regs = cum->words;
@@ -3630,34 +3904,49 @@ ia64_function_arg_advance (cum, mode, type, named)
/* ??? At present this is a GCC extension to the IA-64 ABI. */
int
-ia64_function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type;
- int named ATTRIBUTE_UNUSED;
+ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, int named ATTRIBUTE_UNUSED)
{
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
}
+
+/* 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 must always return with our current GP. This means we can
+ only sibcall to functions defined in the current module. */
+ return decl && (*targetm.binds_local_p) (decl);
+}
/* Implement va_arg. */
rtx
-ia64_va_arg (valist, type)
- tree valist, type;
+ia64_va_arg (tree valist, tree type)
{
tree t;
/* Variable sized types are passed by reference. */
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
- rtx addr = std_expand_builtin_va_arg (valist, build_pointer_type (type));
- return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
+ rtx addr = force_reg (ptr_mode,
+ std_expand_builtin_va_arg (valist, build_pointer_type (type)));
+#ifdef POINTERS_EXTEND_UNSIGNED
+ addr = convert_memory_address (Pmode, addr);
+#endif
+ return gen_rtx_MEM (ptr_mode, addr);
}
- /* Arguments with alignment larger than 8 bytes start at the next even
- boundary. */
- if (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
+ /* 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)
{
t = build (PLUS_EXPR, TREE_TYPE (valist), valist,
build_int_2 (2 * UNITS_PER_WORD - 1, 0));
@@ -3675,8 +3964,7 @@ ia64_va_arg (valist, type)
in a register. */
int
-ia64_return_in_memory (valtype)
- tree valtype;
+ia64_return_in_memory (tree valtype)
{
enum machine_mode mode;
enum machine_mode hfa_mode;
@@ -3712,9 +4000,7 @@ ia64_return_in_memory (valtype)
/* Return rtx for register that holds the function return value. */
rtx
-ia64_function_value (valtype, func)
- tree valtype;
- tree func ATTRIBUTE_UNUSED;
+ia64_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
{
enum machine_mode mode;
enum machine_mode hfa_mode;
@@ -3747,8 +4033,7 @@ ia64_function_value (valtype, func)
else
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
- else if (FLOAT_TYPE_P (valtype) &&
- ((mode != TFmode) || INTEL_EXTENDED_IEEE_FORMAT))
+ else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
return gen_rtx_REG (mode, FR_ARG_FIRST);
else
{
@@ -3777,15 +4062,27 @@ ia64_function_value (valtype, func)
}
}
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+ia64_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ if (size != 8)
+ abort ();
+ 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. */
void
-ia64_print_operand_address (stream, address)
- FILE * stream ATTRIBUTE_UNUSED;
- rtx address ATTRIBUTE_UNUSED;
+ia64_print_operand_address (FILE * stream ATTRIBUTE_UNUSED,
+ rtx address ATTRIBUTE_UNUSED)
{
}
@@ -3810,10 +4107,7 @@ ia64_print_operand_address (stream, address)
r Print register name, or constant 0 as r0. HP compatibility for
Linux kernel. */
void
-ia64_print_operand (file, x, code)
- FILE * file;
- rtx x;
- int code;
+ia64_print_operand (FILE * file, rtx x, int code)
{
const char *str;
@@ -3921,9 +4215,7 @@ ia64_print_operand (file, x, code)
break;
}
- putc (',', file);
- putc (' ', file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, value);
+ fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC, value);
return;
}
@@ -3974,7 +4266,7 @@ ia64_print_operand (file, x, code)
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);
@@ -4047,13 +4339,88 @@ ia64_print_operand (file, x, code)
return;
}
-/* Calulate the cost of moving data from a register in class FROM to
+/* 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, int code, int outer_code, int *total)
+{
+ switch (code)
+ {
+ case CONST_INT:
+ switch (outer_code)
+ {
+ case SET:
+ *total = CONST_OK_FOR_J (INTVAL (x)) ? 0 : COSTS_N_INSNS (1);
+ return true;
+ case PLUS:
+ if (CONST_OK_FOR_I (INTVAL (x)))
+ *total = 0;
+ else if (CONST_OK_FOR_J (INTVAL (x)))
+ *total = 1;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ default:
+ if (CONST_OK_FOR_K (INTVAL (x)) || CONST_OK_FOR_L (INTVAL (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 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. */
+ /* ??? Check for FP mode. */
+ if (GET_MODE_SIZE (GET_MODE (x)) > 2)
+ *total = COSTS_N_INSNS (10);
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ 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. */
int
-ia64_register_move_cost (mode, from, to)
- enum machine_mode mode;
- enum reg_class from, to;
+ia64_register_move_cost (enum machine_mode mode, enum reg_class from,
+ enum reg_class to)
{
/* ADDL_REGS is the same as GR_REGS for movement purposes. */
if (to == ADDL_REGS)
@@ -4069,11 +4436,11 @@ ia64_register_move_cost (mode, from, to)
to = from, from = tmp;
}
- /* Moving from FR<->GR in TFmode must be more expensive than 2,
+ /* 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 == TFmode)
+ if (mode == XFmode)
{
if (to != GR_REGS || from != GR_REGS)
return MEMORY_MOVE_COST (mode, to, 0);
@@ -4125,10 +4492,8 @@ ia64_register_move_cost (mode, from, to)
is required. */
enum reg_class
-ia64_secondary_reload_class (class, mode, x)
- enum reg_class class;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx x;
+ia64_secondary_reload_class (enum reg_class class,
+ enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
int regno = -1;
@@ -4162,10 +4527,10 @@ ia64_secondary_reload_class (class, mode, x)
break;
case FR_REGS:
- /* Need to go through general regsters to get to other class 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
@@ -4206,28 +4571,19 @@ ia64_secondary_reload_class (class, mode, x)
return GR_REGS;
break;
- case GR_REGS:
- /* Since we have no offsettable memory addresses, we need a temporary
- to hold the address of the second word. */
- if (mode == TImode)
- return GR_REGS;
- break;
-
default:
break;
}
return NO_REGS;
}
+
/* Emit text to declare externally defined variables and functions, because
the Intel assembler does not support undefined externals. */
void
-ia64_asm_output_external (file, decl, name)
- FILE *file;
- tree decl;
- const char *name;
+ia64_asm_output_external (FILE *file, tree decl, const char *name)
{
int save_referenced;
@@ -4237,7 +4593,7 @@ ia64_asm_output_external (file, decl, name)
if (TARGET_GNU_AS
&& (!TARGET_HPUX_LD
|| TREE_CODE (decl) != FUNCTION_DECL
- || strstr(name, "__builtin_") == name))
+ || strstr (name, "__builtin_") == name))
return;
/* ??? The Intel assembler creates a reference that needs to be satisfied by
@@ -4253,7 +4609,7 @@ ia64_asm_output_external (file, decl, name)
return;
if (TARGET_HPUX_LD)
- ia64_hpux_add_extern_decl (name);
+ ia64_hpux_add_extern_decl (decl);
else
{
/* assemble_name will set TREE_SYMBOL_REFERENCED, so we must save and
@@ -4269,8 +4625,7 @@ ia64_asm_output_external (file, decl, name)
/* Parse the -mfixed-range= option string. */
static void
-fix_range (const_str)
- const char *const_str;
+fix_range (const char *const_str)
{
int i, first, last;
char *str, *dash, *comma;
@@ -4333,7 +4688,7 @@ fix_range (const_str)
}
static struct machine_function *
-ia64_init_machine_status ()
+ia64_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (struct machine_function));
}
@@ -4341,8 +4696,25 @@ ia64_init_machine_status ()
/* Handle TARGET_OPTIONS switches. */
void
-ia64_override_options ()
+ia64_override_options (void)
{
+ static struct pta
+ {
+ const char *const name; /* processor name or nickname. */
+ const enum processor_type processor;
+ }
+ const processor_alias_table[] =
+ {
+ {"itanium", PROCESSOR_ITANIUM},
+ {"itanium1", PROCESSOR_ITANIUM},
+ {"merced", PROCESSOR_ITANIUM},
+ {"itanium2", PROCESSOR_ITANIUM2},
+ {"mckinley", PROCESSOR_ITANIUM2},
+ };
+
+ int const pta_size = ARRAY_SIZE (processor_alias_table);
+ int i;
+
if (TARGET_AUTO_PIC)
target_flags |= MASK_CONST_GP;
@@ -4358,6 +4730,18 @@ ia64_override_options ()
target_flags &= ~MASK_INLINE_INT_DIV_THR;
}
+ if (TARGET_INLINE_SQRT_LAT && TARGET_INLINE_SQRT_THR)
+ {
+ warning ("cannot optimize square root for both latency and throughput");
+ target_flags &= ~MASK_INLINE_SQRT_THR;
+ }
+
+ if (TARGET_INLINE_SQRT_LAT)
+ {
+ warning ("not yet implemented: latency-optimized inline square root");
+ target_flags &= ~MASK_INLINE_SQRT_LAT;
+ }
+
if (ia64_fixed_range_string)
fix_range (ia64_fixed_range_string);
@@ -4371,35 +4755,32 @@ ia64_override_options ()
ia64_tls_size = tmp;
}
+ if (!ia64_tune_string)
+ ia64_tune_string = "itanium2";
+
+ for (i = 0; i < pta_size; i++)
+ if (! strcmp (ia64_tune_string, processor_alias_table[i].name))
+ {
+ ia64_tune = processor_alias_table[i].processor;
+ break;
+ }
+
+ if (i == pta_size)
+ error ("bad value (%s) for -tune= switch", ia64_tune_string);
+
ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
flag_schedule_insns_after_reload = 0;
ia64_section_threshold = g_switch_set ? g_switch_value : IA64_DEFAULT_GVALUE;
init_machine_status = ia64_init_machine_status;
-
- /* Tell the compiler which flavor of TFmode we're using. */
- if (INTEL_EXTENDED_IEEE_FORMAT)
- real_format_for_mode[TFmode - QFmode] = &ieee_extended_intel_128_format;
}
-static enum attr_itanium_requires_unit0 ia64_safe_itanium_requires_unit0 PARAMS((rtx));
-static enum attr_itanium_class ia64_safe_itanium_class PARAMS((rtx));
-static enum attr_type ia64_safe_type PARAMS((rtx));
-
-static enum attr_itanium_requires_unit0
-ia64_safe_itanium_requires_unit0 (insn)
- rtx insn;
-{
- if (recog_memoized (insn) >= 0)
- return get_attr_itanium_requires_unit0 (insn);
- else
- return ITANIUM_REQUIRES_UNIT0_NO;
-}
+static enum attr_itanium_class ia64_safe_itanium_class (rtx);
+static enum attr_type ia64_safe_type (rtx);
static enum attr_itanium_class
-ia64_safe_itanium_class (insn)
- rtx insn;
+ia64_safe_itanium_class (rtx insn)
{
if (recog_memoized (insn) >= 0)
return get_attr_itanium_class (insn);
@@ -4408,8 +4789,7 @@ ia64_safe_itanium_class (insn)
}
static enum attr_type
-ia64_safe_type (insn)
- rtx insn;
+ia64_safe_type (rtx insn)
{
if (recog_memoized (insn) >= 0)
return get_attr_type (insn);
@@ -4487,26 +4867,21 @@ struct reg_flags
unsigned int is_sibcall : 1; /* Is this a sibling or normal call? */
};
-static void rws_update PARAMS ((struct reg_write_state *, int,
- struct reg_flags, int));
-static int rws_access_regno PARAMS ((int, struct reg_flags, int));
-static int rws_access_reg PARAMS ((rtx, struct reg_flags, int));
-static void update_set_flags PARAMS ((rtx, struct reg_flags *, int *, rtx *));
-static int set_src_needs_barrier PARAMS ((rtx, struct reg_flags, int, rtx));
-static int rtx_needs_barrier PARAMS ((rtx, struct reg_flags, int));
-static void init_insn_group_barriers PARAMS ((void));
-static int group_barrier_needed_p PARAMS ((rtx));
-static int safe_group_barrier_needed_p PARAMS ((rtx));
+static void rws_update (struct reg_write_state *, 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 *, int *, rtx *);
+static int set_src_needs_barrier (rtx, struct reg_flags, int, rtx);
+static int rtx_needs_barrier (rtx, struct reg_flags, int);
+static void init_insn_group_barriers (void);
+static int group_barrier_needed_p (rtx);
+static int safe_group_barrier_needed_p (rtx);
/* 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 (rws, regno, flags, pred)
- struct reg_write_state *rws;
- int regno;
- struct reg_flags flags;
- int pred;
+rws_update (struct reg_write_state *rws, int regno, struct reg_flags flags, int pred)
{
if (pred)
rws[regno].write_count++;
@@ -4524,10 +4899,7 @@ rws_update (rws, regno, flags, pred)
a dependency with an earlier instruction in the same group. */
static int
-rws_access_regno (regno, flags, pred)
- int regno;
- struct reg_flags flags;
- int pred;
+rws_access_regno (int regno, struct reg_flags flags, int pred)
{
int need_barrier = 0;
@@ -4562,7 +4934,7 @@ rws_access_regno (regno, flags, pred)
/* ??? This assumes that P and P+1 are always complementary
predicates for P even. */
if (flags.is_and && rws_sum[regno].written_by_and)
- ;
+ ;
else if (flags.is_or && rws_sum[regno].written_by_or)
;
else if ((rws_sum[regno].first_pred ^ 1) != pred)
@@ -4645,10 +5017,7 @@ rws_access_regno (regno, flags, pred)
}
static int
-rws_access_reg (reg, flags, pred)
- rtx reg;
- struct reg_flags flags;
- int pred;
+rws_access_reg (rtx reg, struct reg_flags flags, int pred)
{
int regno = REGNO (reg);
int n = HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg));
@@ -4668,11 +5037,7 @@ rws_access_reg (reg, flags, pred)
the condition, stored in *PFLAGS, *PPRED and *PCOND. */
static void
-update_set_flags (x, pflags, ppred, pcond)
- rtx x;
- struct reg_flags *pflags;
- int *ppred;
- rtx *pcond;
+update_set_flags (rtx x, struct reg_flags *pflags, int *ppred, rtx *pcond)
{
rtx src = SET_SRC (x);
@@ -4686,7 +5051,7 @@ update_set_flags (x, pflags, ppred, pcond)
case IF_THEN_ELSE:
if (SET_DEST (x) == pc_rtx)
/* X is a conditional branch. */
- return;
+ return;
else
{
int is_complemented = 0;
@@ -4749,13 +5114,9 @@ update_set_flags (x, pflags, ppred, pcond)
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 (x, flags, pred, cond)
- rtx x;
- struct reg_flags flags;
- int pred;
- rtx cond;
+set_src_needs_barrier (rtx x, struct reg_flags flags, int pred, rtx cond)
{
int need_barrier = 0;
rtx dst;
@@ -4790,15 +5151,12 @@ set_src_needs_barrier (x, flags, pred, cond)
return need_barrier;
}
-/* Handle an access to rtx X of type FLAGS using predicate register PRED.
- Return 1 is this access creates a dependency with an earlier instruction
- in the same group. */
+/* 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 (x, flags, pred)
- rtx x;
- struct reg_flags flags;
- int pred;
+rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
{
int i, j;
int is_complemented = 0;
@@ -4814,7 +5172,7 @@ rtx_needs_barrier (x, flags, pred)
switch (GET_CODE (x))
{
- case SET:
+ case SET:
update_set_flags (x, &new_flags, &pred, &cond);
need_barrier = set_src_needs_barrier (x, new_flags, pred, cond);
if (GET_CODE (SET_SRC (x)) != CALL)
@@ -4984,7 +5342,7 @@ rtx_needs_barrier (x, flags, pred)
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 SQRT: case FFS: case POPCOUNT:
need_barrier = rtx_needs_barrier (XEXP (x, 0), flags, pred);
break;
@@ -5017,14 +5375,13 @@ rtx_needs_barrier (x, flags, pred)
new_flags, pred);
break;
}
-
+
case UNSPEC_FR_SPILL:
case UNSPEC_FR_RESTORE:
- case UNSPEC_POPCNT:
- need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
- break;
-
+ case UNSPEC_GETF_EXP:
+ case UNSPEC_SETF_EXP:
case UNSPEC_ADDP4:
+ case UNSPEC_FR_SQRT_RECIP_APPROX:
need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
break;
@@ -5122,7 +5479,7 @@ rtx_needs_barrier (x, flags, pred)
sequence of insns. */
static void
-init_insn_group_barriers ()
+init_insn_group_barriers (void)
{
memset (rws_sum, 0, sizeof (rws_sum));
first_instruction = 1;
@@ -5133,8 +5490,7 @@ init_insn_group_barriers ()
Return nonzero if so. */
static int
-group_barrier_needed_p (insn)
- rtx insn;
+group_barrier_needed_p (rtx insn)
{
rtx pat;
int need_barrier = 0;
@@ -5230,7 +5586,10 @@ group_barrier_needed_p (insn)
abort ();
}
- if (first_instruction)
+ if (first_instruction && INSN_P (insn)
+ && ia64_safe_itanium_class (insn) != ITANIUM_CLASS_IGNORE
+ && GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER)
{
need_barrier = 0;
first_instruction = 0;
@@ -5242,8 +5601,7 @@ group_barrier_needed_p (insn)
/* Like group_barrier_needed_p, but do not clobber the current state. */
static int
-safe_group_barrier_needed_p (insn)
- rtx insn;
+safe_group_barrier_needed_p (rtx insn)
{
struct reg_write_state rws_saved[NUM_REGS];
int saved_first_instruction;
@@ -5260,17 +5618,15 @@ safe_group_barrier_needed_p (insn)
return t;
}
-/* INSNS is an chain of instructions. Scan the chain, and insert stop bits
- as necessary to eliminate dependendencies. 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. */
+/* 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 (dump, insns)
- FILE *dump;
- rtx insns;
+emit_insn_group_barriers (FILE *dump)
{
rtx insn;
rtx last_label = 0;
@@ -5278,7 +5634,7 @@ emit_insn_group_barriers (dump, insns)
init_insn_group_barriers ();
- for (insn = insns; insn; insn = NEXT_INSN (insn))
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) == CODE_LABEL)
{
@@ -5326,15 +5682,13 @@ emit_insn_group_barriers (dump, insns)
This function has to emit all necessary group barriers. */
static void
-emit_all_insn_group_barriers (dump, insns)
- FILE *dump ATTRIBUTE_UNUSED;
- rtx insns;
+emit_all_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
{
rtx insn;
init_insn_group_barriers ();
- for (insn = insns; insn; insn = NEXT_INSN (insn))
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) == BARRIER)
{
@@ -5363,10 +5717,11 @@ emit_all_insn_group_barriers (dump, insns)
}
}
}
+
-static int errata_find_address_regs PARAMS ((rtx *, void *));
-static void errata_emit_nops PARAMS ((rtx));
-static void fixup_errata PARAMS ((void));
+static int errata_find_address_regs (rtx *, void *);
+static void errata_emit_nops (rtx);
+static void fixup_errata (void);
/* This structure is used to track some details about the previous insns
groups so we can determine if it may be necessary to insert NOPs to
@@ -5384,9 +5739,7 @@ static int group_idx;
conditionally set in the previous group is used as an address register.
It ensures that for_each_rtx returns 1 in that case. */
static int
-errata_find_address_regs (xp, data)
- rtx *xp;
- void *data ATTRIBUTE_UNUSED;
+errata_find_address_regs (rtx *xp, void *data ATTRIBUTE_UNUSED)
{
rtx x = *xp;
if (GET_CODE (x) != MEM)
@@ -5409,8 +5762,7 @@ errata_find_address_regs (xp, data)
last_group and emits additional NOPs if necessary to work around
an Itanium A/B step erratum. */
static void
-errata_emit_nops (insn)
- rtx insn;
+errata_emit_nops (rtx insn)
{
struct group *this_group = last_group + group_idx;
struct group *prev_group = last_group + (group_idx ^ 1);
@@ -5483,7 +5835,7 @@ errata_emit_nops (insn)
/* Emit extra nops if they are required to work around hardware errata. */
static void
-fixup_errata ()
+fixup_errata (void)
{
rtx insn;
@@ -5508,153 +5860,106 @@ fixup_errata ()
}
}
-/* Instruction scheduling support. */
-/* Describe one bundle. */
-struct bundle
-{
- /* Zero if there's no possibility of a stop in this bundle other than
- at the end, otherwise the position of the optional stop bit. */
- int possible_stop;
- /* The types of the three slots. */
- enum attr_type t[3];
- /* The pseudo op to be emitted into the assembler output. */
- const char *name;
-};
+/* Instruction scheduling support. */
#define NR_BUNDLES 10
-/* A list of all available bundles. */
+/* A list of names of all available bundles. */
-static const struct bundle bundle[NR_BUNDLES] =
+static const char *bundle_name [NR_BUNDLES] =
{
- { 2, { TYPE_M, TYPE_I, TYPE_I }, ".mii" },
- { 1, { TYPE_M, TYPE_M, TYPE_I }, ".mmi" },
- { 0, { TYPE_M, TYPE_F, TYPE_I }, ".mfi" },
- { 0, { TYPE_M, TYPE_M, TYPE_F }, ".mmf" },
+ ".mii",
+ ".mmi",
+ ".mfi",
+ ".mmf",
#if NR_BUNDLES == 10
- { 0, { TYPE_B, TYPE_B, TYPE_B }, ".bbb" },
- { 0, { TYPE_M, TYPE_B, TYPE_B }, ".mbb" },
+ ".bbb",
+ ".mbb",
#endif
- { 0, { TYPE_M, TYPE_I, TYPE_B }, ".mib" },
- { 0, { TYPE_M, TYPE_M, TYPE_B }, ".mmb" },
- { 0, { TYPE_M, TYPE_F, TYPE_B }, ".mfb" },
- /* .mfi needs to occur earlier than .mlx, so that we only generate it if
- it matches an L type insn. Otherwise we'll try to generate L type
- nops. */
- { 0, { TYPE_M, TYPE_L, TYPE_X }, ".mlx" }
+ ".mib",
+ ".mmb",
+ ".mfb",
+ ".mlx"
};
-/* Describe a packet of instructions. Packets consist of two bundles that
- are visible to the hardware in one scheduling window. */
+/* Nonzero if we should insert stop bits into the schedule. */
-struct ia64_packet
-{
- const struct bundle *t1, *t2;
- /* Precomputed value of the first split issue in this packet if a cycle
- starts at its beginning. */
- int first_split;
- /* For convenience, the insn types are replicated here so we don't have
- to go through T1 and T2 all the time. */
- enum attr_type t[6];
-};
+int ia64_final_schedule = 0;
-/* An array containing all possible packets. */
-#define NR_PACKETS (NR_BUNDLES * NR_BUNDLES)
-static struct ia64_packet packets[NR_PACKETS];
+/* Codes of the corresponding quieryied units: */
-/* Map attr_type to a string with the name. */
+static int _0mii_, _0mmi_, _0mfi_, _0mmf_;
+static int _0bbb_, _0mbb_, _0mib_, _0mmb_, _0mfb_, _0mlx_;
-static const char *const type_names[] =
-{
- "UNKNOWN", "A", "I", "M", "F", "B", "L", "X", "S"
-};
+static int _1mii_, _1mmi_, _1mfi_, _1mmf_;
+static int _1bbb_, _1mbb_, _1mib_, _1mmb_, _1mfb_, _1mlx_;
-/* Nonzero if we should insert stop bits into the schedule. */
-int ia64_final_schedule = 0;
+static int pos_1, pos_2, pos_3, pos_4, pos_5, pos_6;
-static int itanium_split_issue PARAMS ((const struct ia64_packet *, int));
-static rtx ia64_single_set PARAMS ((rtx));
-static int insn_matches_slot PARAMS ((const struct ia64_packet *, enum attr_type, int, rtx));
-static void ia64_emit_insn_before PARAMS ((rtx, rtx));
-static void maybe_rotate PARAMS ((FILE *));
-static void finish_last_head PARAMS ((FILE *, int));
-static void rotate_one_bundle PARAMS ((FILE *));
-static void rotate_two_bundles PARAMS ((FILE *));
-static void nop_cycles_until PARAMS ((int, FILE *));
-static void cycle_end_fill_slots PARAMS ((FILE *));
-static int packet_matches_p PARAMS ((const struct ia64_packet *, int, int *));
-static int get_split PARAMS ((const struct ia64_packet *, int));
-static int find_best_insn PARAMS ((rtx *, enum attr_type *, int,
- const struct ia64_packet *, int));
-static void find_best_packet PARAMS ((int *, const struct ia64_packet **,
- rtx *, enum attr_type *, int));
-static int itanium_reorder PARAMS ((FILE *, rtx *, rtx *, int));
-static void dump_current_packet PARAMS ((FILE *));
-static void schedule_stop PARAMS ((FILE *));
-static rtx gen_nop_type PARAMS ((enum attr_type));
-static void ia64_emit_nops PARAMS ((void));
+/* The following variable value is an insn group barrier. */
-/* Map a bundle number to its pseudo-op. */
+static rtx dfa_stop_insn;
-const char *
-get_bundle_name (b)
- int b;
-{
- return bundle[b].name;
-}
+/* The following variable value is the last issued insn. */
-/* Compute the slot which will cause a split issue in packet P if the
- current cycle begins at slot BEGIN. */
+static rtx last_scheduled_insn;
-static int
-itanium_split_issue (p, begin)
- const struct ia64_packet *p;
- int begin;
-{
- int type_count[TYPE_S];
- int i;
- int split = 6;
+/* The following variable value is size of the DFA state. */
- if (begin < 3)
- {
- /* Always split before and after MMF. */
- if (p->t[0] == TYPE_M && p->t[1] == TYPE_M && p->t[2] == TYPE_F)
- return 3;
- if (p->t[3] == TYPE_M && p->t[4] == TYPE_M && p->t[5] == TYPE_F)
- return 3;
- /* Always split after MBB and BBB. */
- if (p->t[1] == TYPE_B)
- return 3;
- /* Split after first bundle in MIB BBB combination. */
- if (p->t[2] == TYPE_B && p->t[3] == TYPE_B)
- return 3;
- }
+static size_t dfa_state_size;
- memset (type_count, 0, sizeof type_count);
- for (i = begin; i < split; i++)
- {
- enum attr_type t0 = p->t[i];
- /* An MLX bundle reserves the same units as an MFI bundle. */
- enum attr_type t = (t0 == TYPE_L ? TYPE_F
- : t0 == TYPE_X ? TYPE_I
- : t0);
+/* The following variable value is pointer to a DFA state used as
+ temporary variable. */
- /* Itanium can execute up to 3 branches, 2 floating point, 2 memory, and
- 2 integer per cycle. */
- int max = (t == TYPE_B ? 3 : 2);
- if (type_count[t] == max)
- return i;
+static state_t temp_dfa_state = NULL;
- type_count[t]++;
- }
- return split;
+/* 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;
+
+/* 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 array element values are cycles on which the
+ corresponding insn will be issued. The array is used only for
+ Itanium1. */
+
+static int *clocks;
+
+/* The following array element values are numbers of cycles should be
+ added to improve insn scheduling for MM_insns for Itanium1. */
+
+static int *add_cycles;
+
+static rtx ia64_single_set (rtx);
+static void ia64_emit_insn_before (rtx, rtx);
+
+/* 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 ()
+ia64_issue_rate (void)
{
return 6;
}
@@ -5662,8 +5967,7 @@ ia64_issue_rate ()
/* Helper function - like single_set, but look inside COND_EXEC. */
static rtx
-ia64_single_set (insn)
- rtx insn;
+ia64_single_set (rtx insn)
{
rtx x = PATTERN (insn), ret;
if (GET_CODE (x) == COND_EXEC)
@@ -5693,1273 +5997,1438 @@ ia64_single_set (insn)
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
static int
-ia64_adjust_cost (insn, link, dep_insn, cost)
- rtx insn, link, dep_insn;
- int cost;
+ia64_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
- enum attr_type dep_type;
enum attr_itanium_class dep_class;
enum attr_itanium_class insn_class;
- rtx dep_set, set, src, addr;
-
- if (GET_CODE (PATTERN (insn)) == CLOBBER
- || GET_CODE (PATTERN (insn)) == USE
- || GET_CODE (PATTERN (dep_insn)) == CLOBBER
- || GET_CODE (PATTERN (dep_insn)) == USE
- /* @@@ Not accurate for indirect calls. */
- || GET_CODE (insn) == CALL_INSN
- || ia64_safe_type (insn) == TYPE_S)
- return 0;
- if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT
- || REG_NOTE_KIND (link) == REG_DEP_ANTI)
- return 0;
+ if (REG_NOTE_KIND (link) != REG_DEP_OUTPUT)
+ return cost;
- dep_type = ia64_safe_type (dep_insn);
- dep_class = ia64_safe_itanium_class (dep_insn);
insn_class = ia64_safe_itanium_class (insn);
-
- /* Compares that feed a conditional branch can execute in the same
- cycle. */
- dep_set = ia64_single_set (dep_insn);
- set = ia64_single_set (insn);
-
- if (dep_type != TYPE_F
- && dep_set
- && GET_CODE (SET_DEST (dep_set)) == REG
- && PR_REG (REGNO (SET_DEST (dep_set)))
- && GET_CODE (insn) == JUMP_INSN)
+ dep_class = ia64_safe_itanium_class (dep_insn);
+ if (dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF
+ || insn_class == ITANIUM_CLASS_ST || insn_class == ITANIUM_CLASS_STF)
return 0;
- if (dep_set && GET_CODE (SET_DEST (dep_set)) == MEM)
- {
- /* ??? Can't find any information in the documenation about whether
- a sequence
- st [rx] = ra
- ld rb = [ry]
- splits issue. Assume it doesn't. */
- return 0;
- }
-
- src = set ? SET_SRC (set) : 0;
- addr = 0;
- if (set)
- {
- if (GET_CODE (SET_DEST (set)) == MEM)
- addr = XEXP (SET_DEST (set), 0);
- else if (GET_CODE (SET_DEST (set)) == SUBREG
- && GET_CODE (SUBREG_REG (SET_DEST (set))) == MEM)
- addr = XEXP (SUBREG_REG (SET_DEST (set)), 0);
- else
- {
- addr = src;
- if (GET_CODE (addr) == UNSPEC && XVECLEN (addr, 0) > 0)
- addr = XVECEXP (addr, 0, 0);
- while (GET_CODE (addr) == SUBREG || GET_CODE (addr) == ZERO_EXTEND)
- addr = XEXP (addr, 0);
-
- /* Note that LO_SUM is used for GOT loads. */
- if (GET_CODE (addr) == MEM || GET_CODE (addr) == LO_SUM)
- addr = XEXP (addr, 0);
- else
- addr = 0;
- }
- }
-
- if (addr && GET_CODE (addr) == POST_MODIFY)
- addr = XEXP (addr, 0);
-
- set = ia64_single_set (dep_insn);
-
- if ((dep_class == ITANIUM_CLASS_IALU
- || dep_class == ITANIUM_CLASS_ILOG
- || dep_class == ITANIUM_CLASS_LD)
- && (insn_class == ITANIUM_CLASS_LD
- || insn_class == ITANIUM_CLASS_ST))
- {
- if (! addr || ! set)
- abort ();
- /* This isn't completely correct - an IALU that feeds an address has
- a latency of 1 cycle if it's issued in an M slot, but 2 cycles
- otherwise. Unfortunately there's no good way to describe this. */
- if (reg_overlap_mentioned_p (SET_DEST (set), addr))
- return cost + 1;
- }
-
- if ((dep_class == ITANIUM_CLASS_IALU
- || dep_class == ITANIUM_CLASS_ILOG
- || dep_class == ITANIUM_CLASS_LD)
- && (insn_class == ITANIUM_CLASS_MMMUL
- || insn_class == ITANIUM_CLASS_MMSHF
- || insn_class == ITANIUM_CLASS_MMSHFI))
- return 3;
-
- if (dep_class == ITANIUM_CLASS_FMAC
- && (insn_class == ITANIUM_CLASS_FMISC
- || insn_class == ITANIUM_CLASS_FCVTFX
- || insn_class == ITANIUM_CLASS_XMPY))
- return 7;
-
- if ((dep_class == ITANIUM_CLASS_FMAC
- || dep_class == ITANIUM_CLASS_FMISC
- || dep_class == ITANIUM_CLASS_FCVTFX
- || dep_class == ITANIUM_CLASS_XMPY)
- && insn_class == ITANIUM_CLASS_STF)
- return 8;
-
- /* Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
- but HP engineers say any non-MM operation. */
- if ((dep_class == ITANIUM_CLASS_MMMUL
- || dep_class == ITANIUM_CLASS_MMSHF
- || dep_class == ITANIUM_CLASS_MMSHFI)
- && insn_class != ITANIUM_CLASS_MMMUL
- && insn_class != ITANIUM_CLASS_MMSHF
- && insn_class != ITANIUM_CLASS_MMSHFI)
- return 4;
-
return cost;
}
-/* Describe the current state of the Itanium pipeline. */
-static struct
-{
- /* The first slot that is used in the current cycle. */
- int first_slot;
- /* The next slot to fill. */
- int cur;
- /* The packet we have selected for the current issue window. */
- const struct ia64_packet *packet;
- /* The position of the split issue that occurs due to issue width
- limitations (6 if there's no split issue). */
- int split;
- /* Record data about the insns scheduled so far in the same issue
- window. The elements up to but not including FIRST_SLOT belong
- to the previous cycle, the ones starting with FIRST_SLOT belong
- to the current cycle. */
- enum attr_type types[6];
- rtx insns[6];
- int stopbit[6];
- /* Nonzero if we decided to schedule a stop bit. */
- int last_was_stop;
-} sched_data;
-
-/* Temporary arrays; they have enough elements to hold all insns that
- can be ready at the same time while scheduling of the current block.
- SCHED_READY can hold ready insns, SCHED_TYPES their types. */
-static rtx *sched_ready;
-static enum attr_type *sched_types;
-
-/* Determine whether an insn INSN of type ITYPE can fit into slot SLOT
- of packet P. */
-
-static int
-insn_matches_slot (p, itype, slot, insn)
- const struct ia64_packet *p;
- enum attr_type itype;
- int slot;
- rtx insn;
-{
- enum attr_itanium_requires_unit0 u0;
- enum attr_type stype = p->t[slot];
-
- if (insn)
- {
- u0 = ia64_safe_itanium_requires_unit0 (insn);
- if (u0 == ITANIUM_REQUIRES_UNIT0_YES)
- {
- int i;
- for (i = sched_data.first_slot; i < slot; i++)
- if (p->t[i] == stype
- || (stype == TYPE_F && p->t[i] == TYPE_L)
- || (stype == TYPE_I && p->t[i] == TYPE_X))
- return 0;
- }
- if (GET_CODE (insn) == CALL_INSN)
- {
- /* Reject calls in multiway branch packets. We want to limit
- the number of multiway branches we generate (since the branch
- predictor is limited), and this seems to work fairly well.
- (If we didn't do this, we'd have to add another test here to
- force calls into the third slot of the bundle.) */
- if (slot < 3)
- {
- if (p->t[1] == TYPE_B)
- return 0;
- }
- else
- {
- if (p->t[4] == TYPE_B)
- return 0;
- }
- }
- }
-
- if (itype == stype)
- return 1;
- if (itype == TYPE_A)
- return stype == TYPE_M || stype == TYPE_I;
- return 0;
-}
-
/* Like emit_insn_before, but skip cycle_display notes.
??? When cycle display notes are implemented, update this. */
static void
-ia64_emit_insn_before (insn, before)
- rtx insn, before;
+ia64_emit_insn_before (rtx insn, rtx before)
{
emit_insn_before (insn, before);
}
-/* When rotating a bundle out of the issue window, insert a bundle selector
- insn in front of it. DUMP is the scheduling dump file or NULL. START
- is either 0 or 3, depending on whether we want to emit a bundle selector
- for the first bundle or the second bundle in the current issue window.
-
- The selector insns are emitted this late because the selected packet can
- be changed until parts of it get rotated out. */
+/* 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
-finish_last_head (dump, start)
- FILE *dump;
- int start;
+ia64_dependencies_evaluation_hook (rtx head, rtx tail)
{
- const struct ia64_packet *p = sched_data.packet;
- const struct bundle *b = start == 0 ? p->t1 : p->t2;
- int bundle_type = b - bundle;
- rtx insn;
- int i;
-
- if (! ia64_final_schedule)
- return;
-
- for (i = start; sched_data.insns[i] == 0; i++)
- if (i == start + 3)
- abort ();
- insn = sched_data.insns[i];
-
- if (dump)
- fprintf (dump, "// Emitting template before %d: %s\n",
- INSN_UID (insn), b->name);
+ rtx insn, link, next, next_tail;
- ia64_emit_insn_before (gen_bundle_selector (GEN_INT (bundle_type)), insn);
+ 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)
+ {
+ for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
+ {
+ next = XEXP (link, 0);
+ if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_ST
+ || ia64_safe_itanium_class (next) == ITANIUM_CLASS_STF)
+ && ia64_st_address_bypass_p (insn, next))
+ break;
+ else if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_LD
+ || ia64_safe_itanium_class (next)
+ == ITANIUM_CLASS_FLD)
+ && ia64_ld_address_bypass_p (insn, next))
+ break;
+ }
+ insn->call = link != 0;
+ }
}
-/* We can't schedule more insns this cycle. Fix up the scheduling state
- and advance FIRST_SLOT and CUR.
- We have to distribute the insns that are currently found between
- FIRST_SLOT and CUR into the slots of the packet we have selected. So
- far, they are stored successively in the fields starting at FIRST_SLOT;
- now they must be moved to the correct slots.
- DUMP is the current scheduling dump file, or NULL. */
+/* We're beginning a new block. Initialize data structures as necessary. */
static void
-cycle_end_fill_slots (dump)
- FILE *dump;
+ia64_sched_init (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ int max_ready ATTRIBUTE_UNUSED)
{
- const struct ia64_packet *packet = sched_data.packet;
- int slot, i;
- enum attr_type tmp_types[6];
- rtx tmp_insns[6];
-
- memcpy (tmp_types, sched_data.types, 6 * sizeof (enum attr_type));
- memcpy (tmp_insns, sched_data.insns, 6 * sizeof (rtx));
+#ifdef ENABLE_CHECKING
+ rtx insn;
- for (i = slot = sched_data.first_slot; i < sched_data.cur; i++)
- {
- enum attr_type t = tmp_types[i];
- if (t != ia64_safe_type (tmp_insns[i]))
+ if (reload_completed)
+ for (insn = NEXT_INSN (current_sched_info->prev_head);
+ insn != current_sched_info->next_tail;
+ insn = NEXT_INSN (insn))
+ if (SCHED_GROUP_P (insn))
abort ();
- while (! insn_matches_slot (packet, t, slot, tmp_insns[i]))
- {
- if (slot > sched_data.split)
- abort ();
- if (dump)
- fprintf (dump, "// Packet needs %s, have %s\n",
- type_names[packet->t[slot]], type_names[t]);
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = 0;
- sched_data.stopbit[slot] = 0;
-
- /* ??? TYPE_L instructions always fill up two slots, but we don't
- support TYPE_L nops. */
- if (packet->t[slot] == TYPE_L)
- abort ();
-
- slot++;
- }
-
- /* Do _not_ use T here. If T == TYPE_A, then we'd risk changing the
- actual slot type later. */
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = tmp_insns[i];
- sched_data.stopbit[slot] = 0;
- slot++;
-
- /* TYPE_L instructions always fill up two slots. */
- if (t == TYPE_L)
- {
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = 0;
- sched_data.stopbit[slot] = 0;
- slot++;
- }
- }
-
- /* This isn't right - there's no need to pad out until the forced split;
- the CPU will automatically split if an insn isn't ready. */
-#if 0
- while (slot < sched_data.split)
- {
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = 0;
- sched_data.stopbit[slot] = 0;
- slot++;
- }
#endif
-
- sched_data.first_slot = sched_data.cur = slot;
+ last_scheduled_insn = NULL_RTX;
+ init_insn_group_barriers ();
}
-/* Bundle rotations, as described in the Itanium optimization manual.
- We can rotate either one or both bundles out of the issue window.
- DUMP is the current scheduling dump file, or NULL. */
-
-static void
-rotate_one_bundle (dump)
- FILE *dump;
-{
- if (dump)
- fprintf (dump, "// Rotating one bundle.\n");
-
- finish_last_head (dump, 0);
- if (sched_data.cur > 3)
- {
- sched_data.cur -= 3;
- sched_data.first_slot -= 3;
- memmove (sched_data.types,
- sched_data.types + 3,
- sched_data.cur * sizeof *sched_data.types);
- memmove (sched_data.stopbit,
- sched_data.stopbit + 3,
- sched_data.cur * sizeof *sched_data.stopbit);
- memmove (sched_data.insns,
- sched_data.insns + 3,
- sched_data.cur * sizeof *sched_data.insns);
- sched_data.packet
- = &packets[(sched_data.packet->t2 - bundle) * NR_BUNDLES];
- }
- else
- {
- sched_data.cur = 0;
- sched_data.first_slot = 0;
- }
-}
+/* We are about to being issuing insns for this clock cycle.
+ Override the default sort algorithm to better slot instructions. */
-static void
-rotate_two_bundles (dump)
- FILE *dump;
+static int
+ia64_dfa_sched_reorder (FILE *dump, int sched_verbose, rtx *ready,
+ int *pn_ready, int clock_var ATTRIBUTE_UNUSED,
+ int reorder_type)
{
- if (dump)
- fprintf (dump, "// Rotating two bundles.\n");
-
- if (sched_data.cur == 0)
- return;
-
- finish_last_head (dump, 0);
- if (sched_data.cur > 3)
- finish_last_head (dump, 3);
- sched_data.cur = 0;
- sched_data.first_slot = 0;
-}
-
-/* We're beginning a new block. Initialize data structures as necessary. */
+ int n_asms;
+ int n_ready = *pn_ready;
+ rtx *e_ready = ready + n_ready;
+ rtx *insnp;
-static void
-ia64_sched_init (dump, sched_verbose, max_ready)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- int max_ready;
-{
- static int initialized = 0;
+ if (sched_verbose)
+ fprintf (dump, "// ia64_dfa_sched_reorder (type %d):\n", reorder_type);
- if (! initialized)
+ if (reorder_type == 0)
{
- int b1, b2, i;
-
- initialized = 1;
-
- for (i = b1 = 0; b1 < NR_BUNDLES; b1++)
- {
- const struct bundle *t1 = bundle + b1;
- for (b2 = 0; b2 < NR_BUNDLES; b2++, i++)
- {
- const struct bundle *t2 = bundle + b2;
+ /* 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 = *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 lowest = ready[n_asms];
+ ready[n_asms] = insn;
+ *insnp = lowest;
+ n_asms++;
+ }
+ else
+ {
+ rtx highest = ready[n_ready - 1];
+ ready[n_ready - 1] = insn;
+ *insnp = highest;
+ return 1;
+ }
+ }
+ }
- packets[i].t1 = t1;
- packets[i].t2 = t2;
- }
- }
- for (i = 0; i < NR_PACKETS; i++)
+ if (n_asms < n_ready)
{
- int j;
- for (j = 0; j < 3; j++)
- packets[i].t[j] = packets[i].t1->t[j];
- for (j = 0; j < 3; j++)
- packets[i].t[j + 3] = packets[i].t2->t[j];
- packets[i].first_split = itanium_split_issue (packets + i, 0);
+ /* Some normal insns to process. Skip the asms. */
+ ready += n_asms;
+ n_ready -= n_asms;
}
-
+ else if (n_ready > 0)
+ return 1;
}
- init_insn_group_barriers ();
-
- memset (&sched_data, 0, sizeof sched_data);
- sched_types = (enum attr_type *) xmalloc (max_ready
- * sizeof (enum attr_type));
- sched_ready = (rtx *) xmalloc (max_ready * sizeof (rtx));
-}
-
-/* See if the packet P can match the insns we have already scheduled. Return
- nonzero if so. In *PSLOT, we store the first slot that is available for
- more instructions if we choose this packet.
- SPLIT holds the last slot we can use, there's a split issue after it so
- scheduling beyond it would cause us to use more than one cycle. */
+ if (ia64_final_schedule)
+ {
+ int deleted = 0;
+ int nr_need_stop = 0;
-static int
-packet_matches_p (p, split, pslot)
- const struct ia64_packet *p;
- int split;
- int *pslot;
-{
- int filled = sched_data.cur;
- int first = sched_data.first_slot;
- int i, slot;
-
- /* First, check if the first of the two bundles must be a specific one (due
- to stop bits). */
- if (first > 0 && sched_data.stopbit[0] && p->t1->possible_stop != 1)
- return 0;
- if (first > 1 && sched_data.stopbit[1] && p->t1->possible_stop != 2)
- return 0;
+ for (insnp = ready; insnp < e_ready; insnp++)
+ if (safe_group_barrier_needed_p (*insnp))
+ nr_need_stop++;
- for (i = 0; i < first; i++)
- if (! insn_matches_slot (p, sched_data.types[i], i,
- sched_data.insns[i]))
- return 0;
- for (i = slot = first; i < filled; i++)
- {
- while (slot < split)
- {
- if (insn_matches_slot (p, sched_data.types[i], slot,
- sched_data.insns[i]))
- break;
- slot++;
- }
- if (slot == split)
+ if (reorder_type == 1 && n_ready == nr_need_stop)
return 0;
- slot++;
+ 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 = *insnp;
+ if (! safe_group_barrier_needed_p (insn))
+ break;
+ memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
+ *ready = insn;
+ deleted++;
+ }
+ n_ready -= deleted;
+ ready += deleted;
}
- if (pslot)
- *pslot = slot;
return 1;
}
-/* A frontend for itanium_split_issue. For a packet P and a slot
- number FIRST that describes the start of the current clock cycle,
- return the slot number of the first split issue. This function
- uses the cached number found in P if possible. */
+/* We are about to being issuing insns for this clock cycle. Override
+ the default sort algorithm to better slot instructions. */
static int
-get_split (p, first)
- const struct ia64_packet *p;
- int first;
+ia64_sched_reorder (FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
+ int clock_var)
{
- if (first == 0)
- return p->first_split;
- return itanium_split_issue (p, first);
+ return ia64_dfa_sched_reorder (dump, sched_verbose, ready,
+ pn_ready, clock_var, 0);
}
-/* Given N_READY insns in the array READY, whose types are found in the
- corresponding array TYPES, return the insn that is best suited to be
- scheduled in slot SLOT of packet P. */
+/* Like ia64_sched_reorder, but called after issuing each insn.
+ Override the default sort algorithm to better slot instructions. */
static int
-find_best_insn (ready, types, n_ready, p, slot)
- rtx *ready;
- enum attr_type *types;
- int n_ready;
- const struct ia64_packet *p;
- int slot;
-{
- int best = -1;
- int best_pri = 0;
- while (n_ready-- > 0)
- {
- rtx insn = ready[n_ready];
- if (! insn)
- continue;
- if (best >= 0 && INSN_PRIORITY (ready[n_ready]) < best_pri)
- break;
- /* If we have equally good insns, one of which has a stricter
- slot requirement, prefer the one with the stricter requirement. */
- if (best >= 0 && types[n_ready] == TYPE_A)
- continue;
- if (insn_matches_slot (p, types[n_ready], slot, insn))
- {
- best = n_ready;
- best_pri = INSN_PRIORITY (ready[best]);
+ia64_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED, rtx *ready,
+ int *pn_ready, int clock_var)
+{
+ if (ia64_tune == PROCESSOR_ITANIUM && reload_completed && last_scheduled_insn)
+ clocks [INSN_UID (last_scheduled_insn)] = clock_var;
+ return ia64_dfa_sched_reorder (dump, sched_verbose, ready, pn_ready,
+ clock_var, 1);
+}
- /* If there's no way we could get a stricter requirement, stop
- looking now. */
- if (types[n_ready] != TYPE_A
- && ia64_safe_itanium_requires_unit0 (ready[n_ready]))
- break;
- break;
- }
+/* 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 ATTRIBUTE_UNUSED,
+ int can_issue_more ATTRIBUTE_UNUSED)
+{
+ last_scheduled_insn = insn;
+ memcpy (prev_cycle_state, curr_state, dfa_state_size);
+ if (reload_completed)
+ {
+ if (group_barrier_needed_p (insn))
+ abort ();
+ if (GET_CODE (insn) == CALL_INSN)
+ init_insn_group_barriers ();
+ stops_p [INSN_UID (insn)] = stop_before_p;
+ stop_before_p = 0;
}
- return best;
+ return 1;
}
-/* Select the best packet to use given the current scheduler state and the
- current ready list.
- READY is an array holding N_READY ready insns; TYPES is a corresponding
- array that holds their types. Store the best packet in *PPACKET and the
- number of insns that can be scheduled in the current cycle in *PBEST. */
+/* We are choosing insn from the ready queue. Return nonzero if INSN
+ can be chosen. */
-static void
-find_best_packet (pbest, ppacket, ready, types, n_ready)
- int *pbest;
- const struct ia64_packet **ppacket;
- rtx *ready;
- enum attr_type *types;
- int n_ready;
-{
- int first = sched_data.first_slot;
- int best = 0;
- int lowest_end = 6;
- const struct ia64_packet *best_packet = NULL;
- int i;
-
- for (i = 0; i < NR_PACKETS; i++)
- {
- const struct ia64_packet *p = packets + i;
- int slot;
- int split = get_split (p, first);
- int win = 0;
- int first_slot, last_slot;
- int b_nops = 0;
+static int
+ia64_first_cycle_multipass_dfa_lookahead_guard (rtx insn)
+{
+ if (insn == NULL_RTX || !INSN_P (insn))
+ abort ();
+ return (!reload_completed
+ || !safe_group_barrier_needed_p (insn));
+}
- if (! packet_matches_p (p, split, &first_slot))
- continue;
+/* The following variable value is pseudo-insn used by the DFA insn
+ scheduler to change the DFA state when the simulated clock is
+ increased. */
- memcpy (sched_ready, ready, n_ready * sizeof (rtx));
+static rtx dfa_pre_cycle_insn;
- win = 0;
- last_slot = 6;
- for (slot = first_slot; slot < split; slot++)
- {
- int insn_nr;
+/* We are about to being issuing INSN. Return nonzero if we can not
+ issue it on given cycle CLOCK and return zero if we should not sort
+ the ready queue on the next clock start. */
- /* Disallow a degenerate case where the first bundle doesn't
- contain anything but NOPs! */
- if (first_slot == 0 && win == 0 && slot == 3)
- {
- win = -1;
- break;
- }
+static int
+ia64_dfa_new_cycle (FILE *dump, int verbose, rtx insn, int last_clock,
+ int clock, int *sort_p)
+{
+ int setup_clocks_p = FALSE;
- insn_nr = find_best_insn (sched_ready, types, n_ready, p, slot);
- if (insn_nr >= 0)
- {
- sched_ready[insn_nr] = 0;
- last_slot = slot;
- win++;
- }
- else if (p->t[slot] == TYPE_B)
- b_nops++;
- }
- /* We must disallow MBB/BBB packets if any of their B slots would be
- filled with nops. */
- if (last_slot < 3)
+ if (insn == NULL_RTX || !INSN_P (insn))
+ abort ();
+ if ((reload_completed && safe_group_barrier_needed_p (insn))
+ || (last_scheduled_insn
+ && (GET_CODE (last_scheduled_insn) == CALL_INSN
+ || GET_CODE (PATTERN (last_scheduled_insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (last_scheduled_insn)) >= 0)))
+ {
+ 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;
+ if (last_clock == clock)
{
- if (p->t[1] == TYPE_B && (b_nops || last_slot < 2))
- win = -1;
+ state_transition (curr_state, dfa_stop_insn);
+ if (TARGET_EARLY_STOP_BITS)
+ *sort_p = (last_scheduled_insn == NULL_RTX
+ || GET_CODE (last_scheduled_insn) != CALL_INSN);
+ else
+ *sort_p = 0;
+ return 1;
}
+ else if (reload_completed)
+ setup_clocks_p = TRUE;
+ if (GET_CODE (PATTERN (last_scheduled_insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (last_scheduled_insn)) >= 0)
+ state_reset (curr_state);
else
{
- if (p->t[4] == TYPE_B && (b_nops || last_slot < 5))
- win = -1;
+ 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);
}
+ }
+ else if (reload_completed)
+ setup_clocks_p = TRUE;
+ if (setup_clocks_p && ia64_tune == PROCESSOR_ITANIUM
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && asm_noperands (PATTERN (insn)) < 0)
+ {
+ enum attr_itanium_class c = ia64_safe_itanium_class (insn);
- if (win > best
- || (win == best && last_slot < lowest_end))
+ if (c != ITANIUM_CLASS_MMMUL && c != ITANIUM_CLASS_MMSHF)
{
- best = win;
- lowest_end = last_slot;
- best_packet = p;
+ rtx link;
+ int d = -1;
+
+ for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
+ if (REG_NOTE_KIND (link) == 0)
+ {
+ enum attr_itanium_class dep_class;
+ rtx dep_insn = XEXP (link, 0);
+
+ dep_class = ia64_safe_itanium_class (dep_insn);
+ if ((dep_class == ITANIUM_CLASS_MMMUL
+ || dep_class == ITANIUM_CLASS_MMSHF)
+ && last_clock - clocks [INSN_UID (dep_insn)] < 4
+ && (d < 0
+ || last_clock - clocks [INSN_UID (dep_insn)] < d))
+ d = last_clock - clocks [INSN_UID (dep_insn)];
+ }
+ if (d >= 0)
+ add_cycles [INSN_UID (insn)] = 3 - d;
}
}
- *pbest = best;
- *ppacket = best_packet;
+ return 0;
}
-/* Reorder the ready list so that the insns that can be issued in this cycle
- are found in the correct order at the end of the list.
- DUMP is the scheduling dump file, or NULL. READY points to the start,
- E_READY to the end of the ready list. MAY_FAIL determines what should be
- done if no insns can be scheduled in this cycle: if it is zero, we abort,
- otherwise we return 0.
- Return 1 if any insns can be scheduled in this cycle. */
+
-static int
-itanium_reorder (dump, ready, e_ready, may_fail)
- FILE *dump;
- rtx *ready;
- rtx *e_ready;
- int may_fail;
-{
- const struct ia64_packet *best_packet;
- int n_ready = e_ready - ready;
- int first = sched_data.first_slot;
- int i, best, best_split, filled;
+/* 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; /* 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 */
+ 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;
+};
- for (i = 0; i < n_ready; i++)
- sched_types[i] = ia64_safe_type (ready[i]);
+/* The following is map insn number to the corresponding bundle state. */
- find_best_packet (&best, &best_packet, ready, sched_types, n_ready);
+static struct bundle_state **index_to_bundle_states;
- if (best == 0)
- {
- if (may_fail)
- return 0;
- abort ();
- }
+/* The unique number of next bundle state. */
- if (dump)
- {
- fprintf (dump, "// Selected bundles: %s %s (%d insns)\n",
- best_packet->t1->name,
- best_packet->t2 ? best_packet->t2->name : NULL, best);
- }
+static int bundle_states_num;
- best_split = itanium_split_issue (best_packet, first);
- packet_matches_p (best_packet, best_split, &filled);
+/* All allocated bundle states are in the following chain. */
- for (i = filled; i < best_split; i++)
- {
- int insn_nr;
+static struct bundle_state *allocated_bundle_states_chain;
- insn_nr = find_best_insn (ready, sched_types, n_ready, best_packet, i);
- if (insn_nr >= 0)
- {
- rtx insn = ready[insn_nr];
- memmove (ready + insn_nr, ready + insn_nr + 1,
- (n_ready - insn_nr - 1) * sizeof (rtx));
- memmove (sched_types + insn_nr, sched_types + insn_nr + 1,
- (n_ready - insn_nr - 1) * sizeof (enum attr_type));
- ready[--n_ready] = insn;
- }
- }
+/* All allocated but not used bundle states are in the following
+ chain. */
- sched_data.packet = best_packet;
- sched_data.split = best_split;
- return 1;
-}
+static struct bundle_state *free_bundle_state_chain;
-/* Dump information about the current scheduling state to file DUMP. */
-static void
-dump_current_packet (dump)
- FILE *dump;
+/* The following function returns a free bundle state. */
+
+static struct bundle_state *
+get_free_bundle_state (void)
{
- int i;
- fprintf (dump, "// %d slots filled:", sched_data.cur);
- for (i = 0; i < sched_data.first_slot; i++)
+ struct bundle_state *result;
+
+ if (free_bundle_state_chain != NULL)
{
- rtx insn = sched_data.insns[i];
- fprintf (dump, " %s", type_names[sched_data.types[i]]);
- if (insn)
- fprintf (dump, "/%s", type_names[ia64_safe_type (insn)]);
- if (sched_data.stopbit[i])
- fprintf (dump, " ;;");
+ result = free_bundle_state_chain;
+ free_bundle_state_chain = result->next;
}
- fprintf (dump, " :::");
- for (i = sched_data.first_slot; i < sched_data.cur; i++)
+ else
{
- rtx insn = sched_data.insns[i];
- enum attr_type t = ia64_safe_type (insn);
- fprintf (dump, " (%d) %s", INSN_UID (insn), type_names[t]);
+ result = xmalloc (sizeof (struct bundle_state));
+ result->dfa_state = xmalloc (dfa_state_size);
+ result->allocated_states_chain = allocated_bundle_states_chain;
+ allocated_bundle_states_chain = result;
}
- fprintf (dump, "\n");
+ result->unique_num = bundle_states_num++;
+ return result;
+
}
-/* Schedule a stop bit. DUMP is the current scheduling dump file, or
- NULL. */
+/* The following function frees given bundle state. */
static void
-schedule_stop (dump)
- FILE *dump;
+free_bundle_state (struct bundle_state *state)
{
- const struct ia64_packet *best = sched_data.packet;
- int i;
- int best_stop = 6;
+ state->next = free_bundle_state_chain;
+ free_bundle_state_chain = state;
+}
- if (dump)
- fprintf (dump, "// Stop bit, cur = %d.\n", sched_data.cur);
+/* Start work with abstract data `bundle states'. */
- if (sched_data.cur == 0)
- {
- if (dump)
- fprintf (dump, "// At start of bundle, so nothing to do.\n");
+static void
+initiate_bundle_states (void)
+{
+ bundle_states_num = 0;
+ free_bundle_state_chain = NULL;
+ allocated_bundle_states_chain = NULL;
+}
- rotate_two_bundles (NULL);
- return;
- }
+/* Finish work with abstract data `bundle states'. */
- for (i = -1; i < NR_PACKETS; i++)
+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)
{
- /* This is a slight hack to give the current packet the first chance.
- This is done to avoid e.g. switching from MIB to MBB bundles. */
- const struct ia64_packet *p = (i >= 0 ? packets + i : sched_data.packet);
- int split = get_split (p, sched_data.first_slot);
- const struct bundle *compare;
- int next, stoppos;
+ next_state = curr_state->allocated_states_chain;
+ free (curr_state->dfa_state);
+ free (curr_state);
+ }
+}
- if (! packet_matches_p (p, split, &next))
- continue;
+/* Hash table of the bundle states. The key is dfa_state and insn_num
+ of the bundle states. */
- compare = next > 3 ? p->t2 : p->t1;
+static htab_t bundle_state_table;
- stoppos = 3;
- if (compare->possible_stop)
- stoppos = compare->possible_stop;
- if (next > 3)
- stoppos += 3;
+/* The function returns hash of BUNDLE_STATE. */
- if (stoppos < next || stoppos >= best_stop)
- {
- if (compare->possible_stop == 0)
- continue;
- stoppos = (next > 3 ? 6 : 3);
- }
- if (stoppos < next || stoppos >= best_stop)
- continue;
+static unsigned
+bundle_state_hash (const void *bundle_state)
+{
+ const struct bundle_state *state = (struct bundle_state *) bundle_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. */
+
+static int
+bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
+{
+ const struct bundle_state * state1 = (struct bundle_state *) bundle_state_1;
+ const struct bundle_state * state2 = (struct bundle_state *) bundle_state_2;
+
+ return (state1->insn_num == state2->insn_num
+ && memcmp (state1->dfa_state, state2->dfa_state,
+ dfa_state_size) == 0);
+}
- if (dump)
- fprintf (dump, "// switching from %s %s to %s %s (stop at %d)\n",
- best->t1->name, best->t2->name, p->t1->name, p->t2->name,
- stoppos);
+/* 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. */
- best_stop = stoppos;
- best = p;
+static int
+insert_bundle_state (struct bundle_state *bundle_state)
+{
+ void **entry_ptr;
+
+ entry_ptr = htab_find_slot (bundle_state_table, bundle_state, 1);
+ 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 = (void *) bundle_state;
+ return TRUE;
}
+ else if (bundle_state->cost < ((struct bundle_state *) *entry_ptr)->cost
+ || (bundle_state->cost == ((struct bundle_state *) *entry_ptr)->cost
+ && (((struct bundle_state *)*entry_ptr)->accumulated_insns_num
+ > bundle_state->accumulated_insns_num
+ || (((struct bundle_state *)
+ *entry_ptr)->accumulated_insns_num
+ == bundle_state->accumulated_insns_num
+ && ((struct bundle_state *)
+ *entry_ptr)->branch_deviation
+ > bundle_state->branch_deviation))))
- sched_data.packet = best;
- cycle_end_fill_slots (dump);
- while (sched_data.cur < best_stop)
{
- sched_data.types[sched_data.cur] = best->t[sched_data.cur];
- sched_data.insns[sched_data.cur] = 0;
- sched_data.stopbit[sched_data.cur] = 0;
- sched_data.cur++;
+ struct bundle_state temp;
+
+ temp = *(struct bundle_state *) *entry_ptr;
+ *(struct bundle_state *) *entry_ptr = *bundle_state;
+ ((struct bundle_state *) *entry_ptr)->next = temp.next;
+ *bundle_state = temp;
}
- sched_data.stopbit[sched_data.cur - 1] = 1;
- sched_data.first_slot = best_stop;
+ return FALSE;
+}
- if (dump)
- dump_current_packet (dump);
+/* Start work with the hash table. */
+
+static void
+initiate_bundle_state_table (void)
+{
+ bundle_state_table = htab_create (50, bundle_state_hash, bundle_state_eq_p,
+ (htab_del) 0);
}
-/* If necessary, perform one or two rotations on the scheduling state.
- This should only be called if we are starting a new cycle. */
+/* Finish work with the hash table. */
static void
-maybe_rotate (dump)
- FILE *dump;
+finish_bundle_state_table (void)
{
- cycle_end_fill_slots (dump);
- if (sched_data.cur == 6)
- rotate_two_bundles (dump);
- else if (sched_data.cur >= 3)
- rotate_one_bundle (dump);
- sched_data.first_slot = sched_data.cur;
+ htab_delete (bundle_state_table);
}
-/* The clock cycle when ia64_sched_reorder was last called. */
-static int prev_cycle;
+
-/* The first insn scheduled in the previous cycle. This is the saved
- value of sched_data.first_slot. */
-static int prev_first;
+/* The following variable is a insn `nop' used to check bundle states
+ with different number of inserted nops. */
-/* Emit NOPs to fill the delay between PREV_CYCLE and CLOCK_VAR. Used to
- pad out the delay between MM (shifts, etc.) and integer operations. */
+static rtx ia64_nop;
-static void
-nop_cycles_until (clock_var, dump)
- int clock_var;
- FILE *dump;
+/* 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 prev_clock = prev_cycle;
- int cycles_left = clock_var - prev_clock;
- bool did_stop = false;
+ int i;
- /* Finish the previous cycle; pad it out with NOPs. */
- if (sched_data.cur == 3)
+ 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)
{
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
- did_stop = true;
- maybe_rotate (dump);
+ free_bundle_state (curr_state);
+ return FALSE;
}
- else if (sched_data.cur > 0)
- {
- int need_stop = 0;
- int split = itanium_split_issue (sched_data.packet, prev_first);
-
- if (sched_data.cur < 3 && split > 3)
- {
- split = 3;
- need_stop = 1;
- }
+ return TRUE;
+}
- if (split > sched_data.cur)
- {
- int i;
- for (i = sched_data.cur; i < split; i++)
- {
- rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
- sched_data.types[i] = sched_data.packet->t[i];
- sched_data.insns[i] = t;
- sched_data.stopbit[i] = 0;
- }
- sched_data.cur = split;
- }
+/* 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'. */
- if (! need_stop && sched_data.cur > 0 && sched_data.cur < 6
- && cycles_left > 1)
+static void
+issue_nops_and_insn (struct bundle_state *originator, int before_nops_num,
+ rtx 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;
+ if (insn == NULL_RTX)
+ abort ();
+ else if (INSN_CODE (insn) == CODE_FOR_insn_group_barrier)
+ {
+ if (GET_MODE (insn) == TImode)
+ abort ();
+ 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 (state_transition (temp_dfa_state, dfa_pre_cycle_insn) >= 0
+ && curr_state->accumulated_insns_num % 3 != 0)
{
- int i;
- for (i = sched_data.cur; i < 6; i++)
- {
- rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
- sched_data.types[i] = sched_data.packet->t[i];
- sched_data.insns[i] = t;
- sched_data.stopbit[i] = 0;
- }
- sched_data.cur = 6;
- cycles_left--;
- need_stop = 1;
+ free_bundle_state (curr_state);
+ return;
}
-
- if (need_stop || sched_data.cur == 6)
+ }
+ 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++;
+ if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
+ abort ();
+ if (ia64_safe_type (insn) == TYPE_L)
+ curr_state->accumulated_insns_num++;
+ }
+ else
+ {
+ 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 (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
{
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
- did_stop = true;
+ /* 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;
}
- maybe_rotate (dump);
+ else if (ia64_safe_type (insn) == TYPE_L)
+ curr_state->accumulated_insns_num++;
}
-
- cycles_left--;
- while (cycles_left > 0)
+ 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)
{
- sched_emit_insn (gen_bundle_selector (GEN_INT (0)));
- sched_emit_insn (gen_nop_type (TYPE_M));
- sched_emit_insn (gen_nop_type (TYPE_I));
- if (cycles_left > 1)
+ if (!only_bundle_end_p && insert_bundle_state (curr_state))
{
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (2)));
- cycles_left--;
+ 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;
}
- sched_emit_insn (gen_nop_type (TYPE_I));
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
- did_stop = true;
- cycles_left--;
+ 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 (did_stop)
- init_insn_group_barriers ();
+ if (!insert_bundle_state (curr_state))
+ free_bundle_state (curr_state);
+ return;
}
-/* We are about to being issuing insns for this clock cycle.
- Override the default sort algorithm to better slot instructions. */
+/* The following function returns position in the two window bundle
+ for given STATE. */
static int
-ia64_internal_sched_reorder (dump, sched_verbose, ready, pn_ready,
- reorder_type, clock_var)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- rtx *ready;
- int *pn_ready;
- int reorder_type, clock_var;
+get_max_pos (state_t state)
{
- int n_asms;
- int n_ready = *pn_ready;
- rtx *e_ready = ready + n_ready;
- rtx *insnp;
+ 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;
+}
- if (sched_verbose)
- {
- fprintf (dump, "// ia64_sched_reorder (type %d):\n", reorder_type);
- dump_current_packet (dump);
- }
+/* 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. */
- /* Work around the pipeline flush that will occurr if the results of
- an MM instruction are accessed before the result is ready. Intel
- documentation says this only happens with IALU, ISHF, ILOG, LD,
- and ST consumers, but experimental evidence shows that *any* non-MM
- type instruction will incurr the flush. */
- if (reorder_type == 0 && clock_var > 0 && ia64_final_schedule)
+static int
+get_template (state_t state, int pos)
+{
+ switch (pos)
{
- for (insnp = ready; insnp < e_ready; insnp++)
- {
- rtx insn = *insnp, link;
- enum attr_itanium_class t = ia64_safe_itanium_class (insn);
+ case 3:
+ if (cpu_unit_reservation_p (state, _0mii_))
+ return 0;
+ else if (cpu_unit_reservation_p (state, _0mmi_))
+ return 1;
+ else if (cpu_unit_reservation_p (state, _0mfi_))
+ return 2;
+ else if (cpu_unit_reservation_p (state, _0mmf_))
+ return 3;
+ else if (cpu_unit_reservation_p (state, _0bbb_))
+ return 4;
+ else if (cpu_unit_reservation_p (state, _0mbb_))
+ return 5;
+ else if (cpu_unit_reservation_p (state, _0mib_))
+ return 6;
+ else if (cpu_unit_reservation_p (state, _0mmb_))
+ return 7;
+ else if (cpu_unit_reservation_p (state, _0mfb_))
+ return 8;
+ else if (cpu_unit_reservation_p (state, _0mlx_))
+ return 9;
+ else
+ abort ();
+ case 6:
+ if (cpu_unit_reservation_p (state, _1mii_))
+ return 0;
+ else if (cpu_unit_reservation_p (state, _1mmi_))
+ return 1;
+ else if (cpu_unit_reservation_p (state, _1mfi_))
+ return 2;
+ else if (_1mmf_ >= 0 && cpu_unit_reservation_p (state, _1mmf_))
+ return 3;
+ else if (cpu_unit_reservation_p (state, _1bbb_))
+ return 4;
+ else if (cpu_unit_reservation_p (state, _1mbb_))
+ return 5;
+ else if (cpu_unit_reservation_p (state, _1mib_))
+ return 6;
+ else if (cpu_unit_reservation_p (state, _1mmb_))
+ return 7;
+ else if (cpu_unit_reservation_p (state, _1mfb_))
+ return 8;
+ else if (cpu_unit_reservation_p (state, _1mlx_))
+ return 9;
+ else
+ abort ();
+ default:
+ abort ();
+ }
+}
- if (t == ITANIUM_CLASS_MMMUL
- || t == ITANIUM_CLASS_MMSHF
- || t == ITANIUM_CLASS_MMSHFI)
- continue;
+/* The following function returns an insn important for insn bundling
+ followed by INSN and before TAIL. */
- for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == 0)
- {
- rtx other = XEXP (link, 0);
- enum attr_itanium_class t0 = ia64_safe_itanium_class (other);
- if (t0 == ITANIUM_CLASS_MMSHF || t0 == ITANIUM_CLASS_MMMUL)
- {
- nop_cycles_until (clock_var, sched_verbose ? dump : NULL);
- goto out;
- }
- }
- }
- }
- out:
+static rtx
+get_next_important_insn (rtx insn, rtx tail)
+{
+ for (; insn && insn != tail; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && ia64_safe_itanium_class (insn) != ITANIUM_CLASS_IGNORE
+ && GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER)
+ return insn;
+ return NULL_RTX;
+}
- prev_first = sched_data.first_slot;
- prev_cycle = clock_var;
+/* 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 follows 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 can not 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. There is an additional forward pass through EBB for Itanium1
+ processor. This pass inserts more nops to make dependency between
+ a producer insn and MMMUL/MMSHF at least 4 cycles long. */
- if (reorder_type == 0)
- maybe_rotate (sched_verbose ? dump : NULL);
+static void
+bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail)
+{
+ struct bundle_state *curr_state, *next_state, *best_state;
+ rtx 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 b;
+ rtx nop;
+ enum attr_type type;
- /* 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)
+ 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 = xmalloc ((insn_num + 2)
+ * sizeof (struct bundle_state *));
+ /* 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->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)
+ && (ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IGNORE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ && GET_MODE (insn) == TImode)
{
- rtx insn = *insnp;
- enum attr_type t = ia64_safe_type (insn);
- if (t == TYPE_UNKNOWN)
+ PUT_MODE (insn, VOIDmode);
+ for (next_insn = NEXT_INSN (insn);
+ next_insn != tail;
+ next_insn = NEXT_INSN (next_insn))
+ if (INSN_P (next_insn)
+ && ia64_safe_itanium_class (next_insn) != ITANIUM_CLASS_IGNORE
+ && GET_CODE (PATTERN (next_insn)) != USE
+ && GET_CODE (PATTERN (next_insn)) != CLOBBER)
+ {
+ PUT_MODE (next_insn, TImode);
+ break;
+ }
+ }
+ /* Froward pass: generation of bundle states. */
+ for (insn = get_next_important_insn (NEXT_INSN (prev_head_insn), tail);
+ insn != NULL_RTX;
+ insn = next_insn)
+ {
+ if (!INSN_P (insn)
+ || ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IGNORE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ abort ();
+ 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
+ && ia64_safe_type (next_insn) == TYPE_UNKNOWN);
+ /* 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
+ /* We need to insert 2 nops for cases like M_MII. To
+ guarantee issuing all insns on the same cycle for
+ Itanium 1, we need to issue 2 nops after the first M
+ insn (MnnMII where n is a nop insn). */
+ || ((type == TYPE_M || type == TYPE_A)
+ && ia64_tune == PROCESSOR_ITANIUM
+ && !bundle_end_p && pos == 1))
+ 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);
+ }
+ if (index_to_bundle_states [insn_num] == NULL)
+ abort ();
+ for (curr_state = index_to_bundle_states [insn_num];
+ curr_state != NULL;
+ curr_state = curr_state->next)
+ if (verbose >= 2 && dump)
{
- if (GET_CODE (PATTERN (insn)) == ASM_INPUT
- || asm_noperands (PATTERN (insn)) >= 0)
- {
- rtx lowest = ready[n_asms];
- ready[n_asms] = insn;
- *insnp = lowest;
- n_asms++;
- }
- else
- {
- rtx highest = ready[n_ready - 1];
- ready[n_ready - 1] = insn;
- *insnp = highest;
- if (ia64_final_schedule && group_barrier_needed_p (insn))
- {
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- maybe_rotate (sched_verbose ? dump : NULL);
- }
-
- return 1;
- }
+ /* This structure is taken from generated code of the
+ pipeline hazard recognizer (see file insn-attrtab.c).
+ 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, 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,
+ (ia64_tune == PROCESSOR_ITANIUM
+ ? ((struct DFA_chip *) curr_state->dfa_state)->oneb_automaton_state
+ : ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state),
+ INSN_UID (insn));
}
- }
- 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)
- {
- /* Only asm insns left. */
- if (ia64_final_schedule && group_barrier_needed_p (ready[n_ready - 1]))
+ if (index_to_bundle_states [insn_num] == NULL)
+ /* We should find a solution because the 2nd insn scheduling has
+ found one. */
+ abort ();
+ /* 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)))))
+ best_state = curr_state;
+ /* Second (backward) pass: adding nops and templates. */
+ 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 = (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0);
+ insn_num++;
+ if (verbose >= 2 && dump)
{
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- maybe_rotate (sched_verbose ? dump : NULL);
+ 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, 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,
+ (ia64_tune == PROCESSOR_ITANIUM
+ ? ((struct DFA_chip *) curr_state->dfa_state)->oneb_automaton_state
+ : ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state),
+ INSN_UID (insn));
}
- cycle_end_fill_slots (sched_verbose ? dump : NULL);
- return 1;
- }
-
- if (ia64_final_schedule)
- {
- int nr_need_stop = 0;
-
- for (insnp = ready; insnp < e_ready; insnp++)
- if (safe_group_barrier_needed_p (*insnp))
- nr_need_stop++;
-
- /* Schedule a stop bit if
- - all insns require a stop bit, or
- - we are starting a new cycle and _any_ insns require a stop bit.
- The reason for the latter is that if our schedule is accurate, then
- the additional stop won't decrease performance at this point (since
- there's a split issue at this point anyway), but it gives us more
- freedom when scheduling the currently ready insns. */
- if ((reorder_type == 0 && nr_need_stop)
- || (reorder_type == 1 && n_ready == nr_need_stop))
+ /* 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))
{
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- maybe_rotate (sched_verbose ? dump : NULL);
- if (reorder_type == 1)
- return 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);
+ }
}
- else
+ if (max_pos > 3 && template1 < 0)
+ /* It may happen when we have the stop inside a bundle. */
{
- int deleted = 0;
- insnp = e_ready;
- /* Move down everything that needs a stop bit, preserving relative
- order. */
- while (insnp-- > ready + deleted)
- while (insnp >= ready + deleted)
+ if (pos > 3)
+ abort ();
+ 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++)
+ {
+ nop = gen_nop ();
+ emit_insn_after (nop, insn);
+ pos--;
+ if (pos < 0)
+ abort ();
+ if (pos % 3 == 0)
{
- rtx insn = *insnp;
- if (! safe_group_barrier_needed_p (insn))
- break;
- memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
- *ready = insn;
- deleted++;
+ /* We are at the start of a bundle: emit the template
+ (it should be defined). */
+ if (template0 < 0)
+ abort ();
+ b = gen_bundle_selector (GEN_INT (template0));
+ ia64_emit_insn_before (b, nop);
+ /* If we have two bundle window, we make one bundle
+ rotation. Otherwise template0 will be undefined
+ (negative value). */
+ template0 = template1;
+ template1 = -1;
}
- n_ready -= deleted;
- ready += deleted;
- if (deleted != nr_need_stop)
+ }
+ /* 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
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && asm_noperands (PATTERN (insn)) < 0)
+ pos--;
+ /* Long insn takes 2 slots. */
+ if (ia64_safe_type (insn) == TYPE_L)
+ pos--;
+ if (pos < 0)
+ abort ();
+ if (pos % 3 == 0
+ && INSN_CODE (insn) != CODE_FOR_insn_group_barrier
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && asm_noperands (PATTERN (insn)) < 0)
+ {
+ /* The current insn is at the bundle start: emit the
+ template. */
+ if (template0 < 0)
abort ();
+ b = gen_bundle_selector (GEN_INT (template0));
+ ia64_emit_insn_before (b, insn);
+ b = PREV_INSN (insn);
+ insn = b;
+ /* See comment above in analogous place for emiting nops
+ after the insn. */
+ template0 = template1;
+ template1 = -1;
+ }
+ /* Emit nops after the current insn. */
+ for (i = 0; i < curr_state->before_nops_num; i++)
+ {
+ nop = gen_nop ();
+ ia64_emit_insn_before (nop, insn);
+ nop = PREV_INSN (insn);
+ insn = nop;
+ pos--;
+ if (pos < 0)
+ abort ();
+ if (pos % 3 == 0)
+ {
+ /* See comment above in analogous place for emiting nops
+ after the insn. */
+ if (template0 < 0)
+ abort ();
+ b = gen_bundle_selector (GEN_INT (template0));
+ ia64_emit_insn_before (b, insn);
+ b = PREV_INSN (insn);
+ insn = b;
+ template0 = template1;
+ template1 = -1;
+ }
}
}
-
- return itanium_reorder (sched_verbose ? dump : NULL,
- ready, e_ready, reorder_type == 1);
+ if (ia64_tune == PROCESSOR_ITANIUM)
+ /* Insert additional cycles for MM-insns (MMMUL and MMSHF).
+ Itanium1 has a strange design, if the distance between an insn
+ and dependent MM-insn is less 4 then we have a 6 additional
+ cycles stall. So we make the distance equal to 4 cycles if it
+ is less. */
+ for (insn = get_next_important_insn (NEXT_INSN (prev_head_insn), tail);
+ insn != NULL_RTX;
+ insn = next_insn)
+ {
+ if (!INSN_P (insn)
+ || ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IGNORE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ abort ();
+ next_insn = get_next_important_insn (NEXT_INSN (insn), tail);
+ if (INSN_UID (insn) < clocks_length && add_cycles [INSN_UID (insn)])
+ /* We found a MM-insn which needs additional cycles. */
+ {
+ rtx last;
+ int i, j, n;
+ int pred_stop_p;
+
+ /* Now we are searching for a template of the bundle in
+ which the MM-insn is placed and the position of the
+ insn in the bundle (0, 1, 2). Also we are searching
+ for that there is a stop before the insn. */
+ last = prev_active_insn (insn);
+ pred_stop_p = recog_memoized (last) == CODE_FOR_insn_group_barrier;
+ if (pred_stop_p)
+ last = prev_active_insn (last);
+ n = 0;
+ for (;; last = prev_active_insn (last))
+ if (recog_memoized (last) == CODE_FOR_bundle_selector)
+ {
+ template0 = XINT (XVECEXP (PATTERN (last), 0, 0), 0);
+ if (template0 == 9)
+ /* The insn is in MLX bundle. Change the template
+ onto MFI because we will add nops before the
+ insn. It simplifies subsequent code a lot. */
+ PATTERN (last)
+ = gen_bundle_selector (GEN_INT (2)); /* -> MFI */
+ break;
+ }
+ else if (recog_memoized (last) != CODE_FOR_insn_group_barrier
+ && (ia64_safe_itanium_class (last)
+ != ITANIUM_CLASS_IGNORE))
+ n++;
+ /* Some check of correctness: the stop is not at the
+ bundle start, there are no more 3 insns in the bundle,
+ and the MM-insn is not at the start of bundle with
+ template MLX. */
+ if ((pred_stop_p && n == 0) || n > 2
+ || (template0 == 9 && n != 0))
+ abort ();
+ /* Put nops after the insn in the bundle. */
+ for (j = 3 - n; j > 0; j --)
+ ia64_emit_insn_before (gen_nop (), insn);
+ /* It takes into account that we will add more N nops
+ before the insn lately -- please see code below. */
+ add_cycles [INSN_UID (insn)]--;
+ if (!pred_stop_p || add_cycles [INSN_UID (insn)])
+ ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ if (pred_stop_p)
+ add_cycles [INSN_UID (insn)]--;
+ for (i = add_cycles [INSN_UID (insn)]; i > 0; i--)
+ {
+ /* Insert "MII;" template. */
+ ia64_emit_insn_before (gen_bundle_selector (GEN_INT (0)),
+ insn);
+ ia64_emit_insn_before (gen_nop (), insn);
+ ia64_emit_insn_before (gen_nop (), insn);
+ if (i > 1)
+ {
+ /* To decrease code size, we use "MI;I;"
+ template. */
+ ia64_emit_insn_before
+ (gen_insn_group_barrier (GEN_INT (3)), insn);
+ i--;
+ }
+ ia64_emit_insn_before (gen_nop (), insn);
+ ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ }
+ /* Put the MM-insn in the same slot of a bundle with the
+ same template as the original one. */
+ ia64_emit_insn_before (gen_bundle_selector (GEN_INT (template0)),
+ insn);
+ /* To put the insn in the same slot, add necessary number
+ of nops. */
+ for (j = n; j > 0; j --)
+ ia64_emit_insn_before (gen_nop (), insn);
+ /* Put the stop if the original bundle had it. */
+ if (pred_stop_p)
+ ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ }
+ }
+ free (index_to_bundle_states);
+ finish_bundle_state_table ();
+ bundling_p = 0;
+ dfa_clean_insn_cache ();
}
-static int
-ia64_sched_reorder (dump, sched_verbose, ready, pn_ready, clock_var)
- FILE *dump;
- int sched_verbose;
- rtx *ready;
- int *pn_ready;
- int clock_var;
+/* 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)
{
- return ia64_internal_sched_reorder (dump, sched_verbose, ready,
- pn_ready, 0, clock_var);
+ 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;
+ }
}
-/* Like ia64_sched_reorder, but called after issuing each insn.
- Override the default sort algorithm to better slot instructions. */
+/* The following function inserts stop bits in scheduled BB or EBB. */
-static int
-ia64_sched_reorder2 (dump, sched_verbose, ready, pn_ready, clock_var)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- rtx *ready;
- int *pn_ready;
- int clock_var;
-{
- if (sched_data.last_was_stop)
- return 0;
+static void
+final_emit_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
+{
+ rtx insn;
+ int need_barrier_p = 0;
+ rtx prev_insn = NULL_RTX;
- /* Detect one special case and try to optimize it.
- If we have 1.M;;MI 2.MIx, and slots 2.1 (M) and 2.2 (I) are both NOPs,
- then we can get better code by transforming this to 1.MFB;; 2.MIx. */
- if (sched_data.first_slot == 1
- && sched_data.stopbit[0]
- && ((sched_data.cur == 4
- && (sched_data.types[1] == TYPE_M || sched_data.types[1] == TYPE_A)
- && (sched_data.types[2] == TYPE_I || sched_data.types[2] == TYPE_A)
- && (sched_data.types[3] != TYPE_M && sched_data.types[3] != TYPE_A))
- || (sched_data.cur == 3
- && (sched_data.types[1] == TYPE_M
- || sched_data.types[1] == TYPE_A)
- && (sched_data.types[2] != TYPE_M
- && sched_data.types[2] != TYPE_I
- && sched_data.types[2] != TYPE_A))))
-
- {
- int i, best;
- rtx stop = sched_data.insns[1];
+ init_insn_group_barriers ();
- /* Search backward for the stop bit that must be there. */
- while (1)
+ for (insn = NEXT_INSN (current_sched_info->prev_head);
+ insn != current_sched_info->next_tail;
+ insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == BARRIER)
{
- int insn_code;
-
- stop = PREV_INSN (stop);
- if (GET_CODE (stop) != INSN)
- abort ();
- insn_code = recog_memoized (stop);
-
- /* Ignore .pred.rel.mutex.
+ rtx last = prev_active_insn (insn);
- ??? Update this to ignore cycle display notes too
- ??? once those are implemented */
- if (insn_code == CODE_FOR_pred_rel_mutex
- || insn_code == CODE_FOR_prologue_use)
+ if (! last)
continue;
+ if (GET_CODE (last) == JUMP_INSN
+ && GET_CODE (PATTERN (last)) == ADDR_DIFF_VEC)
+ 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);
- if (insn_code == CODE_FOR_insn_group_barrier)
- break;
- abort ();
+ init_insn_group_barriers ();
+ need_barrier_p = 0;
+ prev_insn = NULL_RTX;
}
-
- /* Adjust the stop bit's slot selector. */
- if (INTVAL (XVECEXP (PATTERN (stop), 0, 0)) != 1)
- abort ();
- XVECEXP (PATTERN (stop), 0, 0) = GEN_INT (3);
-
- sched_data.stopbit[0] = 0;
- sched_data.stopbit[2] = 1;
-
- sched_data.types[5] = sched_data.types[3];
- sched_data.types[4] = sched_data.types[2];
- sched_data.types[3] = sched_data.types[1];
- sched_data.insns[5] = sched_data.insns[3];
- sched_data.insns[4] = sched_data.insns[2];
- sched_data.insns[3] = sched_data.insns[1];
- sched_data.stopbit[5] = sched_data.stopbit[4] = sched_data.stopbit[3] = 0;
- sched_data.cur += 2;
- sched_data.first_slot = 3;
- for (i = 0; i < NR_PACKETS; i++)
+ else if (INSN_P (insn))
{
- const struct ia64_packet *p = packets + i;
- if (p->t[0] == TYPE_M && p->t[1] == TYPE_F && p->t[2] == TYPE_B)
+ if (recog_memoized (insn) == CODE_FOR_insn_group_barrier)
{
- sched_data.packet = p;
- break;
+ init_insn_group_barriers ();
+ need_barrier_p = 0;
+ prev_insn = NULL_RTX;
}
- }
- rotate_one_bundle (sched_verbose ? dump : NULL);
-
- best = 6;
- for (i = 0; i < NR_PACKETS; i++)
- {
- const struct ia64_packet *p = packets + i;
- int split = get_split (p, sched_data.first_slot);
- int next;
-
- /* Disallow multiway branches here. */
- if (p->t[1] == TYPE_B)
- continue;
-
- if (packet_matches_p (p, split, &next) && next < best)
+ else if (need_barrier_p || group_barrier_needed_p (insn))
{
- best = next;
- sched_data.packet = p;
- sched_data.split = split;
+ if (TARGET_EARLY_STOP_BITS)
+ {
+ rtx 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_p (last);
+ }
+ else
+ {
+ emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ init_insn_group_barriers ();
+ }
+ group_barrier_needed_p (insn);
+ prev_insn = NULL_RTX;
}
+ else if (recog_memoized (insn) >= 0)
+ prev_insn = insn;
+ need_barrier_p = (GET_CODE (insn) == CALL_INSN
+ || GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0);
}
- if (best == 6)
- abort ();
}
+}
- if (*pn_ready > 0)
- {
- int more = ia64_internal_sched_reorder (dump, sched_verbose,
- ready, pn_ready, 1,
- clock_var);
- if (more)
- return more;
- /* Did we schedule a stop? If so, finish this cycle. */
- if (sched_data.cur == sched_data.first_slot)
- return 0;
- }
+
- if (sched_verbose)
- fprintf (dump, "// Can't issue more this cycle; updating type array.\n");
+/* If the following function returns TRUE, we will use the the DFA
+ insn scheduler. */
- cycle_end_fill_slots (sched_verbose ? dump : NULL);
- if (sched_verbose)
- dump_current_packet (dump);
- return 0;
+static int
+ia64_use_dfa_pipeline_interface (void)
+{
+ return 1;
}
-/* We are about to issue INSN. Return the number of insns left on the
- ready queue that can be issued this cycle. */
+/* If the following function returns TRUE, we will use the the DFA
+ insn scheduler. */
static int
-ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
- FILE *dump;
- int sched_verbose;
- rtx insn;
- int can_issue_more ATTRIBUTE_UNUSED;
+ia64_first_cycle_multipass_dfa_lookahead (void)
{
- enum attr_type t = ia64_safe_type (insn);
+ return (reload_completed ? 6 : 4);
+}
- if (sched_data.last_was_stop)
- {
- int t = sched_data.first_slot;
- if (t == 0)
- t = 3;
- ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (t)), insn);
- init_insn_group_barriers ();
- sched_data.last_was_stop = 0;
- }
+/* The following function initiates variable `dfa_pre_cycle_insn'. */
- if (t == TYPE_UNKNOWN)
+static void
+ia64_init_dfa_pre_cycle_insn (void)
+{
+ if (temp_dfa_state == NULL)
{
- if (sched_verbose)
- fprintf (dump, "// Ignoring type %s\n", type_names[t]);
- if (GET_CODE (PATTERN (insn)) == ASM_INPUT
- || asm_noperands (PATTERN (insn)) >= 0)
- {
- /* This must be some kind of asm. Clear the scheduling state. */
- rotate_two_bundles (sched_verbose ? dump : NULL);
- if (ia64_final_schedule)
- group_barrier_needed_p (insn);
- }
- return 1;
+ 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 ());
+ PREV_INSN (dfa_pre_cycle_insn) = 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)));
+ PREV_INSN (dfa_stop_insn) = 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). */
- /* This is _not_ just a sanity check. group_barrier_needed_p will update
- important state info. Don't delete this test. */
- if (ia64_final_schedule
- && group_barrier_needed_p (insn))
+int
+ia64_st_address_bypass_p (rtx producer, rtx consumer)
+{
+ rtx dest, reg, mem;
+
+ if (producer == NULL_RTX || consumer == NULL_RTX)
+ abort ();
+ dest = ia64_single_set (producer);
+ if (dest == NULL_RTX || (reg = SET_DEST (dest)) == NULL_RTX
+ || (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG))
abort ();
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ dest = ia64_single_set (consumer);
+ if (dest == NULL_RTX || (mem = SET_DEST (dest)) == NULL_RTX
+ || GET_CODE (mem) != MEM)
+ abort ();
+ return reg_mentioned_p (reg, mem);
+}
- sched_data.stopbit[sched_data.cur] = 0;
- sched_data.insns[sched_data.cur] = insn;
- sched_data.types[sched_data.cur] = t;
+/* The following function returns TRUE if PRODUCER (of type ilog or
+ ld) produces address for CONSUMER (of type ld or fld). */
- sched_data.cur++;
- if (sched_verbose)
- fprintf (dump, "// Scheduling insn %d of type %s\n",
- INSN_UID (insn), type_names[t]);
+int
+ia64_ld_address_bypass_p (rtx producer, rtx consumer)
+{
+ rtx dest, src, reg, mem;
- if (GET_CODE (insn) == CALL_INSN && ia64_final_schedule)
- {
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- }
+ if (producer == NULL_RTX || consumer == NULL_RTX)
+ abort ();
+ dest = ia64_single_set (producer);
+ if (dest == NULL_RTX || (reg = SET_DEST (dest)) == NULL_RTX
+ || (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG))
+ abort ();
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ src = ia64_single_set (consumer);
+ if (src == NULL_RTX || (mem = SET_SRC (src)) == NULL_RTX)
+ abort ();
+ if (GET_CODE (mem) == UNSPEC && XVECLEN (mem, 0) > 0)
+ mem = XVECEXP (mem, 0, 0);
+ while (GET_CODE (mem) == SUBREG || GET_CODE (mem) == ZERO_EXTEND)
+ mem = XEXP (mem, 0);
- return 1;
+ /* Note that LO_SUM is used for GOT loads. */
+ if (GET_CODE (mem) != LO_SUM && GET_CODE (mem) != MEM)
+ abort ();
+
+ return reg_mentioned_p (reg, mem);
}
-/* Free data allocated by ia64_sched_init. */
+/* 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. */
-static void
-ia64_sched_finish (dump, sched_verbose)
- FILE *dump;
- int sched_verbose;
+int
+ia64_produce_address_p (rtx insn)
{
- if (sched_verbose)
- fprintf (dump, "// Finishing schedule.\n");
- rotate_two_bundles (NULL);
- free (sched_types);
- free (sched_ready);
+ return insn->call;
}
+
/* Emit pseudo-ops for the assembler to describe predicate relations.
At present this assumes that we only consider predicate pairs to
@@ -6967,14 +7436,14 @@ ia64_sched_finish (dump, sched_verbose)
straight-line code. */
static void
-emit_predicate_relation_info ()
+emit_predicate_relation_info (void)
{
basic_block bb;
FOR_EACH_BB_REVERSE (bb)
{
int r;
- rtx head = bb->head;
+ rtx head = BB_HEAD (bb);
/* We only need such notes at code labels. */
if (GET_CODE (head) != CODE_LABEL)
@@ -6988,8 +7457,8 @@ emit_predicate_relation_info ()
{
rtx p = gen_rtx_REG (BImode, r);
rtx n = emit_insn_after (gen_pred_rel_mutex (p), head);
- if (head == bb->end)
- bb->end = n;
+ if (head == BB_END (bb))
+ BB_END (bb) = n;
head = n;
}
}
@@ -7000,8 +7469,8 @@ emit_predicate_relation_info ()
the call. */
FOR_EACH_BB_REVERSE (bb)
{
- rtx insn = bb->head;
-
+ rtx insn = BB_HEAD (bb);
+
while (1)
{
if (GET_CODE (insn) == CALL_INSN
@@ -7010,130 +7479,23 @@ emit_predicate_relation_info ()
{
rtx b = emit_insn_before (gen_safe_across_calls_all (), insn);
rtx a = emit_insn_after (gen_safe_across_calls_normal (), insn);
- if (bb->head == insn)
- bb->head = b;
- if (bb->end == insn)
- bb->end = a;
+ if (BB_HEAD (bb) == insn)
+ BB_HEAD (bb) = b;
+ if (BB_END (bb) == insn)
+ BB_END (bb) = a;
}
-
- if (insn == bb->end)
+
+ if (insn == BB_END (bb))
break;
insn = NEXT_INSN (insn);
}
}
}
-/* Generate a NOP instruction of type T. We will never generate L type
- nops. */
-
-static rtx
-gen_nop_type (t)
- enum attr_type t;
-{
- switch (t)
- {
- case TYPE_M:
- return gen_nop_m ();
- case TYPE_I:
- return gen_nop_i ();
- case TYPE_B:
- return gen_nop_b ();
- case TYPE_F:
- return gen_nop_f ();
- case TYPE_X:
- return gen_nop_x ();
- default:
- abort ();
- }
-}
-
-/* After the last scheduling pass, fill in NOPs. It's easier to do this
- here than while scheduling. */
-
-static void
-ia64_emit_nops ()
-{
- rtx insn;
- const struct bundle *b = 0;
- int bundle_pos = 0;
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- rtx pat;
- enum attr_type t;
- pat = INSN_P (insn) ? PATTERN (insn) : const0_rtx;
- if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
- continue;
- if ((GET_CODE (pat) == UNSPEC && XINT (pat, 1) == UNSPEC_BUNDLE_SELECTOR)
- || GET_CODE (insn) == CODE_LABEL)
- {
- if (b)
- while (bundle_pos < 3)
- {
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- if (GET_CODE (insn) != CODE_LABEL)
- b = bundle + INTVAL (XVECEXP (pat, 0, 0));
- else
- b = 0;
- bundle_pos = 0;
- continue;
- }
- else if (GET_CODE (pat) == UNSPEC_VOLATILE
- && XINT (pat, 1) == UNSPECV_INSN_GROUP_BARRIER)
- {
- int t = INTVAL (XVECEXP (pat, 0, 0));
- if (b)
- while (bundle_pos < t)
- {
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- continue;
- }
-
- if (bundle_pos == 3)
- b = 0;
-
- if (b && INSN_P (insn))
- {
- t = ia64_safe_type (insn);
- if (asm_noperands (PATTERN (insn)) >= 0
- || GET_CODE (PATTERN (insn)) == ASM_INPUT)
- {
- while (bundle_pos < 3)
- {
- if (b->t[bundle_pos] != TYPE_L)
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- continue;
- }
-
- if (t == TYPE_UNKNOWN)
- continue;
- while (bundle_pos < 3)
- {
- if (t == b->t[bundle_pos]
- || (t == TYPE_A && (b->t[bundle_pos] == TYPE_M
- || b->t[bundle_pos] == TYPE_I)))
- break;
-
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- if (bundle_pos < 3)
- bundle_pos++;
- }
- }
-}
-
/* Perform machine dependent operations on the rtl chain INSNS. */
-void
-ia64_reorg (insns)
- rtx 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. */
@@ -7151,17 +7513,91 @@ ia64_reorg (insns)
{
timevar_push (TV_SCHED2);
ia64_final_schedule = 1;
+
+ initiate_bundle_states ();
+ ia64_nop = make_insn_raw (gen_nop ());
+ PREV_INSN (ia64_nop) = NEXT_INSN (ia64_nop) = NULL_RTX;
+ recog_memoized (ia64_nop);
+ clocks_length = get_max_uid () + 1;
+ stops_p = xcalloc (1, clocks_length);
+ if (ia64_tune == PROCESSOR_ITANIUM)
+ {
+ clocks = xcalloc (clocks_length, sizeof (int));
+ add_cycles = xcalloc (clocks_length, sizeof (int));
+ }
+ 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.");
+ }
schedule_ebbs (rtl_dump_file);
+ finish_bundle_states ();
+ if (ia64_tune == PROCESSOR_ITANIUM)
+ {
+ free (add_cycles);
+ free (clocks);
+ }
+ free (stops_p);
+ emit_insn_group_barriers (rtl_dump_file);
+
ia64_final_schedule = 0;
timevar_pop (TV_SCHED2);
-
- /* This relies on the NOTE_INSN_BASIC_BLOCK notes to be in the same
- place as they were during scheduling. */
- emit_insn_group_barriers (rtl_dump_file, insns);
- ia64_emit_nops ();
}
else
- emit_all_insn_group_barriers (rtl_dump_file, insns);
+ emit_all_insn_group_barriers (rtl_dump_file);
/* 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
@@ -7174,11 +7610,12 @@ ia64_reorg (insns)
insn = get_last_insn ();
if (! INSN_P (insn))
insn = prev_active_insn (insn);
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
- && XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
- {
- saw_stop = 1;
+ /* Skip over insns that expand to nothing. */
+ while (GET_CODE (insn) == 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 (GET_CODE (insn) == CALL_INSN)
@@ -7197,8 +7634,7 @@ ia64_reorg (insns)
/* Return true if REGNO is used by the epilogue. */
int
-ia64_epilogue_uses (regno)
- int regno;
+ia64_epilogue_uses (int regno)
{
switch (regno)
{
@@ -7237,8 +7673,7 @@ ia64_epilogue_uses (regno)
/* Return true if REGNO is used by the frame unwinder. */
int
-ia64_eh_uses (regno)
- int regno;
+ia64_eh_uses (int regno)
{
if (! reload_completed)
return 0;
@@ -7262,18 +7697,7 @@ ia64_eh_uses (regno)
return 0;
}
-/* For ia64, SYMBOL_REF_FLAG set means that it is a function.
-
- We add @ to the name if this goes in small data/bss. We can only put
- a variable in small data/bss if it is defined in this module or a module
- that we are statically linked with. We can't check the second condition,
- but TREE_STATIC gives us the first one. */
-
-/* ??? If we had IPA, we could check the second condition. We could support
- programmer added section attributes if the variable is not defined in this
- module. */
-
-/* ??? See the v850 port for a cleaner way to do this. */
+/* 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
@@ -7281,12 +7705,19 @@ ia64_eh_uses (regno)
types which can't go in sdata/sbss. */
static bool
-ia64_in_small_data_p (exp)
- tree exp;
+ia64_in_small_data_p (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 = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
@@ -7306,93 +7737,6 @@ ia64_in_small_data_p (exp)
return false;
}
-
-static void
-ia64_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
-{
- const char *symbol_str;
- bool is_local;
- rtx symbol;
- char encoding = 0;
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- {
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
- return;
- }
-
- /* 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)
- return;
-
- symbol = XEXP (DECL_RTL (decl), 0);
- symbol_str = XSTR (symbol, 0);
-
- is_local = (*targetm.binds_local_p) (decl);
-
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
- encoding = " GLil"[decl_tls_model (decl)];
- /* Determine if DECL will wind up in .sdata/.sbss. */
- else if (is_local && ia64_in_small_data_p (decl))
- encoding = 's';
-
- /* Finally, encode this into the symbol string. */
- if (encoding)
- {
- char *newstr;
- size_t len;
-
- if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
- {
- if (encoding == symbol_str[1])
- return;
- /* ??? Sdata became thread or thread becaome not thread. Lose. */
- abort ();
- }
-
- len = strlen (symbol_str);
- newstr = alloca (len + 3);
- newstr[0] = ENCODE_SECTION_INFO_CHAR;
- newstr[1] = encoding;
- memcpy (newstr + 2, symbol_str, len + 1);
-
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2);
- }
-
- /* This decl is marked as being in small data/bss but it shouldn't be;
- one likely explanation for this is that the decl has been moved into
- a different section from the one it was in when encode_section_info
- was first called. Remove the encoding. */
- else if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
- XSTR (symbol, 0) = ggc_strdup (symbol_str + 2);
-}
-
-static const char *
-ia64_strip_name_encoding (str)
- const char *str;
-{
- if (str[0] == ENCODE_SECTION_INFO_CHAR)
- str += 2;
- if (str[0] == '*')
- str++;
- return str;
-}
-
-/* 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. */
-bool
-ia64_function_ok_for_sibcall (decl)
- tree decl;
-{
- /* We must always return with our current GP. This means we can
- only sibcall to functions defined in the current module. */
- return decl && (*targetm.binds_local_p) (decl);
-}
/* Output assembly directives for prologue regions. */
@@ -7407,7 +7751,7 @@ static bool need_copy_state;
/* The function emits unwind directives for the start of an epilogue. */
static void
-process_epilogue ()
+process_epilogue (void)
{
/* 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. */
@@ -7425,9 +7769,7 @@ process_epilogue ()
which result in emitting an assembly directive required for unwinding. */
static int
-process_set (asm_out_file, pat)
- FILE *asm_out_file;
- rtx pat;
+process_set (FILE *asm_out_file, rtx pat)
{
rtx src = SET_SRC (pat);
rtx dest = SET_DEST (pat);
@@ -7460,12 +7802,8 @@ process_set (asm_out_file, pat)
if (op0 == dest && GET_CODE (op1) == CONST_INT)
{
if (INTVAL (op1) < 0)
- {
- fputs ("\t.fframe ", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
- -INTVAL (op1));
- fputc ('\n', asm_out_file);
- }
+ fprintf (asm_out_file, "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n",
+ -INTVAL (op1));
else
process_epilogue ();
}
@@ -7641,9 +7979,7 @@ process_set (asm_out_file, pat)
/* This function looks at a single insn and emits any directives
required to unwind this insn. */
void
-process_for_unwind_directive (asm_out_file, insn)
- FILE *asm_out_file;
- rtx insn;
+process_for_unwind_directive (FILE *asm_out_file, rtx insn)
{
if (flag_unwind_tables
|| (flag_exceptions && !USING_SJLJ_EXCEPTIONS))
@@ -7700,7 +8036,7 @@ process_for_unwind_directive (asm_out_file, insn)
void
-ia64_init_builtins ()
+ia64_init_builtins (void)
{
tree psi_type_node = build_pointer_type (integer_type_node);
tree pdi_type_node = build_pointer_type (long_integer_type_node);
@@ -7744,6 +8080,36 @@ ia64_init_builtins ()
tree void_ftype_pdi
= build_function_type_list (void_type_node, pdi_type_node, NULL_TREE);
+ tree fpreg_type;
+ tree float80_type;
+
+ /* The __fpreg type. */
+ fpreg_type = make_node (REAL_TYPE);
+ /* ??? The back end should know to load/save __fpreg variables using
+ the ldf.fill and stf.spill instructions. */
+ TYPE_PRECISION (fpreg_type) = 96;
+ layout_type (fpreg_type);
+ (*lang_hooks.types.register_builtin_type) (fpreg_type, "__fpreg");
+
+ /* The __float80 type. */
+ float80_type = make_node (REAL_TYPE);
+ TYPE_PRECISION (float80_type) = 96;
+ layout_type (float80_type);
+ (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
+
+ /* The __float128 type. */
+ if (!TARGET_HPUX)
+ {
+ tree float128_type = make_node (REAL_TYPE);
+ TYPE_PRECISION (float128_type) = 128;
+ layout_type (float128_type);
+ (*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
+ }
+ else
+ /* Under HPUX, this is a synonym for "long double". */
+ (*lang_hooks.types.register_builtin_type) (long_double_type_node,
+ "__float128");
+
#define def_builtin(name, type, code) \
builtin_function ((name), (type), (code), BUILT_IN_MD, NULL, NULL_TREE)
@@ -7772,8 +8138,8 @@ ia64_init_builtins ()
build_function_type (ptr_type_node, void_list_node),
IA64_BUILTIN_BSP);
- def_builtin ("__builtin_ia64_flushrs",
- build_function_type (void_type_node, void_list_node),
+ def_builtin ("__builtin_ia64_flushrs",
+ build_function_type (void_type_node, void_list_node),
IA64_BUILTIN_FLUSHRS);
def_builtin ("__sync_fetch_and_add_si", si_ftype_psi_si,
@@ -7844,11 +8210,8 @@ ia64_init_builtins ()
*/
static rtx
-ia64_expand_fetch_and_op (binoptab, mode, arglist, target)
- optab binoptab;
- enum machine_mode mode;
- tree arglist;
- rtx target;
+ia64_expand_fetch_and_op (optab binoptab, enum machine_mode mode,
+ tree arglist, rtx target)
{
rtx ret, label, tmp, ccv, insn, mem, value;
tree arg0, arg1;
@@ -7884,13 +8247,14 @@ ia64_expand_fetch_and_op (binoptab, mode, arglist, target)
}
tmp = gen_reg_rtx (mode);
- ccv = gen_rtx_REG (mode, AR_CCV_REGNUM);
+ /* ar.ccv must always be loaded with a zero-extended DImode value. */
+ ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
emit_move_insn (tmp, mem);
label = gen_label_rtx ();
emit_label (label);
emit_move_insn (ret, tmp);
- emit_move_insn (ccv, tmp);
+ convert_move (ccv, tmp, /*unsignedp=*/1);
/* Perform the specific operation. Special case NAND by noticing
one_cmpl_optab instead. */
@@ -7925,11 +8289,8 @@ ia64_expand_fetch_and_op (binoptab, mode, arglist, target)
*/
static rtx
-ia64_expand_op_and_fetch (binoptab, mode, arglist, target)
- optab binoptab;
- enum machine_mode mode;
- tree arglist;
- rtx target;
+ia64_expand_op_and_fetch (optab binoptab, enum machine_mode mode,
+ tree arglist, rtx target)
{
rtx old, label, tmp, ret, ccv, insn, mem, value;
tree arg0, arg1;
@@ -7953,14 +8314,15 @@ ia64_expand_op_and_fetch (binoptab, mode, arglist, target)
emit_insn (gen_mf ());
tmp = gen_reg_rtx (mode);
old = gen_reg_rtx (mode);
- ccv = gen_rtx_REG (mode, AR_CCV_REGNUM);
+ /* ar.ccv must always be loaded with a zero-extended DImode value. */
+ ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
emit_move_insn (tmp, mem);
label = gen_label_rtx ();
emit_label (label);
emit_move_insn (old, tmp);
- emit_move_insn (ccv, tmp);
+ convert_move (ccv, tmp, /*unsignedp=*/1);
/* Perform the specific operation. Special case NAND by noticing
one_cmpl_optab instead. */
@@ -7993,12 +8355,8 @@ ia64_expand_op_and_fetch (binoptab, mode, arglist, target)
*/
static rtx
-ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
- enum machine_mode rmode;
- enum machine_mode mode;
- int boolp;
- tree arglist;
- rtx target;
+ia64_expand_compare_and_swap (enum machine_mode rmode, enum machine_mode mode,
+ int boolp, tree arglist, rtx target)
{
tree arg0, arg1, arg2;
rtx mem, old, new, ccv, tmp, insn;
@@ -8013,6 +8371,11 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
MEM_VOLATILE_P (mem) = 1;
+ if (GET_MODE (old) != mode)
+ old = convert_to_mode (mode, old, /*unsignedp=*/1);
+ if (GET_MODE (new) != mode)
+ new = convert_to_mode (mode, new, /*unsignedp=*/1);
+
if (! register_operand (old, mode))
old = copy_to_mode_reg (mode, old);
if (! register_operand (new, mode))
@@ -8024,14 +8387,7 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
tmp = gen_reg_rtx (mode);
ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
- if (mode == DImode)
- emit_move_insn (ccv, old);
- else
- {
- rtx ccvtmp = gen_reg_rtx (DImode);
- emit_insn (gen_zero_extendsidi2 (ccvtmp, old));
- emit_move_insn (ccv, ccvtmp);
- }
+ convert_move (ccv, old, /*unsignedp=*/1);
emit_insn (gen_mf ());
if (mode == SImode)
insn = gen_cmpxchg_acq_si (tmp, mem, new, ccv);
@@ -8052,10 +8408,8 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
/* Expand lock_test_and_set. I.e. `xchgsz ret = [ptr], new'. */
static rtx
-ia64_expand_lock_test_and_set (mode, arglist, target)
- enum machine_mode mode;
- tree arglist;
- rtx target;
+ia64_expand_lock_test_and_set (enum machine_mode mode, tree arglist,
+ rtx target)
{
tree arg0, arg1;
rtx mem, new, ret, insn;
@@ -8087,10 +8441,8 @@ ia64_expand_lock_test_and_set (mode, arglist, target)
/* Expand lock_release. I.e. `stsz.rel [ptr] = r0'. */
static rtx
-ia64_expand_lock_release (mode, arglist, target)
- enum machine_mode mode;
- tree arglist;
- rtx target ATTRIBUTE_UNUSED;
+ia64_expand_lock_release (enum machine_mode mode, tree arglist,
+ rtx target ATTRIBUTE_UNUSED)
{
tree arg0;
rtx mem;
@@ -8107,12 +8459,9 @@ ia64_expand_lock_release (mode, arglist, target)
}
rtx
-ia64_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
@@ -8203,6 +8552,9 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore)
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:
@@ -8268,9 +8620,7 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore)
most significant bits of the stack slot. */
enum direction
-ia64_hpux_function_arg_padding (mode, type)
- enum machine_mode mode;
- tree type;
+ia64_hpux_function_arg_padding (enum machine_mode mode, tree type)
{
/* Exception to normal case for structures/unions/etc. */
@@ -8278,78 +8628,124 @@ ia64_hpux_function_arg_padding (mode, type)
&& int_size_in_bytes (type) < UNITS_PER_WORD)
return upward;
- /* This is the standard FUNCTION_ARG_PADDING with !BYTES_BIG_ENDIAN
- hardwired to be true. */
-
- return((mode == BLKmode
- ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
- : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
- ? downward : upward);
+ /* Fall back to the default. */
+ return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
}
/* Linked list of all external functions that are to be emitted by GCC.
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. */
-struct extern_func_list
+struct extern_func_list GTY(())
{
- struct extern_func_list *next; /* next external */
- char *name; /* name of the external */
-} *extern_func_head = 0;
+ struct extern_func_list *next;
+ tree decl;
+};
+
+static GTY(()) struct extern_func_list *extern_func_head;
static void
-ia64_hpux_add_extern_decl (name)
- const char *name;
+ia64_hpux_add_extern_decl (tree decl)
{
- struct extern_func_list *p;
+ struct extern_func_list *p = ggc_alloc (sizeof (struct extern_func_list));
- p = (struct extern_func_list *) xmalloc (sizeof (struct extern_func_list));
- p->name = xmalloc (strlen (name) + 1);
- strcpy(p->name, name);
+ p->decl = decl;
p->next = extern_func_head;
extern_func_head = p;
}
/* Print out the list of used global functions. */
-void
-ia64_hpux_asm_file_end (file)
- FILE *file;
+static void
+ia64_hpux_file_end (void)
{
- while (extern_func_head)
+ struct extern_func_list *p;
+
+ for (p = extern_func_head; p; p = p->next)
{
- const char *real_name;
- tree decl;
+ tree decl = p->decl;
+ tree id = DECL_ASSEMBLER_NAME (decl);
- real_name = (* targetm.strip_name_encoding) (extern_func_head->name);
- decl = maybe_get_identifier (real_name);
+ if (!id)
+ abort ();
- if (!decl
- || (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl)))
+ if (!TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (id))
{
- if (decl)
- TREE_ASM_WRITTEN (decl) = 1;
- (*targetm.asm_out.globalize_label) (file, extern_func_head->name);
- fprintf (file, "%s", TYPE_ASM_OP);
- assemble_name (file, extern_func_head->name);
- putc (',', file);
- fprintf (file, TYPE_OPERAND_FMT, "function");
- putc ('\n', file);
+ const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+
+ TREE_ASM_WRITTEN (decl) = 1;
+ (*targetm.asm_out.globalize_label) (asm_out_file, name);
+ fputs (TYPE_ASM_OP, asm_out_file);
+ assemble_name (asm_out_file, name);
+ fprintf (asm_out_file, "," TYPE_OPERAND_FMT "\n", "function");
}
- extern_func_head = extern_func_head->next;
}
+
+ extern_func_head = 0;
}
+/* Rename all the TFmode libfuncs using the HPUX conventions. */
+
+static void
+ia64_hpux_init_libfuncs (void)
+{
+ 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 (smin_optab, TFmode, "_U_Qfmin");
+ set_optab_libfunc (smax_optab, TFmode, "_U_Qfmax");
+ set_optab_libfunc (abs_optab, TFmode, "_U_Qfabs");
+ set_optab_libfunc (neg_optab, TFmode, "_U_Qfneg");
+
+ /* 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);
+
+ 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 (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");
+}
+
+/* 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");
+}
/* Switch to the section to which we should output X. The only thing
special we do here is to honor small data. */
static void
-ia64_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+ia64_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
if (GET_MODE_SIZE (mode) > 0
&& GET_MODE_SIZE (mode) <= ia64_section_threshold)
@@ -8362,27 +8758,20 @@ ia64_select_rtx_section (mode, x, align)
Pretend flag_pic is always set. */
static void
-ia64_rwreloc_select_section (exp, reloc, align)
- tree exp;
- int reloc;
- unsigned HOST_WIDE_INT align;
+ia64_rwreloc_select_section (tree exp, int reloc, unsigned HOST_WIDE_INT align)
{
default_elf_select_section_1 (exp, reloc, align, true);
}
static void
-ia64_rwreloc_unique_section (decl, reloc)
- tree decl;
- int reloc;
+ia64_rwreloc_unique_section (tree decl, int reloc)
{
default_unique_section_1 (decl, reloc, true);
}
static void
-ia64_rwreloc_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+ia64_rwreloc_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
int save_pic = flag_pic;
flag_pic = 1;
@@ -8391,32 +8780,50 @@ ia64_rwreloc_select_rtx_section (mode, x, align)
}
static unsigned int
-ia64_rwreloc_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+ia64_rwreloc_section_type_flags (tree decl, const char *name, int reloc)
{
return default_section_type_flags_1 (decl, name, reloc, true);
}
+/* 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)
+ && strcmp (lang_hooks.name, "GNU C++") == 0);
+}
/* 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 non-zero, the word at
+ 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, thunk, delta, vcall_offset, function)
- FILE *file;
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset;
- tree function;
+ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
{
rtx this, insn, funexp;
+ unsigned int this_parmno;
+ unsigned int this_regno;
reload_completed = 1;
+ epilogue_completed = 1;
no_new_pseudos = 1;
/* Set things up as ia64_expand_prologue might. */
@@ -8427,16 +8834,32 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
current_frame_info.n_input_regs = 1;
current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);
- if (!TARGET_REG_NAMES)
- reg_names[IN_REG (0)] = ia64_reg_numbers[0];
-
/* Mark the end of the (empty) prologue. */
- emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+ 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 = gen_rtx_REG (Pmode, IN_REG (0));
+ this = gen_rtx_REG (Pmode, this_regno);
if (TARGET_ILP32)
- emit_insn (gen_ptr_extend (this,
- gen_rtx_REG (ptr_mode, IN_REG (0))));
+ {
+ rtx tmp = gen_rtx_REG (ptr_mode, this_regno);
+ REG_POINTER (tmp) = 1;
+ if (delta && CONST_OK_FOR_I (delta))
+ {
+ emit_insn (gen_ptr_extend_plus_imm (this, tmp, GEN_INT (delta)));
+ delta = 0;
+ }
+ else
+ emit_insn (gen_ptr_extend (this, tmp));
+ }
/* Apply the constant offset, if required. */
if (delta)
@@ -8461,19 +8884,30 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
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));
- emit_insn (gen_ptr_extend (tmp, t));
+ if (CONST_OK_FOR_I (vcall_offset))
+ {
+ 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));
- if (!CONST_OK_FOR_J (vcall_offset))
+ if (vcall_offset)
{
- rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
- emit_move_insn (tmp2, vcall_offset_rtx);
- vcall_offset_rtx = tmp2;
+ if (!CONST_OK_FOR_J (vcall_offset))
+ {
+ 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));
}
- emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
if (TARGET_ILP32)
emit_move_insn (gen_rtx_REG (ptr_mode, 2),
@@ -8498,6 +8932,7 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Code generation for calls relies on splitting. */
reload_completed = 1;
+ epilogue_completed = 1;
try_split (PATTERN (insn), insn, 0);
emit_barrier ();
@@ -8507,15 +8942,28 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
+ insn_locators_initialize ();
+ emit_all_insn_group_barriers (NULL);
insn = get_insns ();
- emit_all_insn_group_barriers (NULL, insn);
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
final_end_function ();
reload_completed = 0;
+ epilogue_completed = 0;
no_new_pseudos = 0;
}
+/* Worker function for TARGET_STRUCT_VALUE_RTX. */
+
+static rtx
+ia64_struct_value_rtx (tree fntype,
+ int incoming ATTRIBUTE_UNUSED)
+{
+ if (fntype && ia64_struct_retval_addr_is_first_parm_p (fntype))
+ return NULL_RTX;
+ return gen_rtx_REG (Pmode, GR_REG (8));
+}
+
#include "gt-ia64.h"
diff --git a/contrib/gcc/config/ia64/ia64.h b/contrib/gcc/config/ia64/ia64.h
index 60d0143..9f7dd05 100644
--- a/contrib/gcc/config/ia64/ia64.h
+++ b/contrib/gcc/config/ia64/ia64.h
@@ -1,22 +1,22 @@
/* Definitions of target machine GNU compiler. IA-64 version.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by James E. Wilson <wilson@cygnus.com> and
David Mosberger <davidm@hpl.hp.com>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -39,18 +39,17 @@ do { \
builtin_define("__ia64"); \
builtin_define("__ia64__"); \
builtin_define("__itanium__"); \
- builtin_define("__ELF__"); \
- if (!TARGET_ILP32) \
- { \
- builtin_define("_LP64"); \
- builtin_define("__LP64__"); \
- } \
if (TARGET_BIG_ENDIAN) \
builtin_define("__BIG_ENDIAN__"); \
} while (0)
+#ifndef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS
+#endif
+
#define EXTRA_SPECS \
- { "asm_extra", ASM_EXTRA_SPEC },
+ { "asm_extra", ASM_EXTRA_SPEC }, \
+ SUBTARGET_EXTRA_SPECS
#define CC1_SPEC "%(cc1_cpu) "
@@ -93,8 +92,14 @@ extern int target_flags;
#define MASK_INLINE_INT_DIV_THR 0x00001000 /* inline div, max throughput. */
+#define MASK_INLINE_SQRT_LAT 0x00002000 /* inline sqrt, min latency. */
+
+#define MASK_INLINE_SQRT_THR 0x00004000 /* inline sqrt, max throughput. */
+
#define MASK_DWARF2_ASM 0x40000000 /* test dwarf2 line info via gas. */
+#define MASK_EARLY_STOP_BITS 0x00002000 /* tune stop bits for the model. */
+
#define TARGET_BIG_ENDIAN (target_flags & MASK_BIG_ENDIAN)
#define TARGET_GNU_AS (target_flags & MASK_GNU_AS)
@@ -131,13 +136,31 @@ extern int target_flags;
#define TARGET_INLINE_INT_DIV \
(target_flags & (MASK_INLINE_INT_DIV_LAT | MASK_INLINE_INT_DIV_THR))
+#define TARGET_INLINE_SQRT_LAT (target_flags & MASK_INLINE_SQRT_LAT)
+
+#define TARGET_INLINE_SQRT_THR (target_flags & MASK_INLINE_SQRT_THR)
+
+#define TARGET_INLINE_SQRT \
+ (target_flags & (MASK_INLINE_SQRT_LAT | MASK_INLINE_SQRT_THR))
+
#define TARGET_DWARF2_ASM (target_flags & MASK_DWARF2_ASM)
+/* If the assembler supports thread-local storage, assume that the
+ system does as well. If a particular target system has an
+ assembler that supports TLS -- but the rest of the system does not
+ support TLS -- that system should explicit define TARGET_HAVE_TLS
+ to false in its own configuration file. */
+#if !defined(TARGET_HAVE_TLS) && defined(HAVE_AS_TLS)
+#define TARGET_HAVE_TLS true
+#endif
+
extern int ia64_tls_size;
#define TARGET_TLS14 (ia64_tls_size == 14)
#define TARGET_TLS22 (ia64_tls_size == 22)
#define TARGET_TLS64 (ia64_tls_size == 64)
+#define TARGET_EARLY_STOP_BITS (target_flags & MASK_EARLY_STOP_BITS)
+#define TARGET_HPUX 0
#define TARGET_HPUX_LD 0
#ifndef HAVE_AS_LTOFFX_LDXMOV_RELOCS
@@ -188,10 +211,18 @@ extern int ia64_tls_size;
N_("Generate inline integer division, optimize for latency") }, \
{ "inline-int-divide-max-throughput", MASK_INLINE_INT_DIV_THR, \
N_("Generate inline integer division, optimize for throughput") },\
+ { "inline-sqrt-min-latency", MASK_INLINE_SQRT_LAT, \
+ N_("Generate inline square root, optimize for latency") }, \
+ { "inline-sqrt-max-throughput", MASK_INLINE_SQRT_THR, \
+ N_("Generate inline square root, optimize for throughput") }, \
{ "dwarf2-asm", MASK_DWARF2_ASM, \
N_("Enable Dwarf 2 line debug info via GNU as")}, \
{ "no-dwarf2-asm", -MASK_DWARF2_ASM, \
N_("Disable Dwarf 2 line debug info via GNU as")}, \
+ { "early-stop-bits", MASK_EARLY_STOP_BITS, \
+ N_("Enable earlier placing stop bits for better scheduling")}, \
+ { "no-early-stop-bits", -MASK_EARLY_STOP_BITS, \
+ N_("Disable earlier placing stop bits")}, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT | TARGET_CPU_DEFAULT, \
NULL } \
@@ -217,12 +248,30 @@ extern int ia64_tls_size;
extern const char *ia64_fixed_range_string;
extern const char *ia64_tls_size_string;
+
+/* Which processor to schedule for. The cpu attribute defines a list
+ that mirrors this list, so changes to i64.md must be made at the
+ same time. */
+
+enum processor_type
+{
+ PROCESSOR_ITANIUM, /* Original Itanium. */
+ PROCESSOR_ITANIUM2,
+ PROCESSOR_max
+};
+
+extern enum processor_type ia64_tune;
+
+extern const char *ia64_tune_string;
+
#define TARGET_OPTIONS \
{ \
{ "fixed-range=", &ia64_fixed_range_string, \
- N_("Specify range of registers to make fixed")}, \
+ N_("Specify range of registers to make fixed"), 0}, \
{ "tls-size=", &ia64_tls_size_string, \
- N_("Specify bit size of immediate TLS offsets")}, \
+ N_("Specify bit size of immediate TLS offsets"), 0}, \
+ { "tune=", &ia64_tune_string, \
+ N_("Schedule code for given CPU"), 0}, \
}
/* Sometimes certain combinations of command options do not make sense on a
@@ -242,16 +291,16 @@ extern const char *ia64_tls_size_string;
/* Driver configuration */
-/* A C string constant that tells the GNU CC driver program options to pass to
- `cc1'. It can also specify how to translate options you give to GNU CC into
- options for GNU CC to pass to the `cc1'. */
+/* A C string constant that tells the GCC driver program options to pass to
+ `cc1'. It can also specify how to translate options you give to GCC into
+ options for GCC to pass to the `cc1'. */
#undef CC1_SPEC
#define CC1_SPEC "%{G*}"
-/* A C string constant that tells the GNU CC driver program options to pass to
- `cc1plus'. It can also specify how to translate options you give to GNU CC
- into options for GNU CC to pass to the `cc1plus'. */
+/* A C string constant that tells the GCC driver program options to pass to
+ `cc1plus'. It can also specify how to translate options you give to GCC
+ into options for GCC to pass to the `cc1plus'. */
/* #define CC1PLUS_SPEC "" */
@@ -281,7 +330,7 @@ extern const char *ia64_tls_size_string;
/* A C expression whose value is zero if pointers that need to be extended
from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and one if
- they are zero-extended and negative one if there is an ptr_extend operation.
+ they are zero-extended and negative one if there is a ptr_extend operation.
You need not define this macro if the `POINTER_SIZE' is equal to the width
of `Pmode'. */
@@ -398,11 +447,11 @@ while (0)
#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 128
+/* long double is XFmode normally, TFmode for HPUX. */
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_HPUX ? 128 : 96)
-/* By default we use the 80-bit Intel extended float format packaged
- in a 128-bit entity. */
-#define INTEL_EXTENDED_IEEE_FORMAT 1
+/* We always want the XFmode operations from libgcc2.c. */
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
#define DEFAULT_SIGNED_CHAR 1
@@ -566,7 +615,7 @@ while (0)
all the FIXED_REGISTERS. Until this problem has been
resolved this macro can be used to overcome this situation.
In particular, block_propagate() requires this list
- be acurate, or we can remove registers which should be live.
+ be accurate, or we can remove registers which should be live.
This macro is used in regs_invalidated_by_call. */
#define CALL_REALLY_USED_REGISTERS \
@@ -632,7 +681,7 @@ while (0)
/* Order of allocation of registers */
/* If defined, an initializer for a vector of integers, containing the numbers
- of hard registers in the order in which GNU CC should prefer to use them
+ of hard registers in the order in which GCC should prefer to use them
(from most preferred to least).
If this macro is not defined, registers are used lowest numbered first (all
@@ -760,7 +809,7 @@ while (0)
((REGNO) == PR_REG (0) && (MODE) == DImode ? 64 \
: PR_REGNO_P (REGNO) && (MODE) == BImode ? 2 \
: PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1 \
- : FR_REGNO_P (REGNO) && (MODE) == TFmode && INTEL_EXTENDED_IEEE_FORMAT ? 1 \
+ : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* A C expression that is nonzero if it is permissible to store a value of mode
@@ -772,10 +821,10 @@ while (0)
GET_MODE_CLASS (MODE) != MODE_CC && \
(MODE) != TImode && \
(MODE) != BImode && \
- ((MODE) != TFmode || INTEL_EXTENDED_IEEE_FORMAT) \
+ (MODE) != TFmode \
: PR_REGNO_P (REGNO) ? \
(MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC \
- : GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != TFmode \
+ : GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != XFmode \
: AR_REGNO_P (REGNO) ? (MODE) == DImode \
: BR_REGNO_P (REGNO) ? (MODE) == DImode \
: 0)
@@ -788,12 +837,19 @@ while (0)
ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
zero. */
/* Don't tie integer and FP modes, as that causes us to get integer registers
- allocated for FP instructions. TFmode only supported in FP registers so
+ allocated for FP instructions. XFmode only supported in FP registers so
we can't tie it with any other modes. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
(GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \
- && (((MODE1) == TFmode) == ((MODE2) == TFmode)) \
+ && (((MODE1) == XFmode) == ((MODE2) == XFmode)) \
&& (((MODE1) == BImode) == ((MODE2) == BImode)))
+
+/* Specify the modes required to caller save a given hard regno.
+ We need to ensure floating pt regs are not saved as DImode. */
+
+#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
+ ((FR_REGNO_P (REGNO) && (NREGS) == 1) ? XFmode \
+ : choose_hard_reg_mode ((REGNO), (NREGS), false))
/* Handling Leaf Functions */
@@ -992,12 +1048,12 @@ enum reg_class
into a register of CLASS2. */
#if 0
-/* ??? May need this, but since we've disallowed TFmode in GR_REGS,
+/* ??? May need this, but since we've disallowed XFmode in GR_REGS,
I'm not quite sure how it could be invoked. The normal problems
with unions should be solved with the addressof fiddling done by
- movtf and friends. */
+ movxf and friends. */
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- ((MODE) == TFmode && (((CLASS1) == GR_REGS && (CLASS2) == FR_REGS) \
+ ((MODE) == XFmode && (((CLASS1) == GR_REGS && (CLASS2) == FR_REGS) \
|| ((CLASS1) == FR_REGS && (CLASS2) == GR_REGS)))
#endif
@@ -1007,7 +1063,7 @@ enum reg_class
#define CLASS_MAX_NREGS(CLASS, MODE) \
((MODE) == BImode && (CLASS) == PR_REGS ? 2 \
- : ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
+ : ((CLASS) == FR_REGS && (MODE) == XFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* In FP regs, we can't change FP values to integer values and vice
@@ -1077,11 +1133,15 @@ enum reg_class
(GET_CODE (VALUE) == MEM \
&& GET_RTX_CLASS (GET_CODE (XEXP ((VALUE), 0))) != 'a' \
&& (reload_in_progress || memory_operand ((VALUE), VOIDmode)))
+/* Symbol ref to small-address-area: */
+#define CONSTRAINT_OK_FOR_T(VALUE) \
+ (GET_CODE (VALUE) == SYMBOL_REF && SYMBOL_REF_SMALL_ADDR_P (VALUE))
#define EXTRA_CONSTRAINT(VALUE, C) \
((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) \
: (C) == 'R' ? CONSTRAINT_OK_FOR_R (VALUE) \
: (C) == 'S' ? CONSTRAINT_OK_FOR_S (VALUE) \
+ : (C) == 'T' ? CONSTRAINT_OK_FOR_T (VALUE) \
: 0)
/* Basic Stack Layout */
@@ -1280,6 +1340,13 @@ enum reg_class
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
+/* Nonzero if we do not know how to pass TYPE solely in registers. */
+
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE)))
+
/* A C type for declaring a variable that is used as the first argument of
`FUNCTION_ARG' and other related values. For some target machines, the type
`int' suffices and can hold the number of bytes of argument so far. */
@@ -1295,7 +1362,7 @@ typedef struct ia64_args
/* A C statement (sans semicolon) for initializing the variable CUM for the
state at the beginning of the argument list. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
do { \
(CUM).words = 0; \
(CUM).int_regs = 0; \
@@ -1344,7 +1411,7 @@ do { \
On many machines, no registers can be used for this purpose since all
function arguments are pushed on the stack. */
#define FUNCTION_ARG_REGNO_P(REGNO) \
-(((REGNO) >= GR_ARG_FIRST && (REGNO) < (GR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \
+(((REGNO) >= AR_ARG_FIRST && (REGNO) < (AR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \
|| ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS)))
/* Implement `va_arg'. */
@@ -1366,7 +1433,7 @@ do { \
gen_rtx_REG (MODE, \
(((GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) && \
- ((MODE) != TFmode || INTEL_EXTENDED_IEEE_FORMAT)) \
+ (MODE) != TFmode) \
? FR_RET_FIRST : GR_RET_FIRST))
/* A C expression that is nonzero if REGNO is the number of a hard register in
@@ -1390,11 +1457,6 @@ do { \
#define DEFAULT_PCC_STRUCT_RETURN 0
-/* If the structure value address is passed in a register, then
- `STRUCT_VALUE_REGNUM' should be the number of that register. */
-
-#define STRUCT_VALUE_REGNUM GR_REG (8)
-
/* Caller-Saves Register Allocation */
@@ -1427,11 +1489,6 @@ do { \
#define EH_USES(REGNO) ia64_eh_uses (REGNO)
-/* Output at beginning of assembler file. */
-
-#define ASM_FILE_START(FILE) \
- emit_safe_across_calls (FILE)
-
/* Output part N of a function descriptor for DECL. For ia64, both
words are emitted with a single relocation, so ignore N > 0. */
#define ASM_OUTPUT_FDESC(FILE, DECL, PART) \
@@ -1537,7 +1594,7 @@ do { \
/* Implicit Calls to Library Routines */
-/* Define this macro if GNU CC should generate calls to the System V (and ANSI
+/* Define this macro if GCC should generate calls to the System V (and ANSI
C) library functions `memcpy' and `memset' rather than the BSD functions
`bcopy' and `bzero'. */
@@ -1643,68 +1700,6 @@ do { \
/* Describing Relative Costs of Operations */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. */
-
-/* ??? This is incomplete. */
-
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT: \
- if ((X) == const0_rtx) \
- return 0; \
- switch (OUTER_CODE) \
- { \
- case SET: \
- return CONST_OK_FOR_J (INTVAL (X)) ? 0 : COSTS_N_INSNS (1); \
- case PLUS: \
- if (CONST_OK_FOR_I (INTVAL (X))) \
- return 0; \
- if (CONST_OK_FOR_J (INTVAL (X))) \
- return 1; \
- return COSTS_N_INSNS (1); \
- default: \
- if (CONST_OK_FOR_K (INTVAL (X)) || CONST_OK_FOR_L (INTVAL (X))) \
- return 0; \
- return COSTS_N_INSNS (1); \
- } \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS (1); \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- return COSTS_N_INSNS (3);
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- 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 (GET_MODE_SIZE (GET_MODE (X)) > 2) \
- return COSTS_N_INSNS (10); \
- return COSTS_N_INSNS (2); \
- case PLUS: \
- case MINUS: \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (1); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- /* We make divide expensive, so that divide-by-constant will be \
- optimized to a multiply. */ \
- return COSTS_N_INSNS (60);
-
-/* An expression giving the cost of an addressing mode that contains ADDRESS.
- If not defined, the cost is computed from the ADDRESS expression and the
- `CONST_COSTS' values. */
-
-#define ADDRESS_COST(ADDRESS) 0
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO, using MODE. */
@@ -1757,8 +1752,6 @@ do { \
#define BSS_SECTION_ASM_OP "\t.bss"
-#define ENCODE_SECTION_INFO_CHAR '@'
-
#define IA64_DEFAULT_GVALUE 8
/* Position Independent Code. */
@@ -1791,17 +1784,12 @@ do { \
/* A C string constant for text to be output before each `asm' statement or
group of consecutive ones. */
-/* ??? This won't work with the Intel assembler, because it does not accept
- # as a comment start character. However, //APP does not work in gas, so we
- can't use that either. Same problem for ASM_APP_OFF below. */
-
-#define ASM_APP_ON "#APP\n"
+#define ASM_APP_ON (TARGET_GNU_AS ? "#APP\n" : "//APP\n")
/* A C string constant for text to be output after each `asm' statement or
group of consecutive ones. */
-#define ASM_APP_OFF "#NO_APP\n"
-
+#define ASM_APP_OFF (TARGET_GNU_AS ? "#NO_APP\n" : "//NO_APP\n")
/* Output of Uninitialized Variables. */
@@ -1843,18 +1831,9 @@ do { \
sprintf (LABEL, "*.%s%d", PREFIX, NUM); \
} while (0)
-/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
- newly allocated string made from the string NAME and the number NUMBER, with
- some suitable punctuation added. */
-
/* ??? Not sure if using a ? in the name for Intel as is safe. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
-do { \
- (OUTVAR) = (char *) alloca (strlen (NAME) + 12); \
- sprintf (OUTVAR, "%s%c%ld", (NAME), (TARGET_GNU_AS ? '.' : '?'), \
- (long)(NUMBER)); \
-} while (0)
+#define ASM_PN_FORMAT (TARGET_GNU_AS ? "%s.%lu" : "%s?%lu")
/* A C statement to output to the stdio stream STREAM assembler code which
defines (equates) the symbol NAME to have the value VALUE. */
@@ -1881,7 +1860,7 @@ do { \
#define REGISTER_NAMES \
{ \
/* General registers. */ \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "ap", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
"r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", \
"r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", \
"r30", "r31", \
@@ -2035,6 +2014,13 @@ do { \
{ "loc79", LOC_REG (79) }, \
}
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ ia64_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
/* A C compound statement to output to stdio stream STREAM the assembler syntax
for an instruction operand X. X is an RTL expression. */
@@ -2168,7 +2154,7 @@ do { \
/* Macros for SDB and Dwarf Output. */
-/* Define this macro if GNU CC should produce dwarf version 2 format debugging
+/* Define this macro if GCC should produce dwarf version 2 format debugging
output in response to the `-g' option. */
#define DWARF2_DEBUGGING_INFO 1
@@ -2177,11 +2163,11 @@ do { \
/* Use tags for debug info labels, so that they don't break instruction
bundles. This also avoids getting spurious DV warnings from the
- assembler. This is similar to ASM_OUTPUT_INTERNAL_LABEL, except that we
+ assembler. This is similar to (*targetm.asm_out.internal_label), except that we
add brackets around the label. */
#define ASM_OUTPUT_DEBUG_LABEL(FILE, PREFIX, NUM) \
- fprintf (FILE, "[.%s%d:]\n", PREFIX, NUM)
+ fprintf (FILE, TARGET_GNU_AS ? "[.%s%d:]\n" : ".%s%d:\n", PREFIX, NUM)
/* Use section-relative relocations for debugging offsets. Unlike other
targets that fake this by putting the section VMA at 0, IA-64 has
@@ -2214,6 +2200,12 @@ do { \
/* Miscellaneous Parameters. */
+/* Flag to mark data that is in the small address area (addressable
+ via "addl", that is, within a 2MByte offset of 0. */
+#define SYMBOL_FLAG_SMALL_ADDR (SYMBOL_FLAG_MACH_DEP << 0)
+#define SYMBOL_REF_SMALL_ADDR_P(X) \
+ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_SMALL_ADDR) != 0)
+
/* Define this if you have defined special-purpose predicates in the file
`MACHINE.c'. For each predicate, list all rtl codes that can be in
expressions matched by the predicate. */
@@ -2222,6 +2214,7 @@ do { \
{ "call_operand", {SUBREG, REG, SYMBOL_REF}}, \
{ "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \
+{ "small_addr_symbolic_operand", {SYMBOL_REF}}, \
{ "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "function_operand", {SYMBOL_REF}}, \
{ "setjmp_operand", {SYMBOL_REF}}, \
@@ -2260,9 +2253,9 @@ do { \
{ "ar_lc_reg_operand", {REG}}, \
{ "ar_ccv_reg_operand", {REG}}, \
{ "ar_pfs_reg_operand", {REG}}, \
-{ "general_tfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
-{ "destination_tfmode_operand", {SUBREG, REG, MEM}}, \
-{ "tfreg_or_fp01_operand", {REG, CONST_DOUBLE}}, \
+{ "general_xfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
+{ "destination_xfmode_operand", {SUBREG, REG, MEM}}, \
+{ "xfreg_or_fp01_operand", {REG, CONST_DOUBLE}}, \
{ "basereg_operand", {SUBREG, REG}},
/* An alias for a machine mode name. This is the machine mode that elements of
@@ -2302,9 +2295,7 @@ do { \
an integral mode and stored by a store-flag instruction (`sCOND') when the
condition is true. */
-/* ??? Investigate using -1 instead of 1. */
-
-#define STORE_FLAG_VALUE 1
+/* ??? Investigate using STORE_FLAG_VALUE of -1 instead of 1. */
/* An alias for the machine mode for pointers. */
@@ -2336,13 +2327,6 @@ do { \
#define HANDLE_SYSV_PRAGMA 1
-/* In rare cases, correct code generation requires extra machine dependent
- processing between the second jump optimization pass and delayed branch
- scheduling. On those machines, define this macro as a C statement to act on
- the code starting at INSN. */
-
-#define MACHINE_DEPENDENT_REORG(INSN) ia64_reorg (INSN)
-
/* A C expression for the maximum number of instructions to execute via
conditional execution instructions instead of a branch. A value of
BRANCH_COST+1 is the default if the machine does not use
@@ -2440,5 +2424,9 @@ enum fetchop_code {
#undef PROFILE_BEFORE_PROLOGUE
#define PROFILE_BEFORE_PROLOGUE 1
-#define FUNCTION_OK_FOR_SIBCALL(DECL) ia64_function_ok_for_sibcall (DECL)
+
+
+/* Switch on code for querying unit reservations. */
+#define CPU_UNITS_QUERY 1
+
/* End of ia64.h */
diff --git a/contrib/gcc/config/ia64/ia64.md b/contrib/gcc/config/ia64/ia64.md
index 3b88d9f..4bda8f4 100644
--- a/contrib/gcc/config/ia64/ia64.md
+++ b/contrib/gcc/config/ia64/ia64.md
@@ -1,22 +1,23 @@
;; IA-64 Machine description template
-;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+;; Free Software Foundation, Inc.
;; Contributed by James E. Wilson <wilson@cygnus.com> and
;; David Mosberger <davidm@hpl.hp.com>.
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -63,7 +64,7 @@
(UNSPEC_FR_RESTORE 13)
(UNSPEC_FR_RECIP_APPROX 14)
(UNSPEC_PRED_REL_MUTEX 15)
- (UNSPEC_POPCNT 16)
+ (UNSPEC_GETF_EXP 16)
(UNSPEC_PIC_CALL 17)
(UNSPEC_MF 18)
(UNSPEC_CMPXCHG_ACQ 19)
@@ -74,6 +75,8 @@
(UNSPEC_ADDP4 24)
(UNSPEC_PROLOGUE_USE 25)
(UNSPEC_RET_ADDR 26)
+ (UNSPEC_SETF_EXP 27)
+ (UNSPEC_FR_SQRT_RECIP_APPROX 28)
])
(define_constants
@@ -93,6 +96,10 @@
;; ::
;; ::::::::::::::::::::
+;; Processor type. This attribute must exactly match the processor_type
+;; enumeration in ia64.h.
+(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
+
;; Instruction type. This primarily determines how instructions can be
;; packed in bundles, and secondarily affects scheduling to function units.
@@ -112,8 +119,8 @@
(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
- syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f,
- nop_i,nop_m,nop_x,lfetch"
+ syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
+ nop_i,nop_m,nop_x,lfetch,pre_cycle"
(const_string "unknown"))
;; chk_s has an I and an M form; use type A for convenience.
@@ -147,77 +154,28 @@
(define_attr "predicable" "no,yes" (const_string "yes"))
+;; Empty. True iff this insn does not generate any code.
+
+(define_attr "empty" "no,yes" (const_string "no"))
+
-;; ::::::::::::::::::::
-;; ::
-;; :: Function Units
-;; ::
-;; ::::::::::::::::::::
-;; We define 6 "dummy" functional units. All the real work to decide which
-;; insn uses which unit is done by our MD_SCHED_REORDER hooks. We only
-;; have to ensure here that there are enough copies of the dummy unit so
-;; that the scheduler doesn't get confused by MD_SCHED_REORDER.
-;; Other than the 6 dummies for normal insns, we also add a single dummy unit
-;; for stop bits.
-
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld") 9 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac") 5 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc") 5 0)
-
-;; There is only one insn `mov = ar.bsp' for frar_i:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0)
-;; There is only ony insn `mov = ar.unat' for frar_m:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr") 2 0)
-
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi") 2 0)
-
-;; Now we have only one insn (flushrs) of such class. We assume that flushrs
-;; is the 1st syllable of the bundle after stop bit.
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem") 11 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0)
-;; Now we use only one insn `mf'. Therfore latency time is set up to 0.
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit") 1 0)
-
-;; There is only one insn `mov ar.pfs =' for toar_i therefore we use
-;; latency time equal to 0:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0)
-;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr") 9 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy") 7 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd") 1 0)
-
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x") 0 0)
-
-(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0)
+;; DFA descriptions of ia64 processors used for insn scheduling and
+;; bundling.
+
+(automata_option "ndfa")
+
+;; Uncomment the following line to output automata for debugging.
+;; (automata_option "v")
+
+(automata_option "w")
+
+;;(automata_option "no-minimization")
+
+
+(include "itanium1.md")
+(include "itanium2.md")
+
;; ::::::::::::::::::::
;; ::
@@ -342,29 +300,6 @@
operands[1] = op1;
})
-;; This is used during early compilation to delay the decision on
-;; how to refer to a variable as long as possible. This is especially
-;; important between initial rtl generation and optimization for
-;; deferred functions, since we may acquire additional information
-;; on the variables used in the meantime.
-
-(define_insn_and_split "movsi_symbolic"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "symbolic_operand" "s"))
- (clobber (match_scratch:DI 2 "=r"))
- (use (reg:DI 1))]
- ""
- "* abort ();"
- "!no_new_pseudos || reload_completed"
- [(const_int 0)]
-{
- rtx scratch = operands[2];
- if (!reload_completed)
- scratch = gen_reg_rtx (Pmode);
- ia64_expand_load_address (operands[0], operands[1], scratch);
- DONE;
-})
-
(define_insn "*movsi_internal"
[(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
(match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
@@ -394,53 +329,11 @@
operands[1] = op1;
})
-;; This is used during early compilation to delay the decision on
-;; how to refer to a variable as long as possible. This is especially
-;; important between initial rtl generation and optimization for
-;; deferred functions, since we may acquire additional information
-;; on the variables used in the meantime.
-
-(define_insn_and_split "movdi_symbolic"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "symbolic_operand" "s"))
- (clobber (match_scratch:DI 2 "=r"))
- (use (reg:DI 1))]
- ""
- "* abort ();"
- "!no_new_pseudos || reload_completed"
- [(const_int 0)]
-{
- rtx scratch = operands[2];
- if (!reload_completed)
- scratch = gen_reg_rtx (Pmode);
- ia64_expand_load_address (operands[0], operands[1], scratch);
- DONE;
-})
-
-;; This is used as a placeholder for the return address during early
-;; compilation. We won't know where we've placed this until during
-;; reload, at which point it can wind up in b0, a general register,
-;; or memory. The only safe destination under these conditions is a
-;; general register.
-
-(define_insn_and_split "*movdi_ret_addr"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
- ""
- "#"
- "reload_completed"
- [(const_int 0)]
-{
- ia64_split_return_addr_rtx (operands[0]);
- DONE;
-}
- [(set_attr "itanium_class" "ialu")])
-
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "destination_operand"
"=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
(match_operand:DI 1 "move_operand"
- "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
+ "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
"ia64_move_ok (operands[0], operands[1])"
{
static const char * const alt[] = {
@@ -473,12 +366,12 @@
[(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,fld,stf,frbr,tobr,frar_i,toar_i,frar_m,toar_m,frpr,topr")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "symbolic_operand" ""))]
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "symbolic_operand" ""))]
"reload_completed && ! TARGET_NO_PIC"
[(const_int 0)]
{
- ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
+ ia64_expand_load_address (operands[0], operands[1]);
DONE;
})
@@ -525,16 +418,24 @@
operands[3] = pic_offset_table_rtx;
})
-(define_expand "load_symptr"
- [(set (match_operand:DI 2 "register_operand" "")
- (plus:DI (high:DI (match_operand:DI 1 "got_symbolic_operand" ""))
- (match_dup 3)))
- (set (match_operand:DI 0 "register_operand" "")
- (lo_sum:DI (match_dup 2) (match_dup 1)))]
+;; This is used as a placeholder for the return address during early
+;; compilation. We won't know where we've placed this until during
+;; reload, at which point it can wind up in b0, a general register,
+;; or memory. The only safe destination under these conditions is a
+;; general register.
+
+(define_insn_and_split "*movdi_ret_addr"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
{
- operands[3] = pic_offset_table_rtx;
-})
+ ia64_split_return_addr_rtx (operands[0]);
+ DONE;
+}
+ [(set_attr "itanium_class" "ialu")])
(define_insn "*load_symptr_high"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -688,11 +589,12 @@
[(set_attr "itanium_class" "ialu")])
;; With no offsettable memory references, we've got to have a scratch
-;; around to play with the second word.
+;; around to play with the second word. However, in order to avoid a
+;; reload nightmare we lie, claim we don't need one, and fix it up
+;; in ia64_split_tmode_move.
(define_expand "movti"
- [(parallel [(set (match_operand:TI 0 "general_operand" "")
- (match_operand:TI 1 "general_operand" ""))
- (clobber (match_scratch:DI 2 ""))])]
+ [(set (match_operand:TI 0 "general_operand" "")
+ (match_operand:TI 1 "general_operand" ""))]
""
{
rtx op1 = ia64_expand_move (operands[0], operands[1]);
@@ -703,106 +605,18 @@
(define_insn_and_split "*movti_internal"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
- (match_operand:TI 1 "general_operand" "ri,m,r"))
- (clobber (match_scratch:DI 2 "=X,&r,&r"))]
+ (match_operand:TI 1 "general_operand" "ri,m,r"))]
"ia64_move_ok (operands[0], operands[1])"
"#"
"reload_completed"
[(const_int 0)]
{
- rtx adj1, adj2, in[2], out[2], insn;
- int first;
-
- adj1 = ia64_split_timode (in, operands[1], operands[2]);
- adj2 = ia64_split_timode (out, operands[0], operands[2]);
-
- first = 0;
- if (reg_overlap_mentioned_p (out[0], in[1]))
- {
- if (reg_overlap_mentioned_p (out[1], in[0]))
- abort ();
- first = 1;
- }
-
- if (adj1 && adj2)
- abort ();
- if (adj1)
- emit_insn (adj1);
- if (adj2)
- emit_insn (adj2);
- insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
- if (GET_CODE (out[first]) == MEM
- && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
- XEXP (XEXP (out[first], 0), 0),
- REG_NOTES (insn));
- insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
- if (GET_CODE (out[!first]) == MEM
- && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
- XEXP (XEXP (out[!first], 0), 0),
- REG_NOTES (insn));
- DONE;
-}
- [(set_attr "itanium_class" "unknown")
- (set_attr "predicable" "no")])
-
-;; ??? SSA creates these. Can't allow memories since we don't have
-;; the scratch register. Fortunately combine will know how to add
-;; the clobber and scratch.
-(define_insn_and_split "*movti_internal_reg"
- [(set (match_operand:TI 0 "register_operand" "=r")
- (match_operand:TI 1 "nonmemory_operand" "ri"))]
- ""
- "#"
- "reload_completed"
- [(const_int 0)]
-{
- rtx in[2], out[2];
- int first;
-
- ia64_split_timode (in, operands[1], NULL_RTX);
- ia64_split_timode (out, operands[0], NULL_RTX);
-
- first = 0;
- if (reg_overlap_mentioned_p (out[0], in[1]))
- {
- if (reg_overlap_mentioned_p (out[1], in[0]))
- abort ();
- first = 1;
- }
-
- emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
- emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
+ ia64_split_tmode_move (operands);
DONE;
}
[(set_attr "itanium_class" "unknown")
(set_attr "predicable" "no")])
-(define_expand "reload_inti"
- [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
- (match_operand:TI 1 "" "m"))
- (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
- ""
-{
- unsigned int s_regno = REGNO (operands[2]);
- if (s_regno == REGNO (operands[0]))
- s_regno += 1;
- operands[2] = gen_rtx_REG (DImode, s_regno);
-})
-
-(define_expand "reload_outti"
- [(parallel [(set (match_operand:TI 0 "" "=m")
- (match_operand:TI 1 "register_operand" "r"))
- (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
- ""
-{
- unsigned int s_regno = REGNO (operands[2]);
- if (s_regno == REGNO (operands[1]))
- s_regno += 1;
- operands[2] = gen_rtx_REG (DImode, s_regno);
-})
-
;; Floating Point Moves
;;
;; Note - Patterns for SF mode moves are compulsory, but
@@ -862,19 +676,19 @@
;; With no offsettable memory references, we've got to have a scratch
;; around to play with the second word if the variable winds up in GRs.
-(define_expand "movtf"
- [(set (match_operand:TF 0 "general_operand" "")
- (match_operand:TF 1 "general_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_expand "movxf"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (match_operand:XF 1 "general_operand" ""))]
+ ""
{
- /* We must support TFmode loads into general registers for stdarg/vararg
+ /* We must support XFmode loads into general registers for stdarg/vararg
and unprototyped calls. We split them into DImode loads for convenience.
- We don't need TFmode stores from general regs, because a stdarg/vararg
+ We don't need XFmode stores from general regs, because a stdarg/vararg
routine does a block store to memory of unnamed arguments. */
if (GET_CODE (operands[0]) == REG
&& GR_REGNO_P (REGNO (operands[0])))
{
- /* We're hoping to transform everything that deals with TFmode
+ /* We're hoping to transform everything that deals with XFmode
quantities and GR registers early in the compiler. */
if (no_new_pseudos)
abort ();
@@ -893,15 +707,15 @@
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
- operand_subword (operands[1], 0, 0, TFmode));
+ operand_subword (operands[1], 0, 0, XFmode));
emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
- operand_subword (operands[1], 1, 0, TFmode));
+ operand_subword (operands[1], 1, 0, XFmode));
DONE;
}
/* If the quantity is in a register not known to be GR, spill it. */
- if (register_operand (operands[1], TFmode))
- operands[1] = spill_tfmode_operand (operands[1], 1);
+ if (register_operand (operands[1], XFmode))
+ operands[1] = spill_xfmode_operand (operands[1], 1);
if (GET_CODE (operands[1]) == MEM)
{
@@ -920,25 +734,53 @@
if (! reload_in_progress && ! reload_completed)
{
- operands[0] = spill_tfmode_operand (operands[0], 0);
- operands[1] = spill_tfmode_operand (operands[1], 0);
+ operands[0] = spill_xfmode_operand (operands[0], 0);
+ operands[1] = spill_xfmode_operand (operands[1], 0);
if (! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (TFmode, operands[1]);
+ operands[1] = force_reg (XFmode, operands[1]);
}
})
;; ??? There's no easy way to mind volatile acquire/release semantics.
-(define_insn "*movtf_internal"
- [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
- (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
- "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])"
+(define_insn "*movxf_internal"
+ [(set (match_operand:XF 0 "destination_xfmode_operand" "=f,f, m")
+ (match_operand:XF 1 "general_xfmode_operand" "fG,m,fG"))]
+ "ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %F1
ldfe %0 = %1%P1
stfe %0 = %F1%P0"
[(set_attr "itanium_class" "fmisc,fld,stf")])
+
+;; Better code generation via insns that deal with TFmode register pairs
+;; directly. Same concerns apply as for TImode.
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "general_operand" "")
+ (match_operand:TF 1 "general_operand" ""))]
+ ""
+{
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
+})
+
+(define_insn_and_split "*movtf_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m")
+ (match_operand:TF 1 "general_operand" "ri,m,r"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+{
+ ia64_split_tmode_move (operands);
+ DONE;
+}
+ [(set_attr "itanium_class" "unknown")
+ (set_attr "predicable" "no")])
+
;; ::::::::::::::::::::
;; ::
@@ -1025,17 +867,17 @@
"fnorm.d %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "extendsftf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "extendsfxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]
+ ""
"fnorm %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "extenddftf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "extenddfxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]
+ ""
"fnorm %0 = %1"
[(set_attr "itanium_class" "fmac")])
@@ -1046,45 +888,29 @@
"fnorm.s %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "trunctfsf2"
+(define_insn "truncxfsf2"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
- (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fnorm.s %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "trunctfdf2"
+(define_insn "truncxfdf2"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
- (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fnorm.d %0 = %1"
[(set_attr "itanium_class" "fmac")])
;; Convert between signed integer types and floating point.
-(define_insn "floatditf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "floatdixf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
+ ""
"fcvt.xf %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-;; ??? Suboptimal. This should be split somehow.
-(define_insn "floatdidf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:DI 1 "register_operand" "f")))]
- "!INTEL_EXTENDED_IEEE_FORMAT"
- "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0"
- [(set_attr "itanium_class" "fcvtfx")])
-
-;; ??? Suboptimal. This should be split somehow.
-(define_insn "floatdisf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:DI 1 "register_operand" "f")))]
- "!INTEL_EXTENDED_IEEE_FORMAT"
- "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0"
- [(set_attr "itanium_class" "fcvtfx")])
-
(define_insn "fix_truncsfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
@@ -1099,18 +925,18 @@
"fcvt.fx.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fix_trunctfdi2"
+(define_insn "fix_truncxfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fcvt.fx.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fix_trunctfdi2_alts"
+(define_insn "fix_truncxfdi2_alts"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
+ (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
(use (match_operand:SI 2 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fcvt.fx.trunc.s%2 %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
@@ -1130,10 +956,10 @@
"fcvt.xuf.d %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "floatunsditf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "floatunsdixf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
+ ""
"fcvt.xuf %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
@@ -1151,18 +977,18 @@
"fcvt.fxu.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fixuns_trunctfdi2"
+(define_insn "fixuns_truncxfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fcvt.fxu.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fixuns_trunctfdi2_alts"
+(define_insn "fixuns_truncxfdi2_alts"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
+ (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
(use (match_operand:SI 2 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fcvt.fxu.trunc.s%2 %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
@@ -2027,32 +1853,32 @@
[(set (match_operand:SI 0 "register_operand" "")
(div:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
+ rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
REAL_VALUE_TYPE twon34_r;
- op0_tf = gen_reg_rtx (TFmode);
+ op0_xf = gen_reg_rtx (XFmode);
op0_di = gen_reg_rtx (DImode);
if (CONSTANT_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
- op1_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 0);
+ op1_xf = gen_reg_rtx (XFmode);
+ expand_float (op1_xf, operands[1], 0);
if (CONSTANT_P (operands[2]))
operands[2] = force_reg (SImode, operands[2]);
- op2_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 0);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 0);
/* 2^-34 */
real_2expN (&twon34_r, -34);
- twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
- twon34 = force_reg (TFmode, twon34);
+ twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
+ twon34 = force_reg (XFmode, twon34);
- emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
+ emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
- emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
+ emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
DONE;
})
@@ -2061,7 +1887,7 @@
[(set (match_operand:SI 0 "register_operand" "")
(mod:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, op1_di, div;
@@ -2084,32 +1910,32 @@
[(set (match_operand:SI 0 "register_operand" "")
(udiv:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
+ rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
REAL_VALUE_TYPE twon34_r;
- op0_tf = gen_reg_rtx (TFmode);
+ op0_xf = gen_reg_rtx (XFmode);
op0_di = gen_reg_rtx (DImode);
if (CONSTANT_P (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
- op1_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 1);
+ op1_xf = gen_reg_rtx (XFmode);
+ expand_float (op1_xf, operands[1], 1);
if (CONSTANT_P (operands[2]))
operands[2] = force_reg (SImode, operands[2]);
- op2_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 1);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 1);
/* 2^-34 */
real_2expN (&twon34_r, -34);
- twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
- twon34 = force_reg (TFmode, twon34);
+ twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
+ twon34 = force_reg (XFmode, twon34);
- emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
+ emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
- emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
+ emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
DONE;
})
@@ -2118,7 +1944,7 @@
[(set (match_operand:SI 0 "register_operand" "")
(umod:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, op1_di, div;
@@ -2138,45 +1964,45 @@
})
(define_insn_and_split "divsi3_internal"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f"))))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
(clobber (match_scratch:BI 6 "=c"))
- (use (match_operand:TF 3 "fr_register_operand" "f"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ (use (match_operand:XF 3 "fr_register_operand" "f"))]
+ "TARGET_INLINE_INT_DIV"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 5)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (mult:TF (match_dup 5) (match_dup 4))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 4))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 5)
- (plus:TF (mult:TF (match_dup 5) (match_dup 5))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 5))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 5) (match_dup 4))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 4))
(match_dup 4)))
(use (const_int 1))]))
]
- "operands[7] = CONST1_RTX (TFmode);"
+ "operands[7] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
;; ::::::::::::::::::::
@@ -2390,7 +2216,7 @@
(set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
(set (match_dup 5) (const_int 0))
(set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
- (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_POPCNT))
+ (set (match_dup 4) (popcount:DI (match_dup 3)))
(set (match_operand:DI 0 "gr_register_operand" "")
(if_then_else:DI (ne (match_dup 6) (const_int 0))
(match_dup 5) (match_dup 4)))]
@@ -2403,40 +2229,77 @@
operands[6] = gen_reg_rtx (BImode);
})
-(define_insn "*popcnt"
+(define_expand "ctzdi2"
+ [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
+ (const_int -1)))
+ (set (match_dup 3) (not:DI (match_dup 1)))
+ (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
+ (set (match_operand:DI 0 "gr_register_operand" "")
+ (popcount:DI (match_dup 4)))]
+ ""
+{
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+})
+
+;; Note the computation here is op0 = 63 - (exp - 0xffff).
+(define_expand "clzdi2"
+ [(set (match_dup 2)
+ (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "")))
+ (set (match_dup 3)
+ (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
+ (set (match_dup 4) (const_int 65598))
+ (set (match_operand:DI 0 "gr_register_operand" "")
+ (minus:DI (match_dup 4) (match_dup 3)))]
+ ""
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+})
+
+(define_insn "popcountdi2"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")]
- UNSPEC_POPCNT))]
+ (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
""
"popcnt %0 = %1"
[(set_attr "itanium_class" "mmmul")])
+(define_insn "*getf_exp_xf"
+ [(set (match_operand:DI 0 "gr_register_operand" "=r")
+ (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
+ UNSPEC_GETF_EXP))]
+ ""
+ "getf.exp %0 = %1"
+ [(set_attr "itanium_class" "frfr")])
+
(define_expand "divdi3"
[(set (match_operand:DI 0 "register_operand" "")
(div:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf;
+ rtx op1_xf, op2_xf, op0_xf;
- op0_tf = gen_reg_rtx (TFmode);
+ op0_xf = gen_reg_rtx (XFmode);
if (CONSTANT_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
- op1_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 0);
+ op1_xf = gen_reg_rtx (XFmode);
+ expand_float (op1_xf, operands[1], 0);
if (CONSTANT_P (operands[2]))
operands[2] = force_reg (DImode, operands[2]);
- op2_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 0);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 0);
if (TARGET_INLINE_INT_DIV_LAT)
- emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
else
- emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
- emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
+ emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
DONE;
})
@@ -2444,7 +2307,7 @@
[(set (match_operand:DI 0 "register_operand" "")
(mod:SI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, div;
@@ -2461,28 +2324,28 @@
[(set (match_operand:DI 0 "register_operand" "")
(udiv:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf;
+ rtx op1_xf, op2_xf, op0_xf;
- op0_tf = gen_reg_rtx (TFmode);
+ op0_xf = gen_reg_rtx (XFmode);
if (CONSTANT_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
- op1_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 1);
+ op1_xf = gen_reg_rtx (XFmode);
+ expand_float (op1_xf, operands[1], 1);
if (CONSTANT_P (operands[2]))
operands[2] = force_reg (DImode, operands[2]);
- op2_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 1);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 1);
if (TARGET_INLINE_INT_DIV_LAT)
- emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
else
- emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
- emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
+ emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
DONE;
})
@@ -2490,7 +2353,7 @@
[(set (match_operand:DI 0 "register_operand" "")
(umod:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, div;
@@ -2504,112 +2367,112 @@
})
(define_insn_and_split "divdi3_internal_lat"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f"))))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
(clobber (match_scratch:BI 6 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_LAT"
+ "TARGET_INLINE_INT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
+ (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (mult:TF (match_dup 3) (match_dup 4))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 4))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 5) (match_dup 4))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 4))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 5) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3)))
(use (const_int 1))]))
]
- "operands[7] = CONST1_RTX (TFmode);"
+ "operands[7] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
(define_insn_and_split "divdi3_internal_thr"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f"))))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=f"))
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_THR"
+ "TARGET_INLINE_INT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
+ (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
+ (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3)))
(use (const_int 1))]))
]
- "operands[6] = CONST1_RTX (TFmode);"
+ "operands[6] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
;; ::::::::::::::::::::
@@ -2721,7 +2584,7 @@
[(set (match_operand:SF 0 "fr_register_operand" "")
(div:SF (match_operand:SF 1 "fr_register_operand" "")
(match_operand:SF 2 "fr_register_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
+ "TARGET_INLINE_FLOAT_DIV"
{
rtx insn;
if (TARGET_INLINE_FLOAT_DIV_LAT)
@@ -2736,44 +2599,44 @@
[(set (match_operand:SF 0 "fr_register_operand" "=&f")
(div:SF (match_operand:SF 1 "fr_register_operand" "f")
(match_operand:SF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=f"))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
+ "TARGET_INLINE_FLOAT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
+ [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
(set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
+ (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
(match_dup 10)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 9)
(float_truncate:DF
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
@@ -2781,11 +2644,11 @@
(float_truncate:SF (match_dup 6))))
]
{
- operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
- operands[10] = CONST1_RTX (TFmode);
+ operands[10] = CONST1_RTX (XFmode);
}
[(set_attr "predicable" "no")])
@@ -2793,53 +2656,202 @@
[(set (match_operand:SF 0 "fr_register_operand" "=&f")
(div:SF (match_operand:SF 1 "fr_register_operand" "f")
(match_operand:SF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=f"))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
+ "TARGET_INLINE_FLOAT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
+ [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
(set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
(match_dup 10)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 3) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 9)
(float_truncate:SF
- (mult:TF (match_dup 7) (match_dup 6))))
+ (mult:XF (match_dup 7) (match_dup 6))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 3)))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(set (match_dup 0)
(float_truncate:SF
- (plus:TF (mult:TF (match_dup 4) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 6))
(match_dup 3)))))
]
{
- operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
- operands[10] = CONST1_RTX (TFmode);
+ operands[10] = CONST1_RTX (XFmode);
+}
+ [(set_attr "predicable" "no")])
+
+;; Inline square root.
+
+(define_insn "*sqrt_approx"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (div:XF (const_int 1)
+ (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
+ (set (match_operand:BI 1 "register_operand" "=c")
+ (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
+ (use (match_operand:SI 3 "const_int_operand" "")) ]
+ ""
+ "frsqrta.s%3 %0, %1 = %2"
+ [(set_attr "itanium_class" "fmisc")
+ (set_attr "predicable" "no")])
+
+(define_insn "*setf_exp_xf"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
+ UNSPEC_SETF_EXP))]
+ ""
+ "setf.exp %0 = %1"
+ [(set_attr "itanium_class" "frfr")])
+
+(define_expand "sqrtsf2"
+ [(set (match_operand:SF 0 "fr_register_operand" "=&f")
+ (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+ if (TARGET_INLINE_SQRT_LAT)
+#if 0
+ insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
+#else
+ abort ();
+#endif
+ else
+ insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
+ emit_insn (insn);
+ DONE;
+})
+
+;; Latency-optimized square root.
+;; FIXME: Implement.
+
+;; Throughput-optimized square root.
+
+(define_insn_and_split "sqrtsf2_internal_thr"
+ [(set (match_operand:SF 0 "fr_register_operand" "=&f")
+ (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))
+ ;; Register r2 in optimization guide.
+ (clobber (match_scratch:DI 2 "=r"))
+ ;; Register f8 in optimization guide
+ (clobber (match_scratch:XF 3 "=&f"))
+ ;; Register f9 in optimization guide
+ (clobber (match_scratch:XF 4 "=&f"))
+ ;; Register f10 in optimization guide
+ (clobber (match_scratch:XF 5 "=&f"))
+ ;; Register p6 in optimization guide.
+ (clobber (match_scratch:BI 6 "=c"))]
+ "TARGET_INLINE_SQRT_THR"
+ "#"
+ "&& reload_completed"
+ [ ;; exponent of +1/2 in r2
+ (set (match_dup 2) (const_int 65534))
+ ;; +1/2 in f8
+ (set (match_dup 3)
+ (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
+ ;; Step 1
+ ;; y0 = 1/sqrt(a) in f7
+ (parallel [(set (match_dup 7)
+ (div:XF (const_int 1)
+ (sqrt:XF (match_dup 8))))
+ (set (match_dup 6)
+ (unspec:BI [(match_dup 8)]
+ UNSPEC_FR_SQRT_RECIP_APPROX))
+ (use (const_int 0))])
+ ;; Step 2
+ ;; H0 = 1/2 * y0 in f9
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (mult:XF (match_dup 3) (match_dup 7))
+ (match_dup 9)))
+ (use (const_int 1))]))
+ ;; Step 3
+ ;; S0 = a * y0 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 7)
+ (plus:XF (mult:XF (match_dup 8) (match_dup 7))
+ (match_dup 9)))
+ (use (const_int 1))]))
+ ;; Step 4
+ ;; d = 1/2 - S0 * H0 in f10
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 5)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 4)))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ;; Step 5
+ ;; d' = d + 1/2 * d in f8
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (mult:XF (match_dup 3) (match_dup 5))
+ (match_dup 5)))
+ (use (const_int 1))]))
+ ;; Step 6
+ ;; e = d + d * d' in f8
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (mult:XF (match_dup 5) (match_dup 3))
+ (match_dup 5)))
+ (use (const_int 1))]))
+ ;; Step 7
+ ;; S1 = S0 + e * S0 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (float_truncate:SF
+ (plus:XF (mult:XF (match_dup 3) (match_dup 7))
+ (match_dup 7))))
+ (use (const_int 1))]))
+ ;; Step 8
+ ;; H1 = H0 + e * H0 in f8
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (mult:XF (match_dup 3) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ ;; Step 9
+ ;; d1 = a - S1 * S1 in f9
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
+ (match_dup 8)))
+ (use (const_int 1))]))
+ ;; Step 10
+ ;; S = S1 + d1 * H1 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (float_truncate:SF
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
+ (match_dup 7))))
+ (use (const_int 0))]))]
+{
+ /* Generate 82-bit versions of the input and output operands. */
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ /* Generate required floating-point constants. */
+ operands[9] = CONST0_RTX (XFmode);
}
[(set_attr "predicable" "no")])
@@ -3030,7 +3042,7 @@
[(set (match_operand:DF 0 "fr_register_operand" "")
(div:DF (match_operand:DF 1 "fr_register_operand" "")
(match_operand:DF 2 "fr_register_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
+ "TARGET_INLINE_FLOAT_DIV"
{
rtx insn;
if (TARGET_INLINE_FLOAT_DIV_LAT)
@@ -3045,80 +3057,80 @@
[(set (match_operand:DF 0 "fr_register_operand" "=&f")
(div:DF (match_operand:DF 1 "fr_register_operand" "f")
(match_operand:DF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
(clobber (match_scratch:BI 6 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
+ "TARGET_INLINE_FLOAT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
+ [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
(set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
+ (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7)))
+ (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 7)))
(match_dup 12)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4)))
+ (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 7)
- (plus:TF (mult:TF (match_dup 4) (match_dup 7))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 7))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 5) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 7)
- (plus:TF (mult:TF (match_dup 5) (match_dup 7))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 7))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 10)
(float_truncate:DF
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 7)
- (plus:TF (mult:TF (match_dup 4) (match_dup 7))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 7))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 11)
(float_truncate:DF
- (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 3)))
(match_dup 8))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(set (match_dup 0)
- (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7))
+ (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
(match_dup 3)))))
]
{
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
- operands[12] = CONST1_RTX (TFmode);
+ operands[12] = CONST1_RTX (XFmode);
}
[(set_attr "predicable" "no")])
@@ -3126,48 +3138,48 @@
[(set (match_operand:DF 0 "fr_register_operand" "=&f")
(div:DF (match_operand:DF 1 "fr_register_operand" "f")
(match_operand:DF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
+ (clobber (match_scratch:XF 3 "=&f"))
(clobber (match_scratch:DF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
+ "TARGET_INLINE_FLOAT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
+ [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
(set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
(match_dup 10)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (mult:TF (match_dup 3) (match_dup 3)))
+ (mult:XF (match_dup 3) (match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (mult:TF (match_dup 3) (match_dup 3)))
+ (mult:XF (match_dup 3) (match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 9)
(float_truncate:DF
- (mult:TF (match_dup 7) (match_dup 3))))
+ (mult:XF (match_dup 7) (match_dup 3))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
@@ -3180,11 +3192,160 @@
(match_dup 9))))
]
{
- operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
- operands[10] = CONST1_RTX (TFmode);
+ operands[10] = CONST1_RTX (XFmode);
+}
+ [(set_attr "predicable" "no")])
+
+;; Inline square root.
+
+(define_expand "sqrtdf2"
+ [(set (match_operand:DF 0 "fr_register_operand" "=&f")
+ (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+ if (TARGET_INLINE_SQRT_LAT)
+#if 0
+ insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
+#else
+ abort ();
+#endif
+ else
+ insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
+ emit_insn (insn);
+ DONE;
+})
+
+;; Latency-optimized square root.
+;; FIXME: Implement.
+
+;; Throughput-optimized square root.
+
+(define_insn_and_split "sqrtdf2_internal_thr"
+ [(set (match_operand:DF 0 "fr_register_operand" "=&f")
+ (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))
+ ;; Register r2 in optimization guide.
+ (clobber (match_scratch:DI 2 "=r"))
+ ;; Register f8 in optimization guide
+ (clobber (match_scratch:XF 3 "=&f"))
+ ;; Register f9 in optimization guide
+ (clobber (match_scratch:XF 4 "=&f"))
+ ;; Register f10 in optimization guide
+ (clobber (match_scratch:XF 5 "=&f"))
+ ;; Register p6 in optimization guide.
+ (clobber (match_scratch:BI 6 "=c"))]
+ "TARGET_INLINE_SQRT_THR"
+ "#"
+ "&& reload_completed"
+ [ ;; exponent of +1/2 in r2
+ (set (match_dup 2) (const_int 65534))
+ ;; +1/2 in f10
+ (set (match_dup 5)
+ (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
+ ;; Step 1
+ ;; y0 = 1/sqrt(a) in f7
+ (parallel [(set (match_dup 7)
+ (div:XF (const_int 1)
+ (sqrt:XF (match_dup 8))))
+ (set (match_dup 6)
+ (unspec:BI [(match_dup 8)]
+ UNSPEC_FR_SQRT_RECIP_APPROX))
+ (use (const_int 0))])
+ ;; Step 2
+ ;; H0 = 1/2 * y0 in f8
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (mult:XF (match_dup 5) (match_dup 7))
+ (match_dup 9)))
+ (use (const_int 1))]))
+ ;; Step 3
+ ;; G0 = a * y0 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 7)
+ (plus:XF (mult:XF (match_dup 8) (match_dup 7))
+ (match_dup 9)))
+ (use (const_int 1))]))
+ ;; Step 4
+ ;; r0 = 1/2 - G0 * H0 in f9
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
+ (match_dup 5)))
+ (use (const_int 1))]))
+ ;; Step 5
+ ;; H1 = H0 + r0 * H0 in f8
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ;; Step 6
+ ;; G1 = G0 + r0 * G0 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 7)
+ (plus:XF (mult:XF (match_dup 4) (match_dup 7))
+ (match_dup 7)))
+ (use (const_int 1))]))
+ ;; Step 7
+ ;; r1 = 1/2 - G1 * H1 in f9
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
+ (match_dup 5)))
+ (use (const_int 1))]))
+ ;; Step 8
+ ;; H2 = H1 + r1 * H1 in f8
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ;; Step 9
+ ;; G2 = G1 + r1 * G1 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 7)
+ (plus:XF (mult:XF (match_dup 4) (match_dup 7))
+ (match_dup 7)))
+ (use (const_int 1))]))
+ ;; Step 10
+ ;; d2 = a - G2 * G2 in f9
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
+ (match_dup 8)))
+ (use (const_int 1))]))
+ ;; Step 11
+ ;; G3 = G2 + d2 * H2 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 7)
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
+ (match_dup 7)))
+ (use (const_int 1))]))
+ ;; Step 12
+ ;; d3 = a - G3 * G3 in f9
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
+ (match_dup 8)))
+ (use (const_int 1))]))
+ ;; Step 13
+ ;; S = G3 + d3 * H2 in f7
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (float_truncate:DF
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
+ (match_dup 7))))
+ (use (const_int 0))]))]
+{
+ /* Generate 82-bit versions of the input and output operands. */
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ /* Generate required floating-point constants. */
+ operands[9] = CONST0_RTX (XFmode);
}
[(set_attr "predicable" "no")])
@@ -3194,499 +3355,674 @@
;; ::
;; ::::::::::::::::::::
-(define_insn "addtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "addxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fadd %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*addtf3_truncsf"
+(define_insn "*addxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fadd.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*addtf3_truncdf"
+(define_insn "*addxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fadd.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "subtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "subxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fsub %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*subtf3_truncsf"
+(define_insn "*subxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fsub.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*subtf3_truncdf"
+(define_insn "*subxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fsub.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "multf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "mulxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fmpy %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncsf"
+(define_insn "*mulxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fmpy.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncdf"
+(define_insn "*mulxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fmpy.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_alts"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
+(define_insn "*mulxf3_alts"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
(use (match_operand:SI 3 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fmpy.s%3 %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncsf_alts"
+(define_insn "*mulxf3_truncsf_alts"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
(use (match_operand:SI 3 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fmpy.s.s%3 %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncdf_alts"
+(define_insn "*mulxf3_truncdf_alts"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
(use (match_operand:SI 3 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fmpy.d.s%3 %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "abstf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "absxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fabs %0 = %F1"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "negtf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "negxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fneg %0 = %F1"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "*nabstf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*nabsxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fnegabs %0 = %F1"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "mintf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "minxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fmin %0 = %F1, %F2"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "maxtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "maxxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fmax %0 = %F1, %F2"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "*maddtf4"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*maddxf4"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fma %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_truncsf"
+(define_insn "*maddxf4_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_truncdf"
+(define_insn "*maddxf4_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_alts"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
+(define_insn "*maddxf4_alts"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
(use (match_operand:SI 4 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fma.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_alts_truncdf"
+(define_insn "*maddxf4_alts_truncsf"
+ [(set (match_operand:SF 0 "fr_register_operand" "=f")
+ (float_truncate:SF
+ (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
+ (use (match_operand:SI 4 "const_int_operand" ""))]
+ ""
+ "fma.s.s%4 %0 = %F1, %F2, %F3"
+ [(set_attr "itanium_class" "fmac")])
+
+(define_insn "*maddxf4_alts_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
+ (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
(use (match_operand:SI 4 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fma.d.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*msubtf4"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*msubxf4"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fms %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*msubtf4_truncsf"
+(define_insn "*msubxf4_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fms.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*msubtf4_truncdf"
+(define_insn "*msubxf4_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fms.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmultf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*nmulxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fnmpy %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmultf3_truncsf"
+(define_insn "*nmulxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
+ ""
"fnmpy.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmultf3_truncdf"
+(define_insn "*nmulxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
+ ""
"fnmpy.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
-(define_insn "*nmaddtf4"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*nmaddxf4"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fnma %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_truncsf"
+(define_insn "*nmaddxf4_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fnma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_truncdf"
+(define_insn "*nmaddxf4_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fnma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_alts"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
+(define_insn "*nmaddxf4_alts"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
(use (match_operand:SI 4 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fnma.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_truncdf_alts"
+(define_insn "*nmaddxf4_truncdf_alts"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (neg:TF
- (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
+ (plus:XF (neg:XF
+ (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
(use (match_operand:SI 4 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fnma.d.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_expand "divtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "")
- (div:TF (match_operand:TF 1 "fr_register_operand" "")
- (match_operand:TF 2 "fr_register_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
+(define_expand "divxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "")
+ (div:XF (match_operand:XF 1 "fr_register_operand" "")
+ (match_operand:XF 2 "fr_register_operand" "")))]
+ "TARGET_INLINE_FLOAT_DIV"
{
rtx insn;
if (TARGET_INLINE_FLOAT_DIV_LAT)
- insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]);
+ insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
else
- insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]);
+ insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
emit_insn (insn);
DONE;
})
-(define_insn_and_split "divtf3_internal_lat"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (div:TF (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
- (clobber (match_scratch:TF 6 "=&f"))
+(define_insn_and_split "divxf3_internal_lat"
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (div:XF (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f")))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
+ (clobber (match_scratch:XF 6 "=&f"))
(clobber (match_scratch:BI 7 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
+ "TARGET_INLINE_FLOAT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 8)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
+ (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 5) (match_dup 5))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 5))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 5)
- (plus:TF (mult:TF (match_dup 6) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 6) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 5) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 3))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 5)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 8)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3))))
]
- "operands[8] = CONST1_RTX (TFmode);"
+ "operands[8] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
-(define_insn_and_split "divtf3_internal_thr"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (div:TF (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
+(define_insn_and_split "divxf3_internal_thr"
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (div:XF (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f")))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
+ "TARGET_INLINE_FLOAT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
+ (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 3) (match_dup 4))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 4))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 0) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 0) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3))))
]
- "operands[6] = CONST1_RTX (TFmode);"
+ "operands[6] = CONST1_RTX (XFmode);"
+ [(set_attr "predicable" "no")])
+
+;; Inline square root.
+
+(define_expand "sqrtxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+ if (TARGET_INLINE_SQRT_LAT)
+#if 0
+ insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
+#else
+ abort ();
+#endif
+ else
+ insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]);
+ emit_insn (insn);
+ DONE;
+})
+
+;; Latency-optimized square root.
+;; FIXME: Implement.
+
+;; Throughput-optimized square root.
+
+(define_insn_and_split "sqrtxf2_internal_thr"
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))
+ ;; Register r2 in optimization guide.
+ (clobber (match_scratch:DI 2 "=r"))
+ ;; Register f8 in optimization guide
+ (clobber (match_scratch:XF 3 "=&f"))
+ ;; Register f9 in optimization guide
+ (clobber (match_scratch:XF 4 "=&f"))
+ ;; Register f10 in optimization guide
+ (clobber (match_scratch:XF 5 "=&f"))
+ ;; Register f11 in optimization guide
+ (clobber (match_scratch:XF 6 "=&f"))
+ ;; Register p6 in optimization guide.
+ (clobber (match_scratch:BI 7 "=c"))]
+ "TARGET_INLINE_SQRT_THR"
+ "#"
+ "&& reload_completed"
+ [ ;; exponent of +1/2 in r2
+ (set (match_dup 2) (const_int 65534))
+ ;; +1/2 in f8. The Intel manual mistakenly specifies f10.
+ (set (match_dup 3)
+ (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
+ ;; Step 1
+ ;; y0 = 1/sqrt(a) in f7
+ (parallel [(set (match_dup 8)
+ (div:XF (const_int 1)
+ (sqrt:XF (match_dup 9))))
+ (set (match_dup 7)
+ (unspec:BI [(match_dup 9)]
+ UNSPEC_FR_SQRT_RECIP_APPROX))
+ (use (const_int 0))])
+ ;; Step 2
+ ;; H0 = 1/2 * y0 in f9
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (mult:XF (match_dup 3) (match_dup 8))
+ (match_dup 10)))
+ (use (const_int 1))]))
+ ;; Step 3
+ ;; S0 = a * y0 in f7
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 8)
+ (plus:XF (mult:XF (match_dup 9) (match_dup 8))
+ (match_dup 10)))
+ (use (const_int 1))]))
+ ;; Step 4
+ ;; d0 = 1/2 - S0 * H0 in f10
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 5)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ;; Step 5
+ ;; H1 = H0 + d0 * H0 in f9
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (mult:XF (match_dup 5) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ ;; Step 6
+ ;; S1 = S0 + d0 * S0 in f7
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 8)
+ (plus:XF (mult:XF (match_dup 5) (match_dup 8))
+ (match_dup 8)))
+ (use (const_int 1))]))
+ ;; Step 7
+ ;; d1 = 1/2 - S1 * H1 in f10
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 5)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ;; Step 8
+ ;; H2 = H1 + d1 * H1 in f9
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (mult:XF (match_dup 5) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ ;; Step 9
+ ;; S2 = S1 + d1 * S1 in f7
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 8)
+ (plus:XF (mult:XF (match_dup 5) (match_dup 8))
+ (match_dup 8)))
+ (use (const_int 1))]))
+ ;; Step 10
+ ;; d2 = 1/2 - S2 * H2 in f10
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 5)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ;; Step 11
+ ;; e2 = a - S2 * S2 in f8
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
+ (match_dup 9)))
+ (use (const_int 1))]))
+ ;; Step 12
+ ;; S3 = S2 + e2 * H2 in f7
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 8)
+ (plus:XF (mult:XF (match_dup 3) (match_dup 4))
+ (match_dup 8)))
+ (use (const_int 1))]))
+ ;; Step 13
+ ;; H3 = H2 + d2 * H2 in f9
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:XF (mult:XF (match_dup 5) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ ;; Step 14
+ ;; e3 = a - S3 * S3 in f8
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
+ (match_dup 9)))
+ (use (const_int 1))]))
+ ;; Step 15
+ ;; S = S3 + e3 * H3 in f7
+ (cond_exec (ne (match_dup 7) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:XF (mult:XF (match_dup 3) (match_dup 4))
+ (match_dup 8)))
+ (use (const_int 0))]))]
+{
+ /* Generate 82-bit versions of the input and output operands. */
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ /* Generate required floating-point constants. */
+ operands[10] = CONST0_RTX (XFmode);
+}
[(set_attr "predicable" "no")])
;; ??? frcpa works like cmp.foo.unc.
(define_insn "*recip_approx"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (div:TF (const_int 1)
- (match_operand:TF 3 "fr_register_operand" "f")))
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (div:XF (const_int 1)
+ (match_operand:XF 3 "fr_register_operand" "f")))
(set (match_operand:BI 1 "register_operand" "=c")
- (unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
+ (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f")
(match_dup 3)] UNSPEC_FR_RECIP_APPROX))
(use (match_operand:SI 4 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"frcpa.s%4 %0, %1 = %2, %3"
[(set_attr "itanium_class" "fmisc")
(set_attr "predicable" "no")])
@@ -4083,11 +4419,22 @@
DONE;
})
+(define_expand "cmpxf"
+ [(set (cc0)
+ (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
+ ""
+{
+ ia64_compare_op0 = operands[0];
+ ia64_compare_op1 = operands[1];
+ DONE;
+})
+
(define_expand "cmptf"
[(set (cc0)
- (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
- (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (compare (match_operand:TF 0 "gr_register_operand" "")
+ (match_operand:TF 1 "gr_register_operand" "")))]
+ "TARGET_HPUX"
{
ia64_compare_op0 = operands[0];
ia64_compare_op1 = operands[1];
@@ -4154,12 +4501,12 @@
"fcmp.%D1 %0, %I0 = %F2, %F3"
[(set_attr "itanium_class" "fcmp")])
-(define_insn "*cmptf_internal"
+(define_insn "*cmpxf_internal"
[(set (match_operand:BI 0 "register_operand" "=c")
(match_operator:BI 1 "comparison_operator"
- [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
+ ""
"fcmp.%D1 %0, %I0 = %F2, %F3"
[(set_attr "itanium_class" "fcmp")])
@@ -4464,9 +4811,9 @@
"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
(const_int 0)])
(match_operand:DI 2 "move_operand"
- "rnm, *f, *b,*d*e,rnm,rnm, rnm,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
+ "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
(match_operand:DI 3 "move_operand"
- "rnm,rnm,rnm, rnm, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
+ "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
{ abort (); }
@@ -4483,29 +4830,26 @@
"reload_completed"
[(const_int 0)]
{
- rtx tmp;
- int emitted_something;
+ bool emitted_something = false;
+ rtx dest = operands[0];
+ rtx srct = operands[2];
+ rtx srcf = operands[3];
+ rtx cond = operands[4];
- emitted_something = 0;
- if (! rtx_equal_p (operands[0], operands[2]))
+ if (! rtx_equal_p (dest, srct))
{
- tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
- tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
- emit_insn (tmp);
- emitted_something = 1;
+ ia64_emit_cond_move (dest, srct, cond);
+ emitted_something = true;
}
- if (! rtx_equal_p (operands[0], operands[3]))
+ if (! rtx_equal_p (dest, srcf))
{
- tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
- VOIDmode, operands[1], const0_rtx);
- tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
- gen_rtx_SET (VOIDmode, operands[0],
- operands[3]));
- emit_insn (tmp);
- emitted_something = 1;
+ cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
+ VOIDmode, operands[1], const0_rtx);
+ ia64_emit_cond_move (dest, srcf, cond);
+ emitted_something = true;
}
if (! emitted_something)
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
DONE;
})
@@ -4570,9 +4914,9 @@
[(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
(const_int 0)])
(match_operand:SI 2 "move_operand"
- "0,0,0,rnm*f,rO,rO,rnm*f,rO,rO")
+ "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
(match_operand:SI 3 "move_operand"
- "rnm*f,rO,rO,0,0,0,rnm*f,rO,rO")))]
+ "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
{ abort (); }
@@ -4786,7 +5130,7 @@
[(set_attr "itanium_class" "br,scall")])
(define_insn "call_value_nogp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "=X,X")
(call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
(const_int 0)))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))]
@@ -4802,7 +5146,7 @@
[(set_attr "itanium_class" "br,scall")])
(define_insn "call_gp"
- [(call (mem (match_operand 0 "call_operand" "?r,i"))
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
(const_int 1))
(clobber (match_operand:DI 1 "register_operand" "=b,b"))
(clobber (match_scratch:DI 2 "=&r,X"))
@@ -4842,7 +5186,7 @@
})
(define_insn "call_value_gp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "=X,X")
(call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
(const_int 1)))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))
@@ -5062,7 +5406,8 @@
""
""
[(set_attr "itanium_class" "ignore")
- (set_attr "predicable" "no")])
+ (set_attr "predicable" "no")
+ (set_attr "empty" "yes")])
;; Allocate a new register frame.
@@ -5123,16 +5468,16 @@
[(set_attr "itanium_class" "ld")])
(define_insn "fr_spill"
- [(set (match_operand:TF 0 "memory_operand" "=m")
- (unspec:TF [(match_operand:TF 1 "register_operand" "f")]
+ [(set (match_operand:XF 0 "memory_operand" "=m")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FR_SPILL))]
""
"stf.spill %0 = %1%P0"
[(set_attr "itanium_class" "stf")])
(define_insn "fr_restore"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (unspec:TF [(match_operand:TF 1 "memory_operand" "m")]
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
UNSPEC_FR_RESTORE))]
""
"ldf.fill %0 = %1%P1"
@@ -5191,7 +5536,7 @@
;; ::
;; ::::::::::::::::::::
-;; ??? Emiting a NOP instruction isn't very useful. This should probably
+;; ??? Emitting a NOP instruction isn't very useful. This should probably
;; be emitting ";;" to force a break in the instruction packing.
;; No operation, needed in case the user uses -g but not -O.
@@ -5199,7 +5544,7 @@
[(const_int 0)]
""
"nop 0"
- [(set_attr "itanium_class" "unknown")])
+ [(set_attr "itanium_class" "nop")])
(define_insn "nop_m"
[(const_int 1)]
@@ -5229,7 +5574,16 @@
[(const_int 5)]
""
""
- [(set_attr "itanium_class" "nop_x")])
+ [(set_attr "itanium_class" "nop_x")
+ (set_attr "empty" "yes")])
+
+;; The following insn will be never generated. It is used only by
+;; insn scheduler to change state before advancing cycle.
+(define_insn "pre_cycle"
+ [(const_int 6)]
+ ""
+ ""
+ [(set_attr "itanium_class" "pre_cycle")])
(define_insn "bundle_selector"
[(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
@@ -5253,7 +5607,8 @@
""
";;"
[(set_attr "itanium_class" "stop_bit")
- (set_attr "predicable" "no")])
+ (set_attr "predicable" "no")
+ (set_attr "empty" "yes")])
(define_expand "trap"
[(trap_if (const_int 1) (const_int 0))]
@@ -5425,8 +5780,8 @@
(define_insn "fetchadd_acq_si"
[(set (match_operand:SI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:SI [(match_dup 1)
(match_operand:SI 2 "fetchadd_operand" "n")]
UNSPEC_FETCHADD_ACQ))]
@@ -5436,8 +5791,8 @@
(define_insn "fetchadd_acq_di"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:DI [(match_dup 1)
(match_operand:DI 2 "fetchadd_operand" "n")]
UNSPEC_FETCHADD_ACQ))]
@@ -5447,11 +5802,11 @@
(define_insn "cmpxchg_acq_si"
[(set (match_operand:SI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:SI [(match_dup 1)
(match_operand:SI 2 "gr_register_operand" "r")
- (match_operand 3 "ar_ccv_reg_operand" "")]
+ (match_operand:DI 3 "ar_ccv_reg_operand" "")]
UNSPEC_CMPXCHG_ACQ))]
""
"cmpxchg4.acq %0 = %1, %2, %3"
@@ -5459,8 +5814,8 @@
(define_insn "cmpxchg_acq_di"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:DI [(match_dup 1)
(match_operand:DI 2 "gr_register_operand" "r")
(match_operand:DI 3 "ar_ccv_reg_operand" "")]
@@ -5515,7 +5870,7 @@
[(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
""
{
- emit_safe_across_calls (asm_out_file);
+ emit_safe_across_calls ();
return "";
}
[(set_attr "itanium_class" "ignore")
@@ -5535,7 +5890,7 @@
;;
;; Optimizations for ptr_extend
-(define_insn "*ptr_extend_plus_1"
+(define_insn "ptr_extend_plus_imm"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
(unspec:DI
[(plus:SI (match_operand:SI 1 "basereg_operand" "r")
diff --git a/contrib/gcc/config/ia64/itanium1.md b/contrib/gcc/config/ia64/itanium1.md
new file mode 100644
index 0000000..2b84411
--- /dev/null
+++ b/contrib/gcc/config/ia64/itanium1.md
@@ -0,0 +1,1616 @@
+;; Itanium1 (original Itanium) DFA descriptions for insn scheduling
+;; and bundling.
+;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Contributed by Vladimir Makarov <vmakarov@redhat.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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA. */
+;;
+
+
+/* This is description of pipeline hazards based on DFA. The
+ following constructions can be used for this:
+
+ o define_cpu_unit string [string]) describes a cpu functional unit
+ (separated by comma).
+
+ 1st operand: Names of cpu function units.
+ 2nd operand: Name of automaton (see comments for
+ DEFINE_AUTOMATON).
+
+ All define_reservations and define_cpu_units should have unique
+ names which can not be "nothing".
+
+ o (exclusion_set string string) means that each CPU function unit
+ in the first string can not be reserved simultaneously with each
+ unit whose name is in the second string and vise versa. CPU
+ units in the string are separated by commas. For example, it is
+ useful for description CPU with fully pipelined floating point
+ functional unit which can execute simultaneously only single
+ floating point insns or only double floating point insns.
+
+ o (presence_set string string) means that each CPU function unit in
+ the first string can not be reserved unless at least one of
+ pattern of units whose names are in the second string is
+ reserved. This is an asymmetric relation. CPU units or unit
+ patterns in the strings are separated by commas. Pattern is one
+ unit name or unit names separated by white-spaces.
+
+ For example, it is useful for description that slot1 is reserved
+ after slot0 reservation for a VLIW processor. We could describe
+ it by the following construction
+
+ (presence_set "slot1" "slot0")
+
+ Or slot1 is reserved only after slot0 and unit b0 reservation.
+ In this case we could write
+
+ (presence_set "slot1" "slot0 b0")
+
+ All CPU functional units in a set should belong to the same
+ automaton.
+
+ o (final_presence_set string string) is analogous to
+ `presence_set'. The difference between them is when checking is
+ done. When an instruction is issued in given automaton state
+ reflecting all current and planned unit reservations, the
+ automaton state is changed. The first state is a source state,
+ the second one is a result state. Checking for `presence_set' is
+ done on the source state reservation, checking for
+ `final_presence_set' is done on the result reservation. This
+ construction is useful to describe a reservation which is
+ actually two subsequent reservations. For example, if we use
+
+ (presence_set "slot1" "slot0")
+
+ the following insn will be never issued (because slot1 requires
+ slot0 which is absent in the source state).
+
+ (define_reservation "insn_and_nop" "slot0 + slot1")
+
+ but it can be issued if we use analogous `final_presence_set'.
+
+ o (absence_set string string) means that each CPU function unit in
+ the first string can be reserved only if each pattern of units
+ whose names are in the second string is not reserved. This is an
+ asymmetric relation (actually exclusion set is analogous to this
+ one but it is symmetric). CPU units or unit patterns in the
+ string are separated by commas. Pattern is one unit name or unit
+ names separated by white-spaces.
+
+ For example, it is useful for description that slot0 can not be
+ reserved after slot1 or slot2 reservation for a VLIW processor.
+ We could describe it by the following construction
+
+ (absence_set "slot2" "slot0, slot1")
+
+ Or slot2 can not be reserved if slot0 and unit b0 are reserved or
+ slot1 and unit b1 are reserved . In this case we could write
+
+ (absence_set "slot2" "slot0 b0, slot1 b1")
+
+ All CPU functional units in a set should to belong the same
+ automaton.
+
+ o (final_absence_set string string) is analogous to `absence_set' but
+ checking is done on the result (state) reservation. See comments
+ for final_presence_set.
+
+ o (define_bypass number out_insn_names in_insn_names) names bypass with
+ given latency (the first number) from insns given by the first
+ string (see define_insn_reservation) into insns given by the
+ second string. Insn names in the strings are separated by
+ commas.
+
+ o (define_automaton string) describes names of an automaton
+ generated and used for pipeline hazards recognition. The names
+ are separated by comma. Actually it is possibly to generate the
+ single automaton but unfortunately it can be very large. If we
+ use more one automata, the summary size of the automata usually
+ is less than the single one. The automaton name is used in
+ define_cpu_unit. All automata should have unique names.
+
+ o (automata_option string) describes option for generation of
+ automata. Currently there are the following options:
+
+ o "no-minimization" which makes no minimization of automata.
+ This is only worth to do when we are debugging the description
+ and need to look more accurately at reservations of states.
+
+ o "ndfa" which makes automata with nondetermenistic reservation
+ by insns.
+
+ o (define_reservation string string) names reservation (the first
+ string) of cpu functional units (the 2nd string). Sometimes unit
+ reservations for different insns contain common parts. In such
+ case, you describe common part and use one its name (the 1st
+ parameter) in regular expression in define_insn_reservation. All
+ define_reservations, define results and define_cpu_units should
+ have unique names which can not be "nothing".
+
+ o (define_insn_reservation name default_latency condition regexpr)
+ describes reservation of cpu functional units (the 3nd operand)
+ for instruction which is selected by the condition (the 2nd
+ parameter). The first parameter is used for output of debugging
+ information. The reservations are described by a regular
+ expression according the following syntax:
+
+ regexp = regexp "," oneof
+ | oneof
+
+ oneof = oneof "|" allof
+ | allof
+
+ allof = allof "+" repeat
+ | repeat
+
+ repeat = element "*" number
+ | element
+
+ element = cpu_function_name
+ | reservation_name
+ | result_name
+ | "nothing"
+ | "(" regexp ")"
+
+ 1. "," is used for describing start of the next cycle in
+ reservation.
+
+ 2. "|" is used for describing the reservation described by the
+ first regular expression *or* the reservation described by
+ the second regular expression *or* etc.
+
+ 3. "+" is used for describing the reservation described by the
+ first regular expression *and* the reservation described by
+ the second regular expression *and* etc.
+
+ 4. "*" is used for convenience and simply means sequence in
+ which the regular expression are repeated NUMBER times with
+ cycle advancing (see ",").
+
+ 5. cpu function unit name which means reservation.
+
+ 6. reservation name -- see define_reservation.
+
+ 7. string "nothing" means no units reservation.
+
+*/
+
+(define_automaton "one")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx" "one")
+(define_cpu_unit "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b,\
+ 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx." "one")
+(define_cpu_unit "1_0mii., 1_0mmi., 1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb.,\
+ 1_0mib., 1_0mmb., 1_0mfb." "one")
+
+(define_cpu_unit "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb,\
+ 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx" "one")
+(define_cpu_unit "1_1mi.i, 1_1mm.i, 1_1mf.i, 1_1bb.b, 1_1mb.b,\
+ 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx." "one")
+(define_cpu_unit "1_1mii., 1_1mmi., 1_1mfi., 1_1bbb., 1_1mbb.,\
+ 1_1mib., 1_1mmb., 1_1mfb." "one")
+
+;; Slot 1
+(exclusion_set "1_0m.ii"
+ "1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb,\
+ 1_0m.lx")
+(exclusion_set "1_0m.mi"
+ "1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.fi"
+ "1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.mf"
+ "1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0b.bb" "1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.bb" "1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.ib" "1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.mb" "1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.fb" "1_0m.lx")
+
+;; Slot 2
+(exclusion_set "1_0mi.i"
+ "1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b,\
+ 1_0mlx.")
+(exclusion_set "1_0mm.i"
+ "1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mf.i"
+ "1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mm.f"
+ "1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0bb.b" "1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mb.b" "1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mi.b" "1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mm.b" "1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mf.b" "1_0mlx.")
+
+;; Slot 3
+(exclusion_set "1_0mii."
+ "1_0mmi., 1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb.,\
+ 1_0mlx.")
+(exclusion_set "1_0mmi."
+ "1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mfi."
+ "1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mmf."
+ "1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0bbb." "1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mbb." "1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mib." "1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mmb." "1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mfb." "1_0mlx.")
+
+;; Slot 4
+(exclusion_set "1_1m.ii"
+ "1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.mi"
+ "1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.fi"
+ "1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1b.bb" "1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.bb" "1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.ib" "1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.mb" "1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.fb" "1_1m.lx")
+
+;; Slot 5
+(exclusion_set "1_1mi.i"
+ "1_1mm.i, 1_1mf.i, 1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mm.i"
+ "1_1mf.i, 1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mf.i"
+ "1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1bb.b" "1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mb.b" "1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mi.b" "1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mm.b" "1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mf.b" "1_1mlx.")
+
+;; Slot 6
+(exclusion_set "1_1mii."
+ "1_1mmi., 1_1mfi., 1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mmi."
+ "1_1mfi., 1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mfi."
+ "1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1bbb." "1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mbb." "1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mib." "1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mmb." "1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mfb." "1_1mlx.")
+
+(final_presence_set "1_0mi.i" "1_0m.ii")
+(final_presence_set "1_0mii." "1_0mi.i")
+(final_presence_set "1_1mi.i" "1_1m.ii")
+(final_presence_set "1_1mii." "1_1mi.i")
+
+(final_presence_set "1_0mm.i" "1_0m.mi")
+(final_presence_set "1_0mmi." "1_0mm.i")
+(final_presence_set "1_1mm.i" "1_1m.mi")
+(final_presence_set "1_1mmi." "1_1mm.i")
+
+(final_presence_set "1_0mf.i" "1_0m.fi")
+(final_presence_set "1_0mfi." "1_0mf.i")
+(final_presence_set "1_1mf.i" "1_1m.fi")
+(final_presence_set "1_1mfi." "1_1mf.i")
+
+(final_presence_set "1_0mm.f" "1_0m.mf")
+(final_presence_set "1_0mmf." "1_0mm.f")
+
+(final_presence_set "1_0bb.b" "1_0b.bb")
+(final_presence_set "1_0bbb." "1_0bb.b")
+(final_presence_set "1_1bb.b" "1_1b.bb")
+(final_presence_set "1_1bbb." "1_1bb.b")
+
+(final_presence_set "1_0mb.b" "1_0m.bb")
+(final_presence_set "1_0mbb." "1_0mb.b")
+(final_presence_set "1_1mb.b" "1_1m.bb")
+(final_presence_set "1_1mbb." "1_1mb.b")
+
+(final_presence_set "1_0mi.b" "1_0m.ib")
+(final_presence_set "1_0mib." "1_0mi.b")
+(final_presence_set "1_1mi.b" "1_1m.ib")
+(final_presence_set "1_1mib." "1_1mi.b")
+
+(final_presence_set "1_0mm.b" "1_0m.mb")
+(final_presence_set "1_0mmb." "1_0mm.b")
+(final_presence_set "1_1mm.b" "1_1m.mb")
+(final_presence_set "1_1mmb." "1_1mm.b")
+
+(final_presence_set "1_0mf.b" "1_0m.fb")
+(final_presence_set "1_0mfb." "1_0mf.b")
+(final_presence_set "1_1mf.b" "1_1m.fb")
+(final_presence_set "1_1mfb." "1_1mf.b")
+
+(final_presence_set "1_0mlx." "1_0m.lx")
+(final_presence_set "1_1mlx." "1_1m.lx")
+
+(final_presence_set
+ "1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx"
+ "1_0mii.,1_0mmi.,1_0mfi.,1_0mmf.,1_0bbb.,1_0mbb.,1_0mib.,1_0mmb.,1_0mfb.,\
+ 1_0mlx.")
+
+;; Microarchitecture units:
+(define_cpu_unit
+ "1_um0, 1_um1, 1_ui0, 1_ui1, 1_uf0, 1_uf1, 1_ub0, 1_ub1, 1_ub2,\
+ 1_unb0, 1_unb1, 1_unb2" "one")
+
+(exclusion_set "1_ub0" "1_unb0")
+(exclusion_set "1_ub1" "1_unb1")
+(exclusion_set "1_ub2" "1_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium microarchitecture. They also
+;; describe the following rules mentioned in Itanium
+;; microarchitecture: rules mentioned in Itanium microarchitecture:
+;; o "MMF: Always splits issue before the first M and after F regardless
+;; of surrounding bundles and stops".
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+
+(exclusion_set "1_0m.mf,1_0mm.f,1_0mmf."
+ "1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx")
+(exclusion_set "1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb."
+ "1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx")
+(exclusion_set "1_0m.ib,1_0mi.b,1_0mib." "1_1b.bb")
+
+;; For exceptions of M, I, B, F insns:
+(define_cpu_unit "1_not_um1, 1_not_ui1, 1_not_uf1" "one")
+
+(final_absence_set "1_not_um1" "1_um1")
+(final_absence_set "1_not_ui1" "1_ui1")
+(final_absence_set "1_not_uf1" "1_uf1")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb,\
+ 1_1m.lx"
+ "1_0mib. 1_ub2, 1_0mfb. 1_ub2, 1_0mmb. 1_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "1_stop" "one")
+(final_absence_set
+ "1_0m.ii,1_0mi.i,1_0mii.,1_0m.mi,1_0mm.i,1_0mmi.,1_0m.fi,1_0mf.i,1_0mfi.,\
+ 1_0m.mf,1_0mm.f,1_0mmf.,1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb.,\
+ 1_0m.ib,1_0mi.b,1_0mib.,1_0m.mb,1_0mm.b,1_0mmb.,1_0m.fb,1_0mf.b,1_0mfb.,\
+ 1_0m.lx,1_0mlx., \
+ 1_1m.ii,1_1mi.i,1_1mii.,1_1m.mi,1_1mm.i,1_1mmi.,1_1m.fi,1_1mf.i,1_1mfi.,\
+ 1_1b.bb,1_1bb.b,1_1bbb.,1_1m.bb,1_1mb.b,1_1mbb.,1_1m.ib,1_1mi.b,1_1mib.,\
+ 1_1m.mb,1_1mm.b,1_1mmb.,1_1m.fb,1_1mf.b,1_1mfb.,1_1m.lx,1_1mlx."
+ "1_stop")
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(final_presence_set "1_um1" "1_um0")
+(final_presence_set "1_ui1" "1_ui0, 1_1mii., 1_1mmi., 1_1mfi.")
+
+;; Insns
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(define_reservation "1_M0"
+ "1_0m.ii+1_um0|1_0m.mi+1_um0|1_0mm.i+(1_um0|1_um1)\
+ |1_0m.fi+1_um0|1_0m.mf+1_um0|1_0mm.f+1_um1\
+ |1_0m.bb+1_um0|1_0m.ib+1_um0|1_0m.mb+1_um0\
+ |1_0mm.b+1_um1|1_0m.fb+1_um0|1_0m.lx+1_um0\
+ |1_1mm.i+1_um1|1_1mm.b+1_um1\
+ |(1_1m.ii|1_1m.mi|1_1m.fi|1_1m.bb|1_1m.ib|1_1m.mb|1_1m.fb|1_1m.lx)\
+ +(1_um0|1_um1)")
+
+(define_reservation "1_M1"
+ "(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mib.+1_unb0|1_0mfb.+1_unb0|1_0mmb.+1_unb0)\
+ +(1_1m.ii|1_1m.mi|1_1m.fi|1_1m.bb|1_1m.ib|1_1m.mb|1_1m.fb|1_1m.lx)\
+ +(1_um0|1_um1)")
+
+(define_reservation "1_M" "1_M0|1_M1")
+
+;; Exceptions for dispersal rules.
+;; "An I slot in the 3rd position of 2nd bundle is always dispersed to I1".
+(define_reservation "1_I0"
+ "1_0mi.i+1_ui0|1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mi.b+1_ui0|(1_1mi.i|1_1mi.b)+(1_ui0|1_ui1)\
+ |1_1mii.+1_ui1|1_1mmi.+1_ui1|1_1mfi.+1_ui1")
+
+(define_reservation "1_I1"
+ "1_0m.ii+1_um0+1_0mi.i+1_ui0|1_0mm.i+(1_um0|1_um1)+1_0mmi.+1_ui0\
+ |1_0mf.i+1_uf0+1_0mfi.+1_ui0|1_0m.ib+1_um0+1_0mi.b+1_ui0\
+ |(1_1m.ii+(1_um0|1_um1)+1_1mi.i\
+ |1_1m.ib+(1_um0|1_um1)+1_1mi.b)+(1_ui0|1_ui1)\
+ |1_1mm.i+1_um1+1_1mmi.+1_ui1|1_1mf.i+1_uf1+1_1mfi.+1_ui1")
+
+(define_reservation "1_I" "1_I0|1_I1")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "1_F0"
+ "1_0mf.i+1_uf0|1_0mmf.+1_uf0|1_0mf.b+1_uf0|1_1mf.i+1_uf1|1_1mf.b+1_uf1")
+
+(define_reservation "1_F1"
+ "1_0m.fi+1_um0+1_0mf.i+1_uf0|1_0mm.f+(1_um0|1_um1)+1_0mmf.+1_uf0\
+ |1_0m.fb+1_um0+1_0mf.b+1_uf0|1_1m.fi+(1_um0|1_um1)+1_1mf.i+1_uf1\
+ |1_1m.fb+(1_um0|1_um1)+1_1mf.b+1_uf1")
+
+(define_reservation "1_F2"
+ "1_0m.mf+1_um0+1_0mm.f+1_um1+1_0mmf.+1_uf0\
+ |(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0)\
+ +(1_1m.fi+(1_um0|1_um1)+1_1mf.i+1_uf1\
+ |1_1m.fb+(1_um0|1_um1)+1_1mf.b+1_uf1)")
+
+(define_reservation "1_F" "1_F0|1_F1|1_F2")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "1_NB"
+ "1_0b.bb+1_unb0|1_0bb.b+1_unb1|1_0bbb.+1_unb2\
+ |1_0mb.b+1_unb1|1_0mbb.+1_unb2\
+ |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0\
+ |1_1b.bb+1_unb0|1_1bb.b+1_unb1\
+ |1_1bbb.+1_unb2|1_1mb.b+1_unb1|1_1mbb.+1_unb2|1_1mib.+1_unb0\
+ |1_1mmb.+1_unb0|1_1mfb.+1_unb0")
+
+(define_reservation "1_B0"
+ "1_0b.bb+1_ub0|1_0bb.b+1_ub1|1_0bbb.+1_ub2\
+ |1_0mb.b+1_ub1|1_0mbb.+1_ub2|1_0mib.+1_ub2\
+ |1_0mfb.+1_ub2|1_1b.bb+1_ub0|1_1bb.b+1_ub1\
+ |1_1bbb.+1_ub2|1_1mb.b+1_ub1\
+ |1_1mib.+1_ub2|1_1mmb.+1_ub2|1_1mfb.+1_ub2")
+
+(define_reservation "1_B1"
+ "1_0m.bb+1_um0+1_0mb.b+1_ub1|1_0mi.b+1_ui0+1_0mib.+1_ub2\
+ |1_0mf.b+1_uf0+1_0mfb.+1_ub2\
+ |(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0)+1_1b.bb+1_ub0\
+ |1_1m.bb+(1_um0|1_um1)+1_1mb.b+1_ub1\
+ |1_1mi.b+(1_ui0|1_ui1)+1_1mib.+1_ub2\
+ |1_1mm.b+1_um1+1_1mmb.+1_ub2\
+ |1_1mf.b+1_uf1+1_1mfb.+1_ub2")
+
+(define_reservation "1_B" "1_B0|1_B1")
+
+;; MLX bunlde uses ports equivalent to MFI bundles.
+(define_reservation "1_L0" "1_0mlx.+1_ui0+1_uf0|1_1mlx.+(1_ui0|1_ui1)+1_uf1")
+(define_reservation "1_L1"
+ "1_0m.lx+1_um0+1_0mlx.+1_ui0+1_uf0\
+ |1_1m.lx+(1_um0|1_um1)+1_1mlx.+(1_ui0|1_ui1)+1_uf1")
+(define_reservation "1_L2"
+ "(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0)
+ +1_1m.lx+(1_um0|1_um1)+1_1mlx.+1_ui1+1_uf1")
+(define_reservation "1_L" "1_L0|1_L1|1_L2")
+
+(define_reservation "1_A" "1_M|1_I")
+
+(define_insn_reservation "1_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stop_bit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_stop|1_m0_stop|1_m1_stop|1_mi0_stop|1_mi1_stop")
+
+(define_insn_reservation "1_br" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "br"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_B")
+(define_insn_reservation "1_scall" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "scall"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_B")
+(define_insn_reservation "1_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_F+1_not_uf1")
+(define_insn_reservation "1_fcvtfx" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+(define_insn_reservation "1_fld" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fld"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_fmac" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmac"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+(define_insn_reservation "1_fmisc" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmisc"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_F+1_not_uf1")
+
+;; There is only one insn `mov = ar.bsp' for frar_i:
+(define_insn_reservation "1_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+;; There is only two insns `mov = ar.unat' or `mov = ar.ccv' for frar_m:
+(define_insn_reservation "1_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_frbr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frbr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_frfr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frfr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_frpr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frpr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+
+(define_insn_reservation "1_ialu" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref
+ "bundling_p || ia64_produce_address_p (insn)")
+ (const_int 0)))
+ "1_A")
+(define_insn_reservation "1_ialu_addr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref
+ "!bundling_p && ia64_produce_address_p (insn)")
+ (const_int 1)))
+ "1_M")
+(define_insn_reservation "1_icmp" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "icmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+(define_insn_reservation "1_ilog" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ilog"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+(define_insn_reservation "1_ishf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ishf"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_ld" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ld"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_long_i" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "long_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_L")
+(define_insn_reservation "1_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmmul"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshf"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+(define_insn_reservation "1_mmshfi" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshfi"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+
+;; Now we have only one insn (flushrs) of such class. We assume that flushrs
+;; is the 1st syllable of the bundle after stop bit.
+(define_insn_reservation "1_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "rse_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "(1_0m.ii|1_0m.mi|1_0m.fi|1_0m.mf|1_0b.bb|1_0m.bb\
+ |1_0m.ib|1_0m.mb|1_0m.fb|1_0m.lx)+1_um0")
+(define_insn_reservation "1_sem" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "sem"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_stf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stf"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_st" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "st"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m0"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_tbit" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tbit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+
+;; There is only ony insn `mov ar.pfs =' for toar_i:
+(define_insn_reservation "1_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
+(define_insn_reservation "1_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_tobr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tobr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_tofr" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tofr"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_topr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "topr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_xmpy" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xmpy"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+(define_insn_reservation "1_xtd" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xtd"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+
+(define_insn_reservation "1_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "chk_s"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+(define_insn_reservation "1_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "lfetch"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+
+(define_insn_reservation "1_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M0")
+(define_insn_reservation "1_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_b"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_NB")
+(define_insn_reservation "1_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I0")
+(define_insn_reservation "1_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_f"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F0")
+(define_insn_reservation "1_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_x"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_L0")
+
+;; We assume that there is no insn issued on the same cycle as unknown insn.
+(define_cpu_unit "1_empty" "one")
+(exclusion_set "1_empty"
+ "1_0m.ii,1_0m.mi,1_0m.fi,1_0m.mf,1_0b.bb,1_0m.bb,1_0m.ib,1_0m.mb,1_0m.fb,\
+ 1_0m.lx")
+
+(define_insn_reservation "1_unknown" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "unknown"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_empty")
+
+(define_insn_reservation "1_nop" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M0|1_NB|1_I0|1_F0")
+
+(define_insn_reservation "1_ignore" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ignore"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "nothing")
+
+
+(define_cpu_unit
+ "1_0m_bs, 1_0mi_bs, 1_0mm_bs, 1_0mf_bs, 1_0b_bs, 1_0bb_bs, 1_0mb_bs"
+ "one")
+(define_cpu_unit
+ "1_1m_bs, 1_1mi_bs, 1_1mm_bs, 1_1mf_bs, 1_1b_bs, 1_1bb_bs, 1_1mb_bs"
+ "one")
+
+(define_cpu_unit "1_m_cont, 1_mi_cont, 1_mm_cont, 1_mf_cont, 1_mb_cont,\
+ 1_b_cont, 1_bb_cont" "one")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "1_m_stop, 1_m0_stop, 1_m1_stop, 1_0mmi_cont" "one")
+(define_cpu_unit "1_mi_stop, 1_mi0_stop, 1_mi1_stop, 1_0mii_cont" "one")
+
+(final_presence_set "1_0m_bs"
+ "1_0m.ii, 1_0m.mi, 1_0m.mf, 1_0m.fi, 1_0m.bb,\
+ 1_0m.ib, 1_0m.fb, 1_0m.mb, 1_0m.lx")
+(final_presence_set "1_1m_bs"
+ "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1m.bb, 1_1m.ib, 1_1m.fb, 1_1m.mb,\
+ 1_1m.lx")
+(final_presence_set "1_0mi_bs" "1_0mi.i, 1_0mi.i")
+(final_presence_set "1_1mi_bs" "1_1mi.i, 1_1mi.i")
+(final_presence_set "1_0mm_bs" "1_0mm.i, 1_0mm.f, 1_0mm.b")
+(final_presence_set "1_1mm_bs" "1_1mm.i, 1_1mm.b")
+(final_presence_set "1_0mf_bs" "1_0mf.i, 1_0mf.b")
+(final_presence_set "1_1mf_bs" "1_1mf.i, 1_1mf.b")
+(final_presence_set "1_0b_bs" "1_0b.bb")
+(final_presence_set "1_1b_bs" "1_1b.bb")
+(final_presence_set "1_0bb_bs" "1_0bb.b")
+(final_presence_set "1_1bb_bs" "1_1bb.b")
+(final_presence_set "1_0mb_bs" "1_0mb.b")
+(final_presence_set "1_1mb_bs" "1_1mb.b")
+
+(exclusion_set "1_0m_bs"
+ "1_0mi.i, 1_0mm.i, 1_0mm.f, 1_0mf.i, 1_0mb.b,\
+ 1_0mi.b, 1_0mf.b, 1_0mm.b, 1_0mlx., 1_m0_stop")
+(exclusion_set "1_1m_bs"
+ "1_1mi.i, 1_1mm.i, 1_1mf.i, 1_1mb.b, 1_1mi.b, 1_1mf.b, 1_1mm.b,\
+ 1_1mlx., 1_m1_stop")
+(exclusion_set "1_0mi_bs" "1_0mii., 1_0mib., 1_mi0_stop")
+(exclusion_set "1_1mi_bs" "1_1mii., 1_1mib., 1_mi1_stop")
+(exclusion_set "1_0mm_bs" "1_0mmi., 1_0mmf., 1_0mmb.")
+(exclusion_set "1_1mm_bs" "1_1mmi., 1_1mmb.")
+(exclusion_set "1_0mf_bs" "1_0mfi., 1_0mfb.")
+(exclusion_set "1_1mf_bs" "1_1mfi., 1_1mfb.")
+(exclusion_set "1_0b_bs" "1_0bb.b")
+(exclusion_set "1_1b_bs" "1_1bb.b")
+(exclusion_set "1_0bb_bs" "1_0bbb.")
+(exclusion_set "1_1bb_bs" "1_1bbb.")
+(exclusion_set "1_0mb_bs" "1_0mbb.")
+(exclusion_set "1_1mb_bs" "1_1mbb.")
+
+(exclusion_set
+ "1_0m_bs, 1_0mi_bs, 1_0mm_bs, 1_0mf_bs, 1_0b_bs, 1_0bb_bs, 1_0mb_bs,
+ 1_1m_bs, 1_1mi_bs, 1_1mm_bs, 1_1mf_bs, 1_1b_bs, 1_1bb_bs, 1_1mb_bs"
+ "1_stop")
+
+(final_presence_set
+ "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0mb.b,\
+ 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx."
+ "1_m_cont")
+(final_presence_set "1_0mii., 1_0mib." "1_mi_cont")
+(final_presence_set "1_0mmi., 1_0mmf., 1_0mmb." "1_mm_cont")
+(final_presence_set "1_0mfi., 1_0mfb." "1_mf_cont")
+(final_presence_set "1_0bb.b" "1_b_cont")
+(final_presence_set "1_0bbb." "1_bb_cont")
+(final_presence_set "1_0mbb." "1_mb_cont")
+
+(exclusion_set
+ "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx"
+ "1_m_cont, 1_mi_cont, 1_mm_cont, 1_mf_cont,\
+ 1_mb_cont, 1_b_cont, 1_bb_cont")
+
+(exclusion_set "1_empty"
+ "1_m_cont,1_mi_cont,1_mm_cont,1_mf_cont,\
+ 1_mb_cont,1_b_cont,1_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "1_m0_stop" "1_0m.mi")
+(final_presence_set "1_0mm.i" "1_0mmi_cont")
+(exclusion_set "1_0mmi_cont"
+ "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_m0_stop" "1_0mm.i")
+(final_presence_set "1_m1_stop" "1_1m.mi")
+(exclusion_set "1_m1_stop" "1_1mm.i")
+(final_presence_set "1_m_stop" "1_m0_stop, 1_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "1_mi0_stop" "1_0mi.i")
+(final_presence_set "1_0mii." "1_0mii_cont")
+(exclusion_set "1_0mii_cont"
+ "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_mi0_stop" "1_0mii.")
+(final_presence_set "1_mi1_stop" "1_1mi.i")
+(exclusion_set "1_mi1_stop" "1_1mii.")
+(final_presence_set "1_mi_stop" "1_mi0_stop, 1_mi1_stop")
+
+(final_absence_set
+ "1_0m.ii,1_0mi.i,1_0mii.,1_0m.mi,1_0mm.i,1_0mmi.,1_0m.fi,1_0mf.i,1_0mfi.,\
+ 1_0m.mf,1_0mm.f,1_0mmf.,1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb.,\
+ 1_0m.ib,1_0mi.b,1_0mib.,1_0m.mb,1_0mm.b,1_0mmb.,1_0m.fb,1_0mf.b,1_0mfb.,\
+ 1_0m.lx,1_0mlx., \
+ 1_1m.ii,1_1mi.i,1_1mii.,1_1m.mi,1_1mm.i,1_1mmi.,1_1m.fi,1_1mf.i,1_1mfi.,\
+ 1_1b.bb,1_1bb.b,1_1bbb.,1_1m.bb,1_1mb.b,1_1mbb.,\
+ 1_1m.ib,1_1mi.b,1_1mib.,1_1m.mb,1_1mm.b,1_1mmb.,1_1m.fb,1_1mf.b,1_1mfb.,\
+ 1_1m.lx,1_1mlx."
+ "1_m0_stop,1_m1_stop,1_mi0_stop,1_mi1_stop")
+
+(define_cpu_unit "1_m_cont_only, 1_b_cont_only" "one")
+(define_cpu_unit "1_mi_cont_only, 1_mm_cont_only, 1_mf_cont_only" "one")
+(define_cpu_unit "1_mb_cont_only, 1_bb_cont_only" "one")
+
+(final_presence_set "1_m_cont_only" "1_m_cont")
+(exclusion_set "1_m_cont_only"
+ "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0mb.b,\
+ 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+
+(final_presence_set "1_b_cont_only" "1_b_cont")
+(exclusion_set "1_b_cont_only" "1_0bb.b")
+
+(final_presence_set "1_mi_cont_only" "1_mi_cont")
+(exclusion_set "1_mi_cont_only" "1_0mii., 1_0mib.")
+
+(final_presence_set "1_mm_cont_only" "1_mm_cont")
+(exclusion_set "1_mm_cont_only" "1_0mmi., 1_0mmf., 1_0mmb.")
+
+(final_presence_set "1_mf_cont_only" "1_mf_cont")
+(exclusion_set "1_mf_cont_only" "1_0mfi., 1_0mfb.")
+
+(final_presence_set "1_mb_cont_only" "1_mb_cont")
+(exclusion_set "1_mb_cont_only" "1_0mbb.")
+
+(final_presence_set "1_bb_cont_only" "1_bb_cont")
+(exclusion_set "1_bb_cont_only" "1_0bbb.")
+
+(define_insn_reservation "1_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "(1_0m_bs, 1_m_cont) \
+ | (1_0mi_bs, (1_mi_cont|nothing)) \
+ | (1_0mm_bs, 1_mm_cont) \
+ | (1_0mf_bs, (1_mf_cont|nothing)) \
+ | (1_0b_bs, (1_b_cont|nothing)) \
+ | (1_0bb_bs, (1_bb_cont|nothing)) \
+ | (1_0mb_bs, (1_mb_cont|nothing)) \
+ | (1_1m_bs, 1_m_cont) \
+ | (1_1mi_bs, (1_mi_cont|nothing)) \
+ | (1_1mm_bs, 1_mm_cont) \
+ | (1_1mf_bs, (1_mf_cont|nothing)) \
+ | (1_1b_bs, (1_b_cont|nothing)) \
+ | (1_1bb_bs, (1_bb_cont|nothing)) \
+ | (1_1mb_bs, (1_mb_cont|nothing)) \
+ | (1_m_cont_only, (1_m_cont|nothing)) \
+ | (1_b_cont_only, (1_b_cont|nothing)) \
+ | (1_mi_cont_only, (1_mi_cont|nothing)) \
+ | (1_mm_cont_only, (1_mm_cont|nothing)) \
+ | (1_mf_cont_only, (1_mf_cont|nothing)) \
+ | (1_mb_cont_only, (1_mb_cont|nothing)) \
+ | (1_bb_cont_only, (1_bb_cont|nothing)) \
+ | (1_m_stop, (1_0mmi_cont|nothing)) \
+ | (1_mi_stop, (1_0mii_cont|nothing))")
+
+;; Bypasses:
+(define_bypass 1 "1_fcmp" "1_br,1_scall")
+;; ??? I found 7 cycle delay for 1_fmac -> 1_fcmp for Itanium1
+(define_bypass 7 "1_fmac" "1_fmisc,1_fcvtfx,1_xmpy,1_fcmp")
+
+;; ???
+(define_bypass 3 "1_frbr" "1_mmmul,1_mmshf")
+(define_bypass 14 "1_frar_i" "1_mmmul,1_mmshf")
+(define_bypass 7 "1_frar_m" "1_mmmul,1_mmshf")
+
+;; ????
+;; There is only one insn `mov ar.pfs =' for toar_i.
+(define_bypass 0 "1_tobr,1_topr,1_toar_i" "1_br,1_scall")
+
+(define_bypass 3 "1_ialu,1_ialu_addr" "1_mmmul,1_mmshf")
+;; ??? howto describe ialu for I slot only. We use ialu_addr for that
+;;(define_bypass 2 "1_ialu" "1_ld" "ia64_ld_address_bypass_p")
+;; ??? howto describe ialu st/address for I slot only. We use ialu_addr
+;; for that.
+;;(define_bypass 2 "1_ialu" "1_st" "ia64_st_address_bypass_p")
+
+(define_bypass 0 "1_icmp" "1_br,1_scall")
+
+(define_bypass 3 "1_ilog" "1_mmmul,1_mmshf")
+
+(define_bypass 2 "1_ilog,1_xtd" "1_ld" "ia64_ld_address_bypass_p")
+(define_bypass 2 "1_ilog,1_xtd" "1_st" "ia64_st_address_bypass_p")
+
+(define_bypass 3 "1_ld" "1_mmmul,1_mmshf")
+(define_bypass 3 "1_ld" "1_ld" "ia64_ld_address_bypass_p")
+(define_bypass 3 "1_ld" "1_st" "ia64_st_address_bypass_p")
+
+;; Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
+;; but HP engineers say any non-MM operation.
+(define_bypass 4 "1_mmmul,1_mmshf"
+ "1_br,1_fcmp,1_fcvtfx,1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,\
+ 1_frbr,1_frfr,1_frpr,1_ialu,1_icmp,1_ilog,1_ishf,1_ld,1_chk_s,\
+ 1_long_i,1_rse_m,1_sem,1_stf,1_st,1_syst_m0,1_syst_m,\
+ 1_tbit,1_toar_i,1_toar_m,1_tobr,1_tofr,1_topr,1_xmpy,1_xtd")
+
+;; ??? how to describe that if scheduled < 4 cycle then latency is 10 cycles.
+;; (define_bypass 10 "1_mmmul,1_mmshf" "1_ialu,1_ilog,1_ishf,1_st,1_ld")
+
+(define_bypass 0 "1_tbit" "1_br,1_scall")
+
+(define_bypass 8 "1_tofr" "1_frfr,1_stf")
+(define_bypass 7 "1_fmisc,1_fcvtfx,1_fmac,1_xmpy" "1_frfr")
+(define_bypass 8 "1_fmisc,1_fcvtfx,1_fmac,1_xmpy" "1_stf")
+
+;; We don't use here fcmp because scall may be predicated.
+(define_bypass 0 "1_fcvtfx,1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,\
+ 1_frbr,1_frfr,1_frpr,1_ialu,1_ialu_addr,1_ilog,1_ishf,\
+ 1_ld,1_long_i,1_mmmul,1_mmshf,1_mmshfi,1_toar_m,1_tofr,\
+ 1_xmpy,1_xtd" "1_scall")
+
+(define_bypass 0 "1_unknown,1_ignore,1_stop_bit,1_br,1_fcmp,1_fcvtfx,\
+ 1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,1_frbr,1_frfr,\
+ 1_frpr,1_ialu,1_ialu_addr,1_icmp,1_ilog,1_ishf,1_ld,\
+ 1_chk_s,1_long_i,1_mmmul,1_mmshf,1_mmshfi,1_nop,\
+ 1_nop_b,1_nop_f,1_nop_i,1_nop_m,1_nop_x,1_rse_m,1_scall,\
+ 1_sem,1_stf,1_st,1_syst_m0,1_syst_m,1_tbit,1_toar_i,\
+ 1_toar_m,1_tobr,1_tofr,1_topr,1_xmpy,1_xtd,1_lfetch"
+ "1_ignore")
+
+
+;; Bundling
+
+(define_automaton "oneb")
+
+;; Pseudo units for quicker searching for position in two packet window. */
+(define_query_cpu_unit "1_1,1_2,1_3,1_4,1_5,1_6" "oneb")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx" "oneb")
+(define_cpu_unit
+ "1b_0mi.i, 1b_0mm.i, 1b_0mf.i, 1b_0mm.f, 1b_0bb.b, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b" "oneb")
+(define_query_cpu_unit
+ "1b_0mii., 1b_0mmi., 1b_0mfi., 1b_0mmf., 1b_0bbb., 1b_0mbb.,\
+ 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx." "oneb")
+
+(define_cpu_unit "1b_1m.ii, 1b_1m.mi, 1b_1m.fi, 1b_1b.bb, 1b_1m.bb,\
+ 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx" "oneb")
+(define_cpu_unit "1b_1mi.i, 1b_1mm.i, 1b_1mf.i, 1b_1bb.b, 1b_1mb.b,\
+ 1b_1mi.b, 1b_1mm.b, 1b_1mf.b" "oneb")
+(define_query_cpu_unit "1b_1mii., 1b_1mmi., 1b_1mfi., 1b_1bbb., 1b_1mbb.,\
+ 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx." "oneb")
+
+;; Slot 1
+(exclusion_set "1b_0m.ii"
+ "1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.mi"
+ "1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb, 1b_0m.ib,\
+ 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.fi"
+ "1b_0m.mf, 1b_0b.bb, 1b_0m.bb, 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.mf"
+ "1b_0b.bb, 1b_0m.bb, 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0b.bb" "1b_0m.bb, 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.bb" "1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.ib" "1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.mb" "1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.fb" "1b_0m.lx")
+
+;; Slot 2
+(exclusion_set "1b_0mi.i"
+ "1b_0mm.i, 1b_0mf.i, 1b_0mm.f, 1b_0bb.b, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mm.i"
+ "1b_0mf.i, 1b_0mm.f, 1b_0bb.b, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mf.i"
+ "1b_0mm.f, 1b_0bb.b, 1b_0mb.b, 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mm.f"
+ "1b_0bb.b, 1b_0mb.b, 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0bb.b" "1b_0mb.b, 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mb.b" "1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mi.b" "1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mm.b" "1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mf.b" "1b_0mlx.")
+
+;; Slot 3
+(exclusion_set "1b_0mii."
+ "1b_0mmi., 1b_0mfi., 1b_0mmf., 1b_0bbb., 1b_0mbb.,\
+ 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mmi."
+ "1b_0mfi., 1b_0mmf., 1b_0bbb., 1b_0mbb.,\
+ 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mfi."
+ "1b_0mmf., 1b_0bbb., 1b_0mbb., 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mmf."
+ "1b_0bbb., 1b_0mbb., 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0bbb." "1b_0mbb., 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mbb." "1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mib." "1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mmb." "1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mfb." "1b_0mlx.")
+
+;; Slot 4
+(exclusion_set "1b_1m.ii"
+ "1b_1m.mi, 1b_1m.fi, 1b_1b.bb, 1b_1m.bb,\
+ 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.mi"
+ "1b_1m.fi, 1b_1b.bb, 1b_1m.bb, 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.fi"
+ "1b_1b.bb, 1b_1m.bb, 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1b.bb" "1b_1m.bb, 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.bb" "1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.ib" "1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.mb" "1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.fb" "1b_1m.lx")
+
+;; Slot 5
+(exclusion_set "1b_1mi.i"
+ "1b_1mm.i, 1b_1mf.i, 1b_1bb.b, 1b_1mb.b,\
+ 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mm.i"
+ "1b_1mf.i, 1b_1bb.b, 1b_1mb.b, 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mf.i"
+ "1b_1bb.b, 1b_1mb.b, 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1bb.b" "1b_1mb.b, 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mb.b" "1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mi.b" "1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mm.b" "1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mf.b" "1b_1mlx.")
+
+;; Slot 6
+(exclusion_set "1b_1mii."
+ "1b_1mmi., 1b_1mfi., 1b_1bbb., 1b_1mbb.,\
+ 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mmi."
+ "1b_1mfi., 1b_1bbb., 1b_1mbb., 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mfi."
+ "1b_1bbb., 1b_1mbb., 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1bbb." "1b_1mbb., 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mbb." "1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mib." "1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mmb." "1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mfb." "1b_1mlx.")
+
+(final_presence_set "1b_0mi.i" "1b_0m.ii")
+(final_presence_set "1b_0mii." "1b_0mi.i")
+(final_presence_set "1b_1mi.i" "1b_1m.ii")
+(final_presence_set "1b_1mii." "1b_1mi.i")
+
+(final_presence_set "1b_0mm.i" "1b_0m.mi")
+(final_presence_set "1b_0mmi." "1b_0mm.i")
+(final_presence_set "1b_1mm.i" "1b_1m.mi")
+(final_presence_set "1b_1mmi." "1b_1mm.i")
+
+(final_presence_set "1b_0mf.i" "1b_0m.fi")
+(final_presence_set "1b_0mfi." "1b_0mf.i")
+(final_presence_set "1b_1mf.i" "1b_1m.fi")
+(final_presence_set "1b_1mfi." "1b_1mf.i")
+
+(final_presence_set "1b_0mm.f" "1b_0m.mf")
+(final_presence_set "1b_0mmf." "1b_0mm.f")
+
+(final_presence_set "1b_0bb.b" "1b_0b.bb")
+(final_presence_set "1b_0bbb." "1b_0bb.b")
+(final_presence_set "1b_1bb.b" "1b_1b.bb")
+(final_presence_set "1b_1bbb." "1b_1bb.b")
+
+(final_presence_set "1b_0mb.b" "1b_0m.bb")
+(final_presence_set "1b_0mbb." "1b_0mb.b")
+(final_presence_set "1b_1mb.b" "1b_1m.bb")
+(final_presence_set "1b_1mbb." "1b_1mb.b")
+
+(final_presence_set "1b_0mi.b" "1b_0m.ib")
+(final_presence_set "1b_0mib." "1b_0mi.b")
+(final_presence_set "1b_1mi.b" "1b_1m.ib")
+(final_presence_set "1b_1mib." "1b_1mi.b")
+
+(final_presence_set "1b_0mm.b" "1b_0m.mb")
+(final_presence_set "1b_0mmb." "1b_0mm.b")
+(final_presence_set "1b_1mm.b" "1b_1m.mb")
+(final_presence_set "1b_1mmb." "1b_1mm.b")
+
+(final_presence_set "1b_0mf.b" "1b_0m.fb")
+(final_presence_set "1b_0mfb." "1b_0mf.b")
+(final_presence_set "1b_1mf.b" "1b_1m.fb")
+(final_presence_set "1b_1mfb." "1b_1mf.b")
+
+(final_presence_set "1b_0mlx." "1b_0m.lx")
+(final_presence_set "1b_1mlx." "1b_1m.lx")
+
+(final_presence_set
+ "1b_1m.ii,1b_1m.mi,1b_1m.fi,1b_1b.bb,1b_1m.bb,\
+ 1b_1m.ib,1b_1m.mb,1b_1m.fb,1b_1m.lx"
+ "1b_0mii.,1b_0mmi.,1b_0mfi.,1b_0mmf.,1b_0bbb.,1b_0mbb.,\
+ 1b_0mib.,1b_0mmb.,1b_0mfb.,1b_0mlx.")
+
+;; Microarchitecture units:
+(define_cpu_unit
+ "1b_um0, 1b_um1, 1b_ui0, 1b_ui1, 1b_uf0, 1b_uf1, 1b_ub0, 1b_ub1, 1b_ub2,\
+ 1b_unb0, 1b_unb1, 1b_unb2" "oneb")
+
+(exclusion_set "1b_ub0" "1b_unb0")
+(exclusion_set "1b_ub1" "1b_unb1")
+(exclusion_set "1b_ub2" "1b_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium microarchitecture. They also
+;; describe the following rules mentioned in Itanium
+;; microarchitecture: rules mentioned in Itanium microarchitecture:
+;; o "MMF: Always splits issue before the first M and after F regardless
+;; of surrounding bundles and stops".
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+
+(exclusion_set "1b_0m.mf,1b_0mm.f,1b_0mmf."
+ "1b_1m.ii,1b_1m.mi,1b_1m.fi,1b_1b.bb,1b_1m.bb,\
+ 1b_1m.ib,1b_1m.mb,1b_1m.fb,1b_1m.lx")
+(exclusion_set "1b_0b.bb,1b_0bb.b,1b_0bbb.,1b_0m.bb,1b_0mb.b,1b_0mbb."
+ "1b_1m.ii,1b_1m.mi,1b_1m.fi,1b_1b.bb,1b_1m.bb,\
+ 1b_1m.ib,1b_1m.mb,1b_1m.fb,1b_1m.lx")
+(exclusion_set "1b_0m.ib,1b_0mi.b,1b_0mib." "1b_1b.bb")
+
+;; For exceptions of M, I, B, F insns:
+(define_cpu_unit "1b_not_um1, 1b_not_ui1, 1b_not_uf1" "oneb")
+
+(final_absence_set "1b_not_um1" "1b_um1")
+(final_absence_set "1b_not_ui1" "1b_ui1")
+(final_absence_set "1b_not_uf1" "1b_uf1")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "1b_1m.ii, 1b_1m.mi, 1b_1m.fi, 1b_1b.bb, 1b_1m.bb,\
+ 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx"
+ "1b_0mib. 1b_ub2, 1b_0mfb. 1b_ub2, 1b_0mmb. 1b_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "1b_stop" "oneb")
+(final_absence_set
+ "1b_0m.ii,1b_0mi.i,1b_0mii.,1b_0m.mi,1b_0mm.i,1b_0mmi.,\
+ 1b_0m.fi,1b_0mf.i,1b_0mfi.,\
+ 1b_0m.mf,1b_0mm.f,1b_0mmf.,1b_0b.bb,1b_0bb.b,1b_0bbb.,\
+ 1b_0m.bb,1b_0mb.b,1b_0mbb.,\
+ 1b_0m.ib,1b_0mi.b,1b_0mib.,1b_0m.mb,1b_0mm.b,1b_0mmb.,\
+ 1b_0m.fb,1b_0mf.b,1b_0mfb.,1b_0m.lx,1b_0mlx., \
+ 1b_1m.ii,1b_1mi.i,1b_1mii.,1b_1m.mi,1b_1mm.i,1b_1mmi.,\
+ 1b_1m.fi,1b_1mf.i,1b_1mfi.,\
+ 1b_1b.bb,1b_1bb.b,1b_1bbb.,1b_1m.bb,1b_1mb.b,1b_1mbb.,\
+ 1b_1m.ib,1b_1mi.b,1b_1mib.,\
+ 1b_1m.mb,1b_1mm.b,1b_1mmb.,1b_1m.fb,1b_1mf.b,1b_1mfb.,1b_1m.lx,1b_1mlx."
+ "1b_stop")
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(final_presence_set "1b_um1" "1b_um0")
+(final_presence_set "1b_ui1" "1b_ui0, 1b_1mii., 1b_1mmi., 1b_1mfi.")
+
+;; Insns
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(define_reservation "1b_M"
+ "1b_0m.ii+1_1+1b_um0|1b_0m.mi+1_1+1b_um0|1b_0mm.i+1_2+(1b_um0|1b_um1)\
+ |1b_0m.fi+1_1+1b_um0|1b_0m.mf+1_1+1b_um0|1b_0mm.f+1_2+1b_um1\
+ |1b_0m.bb+1_1+1b_um0|1b_0m.ib+1_1+1b_um0|1b_0m.mb+1_1+1b_um0\
+ |1b_0mm.b+1_2+1b_um1|1b_0m.fb+1_1+1b_um0|1b_0m.lx+1_1+1b_um0\
+ |1b_1mm.i+1_5+1b_um1|1b_1mm.b+1_5+1b_um1\
+ |(1b_1m.ii+1_4|1b_1m.mi+1_4|1b_1m.fi+1_4|1b_1m.bb+1_4|1b_1m.ib+1_4\
+ |1b_1m.mb+1_4|1b_1m.fb+1_4|1b_1m.lx+1_4)\
+ +(1b_um0|1b_um1)")
+
+;; Exceptions for dispersal rules.
+;; "An I slot in the 3rd position of 2nd bundle is always dispersed to I1".
+(define_reservation "1b_I"
+ "1b_0mi.i+1_2+1b_ui0|1b_0mii.+1_3+(1b_ui0|1b_ui1)|1b_0mmi.+1_3+1b_ui0\
+ |1b_0mfi.+1_3+1b_ui0|1b_0mi.b+1_2+1b_ui0\
+ |(1b_1mi.i+1_5|1b_1mi.b+1_5)+(1b_ui0|1b_ui1)\
+ |1b_1mii.+1_6+1b_ui1|1b_1mmi.+1_6+1b_ui1|1b_1mfi.+1_6+1b_ui1")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "1b_F"
+ "1b_0mf.i+1_2+1b_uf0|1b_0mmf.+1_3+1b_uf0|1b_0mf.b+1_2+1b_uf0\
+ |1b_1mf.i+1_5+1b_uf1|1b_1mf.b+1_5+1b_uf1")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "1b_NB"
+ "1b_0b.bb+1_1+1b_unb0|1b_0bb.b+1_2+1b_unb1|1b_0bbb.+1_3+1b_unb2\
+ |1b_0mb.b+1_2+1b_unb1|1b_0mbb.+1_3+1b_unb2\
+ |1b_0mib.+1_3+1b_unb0|1b_0mmb.+1_3+1b_unb0|1b_0mfb.+1_3+1b_unb0\
+ |1b_1b.bb+1_4+1b_unb0|1b_1bb.b+1_5+1b_unb1\
+ |1b_1bbb.+1_6+1b_unb2|1b_1mb.b+1_5+1b_unb1|1b_1mbb.+1_6+1b_unb2\
+ |1b_1mib.+1_6+1b_unb0|1b_1mmb.+1_6+1b_unb0|1b_1mfb.+1_6+1b_unb0")
+
+(define_reservation "1b_B"
+ "1b_0b.bb+1_1+1b_ub0|1b_0bb.b+1_2+1b_ub1|1b_0bbb.+1_3+1b_ub2\
+ |1b_0mb.b+1_2+1b_ub1|1b_0mbb.+1_3+1b_ub2|1b_0mib.+1_3+1b_ub2\
+ |1b_0mfb.+1_3+1b_ub2|1b_1b.bb+1_4+1b_ub0|1b_1bb.b+1_5+1b_ub1\
+ |1b_1bbb.+1_6+1b_ub2|1b_1mb.b+1_5+1b_ub1\
+ |1b_1mib.+1_6+1b_ub2|1b_1mmb.+1_6+1b_ub2|1b_1mfb.+1_6+1b_ub2")
+
+(define_reservation "1b_L" "1b_0mlx.+1_3+1b_ui0+1b_uf0\
+ |1b_1mlx.+1_6+(1b_ui0|1b_ui1)+1b_uf1")
+
+;; We assume that there is no insn issued on the same cycle as unknown insn.
+(define_cpu_unit "1b_empty" "oneb")
+(exclusion_set "1b_empty"
+ "1b_0m.ii,1b_0m.mi,1b_0m.fi,1b_0m.mf,1b_0b.bb,1b_0m.bb,\
+ 1b_0m.ib,1b_0m.mb,1b_0m.fb,1b_0m.lx")
+
+(define_cpu_unit
+ "1b_0m_bs, 1b_0mi_bs, 1b_0mm_bs, 1b_0mf_bs, 1b_0b_bs, 1b_0bb_bs, 1b_0mb_bs"
+ "oneb")
+(define_cpu_unit
+ "1b_1m_bs, 1b_1mi_bs, 1b_1mm_bs, 1b_1mf_bs, 1b_1b_bs, 1b_1bb_bs, 1b_1mb_bs"
+ "oneb")
+
+(define_cpu_unit "1b_m_cont, 1b_mi_cont, 1b_mm_cont, 1b_mf_cont, 1b_mb_cont,\
+ 1b_b_cont, 1b_bb_cont" "oneb")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "1b_m_stop, 1b_m0_stop, 1b_m1_stop, 1b_0mmi_cont" "oneb")
+(define_cpu_unit "1b_mi_stop, 1b_mi0_stop, 1b_mi1_stop, 1b_0mii_cont" "oneb")
+
+(final_presence_set "1b_0m_bs"
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.mf, 1b_0m.fi, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.fb, 1b_0m.mb, 1b_0m.lx")
+(final_presence_set "1b_1m_bs"
+ "1b_1m.ii, 1b_1m.mi, 1b_1m.fi, 1b_1m.bb, 1b_1m.ib, 1b_1m.fb, 1b_1m.mb,\
+ 1b_1m.lx")
+(final_presence_set "1b_0mi_bs" "1b_0mi.i, 1b_0mi.i")
+(final_presence_set "1b_1mi_bs" "1b_1mi.i, 1b_1mi.i")
+(final_presence_set "1b_0mm_bs" "1b_0mm.i, 1b_0mm.f, 1b_0mm.b")
+(final_presence_set "1b_1mm_bs" "1b_1mm.i, 1b_1mm.b")
+(final_presence_set "1b_0mf_bs" "1b_0mf.i, 1b_0mf.b")
+(final_presence_set "1b_1mf_bs" "1b_1mf.i, 1b_1mf.b")
+(final_presence_set "1b_0b_bs" "1b_0b.bb")
+(final_presence_set "1b_1b_bs" "1b_1b.bb")
+(final_presence_set "1b_0bb_bs" "1b_0bb.b")
+(final_presence_set "1b_1bb_bs" "1b_1bb.b")
+(final_presence_set "1b_0mb_bs" "1b_0mb.b")
+(final_presence_set "1b_1mb_bs" "1b_1mb.b")
+
+(exclusion_set "1b_0m_bs"
+ "1b_0mi.i, 1b_0mm.i, 1b_0mm.f, 1b_0mf.i, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mf.b, 1b_0mm.b, 1b_0mlx., 1b_m0_stop")
+(exclusion_set "1b_1m_bs"
+ "1b_1mi.i, 1b_1mm.i, 1b_1mf.i, 1b_1mb.b, 1b_1mi.b, 1b_1mf.b, 1b_1mm.b,\
+ 1b_1mlx., 1b_m1_stop")
+(exclusion_set "1b_0mi_bs" "1b_0mii., 1b_0mib., 1b_mi0_stop")
+(exclusion_set "1b_1mi_bs" "1b_1mii., 1b_1mib., 1b_mi1_stop")
+(exclusion_set "1b_0mm_bs" "1b_0mmi., 1b_0mmf., 1b_0mmb.")
+(exclusion_set "1b_1mm_bs" "1b_1mmi., 1b_1mmb.")
+(exclusion_set "1b_0mf_bs" "1b_0mfi., 1b_0mfb.")
+(exclusion_set "1b_1mf_bs" "1b_1mfi., 1b_1mfb.")
+(exclusion_set "1b_0b_bs" "1b_0bb.b")
+(exclusion_set "1b_1b_bs" "1b_1bb.b")
+(exclusion_set "1b_0bb_bs" "1b_0bbb.")
+(exclusion_set "1b_1bb_bs" "1b_1bbb.")
+(exclusion_set "1b_0mb_bs" "1b_0mbb.")
+(exclusion_set "1b_1mb_bs" "1b_1mbb.")
+
+(exclusion_set
+ "1b_0m_bs, 1b_0mi_bs, 1b_0mm_bs, 1b_0mf_bs, 1b_0b_bs, 1b_0bb_bs, 1b_0mb_bs,
+ 1b_1m_bs, 1b_1mi_bs, 1b_1mm_bs, 1b_1mf_bs, 1b_1b_bs, 1b_1bb_bs, 1b_1mb_bs"
+ "1b_stop")
+
+(final_presence_set
+ "1b_0mi.i, 1b_0mm.i, 1b_0mf.i, 1b_0mm.f, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx."
+ "1b_m_cont")
+(final_presence_set "1b_0mii., 1b_0mib." "1b_mi_cont")
+(final_presence_set "1b_0mmi., 1b_0mmf., 1b_0mmb." "1b_mm_cont")
+(final_presence_set "1b_0mfi., 1b_0mfb." "1b_mf_cont")
+(final_presence_set "1b_0bb.b" "1b_b_cont")
+(final_presence_set "1b_0bbb." "1b_bb_cont")
+(final_presence_set "1b_0mbb." "1b_mb_cont")
+
+(exclusion_set
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx"
+ "1b_m_cont, 1b_mi_cont, 1b_mm_cont, 1b_mf_cont,\
+ 1b_mb_cont, 1b_b_cont, 1b_bb_cont")
+
+(exclusion_set "1b_empty"
+ "1b_m_cont,1b_mi_cont,1b_mm_cont,1b_mf_cont,\
+ 1b_mb_cont,1b_b_cont,1b_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "1b_m0_stop" "1b_0m.mi")
+(final_presence_set "1b_0mm.i" "1b_0mmi_cont")
+(exclusion_set "1b_0mmi_cont"
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_m0_stop" "1b_0mm.i")
+(final_presence_set "1b_m1_stop" "1b_1m.mi")
+(exclusion_set "1b_m1_stop" "1b_1mm.i")
+(final_presence_set "1b_m_stop" "1b_m0_stop, 1b_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "1b_mi0_stop" "1b_0mi.i")
+(final_presence_set "1b_0mii." "1b_0mii_cont")
+(exclusion_set "1b_0mii_cont"
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_mi0_stop" "1b_0mii.")
+(final_presence_set "1b_mi1_stop" "1b_1mi.i")
+(exclusion_set "1b_mi1_stop" "1b_1mii.")
+(final_presence_set "1b_mi_stop" "1b_mi0_stop, 1b_mi1_stop")
+
+(final_absence_set
+ "1b_0m.ii,1b_0mi.i,1b_0mii.,1b_0m.mi,1b_0mm.i,1b_0mmi.,\
+ 1b_0m.fi,1b_0mf.i,1b_0mfi.,1b_0m.mf,1b_0mm.f,1b_0mmf.,\
+ 1b_0b.bb,1b_0bb.b,1b_0bbb.,1b_0m.bb,1b_0mb.b,1b_0mbb.,\
+ 1b_0m.ib,1b_0mi.b,1b_0mib.,1b_0m.mb,1b_0mm.b,1b_0mmb.,\
+ 1b_0m.fb,1b_0mf.b,1b_0mfb.,1b_0m.lx,1b_0mlx., \
+ 1b_1m.ii,1b_1mi.i,1b_1mii.,1b_1m.mi,1b_1mm.i,1b_1mmi.,\
+ 1b_1m.fi,1b_1mf.i,1b_1mfi.,\
+ 1b_1b.bb,1b_1bb.b,1b_1bbb.,1b_1m.bb,1b_1mb.b,1b_1mbb.,\
+ 1b_1m.ib,1b_1mi.b,1b_1mib.,1b_1m.mb,1b_1mm.b,1b_1mmb.,\
+ 1b_1m.fb,1b_1mf.b,1b_1mfb.,1b_1m.lx,1b_1mlx."
+ "1b_m0_stop,1b_m1_stop,1b_mi0_stop,1b_mi1_stop")
+
+(define_reservation "1b_A" "1b_M|1b_I")
+
+(define_insn_reservation "1b_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stop_bit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_stop|1b_m0_stop|1b_m1_stop|1b_mi0_stop|1b_mi1_stop")
+(define_insn_reservation "1b_br" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "br"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_B")
+(define_insn_reservation "1b_scall" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "scall"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_B")
+(define_insn_reservation "1b_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_F+1b_not_uf1")
+(define_insn_reservation "1b_fcvtfx" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_fld" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fld"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_fmac" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmac"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_fmisc" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmisc"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_F+1b_not_uf1")
+(define_insn_reservation "1b_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_frbr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frbr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_frfr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frfr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_frpr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frpr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_ialu" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (ne (symbol_ref
+ "bundling_p && !ia64_produce_address_p (insn)")
+ (const_int 0)))
+ "1b_A")
+(define_insn_reservation "1b_ialu_addr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref
+ "bundling_p && ia64_produce_address_p (insn)")
+ (const_int 1)))
+ "1b_M")
+(define_insn_reservation "1b_icmp" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "icmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_A")
+(define_insn_reservation "1b_ilog" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ilog"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_A")
+(define_insn_reservation "1b_ishf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ishf"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_ld" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ld"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_long_i" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "long_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_L")
+(define_insn_reservation "1b_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmmul"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshf"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_mmshfi" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshfi"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "rse_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(1b_0m.ii|1b_0m.mi|1b_0m.fi|1b_0m.mf|1b_0b.bb|1b_0m.bb\
+ |1b_0m.ib|1b_0m.mb|1b_0m.fb|1b_0m.lx)+1_1+1b_um0")
+(define_insn_reservation "1b_sem" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "sem"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_stf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stf"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_st" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "st"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m0"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_tbit" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tbit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_tobr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tobr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_tofr" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tofr"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_topr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "topr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_xmpy" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xmpy"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_xtd" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xtd"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "chk_s"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_A")
+(define_insn_reservation "1b_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "lfetch"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_b"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_NB")
+(define_insn_reservation "1b_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_f"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_x"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_L")
+(define_insn_reservation "1b_unknown" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "unknown"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_empty")
+(define_insn_reservation "1b_nop" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M|1b_NB|1b_I|1b_F")
+(define_insn_reservation "1b_ignore" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ignore"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "nothing")
+
+(define_insn_reservation "1b_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(1b_0m_bs, 1b_m_cont) \
+ | (1b_0mi_bs, 1b_mi_cont) \
+ | (1b_0mm_bs, 1b_mm_cont) \
+ | (1b_0mf_bs, 1b_mf_cont) \
+ | (1b_0b_bs, 1b_b_cont) \
+ | (1b_0bb_bs, 1b_bb_cont) \
+ | (1b_0mb_bs, 1b_mb_cont) \
+ | (1b_1m_bs, 1b_m_cont) \
+ | (1b_1mi_bs, 1b_mi_cont) \
+ | (1b_1mm_bs, 1b_mm_cont) \
+ | (1b_1mf_bs, 1b_mf_cont) \
+ | (1b_1b_bs, 1b_b_cont) \
+ | (1b_1bb_bs, 1b_bb_cont) \
+ | (1b_1mb_bs, 1b_mb_cont) \
+ | (1b_m_stop, 1b_0mmi_cont) \
+ | (1b_mi_stop, 1b_0mii_cont)")
+
diff --git a/contrib/gcc/config/ia64/itanium2.md b/contrib/gcc/config/ia64/itanium2.md
new file mode 100644
index 0000000..0cdb070
--- /dev/null
+++ b/contrib/gcc/config/ia64/itanium2.md
@@ -0,0 +1,1762 @@
+;; Itanium2 DFA descriptions for insn scheduling and bundling.
+;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Contributed by Vladimir Makarov <vmakarov@redhat.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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA. */
+;;
+
+/* This is description of pipeline hazards based on DFA. The
+ following constructions can be used for this:
+
+ o define_cpu_unit string [string]) describes a cpu functional unit
+ (separated by comma).
+
+ 1st operand: Names of cpu function units.
+ 2nd operand: Name of automaton (see comments for
+ DEFINE_AUTOMATON).
+
+ All define_reservations and define_cpu_units should have unique
+ names which can not be "nothing".
+
+ o (exclusion_set string string) means that each CPU function unit
+ in the first string can not be reserved simultaneously with each
+ unit whose name is in the second string and vise versa. CPU
+ units in the string are separated by commas. For example, it is
+ useful for description CPU with fully pipelined floating point
+ functional unit which can execute simultaneously only single
+ floating point insns or only double floating point insns.
+
+ o (presence_set string string) means that each CPU function unit in
+ the first string can not be reserved unless at least one of
+ pattern of units whose names are in the second string is
+ reserved. This is an asymmetric relation. CPU units or unit
+ patterns in the strings are separated by commas. Pattern is one
+ unit name or unit names separated by white-spaces.
+
+ For example, it is useful for description that slot1 is reserved
+ after slot0 reservation for a VLIW processor. We could describe
+ it by the following construction
+
+ (presence_set "slot1" "slot0")
+
+ Or slot1 is reserved only after slot0 and unit b0 reservation.
+ In this case we could write
+
+ (presence_set "slot1" "slot0 b0")
+
+ All CPU functional units in a set should belong to the same
+ automaton.
+
+ o (final_presence_set string string) is analogous to
+ `presence_set'. The difference between them is when checking is
+ done. When an instruction is issued in given automaton state
+ reflecting all current and planned unit reservations, the
+ automaton state is changed. The first state is a source state,
+ the second one is a result state. Checking for `presence_set' is
+ done on the source state reservation, checking for
+ `final_presence_set' is done on the result reservation. This
+ construction is useful to describe a reservation which is
+ actually two subsequent reservations. For example, if we use
+
+ (presence_set "slot1" "slot0")
+
+ the following insn will be never issued (because slot1 requires
+ slot0 which is absent in the source state).
+
+ (define_reservation "insn_and_nop" "slot0 + slot1")
+
+ but it can be issued if we use analogous `final_presence_set'.
+
+ o (absence_set string string) means that each CPU function unit in
+ the first string can be reserved only if each pattern of units
+ whose names are in the second string is not reserved. This is an
+ asymmetric relation (actually exclusion set is analogous to this
+ one but it is symmetric). CPU units or unit patterns in the
+ string are separated by commas. Pattern is one unit name or unit
+ names separated by white-spaces.
+
+ For example, it is useful for description that slot0 can not be
+ reserved after slot1 or slot2 reservation for a VLIW processor.
+ We could describe it by the following construction
+
+ (absence_set "slot2" "slot0, slot1")
+
+ Or slot2 can not be reserved if slot0 and unit b0 are reserved or
+ slot1 and unit b1 are reserved . In this case we could write
+
+ (absence_set "slot2" "slot0 b0, slot1 b1")
+
+ All CPU functional units in a set should to belong the same
+ automaton.
+
+ o (final_absence_set string string) is analogous to `absence_set' but
+ checking is done on the result (state) reservation. See comments
+ for final_presence_set.
+
+ o (define_bypass number out_insn_names in_insn_names) names bypass with
+ given latency (the first number) from insns given by the first
+ string (see define_insn_reservation) into insns given by the
+ second string. Insn names in the strings are separated by
+ commas.
+
+ o (define_automaton string) describes names of an automaton
+ generated and used for pipeline hazards recognition. The names
+ are separated by comma. Actually it is possibly to generate the
+ single automaton but unfortunately it can be very large. If we
+ use more one automata, the summary size of the automata usually
+ is less than the single one. The automaton name is used in
+ define_cpu_unit. All automata should have unique names.
+
+ o (automata_option string) describes option for generation of
+ automata. Currently there are the following options:
+
+ o "no-minimization" which makes no minimization of automata.
+ This is only worth to do when we are debugging the description
+ and need to look more accurately at reservations of states.
+
+ o "ndfa" which makes automata with nondetermenistic reservation
+ by insns.
+
+ o (define_reservation string string) names reservation (the first
+ string) of cpu functional units (the 2nd string). Sometimes unit
+ reservations for different insns contain common parts. In such
+ case, you describe common part and use one its name (the 1st
+ parameter) in regular expression in define_insn_reservation. All
+ define_reservations, define results and define_cpu_units should
+ have unique names which can not be "nothing".
+
+ o (define_insn_reservation name default_latency condition regexpr)
+ describes reservation of cpu functional units (the 3nd operand)
+ for instruction which is selected by the condition (the 2nd
+ parameter). The first parameter is used for output of debugging
+ information. The reservations are described by a regular
+ expression according the following syntax:
+
+ regexp = regexp "," oneof
+ | oneof
+
+ oneof = oneof "|" allof
+ | allof
+
+ allof = allof "+" repeat
+ | repeat
+
+ repeat = element "*" number
+ | element
+
+ element = cpu_function_name
+ | reservation_name
+ | result_name
+ | "nothing"
+ | "(" regexp ")"
+
+ 1. "," is used for describing start of the next cycle in
+ reservation.
+
+ 2. "|" is used for describing the reservation described by the
+ first regular expression *or* the reservation described by
+ the second regular expression *or* etc.
+
+ 3. "+" is used for describing the reservation described by the
+ first regular expression *and* the reservation described by
+ the second regular expression *and* etc.
+
+ 4. "*" is used for convenience and simply means sequence in
+ which the regular expression are repeated NUMBER times with
+ cycle advancing (see ",").
+
+ 5. cpu function unit name which means reservation.
+
+ 6. reservation name -- see define_reservation.
+
+ 7. string "nothing" means no units reservation.
+
+*/
+
+(define_automaton "two")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx" "two")
+(define_cpu_unit "2_0mi.i, 2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0bb.b, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx." "two")
+(define_cpu_unit "2_0mii., 2_0mmi., 2_0mfi., 2_0mmf., 2_0bbb., 2_0mbb.,\
+ 2_0mib., 2_0mmb., 2_0mfb." "two")
+
+(define_cpu_unit "2_1m.ii, 2_1m.mi, 2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb,\
+ 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx" "two")
+(define_cpu_unit "2_1mi.i, 2_1mm.i, 2_1mf.i, 2_1mm.f, 2_1bb.b, 2_1mb.b,\
+ 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx." "two")
+(define_cpu_unit "2_1mii., 2_1mmi., 2_1mfi., 2_1mmf., 2_1bbb., 2_1mbb.,\
+ 2_1mib., 2_1mmb., 2_1mfb." "two")
+
+;; Slot 1
+(exclusion_set "2_0m.ii" "2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.mi" "2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb, 2_0m.ib,\
+ 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.fi" "2_0m.mf, 2_0b.bb, 2_0m.bb, 2_0m.ib, 2_0m.mb,\
+ 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.mf" "2_0b.bb, 2_0m.bb, 2_0m.ib, 2_0m.mb, 2_0m.fb,\
+ 2_0m.lx")
+(exclusion_set "2_0b.bb" "2_0m.bb, 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.bb" "2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.ib" "2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.mb" "2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.fb" "2_0m.lx")
+
+;; Slot 2
+(exclusion_set "2_0mi.i" "2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0bb.b, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mm.i" "2_0mf.i, 2_0mm.f, 2_0bb.b, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mf.i" "2_0mm.f, 2_0bb.b, 2_0mb.b, 2_0mi.b, 2_0mm.b,\
+ 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mm.f" "2_0bb.b, 2_0mb.b, 2_0mi.b, 2_0mm.b, 2_0mf.b,\
+ 2_0mlx.")
+(exclusion_set "2_0bb.b" "2_0mb.b, 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mb.b" "2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mi.b" "2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mm.b" "2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mf.b" "2_0mlx.")
+
+;; Slot 3
+(exclusion_set "2_0mii." "2_0mmi., 2_0mfi., 2_0mmf., 2_0bbb., 2_0mbb.,\
+ 2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mmi." "2_0mfi., 2_0mmf., 2_0bbb., 2_0mbb.,\
+ 2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mfi." "2_0mmf., 2_0bbb., 2_0mbb., 2_0mib., 2_0mmb.,\
+ 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mmf." "2_0bbb., 2_0mbb., 2_0mib., 2_0mmb., 2_0mfb.,\
+ 2_0mlx.")
+(exclusion_set "2_0bbb." "2_0mbb., 2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mbb." "2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mib." "2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mmb." "2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mfb." "2_0mlx.")
+
+;; Slot 4
+(exclusion_set "2_1m.ii" "2_1m.mi, 2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb,\
+ 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.mi" "2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb, 2_1m.ib,\
+ 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.fi" "2_1m.mf, 2_1b.bb, 2_1m.bb, 2_1m.ib, 2_1m.mb,\
+ 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.mf" "2_1b.bb, 2_1m.bb, 2_1m.ib, 2_1m.mb, 2_1m.fb,\
+ 2_1m.lx")
+(exclusion_set "2_1b.bb" "2_1m.bb, 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.bb" "2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.ib" "2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.mb" "2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.fb" "2_1m.lx")
+
+;; Slot 5
+(exclusion_set "2_1mi.i" "2_1mm.i, 2_1mf.i, 2_1mm.f, 2_1bb.b, 2_1mb.b,\
+ 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mm.i" "2_1mf.i, 2_1mm.f, 2_1bb.b, 2_1mb.b,\
+ 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mf.i" "2_1mm.f, 2_1bb.b, 2_1mb.b, 2_1mi.b, 2_1mm.b,\
+ 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mm.f" "2_1bb.b, 2_1mb.b, 2_1mi.b, 2_1mm.b, 2_1mf.b,\
+ 2_1mlx.")
+(exclusion_set "2_1bb.b" "2_1mb.b, 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mb.b" "2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mi.b" "2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mm.b" "2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mf.b" "2_1mlx.")
+
+;; Slot 6
+(exclusion_set "2_1mii." "2_1mmi., 2_1mfi., 2_1mmf., 2_1bbb., 2_1mbb.,\
+ 2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mmi." "2_1mfi., 2_1mmf., 2_1bbb., 2_1mbb.,\
+ 2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mfi." "2_1mmf., 2_1bbb., 2_1mbb., 2_1mib., 2_1mmb.,\
+ 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mmf." "2_1bbb., 2_1mbb., 2_1mib., 2_1mmb., 2_1mfb.,\
+ 2_1mlx.")
+(exclusion_set "2_1bbb." "2_1mbb., 2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mbb." "2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mib." "2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mmb." "2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mfb." "2_1mlx.")
+
+(final_presence_set "2_0mi.i" "2_0m.ii")
+(final_presence_set "2_0mii." "2_0mi.i")
+(final_presence_set "2_1mi.i" "2_1m.ii")
+(final_presence_set "2_1mii." "2_1mi.i")
+
+(final_presence_set "2_0mm.i" "2_0m.mi")
+(final_presence_set "2_0mmi." "2_0mm.i")
+(final_presence_set "2_1mm.i" "2_1m.mi")
+(final_presence_set "2_1mmi." "2_1mm.i")
+
+(final_presence_set "2_0mf.i" "2_0m.fi")
+(final_presence_set "2_0mfi." "2_0mf.i")
+(final_presence_set "2_1mf.i" "2_1m.fi")
+(final_presence_set "2_1mfi." "2_1mf.i")
+
+(final_presence_set "2_0mm.f" "2_0m.mf")
+(final_presence_set "2_0mmf." "2_0mm.f")
+(final_presence_set "2_1mm.f" "2_1m.mf")
+(final_presence_set "2_1mmf." "2_1mm.f")
+
+(final_presence_set "2_0bb.b" "2_0b.bb")
+(final_presence_set "2_0bbb." "2_0bb.b")
+(final_presence_set "2_1bb.b" "2_1b.bb")
+(final_presence_set "2_1bbb." "2_1bb.b")
+
+(final_presence_set "2_0mb.b" "2_0m.bb")
+(final_presence_set "2_0mbb." "2_0mb.b")
+(final_presence_set "2_1mb.b" "2_1m.bb")
+(final_presence_set "2_1mbb." "2_1mb.b")
+
+(final_presence_set "2_0mi.b" "2_0m.ib")
+(final_presence_set "2_0mib." "2_0mi.b")
+(final_presence_set "2_1mi.b" "2_1m.ib")
+(final_presence_set "2_1mib." "2_1mi.b")
+
+(final_presence_set "2_0mm.b" "2_0m.mb")
+(final_presence_set "2_0mmb." "2_0mm.b")
+(final_presence_set "2_1mm.b" "2_1m.mb")
+(final_presence_set "2_1mmb." "2_1mm.b")
+
+(final_presence_set "2_0mf.b" "2_0m.fb")
+(final_presence_set "2_0mfb." "2_0mf.b")
+(final_presence_set "2_1mf.b" "2_1m.fb")
+(final_presence_set "2_1mfb." "2_1mf.b")
+
+(final_presence_set "2_0mlx." "2_0m.lx")
+(final_presence_set "2_1mlx." "2_1m.lx")
+
+;; The following reflects the dual issue bundle types table.
+;; We could place all possible combinations here because impossible
+;; combinations would go away by the subsequent constrains.
+(final_presence_set
+ "2_1m.lx"
+ "2_0mmi.,2_0mfi.,2_0mmf.,2_0mib.,2_0mmb.,2_0mfb.,2_0mlx.")
+(final_presence_set "2_1b.bb" "2_0mii.,2_0mmi.,2_0mfi.,2_0mmf.,2_0mlx.")
+(final_presence_set
+ "2_1m.ii,2_1m.mi,2_1m.fi,2_1m.mf,2_1m.bb,2_1m.ib,2_1m.mb,2_1m.fb"
+ "2_0mii.,2_0mmi.,2_0mfi.,2_0mmf.,2_0mib.,2_0mmb.,2_0mfb.,2_0mlx.")
+
+;; Ports/units (nb means nop.b insn issued into given port):
+(define_cpu_unit
+ "2_um0, 2_um1, 2_um2, 2_um3, 2_ui0, 2_ui1, 2_uf0, 2_uf1,\
+ 2_ub0, 2_ub1, 2_ub2, 2_unb0, 2_unb1, 2_unb2" "two")
+
+(exclusion_set "2_ub0" "2_unb0")
+(exclusion_set "2_ub1" "2_unb1")
+(exclusion_set "2_ub2" "2_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium2 microarchitecture. They also
+;; describe the following rules mentioned in Itanium2
+;; microarchitecture: rules mentioned in Itanium2 microarchitecture:
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+(exclusion_set
+ "2_0b.bb,2_0bb.b,2_0bbb.,2_0m.bb,2_0mb.b,2_0mbb."
+ "2_1m.ii,2_1m.mi,2_1m.fi,2_1m.mf,2_1b.bb,2_1m.bb,\
+ 2_1m.ib,2_1m.mb,2_1m.fb,2_1m.lx")
+(exclusion_set "2_0m.ib,2_0mi.b,2_0mib." "2_1b.bb")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "2_1m.ii, 2_1m.mi, 2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb,\
+ 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx"
+ "2_0mib. 2_ub2, 2_0mfb. 2_ub2, 2_0mmb. 2_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "2_stop" "two")
+(final_absence_set
+ "2_0m.ii,2_0mi.i,2_0mii.,2_0m.mi,2_0mm.i,2_0mmi.,2_0m.fi,2_0mf.i,2_0mfi.,\
+ 2_0m.mf,2_0mm.f,2_0mmf.,2_0b.bb,2_0bb.b,2_0bbb.,2_0m.bb,2_0mb.b,2_0mbb.,\
+ 2_0m.ib,2_0mi.b,2_0mib.,2_0m.mb,2_0mm.b,2_0mmb.,2_0m.fb,2_0mf.b,2_0mfb.,\
+ 2_0m.lx,2_0mlx., \
+ 2_1m.ii,2_1mi.i,2_1mii.,2_1m.mi,2_1mm.i,2_1mmi.,2_1m.fi,2_1mf.i,2_1mfi.,\
+ 2_1m.mf,2_1mm.f,2_1mmf.,2_1b.bb,2_1bb.b,2_1bbb.,2_1m.bb,2_1mb.b,2_1mbb.,\
+ 2_1m.ib,2_1mi.b,2_1mib.,2_1m.mb,2_1mm.b,2_1mmb.,2_1m.fb,2_1mf.b,2_1mfb.,\
+ 2_1m.lx,2_1mlx."
+ "2_stop")
+
+;; The issue logic can reorder M slot insns between different subtypes
+;; but can not reorder insn within the same subtypes. The following
+;; constraint is enough to describe this.
+(final_presence_set "2_um1" "2_um0")
+(final_presence_set "2_um3" "2_um2")
+
+;; The insn in the 1st I slot of the two bundle issue group will issue
+;; to I0. The second I slot insn will issue to I1.
+(final_presence_set "2_ui1" "2_ui0")
+
+;; For exceptions of I insns:
+(define_cpu_unit "2_only_ui0" "two")
+(final_absence_set "2_only_ui0" "2_ui1")
+
+;; Insns
+
+(define_reservation "2_M0"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +(2_um0|2_um1|2_um2|2_um3)")
+
+(define_reservation "2_M1"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +(2_um0|2_um1|2_um2|2_um3)")
+
+(define_reservation "2_M" "2_M0|2_M1")
+
+(define_reservation "2_M0_only_um0"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +2_um0")
+
+(define_reservation "2_M1_only_um0"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +2_um0")
+
+(define_reservation "2_M_only_um0" "2_M0_only_um0|2_M1_only_um0")
+
+(define_reservation "2_M0_only_um2"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +2_um2")
+
+(define_reservation "2_M1_only_um2"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +2_um2")
+
+(define_reservation "2_M_only_um2" "2_M0_only_um2|2_M1_only_um2")
+
+(define_reservation "2_M0_only_um23"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +(2_um2|2_um3)")
+
+(define_reservation "2_M1_only_um23"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +(2_um2|2_um3)")
+
+(define_reservation "2_M_only_um23" "2_M0_only_um23|2_M1_only_um23")
+
+(define_reservation "2_M0_only_um01"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +(2_um0|2_um1)")
+
+(define_reservation "2_M1_only_um01"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +(2_um0|2_um1)")
+
+(define_reservation "2_M_only_um01" "2_M0_only_um01|2_M1_only_um01")
+
+;; I instruction is dispersed to the lowest numbered I unit
+;; not already in use. Remeber about possible splitting.
+(define_reservation "2_I0"
+ "2_0mi.i+2_ui0|2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0\
+ |2_0mfi.+2_ui0|2_0mi.b+2_ui0|(2_1mi.i|2_1mi.b)+(2_ui0|2_ui1)\
+ |(2_1mii.|2_1mmi.|2_1mfi.)+(2_ui0|2_ui1)")
+
+(define_reservation "2_I1"
+ "2_0m.ii+(2_um0|2_um1|2_um2|2_um3)+2_0mi.i+2_ui0\
+ |2_0mm.i+(2_um0|2_um1|2_um2|2_um3)+2_0mmi.+2_ui0\
+ |2_0mf.i+2_uf0+2_0mfi.+2_ui0\
+ |2_0m.ib+(2_um0|2_um1|2_um2|2_um3)+2_0mi.b+2_ui0\
+ |(2_1m.ii+2_1mi.i|2_1m.ib+2_1mi.b)+(2_um0|2_um1|2_um2|2_um3)+(2_ui0|2_ui1)\
+ |2_1mm.i+(2_um0|2_um1|2_um2|2_um3)+2_1mmi.+(2_ui0|2_ui1)\
+ |2_1mf.i+2_uf1+2_1mfi.+(2_ui0|2_ui1)")
+
+(define_reservation "2_I" "2_I0|2_I1")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "2_F0"
+ "2_0mf.i+2_uf0|2_0mmf.+2_uf0|2_0mf.b+2_uf0\
+ |2_1mf.i+2_uf1|2_1mmf.+2_uf1|2_1mf.b+2_uf1")
+
+(define_reservation "2_F1"
+ "(2_0m.fi+2_0mf.i|2_0mm.f+2_0mmf.|2_0m.fb+2_0mf.b)\
+ +(2_um0|2_um1|2_um2|2_um3)+2_uf0\
+ |(2_1m.fi+2_1mf.i|2_1mm.f+2_1mmf.|2_1m.fb+2_1mf.b)\
+ +(2_um0|2_um1|2_um2|2_um3)+2_uf1")
+
+(define_reservation "2_F2"
+ "(2_0m.mf+2_0mm.f+2_0mmf.+2_uf0|2_1m.mf+2_1mm.f+2_1mmf.+2_uf1)\
+ +(2_um0|2_um1|2_um2|2_um3)+(2_um0|2_um1|2_um2|2_um3)\
+ |(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0\
+ |2_0mmf.+(2_um0|2_um1|2_um2|2_um3)\
+ |2_0mib.+2_unb0|2_0mmb.+2_unb0|2_0mfb.+2_unb0)\
+ +(2_1m.fi+2_1mf.i|2_1m.fb+2_1mf.b)+(2_um0|2_um1|2_um2|2_um3)+2_uf1")
+
+(define_reservation "2_F" "2_F0|2_F1|2_F2")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "2_NB"
+ "2_0b.bb+2_unb0|2_0bb.b+2_unb1|2_0bbb.+2_unb2\
+ |2_0mb.b+2_unb1|2_0mbb.+2_unb2|2_0mib.+2_unb0\
+ |2_0mmb.+2_unb0|2_0mfb.+2_unb0\
+ |2_1b.bb+2_unb0|2_1bb.b+2_unb1
+ |2_1bbb.+2_unb2|2_1mb.b+2_unb1|2_1mbb.+2_unb2\
+ |2_1mib.+2_unb0|2_1mmb.+2_unb0|2_1mfb.+2_unb0")
+
+(define_reservation "2_B0"
+ "2_0b.bb+2_ub0|2_0bb.b+2_ub1|2_0bbb.+2_ub2\
+ |2_0mb.b+2_ub1|2_0mbb.+2_ub2|2_0mib.+2_ub2\
+ |2_0mfb.+2_ub2|2_1b.bb+2_ub0|2_1bb.b+2_ub1\
+ |2_1bbb.+2_ub2|2_1mb.b+2_ub1\
+ |2_1mib.+2_ub2|2_1mmb.+2_ub2|2_1mfb.+2_ub2")
+
+(define_reservation "2_B1"
+ "2_0m.bb+(2_um0|2_um1|2_um2|2_um3)+2_0mb.b+2_ub1\
+ |2_0mi.b+2_ui0+2_0mib.+2_ub2\
+ |2_0mm.b+(2_um0|2_um1|2_um2|2_um3)+2_0mmb.+2_ub2\
+ |2_0mf.b+2_uf0+2_0mfb.+2_ub2\
+ |(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0)\
+ +2_1b.bb+2_ub0\
+ |2_1m.bb+(2_um0|2_um1|2_um2|2_um3)+2_1mb.b+2_ub1\
+ |2_1mi.b+(2_ui0|2_ui1)+2_1mib.+2_ub2\
+ |2_1mm.b+(2_um0|2_um1|2_um2|2_um3)+2_1mmb.+2_ub2\
+ |2_1mf.b+2_uf1+2_1mfb.+2_ub2")
+
+(define_reservation "2_B" "2_B0|2_B1")
+
+;; MLX bunlde uses ports equivalent to MFI bundles.
+
+;; For the MLI template, the I slot insn is always assigned to port I0
+;; if it is in the first bundle or it is assigned to port I1 if it is in
+;; the second bundle.
+(define_reservation "2_L0" "2_0mlx.+2_ui0+2_uf0|2_1mlx.+2_ui1+2_uf1")
+
+(define_reservation "2_L1"
+ "2_0m.lx+(2_um0|2_um1|2_um2|2_um3)+2_0mlx.+2_ui0+2_uf0\
+ |2_1m.lx+(2_um0|2_um1|2_um2|2_um3)+2_1mlx.+2_ui1+2_uf1")
+
+(define_reservation "2_L2"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mmb.+2_unb0|2_0mfb.+2_unb0)
+ +2_1m.lx+(2_um0|2_um1|2_um2|2_um3)+2_1mlx.+2_ui1+2_uf1")
+
+(define_reservation "2_L" "2_L0|2_L1|2_L2")
+
+;; Should we describe that A insn in I slot can be issued into M
+;; ports? I think it is not necessary because of multipass
+;; scheduling. For example, the multipass scheduling could use
+;; MMI-MMI instead of MII-MII where the two last I slots contain A
+;; insns (even if the case is complicated by use-def conflicts).
+;;
+;; In any case we could describe it as
+;; (define_cpu_unit "2_ui1_0pres,2_ui1_1pres,2_ui1_2pres,2_ui1_3pres" "two")
+;; (final_presence_set "2_ui1_0pres,2_ui1_1pres,2_ui1_2pres,2_ui1_3pres"
+;; "2_ui1")
+;; (define_reservation "b_A"
+;; "b_M|b_I\
+;; |(2_1mi.i|2_1mii.|2_1mmi.|2_1mfi.|2_1mi.b)+(2_um0|2_um1|2_um2|2_um3)\
+;; +(2_ui1_0pres|2_ui1_1pres|2_ui1_2pres|2_ui1_3pres)")
+
+(define_reservation "2_A" "2_M|2_I")
+
+;; We assume that there is no insn issued on the same cycle as the
+;; unknown insn.
+(define_cpu_unit "2_empty" "two")
+(exclusion_set "2_empty"
+ "2_0m.ii,2_0m.mi,2_0m.fi,2_0m.mf,2_0b.bb,2_0m.bb,2_0m.ib,2_0m.mb,2_0m.fb,\
+ 2_0m.lx")
+
+(define_cpu_unit
+ "2_0m_bs, 2_0mi_bs, 2_0mm_bs, 2_0mf_bs, 2_0b_bs, 2_0bb_bs, 2_0mb_bs"
+ "two")
+(define_cpu_unit
+ "2_1m_bs, 2_1mi_bs, 2_1mm_bs, 2_1mf_bs, 2_1b_bs, 2_1bb_bs, 2_1mb_bs"
+ "two")
+
+(define_cpu_unit "2_m_cont, 2_mi_cont, 2_mm_cont, 2_mf_cont, 2_mb_cont,\
+ 2_b_cont, 2_bb_cont" "two")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "2_m_stop, 2_m0_stop, 2_m1_stop, 2_0mmi_cont" "two")
+(define_cpu_unit "2_mi_stop, 2_mi0_stop, 2_mi1_stop, 2_0mii_cont" "two")
+
+(final_presence_set "2_0m_bs"
+ "2_0m.ii, 2_0m.mi, 2_0m.mf, 2_0m.fi, 2_0m.bb,\
+ 2_0m.ib, 2_0m.fb, 2_0m.mb, 2_0m.lx")
+(final_presence_set "2_1m_bs"
+ "2_1m.ii, 2_1m.mi, 2_1m.mf, 2_1m.fi, 2_1m.bb,\
+ 2_1m.ib, 2_1m.fb, 2_1m.mb, 2_1m.lx")
+(final_presence_set "2_0mi_bs" "2_0mi.i, 2_0mi.i")
+(final_presence_set "2_1mi_bs" "2_1mi.i, 2_1mi.i")
+(final_presence_set "2_0mm_bs" "2_0mm.i, 2_0mm.f, 2_0mm.b")
+(final_presence_set "2_1mm_bs" "2_1mm.i, 2_1mm.f, 2_1mm.b")
+(final_presence_set "2_0mf_bs" "2_0mf.i, 2_0mf.b")
+(final_presence_set "2_1mf_bs" "2_1mf.i, 2_1mf.b")
+(final_presence_set "2_0b_bs" "2_0b.bb")
+(final_presence_set "2_1b_bs" "2_1b.bb")
+(final_presence_set "2_0bb_bs" "2_0bb.b")
+(final_presence_set "2_1bb_bs" "2_1bb.b")
+(final_presence_set "2_0mb_bs" "2_0mb.b")
+(final_presence_set "2_1mb_bs" "2_1mb.b")
+
+(exclusion_set "2_0m_bs"
+ "2_0mi.i, 2_0mm.i, 2_0mm.f, 2_0mf.i, 2_0mb.b,\
+ 2_0mi.b, 2_0mf.b, 2_0mm.b, 2_0mlx., 2_m0_stop")
+(exclusion_set "2_1m_bs"
+ "2_1mi.i, 2_1mm.i, 2_1mm.f, 2_1mf.i, 2_1mb.b,\
+ 2_1mi.b, 2_1mf.b, 2_1mm.b, 2_1mlx., 2_m1_stop")
+(exclusion_set "2_0mi_bs" "2_0mii., 2_0mib., 2_mi0_stop")
+(exclusion_set "2_1mi_bs" "2_1mii., 2_1mib., 2_mi1_stop")
+(exclusion_set "2_0mm_bs" "2_0mmi., 2_0mmf., 2_0mmb.")
+(exclusion_set "2_1mm_bs" "2_1mmi., 2_1mmf., 2_1mmb.")
+(exclusion_set "2_0mf_bs" "2_0mfi., 2_0mfb.")
+(exclusion_set "2_1mf_bs" "2_1mfi., 2_1mfb.")
+(exclusion_set "2_0b_bs" "2_0bb.b")
+(exclusion_set "2_1b_bs" "2_1bb.b")
+(exclusion_set "2_0bb_bs" "2_0bbb.")
+(exclusion_set "2_1bb_bs" "2_1bbb.")
+(exclusion_set "2_0mb_bs" "2_0mbb.")
+(exclusion_set "2_1mb_bs" "2_1mbb.")
+
+(exclusion_set
+ "2_0m_bs, 2_0mi_bs, 2_0mm_bs, 2_0mf_bs, 2_0b_bs, 2_0bb_bs, 2_0mb_bs,
+ 2_1m_bs, 2_1mi_bs, 2_1mm_bs, 2_1mf_bs, 2_1b_bs, 2_1bb_bs, 2_1mb_bs"
+ "2_stop")
+
+(final_presence_set
+ "2_0mi.i, 2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx."
+ "2_m_cont")
+(final_presence_set "2_0mii., 2_0mib." "2_mi_cont")
+(final_presence_set "2_0mmi., 2_0mmf., 2_0mmb." "2_mm_cont")
+(final_presence_set "2_0mfi., 2_0mfb." "2_mf_cont")
+(final_presence_set "2_0bb.b" "2_b_cont")
+(final_presence_set "2_0bbb." "2_bb_cont")
+(final_presence_set "2_0mbb." "2_mb_cont")
+
+(exclusion_set
+ "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx"
+ "2_m_cont, 2_mi_cont, 2_mm_cont, 2_mf_cont,\
+ 2_mb_cont, 2_b_cont, 2_bb_cont")
+
+(exclusion_set "2_empty"
+ "2_m_cont,2_mi_cont,2_mm_cont,2_mf_cont,\
+ 2_mb_cont,2_b_cont,2_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "2_m0_stop" "2_0m.mi")
+(final_presence_set "2_0mm.i" "2_0mmi_cont")
+(exclusion_set "2_0mmi_cont"
+ "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_m0_stop" "2_0mm.i")
+(final_presence_set "2_m1_stop" "2_1m.mi")
+(exclusion_set "2_m1_stop" "2_1mm.i")
+(final_presence_set "2_m_stop" "2_m0_stop, 2_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "2_mi0_stop" "2_0mi.i")
+(final_presence_set "2_0mii." "2_0mii_cont")
+(exclusion_set "2_0mii_cont"
+ "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_mi0_stop" "2_0mii.")
+(final_presence_set "2_mi1_stop" "2_1mi.i")
+(exclusion_set "2_mi1_stop" "2_1mii.")
+(final_presence_set "2_mi_stop" "2_mi0_stop, 2_mi1_stop")
+
+(final_absence_set
+ "2_0m.ii,2_0mi.i,2_0mii.,2_0m.mi,2_0mm.i,2_0mmi.,2_0m.fi,2_0mf.i,2_0mfi.,\
+ 2_0m.mf,2_0mm.f,2_0mmf.,2_0b.bb,2_0bb.b,2_0bbb.,2_0m.bb,2_0mb.b,2_0mbb.,\
+ 2_0m.ib,2_0mi.b,2_0mib.,2_0m.mb,2_0mm.b,2_0mmb.,2_0m.fb,2_0mf.b,2_0mfb.,\
+ 2_0m.lx,2_0mlx., \
+ 2_1m.ii,2_1mi.i,2_1mii.,2_1m.mi,2_1mm.i,2_1mmi.,2_1m.fi,2_1mf.i,2_1mfi.,\
+ 2_1m.mf,2_1mm.f,2_1mmf.,2_1b.bb,2_1bb.b,2_1bbb.,2_1m.bb,2_1mb.b,2_1mbb.,\
+ 2_1m.ib,2_1mi.b,2_1mib.,2_1m.mb,2_1mm.b,2_1mmb.,2_1m.fb,2_1mf.b,2_1mfb.,\
+ 2_1m.lx,2_1mlx."
+ "2_m0_stop,2_m1_stop,2_mi0_stop,2_mi1_stop")
+
+(define_insn_reservation "2_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stop_bit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_stop|2_m0_stop|2_m1_stop|2_mi0_stop|2_mi1_stop")
+
+(define_insn_reservation "2_br" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "br"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_B")
+(define_insn_reservation "2_scall" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "scall"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_B")
+(define_insn_reservation "2_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+(define_insn_reservation "2_fcvtfx" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+(define_insn_reservation "2_fld" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fld"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_M")
+(define_insn_reservation "2_fmac" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmac"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+(define_insn_reservation "2_fmisc" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmisc"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+
+;; There is only one insn `mov = ar.bsp' for frar_i:
+;; Latency time ???
+(define_insn_reservation "2_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+;; There is only two insns `mov = ar.unat' or `mov = ar.ccv' for frar_m:
+;; Latency time ???
+(define_insn_reservation "2_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+(define_insn_reservation "2_frbr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frbr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+(define_insn_reservation "2_frfr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frfr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+(define_insn_reservation "2_frpr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frpr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+
+(define_insn_reservation "2_ialu" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_A")
+(define_insn_reservation "2_icmp" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "icmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_A")
+(define_insn_reservation "2_ilog" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ilog"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_A")
+;; Latency time ???
+(define_insn_reservation "2_ishf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ishf"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+(define_insn_reservation "2_ld" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ld"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um01")
+(define_insn_reservation "2_long_i" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "long_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_L")
+
+(define_insn_reservation "2_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmmul"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshf"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I")
+;; Latency time ???
+(define_insn_reservation "2_mmshfi" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshfi"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I")
+
+;; Now we have only one insn (flushrs) of such class. We assume that flushrs
+;; is the 1st syllable of the bundle after stop bit.
+(define_insn_reservation "2_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "rse_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb\
+ |2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx)+2_um0")
+(define_insn_reservation "2_sem" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "sem"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+
+(define_insn_reservation "2_stf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stf"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+(define_insn_reservation "2_st" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "st"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+(define_insn_reservation "2_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m0"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+(define_insn_reservation "2_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um0")
+;; Reservation???
+(define_insn_reservation "2_tbit" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tbit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+
+;; There is only ony insn `mov ar.pfs =' for toar_i:
+(define_insn_reservation "2_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
+;; Latency time ???
+(define_insn_reservation "2_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+;; Latency time ???
+(define_insn_reservation "2_tobr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tobr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+(define_insn_reservation "2_tofr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tofr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+;; Latency time ???
+(define_insn_reservation "2_topr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "topr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+
+(define_insn_reservation "2_xmpy" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xmpy"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+;; Latency time ???
+(define_insn_reservation "2_xtd" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xtd"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I")
+
+(define_insn_reservation "2_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "chk_s"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I|2_M_only_um23")
+(define_insn_reservation "2_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "lfetch"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um01")
+
+(define_insn_reservation "2_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_M0")
+(define_insn_reservation "2_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_b"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_NB")
+(define_insn_reservation "2_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I0")
+(define_insn_reservation "2_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_f"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F0")
+(define_insn_reservation "2_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_x"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_L0")
+
+(define_insn_reservation "2_unknown" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "unknown"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_empty")
+
+(define_insn_reservation "2_nop" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M0|2_NB|2_I0|2_F0")
+
+(define_insn_reservation "2_ignore" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ignore"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "nothing")
+
+(define_cpu_unit "2_m_cont_only, 2_b_cont_only" "two")
+(define_cpu_unit "2_mi_cont_only, 2_mm_cont_only, 2_mf_cont_only" "two")
+(define_cpu_unit "2_mb_cont_only, 2_bb_cont_only" "two")
+
+(final_presence_set "2_m_cont_only" "2_m_cont")
+(exclusion_set "2_m_cont_only"
+ "2_0mi.i, 2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+
+(final_presence_set "2_b_cont_only" "2_b_cont")
+(exclusion_set "2_b_cont_only" "2_0bb.b")
+
+(final_presence_set "2_mi_cont_only" "2_mi_cont")
+(exclusion_set "2_mi_cont_only" "2_0mii., 2_0mib.")
+
+(final_presence_set "2_mm_cont_only" "2_mm_cont")
+(exclusion_set "2_mm_cont_only" "2_0mmi., 2_0mmf., 2_0mmb.")
+
+(final_presence_set "2_mf_cont_only" "2_mf_cont")
+(exclusion_set "2_mf_cont_only" "2_0mfi., 2_0mfb.")
+
+(final_presence_set "2_mb_cont_only" "2_mb_cont")
+(exclusion_set "2_mb_cont_only" "2_0mbb.")
+
+(final_presence_set "2_bb_cont_only" "2_bb_cont")
+(exclusion_set "2_bb_cont_only" "2_0bbb.")
+
+(define_insn_reservation "2_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "nothing")
+
+;;(define_insn_reservation "2_pre_cycle" 0
+;; (and (and (eq_attr "cpu" "itanium2")
+;; (eq_attr "itanium_class" "pre_cycle"))
+;; (eq (symbol_ref "bundling_p") (const_int 0)))
+;; "(2_0m_bs, 2_m_cont) \
+;; | (2_0mi_bs, (2_mi_cont|nothing)) \
+;; | (2_0mm_bs, 2_mm_cont) \
+;; | (2_0mf_bs, (2_mf_cont|nothing)) \
+;; | (2_0b_bs, (2_b_cont|nothing)) \
+;; | (2_0bb_bs, (2_bb_cont|nothing)) \
+;; | (2_0mb_bs, (2_mb_cont|nothing)) \
+;; | (2_1m_bs, 2_m_cont) \
+;; | (2_1mi_bs, (2_mi_cont|nothing)) \
+;; | (2_1mm_bs, 2_mm_cont) \
+;; | (2_1mf_bs, (2_mf_cont|nothing)) \
+;; | (2_1b_bs, (2_b_cont|nothing)) \
+;; | (2_1bb_bs, (2_bb_cont|nothing)) \
+;; | (2_1mb_bs, (2_mb_cont|nothing)) \
+;; | (2_m_cont_only, (2_m_cont|nothing)) \
+;; | (2_b_cont_only, (2_b_cont|nothing)) \
+;; | (2_mi_cont_only, (2_mi_cont|nothing)) \
+;; | (2_mm_cont_only, (2_mm_cont|nothing)) \
+;; | (2_mf_cont_only, (2_mf_cont|nothing)) \
+;; | (2_mb_cont_only, (2_mb_cont|nothing)) \
+;; | (2_bb_cont_only, (2_bb_cont|nothing)) \
+;; | (2_m_stop, (2_0mmi_cont|nothing)) \
+;; | (2_mi_stop, (2_0mii_cont|nothing))")
+
+;; Bypasses:
+
+(define_bypass 1 "2_fcmp" "2_br,2_scall")
+(define_bypass 0 "2_icmp" "2_br,2_scall")
+(define_bypass 0 "2_tbit" "2_br,2_scall")
+(define_bypass 2 "2_ld" "2_ld" "ia64_ld_address_bypass_p")
+(define_bypass 2 "2_ld" "2_st" "ia64_st_address_bypass_p")
+(define_bypass 2 "2_ld" "2_mmmul,2_mmshf")
+(define_bypass 3 "2_ilog" "2_mmmul,2_mmshf")
+(define_bypass 3 "2_ialu" "2_mmmul,2_mmshf")
+(define_bypass 3 "2_mmmul,2_mmshf" "2_ialu,2_ilog,2_ishf,2_st,2_ld")
+(define_bypass 6 "2_tofr" "2_frfr,2_stf")
+(define_bypass 7 "2_fmac" "2_frfr,2_stf")
+
+;; We don't use here fcmp because scall may be predicated.
+(define_bypass 0 "2_fcvtfx,2_fld,2_fmac,2_fmisc,2_frar_i,2_frar_m,\
+ 2_frbr,2_frfr,2_frpr,2_ialu,2_ilog,2_ishf,2_ld,2_long_i,\
+ 2_mmmul,2_mmshf,2_mmshfi,2_toar_m,2_tofr,2_xmpy,2_xtd"
+ "2_scall")
+
+(define_bypass 0 "2_unknown,2_ignore,2_stop_bit,2_br,2_fcmp,2_fcvtfx,2_fld,\
+ 2_fmac,2_fmisc,2_frar_i,2_frar_m,2_frbr,2_frfr,2_frpr,\
+ 2_ialu,2_icmp,2_ilog,2_ishf,2_ld,2_chk_s,\
+ 2_long_i,2_mmmul,2_mmshf,2_mmshfi,2_nop,2_nop_b,2_nop_f,\
+ 2_nop_i,2_nop_m,2_nop_x,2_rse_m,2_scall,2_sem,2_stf,2_st,\
+ 2_syst_m0,2_syst_m,2_tbit,2_toar_i,2_toar_m,2_tobr,2_tofr,\
+ 2_topr,2_xmpy,2_xtd,2_lfetch" "2_ignore")
+
+
+
+;; Bundling
+
+(define_automaton "twob")
+
+;; Pseudo units for quicker searching for position in two packet window. */
+(define_query_cpu_unit "2_1,2_2,2_3,2_4,2_5,2_6" "twob")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx" "twob")
+(define_cpu_unit
+ "2b_0mi.i, 2b_0mm.i, 2b_0mf.i, 2b_0mm.f, 2b_0bb.b, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b" "twob")
+(define_query_cpu_unit
+ "2b_0mii., 2b_0mmi., 2b_0mfi., 2b_0mmf., 2b_0bbb., 2b_0mbb.,\
+ 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx." "twob")
+
+(define_cpu_unit
+ "2b_1m.ii, 2b_1m.mi, 2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx" "twob")
+(define_cpu_unit
+ "2b_1mi.i, 2b_1mm.i, 2b_1mf.i, 2b_1mm.f, 2b_1bb.b, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mm.b, 2b_1mf.b" "twob")
+(define_query_cpu_unit
+ "2b_1mii., 2b_1mmi., 2b_1mfi., 2b_1mmf., 2b_1bbb., 2b_1mbb.,\
+ 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx." "twob")
+
+;; Slot 1
+(exclusion_set "2b_0m.ii"
+ "2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.mi"
+ "2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb, 2b_0m.ib,\
+ 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.fi"
+ "2b_0m.mf, 2b_0b.bb, 2b_0m.bb, 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.mf"
+ "2b_0b.bb, 2b_0m.bb, 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0b.bb" "2b_0m.bb, 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.bb" "2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.ib" "2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.mb" "2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.fb" "2b_0m.lx")
+
+;; Slot 2
+(exclusion_set "2b_0mi.i"
+ "2b_0mm.i, 2b_0mf.i, 2b_0mm.f, 2b_0bb.b, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mm.i"
+ "2b_0mf.i, 2b_0mm.f, 2b_0bb.b, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mf.i"
+ "2b_0mm.f, 2b_0bb.b, 2b_0mb.b, 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mm.f"
+ "2b_0bb.b, 2b_0mb.b, 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0bb.b" "2b_0mb.b, 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mb.b" "2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mi.b" "2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mm.b" "2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mf.b" "2b_0mlx.")
+
+;; Slot 3
+(exclusion_set "2b_0mii."
+ "2b_0mmi., 2b_0mfi., 2b_0mmf., 2b_0bbb., 2b_0mbb.,\
+ 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mmi."
+ "2b_0mfi., 2b_0mmf., 2b_0bbb., 2b_0mbb.,\
+ 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mfi."
+ "2b_0mmf., 2b_0bbb., 2b_0mbb., 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mmf."
+ "2b_0bbb., 2b_0mbb., 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0bbb." "2b_0mbb., 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mbb." "2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mib." "2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mmb." "2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mfb." "2b_0mlx.")
+
+;; Slot 4
+(exclusion_set "2b_1m.ii"
+ "2b_1m.mi, 2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.mi"
+ "2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb, 2b_1m.ib,\
+ 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.fi"
+ "2b_1m.mf, 2b_1b.bb, 2b_1m.bb, 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.mf"
+ "2b_1b.bb, 2b_1m.bb, 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1b.bb" "2b_1m.bb, 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.bb" "2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.ib" "2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.mb" "2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.fb" "2b_1m.lx")
+
+;; Slot 5
+(exclusion_set "2b_1mi.i"
+ "2b_1mm.i, 2b_1mf.i, 2b_1mm.f, 2b_1bb.b, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mm.i"
+ "2b_1mf.i, 2b_1mm.f, 2b_1bb.b, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mf.i"
+ "2b_1mm.f, 2b_1bb.b, 2b_1mb.b, 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mm.f"
+ "2b_1bb.b, 2b_1mb.b, 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1bb.b" "2b_1mb.b, 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mb.b" "2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mi.b" "2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mm.b" "2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mf.b" "2b_1mlx.")
+
+;; Slot 6
+(exclusion_set "2b_1mii."
+ "2b_1mmi., 2b_1mfi., 2b_1mmf., 2b_1bbb., 2b_1mbb.,\
+ 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mmi."
+ "2b_1mfi., 2b_1mmf., 2b_1bbb., 2b_1mbb.,\
+ 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mfi."
+ "2b_1mmf., 2b_1bbb., 2b_1mbb., 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mmf."
+ "2b_1bbb., 2b_1mbb., 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1bbb." "2b_1mbb., 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mbb." "2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mib." "2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mmb." "2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mfb." "2b_1mlx.")
+
+(final_presence_set "2b_0mi.i" "2b_0m.ii")
+(final_presence_set "2b_0mii." "2b_0mi.i")
+(final_presence_set "2b_1mi.i" "2b_1m.ii")
+(final_presence_set "2b_1mii." "2b_1mi.i")
+
+(final_presence_set "2b_0mm.i" "2b_0m.mi")
+(final_presence_set "2b_0mmi." "2b_0mm.i")
+(final_presence_set "2b_1mm.i" "2b_1m.mi")
+(final_presence_set "2b_1mmi." "2b_1mm.i")
+
+(final_presence_set "2b_0mf.i" "2b_0m.fi")
+(final_presence_set "2b_0mfi." "2b_0mf.i")
+(final_presence_set "2b_1mf.i" "2b_1m.fi")
+(final_presence_set "2b_1mfi." "2b_1mf.i")
+
+(final_presence_set "2b_0mm.f" "2b_0m.mf")
+(final_presence_set "2b_0mmf." "2b_0mm.f")
+(final_presence_set "2b_1mm.f" "2b_1m.mf")
+(final_presence_set "2b_1mmf." "2b_1mm.f")
+
+(final_presence_set "2b_0bb.b" "2b_0b.bb")
+(final_presence_set "2b_0bbb." "2b_0bb.b")
+(final_presence_set "2b_1bb.b" "2b_1b.bb")
+(final_presence_set "2b_1bbb." "2b_1bb.b")
+
+(final_presence_set "2b_0mb.b" "2b_0m.bb")
+(final_presence_set "2b_0mbb." "2b_0mb.b")
+(final_presence_set "2b_1mb.b" "2b_1m.bb")
+(final_presence_set "2b_1mbb." "2b_1mb.b")
+
+(final_presence_set "2b_0mi.b" "2b_0m.ib")
+(final_presence_set "2b_0mib." "2b_0mi.b")
+(final_presence_set "2b_1mi.b" "2b_1m.ib")
+(final_presence_set "2b_1mib." "2b_1mi.b")
+
+(final_presence_set "2b_0mm.b" "2b_0m.mb")
+(final_presence_set "2b_0mmb." "2b_0mm.b")
+(final_presence_set "2b_1mm.b" "2b_1m.mb")
+(final_presence_set "2b_1mmb." "2b_1mm.b")
+
+(final_presence_set "2b_0mf.b" "2b_0m.fb")
+(final_presence_set "2b_0mfb." "2b_0mf.b")
+(final_presence_set "2b_1mf.b" "2b_1m.fb")
+(final_presence_set "2b_1mfb." "2b_1mf.b")
+
+(final_presence_set "2b_0mlx." "2b_0m.lx")
+(final_presence_set "2b_1mlx." "2b_1m.lx")
+
+;; See the corresponding comment in non-bundling section above.
+(final_presence_set
+ "2b_1m.lx"
+ "2b_0mmi.,2b_0mfi.,2b_0mmf.,2b_0mib.,2b_0mmb.,2b_0mfb.,2b_0mlx.")
+(final_presence_set "2b_1b.bb" "2b_0mii.,2b_0mmi.,2b_0mfi.,2b_0mmf.,2b_0mlx.")
+(final_presence_set
+ "2b_1m.ii,2b_1m.mi,2b_1m.fi,2b_1m.mf,2b_1m.bb,2b_1m.ib,2b_1m.mb,2b_1m.fb"
+ "2b_0mii.,2b_0mmi.,2b_0mfi.,2b_0mmf.,2b_0mib.,2b_0mmb.,2b_0mfb.,2b_0mlx.")
+
+;; Ports/units (nb means nop.b insn issued into given port):
+(define_cpu_unit
+ "2b_um0, 2b_um1, 2b_um2, 2b_um3, 2b_ui0, 2b_ui1, 2b_uf0, 2b_uf1,\
+ 2b_ub0, 2b_ub1, 2b_ub2, 2b_unb0, 2b_unb1, 2b_unb2" "twob")
+
+(exclusion_set "2b_ub0" "2b_unb0")
+(exclusion_set "2b_ub1" "2b_unb1")
+(exclusion_set "2b_ub2" "2b_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium2 microarchitecture. They also
+;; describe the following rules mentioned in Itanium2
+;; microarchitecture: rules mentioned in Itanium2 microarchitecture:
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+(exclusion_set
+ "2b_0b.bb,2b_0bb.b,2b_0bbb.,2b_0m.bb,2b_0mb.b,2b_0mbb."
+ "2b_1m.ii,2b_1m.mi,2b_1m.fi,2b_1m.mf,2b_1b.bb,2b_1m.bb,\
+ 2b_1m.ib,2b_1m.mb,2b_1m.fb,2b_1m.lx")
+(exclusion_set "2b_0m.ib,2b_0mi.b,2b_0mib." "2b_1b.bb")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "2b_1m.ii, 2b_1m.mi, 2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx"
+ "2b_0mib. 2b_ub2, 2b_0mfb. 2b_ub2, 2b_0mmb. 2b_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "2b_stop" "twob")
+(final_absence_set
+ "2b_0m.ii,2b_0mi.i,2b_0mii.,2b_0m.mi,2b_0mm.i,2b_0mmi.,\
+ 2b_0m.fi,2b_0mf.i,2b_0mfi.,\
+ 2b_0m.mf,2b_0mm.f,2b_0mmf.,2b_0b.bb,2b_0bb.b,2b_0bbb.,\
+ 2b_0m.bb,2b_0mb.b,2b_0mbb.,\
+ 2b_0m.ib,2b_0mi.b,2b_0mib.,2b_0m.mb,2b_0mm.b,2b_0mmb.,\
+ 2b_0m.fb,2b_0mf.b,2b_0mfb.,2b_0m.lx,2b_0mlx., \
+ 2b_1m.ii,2b_1mi.i,2b_1mii.,2b_1m.mi,2b_1mm.i,2b_1mmi.,\
+ 2b_1m.fi,2b_1mf.i,2b_1mfi.,\
+ 2b_1m.mf,2b_1mm.f,2b_1mmf.,2b_1b.bb,2b_1bb.b,2b_1bbb.,\
+ 2b_1m.bb,2b_1mb.b,2b_1mbb.,\
+ 2b_1m.ib,2b_1mi.b,2b_1mib.,2b_1m.mb,2b_1mm.b,2b_1mmb.,\
+ 2b_1m.fb,2b_1mf.b,2b_1mfb.,2b_1m.lx,2b_1mlx."
+ "2b_stop")
+
+;; The issue logic can reorder M slot insns between different subtypes
+;; but can not reorder insn within the same subtypes. The following
+;; constraint is enough to describe this.
+(final_presence_set "2b_um1" "2b_um0")
+(final_presence_set "2b_um3" "2b_um2")
+
+;; The insn in the 1st I slot of the two bundle issue group will issue
+;; to I0. The second I slot insn will issue to I1.
+(final_presence_set "2b_ui1" "2b_ui0")
+
+;; For exceptions of I insns:
+(define_cpu_unit "2b_only_ui0" "twob")
+(final_absence_set "2b_only_ui0" "2b_ui1")
+
+;; Insns
+
+(define_reservation "2b_M"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +(2b_um0|2b_um1|2b_um2|2b_um3)")
+
+(define_reservation "2b_M_only_um0"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +2b_um0")
+
+(define_reservation "2b_M_only_um2"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +2b_um2")
+
+(define_reservation "2b_M_only_um01"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +(2b_um0|2b_um1)")
+
+(define_reservation "2b_M_only_um23"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +(2b_um2|2b_um3)")
+
+;; I instruction is dispersed to the lowest numbered I unit
+;; not already in use. Remeber about possible splitting.
+(define_reservation "2b_I"
+ "2b_0mi.i+2_2+2b_ui0|2b_0mii.+2_3+(2b_ui0|2b_ui1)|2b_0mmi.+2_3+2b_ui0\
+ |2b_0mfi.+2_3+2b_ui0|2b_0mi.b+2_2+2b_ui0\
+ |(2b_1mi.i+2_5|2b_1mi.b+2_5)+(2b_ui0|2b_ui1)\
+ |(2b_1mii.|2b_1mmi.|2b_1mfi.)+2_6+(2b_ui0|2b_ui1)")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "2b_F"
+ "2b_0mf.i+2_2+2b_uf0|2b_0mmf.+2_3+2b_uf0|2b_0mf.b+2_2+2b_uf0\
+ |2b_1mf.i+2_5+2b_uf1|2b_1mmf.+2_6+2b_uf1|2b_1mf.b+2_5+2b_uf1")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "2b_NB"
+ "2b_0b.bb+2_1+2b_unb0|2b_0bb.b+2_2+2b_unb1|2b_0bbb.+2_3+2b_unb2\
+ |2b_0mb.b+2_2+2b_unb1|2b_0mbb.+2_3+2b_unb2\
+ |2b_0mib.+2_3+2b_unb0|2b_0mmb.+2_3+2b_unb0|2b_0mfb.+2_3+2b_unb0\
+ |2b_1b.bb+2_4+2b_unb0|2b_1bb.b+2_5+2b_unb1\
+ |2b_1bbb.+2_6+2b_unb2|2b_1mb.b+2_5+2b_unb1|2b_1mbb.+2_6+2b_unb2\
+ |2b_1mib.+2_6+2b_unb0|2b_1mmb.+2_6+2b_unb0|2b_1mfb.+2_6+2b_unb0")
+
+(define_reservation "2b_B"
+ "2b_0b.bb+2_1+2b_ub0|2b_0bb.b+2_2+2b_ub1|2b_0bbb.+2_3+2b_ub2\
+ |2b_0mb.b+2_2+2b_ub1|2b_0mbb.+2_3+2b_ub2|2b_0mib.+2_3+2b_ub2\
+ |2b_0mfb.+2_3+2b_ub2|2b_1b.bb+2_4+2b_ub0|2b_1bb.b+2_5+2b_ub1\
+ |2b_1bbb.+2_6+2b_ub2|2b_1mb.b+2_5+2b_ub1\
+ |2b_1mib.+2_6+2b_ub2|2b_1mmb.+2_6+2b_ub2|2b_1mfb.+2_6+2b_ub2")
+
+;; For the MLI template, the I slot insn is always assigned to port I0
+;; if it is in the first bundle or it is assigned to port I1 if it is in
+;; the second bundle.
+(define_reservation "2b_L"
+ "2b_0mlx.+2_3+2b_ui0+2b_uf0|2b_1mlx.+2_6+2b_ui1+2b_uf1")
+
+;; Should we describe that A insn in I slot can be issued into M
+;; ports? I think it is not necessary because of multipass
+;; scheduling. For example, the multipass scheduling could use
+;; MMI-MMI instead of MII-MII where the two last I slots contain A
+;; insns (even if the case is complicated by use-def conflicts).
+;;
+;; In any case we could describe it as
+;; (define_cpu_unit "2b_ui1_0pres,2b_ui1_1pres,2b_ui1_2pres,2b_ui1_3pres"
+;; "twob")
+;; (final_presence_set "2b_ui1_0pres,2b_ui1_1pres,2b_ui1_2pres,2b_ui1_3pres"
+;; "2b_ui1")
+;; (define_reservation "b_A"
+;; "b_M|b_I\
+;; |(2b_1mi.i+2_5|2b_1mii.+2_6|2b_1mmi.+2_6|2b_1mfi.+2_6|2b_1mi.b+2_5)\
+;; +(2b_um0|2b_um1|2b_um2|2b_um3)\
+;; +(2b_ui1_0pres|2b_ui1_1pres|2b_ui1_2pres|2b_ui1_3pres)")
+
+(define_reservation "2b_A" "2b_M|2b_I")
+
+;; We assume that there is no insn issued on the same cycle as the
+;; unknown insn.
+(define_cpu_unit "2b_empty" "twob")
+(exclusion_set "2b_empty"
+ "2b_0m.ii,2b_0m.mi,2b_0m.fi,2b_0m.mf,2b_0b.bb,2b_0m.bb,\
+ 2b_0m.ib,2b_0m.mb,2b_0m.fb,2b_0m.lx,2b_0mm.i")
+
+(define_cpu_unit
+ "2b_0m_bs, 2b_0mi_bs, 2b_0mm_bs, 2b_0mf_bs, 2b_0b_bs, 2b_0bb_bs, 2b_0mb_bs"
+ "twob")
+(define_cpu_unit
+ "2b_1m_bs, 2b_1mi_bs, 2b_1mm_bs, 2b_1mf_bs, 2b_1b_bs, 2b_1bb_bs, 2b_1mb_bs"
+ "twob")
+
+(define_cpu_unit "2b_m_cont, 2b_mi_cont, 2b_mm_cont, 2b_mf_cont, 2b_mb_cont,\
+ 2b_b_cont, 2b_bb_cont" "twob")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "2b_m_stop, 2b_m0_stop, 2b_m1_stop, 2b_0mmi_cont" "twob")
+(define_cpu_unit "2b_mi_stop, 2b_mi0_stop, 2b_mi1_stop, 2b_0mii_cont" "twob")
+
+(final_presence_set "2b_0m_bs"
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.mf, 2b_0m.fi, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.fb, 2b_0m.mb, 2b_0m.lx")
+(final_presence_set "2b_1m_bs"
+ "2b_1m.ii, 2b_1m.mi, 2b_1m.mf, 2b_1m.fi, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.fb, 2b_1m.mb, 2b_1m.lx")
+(final_presence_set "2b_0mi_bs" "2b_0mi.i, 2b_0mi.i")
+(final_presence_set "2b_1mi_bs" "2b_1mi.i, 2b_1mi.i")
+(final_presence_set "2b_0mm_bs" "2b_0mm.i, 2b_0mm.f, 2b_0mm.b")
+(final_presence_set "2b_1mm_bs" "2b_1mm.i, 2b_1mm.f, 2b_1mm.b")
+(final_presence_set "2b_0mf_bs" "2b_0mf.i, 2b_0mf.b")
+(final_presence_set "2b_1mf_bs" "2b_1mf.i, 2b_1mf.b")
+(final_presence_set "2b_0b_bs" "2b_0b.bb")
+(final_presence_set "2b_1b_bs" "2b_1b.bb")
+(final_presence_set "2b_0bb_bs" "2b_0bb.b")
+(final_presence_set "2b_1bb_bs" "2b_1bb.b")
+(final_presence_set "2b_0mb_bs" "2b_0mb.b")
+(final_presence_set "2b_1mb_bs" "2b_1mb.b")
+
+(exclusion_set "2b_0m_bs"
+ "2b_0mi.i, 2b_0mm.i, 2b_0mm.f, 2b_0mf.i, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mf.b, 2b_0mm.b, 2b_0mlx., 2b_m0_stop")
+(exclusion_set "2b_1m_bs"
+ "2b_1mi.i, 2b_1mm.i, 2b_1mm.f, 2b_1mf.i, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mf.b, 2b_1mm.b, 2b_1mlx., 2b_m1_stop")
+(exclusion_set "2b_0mi_bs" "2b_0mii., 2b_0mib., 2b_mi0_stop")
+(exclusion_set "2b_1mi_bs" "2b_1mii., 2b_1mib., 2b_mi1_stop")
+(exclusion_set "2b_0mm_bs" "2b_0mmi., 2b_0mmf., 2b_0mmb.")
+(exclusion_set "2b_1mm_bs" "2b_1mmi., 2b_1mmf., 2b_1mmb.")
+(exclusion_set "2b_0mf_bs" "2b_0mfi., 2b_0mfb.")
+(exclusion_set "2b_1mf_bs" "2b_1mfi., 2b_1mfb.")
+(exclusion_set "2b_0b_bs" "2b_0bb.b")
+(exclusion_set "2b_1b_bs" "2b_1bb.b")
+(exclusion_set "2b_0bb_bs" "2b_0bbb.")
+(exclusion_set "2b_1bb_bs" "2b_1bbb.")
+(exclusion_set "2b_0mb_bs" "2b_0mbb.")
+(exclusion_set "2b_1mb_bs" "2b_1mbb.")
+
+(exclusion_set
+ "2b_0m_bs, 2b_0mi_bs, 2b_0mm_bs, 2b_0mf_bs, 2b_0b_bs, 2b_0bb_bs, 2b_0mb_bs,
+ 2b_1m_bs, 2b_1mi_bs, 2b_1mm_bs, 2b_1mf_bs, 2b_1b_bs, 2b_1bb_bs, 2b_1mb_bs"
+ "2b_stop")
+
+(final_presence_set
+ "2b_0mi.i, 2b_0mm.i, 2b_0mf.i, 2b_0mm.f, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx."
+ "2b_m_cont")
+(final_presence_set "2b_0mii., 2b_0mib." "2b_mi_cont")
+(final_presence_set "2b_0mmi., 2b_0mmf., 2b_0mmb." "2b_mm_cont")
+(final_presence_set "2b_0mfi., 2b_0mfb." "2b_mf_cont")
+(final_presence_set "2b_0bb.b" "2b_b_cont")
+(final_presence_set "2b_0bbb." "2b_bb_cont")
+(final_presence_set "2b_0mbb." "2b_mb_cont")
+
+(exclusion_set
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx"
+ "2b_m_cont, 2b_mi_cont, 2b_mm_cont, 2b_mf_cont,\
+ 2b_mb_cont, 2b_b_cont, 2b_bb_cont")
+
+(exclusion_set "2b_empty"
+ "2b_m_cont,2b_mi_cont,2b_mm_cont,2b_mf_cont,\
+ 2b_mb_cont,2b_b_cont,2b_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "2b_m0_stop" "2b_0m.mi")
+(final_presence_set "2b_0mm.i" "2b_0mmi_cont")
+(exclusion_set "2b_0mmi_cont"
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_m0_stop" "2b_0mm.i")
+(final_presence_set "2b_m1_stop" "2b_1m.mi")
+(exclusion_set "2b_m1_stop" "2b_1mm.i")
+(final_presence_set "2b_m_stop" "2b_m0_stop, 2b_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "2b_mi0_stop" "2b_0mi.i")
+(final_presence_set "2b_0mii." "2b_0mii_cont")
+(exclusion_set "2b_0mii_cont"
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_mi0_stop" "2b_0mii.")
+(final_presence_set "2b_mi1_stop" "2b_1mi.i")
+(exclusion_set "2b_mi1_stop" "2b_1mii.")
+(final_presence_set "2b_mi_stop" "2b_mi0_stop, 2b_mi1_stop")
+
+(final_absence_set
+ "2b_0m.ii,2b_0mi.i,2b_0mii.,2b_0m.mi,2b_0mm.i,2b_0mmi.,\
+ 2b_0m.fi,2b_0mf.i,2b_0mfi.,2b_0m.mf,2b_0mm.f,2b_0mmf.,\
+ 2b_0b.bb,2b_0bb.b,2b_0bbb.,2b_0m.bb,2b_0mb.b,2b_0mbb.,\
+ 2b_0m.ib,2b_0mi.b,2b_0mib.,2b_0m.mb,2b_0mm.b,2b_0mmb.,\
+ 2b_0m.fb,2b_0mf.b,2b_0mfb.,2b_0m.lx,2b_0mlx., \
+ 2b_1m.ii,2b_1mi.i,2b_1mii.,2b_1m.mi,2b_1mm.i,2b_1mmi.,\
+ 2b_1m.fi,2b_1mf.i,2b_1mfi.,2b_1m.mf,2b_1mm.f,2b_1mmf.,\
+ 2b_1b.bb,2b_1bb.b,2b_1bbb.,2b_1m.bb,2b_1mb.b,2b_1mbb.,\
+ 2b_1m.ib,2b_1mi.b,2b_1mib.,2b_1m.mb,2b_1mm.b,2b_1mmb.,\
+ 2b_1m.fb,2b_1mf.b,2b_1mfb.,2b_1m.lx,2b_1mlx."
+ "2b_m0_stop,2b_m1_stop,2b_mi0_stop,2b_mi1_stop")
+
+(define_insn_reservation "2b_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stop_bit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_stop|2b_m0_stop|2b_m1_stop|2b_mi0_stop|2b_mi1_stop")
+(define_insn_reservation "2b_br" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "br"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_B")
+(define_insn_reservation "2b_scall" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "scall"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_B")
+(define_insn_reservation "2b_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_fcvtfx" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_fld" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fld"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_M")
+(define_insn_reservation "2b_fmac" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmac"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_fmisc" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmisc"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+
+;; Latency time ???
+(define_insn_reservation "2b_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2b_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+(define_insn_reservation "2b_frbr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frbr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_frfr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frfr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+(define_insn_reservation "2b_frpr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frpr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+
+(define_insn_reservation "2b_ialu" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ialu"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_A")
+(define_insn_reservation "2b_icmp" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "icmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_A")
+(define_insn_reservation "2b_ilog" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ilog"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_A")
+;; Latency time ???
+(define_insn_reservation "2b_ishf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ishf"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_ld" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ld"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um01")
+(define_insn_reservation "2b_long_i" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "long_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_L")
+
+;; Latency time ???
+(define_insn_reservation "2b_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmmul"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2b_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshf"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+;; Latency time ???
+(define_insn_reservation "2b_mmshfi" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshfi"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+
+(define_insn_reservation "2b_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "rse_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1+2b_um0")
+(define_insn_reservation "2b_sem" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "sem"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+
+(define_insn_reservation "2b_stf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stf"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+(define_insn_reservation "2b_st" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "st"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+(define_insn_reservation "2b_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m0"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+(define_insn_reservation "2b_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um0")
+;; Reservation???
+(define_insn_reservation "2b_tbit" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tbit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2b_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+;; Latency time ???
+(define_insn_reservation "2b_tobr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tobr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_tofr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tofr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+;; Latency time ???
+(define_insn_reservation "2b_topr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "topr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+
+(define_insn_reservation "2b_xmpy" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xmpy"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+;; Latency time ???
+(define_insn_reservation "2b_xtd" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xtd"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+(define_insn_reservation "2b_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "chk_s"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I|2b_M_only_um23")
+(define_insn_reservation "2b_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "lfetch"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um01")
+(define_insn_reservation "2b_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_M")
+(define_insn_reservation "2b_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_b"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_NB")
+(define_insn_reservation "2b_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+(define_insn_reservation "2b_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_f"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_x"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_L")
+(define_insn_reservation "2b_unknown" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "unknown"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_empty")
+(define_insn_reservation "2b_nop" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M|2b_NB|2b_I|2b_F")
+(define_insn_reservation "2b_ignore" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ignore"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "nothing")
+
+(define_insn_reservation "2b_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(2b_0m_bs, 2b_m_cont) \
+ | (2b_0mi_bs, 2b_mi_cont) \
+ | (2b_0mm_bs, 2b_mm_cont) \
+ | (2b_0mf_bs, 2b_mf_cont) \
+ | (2b_0b_bs, 2b_b_cont) \
+ | (2b_0bb_bs, 2b_bb_cont) \
+ | (2b_0mb_bs, 2b_mb_cont) \
+ | (2b_1m_bs, 2b_m_cont) \
+ | (2b_1mi_bs, 2b_mi_cont) \
+ | (2b_1mm_bs, 2b_mm_cont) \
+ | (2b_1mf_bs, 2b_mf_cont) \
+ | (2b_1b_bs, 2b_b_cont) \
+ | (2b_1bb_bs, 2b_bb_cont) \
+ | (2b_1mb_bs, 2b_mb_cont) \
+ | (2b_m_stop, 2b_0mmi_cont) \
+ | (2b_mi_stop, 2b_0mii_cont)")
+
diff --git a/contrib/gcc/config/ia64/lib1funcs.asm b/contrib/gcc/config/ia64/lib1funcs.asm
index 75e79b0..e3d348b 100644
--- a/contrib/gcc/config/ia64/lib1funcs.asm
+++ b/contrib/gcc/config/ia64/lib1funcs.asm
@@ -1,15 +1,19 @@
-#ifdef L__divtf3
+#ifdef L__divxf3
// Compute a 80-bit IEEE double-extended quotient.
//
// From the Intel IA-64 Optimization Guide, choose the minimum latency
// alternative.
//
// farg0 holds the dividend. farg1 holds the divisor.
+//
+// __divtf3 is an alternate symbol name for backward compatibility.
.text
.align 16
+ .global __divxf3
.global __divtf3
- .proc __divtf3
+ .proc __divxf3
+__divxf3:
__divtf3:
cmp.eq p7, p0 = r0, r0
frcpa.s0 f10, p6 = farg0, farg1
@@ -37,7 +41,7 @@ __divtf3:
(p6) fma.s0 fret0 = f12, f10, f11
(p7) mov fret0 = f10
br.ret.sptk rp
- .endp __divtf3
+ .endp __divxf3
#endif
#ifdef L__divdf3
@@ -701,3 +705,39 @@ __ia64_trampoline:
}
.endp __ia64_trampoline
#endif
+
+#ifdef L__compat
+// Thunks for backward compatibility.
+
+ .text
+ .align 16
+ .global __fixtfti
+ .proc __fixtfti
+__fixtfti:
+ { .bbb
+ br.sptk.many __fixxfti
+ ;;
+ }
+ .endp __fixtfti
+
+ .align 16
+ .global __fixunstfti
+ .proc __fixunstfti
+__fixunstfti:
+ { .bbb
+ br.sptk.many __fixunsxfti
+ ;;
+ }
+ .endp __fixunstfti
+
+ .align 16
+ .global __floattitf
+ .proc __floattitf
+__floattitf:
+ { .bbb
+ br.sptk.many __floattixf
+ ;;
+ }
+ .endp __floattitf
+
+#endif
diff --git a/contrib/gcc/config/ia64/linux.h b/contrib/gcc/config/ia64/linux.h
index e1d60f7..5c73b0c 100644
--- a/contrib/gcc/config/ia64/linux.h
+++ b/contrib/gcc/config/ia64/linux.h
@@ -12,27 +12,27 @@
/* Target OS builtins. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
- builtin_assert("system=linux"); \
- builtin_define_std("linux"); \
- builtin_define_std("unix"); \
- builtin_define("__gnu_linux__"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
builtin_define("_LONGLONG"); \
} while (0)
/* Need to override linux.h STARTFILE_SPEC, since it has crtbeginT.o in. */
#undef STARTFILE_SPEC
+#ifdef HAVE_LD_PIE
#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
- %{!p:%{profile:gcrt1.o%s} \
- %{!profile:crt1.o%s}}}} \
- crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+#else
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+#endif
/* Similar to standard Linux, but adding -ffast-math support. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
- %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* Define this for shared library support because it isn't in the main
linux.h file. */
@@ -58,12 +58,17 @@ do { \
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
+/* This works only for glibc-2.3 and later, because sigcontext is different
+ in glibc-2.2.4. */
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
+
#ifdef IN_LIBGCC2
#include <signal.h>
#include <sys/ucontext.h>
#define IA64_GATE_AREA_START 0xa000000000000100LL
-#define IA64_GATE_AREA_END 0xa000000000020000LL
+#define IA64_GATE_AREA_END 0xa000000000030000LL
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
if ((CONTEXT)->rp >= IA64_GATE_AREA_START \
@@ -90,11 +95,13 @@ do { \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
} \
\
+ (CONTEXT)->fpsr_loc = &(sc_->sc_ar_fpsr); \
(CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
(CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
(CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
(CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
- (CONTEXT)->bsp = sc_->sc_ar_bsp; \
+ (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
+ (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
(CONTEXT)->pr = sc_->sc_pr; \
(CONTEXT)->psp = sc_->sc_gr[12]; \
(CONTEXT)->gp = sc_->sc_gr[1]; \
@@ -102,11 +109,26 @@ do { \
other than what we adjust for below. */ \
(FS) -> no_reg_stack_frame = 1; \
\
- /* Don't touch the branch registers o.t. b0. The kernel doesn't \
- pass the preserved branch registers in the sigcontext but \
- leaves them intact, so there's no need to do anything \
- with them here. */ \
+ if (sc_->sc_rbs_base) \
+ { \
+ /* Need to switch from alternate register backing store. */ \
+ long ndirty, loadrs = sc_->sc_loadrs >> 16; \
+ unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
+ unsigned long bspstore; \
+ unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
\
+ ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
+ (unsigned long *) (CONTEXT)->bsp);\
+ bspstore = (unsigned long) \
+ ia64_rse_skip_regs (ar_bsp, -ndirty); \
+ ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
+ sc_->sc_ar_rnat); \
+ } \
+ \
+ /* Don't touch the branch registers o.t. b0, b6 and b7. \
+ The kernel doesn't pass the preserved branch registers \
+ in the sigcontext but leaves them intact, so there's no \
+ need to do anything with them here. */ \
{ \
unsigned long sof = sc_->sc_cfm & 0x7f; \
(CONTEXT)->bsp = (unsigned long) \
@@ -120,4 +142,74 @@ do { \
\
goto SUCCESS; \
}
+
+#define MD_HANDLE_UNWABI(CONTEXT, FS) \
+ if ((FS)->unwabi == ((3 << 8) | 's') \
+ || (FS)->unwabi == ((0 << 8) | 's')) \
+ { \
+ struct sigframe { \
+ char scratch[16]; \
+ unsigned long sig_number; \
+ struct siginfo *info; \
+ struct sigcontext *sc; \
+ } *frame_ = (struct sigframe *)(CONTEXT)->psp; \
+ struct sigcontext *sc_ = frame_->sc; \
+ \
+ /* Restore scratch registers in case the unwinder needs to \
+ refer to a value stored in one of them. */ \
+ { \
+ int i_; \
+ \
+ for (i_ = 2; i_ < 4; i_++) \
+ (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
+ for (i_ = 8; i_ < 12; i_++) \
+ (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
+ for (i_ = 14; i_ < 32; i_++) \
+ (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
+ } \
+ \
+ (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
+ (CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
+ (CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
+ (CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
+ (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
+ (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
+ (CONTEXT)->pr = sc_->sc_pr; \
+ (CONTEXT)->gp = sc_->sc_gr[1]; \
+ /* Signal frame doesn't have an associated reg. stack frame \
+ other than what we adjust for below. */ \
+ (FS) -> no_reg_stack_frame = 1; \
+ \
+ if (sc_->sc_rbs_base) \
+ { \
+ /* Need to switch from alternate register backing store. */ \
+ long ndirty, loadrs = sc_->sc_loadrs >> 16; \
+ unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
+ unsigned long bspstore; \
+ unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
+ \
+ ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
+ (unsigned long *) (CONTEXT)->bsp);\
+ bspstore = (unsigned long) \
+ ia64_rse_skip_regs (ar_bsp, -ndirty); \
+ ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
+ sc_->sc_ar_rnat); \
+ } \
+ \
+ /* Don't touch the branch registers o.t. b0, b6 and b7. \
+ The kernel doesn't pass the preserved branch registers \
+ in the sigcontext but leaves them intact, so there's no \
+ need to do anything with them here. */ \
+ { \
+ unsigned long sof = sc_->sc_cfm & 0x7f; \
+ (CONTEXT)->bsp = (unsigned long) \
+ ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
+ } \
+ \
+ /* pfs_loc already set above. Without this pfs_loc would point \
+ incorrectly to sc_cfm instead of sc_ar_pfs. */ \
+ (FS)->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE; \
+ }
+
#endif /* IN_LIBGCC2 */
+#endif /* glibc-2.3 or better */
diff --git a/contrib/gcc/config/ia64/quadlib.c b/contrib/gcc/config/ia64/quadlib.c
index e55c97d..cc367ea 100644
--- a/contrib/gcc/config/ia64/quadlib.c
+++ b/contrib/gcc/config/ia64/quadlib.c
@@ -1,9 +1,9 @@
/* Subroutines for long double support.
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -17,13 +17,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/ia64/sysv4.h b/contrib/gcc/config/ia64/sysv4.h
index 3254fa5..15a57d9 100644
--- a/contrib/gcc/config/ia64/sysv4.h
+++ b/contrib/gcc/config/ia64/sysv4.h
@@ -61,8 +61,6 @@ do { \
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
do { \
const char *name_ = NAME; \
- if (*name_ == ENCODE_SECTION_INFO_CHAR) \
- name_ += 2; \
if (*name_ == '*') \
name_++; \
else \
@@ -119,26 +117,6 @@ do { \
fputc ('\n', FILE); \
} while (0)
-/* A C expression which outputs to the stdio stream STREAM some appropriate
- text to go at the start of an assembler file. */
-
-/* ??? Looks like almost every port, except for a few original ones, get this
- wrong. Must emit #NO_APP as first line of file to turn of special assembler
- preprocessing of files. */
-
-/* ??? Even worse, it doesn't work, because gas does not accept the tab chars
- that dwarf2out.c emits when #NO_APP. */
-
-/* ??? Unrelated, but dwarf2out.c emits unnecessary newlines after strings,
- may as well fix at the same time. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
-do { \
- output_file_directive (STREAM, main_input_filename); \
- emit_safe_across_calls (STREAM); \
-} while (0)
-
/* Override default elf definition. */
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION ia64_select_rtx_section
@@ -155,7 +133,7 @@ do { \
#define SDATA_SECTION_FUNCTION \
void \
-sdata_section () \
+sdata_section (void) \
{ \
if (in_section != in_sdata) \
{ \
@@ -168,7 +146,7 @@ sdata_section () \
#define SBSS_SECTION_FUNCTION \
void \
-sbss_section () \
+sbss_section (void) \
{ \
if (in_section != in_sbss) \
{ \
diff --git a/contrib/gcc/config/ia64/t-hpux b/contrib/gcc/config/ia64/t-hpux
index 7b42fe5..597c2ac 100644
--- a/contrib/gcc/config/ia64/t-hpux
+++ b/contrib/gcc/config/ia64/t-hpux
@@ -20,22 +20,17 @@ quadlib.c: $(srcdir)/config/ia64/quadlib.c
LIBGCC1_TEST =
-# Don't run fix-headers. HP-UX headers are standards conformant
-# and don't need to be fixed up in this way.
-# If we remove this (and run fix-headers) we should define FIXPROTO_DEFINES
-# and also fix the definition of putenv in sys-protos.h (const char not char).
-
-STMP_FIXPROTO =
-
# We do not want to include the EH stuff that linux uses, we want to use
# the HP-UX libunwind library.
LIB2ADDEH =
SHLIB_EXT = .so
+# Must include -lunwind in the link, so that libgcc_s.so has the necessary
+# DT_NEEDED entry for libunwind.
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
-Wl,+h,@shlib_base_name@.so.0 \
- -o @shlib_base_name@.so @multilib_flags@ @shlib_objs@ -lc && \
+ -o @shlib_base_name@.so @multilib_flags@ @shlib_objs@ -lunwind -lc && \
rm -f @shlib_base_name@.so.0 && \
$(LN_S) @shlib_base_name@.so @shlib_base_name@.so.0
# $(slibdir) double quoted to protect it from expansion while building
diff --git a/contrib/gcc/config/ia64/t-ia64 b/contrib/gcc/config/ia64/t-ia64
index 7c63b31..21d37a7 100644
--- a/contrib/gcc/config/ia64/t-ia64
+++ b/contrib/gcc/config/ia64/t-ia64
@@ -5,10 +5,10 @@ LIB1ASMSRC = ia64/lib1funcs.asm
# we use __ as the prefix. Note that L_divdi3 in libgcc2.c actually defines
# a TImode divide function, so there is no actual overlap here between
# libgcc2.c and lib1funcs.asm.
-LIB1ASMFUNCS = __divtf3 __divdf3 __divsf3 \
+LIB1ASMFUNCS = __divxf3 __divdf3 __divsf3 \
__divdi3 __moddi3 __udivdi3 __umoddi3 \
__divsi3 __modsi3 __udivsi3 __umodsi3 __save_stack_nonlocal \
- __nonlocal_goto __restore_stack_nonlocal __trampoline
+ __nonlocal_goto __restore_stack_nonlocal __trampoline __compat
# ??? Hack to get -P option used when compiling lib1funcs.asm, because Intel
# assembler does not accept # line number as a comment.
@@ -41,8 +41,11 @@ crtfastmath.o: $(srcdir)/config/ia64/crtfastmath.c $(GCC_PASSES)
$(srcdir)/config/ia64/crtfastmath.c
LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c \
- $(srcdir)/unwind-c.c
+ $(srcdir)/unwind-c.c $(srcdir)/gthr-gnat.c
ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) c-pragma.h toplev.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ coretypes.h $(TM_H) $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) c-pragma.h toplev.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/ia64/ia64-c.c
+
+# genattrtab generates very long string literals.
+insn-attrtab.o-warn = -Wno-error
diff --git a/contrib/gcc/config/ia64/unwind-ia64.c b/contrib/gcc/config/ia64/unwind-ia64.c
index 88d236b..d981d8c 100644
--- a/contrib/gcc/config/ia64/unwind-ia64.c
+++ b/contrib/gcc/config/ia64/unwind-ia64.c
@@ -6,20 +6,20 @@
Andrew Haley <aph@cygnus.com>
David Mosberger-Tang <davidm@hpl.hp.com>
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,6 +33,8 @@
#include "tconfig.h"
#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
#include "unwind.h"
#include "unwind-ia64.h"
#include "ia64intrin.h"
@@ -155,6 +157,7 @@ typedef struct unw_state_record
unsigned char gr_save_loc; /* next general register to use for saving */
unsigned char return_link_reg; /* branch register for return link */
+ unsigned short unwabi;
struct unw_labeled_state *labeled_states; /* list of all labeled states */
struct unw_reg_state curr; /* current state */
@@ -181,7 +184,8 @@ struct _Unwind_Context
{
/* Initial frame info. */
unsigned long rnat; /* rse nat collection */
- unsigned long regstk_top; /* bsp for first frame */
+ unsigned long regstk_top; /* lowest address of rbs stored register
+ which uses context->rnat collection */
/* Current frame info. */
unsigned long bsp; /* backing store pointer value
@@ -219,7 +223,7 @@ struct _Unwind_Context
} nat;
} ireg[32 - 2]; /* Indexed by <register number> - 2 */
- unsigned long *br_loc[7];
+ unsigned long *br_loc[8];
void *fr_loc[32 - 2];
/* ??? We initially point pri_unat_loc here. The entire NAT bit
@@ -619,11 +623,11 @@ desc_prologue (int body, unw_word rlen, unsigned char mask,
*/
static inline void
-desc_abi (unsigned char abi __attribute__((unused)),
- unsigned char context __attribute__((unused)),
- struct unw_state_record *sr __attribute__((unused)))
+desc_abi (unsigned char abi,
+ unsigned char context,
+ struct unw_state_record *sr)
{
- /* Anything to do? */
+ sr->unwabi = (abi << 8) | context;
}
static inline void
@@ -1465,7 +1469,7 @@ ia64_rse_rnat_addr (unsigned long *slot_addr)
return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
}
-/* Calcuate the number of registers in the dirty partition starting at
+/* Calculate the number of registers in the dirty partition starting at
BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
divided by eight because the 64th slot is used to store ar.rnat. */
static inline unsigned long
@@ -1489,6 +1493,80 @@ ia64_rse_skip_regs (unsigned long *addr, long num_regs)
}
+/* Copy register backing store from SRC to DST, LEN words
+ (which include both saved registers and nat collections).
+ DST_RNAT is a partial nat collection for DST. SRC and DST
+ don't have to be equal modulo 64 slots, so it cannot be
+ done with a simple memcpy as the nat collections will be
+ at different relative offsets and need to be combined together. */
+static void
+ia64_copy_rbs (struct _Unwind_Context *info, unsigned long dst,
+ unsigned long src, long len, unsigned long dst_rnat)
+{
+ long count;
+ unsigned long src_rnat;
+ unsigned long shift1, shift2;
+
+ len <<= 3;
+ dst_rnat &= (1UL << ((dst >> 3) & 0x3f)) - 1;
+ src_rnat = src >= info->regstk_top
+ ? info->rnat : *(unsigned long *) (src | 0x1f8);
+ src_rnat &= ~((1UL << ((src >> 3) & 0x3f)) - 1);
+ /* Just to make sure. */
+ src_rnat &= ~(1UL << 63);
+ shift1 = ((dst - src) >> 3) & 0x3f;
+ if ((dst & 0x1f8) < (src & 0x1f8))
+ shift1--;
+ shift2 = 0x3f - shift1;
+ if ((dst & 0x1f8) >= (src & 0x1f8))
+ {
+ count = ~dst & 0x1f8;
+ goto first;
+ }
+ count = ~src & 0x1f8;
+ goto second;
+ while (len > 0)
+ {
+ src_rnat = src >= info->regstk_top
+ ? info->rnat : *(unsigned long *) (src | 0x1f8);
+ /* Just to make sure. */
+ src_rnat &= ~(1UL << 63);
+ count = shift2 << 3;
+first:
+ if (count > len)
+ count = len;
+ memcpy ((char *) dst, (char *) src, count);
+ dst += count;
+ src += count;
+ len -= count;
+ dst_rnat |= (src_rnat << shift1) & ~(1UL << 63);
+ if (len <= 0)
+ break;
+ *(long *) dst = dst_rnat;
+ dst += 8;
+ dst_rnat = 0;
+ count = shift1 << 3;
+second:
+ if (count > len)
+ count = len;
+ memcpy ((char *) dst, (char *) src, count);
+ dst += count;
+ src += count + 8;
+ len -= count + 8;
+ dst_rnat |= (src_rnat >> shift2);
+ }
+ if ((dst & 0x1f8) == 0x1f8)
+ {
+ *(long *) dst = dst_rnat;
+ dst += 8;
+ dst_rnat = 0;
+ }
+ /* Set info->regstk_top to lowest rbs address which will use
+ info->rnat collection. */
+ info->regstk_top = dst & ~0x1ffUL;
+ info->rnat = dst_rnat;
+}
+
/* Unwind accessors. */
static void
@@ -1548,9 +1626,10 @@ unw_access_gr (struct _Unwind_Context *info, int regnum,
break;
case UNW_NAT_REGSTK:
- nat_addr = ia64_rse_rnat_addr (addr);
- if ((unsigned long) nat_addr >= info->regstk_top)
+ if ((unsigned long) addr >= info->regstk_top)
nat_addr = &info->rnat;
+ else
+ nat_addr = ia64_rse_rnat_addr (addr);
nat_mask = 1UL << ia64_rse_slot_num (addr);
break;
}
@@ -1560,9 +1639,10 @@ unw_access_gr (struct _Unwind_Context *info, int regnum,
{
/* Access a stacked register. */
addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32);
- nat_addr = ia64_rse_rnat_addr (addr);
- if ((unsigned long) nat_addr >= info->regstk_top)
+ if ((unsigned long) addr >= info->regstk_top)
nat_addr = &info->rnat;
+ else
+ nat_addr = ia64_rse_rnat_addr (addr);
nat_mask = 1UL << ia64_rse_slot_num (addr);
}
@@ -1703,8 +1783,10 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
an unwind table entry.
This can only happen in the frame after unwinding through a signal
- handler. Avoid infinite looping by requiring that B0 != RP. */
- if (context->br_loc[0] && *context->br_loc[0] != context->rp)
+ handler. Avoid infinite looping by requiring that B0 != RP.
+ RP == 0 terminates the chain. */
+ if (context->br_loc[0] && *context->br_loc[0] != context->rp
+ && context->rp != 0)
{
fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
fs->curr.reg[UNW_REG_RP].when = -1;
@@ -1721,7 +1803,8 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
}
context->region_start = ent->start_offset + segment_base;
- fs->when_target = (context->rp - context->region_start) / 16 * 3;
+ fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3
+ + (context->rp & 15);
unw = (unsigned long *) (ent->info_offset + segment_base);
header = *unw;
@@ -1812,9 +1895,9 @@ uw_update_reg_address (struct _Unwind_Context *context,
case UNW_WHERE_BR:
/* Note that while RVAL can only be 1-5 from normal descriptors,
- we can want to look at B0 due to having manually unwound a
+ we can want to look at B0, B6 and B7 due to having manually unwound a
signal frame. */
- if (rval <= 5)
+ if (rval < 8)
addr = context->br_loc[rval];
else
abort ();
@@ -1928,6 +2011,10 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
long i;
+#ifdef MD_HANDLE_UNWABI
+ MD_HANDLE_UNWABI (context, fs);
+#endif
+
context->sp = context->psp;
/* First, set PSP. Subsequent instructions may depend on this value. */
@@ -1991,18 +2078,31 @@ uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
/* Set psp to the caller's stack pointer. */
void *psp = __builtin_dwarf_cfa () - 16;
_Unwind_FrameState fs;
-
- /* Flush the register stack to memory so that we can access it. */
- __builtin_ia64_flushrs ();
+ unsigned long rnat, tmp1, tmp2;
+
+ /* Flush the register stack to memory so that we can access it.
+ Get rse nat collection for the last incomplete rbs chunk of
+ registers at the same time. For this RSE needs to be turned
+ into the mandatory only mode. */
+ asm ("mov.m %1 = ar.rsc;;\n\t"
+ "and %2 = 0x1c, %1;;\n\t"
+ "mov.m ar.rsc = %2;;\n\t"
+ "flushrs;;\n\t"
+ "mov.m %0 = ar.rnat;;\n\t"
+ "mov.m ar.rsc = %1\n\t"
+ : "=r" (rnat), "=r" (tmp1), "=r" (tmp2));
memset (context, 0, sizeof (struct _Unwind_Context));
- context->bsp = context->regstk_top = (unsigned long) bsp;
+ context->bsp = (unsigned long) bsp;
+ /* Set context->regstk_top to lowest rbs address which will use
+ context->rnat collection. */
+ context->regstk_top = context->bsp & ~0x1ffULL;
+ context->rnat = rnat;
context->psp = (unsigned long) psp;
context->rp = (unsigned long) rp;
asm ("mov %0 = sp" : "=r" (context->sp));
asm ("mov %0 = pr" : "=r" (context->pr));
context->pri_unat_loc = &context->initial_unat; /* ??? */
- /* ??? Get rnat. Don't we have to turn off the rse for that? */
if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
abort ();
@@ -2043,6 +2143,9 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
ia64_rse_skip_regs ((unsigned long *)target->bsp,
(*target->pfs_loc >> 7) & 0x7f);
+ if (target->bsp < target->regstk_top)
+ target->rnat = *ia64_rse_rnat_addr ((unsigned long *) target->bsp);
+
/* Provide assembly with the offsets into the _Unwind_Context. */
asm volatile ("uc_rnat = %0"
: : "i"(offsetof (struct _Unwind_Context, rnat)));
@@ -2079,22 +2182,22 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
";; \n\t"
"(p6) ld8.fill r4 = [%1] \n\t"
"(p7) ld8.fill r5 = [r20] \n\t"
- "add r21 = uc_br_loc + 8, %0 \n\t"
+ "add r21 = uc_br_loc + 16, %0 \n\t"
"adds %1 = 16, %1 \n\t"
"adds r20 = 16, r20 \n\t"
";; \n\t"
"(p8) ld8.fill r6 = [%1] \n\t"
"(p9) ld8.fill r7 = [r20] \n\t"
- "add r20 = uc_br_loc, %0 \n\t"
+ "add r20 = uc_br_loc + 8, %0 \n\t"
";; \n\t"
/* Load up call-saved branch registers. */
"ld8 r22 = [r20], 16 \n\t"
"ld8 r23 = [r21], 16 \n\t"
";; \n\t"
"ld8 r24 = [r20], 16 \n\t"
- "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 24)\n\t"
+ "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t"
";; \n\t"
- "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 32)\n\t"
+ "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t"
"ld8 r27 = [r21], 24 \n\t"
"cmp.ne p6, p0 = r0, r22 \n\t"
";; \n\t"
@@ -2242,12 +2345,12 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
"(p9) mov.i ar.lc = r29 \n\t"
";; \n\t"
"mov.m r25 = ar.rsc \n\t"
- "(p6) mov.i ar.fpsr = r30 \n\t"
+ "(p6) mov.m ar.fpsr = r30 \n\t"
";; \n\t"
- "and r25 = 0x1c, r25 \n\t"
+ "and r29 = 0x1c, r25 \n\t"
"mov b0 = r26 \n\t"
";; \n\t"
- "mov.m ar.rsc = r25 \n\t"
+ "mov.m ar.rsc = r29 \n\t"
";; \n\t"
/* This must be done before setting AR.BSPSTORE, otherwise
AR.BSP will be initialized with a random displacement
@@ -2258,7 +2361,6 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
";; \n\t"
"mov.m ar.bspstore = r23 \n\t"
";; \n\t"
- "or r25 = 0x3, r25 \n\t"
"mov.m ar.rnat = r22 \n\t"
";; \n\t"
"mov.m ar.rsc = r25 \n\t"
diff --git a/contrib/gcc/config/ia64/unwind-ia64.h b/contrib/gcc/config/ia64/unwind-ia64.h
index a6b850d..b56b38c 100644
--- a/contrib/gcc/config/ia64/unwind-ia64.h
+++ b/contrib/gcc/config/ia64/unwind-ia64.h
@@ -2,20 +2,20 @@
Contributed by Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/interix.h b/contrib/gcc/config/interix.h
index 8d9f58f..9d05f1b 100644
--- a/contrib/gcc/config/interix.h
+++ b/contrib/gcc/config/interix.h
@@ -5,20 +5,20 @@
Modified from code
Contributed by Douglas B. Rupp (drupp@cs.washington.edu).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -70,19 +70,6 @@ for windows/multi thread */
&& strcmp (STR, "Tbss"))
-#if 0
-/* don't do this until we can sort out the default path issues. MK */
-#undef STANDARD_EXEC_PREFIX
-#define STANDARD_EXEC_PREFIX ""
-
-#undef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX ""
-
-#undef TOOLDIR_BASE_PREFIX
-#define TOOLDIR_BASE_PREFIX ""
-
-#endif /* 0 */
-
#define STDC_0_IN_SYSTEM_HEADERS 1
#define HANDLE_SYSV_PRAGMA 1
diff --git a/contrib/gcc/config/interix3.h b/contrib/gcc/config/interix3.h
index 4d4e85c..9e2cc35 100644
--- a/contrib/gcc/config/interix3.h
+++ b/contrib/gcc/config/interix3.h
@@ -3,20 +3,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/kaos.h b/contrib/gcc/config/kaos.h
new file mode 100644
index 0000000..45938da
--- /dev/null
+++ b/contrib/gcc/config/kaos.h
@@ -0,0 +1,31 @@
+/* Definitions of target machine for GCC.
+ common kaOS definitions for all architectures.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Specify predefined symbols in preprocessor. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__kaOS__"); \
+ } while (0)
+
+
+/* do not link any library implicitly for kaOS target. */
+#undef LIB_SPEC
+#define LIB_SPEC ""
diff --git a/contrib/gcc/config/kfreebsdgnu.h b/contrib/gcc/config/kfreebsdgnu.h
new file mode 100644
index 0000000..ad8d68c
--- /dev/null
+++ b/contrib/gcc/config/kfreebsdgnu.h
@@ -0,0 +1,41 @@
+/* Definitions for GNU/KFreeBSD systems with ELF format.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Bruno Haible.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ builtin_define ("__GNU_KFreeBSD__=0"); \
+ builtin_define ("__gnu_kfreebsd__=0"); \
+ builtin_define ("__FreeBSD_kernel__=5"); \
+ builtin_define ("__ELF__"); \
+ builtin_define_std ("unix"); \
+ builtin_assert ("system=posix");
+
+#undef TARGET_CPU_CPP_BUILTINS
+#define TARGET_CPU_CPP_BUILTINS() \
+ builtin_define ("__i386__"); \
+ builtin_define_std ("i386"); \
+ builtin_assert ("cpu=i386"); \
+ builtin_assert ("machine=i386");
+
+/* do {} while (0) */
diff --git a/contrib/gcc/config/libgloss.h b/contrib/gcc/config/libgloss.h
index f73982b..3f9bf6c 100644
--- a/contrib/gcc/config/libgloss.h
+++ b/contrib/gcc/config/libgloss.h
@@ -2,20 +2,20 @@
targeting GCC for Libgloss supported targets.
Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/linux-aout.h b/contrib/gcc/config/linux-aout.h
index 13d9bfd6..5701fd9 100644
--- a/contrib/gcc/config/linux-aout.h
+++ b/contrib/gcc/config/linux-aout.h
@@ -1,35 +1,27 @@
-/* Definitions for Linux-based GNU systems.
+/* Definitions for Linux-based GNU systems with a.out binaries.
Copyright (C) 1995, 1997, 1999, 2000 Free Software Foundation, Inc.
Contributed by H.J. Lu (hjl@nynexst.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
- For now, we play safe. It may change later. */
-
-#if 0
-#undef MULTIBYTE_CHARS
-#define MULTIBYTE_CHARS 1
-#endif
-
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} %{static:-static}"
diff --git a/contrib/gcc/config/linux.h b/contrib/gcc/config/linux.h
index 297fa92..0f7ba17 100644
--- a/contrib/gcc/config/linux.h
+++ b/contrib/gcc/config/linux.h
@@ -1,36 +1,29 @@
/* Definitions for Linux-based GNU systems with ELF format
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
- For now, we play safe. It may change later. */
-
-#if 0
-#undef MULTIBYTE_CHARS
-#define MULTIBYTE_CHARS 1
-#endif
-
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
@@ -53,14 +46,14 @@ Boston, MA 02111-1307, USA. */
%{!p:%{profile:gcrt1.o%s} \
%{!profile:crt1.o%s}}}} \
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#elif defined HAVE_LD_PIE
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
- %{!p:%{profile:gcrt1.o%s} \
- %{!profile:crt1.o%s}}}} \
- crti.o%s %{static:crtbeginT.o%s}\
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
@@ -71,7 +64,7 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
- "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+ "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* This is for -profile to use -lc_p instead of -lc. */
#ifndef CC1_SPEC
@@ -104,14 +97,30 @@ Boston, MA 02111-1307, USA. */
%{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}"
#endif
+#define LINUX_TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__gnu_linux__"); \
+ builtin_define_std ("linux"); \
+ builtin_define_std ("unix"); \
+ builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } while (0)
+
#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
+/* Define this so we can compile MS code for use with WINE. */
+#define HANDLE_PRAGMA_PACK_PUSH_POP
+
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
-/* Define this so we can compile MS code for use with WINE. */
-#define HANDLE_PRAGMA_PACK_PUSH_POP
+/* Determine whether the the entire c99 runtime
+ is present in the runtime library. */
+#ifndef USE_GNULIBC_1
+#define TARGET_C99_FUNCTIONS 1
+#endif
#define TARGET_HAS_F_SETLKW
diff --git a/contrib/gcc/config/lynx-ng.h b/contrib/gcc/config/lynx-ng.h
index 7c257c7..c23ad39 100644
--- a/contrib/gcc/config/lynx-ng.h
+++ b/contrib/gcc/config/lynx-ng.h
@@ -1,20 +1,20 @@
/* Target independent definitions for LynxOS, using Lynx's old as and ld.
Copyright (C) 1993, 1999 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/lynx.h b/contrib/gcc/config/lynx.h
index e060675..a2366d1 100644
--- a/contrib/gcc/config/lynx.h
+++ b/contrib/gcc/config/lynx.h
@@ -1,28 +1,25 @@
-/* Target independent definitions for LynxOS.
- Copyright (C) 1993, 1994, 1995, 1996, 1999, 2000, 2002
+/* Target independent definitions for LynxOS using gas and gnu ld.
+ Copyright (C) 1993, 1994, 1995, 1996, 1999, 2000, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* LynxOS is a multi-platform Unix, similar to SVR3, but not identical.
- We can get quite a bit from generic svr3, but have to do some overrides. */
-
-#include "svr3.h"
+/* LynxOS is a multi-platform Unix, similar to SVR3, but not identical. */
/* Define various macros, depending on the combination of flags. */
@@ -84,14 +81,12 @@ Boston, MA 02111-1307, USA. */
"\t.text\n\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO)
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
- { static int sym_lineno = 1; \
- fprintf (file, ".stabn 68,0,%d,.LM%d-", \
- line, sym_lineno); \
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
+ { fprintf (file, ".stabn 68,0,%d,.LM%d-", \
+ line, counter); \
assemble_name (file, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
- fprintf (file, "\n.LM%d:\n", sym_lineno); \
- sym_lineno += 1; }
+ fprintf (file, "\n.LM%d:\n", counter); }
/* Handle #pragma pack and sometimes #pragma weak. */
diff --git a/contrib/gcc/config/netbsd-aout.h b/contrib/gcc/config/netbsd-aout.h
index 7c2f865..53e6570 100644
--- a/contrib/gcc/config/netbsd-aout.h
+++ b/contrib/gcc/config/netbsd-aout.h
@@ -2,20 +2,20 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -39,7 +39,9 @@ Boston, MA 02111-1307, USA. */
with the options for generating PIC code. */
#undef ASM_SPEC
-#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k -K}"
+#define ASM_SPEC "%{fpic|fpie:-k} %{fPIC|fPIE:-k -K}"
+
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
/* Provide a STARTFILE_SPEC appropriate for NetBSD a.out. Here we
diff --git a/contrib/gcc/config/netbsd-elf.h b/contrib/gcc/config/netbsd-elf.h
index cb38b93..a87699c 100644
--- a/contrib/gcc/config/netbsd-elf.h
+++ b/contrib/gcc/config/netbsd-elf.h
@@ -2,20 +2,20 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
NETBSD_OS_CPP_BUILTINS_COMMON(); \
- builtin_define ("__ELF__"); \
} \
while (0)
diff --git a/contrib/gcc/config/netbsd.h b/contrib/gcc/config/netbsd.h
index 0441389..121dda2 100644
--- a/contrib/gcc/config/netbsd.h
+++ b/contrib/gcc/config/netbsd.h
@@ -2,20 +2,20 @@
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -29,14 +29,6 @@ Boston, MA 02111-1307, USA. */
} \
while (0)
-/* TARGET_OS_CPP_BUILTINS() common to all LP64 NetBSD targets. */
-#define NETBSD_OS_CPP_BUILTINS_LP64() \
- do \
- { \
- builtin_define ("_LP64"); \
- } \
- while (0)
-
/* CPP_SPEC parts common to all NetBSD targets. */
#define NETBSD_CPP_SPEC \
"%{posix:-D_POSIX_SOURCE} \
@@ -189,7 +181,7 @@ Boston, MA 02111-1307, USA. */
/* Attempt to turn on execute permission for the stack. This may be
- used by TRANSFER_FROM_TRAMPOLINE of the target needs it (that is,
+ used by INITIALIZE_TRAMPOLINE of the target needs it (that is,
if the target machine can change execute permissions on a page).
There is no way to query the execute permission of the stack, so
@@ -204,8 +196,7 @@ Boston, MA 02111-1307, USA. */
#define NETBSD_ENABLE_EXECUTE_STACK \
extern void __enable_execute_stack (void *); \
void \
-__enable_execute_stack (addr) \
- void *addr; \
+__enable_execute_stack (void *addr) \
{ \
extern int mprotect (void *, size_t, int); \
extern int __sysctl (int *, unsigned int, void *, size_t *, \
diff --git a/contrib/gcc/config/openbsd-oldgas.h b/contrib/gcc/config/openbsd-oldgas.h
index 823db70..423a15c 100644
--- a/contrib/gcc/config/openbsd-oldgas.h
+++ b/contrib/gcc/config/openbsd-oldgas.h
@@ -2,20 +2,20 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/openbsd.h b/contrib/gcc/config/openbsd.h
index 1c215eb..670a0a0 100644
--- a/contrib/gcc/config/openbsd.h
+++ b/contrib/gcc/config/openbsd.h
@@ -1,20 +1,20 @@
/* Base configuration file for all OpenBSD targets.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -106,16 +106,12 @@ Boston, MA 02111-1307, USA. */
still uses a special flavor of gas that needs to be told when generating
pic code. */
#undef ASM_SPEC
-#define ASM_SPEC "%{fpic:-k} %{fPIC:-k -K} %|"
-
-#else
-/* Since we use gas, stdin -> - is a good idea, but we don't want to
- override native specs just for that. */
-#ifndef ASM_SPEC
-#define ASM_SPEC "%|"
-#endif
+#define ASM_SPEC "%{fpic|fpie:-k} %{fPIC|fPIE:-k -K}"
#endif
+/* Since we use gas, stdin -> - is a good idea. */
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+
/* LINK_SPEC appropriate for OpenBSD. Support for GCC options
-static, -assert, and -nostdlib. */
#undef LINK_SPEC
@@ -134,9 +130,6 @@ Boston, MA 02111-1307, USA. */
/* Runtime target specification. */
-/* You must redefine CPP_PREDEFINES in any arch specific file. */
-#undef CPP_PREDEFINES
-
/* Implicit calls to library routines. */
/* Use memcpy and memset instead of bcopy and bzero. */
diff --git a/contrib/gcc/config/ptx4.h b/contrib/gcc/config/ptx4.h
index 3d8e527..33e91d1 100644
--- a/contrib/gcc/config/ptx4.h
+++ b/contrib/gcc/config/ptx4.h
@@ -1,25 +1,25 @@
-/* Operating system specific defines to be used when targeting GCC for some
- generic System V Release 4 system.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- Contributed by Ron Guilmette (rfg@monkeys.com).
+/* Operating system specific defines to be used when targeting GCC for
+ Sequent's Dynix/ptx v4 and later.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Generic SysV4 file Contributed by Ron Guilmette (rfg@monkeys.com).
Renamed and changed to suit Dynix/ptx v4 and later.
Modified by Tim Wright (timw@sequent.com).
Modified by Janis Johnson (janis@us.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
@@ -28,11 +28,12 @@ Boston, MA 02111-1307, USA.
/* Define a symbol indicating that we are using svr4.h. */
#define USING_SVR4_H
-/* Use DWARF debugging info by default. */
+/* Use DWARF 2 debugging info by default. */
#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+#define DWARF2_DEBUGGING_INFO 1
/* Cpp, assembler, linker, library, and startfile spec's. */
@@ -62,12 +63,6 @@ Boston, MA 02111-1307, USA.
&& strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \
&& strcmp (STR, "Tbss"))
-/* You should redefine CPP_PREDEFINES in any file which includes this one.
- The definition should be appropriate for the type of target system
- involved, and it should include any -A (assertion) options which are
- appropriate for the given target system. */
-#undef CPP_PREDEFINES
-
/* Provide an ASM_SPEC appropriate for svr4. Here we try to support as
many of the specialized svr4 assembler options as seems reasonable,
given that there are certain options which we can't (or shouldn't)
@@ -93,16 +88,7 @@ Boston, MA 02111-1307, USA.
"-no_0f_fix -no_eflags_chk %{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
#endif
-/* svr4 assemblers need the `-' (indicating input from stdin) to come after
- the -o option (and its argument) for some reason. If we try to put it
- before the -o option, the assembler will try to read the file named as
- the output file in the -o option as an input file (after it has already
- written some stuff to it) and the binary stuff contained therein will
- cause totally confuse the assembler, resulting in many spurious error
- messages. */
-
-#undef ASM_FINAL_SPEC
-#define ASM_FINAL_SPEC "%{pipe:-}"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
/* Provide a LIB_SPEC appropriate for svr4. Here we tack on the default
standard C library (unless we are building a shared library). */
@@ -199,16 +185,14 @@ Boston, MA 02111-1307, USA.
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
do \
{ \
- static int sym_lineno = 1; \
fprintf (file, ".stabn 68,0,%d,.LM%d-", \
- line, sym_lineno); \
+ line, counter); \
assemble_name (file, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
- fprintf (file, "\n.LM%d:\n", sym_lineno); \
- sym_lineno += 1; \
+ fprintf (file, "\n.LM%d:\n", counter); \
} \
while (0)
@@ -246,5 +230,6 @@ while (0)
do { \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u\n", (SIZE)); \
+ fprintf ((FILE), ",%lu\n", (unsigned long)(SIZE)); \
} while (0)
+
diff --git a/contrib/gcc/config/rs6000/40x.md b/contrib/gcc/config/rs6000/40x.md
new file mode 100644
index 0000000..9d229b4
--- /dev/null
+++ b/contrib/gcc/config/rs6000/40x.md
@@ -0,0 +1,107 @@
+;; Scheduling description for IBM PowerPC 403 and PowerPC 405 processors.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc40x")
+(define_cpu_unit "iu_40x,bpu_40x,fpu_405" "ppc40x")
+
+;; PPC401 / PPC403 / PPC405 32-bit integer only IU BPU
+;; Embedded PowerPC controller
+;; In-order execution
+;; Max issue two insns/cycle (includes one branch)
+(define_insn_reservation "ppc403-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x,nothing,bpu_40x")
+
+(define_insn_reservation "ppc403-imul" 4
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc403"))
+ "iu_40x*4")
+
+(define_insn_reservation "ppc405-imul" 5
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc405"))
+ "iu_40x*4")
+
+(define_insn_reservation "ppc405-imul2" 3
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc405"))
+ "iu_40x*2")
+
+(define_insn_reservation "ppc405-imul3" 2
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-idiv" 33
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x*33")
+
+(define_insn_reservation "ppc403-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "bpu_40x")
+
+(define_insn_reservation "ppc403-cr" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "bpu_40x")
+
+(define_insn_reservation "ppc405-float" 11
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,fpcompare,fp,dmul,sdiv,ddiv")
+ (eq_attr "cpu" "ppc405"))
+ "fpu_405*10")
+
diff --git a/contrib/gcc/config/rs6000/440.md b/contrib/gcc/config/rs6000/440.md
new file mode 100644
index 0000000..e98d5be
--- /dev/null
+++ b/contrib/gcc/config/rs6000/440.md
@@ -0,0 +1,120 @@
+;; Scheduling description for IBM PowerPC 440 processor.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; PPC440 Embedded PowerPC controller
+;; dual issue
+;; i_pipe - complex integer / compare / branch
+;; j_pipe - simple integer arithmetic
+;; l_pipe - load-store
+;; f_pipe - floating point arithmetic
+
+(define_automaton "ppc440_core,ppc440_apu")
+(define_cpu_unit "ppc440_i_pipe,ppc440_j_pipe,ppc440_l_pipe" "ppc440_core")
+(define_cpu_unit "ppc440_f_pipe" "ppc440_apu")
+(define_cpu_unit "ppc440_issue_0,ppc440_issue_1" "ppc440_core")
+
+(define_reservation "ppc440_issue" "ppc440_issue_0|ppc440_issue_1")
+
+
+(define_insn_reservation "ppc440-load" 3
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-fpload" 4
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-fpstore" 3
+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe|ppc440_j_pipe")
+
+(define_insn_reservation "ppc440-imul" 3
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-imul2" 2
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-idiv" 34
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe*33")
+
+(define_insn_reservation "ppc440-branch" 1
+ (and (eq_attr "type" "branch,jmpreg")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-compare" 2
+ (and (eq_attr "type" "cmp,fast_compare,compare,cr_logical,delayed_cr,mfcr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-fpcompare" 3 ; 2
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe+ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-fp" 5
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe")
+
+(define_insn_reservation "ppc440-sdiv" 19
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe*15")
+
+(define_insn_reservation "ppc440-ddiv" 33
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe*29")
+
+(define_insn_reservation "ppc440-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
diff --git a/contrib/gcc/config/rs6000/603.md b/contrib/gcc/config/rs6000/603.md
new file mode 100644
index 0000000..7ae038e
--- /dev/null
+++ b/contrib/gcc/config/rs6000/603.md
@@ -0,0 +1,127 @@
+;; Scheduling description for PowerPC 603 processor.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc603,ppc603fp")
+(define_cpu_unit "iu_603" "ppc603")
+(define_cpu_unit "fpu_603" "ppc603fp")
+(define_cpu_unit "lsu_603,bpu_603,sru_603" "ppc603")
+
+;; PPC603/PPC603e 32-bit IU, LSU, FPU, BPU, SRU
+;; Max issue 3 insns/clock cycle (includes 1 branch)
+
+;; Branches go straight to the BPU. All other insns are handled
+;; by a dispatch unit which can issue a max of 2 insns per cycle.
+
+;; The PPC603e user's manual recommends that to reduce branch mispredictions,
+;; the insn that sets CR bits should be separated from the branch insn
+;; that evaluates them; separation by more than 9 insns ensures that the CR
+;; bits will be immediately available for execution.
+;; This could be artificially achieved by exaggerating the latency of
+;; compare insns but at the expense of a poorer schedule.
+
+;; CR insns get executed in the SRU. Not modelled.
+
+(define_insn_reservation "ppc603-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ux,load_u")
+ (eq_attr "cpu" "ppc603"))
+ "lsu_603")
+
+(define_insn_reservation "ppc603-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc603"))
+ "lsu_603")
+
+(define_insn_reservation "ppc603-fpload" 2
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc603"))
+ "lsu_603")
+
+(define_insn_reservation "ppc603-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603")
+
+; This takes 2 or 3 cycles
+(define_insn_reservation "ppc603-imul" 3
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603*2")
+
+(define_insn_reservation "ppc603-imul2" 2
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603*2")
+
+(define_insn_reservation "ppc603-idiv" 37
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603*37")
+
+(define_insn_reservation "ppc603-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603,nothing,bpu_603")
+
+(define_insn_reservation "ppc603-fpcompare" 3
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc603"))
+ "(fpu_603+iu_603*2),bpu_603")
+
+(define_insn_reservation "ppc603-fp" 3
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603")
+
+(define_insn_reservation "ppc603-dmul" 4
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603*2")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc603-sdiv" 18
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603*18")
+
+(define_insn_reservation "ppc603-ddiv" 33
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603*33")
+
+(define_insn_reservation "ppc603-crlogical" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr,mfcr,mtcr")
+ (eq_attr "cpu" "ppc603"))
+ "sru_603")
+
+(define_insn_reservation "ppc603-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc603"))
+ "sru_603")
+
+(define_insn_reservation "ppc603-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc603"))
+ "sru_603")
+
+(define_insn_reservation "ppc603-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc603"))
+ "bpu_603")
+
diff --git a/contrib/gcc/config/rs6000/6xx.md b/contrib/gcc/config/rs6000/6xx.md
new file mode 100644
index 0000000..d28d373
--- /dev/null
+++ b/contrib/gcc/config/rs6000/6xx.md
@@ -0,0 +1,234 @@
+;; Scheduling description for PowerPC 604, PowerPC 604e, PowerPC 620,
+;; and PowerPC 630 processors.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc6xx,ppc6xxfp,ppc6xxfp2")
+(define_cpu_unit "iu1_6xx,iu2_6xx,mciu_6xx" "ppc6xx")
+(define_cpu_unit "fpu_6xx" "ppc6xxfp")
+(define_cpu_unit "fpu1_6xx,fpu2_6xx" "ppc6xxfp2")
+(define_cpu_unit "lsu_6xx,bpu_6xx,cru_6xx" "ppc6xx")
+
+;; PPC604 32-bit 2xSCIU, MCIU, LSU, FPU, BPU
+;; PPC604e 32-bit 2xSCIU, MCIU, LSU, FPU, BPU, CRU
+;; MCIU used for imul/idiv and moves from/to spr
+;; LSU 2 stage pipelined
+;; FPU 3 stage pipelined
+;; Max issue 4 insns/clock cycle
+
+;; PPC604e is PPC604 with larger caches and a CRU. In the 604
+;; the CR logical operations are handled in the BPU.
+;; In the 604e, the CRU shares bus with BPU so only one condition
+;; register or branch insn can be issued per clock. Not modelled.
+
+;; PPC620 64-bit 2xSCIU, MCIU, LSU, FPU, BPU, CRU
+;; PPC630 64-bit 2xSCIU, MCIU, LSU, 2xFPU, BPU, CRU
+;; Max issue 4 insns/clock cycle
+;; Out-of-order execution, in-order completion
+
+;; No following instruction can dispatch in the same cycle as a branch
+;; instruction. Not modelled. This is no problem if RCSP is not
+;; enabled since the scheduler stops a schedule when it gets to a branch.
+
+;; Four insns can be dispatched per cycle.
+
+(define_insn_reservation "ppc604-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc604-fpload" 3
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc604-store" 1
+ (and (eq_attr "type" "store,fpstore,store_ux,store_u,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc604-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "iu1_6xx|iu2_6xx")
+
+(define_insn_reservation "ppc604-imul" 4
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc604"))
+ "mciu_6xx*2")
+
+(define_insn_reservation "ppc604e-imul" 2
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc604e"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc620-imul" 5
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*3")
+
+(define_insn_reservation "ppc620-imul2" 4
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*3")
+
+(define_insn_reservation "ppc620-imul3" 3
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*3")
+
+(define_insn_reservation "ppc620-lmul" 7
+ (and (eq_attr "type" "lmul,lmul_compare")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*5")
+
+(define_insn_reservation "ppc604-idiv" 20
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc604,ppc604e"))
+ "mciu_6xx*19")
+
+(define_insn_reservation "ppc620-idiv" 37
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc620"))
+ "mciu_6xx*36")
+
+(define_insn_reservation "ppc630-idiv" 21
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc630"))
+ "mciu_6xx*20")
+
+(define_insn_reservation "ppc620-ldiv" 37
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*36")
+
+(define_insn_reservation "ppc604-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "(iu1_6xx|iu2_6xx)")
+
+; FPU PPC604{,e},PPC620
+(define_insn_reservation "ppc604-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx")
+
+(define_insn_reservation "ppc604-fp" 3
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx")
+
+(define_insn_reservation "ppc604-dmul" 3
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc604-sdiv" 18
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx*18")
+
+(define_insn_reservation "ppc604-ddiv" 32
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx*32")
+
+(define_insn_reservation "ppc620-ssqrt" 31
+ (and (eq_attr "type" "ssqrt")
+ (eq_attr "cpu" "ppc620"))
+ "fpu_6xx*31")
+
+(define_insn_reservation "ppc620-dsqrt" 31
+ (and (eq_attr "type" "dsqrt")
+ (eq_attr "cpu" "ppc620"))
+ "fpu_6xx*31")
+
+
+; 2xFPU PPC630
+(define_insn_reservation "ppc630-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx|fpu2_6xx")
+
+(define_insn_reservation "ppc630-fp" 3
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx|fpu2_6xx")
+
+(define_insn_reservation "ppc630-sdiv" 17
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*17|fpu2_6xx*17")
+
+(define_insn_reservation "ppc630-ddiv" 21
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*21|fpu2_6xx*21")
+
+(define_insn_reservation "ppc630-ssqrt" 18
+ (and (eq_attr "type" "ssqrt")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*18|fpu2_6xx*18")
+
+(define_insn_reservation "ppc630-dsqrt" 25
+ (and (eq_attr "type" "dsqrt")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*25|fpu2_6xx*25")
+
+(define_insn_reservation "ppc604-mfcr" 3
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc604-mtcr" 2
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "iu1_6xx|iu2_6xx")
+
+(define_insn_reservation "ppc604-crlogical" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc604"))
+ "bpu_6xx")
+
+(define_insn_reservation "ppc604e-crlogical" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc604e,ppc620,ppc630"))
+ "cru_6xx")
+
+(define_insn_reservation "ppc604-mtjmpr" 2
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc604-mfjmpr" 3
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc630-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc630"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc604-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "bpu_6xx")
+
diff --git a/contrib/gcc/config/rs6000/7450.md b/contrib/gcc/config/rs6000/7450.md
new file mode 100644
index 0000000..55bd4d8
--- /dev/null
+++ b/contrib/gcc/config/rs6000/7450.md
@@ -0,0 +1,162 @@
+;; Scheduling description for Motorola PowerPC 7450 processor.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc7450,ppc7450fp,ppc7450vec")
+(define_cpu_unit "iu1_7450,iu2_7450,iu3_7450,mciu_7450" "ppc7450")
+(define_cpu_unit "fpu_7450" "ppc7450fp")
+(define_cpu_unit "lsu_7450,bpu_7450" "ppc7450")
+(define_cpu_unit "du1_7450,du2_7450,du3_7450" "ppc7450")
+(define_cpu_unit "vecsmpl_7450,veccmplx_7450,vecflt_7450,vecperm_7450" "ppc7450vec")
+(define_cpu_unit "vdu1_7450,vdu2_7450" "ppc7450vec")
+
+
+;; PPC7450 32-bit 3xIU, MCIU, LSU, SRU, FPU, BPU, 4xVEC
+;; IU1,IU2,IU3 can perform all integer operations
+;; MCIU performs imul and idiv, cr logical, SPR moves
+;; LSU 2 stage pipelined
+;; FPU 3 stage pipelined
+;; It also has 4 vector units, one for each type of vector instruction.
+;; However, we can only dispatch 2 instructions per cycle.
+;; Max issue 3 insns/clock cycle (includes 1 branch)
+;; In-order execution
+
+;; Branches go straight to the BPU. All other insns are handled
+;; by a dispatch unit which can issue a max of 3 insns per cycle.
+(define_reservation "ppc7450_du" "du1_7450|du2_7450|du3_7450")
+(define_reservation "ppc7450_vec_du" "vdu1_7450|vdu2_7450")
+
+(define_insn_reservation "ppc7450-load" 3
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
+ load_ux,load_u,vecload")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
+(define_insn_reservation "ppc7450-store" 3
+ (and (eq_attr "type" "store,store_ux,store_u,vecstore")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
+(define_insn_reservation "ppc7450-fpload" 4
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
+(define_insn_reservation "ppc7450-fpstore" 3
+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450*3")
+
+(define_insn_reservation "ppc7450-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,(iu1_7450|iu2_7450|iu3_7450)")
+
+(define_insn_reservation "ppc7450-imul" 4
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450*2")
+
+(define_insn_reservation "ppc7450-imul2" 3
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450")
+
+(define_insn_reservation "ppc7450-idiv" 23
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450*23")
+
+(define_insn_reservation "ppc7450-compare" 2
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,(iu1_7450|iu2_7450|iu3_7450)")
+
+(define_insn_reservation "ppc7450-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450")
+
+(define_insn_reservation "ppc7450-fp" 5
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc7450-sdiv" 21
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450*21")
+
+(define_insn_reservation "ppc7450-ddiv" 35
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450*35")
+
+(define_insn_reservation "ppc7450-mfcr" 2
+ (and (eq_attr "type" "mfcr,mtcr")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450")
+
+(define_insn_reservation "ppc7450-crlogical" 1
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450")
+
+(define_insn_reservation "ppc7450-mtjmpr" 2
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc7450"))
+ "nothing,mciu_7450*2")
+
+(define_insn_reservation "ppc7450-mfjmpr" 3
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc7450"))
+ "nothing,mciu_7450*2")
+
+(define_insn_reservation "ppc7450-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc7450"))
+ "nothing,bpu_7450")
+
+;; Altivec
+(define_insn_reservation "ppc7450-vecsimple" 1
+ (and (eq_attr "type" "vecsimple")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,vecsmpl_7450")
+
+(define_insn_reservation "ppc7450-veccomplex" 4
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,veccmplx_7450")
+
+(define_insn_reservation "ppc7450-veccmp" 2
+ (and (eq_attr "type" "veccmp")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,veccmplx_7450")
+
+(define_insn_reservation "ppc7450-vecfloat" 4
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,vecflt_7450")
+
+(define_insn_reservation "ppc7450-vecperm" 2
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,vecperm_7450")
+
diff --git a/contrib/gcc/config/rs6000/7xx.md b/contrib/gcc/config/rs6000/7xx.md
new file mode 100644
index 0000000..de8a7b7
--- /dev/null
+++ b/contrib/gcc/config/rs6000/7xx.md
@@ -0,0 +1,167 @@
+;; Scheduling description for Motorola PowerPC 750 and PowerPC 7400 processors.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc7xx,ppc7xxfp")
+(define_cpu_unit "iu1_7xx,iu2_7xx" "ppc7xx")
+(define_cpu_unit "fpu_7xx" "ppc7xxfp")
+(define_cpu_unit "lsu_7xx,bpu_7xx,sru_7xx" "ppc7xx")
+(define_cpu_unit "du1_7xx,du2_7xx" "ppc7xx")
+(define_cpu_unit "veccmplx_7xx,vecperm_7xx,vdu_7xx" "ppc7xx")
+
+;; PPC740/PPC750/PPC7400 32-bit 2xIU, LSU, SRU, FPU, BPU
+;; IU1 can perform all integer operations
+;; IU2 can perform all integer operations except imul and idiv
+;; LSU 2 stage pipelined
+;; FPU 3 stage pipelined
+;; Max issue 3 insns/clock cycle (includes 1 branch)
+;; In-order execution
+
+
+;; The PPC750 user's manual recommends that to reduce branch mispredictions,
+;; the insn that sets CR bits should be separated from the branch insn
+;; that evaluates them. There is no advantage have more than 10 cycles
+;; of separation.
+;; This could be artificially achieved by exaggerating the latency of
+;; compare insns but at the expense of a poorer schedule.
+
+;; Branches go straight to the BPU. All other insns are handled
+;; by a dispatch unit which can issue a max of 2 insns per cycle.
+(define_reservation "ppc750_du" "du1_7xx|du2_7xx")
+(define_reservation "ppc7400_vec_du" "vdu_7xx")
+
+(define_insn_reservation "ppc750-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
+ load_ux,load_u,fpload,fpload_ux,fpload_u,vecload")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,lsu_7xx")
+
+(define_insn_reservation "ppc750-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,\
+ fpstore,fpstore_ux,fpstore_u,vecstore")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,lsu_7xx")
+
+(define_insn_reservation "ppc750-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,(iu1_7xx|iu2_7xx)")
+
+(define_insn_reservation "ppc750-imul" 4
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx*4")
+
+(define_insn_reservation "ppc750-imul2" 3
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx*2")
+
+(define_insn_reservation "ppc750-imul3" 2
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx")
+
+(define_insn_reservation "ppc750-idiv" 19
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx*19")
+
+(define_insn_reservation "ppc750-compare" 2
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,(iu1_7xx|iu2_7xx)")
+
+(define_insn_reservation "ppc750-fpcompare" 2
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx")
+
+(define_insn_reservation "ppc750-fp" 3
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx")
+
+(define_insn_reservation "ppc750-dmul" 4
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc750"))
+ "ppc750_du,fpu_7xx*2")
+
+(define_insn_reservation "ppc7400-dmul" 3
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,fpu_7xx")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc750-sdiv" 17
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx*17")
+
+(define_insn_reservation "ppc750-ddiv" 31
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx*31")
+
+(define_insn_reservation "ppc750-mfcr" 2
+ (and (eq_attr "type" "mfcr,mtcr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx")
+
+(define_insn_reservation "ppc750-crlogical" 3
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,sru_7xx*2")
+
+(define_insn_reservation "ppc750-mtjmpr" 2
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "nothing,sru_7xx*2")
+
+(define_insn_reservation "ppc750-mfjmpr" 3
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "nothing,sru_7xx*2")
+
+(define_insn_reservation "ppc750-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "nothing,bpu_7xx")
+
+;; Altivec
+(define_insn_reservation "ppc7400-vecsimple" 1
+ (and (eq_attr "type" "vecsimple,veccmp")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,veccmplx_7xx")
+
+(define_insn_reservation "ppc7400-veccomplex" 4
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,veccmplx_7xx")
+
+(define_insn_reservation "ppc7400-vecfloat" 4
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,veccmplx_7xx")
+
+(define_insn_reservation "ppc7400-vecperm" 2
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,vecperm_7xx")
+
diff --git a/contrib/gcc/config/rs6000/8540.md b/contrib/gcc/config/rs6000/8540.md
new file mode 100644
index 0000000..737c399
--- /dev/null
+++ b/contrib/gcc/config/rs6000/8540.md
@@ -0,0 +1,235 @@
+;; Pipeline description for Motorola PowerPC 8540 processor.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc8540_most,ppc8540_long,ppc8540_retire")
+(define_cpu_unit "ppc8540_decode_0,ppc8540_decode_1" "ppc8540_most")
+
+;; We don't simulate general issue queue (GIC). If we have SU insn
+;; and then SU1 insn, they can not be issued on the same cycle
+;; (although SU1 insn and then SU insn can be issued) because the SU
+;; insn will go to SU1 from GIC0 entry. Fortunately, the first cycle
+;; multipass insn scheduling will find the situation and issue the SU1
+;; insn and then the SU insn.
+(define_cpu_unit "ppc8540_issue_0,ppc8540_issue_1" "ppc8540_most")
+
+;; We could describe completion buffers slots in combination with the
+;; retirement units and the order of completion but the result
+;; automaton would behave in the same way because we can not describe
+;; real latency time with taking in order completion into account.
+;; Actually we could define the real latency time by querying reserved
+;; automaton units but the current scheduler uses latency time before
+;; issuing insns and making any reservations.
+;;
+;; So our description is aimed to achieve a insn schedule in which the
+;; insns would not wait in the completion buffer.
+(define_cpu_unit "ppc8540_retire_0,ppc8540_retire_1" "ppc8540_retire")
+
+;; Branch unit:
+(define_cpu_unit "ppc8540_bu" "ppc8540_most")
+
+;; SU:
+(define_cpu_unit "ppc8540_su0_stage0,ppc8540_su1_stage0" "ppc8540_most")
+
+;; We could describe here MU subunits for float multiply, float add
+;; etc. But the result automaton would behave the same way as the
+;; described one pipeline below because MU can start only one insn
+;; per cycle. Actually we could simplify the automaton more not
+;; describing stages 1-3, the result automata would be the same.
+(define_cpu_unit "ppc8540_mu_stage0,ppc8540_mu_stage1" "ppc8540_most")
+(define_cpu_unit "ppc8540_mu_stage2,ppc8540_mu_stage3" "ppc8540_most")
+
+;; The following unit is used to describe non-pipelined division.
+(define_cpu_unit "ppc8540_mu_div" "ppc8540_long")
+
+;; Here we simplified LSU unit description not describing the stages.
+(define_cpu_unit "ppc8540_lsu" "ppc8540_most")
+
+;; The following units are used to make automata deterministic
+(define_cpu_unit "present_ppc8540_decode_0" "ppc8540_most")
+(define_cpu_unit "present_ppc8540_issue_0" "ppc8540_most")
+(define_cpu_unit "present_ppc8540_retire_0" "ppc8540_retire")
+(define_cpu_unit "present_ppc8540_su0_stage0" "ppc8540_most")
+
+;; The following sets to make automata deterministic when option ndfa is used.
+(presence_set "present_ppc8540_decode_0" "ppc8540_decode_0")
+(presence_set "present_ppc8540_issue_0" "ppc8540_issue_0")
+(presence_set "present_ppc8540_retire_0" "ppc8540_retire_0")
+(presence_set "present_ppc8540_su0_stage0" "ppc8540_su0_stage0")
+
+;; Some useful abbreviations.
+(define_reservation "ppc8540_decode"
+ "ppc8540_decode_0|ppc8540_decode_1+present_ppc8540_decode_0")
+(define_reservation "ppc8540_issue"
+ "ppc8540_issue_0|ppc8540_issue_1+present_ppc8540_issue_0")
+(define_reservation "ppc8540_retire"
+ "ppc8540_retire_0|ppc8540_retire_1+present_ppc8540_retire_0")
+(define_reservation "ppc8540_su_stage0"
+ "ppc8540_su0_stage0|ppc8540_su1_stage0+present_ppc8540_su0_stage0")
+
+;; Simple SU insns
+(define_insn_reservation "ppc8540_su" 1
+ (and (eq_attr "type" "integer,insert_word,cmp,compare,delayed_compare,fast_compare")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Branch. Actually this latency time is not used by the scheduler.
+(define_insn_reservation "ppc8540_branch" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_bu,ppc8540_retire")
+
+;; Multiply
+(define_insn_reservation "ppc8540_multiply" 4
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; Divide. We use the average latency time here. We omit reserving a
+;; retire unit because of the result automata will be huge. We ignore
+;; reservation of miu_stage3 here because we use the average latency
+;; time.
+(define_insn_reservation "ppc8540_divide" 14
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
+ ppc8540_mu_div*13")
+
+;; CR logical
+(define_insn_reservation "ppc8540_cr_logical" 1
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_bu,ppc8540_retire")
+
+;; Mfcr
+(define_insn_reservation "ppc8540_mfcr" 1
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Mtcrf
+(define_insn_reservation "ppc8540_mtcrf" 1
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Mtjmpr
+(define_insn_reservation "ppc8540_mtjmpr" 1
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Loads
+(define_insn_reservation "ppc8540_load" 3
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
+
+;; Stores.
+(define_insn_reservation "ppc8540_store" 3
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
+
+;; Simple FP
+(define_insn_reservation "ppc8540_simple_float" 1
+ (and (eq_attr "type" "fpsimple")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; FP
+(define_insn_reservation "ppc8540_float" 4
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; float divides. We omit reserving a retire unit and miu_stage3
+;; because of the result automata will be huge.
+(define_insn_reservation "ppc8540_float_vector_divide" 29
+ (and (eq_attr "type" "vecfdiv")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
+ ppc8540_mu_div*28")
+
+;; Brinc
+(define_insn_reservation "ppc8540_brinc" 1
+ (and (eq_attr "type" "brinc")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Simple vector
+(define_insn_reservation "ppc8540_simple_vector" 1
+ (and (eq_attr "type" "vecsimple")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Simple vector compare
+(define_insn_reservation "ppc8540_simple_vector_compare" 1
+ (and (eq_attr "type" "veccmpsimple")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Vector compare
+(define_insn_reservation "ppc8540_vector_compare" 1
+ (and (eq_attr "type" "veccmp")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; evsplatfi evsplati
+(define_insn_reservation "ppc8540_vector_perm" 1
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Vector float
+(define_insn_reservation "ppc8540_float_vector" 4
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; Vector divides: Use the average. We omit reserving a retire unit
+;; because of the result automata will be huge. We ignore reservation
+;; of miu_stage3 here because we use the average latency time.
+(define_insn_reservation "ppc8540_vector_divide" 14
+ (and (eq_attr "type" "vecdiv")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
+ ppc8540_mu_div*13")
+
+;; Complex vector.
+(define_insn_reservation "ppc8540_complex_vector" 4
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; Vector load
+(define_insn_reservation "ppc8540_vector_load" 3
+ (and (eq_attr "type" "vecload")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
+
+;; Vector store
+(define_insn_reservation "ppc8540_vector_store" 3
+ (and (eq_attr "type" "vecstore")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
diff --git a/contrib/gcc/config/rs6000/aix.h b/contrib/gcc/config/rs6000/aix.h
index 505d758..f189407 100644
--- a/contrib/gcc/config/rs6000/aix.h
+++ b/contrib/gcc/config/rs6000/aix.h
@@ -1,23 +1,23 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Yes! We are AIX! */
#define DEFAULT_ABI ABI_AIX
@@ -87,8 +87,8 @@ Boston, MA 02111-1307, USA. */
Don't do this until the fixed IBM assembler is more generally available.
When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL,
ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no
- longer be needed. Also, the extern declaration of mcount in ASM_FILE_START
- will no longer be needed. */
+ longer be needed. Also, the extern declaration of mcount in
+ rs6000_xcoff_file_start will no longer be needed. */
/* #define ASM_SPEC "-u %(asm_cpu)" */
@@ -128,24 +128,48 @@ Boston, MA 02111-1307, USA. */
#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
%{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
+/* This now supports a natural alignment mode. */
/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
(TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
? get_inner_array_type (FIELD) \
: TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED))
+ ? MIN ((COMPUTED), 32) : (COMPUTED)))
/* AIX increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0 \
+ ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
: MAX ((COMPUTED), (SPECIFIED)))
+/* The AIX ABI isn't explicit on whether aggregates smaller than a
+ word/doubleword should be padded upward or downward. One could
+ reasonably assume that they follow the normal rules for structure
+ layout treating the parameter area as any other block of memory,
+ then map the reg param area to registers, i.e., pad upward, which
+ is the way IBM Compilers for AIX behave.
+ Setting both of the following defines results in this behavior. */
+#define AGGREGATE_PADDING_FIXED 1
+#define AGGREGATES_PAD_UPWARD_ALWAYS 1
+
+/* We don't want anything in the reg parm area being passed on the
+ stack. */
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE)))
+
+/* Specify padding for the last element of a block move between
+ registers and memory. FIRST is nonzero if this is the only
+ element. */
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
+
/* Indicate that jump tables go in the text section. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
@@ -172,41 +196,51 @@ Boston, MA 02111-1307, USA. */
/* Define cutoff for using external functions to save floating point. */
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
-/* Optabs entries for the int->float routines and quad FP operations
- using the standard AIX names. */
-#define ADDTF3_LIBCALL "_xlqadd"
-#define DIVTF3_LIBCALL "_xlqdiv"
-#define MULTF3_LIBCALL "_xlqmul"
-#define SUBTF3_LIBCALL "_xlqsub"
+/* __throw will restore its own return address to be the same as the
+ return address of the function that the throw is being made to.
+ This is unfortunate, because we want to check the original
+ return address to see if we need to restore the TOC.
+ So we have to squirrel it away with this. */
+#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+
+/* If the current unwind info (FS) does not contain explicit info
+ saving R2, then we have to do a minor amount of code reading to
+ figure out if it was saved. The big problem here is that the
+ code that does the save/restore is generated by the linker, so
+ we have no good way to determine at compile time what to do. */
-#define INIT_TARGET_OPTABS \
+#ifdef __powerpc64__
+#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
do { \
- if (! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT) \
+ if ((FS)->regs.reg[2].how == REG_UNSAVED) \
{ \
- fixdfsi_libfunc = init_one_libfunc (RS6000_ITRUNC); \
- fixunsdfsi_libfunc = init_one_libfunc (RS6000_UITRUNC); \
+ unsigned int *insn \
+ = (unsigned int *) \
+ _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
+ if (*insn == 0xE8410028) \
+ _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
} \
- if (TARGET_HARD_FLOAT) \
+ } while (0)
+#else
+#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
+ do { \
+ if ((FS)->regs.reg[2].how == REG_UNSAVED) \
{ \
- add_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (ADDTF3_LIBCALL); \
- sub_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SUBTF3_LIBCALL); \
- smul_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (MULTF3_LIBCALL); \
- sdiv_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (DIVTF3_LIBCALL); \
+ unsigned int *insn \
+ = (unsigned int *) \
+ _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
+ if (*insn == 0x80410014) \
+ _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 20); \
} \
} while (0)
-
-/* __throw will restore its own return address to be the same as the
- return address of the function that the throw is being made to.
- This is unfortunate, because we want to check the original
- return address to see if we need to restore the TOC.
- So we have to squirrel it away with this. */
-#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+#endif
#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
/* Print subsidiary information on the compiler version in use. */
#define TARGET_VERSION ;
+
+/* No version of AIX fully supports AltiVec or 64-bit instructions in
+ 32-bit mode. */
+#define OS_MISSING_POWERPC64 1
+#define OS_MISSING_ALTIVEC 1
diff --git a/contrib/gcc/config/rs6000/aix41.h b/contrib/gcc/config/rs6000/aix41.h
index 7f23a48..373c10c 100644
--- a/contrib/gcc/config/rs6000/aix41.h
+++ b/contrib/gcc/config/rs6000/aix41.h
@@ -1,26 +1,25 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX version 4.1.
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef SUBSUBTARGET_SWITCHES
#define SUBSUBTARGET_SWITCHES \
diff --git a/contrib/gcc/config/rs6000/aix43.h b/contrib/gcc/config/rs6000/aix43.h
index bcbfcf2..a76e694 100644
--- a/contrib/gcc/config/rs6000/aix43.h
+++ b/contrib/gcc/config/rs6000/aix43.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX version 4.3.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* AIX 4.3 and above support 64-bit executables. */
#undef SUBSUBTARGET_SWITCHES
@@ -60,9 +59,9 @@ do { \
} while (0);
#undef ASM_SPEC
-#define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)"
+#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
-/* Common ASM definitions used by ASM_SPEC amonst the various targets
+/* Common ASM definitions used by ASM_SPEC amongst the various targets
for handling -mcpu=xxx switches. */
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC \
@@ -75,8 +74,8 @@ do { \
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwr2} \
-%{mcpu=power3: -m604} \
-%{mcpu=power4: -m604} \
+%{mcpu=power3: -m620} \
+%{mcpu=power4: -m620} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
@@ -90,8 +89,8 @@ do { \
%{mcpu=603e: -m603} \
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604}"
+%{mcpu=620: -m620} \
+%{mcpu=630: -m620}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
diff --git a/contrib/gcc/config/rs6000/aix51.h b/contrib/gcc/config/rs6000/aix51.h
index 552394e..278b6a4 100644
--- a/contrib/gcc/config/rs6000/aix51.h
+++ b/contrib/gcc/config/rs6000/aix51.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX V5.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* AIX V5 and above support 64-bit executables. */
#undef SUBSUBTARGET_SWITCHES
@@ -60,9 +59,9 @@ do { \
} while (0);
#undef ASM_SPEC
-#define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)"
+#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
-/* Common ASM definitions used by ASM_SPEC amonst the various targets
+/* Common ASM definitions used by ASM_SPEC amongst the various targets
for handling -mcpu=xxx switches. */
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC \
@@ -75,8 +74,8 @@ do { \
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwr2} \
-%{mcpu=power3: -m604} \
-%{mcpu=power4: -m604} \
+%{mcpu=power3: -m620} \
+%{mcpu=power4: -m620} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
@@ -90,8 +89,8 @@ do { \
%{mcpu=603e: -m603} \
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604}"
+%{mcpu=620: -m620} \
+%{mcpu=630: -m620}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
@@ -197,3 +196,8 @@ do { \
#undef LD_INIT_SWITCH
#define LD_INIT_SWITCH "-binitfini"
+
+/* AIX 5.1 has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
diff --git a/contrib/gcc/config/rs6000/aix52.h b/contrib/gcc/config/rs6000/aix52.h
index b61cc30..c066650 100644
--- a/contrib/gcc/config/rs6000/aix52.h
+++ b/contrib/gcc/config/rs6000/aix52.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX V5.2.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* AIX V5 and above support 64-bit executables. */
#undef SUBSUBTARGET_SWITCHES
@@ -60,25 +59,25 @@ do { \
} while (0);
#undef ASM_SPEC
-#define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)"
+#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
-/* Common ASM definitions used by ASM_SPEC amonst the various targets
+/* Common ASM definitions used by ASM_SPEC amongst the various targets
for handling -mcpu=xxx switches. */
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC \
"%{!mcpu*: %{!maix64: \
%{mpowerpc64: -mppc64} \
%{!mpower64: %(asm_default)}}} \
-%{mcpu=power3: -m604} \
-%{mcpu=power4: -m604} \
+%{mcpu=power3: -m620} \
+%{mcpu=power4: -m620} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rs64a: -mppc} \
%{mcpu=603: -m603} \
%{mcpu=603e: -m603} \
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604}"
+%{mcpu=620: -m620} \
+%{mcpu=630: -m620}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc"
@@ -189,3 +188,8 @@ do { \
#undef LD_INIT_SWITCH
#define LD_INIT_SWITCH "-binitfini"
+
+/* AIX 5.2 has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
diff --git a/contrib/gcc/config/rs6000/altivec-defs.h b/contrib/gcc/config/rs6000/altivec-defs.h
index 123e1c8..4fa1e0d 100644
--- a/contrib/gcc/config/rs6000/altivec-defs.h
+++ b/contrib/gcc/config/rs6000/altivec-defs.h
@@ -1,25 +1,25 @@
/* Target definitions for GNU compiler for PowerPC with AltiVec.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
do { \
rs6000_altivec_abi = 1; \
diff --git a/contrib/gcc/config/rs6000/altivec.h b/contrib/gcc/config/rs6000/altivec.h
index 1e2d8c8..04d120d 100644
--- a/contrib/gcc/config/rs6000/altivec.h
+++ b/contrib/gcc/config/rs6000/altivec.h
@@ -1,23 +1,23 @@
/* PowerPC AltiVec include file.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* As a special exception, if you include this header file into source
files compiled by GCC, this header file does not by itself cause
@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
#define __vector __attribute__((vector_size(16)))
-/* You are allowed to undef this for C++ compatability. */
+/* You are allowed to undef this for C++ compatibility. */
#define vector __vector
#define bool signed
@@ -118,6 +118,8 @@ extern int __altivec_link_error_invalid_argument ();
#ifdef __cplusplus
+extern "C++" {
+
/* Prototypes for builtins that take literals and must always be
inlined. */
inline vector float vec_ctf (vector unsigned int, const char) __attribute__ ((always_inline));
@@ -1094,7 +1096,7 @@ vec_vcmpgtub (vector unsigned char a1, vector unsigned char a2)
inline vector signed int
vec_cmple (vector float a1, vector float a2)
{
- return (vector signed int) __builtin_altivec_vcmpgefp ((vector float) a1, (vector float) a2);
+ return (vector signed int) __builtin_altivec_vcmpgefp ((vector float) a2, (vector float) a1);
}
/* vec_cmplt */
@@ -1198,7 +1200,7 @@ vec_dss (const char a1)
/* vec_dssall */
inline void
-vec_dssall ()
+vec_dssall (void)
{
__builtin_altivec_dssall ();
}
@@ -2419,7 +2421,7 @@ vec_vmrglb (vector unsigned char a1, vector unsigned char a2)
/* vec_mfvscr */
inline vector unsigned short
-vec_mfvscr ()
+vec_mfvscr (void)
{
return (vector unsigned short) __builtin_altivec_mfvscr ();
}
@@ -4697,22 +4699,8 @@ vec_vsubuhs (vector unsigned short a1, vector signed short a2)
return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
}
-/* vec_vsubuhs */
-
-inline vector unsigned short
-vec_vsubsuhs (vector signed short a1, vector unsigned short a2)
-{
- return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
-}
-
inline vector unsigned short
-vec_vsubsuhs (vector unsigned short a1, vector signed short a2)
-{
- return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
-}
-
-inline vector unsigned short
-vec_vsubsuhs (vector unsigned short a1, vector unsigned short a2)
+vec_vsubuhs (vector unsigned short a1, vector unsigned short a2)
{
return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
}
@@ -4728,19 +4716,19 @@ vec_vsubsbs (vector signed char a1, vector signed char a2)
/* vec_vsububs */
inline vector unsigned char
-vec_vsubsubs (vector signed char a1, vector unsigned char a2)
+vec_vsububs (vector signed char a1, vector unsigned char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
inline vector unsigned char
-vec_vsubsubs (vector unsigned char a1, vector signed char a2)
+vec_vsububs (vector unsigned char a1, vector signed char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
inline vector unsigned char
-vec_vsubsubs (vector unsigned char a1, vector unsigned char a2)
+vec_vsububs (vector unsigned char a1, vector unsigned char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
@@ -5526,7 +5514,7 @@ vec_all_nlt (vector float a1, vector float a2)
inline int
vec_all_numeric (vector float a1)
{
- return __builtin_altivec_vcmpeqfp_p (__CR6_EQ, a1, a1);
+ return __builtin_altivec_vcmpeqfp_p (__CR6_LT, a1, a1);
}
/* vec_any_eq */
@@ -6117,6 +6105,8 @@ struct __vec_step_help<vector float>
#define vec_step(t) __vec_step_help<typeof(t)>::_S_elem
+}//extern "C++"
+
#else /* not C++ */
/* "... and so I think no man in a century will suffer as greatly as
@@ -6521,7 +6511,7 @@ __ch (__bin_args_eq (vector unsigned char, (a1), vector unsigned char, (a2)), \
((vector signed char) __builtin_altivec_vcmpgtub ((vector signed char) (a1), (vector signed char) (a2))), \
__altivec_link_error_invalid_argument ())
-#define vec_cmple(a1, a2) __builtin_altivec_vcmpgefp ((a1), (a2))
+#define vec_cmple(a1, a2) __builtin_altivec_vcmpgefp ((a2), (a1))
#define vec_cmplt(a2, a1) \
__ch (__bin_args_eq (vector unsigned char, (a1), vector unsigned char, (a2)), \
@@ -8343,7 +8333,7 @@ __ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
#define vec_all_nlt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a2), (a1))
-#define vec_all_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_EQ, (a1), (a1))
+#define vec_all_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_LT, (a1), (a1))
#define vec_any_eq(a1, a2) \
__ch (__bin_args_eq (vector signed char, (a1), vector unsigned char, (a2)), \
@@ -8533,6 +8523,7 @@ __ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
#define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2))
+
#endif /* __cplusplus */
#endif /* _ALTIVEC_H */
diff --git a/contrib/gcc/config/rs6000/altivec.md b/contrib/gcc/config/rs6000/altivec.md
index 25e4b08..db341cb 100644
--- a/contrib/gcc/config/rs6000/altivec.md
+++ b/contrib/gcc/config/rs6000/altivec.md
@@ -1,23 +1,29 @@
;; AltiVec patterns.
-;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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 2, or (at your option)
-;; any later version.
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, or (at your
+;; option) any later version.
-;; GNU CC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_constants
+ [(UNSPEC_VSPLTISW 141)
+ (UNSPEC_VSPLTISH 140)
+ (UNSPEC_VSPLTISB 139)
+ ])
;; Generic LVX load instruction.
(define_insn "altivec_lvx_4si"
@@ -85,18 +91,47 @@
"{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
(define_insn "*movv4si_internal"
- [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V4SI 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V4SI 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V4SImode)
+ || register_operand (operands[1], V4SImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ (match_operand:V4SI 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
+
+(define_split
+ [(set (match_operand:V4SI 0 "altivec_register_operand" "")
+ (match_operand:V4SI 1 "easy_vector_constant_add_self" ""))]
+ "TARGET_ALTIVEC && reload_completed"
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0)
+ (plus:V4SI (match_dup 0)
+ (match_dup 0)))]
+ "
+{
+ operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
(define_expand "movv8hi"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "")
@@ -105,18 +140,47 @@
"{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
(define_insn "*movv8hi_internal1"
- [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V8HI 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V8HI 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V8HImode)
+ || register_operand (operands[1], V8HImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ (match_operand:V8HI 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
+
+(define_split
+ [(set (match_operand:V8HI 0 "altivec_register_operand" "")
+ (match_operand:V8HI 1 "easy_vector_constant_add_self" ""))]
+ "TARGET_ALTIVEC && reload_completed"
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0)
+ (plus:V8HI (match_dup 0)
+ (match_dup 0)))]
+ "
+{
+ operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
(define_expand "movv16qi"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "")
@@ -125,18 +189,47 @@
"{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
(define_insn "*movv16qi_internal1"
- [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V16QI 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V16QI 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V16QImode)
+ || register_operand (operands[1], V16QImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ (match_operand:V16QI 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
+
+(define_split
+ [(set (match_operand:V16QI 0 "altivec_register_operand" "")
+ (match_operand:V16QI 1 "easy_vector_constant_add_self" ""))]
+ "TARGET_ALTIVEC && reload_completed"
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0)
+ (plus:V16QI (match_dup 0)
+ (match_dup 0)))]
+ "
+{
+ operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
(define_expand "movv4sf"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "")
@@ -145,18 +238,34 @@
"{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
(define_insn "*movv4sf_internal1"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V4SF 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V4SF 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V4SFmode)
+ || register_operand (operands[1], V4SFmode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ (match_operand:V4SF 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_insn "get_vrsave_internal"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -169,7 +278,7 @@
else
return \"mfvrsave %0\";
}"
- [(set_attr "type" "altivec")])
+ [(set_attr "type" "*")])
(define_insn "*set_vrsave_internal"
[(match_parallel 0 "vrsave_operation"
@@ -184,37 +293,7 @@
else
return \"mtvrsave %1\";
}"
- [(set_attr "type" "altivec")])
-
-;; Vector clears
-(define_insn "*movv4si_const0"
- [(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
- (match_operand:V4SI 1 "zero_constant" ""))]
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv4sf_const0"
- [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
- (match_operand:V4SF 1 "zero_constant" ""))]
-
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv8hi_const0"
- [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
- (match_operand:V8HI 1 "zero_constant" ""))]
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv16qi_const0"
- [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
- (match_operand:V16QI 1 "zero_constant" ""))]
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
+ [(set_attr "type" "*")])
;; Simple binary operations.
@@ -529,7 +608,7 @@
(match_operand:V16QI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 65))]
"TARGET_ALTIVEC"
- "vmsumubm %0, %1, %2, %3"
+ "vmsumubm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsummbm"
@@ -538,7 +617,7 @@
(match_operand:V16QI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 66))]
"TARGET_ALTIVEC"
- "vmsumubm %0, %1, %2, %3"
+ "vmsummbm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumuhm"
@@ -547,7 +626,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 67))]
"TARGET_ALTIVEC"
- "vmsumuhm %0, %1, %2, %3"
+ "vmsumuhm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumshm"
@@ -556,7 +635,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 68))]
"TARGET_ALTIVEC"
- "vmsumshm %0, %1, %2, %3"
+ "vmsumshm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumuhs"
@@ -566,7 +645,7 @@
(match_operand:V4SI 3 "register_operand" "v")] 69))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmsumuhs %0, %1, %2, %3"
+ "vmsumuhs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumshs"
@@ -576,7 +655,7 @@
(match_operand:V4SI 3 "register_operand" "v")] 70))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmsumshs %0, %1, %2, %3"
+ "vmsumshs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "umaxv16qi3"
@@ -642,7 +721,7 @@
(match_operand:V8HI 3 "register_operand" "v")] 71))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmhaddshs %0, %1, %2, %3"
+ "vmhaddshs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmhraddshs"
[(set (match_operand:V8HI 0 "register_operand" "=v")
@@ -651,7 +730,7 @@
(match_operand:V8HI 3 "register_operand" "v")] 72))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmhraddshs %0, %1, %2, %3"
+ "vmhraddshs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmladduhm"
[(set (match_operand:V8HI 0 "register_operand" "=v")
@@ -659,7 +738,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:V8HI 3 "register_operand" "v")] 73))]
"TARGET_ALTIVEC"
- "vmladduhm %0, %1, %2, %3"
+ "vmladduhm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmrghb"
@@ -1279,6 +1358,7 @@
"vsumsws %0,%1,%2"
[(set_attr "type" "veccomplex")])
+;; Vector xor's
(define_insn "xorv4si3"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(xor:V4SI (match_operand:V4SI 1 "register_operand" "v")
@@ -1287,6 +1367,22 @@
"vxor %0,%1,%2"
[(set_attr "type" "vecsimple")])
+(define_insn "xorv8hi3"
+ [(set (match_operand:V8HI 0 "register_operand" "=v")
+ (xor:V8HI (match_operand:V8HI 1 "register_operand" "v")
+ (match_operand:V8HI 2 "register_operand" "v")))]
+ "TARGET_ALTIVEC"
+ "vxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")])
+
+(define_insn "xorv16qi3"
+ [(set (match_operand:V16QI 0 "register_operand" "=v")
+ (xor:V16QI (match_operand:V16QI 1 "register_operand" "v")
+ (match_operand:V16QI 2 "register_operand" "v")))]
+ "TARGET_ALTIVEC"
+ "vxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")])
+
(define_insn "altivec_vspltb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
@@ -1294,6 +1390,7 @@
"TARGET_ALTIVEC"
"vspltb %0,%1,%2"
[(set_attr "type" "vecperm")])
+;; End of vector xor's
(define_insn "altivec_vsplth"
[(set (match_operand:V8HI 0 "register_operand" "=v")
@@ -1313,38 +1410,40 @@
(define_insn "altivec_vspltisb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:QI 1 "immediate_operand" "i")] 139))]
+ (unspec:V16QI [(match_operand:QI 1 "immediate_operand" "i")]
+ UNSPEC_VSPLTISB))]
"TARGET_ALTIVEC"
- "vspltisb %0, %1"
- [(set_attr "type" "vecsimple")])
-
+ "vspltisb %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "altivec_vspltish"
[(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:QI 1 "immediate_operand" "i")] 140))]
+ (unspec:V8HI [(match_operand:QI 1 "immediate_operand" "i")]
+ UNSPEC_VSPLTISH))]
"TARGET_ALTIVEC"
- "vspltish %0, %1"
- [(set_attr "type" "vecsimple")])
+ "vspltish %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "altivec_vspltisw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:QI 1 "immediate_operand" "i")] 141))]
+ (unspec:V4SI [(match_operand:QI 1 "immediate_operand" "i")]
+ UNSPEC_VSPLTISW))]
"TARGET_ALTIVEC"
- "vspltisw %0, %1"
- [(set_attr "type" "vecsimple")])
+ "vspltisw %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "altivec_vspltisw_v4sf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:QI 1 "immediate_operand" "i")] 142))]
"TARGET_ALTIVEC"
- "vspltisw %0, %1"
- [(set_attr "type" "vecsimple")])
+ "vspltisw %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "ftruncv4sf2"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
- "vrfiz %0, %1"
+ "vrfiz %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vperm_4si"
@@ -1387,21 +1486,21 @@
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 148))]
"TARGET_ALTIVEC"
- "vrfip %0, %1"
+ "vrfip %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrfin"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 149))]
"TARGET_ALTIVEC"
- "vrfin %0, %1"
+ "vrfin %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrfim"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 150))]
"TARGET_ALTIVEC"
- "vrfim %0, %1"
+ "vrfim %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vcfux"
@@ -1409,7 +1508,7 @@
(unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:QI 2 "immediate_operand" "i")] 151))]
"TARGET_ALTIVEC"
- "vcfux %0, %1, %2"
+ "vcfux %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vcfsx"
@@ -1417,7 +1516,7 @@
(unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:QI 2 "immediate_operand" "i")] 152))]
"TARGET_ALTIVEC"
- "vcfsx %0, %1, %2"
+ "vcfsx %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vctuxs"
@@ -1426,7 +1525,7 @@
(match_operand:QI 2 "immediate_operand" "i")] 153))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vctuxs %0, %1, %2"
+ "vctuxs %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vctsxs"
@@ -1435,35 +1534,35 @@
(match_operand:QI 2 "immediate_operand" "i")] 154))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vctsxs %0, %1, %2"
+ "vctsxs %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vlogefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 155))]
"TARGET_ALTIVEC"
- "vlogefp %0, %1"
+ "vlogefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vexptefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 156))]
"TARGET_ALTIVEC"
- "vexptefp %0, %1"
+ "vexptefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrsqrtefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 157))]
"TARGET_ALTIVEC"
- "vrsqrtefp %0, %1"
+ "vrsqrtefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 158))]
"TARGET_ALTIVEC"
- "vrefp %0, %1"
+ "vrefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vsel_4si"
@@ -1508,7 +1607,7 @@
(match_operand:V4SI 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 163))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsldoi_4sf"
@@ -1517,7 +1616,7 @@
(match_operand:V4SF 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 164))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsldoi_8hi"
@@ -1526,7 +1625,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 165))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsldoi_16qi"
@@ -1535,49 +1634,49 @@
(match_operand:V16QI 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 166))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupkhsb"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 167))]
"TARGET_ALTIVEC"
- "vupkhsb %0, %1"
+ "vupkhsb %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupkhpx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 168))]
"TARGET_ALTIVEC"
- "vupkhpx %0, %1"
+ "vupkhpx %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupkhsh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 169))]
"TARGET_ALTIVEC"
- "vupkhsh %0, %1"
+ "vupkhsh %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupklsb"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 170))]
"TARGET_ALTIVEC"
- "vupklsb %0, %1"
+ "vupklsb %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupklpx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 171))]
"TARGET_ALTIVEC"
- "vupklpx %0, %1"
+ "vupklpx %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupklsh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 172))]
"TARGET_ALTIVEC"
- "vupklsh %0, %1"
+ "vupklsh %0,%1"
[(set_attr "type" "vecperm")])
;; AltiVec predicates.
@@ -1683,51 +1782,49 @@
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dst"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 190)]
"TARGET_ALTIVEC"
- "dst %0,%1,%2"
+ "dst %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dstt"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 191)]
"TARGET_ALTIVEC"
- "dstt %0,%1,%2"
+ "dstt %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dstst"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 192)]
"TARGET_ALTIVEC"
- "dstst %0,%1,%2"
+ "dstst %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dststt"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 193)]
"TARGET_ALTIVEC"
- "dststt %0,%1,%2"
+ "dststt %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_lvsl"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r")] 194))]
+ (unspec:V16QI [(match_operand 1 "memory_operand" "m")] 194))]
"TARGET_ALTIVEC"
- "lvsl %0,%1,%2"
+ "lvsl %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvsr"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r")] 195))]
+ (unspec:V16QI [(match_operand 1 "memory_operand" "m")] 195))]
"TARGET_ALTIVEC"
- "lvsr %0,%1,%2"
+ "lvsr %0,%y1"
[(set_attr "type" "vecload")])
;; Parallel some of the LVE* and STV*'s with unspecs because some have
@@ -1736,112 +1833,89 @@
(define_insn "altivec_lvebx"
[(parallel
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (mem:V16QI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))))
+ (match_operand:V16QI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 196)])]
"TARGET_ALTIVEC"
- "lvebx %0,%1,%2"
+ "lvebx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvehx"
[(parallel
[(set (match_operand:V8HI 0 "register_operand" "=v")
- (mem:V8HI
- (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))
- (const_int -2))))
+ (match_operand:V8HI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 197)])]
"TARGET_ALTIVEC"
- "lvehx %0,%1,%2"
+ "lvehx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvewx"
[(parallel
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))
- (const_int -4))))
+ (match_operand:V4SI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 198)])]
"TARGET_ALTIVEC"
- "lvewx %0,%1,%2"
+ "lvewx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvxl"
[(parallel
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))))
+ (match_operand:V4SI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 213)])]
"TARGET_ALTIVEC"
- "lvxl %0,%1,%2"
+ "lvxl %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))))]
+ (match_operand:V4SI 1 "memory_operand" "m"))]
"TARGET_ALTIVEC"
- "lvx %0,%1,%2"
+ "lvx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_stvx"
[(parallel
- [(set (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -16)))
- (match_operand:V4SI 2 "register_operand" "v"))
+ [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ (match_operand:V4SI 1 "register_operand" "v"))
(unspec [(const_int 0)] 201)])]
"TARGET_ALTIVEC"
- "stvx %2,%0,%1"
+ "stvx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvxl"
[(parallel
- [(set (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -16)))
- (match_operand:V4SI 2 "register_operand" "v"))
+ [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ (match_operand:V4SI 1 "register_operand" "v"))
(unspec [(const_int 0)] 202)])]
"TARGET_ALTIVEC"
- "stvxl %2,%0,%1"
+ "stvxl %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvebx"
[(parallel
- [(set (mem:V16QI
- (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r")))
- (match_operand:V16QI 2 "register_operand" "v"))
+ [(set (match_operand:V16QI 0 "memory_operand" "=m")
+ (match_operand:V16QI 1 "register_operand" "v"))
(unspec [(const_int 0)] 203)])]
"TARGET_ALTIVEC"
- "stvebx %2,%0,%1"
+ "stvebx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvehx"
[(parallel
- [(set (mem:V8HI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -2)))
- (match_operand:V8HI 2 "register_operand" "v"))
+ [(set (match_operand:V8HI 0 "memory_operand" "=m")
+ (match_operand:V8HI 1 "register_operand" "v"))
(unspec [(const_int 0)] 204)])]
"TARGET_ALTIVEC"
- "stvehx %2,%0,%1"
+ "stvehx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvewx"
[(parallel
- [(set (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -4)))
- (match_operand:V4SI 2 "register_operand" "v"))
+ [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ (match_operand:V4SI 1 "register_operand" "v"))
(unspec [(const_int 0)] 205)])]
"TARGET_ALTIVEC"
- "stvewx %2,%0,%1"
+ "stvewx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "absv16qi2"
@@ -1851,7 +1925,7 @@
(clobber (match_scratch:V16QI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsububm %3,%2,%1\;vmaxsb %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "absv8hi2"
@@ -1861,7 +1935,7 @@
(clobber (match_scratch:V8HI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubuhm %3,%2,%1\;vmaxsh %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "absv4si2"
@@ -1871,7 +1945,7 @@
(clobber (match_scratch:V4SI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubuwm %3,%2,%1\;vmaxsw %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "absv4sf2"
@@ -1880,8 +1954,8 @@
(clobber (match_scratch:V4SF 2 "=&v"))
(clobber (match_scratch:V4SF 3 "=&v"))]
"TARGET_ALTIVEC"
- "vspltisw %2, -1\;vslw %3,%2,%2\;vandc %0,%1,%3"
- [(set_attr "type" "altivec")
+ "vspltisw %2,-1\;vslw %3,%2,%2\;vandc %0,%1,%3"
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "altivec_abss_v16qi"
@@ -1891,7 +1965,7 @@
(clobber (match_scratch:V16QI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubsbs %3,%2,%1\;vmaxsb %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "altivec_abss_v8hi"
@@ -1901,7 +1975,7 @@
(clobber (match_scratch:V8HI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubshs %3,%2,%1\;vmaxsh %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "altivec_abss_v4si"
@@ -1911,5 +1985,5 @@
(clobber (match_scratch:V4SI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubsws %3,%2,%1\;vmaxsw %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
diff --git a/contrib/gcc/config/rs6000/beos.h b/contrib/gcc/config/rs6000/beos.h
index 1f788c3..1ce36bf 100644
--- a/contrib/gcc/config/rs6000/beos.h
+++ b/contrib/gcc/config/rs6000/beos.h
@@ -1,24 +1,24 @@
/* Definitions of target machine for GNU compiler, for BeOS.
- Copyright (C) 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Fred Fish (fnf@cygnus.com), based on aix41.h
from David Edelsohn (edelsohn@npac.syr.edu).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (BeOS/PowerPC)");
@@ -39,7 +39,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_SPEC "-u %(asm_cpu)"
#undef TARGET_OS_CPP_BUILTINS
-/* __POWERPC__ must be defined for some header files */
+/* __POWERPC__ must be defined for some header files. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
diff --git a/contrib/gcc/config/rs6000/biarch64.h b/contrib/gcc/config/rs6000/biarch64.h
new file mode 100644
index 0000000..3f8addd
--- /dev/null
+++ b/contrib/gcc/config/rs6000/biarch64.h
@@ -0,0 +1,22 @@
+/* Definitions of target machine for GNU compiler, for 32/64 bit powerpc.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Specify this in a cover file to provide bi-architecture (32/64) support. */
+#define RS6000_BI_ARCH 1
diff --git a/contrib/gcc/config/rs6000/crtsavres.asm b/contrib/gcc/config/rs6000/crtsavres.asm
index 0c65182..327048e 100644
--- a/contrib/gcc/config/rs6000/crtsavres.asm
+++ b/contrib/gcc/config/rs6000/crtsavres.asm
@@ -41,6 +41,7 @@
.section ".text"
#include "ppc-asm.h"
+/* On PowerPC64 Linux, these functions are provided by the linker. */
#ifndef __powerpc64__
/* Routines for saving floating point registers, called by the compiler. */
@@ -303,105 +304,4 @@ FUNC_END(_restgpr_16_x)
FUNC_END(_restgpr_15_x)
FUNC_END(_restgpr_14_x)
-#else /* __powerpc64__ */
-
- .section ".text"
- .align 2
-
-/* Routines for saving floating point registers, called by the compiler. */
-
-.fsav:
-FUNC_START(_savef14) stfd 14,-144(1) /* save fp registers */
-FUNC_START(_savef15) stfd 15,-136(1)
-FUNC_START(_savef16) stfd 16,-128(1)
-FUNC_START(_savef17) stfd 17,-120(1)
-FUNC_START(_savef18) stfd 18,-112(1)
-FUNC_START(_savef19) stfd 19,-104(1)
-FUNC_START(_savef20) stfd 20,-96(1)
-FUNC_START(_savef21) stfd 21,-88(1)
-FUNC_START(_savef22) stfd 22,-80(1)
-FUNC_START(_savef23) stfd 23,-72(1)
-FUNC_START(_savef24) stfd 24,-64(1)
-FUNC_START(_savef25) stfd 25,-56(1)
-FUNC_START(_savef26) stfd 26,-48(1)
-FUNC_START(_savef27) stfd 27,-40(1)
-FUNC_START(_savef28) stfd 28,-32(1)
-FUNC_START(_savef29) stfd 29,-24(1)
-FUNC_START(_savef30) stfd 30,-16(1)
-FUNC_START(_savef31) stfd 31,-8(1)
- blr
-.LTfsav:
- .long 0
- .byte 0,12,0,0,0,0,0,0
- .long 0
- .long .LTfsav-.fsav
- .short 4
- .ascii "fsav"
-FUNC_END(_savef31)
-FUNC_END(_savef30)
-FUNC_END(_savef29)
-FUNC_END(_savef28)
-FUNC_END(_savef27)
-FUNC_END(_savef26)
-FUNC_END(_savef25)
-FUNC_END(_savef24)
-FUNC_END(_savef23)
-FUNC_END(_savef22)
-FUNC_END(_savef21)
-FUNC_END(_savef20)
-FUNC_END(_savef19)
-FUNC_END(_savef18)
-FUNC_END(_savef17)
-FUNC_END(_savef16)
-FUNC_END(_savef15)
-FUNC_END(_savef14)
-
-/* Routines for restoring floating point registers, called by the compiler. */
-
-.fres:
-FUNC_START(_restf14) lfd 14,-144(1) /* restore fp registers */
-FUNC_START(_restf15) lfd 15,-136(1)
-FUNC_START(_restf16) lfd 16,-128(1)
-FUNC_START(_restf17) lfd 17,-120(1)
-FUNC_START(_restf18) lfd 18,-112(1)
-FUNC_START(_restf19) lfd 19,-104(1)
-FUNC_START(_restf20) lfd 20,-96(1)
-FUNC_START(_restf21) lfd 21,-88(1)
-FUNC_START(_restf22) lfd 22,-80(1)
-FUNC_START(_restf23) lfd 23,-72(1)
-FUNC_START(_restf24) lfd 24,-64(1)
-FUNC_START(_restf25) lfd 25,-56(1)
-FUNC_START(_restf26) lfd 26,-48(1)
-FUNC_START(_restf27) lfd 27,-40(1)
-FUNC_START(_restf28) lfd 28,-32(1)
-FUNC_START(_restf29) lfd 29,-24(1)
-FUNC_START(_restf30) lfd 30,-16(1)
-FUNC_START(_restf31) lfd 31,-8(1)
- blr
-.LTfres:
- .long 0
- .byte 0,12,0,0,0,0,0,0
- .long 0
- .long .LTfres-.fres
- .short 4
- .ascii "fres"
-FUNC_END(_restf31)
-FUNC_END(_restf30)
-FUNC_END(_restf29)
-FUNC_END(_restf28)
-FUNC_END(_restf27)
-FUNC_END(_restf26)
-FUNC_END(_restf25)
-FUNC_END(_restf24)
-FUNC_END(_restf23)
-FUNC_END(_restf22)
-FUNC_END(_restf21)
-FUNC_END(_restf20)
-FUNC_END(_restf19)
-FUNC_END(_restf18)
-FUNC_END(_restf17)
-FUNC_END(_restf16)
-FUNC_END(_restf15)
-FUNC_END(_restf14)
-
#endif
diff --git a/contrib/gcc/config/rs6000/darwin-ldouble.c b/contrib/gcc/config/rs6000/darwin-ldouble.c
new file mode 100644
index 0000000..3174ebb
--- /dev/null
+++ b/contrib/gcc/config/rs6000/darwin-ldouble.c
@@ -0,0 +1,205 @@
+/* 128-bit long double support routines for Darwin.
+ Copyright (C) 1993, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Implementations of floating-point long double basic arithmetic
+ functions called by the IBM C compiler when generating code for
+ PowerPC platforms. In particular, the following functions are
+ implemented: _xlqadd, _xlqsub, _xlqmul, and _xlqdiv. Double-double
+ algorithms are based on the paper "Doubled-Precision IEEE Standard
+ 754 Floating-Point Arithmetic" by W. Kahan, February 26, 1987. An
+ alternative published reference is "Software for Doubled-Precision
+ Floating-Point Computations", by Seppo Linnainmaa, ACM TOMS vol 7
+ no 3, September 1961, pages 272-283. */
+
+/* Each long double is made up of two IEEE doubles. The value of the
+ long double is the sum of the values of the two parts. The most
+ significant part is required to be the value of the long double
+ rounded to the nearest double, as specified by IEEE. For Inf
+ values, the least significant part is required to be one of +0.0 or
+ -0.0. No other requirements are made; so, for example, 1.0 may be
+ represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
+ NaN is don't-care.
+
+ This code currently assumes big-endian. */
+
+#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__))
+
+#define fabs(x) __builtin_fabs(x)
+
+#define unlikely(x) __builtin_expect ((x), 0)
+
+/* All these routines actually take two long doubles as parameters,
+ but GCC currently generates poor code when a union is used to turn
+ a long double into a pair of doubles. */
+
+extern long double _xlqadd (double, double, double, double);
+extern long double _xlqsub (double, double, double, double);
+extern long double _xlqmul (double, double, double, double);
+extern long double _xlqdiv (double, double, double, double);
+
+typedef union
+{
+ long double ldval;
+ double dval[2];
+} longDblUnion;
+
+static const double FPKINF = 1.0/0.0;
+
+/* Add two 'long double' values and return the result. */
+long double
+_xlqadd (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double t, tau, u, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ if (unlikely (a != a) || unlikely (c != c))
+ return a + c; /* NaN result. */
+
+ /* Ordered operands are arranged in order of their magnitudes. */
+
+ /* Switch inputs if |(c,d)| > |(a,b)|. */
+ if (fabs (c) > fabs (a))
+ {
+ t = a;
+ tau = b;
+ a = c;
+ b = d;
+ c = t;
+ d = tau;
+ }
+
+ /* b <- second largest magnitude double. */
+ if (fabs (c) > fabs (b))
+ {
+ t = b;
+ b = c;
+ c = t;
+ }
+
+ /* Thanks to commutivity, sum is invariant w.r.t. the next
+ conditional exchange. */
+ tau = d + c;
+
+ /* Order the smallest magnitude doubles. */
+ if (fabs (d) > fabs (c))
+ {
+ t = c;
+ c = d;
+ d = t;
+ }
+
+ t = (tau + b) + a; /* Sum values in ascending magnitude order. */
+
+ /* Infinite or zero result. */
+ if (unlikely (t == FPR_zero) || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Usual case. */
+ tau = (((a-t) + b) + c) + d;
+ u = t + tau;
+ z.dval[0] = u; /* Final fixup for long double result. */
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+long double
+_xlqsub (double a, double b, double c, double d)
+{
+ return _xlqadd (a, b, -c, -d);
+}
+
+long double
+_xlqmul (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double t, tau, u, v, w, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ t = a * c; /* Highest order double term. */
+
+ if (unlikely (t != t) || unlikely (t == FPR_zero)
+ || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Finite nonzero result requires summing of terms of two highest
+ orders. */
+
+ /* Use fused multiply-add to get low part of a * c. */
+ asm ("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
+ v = a*d;
+ w = b*c;
+ tau += v + w; /* Add in other second-order terms. */
+ u = t + tau;
+
+ /* Construct long double result. */
+ z.dval[0] = u;
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+long double
+_xlqdiv (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double s, sigma, t, tau, u, v, w, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ t = a / c; /* highest order double term */
+
+ if (unlikely (t != t) || unlikely (t == FPR_zero)
+ || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Finite nonzero result requires corrections to the highest order term. */
+
+ s = c * t; /* (s,sigma) = c*t exactly. */
+ w = -(-b + d * t); /* Written to get fnmsub for speed, but not
+ numerically necessary. */
+
+ /* Use fused multiply-add to get low part of c * t. */
+ asm ("fmsub %0,%1,%2,%3" : "=f"(sigma) : "f"(c), "f"(t), "f"(s));
+ v = a - s;
+
+ tau = ((v-sigma)+w)/c; /* Correction to t. */
+ u = t + tau;
+
+ /* Construct long double result. */
+ z.dval[0] = u;
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+#endif
diff --git a/contrib/gcc/config/rs6000/darwin.h b/contrib/gcc/config/rs6000/darwin.h
index b3468f2..62ed74c 100644
--- a/contrib/gcc/config/rs6000/darwin.h
+++ b/contrib/gcc/config/rs6000/darwin.h
@@ -1,23 +1,23 @@
/* Target definitions for PowerPC running Darwin (Mac OS X).
- Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Darwin/PowerPC)");
@@ -35,14 +35,15 @@ Boston, MA 02111-1307, USA. */
#define TARGET_TOC 0
#define TARGET_NO_TOC 1
+/* Darwin switches. */
+/* Use dynamic-no-pic codegen (no picbase reg; not suitable for shlibs.) */
+#define MASK_MACHO_DYNAMIC_NO_PIC 0x00800000
+
+#define TARGET_DYNAMIC_NO_PIC (target_flags & MASK_MACHO_DYNAMIC_NO_PIC)
+
/* Handle #pragma weak and #pragma pack. */
#define HANDLE_SYSV_PRAGMA 1
-/* The Darwin ABI always includes AltiVec, can't be (validly) turned
- off. */
-
-#define SUBTARGET_OVERRIDE_OPTIONS \
- rs6000_altivec_abi = 1;
#define TARGET_OS_CPP_BUILTINS() \
do \
@@ -55,12 +56,60 @@ Boston, MA 02111-1307, USA. */
} \
while (0)
+
+/* */
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+ {"dynamic-no-pic", MASK_MACHO_DYNAMIC_NO_PIC, \
+ N_("Generate code suitable for executables (NOT shared libs)")}, \
+ {"no-dynamic-no-pic", -MASK_MACHO_DYNAMIC_NO_PIC, ""},
+
+
+/* The Darwin ABI always includes AltiVec, can't be (validly) turned
+ off. */
+
+#define SUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ rs6000_altivec_abi = 1; \
+ rs6000_altivec_vrsave = 1; \
+ if (DEFAULT_ABI == ABI_DARWIN) \
+ { \
+ if (MACHO_DYNAMIC_NO_PIC_P) \
+ { \
+ if (flag_pic) \
+ warning ("-mdynamic-no-pic overrides -fpic or -fPIC"); \
+ flag_pic = 0; \
+ } \
+ else if (flag_pic == 1) \
+ { \
+ /* Darwin doesn't support -fpic. */ \
+ warning ("-fpic is not supported; -fPIC assumed"); \
+ flag_pic = 2; \
+ } \
+ } \
+}while(0)
+
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. */
+
#define CC1_SPEC "\
+%{gused: -feliminate-unused-debug-symbols %<gused }\
%{static: %{Zdynamic: %e conflicting code gen style switches are used}}\
-%{!static:-fPIC}"
+%{!static:%{!mdynamic-no-pic:-fPIC}}"
+
+/* It's virtually impossible to predict all the possible combinations
+ of -mcpu and -maltivec and whatnot, so just supply
+ -force_cpusubtype_ALL if any are seen. Radar 3492132 against the
+ assembler is asking for a .machine directive so we could get this
+ really right. */
+#define ASM_SPEC "-arch ppc \
+ %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
+ %{!Zforce_cpusubtype_ALL:%{maltivec|mcpu=*|mpowerpc64:-force_cpusubtype_ALL}}"
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "darwin_arch", "ppc" },
/* Make both r2 and r3 available for allocation. */
#define FIXED_R2 0
@@ -87,23 +136,46 @@ Boston, MA 02111-1307, USA. */
(RS6000_ALIGN (current_function_outgoing_args_size, 16) \
+ (STACK_POINTER_OFFSET))
+/* These are used by -fbranch-probabilities */
+#define HOT_TEXT_SECTION_NAME "__TEXT,__text,regular,pure_instructions"
+#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
+ "__TEXT,__text2,regular,pure_instructions"
+
/* Define cutoff for using external functions to save floating point.
Currently on Darwin, always use inline stores. */
#undef FP_SAVE_INLINE
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
-/* Always use the "debug" register names, they're what the assembler
- wants to see. */
-
+/* The assembler wants the alternate register names, but without
+ leading percent sign. */
#undef REGISTER_NAMES
-#define REGISTER_NAMES DEBUG_REGISTER_NAMES
+#define REGISTER_NAMES \
+{ \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ "mq", "lr", "ctr", "ap", \
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
+ "xer", \
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
+ "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
+ "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
+ "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", \
+ "vrsave", "vscr", \
+ "spe_acc", "spefscr" \
+}
/* This outputs NAME to FILE. */
#undef RS6000_OUTPUT_BASENAME
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
- assemble_name (FILE, NAME);
+ assemble_name (FILE, NAME)
/* Globalizing directive for a label. */
#undef GLOBAL_ASM_OP
@@ -125,7 +197,8 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
do { fputs (".comm ", (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fprintf ((FILE), ",%d\n", (SIZE)); } while (0)
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
+ (SIZE)); } while (0)
/* Override the standard rs6000 definition. */
@@ -167,7 +240,7 @@ Boston, MA 02111-1307, USA. */
#define PROCESSOR_DEFAULT PROCESSOR_PPC7400
/* Default target flag settings. Despite the fact that STMW/LMW
- serializes, it's still a big codesize win to use them. Use FSEL by
+ serializes, it's still a big code size win to use them. Use FSEL by
default as well. */
#undef TARGET_DEFAULT
@@ -196,38 +269,40 @@ Boston, MA 02111-1307, USA. */
a SYMBOL_REF. */
#undef PREFERRED_RELOAD_CLASS
-#define PREFERRED_RELOAD_CLASS(X,CLASS) \
- (((GET_CODE (X) == CONST_DOUBLE \
- && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- ? NO_REGS \
- : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \
- && (CLASS) == NON_SPECIAL_REGS) \
- ? GENERAL_REGS \
- : (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == HIGH) \
- ? BASE_REGS \
- : (CLASS)))
+#define PREFERRED_RELOAD_CLASS(X,CLASS) \
+ ((GET_CODE (X) == CONST_DOUBLE \
+ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
+ ? NO_REGS \
+ : ((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == HIGH) \
+ && reg_class_subset_p (BASE_REGS, (CLASS))) \
+ ? BASE_REGS \
+ : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \
+ && (CLASS) == NON_SPECIAL_REGS) \
+ ? GENERAL_REGS \
+ : (CLASS))
/* Fix for emit_group_load (): force large constants to be pushed via regs. */
#define ALWAYS_PUSH_CONSTS_USING_REGS_P 1
+/* This now supports a natural alignment mode */
/* Darwin word-aligns FP doubles but doubleword-aligns 64-bit ints. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
(TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
? get_inner_array_type (FIELD) \
: TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED))
+ ? MIN ((COMPUTED), 32) : (COMPUTED)))
/* Darwin increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
- : (TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0 \
+ ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
+ : (TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
+ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
: MAX ((COMPUTED), (SPECIFIED)))
/* XXX: Darwin supports neither .quad, or .llong, but it also doesn't
@@ -245,3 +320,4 @@ Boston, MA 02111-1307, USA. */
#undef REGISTER_TARGET_PRAGMAS
#define REGISTER_TARGET_PRAGMAS DARWIN_REGISTER_TARGET_PRAGMAS
+
diff --git a/contrib/gcc/config/rs6000/default64.h b/contrib/gcc/config/rs6000/default64.h
new file mode 100644
index 0000000..c6ed142
--- /dev/null
+++ b/contrib/gcc/config/rs6000/default64.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler,
+ for 64 bit powerpc linux defaulting to -m64.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+ (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
diff --git a/contrib/gcc/config/rs6000/eabi-ci.asm b/contrib/gcc/config/rs6000/eabi-ci.asm
index 64ffbfc..447b4e2 100644
--- a/contrib/gcc/config/rs6000/eabi-ci.asm
+++ b/contrib/gcc/config/rs6000/eabi-ci.asm
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA.
#include <ppc-asm.h>
+#ifndef __powerpc64__
.section ".got","aw"
.globl __GOT_START__
.type __GOT_START__,@object
@@ -122,3 +123,4 @@ FUNC_START(__fini)
stwu 1,-16(1)
mflr 0
stw 0,20(1)
+#endif
diff --git a/contrib/gcc/config/rs6000/eabi-cn.asm b/contrib/gcc/config/rs6000/eabi-cn.asm
index 4a01dc6..b2c6095 100644
--- a/contrib/gcc/config/rs6000/eabi-cn.asm
+++ b/contrib/gcc/config/rs6000/eabi-cn.asm
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA.
.file "crtn.s"
.ident "GNU C crtn.s"
+#ifndef __powerpc64__
.section ".got","aw"
.globl __GOT_END__
.type __GOT_END__,@object
@@ -113,3 +114,4 @@ __EH_FRAME_END__:
mtlr 0
addi 1,1,16
blr
+#endif
diff --git a/contrib/gcc/config/rs6000/eabi.h b/contrib/gcc/config/rs6000/eabi.h
index 373dd2b..ff8df2c 100644
--- a/contrib/gcc/config/rs6000/eabi.h
+++ b/contrib/gcc/config/rs6000/eabi.h
@@ -1,30 +1,30 @@
/* Core target definitions for GNU compiler
for IBM RS/6000 PowerPC targeted to embedded ELF systems.
- Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2003 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-/* Add -meabi to target flags */
+/* Add -meabi to target flags. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
-/* Invoke an initializer function to set up the GOT */
+/* Invoke an initializer function to set up the GOT. */
#define NAME__MAIN "__eabi"
#define INVOKE__main
@@ -40,15 +40,18 @@ Boston, MA 02111-1307, USA. */
builtin_assert ("system=embedded"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
#undef TARGET_SPE_ABI
#undef TARGET_SPE
+#undef TARGET_E500
#undef TARGET_ISEL
#undef TARGET_FPRS
#define TARGET_SPE_ABI rs6000_spe_abi
-#define TARGET_SPE (rs6000_cpu == PROCESSOR_PPC8540)
+#define TARGET_SPE rs6000_spe
+#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel
-#define TARGET_FPRS rs6000_fprs
+#define TARGET_FPRS (!rs6000_float_gprs)
diff --git a/contrib/gcc/config/rs6000/eabialtivec.h b/contrib/gcc/config/rs6000/eabialtivec.h
index 23ec8c9..e407e3b 100644
--- a/contrib/gcc/config/rs6000/eabialtivec.h
+++ b/contrib/gcc/config/rs6000/eabialtivec.h
@@ -1,31 +1,31 @@
/* Core target definitions for GNU compiler
for PowerPC targeted systems with AltiVec support.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Add -meabi and -maltivec to target flags. */
-#undef TARGET_DEFAULT
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI | MASK_ALTIVEC)
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded with AltiVec)");
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1
diff --git a/contrib/gcc/config/rs6000/eabisim.h b/contrib/gcc/config/rs6000/eabisim.h
index 00f710e..5e0900d 100644
--- a/contrib/gcc/config/rs6000/eabisim.h
+++ b/contrib/gcc/config/rs6000/eabisim.h
@@ -1,29 +1,29 @@
/* Support for GCC on simulated PowerPC systems targeted to embedded ELF
systems.
- Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2003 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
-#undef TARGET_OS_CPP_BUILTINS
+#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */
builtin_assert ("system=simulator"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
diff --git a/contrib/gcc/config/rs6000/eabispe.h b/contrib/gcc/config/rs6000/eabispe.h
index b0047cd..1551dc1 100644
--- a/contrib/gcc/config/rs6000/eabispe.h
+++ b/contrib/gcc/config/rs6000/eabispe.h
@@ -1,51 +1,57 @@
/* Core target definitions for GNU compiler
for PowerPC embedded targeted systems with SPE support.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_DEFAULT
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded SPE)");
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
- rs6000_cpu = PROCESSOR_PPC8540; \
- rs6000_spe_abi = 1; \
- rs6000_fprs = 0; \
+ if (rs6000_select[1].string == NULL) \
+ rs6000_cpu = PROCESSOR_PPC8540; \
+ if (rs6000_abi_string == NULL) \
+ rs6000_spe_abi = 1; \
+ if (rs6000_float_gprs_string == NULL) \
+ rs6000_float_gprs = 1; \
/* See note below. */ \
- /*rs6000_long_double_type_size = 128;*/ \
- rs6000_isel = 1
-
-/*
- The e500 ABI says that either long doubles are 128 bits, or if
- implemented in any other size, the compiler/linker should error out.
- We have no emulation libraries for 128 bit long doubles, and I hate
- the dozens of failures on the regression suite. So I'm breaking ABI
- specifications, until I properly fix the emulation.
-
- Enable these later.
+ /*if (rs6000_long_double_size_string == NULL)*/ \
+ /* rs6000_long_double_type_size = 128;*/ \
+ if (rs6000_spe_string == NULL) \
+ rs6000_spe = 1; \
+ if (rs6000_isel_string == NULL) \
+ rs6000_isel = 1
+
+/* The e500 ABI says that either long doubles are 128 bits, or if
+ implemented in any other size, the compiler/linker should error out.
+ We have no emulation libraries for 128 bit long doubles, and I hate
+ the dozens of failures on the regression suite. So I'm breaking ABI
+ specifications, until I properly fix the emulation.
+
+ Enable these later.
#undef CPP_LONGDOUBLE_DEFAULT_SPEC
#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1"
*/
-#undef ASM_DEFAULT_SPEC
+#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
diff --git a/contrib/gcc/config/rs6000/freebsd.h b/contrib/gcc/config/rs6000/freebsd.h
index 699d2ad..fe6a801 100644
--- a/contrib/gcc/config/rs6000/freebsd.h
+++ b/contrib/gcc/config/rs6000/freebsd.h
@@ -1,22 +1,23 @@
/* Definitions for PowerPC running FreeBSD using the ELF format
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Override the defaults, which exist to force the proper definition. */
@@ -39,7 +40,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)"
/* XXX: This is wrong for many platforms in sysv4.h.
- We should work on getting that defination fixed. */
+ We should work on getting that definition fixed. */
#undef LINK_SHLIB_SPEC
#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
diff --git a/contrib/gcc/config/rs6000/gnu.h b/contrib/gcc/config/rs6000/gnu.h
index 9aeb696..658a6d6 100644
--- a/contrib/gcc/config/rs6000/gnu.h
+++ b/contrib/gcc/config/rs6000/gnu.h
@@ -1,23 +1,23 @@
/* Definitions of target machine for GNU compiler,
for PowerPC machines running GNU.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_gnu)"
@@ -34,5 +34,5 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_gnu)"
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU)");
diff --git a/contrib/gcc/config/rs6000/host-darwin.c b/contrib/gcc/config/rs6000/host-darwin.c
new file mode 100644
index 0000000..7e80556
--- /dev/null
+++ b/contrib/gcc/config/rs6000/host-darwin.c
@@ -0,0 +1,189 @@
+/* Darwin/powerpc host-specific hook definitions.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include <signal.h>
+#include <sys/ucontext.h>
+#include <sys/mman.h>
+#include "hosthooks.h"
+#include "hosthooks-def.h"
+#include "toplev.h"
+#include "diagnostic.h"
+
+static void segv_crash_handler (int);
+static void segv_handler (int, siginfo_t *, void *);
+static void darwin_rs6000_extra_signals (void);
+
+/* This doesn't have a prototype in signal.h in 10.2.x and earlier,
+ fixed in later releases. */
+extern int sigaltstack(const struct sigaltstack *, struct sigaltstack *);
+
+#undef HOST_HOOKS_EXTRA_SIGNALS
+#define HOST_HOOKS_EXTRA_SIGNALS darwin_rs6000_extra_signals
+
+/* On Darwin/powerpc, hitting the stack limit turns into a SIGSEGV.
+ This code detects the difference between hitting the stack limit and
+ a true wild pointer dereference by looking at the instruction that
+ faulted; only a few kinds of instruction are used to access below
+ the previous bottom of the stack. */
+
+static void
+segv_crash_handler (int sig ATTRIBUTE_UNUSED)
+{
+ internal_error ("Segmentation Fault (code)");
+}
+
+static void
+segv_handler (int sig ATTRIBUTE_UNUSED,
+ siginfo_t *sip ATTRIBUTE_UNUSED,
+ void *scp)
+{
+ ucontext_t *uc = (ucontext_t *)scp;
+ unsigned faulting_insn;
+
+ /* The fault might have happened when trying to run some instruction, in
+ which case the next line will segfault _again_. Handle this case. */
+ signal (SIGSEGV, segv_crash_handler);
+
+ faulting_insn = *(unsigned *)uc->uc_mcontext->ss.srr0;
+
+ /* Note that this only has to work for GCC, so we don't have to deal
+ with all the possible cases (GCC has no AltiVec code, for
+ instance). It's complicated because Darwin allows stores to
+ below the stack pointer, and the prologue code takes advantage of
+ this. */
+
+ if ((faulting_insn & 0xFFFF8000) == 0x94218000 /* stwu %r1, -xxx(%r1) */
+ || (faulting_insn & 0xFFFF03FF) == 0x7C21016E /* stwux %r1, xxx, %r1 */
+ || (faulting_insn & 0xFC1F8000) == 0x90018000 /* stw xxx, -yyy(%r1) */
+ || (faulting_insn & 0xFC1F8000) == 0xD8018000 /* stfd xxx, -yyy(%r1) */
+ || (faulting_insn & 0xFC1F8000) == 0xBC018000 /* stmw xxx, -yyy(%r1) */)
+ {
+ char *shell_name;
+
+ fnotice (stderr, "Out of stack space.\n");
+ shell_name = getenv ("SHELL");
+ if (shell_name != NULL)
+ shell_name = strrchr (shell_name, '/');
+ if (shell_name != NULL)
+ {
+ static const char * shell_commands[][2] = {
+ { "sh", "ulimit -S -s unlimited" },
+ { "bash", "ulimit -S -s unlimited" },
+ { "tcsh", "limit stacksize unlimited" },
+ { "csh", "limit stacksize unlimited" },
+ /* zsh doesn't have "unlimited", this will work under the
+ default configuration. */
+ { "zsh", "limit stacksize 32m" }
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (shell_commands); i++)
+ if (strcmp (shell_commands[i][0], shell_name + 1) == 0)
+ {
+ fnotice (stderr,
+ "Try running `%s' in the shell to raise its limit.\n",
+ shell_commands[i][1]);
+ }
+ }
+
+ if (global_dc->abort_on_error)
+ abort ();
+
+ exit (FATAL_EXIT_CODE);
+ }
+
+ fprintf (stderr, "[address=%08lx pc=%08x]\n",
+ uc->uc_mcontext->es.dar, uc->uc_mcontext->ss.srr0);
+ internal_error ("Segmentation Fault");
+ exit (FATAL_EXIT_CODE);
+}
+
+static void
+darwin_rs6000_extra_signals (void)
+{
+ struct sigaction sact;
+ stack_t sigstk;
+
+ sigstk.ss_sp = xmalloc (SIGSTKSZ);
+ sigstk.ss_size = SIGSTKSZ;
+ sigstk.ss_flags = 0;
+ if (sigaltstack (&sigstk, NULL) < 0)
+ fatal_error ("While setting up signal stack: %m");
+
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = SA_ONSTACK | SA_SIGINFO;
+ sact.sa_sigaction = segv_handler;
+ if (sigaction (SIGSEGV, &sact, 0) < 0)
+ fatal_error ("While setting up signal handler: %m");
+}
+
+static void * darwin_rs6000_gt_pch_get_address (size_t);
+static bool darwin_rs6000_gt_pch_use_address (void *, size_t);
+
+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
+#define HOST_HOOKS_GT_PCH_GET_ADDRESS darwin_rs6000_gt_pch_get_address
+#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
+#define HOST_HOOKS_GT_PCH_USE_ADDRESS darwin_rs6000_gt_pch_use_address
+
+
+/* Yes, this is really supposed to work. */
+static char pch_address_space[1024*1024*1024] __attribute__((aligned (4096)));
+
+/* Return the address of the PCH address space, if the PCH will fit in it. */
+
+static void *
+darwin_rs6000_gt_pch_get_address (size_t sz)
+{
+ if (sz <= sizeof (pch_address_space))
+ return pch_address_space;
+ else
+ return NULL;
+}
+
+/* Check ADDR and SZ for validity, and deallocate (using munmap) that part of
+ pch_address_space beyond SZ. */
+
+static bool
+darwin_rs6000_gt_pch_use_address (void *addr, size_t sz)
+{
+ const size_t pagesize = getpagesize();
+ bool result;
+
+ if ((size_t)pch_address_space % pagesize != 0
+ || sizeof (pch_address_space) % pagesize != 0)
+ abort ();
+
+ result = (addr == pch_address_space && sz <= sizeof (pch_address_space));
+ if (! result)
+ sz = 0;
+
+ /* Round the size to a whole page size. Normally this is a no-op. */
+ sz = (sz + pagesize - 1) / pagesize * pagesize;
+
+ if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0)
+ fatal_error ("couldn't unmap pch_address_space: %m\n");
+
+ return result;
+}
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/contrib/gcc/config/rs6000/kaos-ppc.h b/contrib/gcc/config/rs6000/kaos-ppc.h
new file mode 100644
index 0000000..d6b92e7
--- /dev/null
+++ b/contrib/gcc/config/rs6000/kaos-ppc.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler.
+ kaOS on PowerPC architecture version.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (PowerPC/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/rs6000/libgcc-ppc64.ver b/contrib/gcc/config/rs6000/libgcc-ppc64.ver
new file mode 100644
index 0000000..116d5e7
--- /dev/null
+++ b/contrib/gcc/config/rs6000/libgcc-ppc64.ver
@@ -0,0 +1,7 @@
+GCC_3.4 {
+ # long double support
+ _xlqadd
+ _xlqsub
+ _xlqmul
+ _xlqdiv
+}
diff --git a/contrib/gcc/config/rs6000/linux.h b/contrib/gcc/config/rs6000/linux.h
index 15db88a..009ac66 100644
--- a/contrib/gcc/config/rs6000/linux.h
+++ b/contrib/gcc/config/rs6000/linux.h
@@ -4,35 +4,35 @@
Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-#undef TARGET_OS_CPP_BUILTINS
+#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
builtin_define_std ("PPC"); \
- builtin_define ("__ELF__"); \
builtin_define_std ("powerpc"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
@@ -42,15 +42,12 @@ Boston, MA 02111-1307, USA. */
/* The GNU C++ standard library currently requires _GNU_SOURCE being
defined on glibc-based systems. This temporary hack accomplishes this,
it should go away as soon as libstdc++-v3 has a real fix. */
-#undef CPLUSPLUS_CPP_SPEC
+#undef CPLUSPLUS_CPP_SPEC
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-#undef LINK_SHLIB_SPEC
+#undef LINK_SHLIB_SPEC
#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
-#define LINK_GCC_C_SEQUENCE_SPEC \
- "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
-
#undef LIB_DEFAULT_SPEC
#define LIB_DEFAULT_SPEC "%(lib_linux)"
@@ -66,22 +63,36 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
-#undef TARGET_VERSION
+#define LINK_GCC_C_SEQUENCE_SPEC \
+ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
/* Override rs6000.h definition. */
-#undef ASM_APP_ON
+#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
/* Override rs6000.h definition. */
-#undef ASM_APP_OFF
+#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
/* For backward compatibility, we must continue to use the AIX
structure return convention. */
-#undef DRAFT_V4_STRUCT_RET
+#undef DRAFT_V4_STRUCT_RET
#define DRAFT_V4_STRUCT_RET 1
+/* We are 32-bit all the time, so optimize a little. */
+#undef TARGET_64BIT
+#define TARGET_64BIT 0
+
+/* We don't need to generate entries in .fixup. */
+#undef RELOCATABLE_NEEDS_FIXUP
+
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+#define TARGET_HAS_F_SETLKW
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
@@ -165,3 +176,4 @@ enum { SIGNAL_FRAMESIZE = 64 };
goto SUCCESS; \
} while (0)
+#define OS_MISSING_POWERPC64 1
diff --git a/contrib/gcc/config/rs6000/linux64.h b/contrib/gcc/config/rs6000/linux64.h
index a538d02..4fe4199 100644
--- a/contrib/gcc/config/rs6000/linux64.h
+++ b/contrib/gcc/config/rs6000/linux64.h
@@ -1,128 +1,315 @@
/* Definitions of target machine for GNU compiler,
for 64 bit PowerPC linux.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-/* Yes! We are AIX! Err. Wait. We're Linux!. No, wait, we're a
- combo of both!*/
-#undef DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
+#ifndef RS6000_BI_ARCH
-#undef TARGET_AIX
-#define TARGET_AIX 1
+#undef DEFAULT_ABI
+#define DEFAULT_ABI ABI_AIX
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT \
- (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
+#undef TARGET_64BIT
+#define TARGET_64BIT 1
+
+#define DEFAULT_ARCH64_P 1
+#define RS6000_BI_ARCH_P 0
+
+#else
+
+#define DEFAULT_ARCH64_P (TARGET_DEFAULT & MASK_64BIT)
+#define RS6000_BI_ARCH_P 1
+
+#endif
+
+#ifdef IN_LIBGCC2
+#undef TARGET_64BIT
+#ifdef __powerpc64__
+#define TARGET_64BIT 1
+#else
+#define TARGET_64BIT 0
+#endif
+#endif
+
+#undef TARGET_AIX
+#define TARGET_AIX TARGET_64BIT
-#undef PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_PPC630
#undef PROCESSOR_DEFAULT64
#define PROCESSOR_DEFAULT64 PROCESSOR_PPC630
-#undef ASM_DEFAULT_SPEC
-#define ASM_DEFAULT_SPEC "-mppc64"
+#undef TARGET_RELOCATABLE
+#define TARGET_RELOCATABLE (!TARGET_64BIT && (target_flags & MASK_RELOCATABLE))
+
+#undef RS6000_ABI_NAME
+#define RS6000_ABI_NAME (TARGET_64BIT ? "aixdesc" : "sysv")
+
+#define INVALID_64BIT "-m%s not supported in this configuration"
+#define INVALID_32BIT INVALID_64BIT
+
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#define SUBSUBTARGET_OVERRIDE_OPTIONS \
+ do \
+ { \
+ if (rs6000_alignment_string == 0) \
+ rs6000_alignment_flags = MASK_ALIGN_NATURAL; \
+ if (TARGET_64BIT) \
+ { \
+ if (DEFAULT_ABI != ABI_AIX) \
+ { \
+ rs6000_current_abi = ABI_AIX; \
+ error (INVALID_64BIT, "call"); \
+ } \
+ if (target_flags & MASK_RELOCATABLE) \
+ { \
+ target_flags &= ~MASK_RELOCATABLE; \
+ error (INVALID_64BIT, "relocatable"); \
+ } \
+ if (target_flags & MASK_EABI) \
+ { \
+ target_flags &= ~MASK_EABI; \
+ error (INVALID_64BIT, "eabi"); \
+ } \
+ if (target_flags & MASK_PROTOTYPE) \
+ { \
+ target_flags &= ~MASK_PROTOTYPE; \
+ error (INVALID_64BIT, "prototype"); \
+ } \
+ if ((target_flags & MASK_POWERPC64) == 0) \
+ { \
+ target_flags |= MASK_POWERPC64; \
+ error ("-m64 requires a PowerPC64 cpu"); \
+ } \
+ } \
+ else \
+ { \
+ if (!RS6000_BI_ARCH_P) \
+ error (INVALID_32BIT, "32"); \
+ if (TARGET_PROFILE_KERNEL) \
+ { \
+ target_flags &= ~MASK_PROFILE_KERNEL; \
+ error (INVALID_32BIT, "profile-kernel"); \
+ } \
+ } \
+ } \
+ while (0)
+
+#ifdef RS6000_BI_ARCH
+
+#undef OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS \
+ rs6000_override_options (((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
+ ? (char *) 0 : TARGET_CPU_DEFAULT)
+
+#endif
+#undef ASM_DEFAULT_SPEC
#undef ASM_SPEC
-#define ASM_SPEC "%{.s: %{mregnames} %{mno-regnames}} \
-%{.S: %{mregnames} %{mno-regnames}} \
-%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
-%{v:-V} %{Qy:} %{!Qn:-Qy} -a64 %(asm_cpu) %{Wa,*:%*}"
+#undef LINK_OS_LINUX_SPEC
+
+#ifndef RS6000_BI_ARCH
+#define ASM_DEFAULT_SPEC "-mppc64"
+#define ASM_SPEC "%(asm_spec64) %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%(link_os_linux_spec64)"
+#else
+#if DEFAULT_ARCH64_P
+#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
+#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%{m32:%(link_os_linux_spec32)}%{!m32:%(link_os_linux_spec64)}"
+#else
+#define ASM_DEFAULT_SPEC "-mppc%{m64:64}"
+#define ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}"
+#endif
+#endif
+
+#define ASM_SPEC32 "-a32 %{n} %{T} %{Ym,*} %{Yd,*} \
+%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
+%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
+ %{mcall-freebsd: -mbig} \
+ %{mcall-i960-old: -mlittle} \
+ %{mcall-linux: -mbig} \
+ %{mcall-gnu: -mbig} \
+ %{mcall-netbsd: -mbig} \
+}}}}"
+
+#define ASM_SPEC64 "-a64"
+
+#define ASM_SPEC_COMMON "%(asm_cpu) \
+%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
+%{v:-V} %{Qy:} %{!Qn:-Qy} %{Wa,*:%*} \
+%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
+
+#undef SUBSUBTARGET_EXTRA_SPECS
+#define SUBSUBTARGET_EXTRA_SPECS \
+ { "asm_spec_common", ASM_SPEC_COMMON }, \
+ { "asm_spec32", ASM_SPEC32 }, \
+ { "asm_spec64", ASM_SPEC64 }, \
+ { "link_os_linux_spec32", LINK_OS_LINUX_SPEC32 }, \
+ { "link_os_linux_spec64", LINK_OS_LINUX_SPEC64 },
+
+#undef MULTILIB_DEFAULTS
+#if DEFAULT_ARCH64_P
+#define MULTILIB_DEFAULTS { "m64" }
+#else
+#define MULTILIB_DEFAULTS { "m32" }
+#endif
+
+#ifndef RS6000_BI_ARCH
+
+/* 64-bit PowerPC Linux is always big-endian. */
+#undef TARGET_LITTLE_ENDIAN
+#define TARGET_LITTLE_ENDIAN 0
/* 64-bit PowerPC Linux always has a TOC. */
-#undef TARGET_NO_TOC
-#define TARGET_NO_TOC 0
#undef TARGET_TOC
#define TARGET_TOC 1
-/* We use glibc _mcount for profiling. */
-#define NO_PROFILE_COUNTERS 1
-#undef PROFILE_BEFORE_PROLOGUE
+/* Some things from sysv4.h we don't do when 64 bit. */
+#undef TARGET_RELOCATABLE
+#define TARGET_RELOCATABLE 0
+#undef TARGET_EABI
+#define TARGET_EABI 0
+#undef TARGET_PROTOTYPE
+#define TARGET_PROTOTYPE 0
+
+#endif
-/* Define this for kernel profiling, which just saves LR then calls
+#define MASK_PROFILE_KERNEL 0x00100000
+
+/* Non-standard profiling for kernels, which just saves LR then calls
_mcount without worrying about arg saves. The idea is to change
the function prologue as little as possible as it isn't easy to
account for arg save/restore code added just for _mcount. */
-/* #define PROFILE_KERNEL 1 */
-#if PROFILE_KERNEL
-#define PROFILE_BEFORE_PROLOGUE 1
-#undef PROFILE_HOOK
-#else
-#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
-#endif
+#define TARGET_PROFILE_KERNEL (target_flags & MASK_PROFILE_KERNEL)
+
+/* Override sysv4.h. */
+#undef EXTRA_SUBTARGET_SWITCHES
+#define EXTRA_SUBTARGET_SWITCHES \
+ {"profile-kernel", MASK_PROFILE_KERNEL, \
+ N_("Call mcount for profiling before a function prologue") }, \
+ {"no-profile-kernel", -MASK_PROFILE_KERNEL, \
+ N_("Call mcount for profiling after a function prologue") },
+
+/* We use glibc _mcount for profiling. */
+#define NO_PROFILE_COUNTERS TARGET_64BIT
+#define PROFILE_HOOK(LABEL) \
+ do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
/* We don't need to generate entries in .fixup. */
#undef RELOCATABLE_NEEDS_FIXUP
-#define USER_LABEL_PREFIX ""
-
-/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
+/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */
#undef ADJUST_FIELD_ALIGN
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
- ? get_inner_array_type (FIELD) \
- : TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED))
-
-/* AIX increases natural record alignment to doubleword if the first
- field is an FP double while the FP fields remain word aligned. */
-#undef ROUND_TYPE_ALIGN
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
+ ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ ? 128 \
+ : (TARGET_64BIT \
+ && TARGET_ALIGN_NATURAL == 0 \
+ && TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
+ ? get_inner_array_type (FIELD) \
+ : TREE_TYPE (FIELD)) == DFmode) \
+ ? MIN ((COMPUTED), 32) \
+ : (COMPUTED))
+
+/* PowerPC64 Linux increases natural record alignment to doubleword if
+ the first field is an FP double, only if in power alignment mode. */
+#undef ROUND_TYPE_ALIGN
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
+ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
+ : (TARGET_64BIT \
+ && (TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0) \
+ ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
: MAX ((COMPUTED), (SPECIFIED)))
/* Indicate that jump tables go in the text section. */
#undef JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* 64-bit PowerPC Linux always has GPR13 fixed. */
-#define FIXED_R13 1
+#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
+
+/* The linux ppc64 ABI isn't explicit on whether aggregates smaller
+ than a doubleword should be padded upward or downward. You could
+ reasonably assume that they follow the normal rules for structure
+ layout treating the parameter area as any other block of memory,
+ then map the reg param area to registers. ie. pad updard.
+ Setting both of the following defines results in this behavior.
+ Setting just the first one will result in aggregates that fit in a
+ doubleword being padded downward, and others being padded upward.
+ Not a bad idea as this results in struct { int x; } being passed
+ the same way as an int. */
+#define AGGREGATE_PADDING_FIXED TARGET_64BIT
+#define AGGREGATES_PAD_UPWARD_ALWAYS 0
+
+/* We don't want anything in the reg parm area being passed on the
+ stack. */
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TARGET_64BIT \
+ && (TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE))) \
+ || (!TARGET_64BIT \
+ && default_must_pass_in_stack ((MODE), (TYPE))))
+
+/* Specify padding for the last element of a block move between
+ registers and memory. FIRST is nonzero if this is the only
+ element. */
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
/* __throw will restore its own return address to be the same as the
return address of the function that the throw is being made to.
This is unfortunate, because we want to check the original
return address to see if we need to restore the TOC.
So we have to squirrel it away with this. */
-#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+#define SETUP_FRAME_ADDRESSES() \
+ do { if (TARGET_64BIT) rs6000_aix_emit_builtin_unwind_init (); } while (0)
/* Override svr4.h */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-#undef TARGET_OS_CPP_BUILTINS
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__PPC__"); \
- builtin_define ("__PPC64__"); \
- builtin_define ("__powerpc__"); \
- builtin_define ("__powerpc64__"); \
- builtin_define ("__PIC__"); \
- builtin_define ("__ELF__"); \
- builtin_assert ("cpu=powerpc64"); \
- builtin_assert ("machine=powerpc64"); \
- } \
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ if (TARGET_64BIT) \
+ { \
+ builtin_define ("__PPC__"); \
+ builtin_define ("__PPC64__"); \
+ builtin_define ("__powerpc__"); \
+ builtin_define ("__powerpc64__"); \
+ builtin_define ("__PIC__"); \
+ builtin_assert ("cpu=powerpc64"); \
+ builtin_assert ("machine=powerpc64"); \
+ } \
+ else \
+ { \
+ builtin_define_std ("PPC"); \
+ builtin_define_std ("powerpc"); \
+ builtin_assert ("cpu=powerpc"); \
+ builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
+ } \
+ } \
while (0)
#undef CPP_OS_DEFAULT_SPEC
@@ -137,9 +324,6 @@ Boston, MA 02111-1307, USA. */
#undef LINK_SHLIB_SPEC
#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
-#define LINK_GCC_C_SEQUENCE_SPEC \
- "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
-
#undef LIB_DEFAULT_SPEC
#define LIB_DEFAULT_SPEC "%(lib_linux)"
@@ -155,43 +339,40 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
-#undef LINK_OS_LINUX_SPEC
-#define LINK_OS_LINUX_SPEC "-m elf64ppc %{!shared: %{!static: \
+#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux %{!shared: %{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
-#ifdef NATIVE_CROSS
-#define STARTFILE_PREFIX_SPEC "/usr/local/lib64/ /lib64/ /usr/lib64/"
-#endif
-
-#undef STARTFILE_LINUX_SPEC
-#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} crti.o%s \
-%{static:crtbeginT.o%s} \
-%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-
-#undef ENDFILE_LINUX_SPEC
-#define ENDFILE_LINUX_SPEC "\
-%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+#define LINK_OS_LINUX_SPEC64 "-m elf64ppc %{!shared: %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
#undef TOC_SECTION_ASM_OP
-#define TOC_SECTION_ASM_OP "\t.section\t\".toc\",\"aw\""
+#define TOC_SECTION_ASM_OP \
+ (TARGET_64BIT \
+ ? "\t.section\t\".toc\",\"aw\"" \
+ : "\t.section\t\".got\",\"aw\"")
#undef MINIMAL_TOC_SECTION_ASM_OP
-#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t\".toc1\",\"aw\""
+#define MINIMAL_TOC_SECTION_ASM_OP \
+ (TARGET_64BIT \
+ ? "\t.section\t\".toc1\",\"aw\"" \
+ : ((TARGET_RELOCATABLE || flag_pic) \
+ ? "\t.section\t\".got2\",\"aw\"" \
+ : "\t.section\t\".got1\",\"aw\""))
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC64 GNU/Linux)");
/* Must be at least as big as our pointer type. */
-#undef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
+#undef SIZE_TYPE
+#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
-#undef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
-#undef WCHAR_TYPE
-#define WCHAR_TYPE "int"
+#undef WCHAR_TYPE
+#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int")
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
@@ -205,7 +386,7 @@ Boston, MA 02111-1307, USA. */
/* PowerPC no-op instruction. */
#undef RS6000_CALL_GLUE
-#define RS6000_CALL_GLUE "nop"
+#define RS6000_CALL_GLUE (TARGET_64BIT ? "nop" : "cror 31,31,31")
#undef RS6000_MCOUNT
#define RS6000_MCOUNT "_mcount"
@@ -224,64 +405,18 @@ Boston, MA 02111-1307, USA. */
/* FP save and restore routines. */
#undef SAVE_FP_PREFIX
-#define SAVE_FP_PREFIX "._savef"
+#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
#undef SAVE_FP_SUFFIX
-#define SAVE_FP_SUFFIX ""
+#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
#undef RESTORE_FP_PREFIX
-#define RESTORE_FP_PREFIX "._restf"
+#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
#undef RESTORE_FP_SUFFIX
-#define RESTORE_FP_SUFFIX ""
+#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
/* Dwarf2 debugging. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info
-
-/* This is how to output a reference to a user-level label named NAME.
- `assemble_name' uses this. */
-
-/* Override elfos.h definition. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-do { \
- const char *_name = NAME; \
- if (*_name == '@') \
- _name++; \
- \
- if (*_name == '*') \
- fprintf (FILE, "%s", _name + 1); \
- else \
- asm_fprintf (FILE, "%U%s", _name); \
-} while (0)
-
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do \
- { \
- fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", (FILE)); \
- ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fputs (DOUBLE_INT_ASM_OP, (FILE)); \
- putc ('.', (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",24\n\t.type\t.", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",@function\n", (FILE)); \
- if (TREE_PUBLIC (DECL) && ! DECL_WEAK (DECL)) \
- { \
- fputs ("\t.globl\t.", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- putc ('\n', (FILE)); \
- } \
- ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL)); \
- putc ('.', (FILE)); \
- ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- } \
- while (0)
-
/* This is how to declare the size of a function. */
#undef ASM_DECLARE_FUNCTION_SIZE
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
@@ -289,9 +424,13 @@ do { \
{ \
if (!flag_inhibit_size_directive) \
{ \
- fputs ("\t.size\t.", (FILE)); \
+ fputs ("\t.size\t", (FILE)); \
+ if (TARGET_64BIT) \
+ putc ('.', (FILE)); \
assemble_name ((FILE), (FNAME)); \
- fputs (",.-.", (FILE)); \
+ fputs (",.-", (FILE)); \
+ if (TARGET_64BIT) \
+ putc ('.', (FILE)); \
assemble_name ((FILE), (FNAME)); \
putc ('\n', (FILE)); \
} \
@@ -318,28 +457,34 @@ do { \
|| (GET_CODE (X) == CONST_INT \
&& GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \
|| (GET_CODE (X) == CONST_DOUBLE \
- && (TARGET_POWERPC64 \
- || TARGET_MINIMAL_TOC \
- || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
- && ! TARGET_NO_FP_IN_TOC)))))
+ && ((TARGET_64BIT \
+ && (TARGET_POWERPC64 \
+ || TARGET_MINIMAL_TOC \
+ || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
+ && ! TARGET_NO_FP_IN_TOC))) \
+ || (!TARGET_64BIT \
+ && !TARGET_NO_FP_IN_TOC \
+ && !TARGET_RELOCATABLE \
+ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
+ && BITS_PER_WORD == HOST_BITS_PER_INT)))))
/* This is the same as the dbxelf.h version, except that we need to
use the function code label, not the function descriptor. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE, COUNTER) \
do \
{ \
- static int sym_lineno = 1; \
char temp[256]; \
- ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
+ ASM_GENERATE_INTERNAL_LABEL (temp, "LM", COUNTER); \
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
- fputs ("-.", FILE); \
+ putc ('-', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
putc ('\n', FILE); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
- sym_lineno += 1; \
+ (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER); \
} \
while (0)
@@ -355,7 +500,8 @@ while (0)
flab = IDENTIFIER_POINTER (current_function_func_begin_label); \
else \
{ \
- putc ('.', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
flab = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); \
} \
assemble_name (FILE, flab); \
@@ -372,19 +518,205 @@ while (0)
{ \
fprintf (FILE, "%s\"\",%d,0,0,", ASM_STABS_OP, N_FUN); \
assemble_name (FILE, LSCOPE); \
- fputs ("-.", FILE); \
+ putc ('-', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0)); \
putc ('\n', FILE); \
} \
while (0)
-/* Override sysv4.h as these are ABI_V4 only. */
-#undef ASM_OUTPUT_REG_PUSH
-#undef ASM_OUTPUT_REG_POP
-
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. */
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
- (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_udata8)
+ ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE) \
+ ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \
+ | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \
+ : DW_EH_PE_absptr)
+
+/* For backward compatibility, we must continue to use the AIX
+ structure return convention. */
+#undef DRAFT_V4_STRUCT_RET
+#define DRAFT_V4_STRUCT_RET (!TARGET_64BIT)
+
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+#define TARGET_HAS_F_SETLKW
+
+#define LINK_GCC_C_SEQUENCE_SPEC \
+ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs. */
+
+#ifdef IN_LIBGCC2
+#include <signal.h>
+#ifdef __powerpc64__
+#include <sys/ucontext.h>
+
+enum { SIGNAL_FRAMESIZE = 128 };
+
+#else
+
+/* During the 2.5 kernel series the kernel ucontext was changed, but
+ the new layout is compatible with the old one, so we just define
+ and use the old one here for simplicity and compatibility. */
+
+struct kernel_old_ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext_struct uc_mcontext;
+ sigset_t uc_sigmask;
+};
+enum { SIGNAL_FRAMESIZE = 64 };
+#endif
+
+#endif
+
+#ifdef __powerpc64__
+
+/* If the current unwind info (FS) does not contain explicit info
+ saving R2, then we have to do a minor amount of code reading to
+ figure out if it was saved. The big problem here is that the
+ code that does the save/restore is generated by the linker, so
+ we have no good way to determine at compile time what to do. */
+
+#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
+ do { \
+ if ((FS)->regs.reg[2].how == REG_UNSAVED) \
+ { \
+ unsigned int *insn \
+ = (unsigned int *) \
+ _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
+ if (*insn == 0xE8410028) \
+ _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
+ } \
+ } while (0)
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned char *pc_ = (CONTEXT)->ra; \
+ struct sigcontext *sc_; \
+ long new_cfa_; \
+ int i_; \
+ \
+ /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ \
+ /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ \
+ if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE \
+ || *(unsigned int *) (pc_+8) != 0x44000002) \
+ break; \
+ if (*(unsigned int *) (pc_+4) == 0x38000077) \
+ { \
+ struct sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ struct sigcontext sigctx; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->sigctx; \
+ } \
+ else if (*(unsigned int *) (pc_+4) == 0x380000AC) \
+ { \
+ struct rt_sigframe { \
+ int tramp[6]; \
+ struct siginfo *pinfo; \
+ struct ucontext *puc; \
+ } *rt_ = (struct rt_sigframe *) pc_; \
+ sc_ = &rt_->puc->uc_mcontext; \
+ } \
+ else \
+ break; \
+ \
+ new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = STACK_POINTER_REGNUM; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ \
+ for (i_ = 0; i_ < 32; i_++) \
+ if (i_ != STACK_POINTER_REGNUM) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset \
+ = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
+ } \
+ \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->link) - new_cfa_; \
+ \
+ (FS)->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->nip) - new_cfa_; \
+ (FS)->retaddr_column = ARG_POINTER_REGNUM; \
+ goto SUCCESS; \
+ } while (0)
+
+#else
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned char *pc_ = (CONTEXT)->ra; \
+ struct sigcontext *sc_; \
+ long new_cfa_; \
+ int i_; \
+ \
+ /* li r0, 0x7777; sc (sigreturn old) */ \
+ /* li r0, 0x0077; sc (sigreturn new) */ \
+ /* li r0, 0x6666; sc (rt_sigreturn old) */ \
+ /* li r0, 0x00AC; sc (rt_sigreturn new) */ \
+ if (*(unsigned int *) (pc_+4) != 0x44000002) \
+ break; \
+ if (*(unsigned int *) (pc_+0) == 0x38007777 \
+ || *(unsigned int *) (pc_+0) == 0x38000077) \
+ { \
+ struct sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ struct sigcontext sigctx; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->sigctx; \
+ } \
+ else if (*(unsigned int *) (pc_+0) == 0x38006666 \
+ || *(unsigned int *) (pc_+0) == 0x380000AC) \
+ { \
+ struct rt_sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ unsigned long _unused[2]; \
+ struct siginfo *pinfo; \
+ void *puc; \
+ struct siginfo info; \
+ struct kernel_old_ucontext uc; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->uc.uc_mcontext; \
+ } \
+ else \
+ break; \
+ \
+ new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = STACK_POINTER_REGNUM; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ \
+ for (i_ = 0; i_ < 32; i_++) \
+ if (i_ != STACK_POINTER_REGNUM) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset \
+ = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
+ } \
+ \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->link) - new_cfa_; \
+ \
+ (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[CR0_REGNO].loc.offset \
+ = (long)&(sc_->regs->nip) - new_cfa_; \
+ (FS)->retaddr_column = CR0_REGNO; \
+ goto SUCCESS; \
+ } while (0)
+
+#endif
+
+
+#define OS_MISSING_POWERPC64 !TARGET_64BIT
diff --git a/contrib/gcc/config/rs6000/linuxaltivec.h b/contrib/gcc/config/rs6000/linuxaltivec.h
index d2f184f..73ac864 100644
--- a/contrib/gcc/config/rs6000/linuxaltivec.h
+++ b/contrib/gcc/config/rs6000/linuxaltivec.h
@@ -1,31 +1,31 @@
/* Definitions of target machine for GNU compiler,
for AltiVec enhanced PowerPC machines running GNU/Linux.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC AltiVec GNU/Linux)");
/* Override rs6000.h and sysv4.h definition. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_ALTIVEC)
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1
diff --git a/contrib/gcc/config/rs6000/linuxspe.h b/contrib/gcc/config/rs6000/linuxspe.h
new file mode 100644
index 0000000..59eb831
--- /dev/null
+++ b/contrib/gcc/config/rs6000/linuxspe.h
@@ -0,0 +1,70 @@
+/* Definitions of target machine for GNU compiler,
+ for PowerPC e500 machines running GNU/Linux.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez (aldy@quesejoda.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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (PowerPC E500 GNU/Linux)");
+
+/* Override rs6000.h and sysv4.h definition. */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS)
+
+#undef TARGET_SPE_ABI
+#undef TARGET_SPE
+#undef TARGET_E500
+#undef TARGET_ISEL
+#undef TARGET_FPRS
+
+#define TARGET_SPE_ABI rs6000_spe_abi
+#define TARGET_SPE rs6000_spe
+#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
+#define TARGET_ISEL rs6000_isel
+#define TARGET_FPRS (!rs6000_float_gprs)
+
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#define SUBSUBTARGET_OVERRIDE_OPTIONS \
+ if (rs6000_select[1].string == NULL) \
+ rs6000_cpu = PROCESSOR_PPC8540; \
+ if (rs6000_abi_string == NULL || strstr (rs6000_abi_string, "spe") == NULL) \
+ rs6000_spe_abi = 1; \
+ if (rs6000_float_gprs_string == NULL) \
+ rs6000_float_gprs = 1; \
+ /* See note below. */ \
+ /*if (rs6000_long_double_size_string == NULL)*/ \
+ /* rs6000_long_double_type_size = 128;*/ \
+ if (rs6000_spe_string == NULL) \
+ rs6000_spe = 1; \
+ if (rs6000_isel_string == NULL) \
+ rs6000_isel = 1
+
+/* The e500 ABI says that either long doubles are 128 bits, or if
+ implemented in any other size, the compiler/linker should error out.
+ We have no emulation libraries for 128 bit long doubles, and I hate
+ the dozens of failures on the regression suite. So I'm breaking ABI
+ specifications, until I properly fix the emulation.
+
+ Enable these later.
+#undef CPP_LONGDOUBLE_DEFAULT_SPEC
+#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1"
+*/
+
+#undef ASM_DEFAULT_SPEC
+#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
diff --git a/contrib/gcc/config/rs6000/lynx.h b/contrib/gcc/config/rs6000/lynx.h
index 7878ef9..b32b078 100644
--- a/contrib/gcc/config/rs6000/lynx.h
+++ b/contrib/gcc/config/rs6000/lynx.h
@@ -1,59 +1,32 @@
/* Definitions for Rs6000 running LynxOS.
- Copyright (C) 1995, 1996, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com)
-This file is part of GNU CC.
-
-GNU CC 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 2, or (at your option)
-any later version.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* Definitions we want to override with those from rs6000.h: */
-#undef LIB_SPEC
-#undef PTRDIFF_TYPE
-#undef WCHAR_TYPE
-#undef WCHAR_TYPE_SIZE
-#undef ASM_FILE_START
-#undef EXTRA_SECTIONS
-#undef READONLY_DATA_SECTION
-#undef READONLY_DATA_SECTION_ASM_OP
-#undef EXTRA_SECTION_FUNCTIONS
-#undef TARGET_ASM_SELECT_RTX_SECTION
-#undef TARGET_ASM_SELECT_SECTION
-#undef USER_LABEL_PREFIX
-#undef ASM_OUTPUT_LABELREF
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#undef ASM_GENERATE_INTERNAL_LABEL
-#undef ASM_OUTPUT_COMMON
-#undef ASM_OUTPUT_LOCAL
-
-#undef SDB_DEBUGGING_INFO
-#undef DBX_DEBUGGING_INFO
-#undef PREFERRED_DEBUGGING_TYPE
-
-#undef FUNCTION_PROFILER
-
-#include <rs6000/rs6000.h>
+ 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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Print subsidiary information on the compiler version in use. */
#define TARGET_VERSION fprintf (stderr, " (LynxOS-RS/6000)");
/* LynxOS has signed chars, regardless of what most R/S 6000 systems do */
-#undef DEFAULT_SIGNED_CHAR
+#undef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 1
-#undef TARGET_OS_CPP_BUILTINS
+#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
@@ -70,30 +43,30 @@ Boston, MA 02111-1307, USA. */
} \
while (0)
-#undef LINK_SPEC
+#undef LINK_SPEC
#define LINK_SPEC "-T0x10001000 -H0x1000 -D0x20000000 -btextro -bhalt:4 -bnodelcsect -bnso -bro -bnoglink %{v} %{b*}"
-#undef LIB_SPEC
+#undef LIB_SPEC
#define LIB_SPEC "%{mthreads:-L/lib/thread/} \
%{msystem-v:-lc_v -lm.v} \
%{!msystem-v:%{mposix:-lc_p} -lc -lm}"
-#undef STARTFILE_SPEC
+#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{p:%{mthreads:thread/pinit.o%s}%{!mthreads:pinit.o%s}}%{!p:%{msystem-v:vinit.o%s -e_start}%{!msystem-v:%{mthreads:thread/init.o%s}%{!mthreads:init.o%s}}}"
#undef ENDFILE_SPEC
/* This can become more refined as we have more powerpc options. */
-#undef ASM_SPEC
+#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu)"
-#undef SUBTARGET_SWITCHES
+#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{"threads", MASK_THREADS}, \
{"posix", MASK_POSIX}, \
{"system-v", MASK_SYSTEM_V},
-#undef SUBTARGET_OVERRIDE_OPTIONS
+#undef SUBTARGET_OVERRIDE_OPTIONS
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
if (TARGET_SYSTEM_V && profile_flag) \
@@ -105,11 +78,10 @@ do { \
/* For collect2 */
#define OBJECT_FORMAT_NONE
#undef OBJECT_FORMAT_COFF
-#undef OBJECT_FORMAT_ROSE
#undef MD_EXEC_PREFIX
#undef REAL_LD_FILE_NAME
#undef REAL_STRIP_FILE_NAME
/* LynxOS doesn't have mcount. */
-#undef FUNCTION_PROFILER
+#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(file, profile_label_no)
diff --git a/contrib/gcc/config/rs6000/lynxbase.h b/contrib/gcc/config/rs6000/lynxbase.h
new file mode 100644
index 0000000..02a2552
--- /dev/null
+++ b/contrib/gcc/config/rs6000/lynxbase.h
@@ -0,0 +1,45 @@
+/* Definitions for Rs6000 running LynxOS.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/* Definitions we want to override with those from rs6000.h: */
+#undef LIB_SPEC
+#undef PTRDIFF_TYPE
+#undef SIZE_TYPE
+#undef WCHAR_TYPE
+#undef WCHAR_TYPE_SIZE
+#undef EXTRA_SECTIONS
+#undef READONLY_DATA_SECTION
+#undef READONLY_DATA_SECTION_ASM_OP
+#undef EXTRA_SECTION_FUNCTIONS
+#undef TARGET_ASM_SELECT_RTX_SECTION
+#undef TARGET_ASM_SELECT_SECTION
+#undef USER_LABEL_PREFIX
+#undef ASM_OUTPUT_LABELREF
+#undef ASM_GENERATE_INTERNAL_LABEL
+#undef ASM_OUTPUT_COMMON
+#undef ASM_OUTPUT_LOCAL
+
+#undef SDB_DEBUGGING_INFO
+#undef DBX_DEBUGGING_INFO
+#undef PREFERRED_DEBUGGING_TYPE
+
+#undef FUNCTION_PROFILER
+#undef SUBTARGET_SWITCHES
diff --git a/contrib/gcc/config/rs6000/mpc.md b/contrib/gcc/config/rs6000/mpc.md
new file mode 100644
index 0000000..b95bba5
--- /dev/null
+++ b/contrib/gcc/config/rs6000/mpc.md
@@ -0,0 +1,99 @@
+;; Scheduling description for Motorola PowerPC processor cores.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "mpc,mpcfp")
+(define_cpu_unit "iu_mpc,mciu_mpc" "mpc")
+(define_cpu_unit "fpu_mpc" "mpcfp")
+(define_cpu_unit "lsu_mpc,bpu_mpc" "mpc")
+
+;; MPCCORE 32-bit SCIU, MCIU, LSU, FPU, BPU
+;; 505/801/821/823
+
+(define_insn_reservation "mpccore-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "mpccore"))
+ "lsu_mpc")
+
+(define_insn_reservation "mpccore-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "mpccore"))
+ "lsu_mpc")
+
+(define_insn_reservation "mpccore-fpload" 2
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "mpccore"))
+ "lsu_mpc")
+
+(define_insn_reservation "mpccore-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "mpccore"))
+ "iu_mpc")
+
+(define_insn_reservation "mpccore-imul" 2
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "mpccore"))
+ "mciu_mpc")
+
+; Divide latency varies greatly from 2-11, use 6 as average
+(define_insn_reservation "mpccore-idiv" 6
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "mpccore"))
+ "mciu_mpc*6")
+
+(define_insn_reservation "mpccore-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "mpccore"))
+ "iu_mpc,nothing,bpu_mpc")
+
+(define_insn_reservation "mpccore-fpcompare" 2
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc,bpu_mpc")
+
+(define_insn_reservation "mpccore-fp" 4
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*2")
+
+(define_insn_reservation "mpccore-dmul" 5
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*5")
+
+(define_insn_reservation "mpccore-sdiv" 10
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*10")
+
+(define_insn_reservation "mpccore-ddiv" 17
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*17")
+
+(define_insn_reservation "mpccore-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "mpccore"))
+ "bpu_mpc")
+
+(define_insn_reservation "mpccore-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch,cr_logical,delayed_cr,mfcr,mtcr")
+ (eq_attr "cpu" "mpccore"))
+ "bpu_mpc")
+
diff --git a/contrib/gcc/config/rs6000/netbsd.h b/contrib/gcc/config/rs6000/netbsd.h
index b473a8a..e0c5196 100644
--- a/contrib/gcc/config/rs6000/netbsd.h
+++ b/contrib/gcc/config/rs6000/netbsd.h
@@ -1,26 +1,26 @@
/* Definitions of target machine for GNU compiler,
for PowerPC NetBSD systems.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002, 2003 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_OS_CPP_BUILTINS /* FIXME: sysv4.h should not define this! */
+#undef TARGET_OS_CPP_BUILTINS /* FIXME: sysv4.h should not define this! */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
@@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA. */
/* Override the default from rs6000.h to avoid conflicts with macros
defined in NetBSD header files. */
-#undef RS6000_CPU_CPP_ENDIAN_BUILTINS
+#undef RS6000_CPU_CPP_ENDIAN_BUILTINS
#define RS6000_CPU_CPP_ENDIAN_BUILTINS() \
do \
{ \
@@ -53,41 +53,41 @@ Boston, MA 02111-1307, USA. */
/* Make GCC agree with <machine/ansi.h>. */
-#undef SIZE_TYPE
+#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
-#undef PTRDIFF_TYPE
+#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
/* Undo the spec mess from sysv4.h, and just define the specs
the way NetBSD systems actually expect. */
-#undef CPP_SPEC
+#undef CPP_SPEC
#define CPP_SPEC NETBSD_CPP_SPEC
-#undef LINK_SPEC
+#undef LINK_SPEC
#define LINK_SPEC \
"%{!msdata=none:%{G*}} %{msdata=none:-G0} \
%(netbsd_link_spec)"
#define NETBSD_ENTRY_POINT "_start"
-#undef STARTFILE_SPEC
+#undef STARTFILE_SPEC
#define STARTFILE_SPEC NETBSD_STARTFILE_SPEC
-#undef ENDFILE_SPEC
+#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"crtsavres%O%s %(netbsd_endfile_spec)"
-#undef LIB_SPEC
+#undef LIB_SPEC
#define LIB_SPEC NETBSD_LIB_SPEC
-#undef SUBTARGET_EXTRA_SPECS
+#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
{ "netbsd_entry_point", NETBSD_ENTRY_POINT }, \
{ "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (NetBSD/powerpc ELF)");
diff --git a/contrib/gcc/config/rs6000/power4.md b/contrib/gcc/config/rs6000/power4.md
new file mode 100644
index 0000000..fabc1de
--- /dev/null
+++ b/contrib/gcc/config/rs6000/power4.md
@@ -0,0 +1,392 @@
+;; Scheduling description for IBM Power4 and PowerPC 970 processors.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+;; Sources: IBM Red Book and White Paper on POWER4
+
+;; The POWER4 has 2 iu, 2 fpu, 2 lsu per engine (2 engines per chip).
+;; Instructions that update more than one register get broken into two
+;; (split) or more internal ops. The chip can issue up to 5
+;; internal ops per cycle.
+
+(define_automaton "power4iu,power4fpu,power4vec,power4misc")
+
+(define_cpu_unit "iu1_power4,iu2_power4" "power4iu")
+(define_cpu_unit "lsu1_power4,lsu2_power4" "power4misc")
+(define_cpu_unit "fpu1_power4,fpu2_power4" "power4fpu")
+(define_cpu_unit "bpu_power4,cru_power4" "power4misc")
+(define_cpu_unit "vec_power4,vecperm_power4" "power4vec")
+(define_cpu_unit "du1_power4,du2_power4,du3_power4,du4_power4,du5_power4"
+ "power4misc")
+
+(define_reservation "lsq_power4"
+ "(du1_power4,lsu1_power4)\
+ |(du2_power4,lsu2_power4)\
+ |(du3_power4,nothing,lsu2_power4)\
+ |(du4_power4,nothing,lsu1_power4)")
+
+(define_reservation "lsuq_power4"
+ "(du1_power4+du2_power4,lsu1_power4+iu2_power4)\
+ |(du2_power4+du3_power4,lsu2_power4+iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4+iu1_power4)")
+; |(du2_power4+du3_power4,nothing,lsu2_power4,iu2_power4)
+
+(define_reservation "iq_power4"
+ "(du1_power4,iu1_power4)\
+ |(du2_power4,iu2_power4)\
+ |(du3_power4,nothing,iu2_power4)\
+ |(du4_power4,nothing,iu1_power4)")
+
+(define_reservation "fpq_power4"
+ "(du1_power4,fpu1_power4)\
+ |(du2_power4,fpu2_power4)\
+ |(du3_power4,nothing,fpu2_power4)\
+ |(du4_power4,nothing,fpu1_power4)")
+
+(define_reservation "vq_power4"
+ "(du1_power4,vec_power4)\
+ |(du2_power4,vec_power4)\
+ |(du3_power4,nothing,vec_power4)\
+ |(du4_power4,nothing,vec_power4)")
+
+(define_reservation "vpq_power4"
+ "(du1_power4,vecperm_power4)\
+ |(du2_power4,vecperm_power4)\
+ |(du3_power4,nothing,vecperm_power4)\
+ |(du4_power4,nothing,vecperm_power4)")
+
+
+; Dispatch slots are allocated in order conforming to program order.
+(absence_set "du1_power4" "du2_power4,du3_power4,du4_power4,du5_power4")
+(absence_set "du2_power4" "du3_power4,du4_power4,du5_power4")
+(absence_set "du3_power4" "du4_power4,du5_power4")
+(absence_set "du4_power4" "du5_power4")
+
+
+; Load/store
+(define_insn_reservation "power4-load" 4 ; 3
+ (and (eq_attr "type" "load")
+ (eq_attr "cpu" "power4"))
+ "lsq_power4")
+
+(define_insn_reservation "power4-load-ext" 5
+ (and (eq_attr "type" "load_ext")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,lsu1_power4,nothing,nothing,iu2_power4)\
+ |(du2_power4+du3_power4,lsu2_power4,nothing,nothing,iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4,nothing,nothing,iu1_power4)")
+
+(define_insn_reservation "power4-load-ext-update" 5
+ (and (eq_attr "type" "load_ext_u")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ lsu1_power4+iu2_power4,nothing,nothing,iu2_power4")
+
+(define_insn_reservation "power4-load-ext-update-indexed" 5
+ (and (eq_attr "type" "load_ext_ux")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ iu1_power4,lsu2_power4+iu1_power4,nothing,nothing,iu2_power4")
+
+(define_insn_reservation "power4-load-update-indexed" 3
+ (and (eq_attr "type" "load_ux")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ iu1_power4,lsu2_power4+iu2_power4")
+
+(define_insn_reservation "power4-load-update" 4 ; 3
+ (and (eq_attr "type" "load_u")
+ (eq_attr "cpu" "power4"))
+ "lsuq_power4")
+
+(define_insn_reservation "power4-fpload" 6 ; 5
+ (and (eq_attr "type" "fpload")
+ (eq_attr "cpu" "power4"))
+ "lsq_power4")
+
+(define_insn_reservation "power4-fpload-update" 6 ; 5
+ (and (eq_attr "type" "fpload_u,fpload_ux")
+ (eq_attr "cpu" "power4"))
+ "lsuq_power4")
+
+(define_insn_reservation "power4-vecload" 6 ; 5
+ (and (eq_attr "type" "vecload")
+ (eq_attr "cpu" "power4"))
+ "lsq_power4")
+
+(define_insn_reservation "power4-store" 1
+ (and (eq_attr "type" "store")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,lsu1_power4,iu1_power4)\
+ |(du2_power4,lsu2_power4,iu2_power4)\
+ |(du3_power4,lsu2_power4,nothing,iu2_power4)\
+ |(du4_power4,lsu1_power4,nothing,iu1_power4)")
+
+(define_insn_reservation "power4-store-update" 1
+ (and (eq_attr "type" "store_u")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,lsu1_power4+iu2_power4,iu1_power4)\
+ |(du2_power4+du3_power4,lsu2_power4+iu2_power4,iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4+iu1_power4,iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4,iu1_power4,iu2_power4)")
+
+(define_insn_reservation "power4-store-update-indexed" 1
+ (and (eq_attr "type" "store_ux")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ iu1_power4,lsu2_power4+iu2_power4,iu2_power4")
+
+(define_insn_reservation "power4-fpstore" 1
+ (and (eq_attr "type" "fpstore")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,lsu1_power4,fpu1_power4)\
+ |(du2_power4,lsu2_power4,fpu2_power4)\
+ |(du3_power4,lsu2_power4,nothing,fpu2_power4)\
+ |(du4_power4,lsu1_power4,nothing,fpu1_power4)")
+
+(define_insn_reservation "power4-fpstore-update" 1
+ (and (eq_attr "type" "fpstore_u,fpstore_ux")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,lsu1_power4+iu2_power4,fpu1_power4)\
+ |(du2_power4+du3_power4,lsu2_power4+iu2_power4,fpu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4+iu1_power4,fpu2_power4)")
+; |(du3_power4+du4_power4,nothing,lsu2_power4+iu1_power4,fpu2_power4)")
+
+(define_insn_reservation "power4-vecstore" 1
+ (and (eq_attr "type" "vecstore")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,lsu1_power4,vec_power4)\
+ |(du2_power4,lsu2_power4,vec_power4)\
+ |(du3_power4,lsu2_power4,nothing,vec_power4)\
+ |(du4_power4,lsu1_power4,nothing,vec_power4)")
+
+
+; Integer latency is 2 cycles
+(define_insn_reservation "power4-integer" 2
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "power4"))
+ "iq_power4")
+
+(define_insn_reservation "power4-insert" 4
+ (and (eq_attr "type" "insert_word")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4,nothing,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4,nothing,iu2_power4)\
+ |(du3_power4+du4_power4,iu2_power4,nothing,iu1_power4)")
+
+(define_insn_reservation "power4-cmp" 3
+ (and (eq_attr "type" "cmp,fast_compare")
+ (eq_attr "cpu" "power4"))
+ "iq_power4")
+
+(define_insn_reservation "power4-compare" 2
+ (and (eq_attr "type" "compare,delayed_compare")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4,iu2_power4)\
+ |(du3_power4+du4_power4,nothing,iu2_power4,iu1_power4)")
+
+(define_bypass 4 "power4-compare" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_insn_reservation "power4-lmul-cmp" 7
+ (and (eq_attr "type" "lmul_compare")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4*6,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4*6,iu2_power4)\
+ |(du3_power4+du4_power4,iu2_power4*6,iu1_power4)")
+; |(du3_power4+du4_power4,nothing,iu2_power4*6,iu1_power4)")
+
+(define_bypass 10 "power4-lmul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_insn_reservation "power4-imul-cmp" 5
+ (and (eq_attr "type" "imul_compare")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4*4,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4*4,iu2_power4)\
+ |(du3_power4+du4_power4,iu2_power4*4,iu1_power4)")
+; |(du3_power4+du4_power4,nothing,iu2_power4*4,iu1_power4)")
+
+(define_bypass 8 "power4-imul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_insn_reservation "power4-lmul" 7
+ (and (eq_attr "type" "lmul")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,iu1_power4*6)\
+ |(du2_power4,iu2_power4*6)\
+ |(du3_power4,iu2_power4*6)\
+ |(du4_power4,iu2_power4*6)")
+; |(du3_power4,nothing,iu2_power4*6)\
+; |(du4_power4,nothing,iu2_power4*6)")
+
+(define_insn_reservation "power4-imul" 5
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,iu1_power4*4)\
+ |(du2_power4,iu2_power4*4)\
+ |(du3_power4,iu2_power4*4)\
+ |(du4_power4,iu1_power4*4)")
+; |(du3_power4,nothing,iu2_power4*4)\
+; |(du4_power4,nothing,iu1_power4*4)")
+
+(define_insn_reservation "power4-imul3" 4
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,iu1_power4*3)\
+ |(du2_power4,iu2_power4*3)\
+ |(du3_power4,iu2_power4*3)\
+ |(du4_power4,iu1_power4*3)")
+; |(du3_power4,nothing,iu2_power4*3)\
+; |(du4_power4,nothing,iu1_power4*3)")
+
+
+; SPR move only executes in first IU.
+; Integer division only executes in second IU.
+(define_insn_reservation "power4-idiv" 36
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4,iu2_power4*35")
+
+(define_insn_reservation "power4-ldiv" 68
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4,iu2_power4*67")
+
+
+(define_insn_reservation "power4-mtjmpr" 3
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,bpu_power4")
+
+
+; Branches take dispatch Slot 4. The presence_sets prevent other insn from
+; grabbing previous dispatch slots once this is assigned.
+(define_insn_reservation "power4-branch" 2
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "power4"))
+ "(du5_power4\
+ |du4_power4+du5_power4\
+ |du3_power4+du4_power4+du5_power4\
+ |du2_power4+du3_power4+du4_power4+du5_power4\
+ |du1_power4+du2_power4+du3_power4+du4_power4+du5_power4),bpu_power4")
+
+
+; Condition Register logical ops are split if non-destructive (RT != RB)
+(define_insn_reservation "power4-crlogical" 2
+ (and (eq_attr "type" "cr_logical")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,cru_power4")
+
+(define_insn_reservation "power4-delayedcr" 4
+ (and (eq_attr "type" "delayed_cr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4,cru_power4,cru_power4")
+
+; 4 mfcrf (each 3 cyc, 1/cyc) + 3 fxu
+(define_insn_reservation "power4-mfcr" 6
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ du1_power4+du2_power4+du3_power4+du4_power4+cru_power4,\
+ cru_power4,cru_power4,cru_power4")
+
+; mfcrf (1 field)
+(define_insn_reservation "power4-mfcrf" 3
+ (and (eq_attr "type" "mfcrf")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,cru_power4")
+
+; mtcrf (1 field)
+(define_insn_reservation "power4-mtcr" 4
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,iu1_power4")
+
+; Basic FP latency is 6 cycles
+(define_insn_reservation "power4-fp" 6
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "power4"))
+ "fpq_power4")
+
+(define_insn_reservation "power4-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "power4"))
+ "fpq_power4")
+
+(define_insn_reservation "power4-sdiv" 33
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,fpu1_power4*28)\
+ |(du2_power4,fpu2_power4*28)\
+ |(du3_power4,fpu2_power4*28)\
+ |(du4_power4,fpu1_power4*28)")
+; |(du3_power4,nothing,fpu2_power4*28)\
+; |(du4_power4,nothing,fpu1_power4*28)")
+
+(define_insn_reservation "power4-sqrt" 40
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,fpu1_power4*35)\
+ |(du2_power4,fpu2_power4*35)\
+ |(du3_power4,fpu2_power4*35)\
+ |(du4_power4,fpu2_power4*35)")
+; |(du3_power4,nothing,fpu2_power4*35)\
+; |(du4_power4,nothing,fpu2_power4*35)")
+
+
+; VMX
+(define_insn_reservation "power4-vecsimple" 2
+ (and (eq_attr "type" "vecsimple")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+(define_insn_reservation "power4-veccomplex" 5
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+; vecfp compare
+(define_insn_reservation "power4-veccmp" 8
+ (and (eq_attr "type" "veccmp")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+(define_insn_reservation "power4-vecfloat" 8
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+(define_insn_reservation "power4-vecperm" 2
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "power4"))
+ "vpq_power4")
+
+(define_bypass 4 "power4-vecload" "power4-vecperm")
+
+(define_bypass 3 "power4-vecsimple" "power4-vecperm")
+(define_bypass 6 "power4-veccomplex" "power4-vecperm")
+(define_bypass 3 "power4-vecperm"
+ "power4-vecsimple,power4-veccomplex,power4-vecfloat")
+(define_bypass 9 "power4-vecfloat" "power4-vecperm")
+
+(define_bypass 5 "power4-vecsimple,power4-veccomplex"
+ "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_bypass 4 "power4-vecsimple,power4-vecperm" "power4-vecstore")
+(define_bypass 7 "power4-veccomplex" "power4-vecstore")
+(define_bypass 10 "power4-vecfloat" "power4-vecstore")
diff --git a/contrib/gcc/config/rs6000/power5.md b/contrib/gcc/config/rs6000/power5.md
new file mode 100644
index 0000000..59baa79
--- /dev/null
+++ b/contrib/gcc/config/rs6000/power5.md
@@ -0,0 +1,299 @@
+;; Scheduling description for IBM POWER5 processor.
+;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+;; Sources: IBM Red Book and White Paper on POWER5
+
+;; The POWER5 has 2 iu, 2 fpu, 2 lsu per engine (2 engines per chip).
+;; Instructions that update more than one register get broken into two
+;; (split) or more internal ops. The chip can issue up to 5
+;; internal ops per cycle.
+
+(define_automaton "power5iu,power5fpu,power5misc")
+
+(define_cpu_unit "iu1_power5,iu2_power5" "power5iu")
+(define_cpu_unit "lsu1_power5,lsu2_power5" "power5misc")
+(define_cpu_unit "fpu1_power5,fpu2_power5" "power5fpu")
+(define_cpu_unit "bpu_power5,cru_power5" "power5misc")
+(define_cpu_unit "du1_power5,du2_power5,du3_power5,du4_power5,du5_power5"
+ "power5misc")
+
+(define_reservation "lsq_power5"
+ "(du1_power5,lsu1_power5)\
+ |(du2_power5,lsu2_power5)\
+ |(du3_power5,nothing,lsu2_power5)\
+ |(du4_power5,nothing,lsu1_power5)")
+
+(define_reservation "iq_power5"
+ "(du1_power5,iu1_power5)\
+ |(du2_power5,iu2_power5)\
+ |(du3_power5,nothing,iu2_power5)\
+ |(du4_power5,nothing,iu1_power5)")
+
+(define_reservation "fpq_power5"
+ "(du1_power5,fpu1_power5)\
+ |(du2_power5,fpu2_power5)\
+ |(du3_power5,nothing,fpu2_power5)\
+ |(du4_power5,nothing,fpu1_power5)")
+
+; Dispatch slots are allocated in order conforming to program order.
+(absence_set "du1_power5" "du2_power5,du3_power5,du4_power5,du5_power5")
+(absence_set "du2_power5" "du3_power5,du4_power5,du5_power5")
+(absence_set "du3_power5" "du4_power5,du5_power5")
+(absence_set "du4_power5" "du5_power5")
+
+
+; Load/store
+(define_insn_reservation "power5-load" 4 ; 3
+ (and (eq_attr "type" "load")
+ (eq_attr "cpu" "power5"))
+ "lsq_power5")
+
+(define_insn_reservation "power5-load-ext" 5
+ (and (eq_attr "type" "load_ext")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-ext-update" 5
+ (and (eq_attr "type" "load_ext_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ lsu1_power5+iu2_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-ext-update-indexed" 5
+ (and (eq_attr "type" "load_ext_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu1_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-update-indexed" 3
+ (and (eq_attr "type" "load_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu2_power5")
+
+(define_insn_reservation "power5-load-update" 4 ; 3
+ (and (eq_attr "type" "load_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5")
+
+(define_insn_reservation "power5-fpload" 6 ; 5
+ (and (eq_attr "type" "fpload")
+ (eq_attr "cpu" "power5"))
+ "lsq_power5")
+
+(define_insn_reservation "power5-fpload-update" 6 ; 5
+ (and (eq_attr "type" "fpload_u,fpload_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5")
+
+(define_insn_reservation "power5-store" 1
+ (and (eq_attr "type" "store")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,lsu1_power5,iu1_power5)\
+ |(du2_power5,lsu2_power5,iu2_power5)\
+ |(du3_power5,lsu2_power5,nothing,iu2_power5)\
+ |(du4_power5,lsu1_power5,nothing,iu1_power5)")
+
+(define_insn_reservation "power5-store-update" 1
+ (and (eq_attr "type" "store_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5,iu1_power5")
+
+(define_insn_reservation "power5-store-update-indexed" 1
+ (and (eq_attr "type" "store_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu2_power5,iu2_power5")
+
+(define_insn_reservation "power5-fpstore" 1
+ (and (eq_attr "type" "fpstore")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,lsu1_power5,fpu1_power5)\
+ |(du2_power5,lsu2_power5,fpu2_power5)\
+ |(du3_power5,lsu2_power5,nothing,fpu2_power5)\
+ |(du4_power5,lsu1_power5,nothing,fpu1_power5)")
+
+(define_insn_reservation "power5-fpstore-update" 1
+ (and (eq_attr "type" "fpstore_u,fpstore_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5,fpu1_power5")
+
+
+; Integer latency is 2 cycles
+(define_insn_reservation "power5-integer" 2
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "power5"))
+ "iq_power5")
+
+(define_insn_reservation "power5-insert" 4
+ (and (eq_attr "type" "insert_word")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5,nothing,iu2_power5")
+
+(define_insn_reservation "power5-cmp" 3
+ (and (eq_attr "type" "cmp,fast_compare")
+ (eq_attr "cpu" "power5"))
+ "iq_power5")
+
+(define_insn_reservation "power5-compare" 2
+ (and (eq_attr "type" "compare,delayed_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5,iu2_power5")
+
+(define_bypass 4 "power5-compare" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-lmul-cmp" 7
+ (and (eq_attr "type" "lmul_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5*6,iu2_power5")
+
+(define_bypass 10 "power5-lmul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-imul-cmp" 5
+ (and (eq_attr "type" "imul_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5*4,iu2_power5")
+
+(define_bypass 8 "power5-imul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-lmul" 7
+ (and (eq_attr "type" "lmul")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*6)\
+ |(du2_power5,iu2_power5*6)\
+ |(du3_power5,iu2_power5*6)\
+ |(du4_power5,iu2_power5*6)")
+; |(du3_power5,nothing,iu2_power5*6)\
+; |(du4_power5,nothing,iu2_power5*6)")
+
+(define_insn_reservation "power5-imul" 5
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*4)\
+ |(du2_power5,iu2_power5*4)\
+ |(du3_power5,iu2_power5*4)\
+ |(du4_power5,iu1_power5*4)")
+; |(du3_power5,nothing,iu2_power5*4)\
+; |(du4_power5,nothing,iu1_power5*4)")
+
+(define_insn_reservation "power5-imul3" 4
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*3)\
+ |(du2_power5,iu2_power5*3)\
+ |(du3_power5,iu2_power5*3)\
+ |(du4_power5,iu1_power5*3)")
+; |(du3_power5,nothing,iu2_power5*3)\
+; |(du4_power5,nothing,iu1_power5*3)")
+
+
+; SPR move only executes in first IU.
+; Integer division only executes in second IU.
+(define_insn_reservation "power5-idiv" 36
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu2_power5*35")
+
+(define_insn_reservation "power5-ldiv" 68
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu2_power5*67")
+
+
+(define_insn_reservation "power5-mtjmpr" 3
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,bpu_power5")
+
+
+; Branches take dispatch Slot 4. The presence_sets prevent other insn from
+; grabbing previous dispatch slots once this is assigned.
+(define_insn_reservation "power5-branch" 2
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "power5"))
+ "(du5_power5\
+ |du4_power5+du5_power5\
+ |du3_power5+du4_power5+du5_power5\
+ |du2_power5+du3_power5+du4_power5+du5_power5\
+ |du1_power5+du2_power5+du3_power5+du4_power5+du5_power5),bpu_power5")
+
+
+; Condition Register logical ops are split if non-destructive (RT != RB)
+(define_insn_reservation "power5-crlogical" 2
+ (and (eq_attr "type" "cr_logical")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,cru_power5")
+
+(define_insn_reservation "power5-delayedcr" 4
+ (and (eq_attr "type" "delayed_cr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,cru_power5,cru_power5")
+
+; 4 mfcrf (each 3 cyc, 1/cyc) + 3 fxu
+(define_insn_reservation "power5-mfcr" 6
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ du1_power5+du2_power5+du3_power5+du4_power5+cru_power5,\
+ cru_power5,cru_power5,cru_power5")
+
+; mfcrf (1 field)
+(define_insn_reservation "power5-mfcrf" 3
+ (and (eq_attr "type" "mfcrf")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,cru_power5")
+
+; mtcrf (1 field)
+(define_insn_reservation "power5-mtcr" 4
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,iu1_power5")
+
+; Basic FP latency is 6 cycles
+(define_insn_reservation "power5-fp" 6
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "power5"))
+ "fpq_power5")
+
+(define_insn_reservation "power5-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "power5"))
+ "fpq_power5")
+
+(define_insn_reservation "power5-sdiv" 33
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,fpu1_power5*28)\
+ |(du2_power5,fpu2_power5*28)\
+ |(du3_power5,fpu2_power5*28)\
+ |(du4_power5,fpu1_power5*28)")
+; |(du3_power5,nothing,fpu2_power5*28)\
+; |(du4_power5,nothing,fpu1_power5*28)")
+
+(define_insn_reservation "power5-sqrt" 40
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,fpu1_power5*35)\
+ |(du2_power5,fpu2_power5*35)\
+ |(du3_power5,fpu2_power5*35)\
+ |(du4_power5,fpu2_power5*35)")
+; |(du3_power5,nothing,fpu2_power5*35)\
+; |(du4_power5,nothing,fpu2_power5*35)")
+
diff --git a/contrib/gcc/config/rs6000/ppc-asm.h b/contrib/gcc/config/rs6000/ppc-asm.h
index 2822e18..74e1483 100644
--- a/contrib/gcc/config/rs6000/ppc-asm.h
+++ b/contrib/gcc/config/rs6000/ppc-asm.h
@@ -95,21 +95,15 @@
* the real function with one or two leading periods respectively.
*/
-#ifdef _RELOCATABLE
-#define DESC_SECTION ".got2"
-#else
-#define DESC_SECTION ".got1"
-#endif
-
-#if defined(_CALL_AIXDESC)
+#if defined (__powerpc64__)
#define FUNC_NAME(name) GLUE(.,name)
#define JUMP_TARGET(name) FUNC_NAME(name)
#define FUNC_START(name) \
- .section DESC_SECTION,"aw"; \
+ .section ".opd","aw"; \
name: \
- .long GLUE(.,name); \
- .long _GLOBAL_OFFSET_TABLE_; \
- .long 0; \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
.previous; \
.type GLUE(.,name),@function; \
.globl name; \
@@ -120,15 +114,22 @@ GLUE(.,name):
GLUE(.L,name): \
.size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
-#elif defined (__powerpc64__)
+#elif defined(_CALL_AIXDESC)
+
+#ifdef _RELOCATABLE
+#define DESC_SECTION ".got2"
+#else
+#define DESC_SECTION ".got1"
+#endif
+
#define FUNC_NAME(name) GLUE(.,name)
#define JUMP_TARGET(name) FUNC_NAME(name)
#define FUNC_START(name) \
- .section ".opd","aw"; \
+ .section DESC_SECTION,"aw"; \
name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
+ .long GLUE(.,name); \
+ .long _GLOBAL_OFFSET_TABLE_; \
+ .long 0; \
.previous; \
.type GLUE(.,name),@function; \
.globl name; \
@@ -140,6 +141,7 @@ GLUE(.L,name): \
.size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
#else
+
#define FUNC_NAME(name) GLUE(__USER_LABEL_PREFIX__,name)
#if defined __PIC__ || defined __pic__
#define JUMP_TARGET(name) FUNC_NAME(name@plt)
@@ -156,3 +158,7 @@ GLUE(.L,name): \
.size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name)
#endif
+#if defined __linux__ && !defined __powerpc64__
+ .section .note.GNU-stack
+ .previous
+#endif
diff --git a/contrib/gcc/config/rs6000/ppc64-fp.c b/contrib/gcc/config/rs6000/ppc64-fp.c
index 3f6d7cd..c736d9a 100644
--- a/contrib/gcc/config/rs6000/ppc64-fp.c
+++ b/contrib/gcc/config/rs6000/ppc64-fp.c
@@ -31,19 +31,30 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if defined(__powerpc64__)
-#include "fp-bit.h"
+#include "config/fp-bit.h"
+extern DItype __fixtfdi (TFtype);
extern DItype __fixdfdi (DFtype);
extern DItype __fixsfdi (SFtype);
extern USItype __fixunsdfsi (DFtype);
extern USItype __fixunssfsi (SFtype);
+extern TFtype __floatditf (DItype);
extern DFtype __floatdidf (DItype);
extern SFtype __floatdisf (DItype);
+extern DItype __fixunstfdi (TFtype);
static DItype local_fixunssfdi (SFtype);
static DItype local_fixunsdfdi (DFtype);
DItype
+__fixtfdi (TFtype a)
+{
+ if (a < 0)
+ return - __fixunstfdi (-a);
+ return __fixunstfdi (a);
+}
+
+DItype
__fixdfdi (DFtype a)
{
if (a < 0)
@@ -77,14 +88,25 @@ __fixunssfsi (SFtype a)
return (SItype) a;
}
+TFtype
+__floatditf (DItype u)
+{
+ DFtype dh, dl;
+
+ dh = (SItype) (u >> (sizeof (SItype) * 8));
+ dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return (TFtype) dh + (TFtype) dl;
+}
+
DFtype
__floatdidf (DItype u)
{
DFtype d;
d = (SItype) (u >> (sizeof (SItype) * 8));
- d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
- d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
+ d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d;
@@ -109,13 +131,36 @@ __floatdisf (DItype u)
}
}
f = (SItype) (u >> (sizeof (SItype) * 8));
- f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
- f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
+ f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f;
}
+DItype
+__fixunstfdi (TFtype a)
+{
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ UDItype v = (USItype) b;
+ v <<= (sizeof (SItype) * 8);
+ /* Remove high part from the TFtype, leaving the low part as flonum. */
+ a -= (TFtype) v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (-a);
+ else
+ v += (USItype) a;
+ return v;
+}
+
/* This version is needed to prevent recursion; fixunsdfdi in libgcc
calls fixdfdi, which in turn calls calls fixunsdfdi. */
diff --git a/contrib/gcc/config/rs6000/rios1.md b/contrib/gcc/config/rs6000/rios1.md
new file mode 100644
index 0000000..5e77a67
--- /dev/null
+++ b/contrib/gcc/config/rs6000/rios1.md
@@ -0,0 +1,179 @@
+;; Scheduling description for IBM POWER processor.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "rios1,rios1fp")
+(define_cpu_unit "iu_rios1" "rios1")
+(define_cpu_unit "fpu_rios1" "rios1fp")
+(define_cpu_unit "bpu_rios1" "rios1")
+
+;; RIOS1 32-bit IU, FPU, BPU
+
+(define_insn_reservation "rios1-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-fpload" 2
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1")
+
+(define_insn_reservation "ppc601-fpload" 3
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-fpstore" 1
+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1+fpu_rios1")
+
+(define_insn_reservation "rios1-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-imul" 5
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*5")
+
+(define_insn_reservation "rios1-imul2" 4
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*4")
+
+(define_insn_reservation "rios1-imul3" 3
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*3")
+
+(define_insn_reservation "ppc601-imul" 5
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1*5")
+
+(define_insn_reservation "rios1-idiv" 19
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*19")
+
+(define_insn_reservation "ppc601-idiv" 36
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1*36")
+
+; compare executes on integer unit, but feeds insns which
+; execute on the branch unit.
+(define_insn_reservation "rios1-compare" 4
+ (and (eq_attr "type" "cmp,fast_compare,compare")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1,nothing*2,bpu_rios1")
+
+(define_insn_reservation "rios1-delayed_compare" 5
+ (and (eq_attr "type" "delayed_compare")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1,nothing*3,bpu_rios1")
+
+(define_insn_reservation "ppc601-compare" 3
+ (and (eq_attr "type" "cmp,compare,delayed_compare")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1,nothing,bpu_rios1")
+
+(define_insn_reservation "rios1-fpcompare" 9
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "rios1"))
+ "fpu_rios1,nothing*3,bpu_rios1")
+
+(define_insn_reservation "ppc601-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc601"))
+ "(fpu_rios1+iu_rios1*2),nothing*2,bpu_rios1")
+
+(define_insn_reservation "rios1-fp" 2
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "rios1"))
+ "fpu_rios1")
+
+(define_insn_reservation "ppc601-fp" 4
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1")
+
+(define_insn_reservation "rios1-dmul" 5
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1*2")
+
+(define_insn_reservation "rios1-sdiv" 19
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "rios1"))
+ "fpu_rios1*19")
+
+(define_insn_reservation "ppc601-sdiv" 17
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1*17")
+
+(define_insn_reservation "ppc601-ddiv" 31
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1*31")
+
+(define_insn_reservation "rios1-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-mtcr" 4
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-crlogical" 4
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "bpu_rios1")
+
+(define_insn_reservation "rios1-mtjmpr" 5
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "ppc601-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-branch" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "bpu_rios1")
+
diff --git a/contrib/gcc/config/rs6000/rios2.md b/contrib/gcc/config/rs6000/rios2.md
new file mode 100644
index 0000000..36690ac
--- /dev/null
+++ b/contrib/gcc/config/rs6000/rios2.md
@@ -0,0 +1,117 @@
+;; Scheduling description for IBM Power2 processor.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "rios2,rios2fp")
+(define_cpu_unit "iu1_rios2,iu2_rios2" "rios2")
+(define_cpu_unit "fpu1_rios2,fpu2_rios2" "rios2fp")
+(define_cpu_unit "bpu_rios2" "rios2")
+
+;; RIOS2 32-bit 2xIU, 2xFPU, BPU
+;; IU1 can perform all integer operations
+;; IU2 can perform all integer operations except imul and idiv
+
+(define_insn_reservation "rios2-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
+ load_ux,load_u,fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2|iu2_rios2")
+
+(define_insn_reservation "rios2-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2|iu2_rios2")
+
+(define_insn_reservation "rios2-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2|iu2_rios2")
+
+(define_insn_reservation "rios2-imul" 2
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2*2")
+
+(define_insn_reservation "rios2-idiv" 13
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2*13")
+
+; compare executes on integer unit, but feeds insns which
+; execute on the branch unit.
+(define_insn_reservation "rios2-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "rios2"))
+ "(iu1_rios2|iu2_rios2),nothing,bpu_rios2")
+
+(define_insn_reservation "rios2-fp" 2
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "rios2"))
+ "fpu1_rios2|fpu2_rios2")
+
+(define_insn_reservation "rios2-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "rios2"))
+ "(fpu1_rios2|fpu2_rios2),nothing*3,bpu_rios2")
+
+(define_insn_reservation "rios2-dmul" 2
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "rios2"))
+ "fpu1_rios2|fpu2_rios2")
+
+(define_insn_reservation "rios2-sdiv" 17
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "rios2"))
+ "(fpu1_rios2*17)|(fpu2_rios2*17)")
+
+(define_insn_reservation "rios2-ssqrt" 26
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "rios2"))
+ "(fpu1_rios2*26)|(fpu2_rios2*26)")
+
+(define_insn_reservation "rios2-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-crlogical" 3
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "rios2"))
+ "bpu_rios2")
+
+(define_insn_reservation "rios2-mtjmpr" 5
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-branch" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "rios2"))
+ "bpu_rios2")
+
diff --git a/contrib/gcc/config/rs6000/rs6000-c.c b/contrib/gcc/config/rs6000/rs6000-c.c
index 03f91ba..a47afee 100644
--- a/contrib/gcc/config/rs6000/rs6000-c.c
+++ b/contrib/gcc/config/rs6000/rs6000-c.c
@@ -1,28 +1,30 @@
/* Subroutines for the C front end on the POWER and PowerPC architectures.
- Copyright (C) 2002
+ Copyright (C) 2002, 2003
Free Software Foundation, Inc.
Contributed by Zack Weinberg <zack@codesourcery.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "cpplib.h"
#include "tree.h"
#include "c-pragma.h"
@@ -39,15 +41,14 @@ Boston, MA 02111-1307, USA. */
whether or not new function declarations receive a longcall
attribute by default. */
-#define SYNTAX_ERROR(msgid) do { \
+#define SYNTAX_ERROR(msgid) do { \
warning (msgid); \
warning ("ignoring malformed #pragma longcall"); \
return; \
} while (0)
void
-rs6000_pragma_longcall (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
tree x, n;
@@ -78,8 +79,7 @@ rs6000_pragma_longcall (pfile)
#define builtin_assert(TXT) cpp_assert (pfile, TXT)
void
-rs6000_cpu_cpp_builtins (pfile)
- cpp_reader *pfile;
+rs6000_cpu_cpp_builtins (cpp_reader *pfile)
{
if (TARGET_POWER2)
builtin_define ("_ARCH_PWR2");
@@ -112,9 +112,6 @@ rs6000_cpu_cpp_builtins (pfile)
case ABI_V4:
builtin_define ("_CALL_SYSV");
break;
- case ABI_AIX_NODESC:
- builtin_define ("_CALL_AIX");
- break;
case ABI_AIX:
builtin_define ("_CALL_AIXDESC");
builtin_define ("_CALL_AIX");
diff --git a/contrib/gcc/config/rs6000/rs6000-modes.def b/contrib/gcc/config/rs6000/rs6000-modes.def
index ac4112c..6f17f1a 100644
--- a/contrib/gcc/config/rs6000/rs6000-modes.def
+++ b/contrib/gcc/config/rs6000/rs6000-modes.def
@@ -1,23 +1,32 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/* 128-bit floating point. ABI_V4 uses IEEE quad, AIX/Darwin
+ adjust this in rs6000_override_options. */
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
+/* PSImode is used for the XER register. The XER register
+ is not used for anything; perhaps it should be deleted,
+ except that that would change register numbers. */
+PARTIAL_INT_MODE (SI);
/* Add any extra modes needed to represent the condition code.
@@ -26,6 +35,6 @@ Boston, MA 02111-1307, USA. */
use a mode for the case when we are comparing the results of two
comparisons, as then only the EQ bit is valid in the register. */
-CC (CCUNS)
-CC (CCFP)
-CC (CCEQ)
+CC_MODE (CCUNS);
+CC_MODE (CCFP);
+CC_MODE (CCEQ);
diff --git a/contrib/gcc/config/rs6000/rs6000-protos.h b/contrib/gcc/config/rs6000/rs6000-protos.h
index 4d6daa5..acac75a 100644
--- a/contrib/gcc/config/rs6000/rs6000-protos.h
+++ b/contrib/gcc/config/rs6000/rs6000-protos.h
@@ -1,23 +1,24 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#ifndef GCC_RS6000_PROTOS_H
#define GCC_RS6000_PROTOS_H
@@ -27,178 +28,187 @@ Boston, MA 02111-1307, USA. */
#ifdef RTX_CODE
#ifdef TREE_CODE
-extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int, int));
-extern void rs6000_va_start PARAMS ((tree, rtx));
+extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int);
+extern void rs6000_va_start (tree, rtx);
#endif /* TREE_CODE */
-extern struct rtx_def *rs6000_got_register PARAMS ((rtx));
-extern struct rtx_def *find_addr_reg PARAMS ((rtx));
-extern int any_operand PARAMS ((rtx, enum machine_mode));
-extern int short_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int u_short_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int non_short_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int exact_log2_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int gpc_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int cc_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int cc_reg_not_cr0_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_neg_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_aligned_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_u_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_arith_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_add_cint64_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_sub_cint64_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_logical_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int got_operand PARAMS ((rtx, enum machine_mode));
-extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
-extern int num_insns_constant PARAMS ((rtx, enum machine_mode));
-extern int easy_fp_constant PARAMS ((rtx, enum machine_mode));
-extern int zero_fp_constant PARAMS ((rtx, enum machine_mode));
-extern int zero_constant PARAMS ((rtx, enum machine_mode));
-extern int volatile_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int offsettable_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int mem_or_easy_const_operand PARAMS ((rtx, enum machine_mode));
-extern int add_operand PARAMS ((rtx, enum machine_mode));
-extern int non_add_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int non_logical_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int logical_operand PARAMS ((rtx, enum machine_mode));
-extern int mask_operand PARAMS ((rtx, enum machine_mode));
-extern int mask_operand_wrap PARAMS ((rtx, enum machine_mode));
-extern int mask64_operand PARAMS ((rtx, enum machine_mode));
-extern int mask64_2_operand PARAMS ((rtx, enum machine_mode));
-extern void build_mask64_2_operands PARAMS ((rtx, rtx *));
-extern int and64_operand PARAMS ((rtx, enum machine_mode));
-extern int and64_2_operand PARAMS ((rtx, enum machine_mode));
-extern int and_operand PARAMS ((rtx, enum machine_mode));
-extern int count_register_operand PARAMS ((rtx, enum machine_mode));
-extern int xer_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int lwa_operand PARAMS ((rtx, enum machine_mode));
-extern int call_operand PARAMS ((rtx, enum machine_mode));
-extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
-extern int input_operand PARAMS ((rtx, enum machine_mode));
-extern int small_data_operand PARAMS ((rtx, enum machine_mode));
-extern int s8bit_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int constant_pool_expr_p PARAMS ((rtx));
-extern int toc_relative_expr_p PARAMS ((rtx));
-extern int expand_block_move PARAMS ((rtx[]));
-extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern const char * rs6000_output_load_multiple PARAMS ((rtx[]));
-extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int branch_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int branch_positive_comparison_operator
- PARAMS ((rtx, enum machine_mode));
-extern int scc_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int trap_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int boolean_operator PARAMS ((rtx, enum machine_mode));
-extern int boolean_or_operator PARAMS ((rtx, enum machine_mode));
-extern int min_max_operator PARAMS ((rtx, enum machine_mode));
-extern int includes_lshift_p PARAMS ((rtx, rtx));
-extern int includes_rshift_p PARAMS ((rtx, rtx));
-extern int includes_rldic_lshift_p PARAMS ((rtx, rtx));
-extern int includes_rldicr_lshift_p PARAMS ((rtx, rtx));
-extern int registers_ok_for_quad_peep PARAMS ((rtx, rtx));
-extern int addrs_ok_for_quad_peep PARAMS ((rtx, rtx));
-extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
- enum machine_mode, rtx));
-extern int ccr_bit PARAMS ((rtx, int));
-extern int extract_MB PARAMS ((rtx));
-extern int extract_ME PARAMS ((rtx));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern void print_operand_address PARAMS ((FILE *, rtx));
-extern enum rtx_code rs6000_reverse_condition PARAMS ((enum machine_mode,
- enum rtx_code));
-extern void rs6000_emit_sCOND PARAMS ((enum rtx_code, rtx));
-extern void rs6000_emit_cbranch PARAMS ((enum rtx_code, rtx));
-extern char * output_cbranch PARAMS ((rtx, const char *, int, rtx));
-extern rtx rs6000_emit_set_const PARAMS ((rtx, enum machine_mode, rtx, int));
-extern int rs6000_emit_cmove PARAMS ((rtx, rtx, rtx, rtx));
-extern void rs6000_emit_minmax PARAMS ((rtx, enum rtx_code, rtx, rtx));
-extern void output_toc PARAMS ((FILE *, rtx, int, enum machine_mode));
-extern void rs6000_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern struct rtx_def *rs6000_longcall_ref PARAMS ((rtx));
-extern void rs6000_fatal_bad_address PARAMS ((rtx));
-extern int stmw_operation PARAMS ((rtx, enum machine_mode));
-extern int mtcrf_operation PARAMS ((rtx, enum machine_mode));
-extern int lmw_operation PARAMS ((rtx, enum machine_mode));
-extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
-extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
-extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
-extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-extern rtx rs6000_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
- int, int, int, int *));
-extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
-extern rtx rs6000_return_addr PARAMS ((int, rtx));
-extern void rs6000_output_symbol_ref PARAMS ((FILE*, rtx));
-
-extern rtx rs6000_machopic_legitimize_pic_address PARAMS ((rtx orig, enum machine_mode mode, rtx reg));
+extern struct rtx_def *rs6000_got_register (rtx);
+extern struct rtx_def *find_addr_reg (rtx);
+extern int any_operand (rtx, enum machine_mode);
+extern int short_cint_operand (rtx, enum machine_mode);
+extern int u_short_cint_operand (rtx, enum machine_mode);
+extern int non_short_cint_operand (rtx, enum machine_mode);
+extern int exact_log2_cint_operand (rtx, enum machine_mode);
+extern int gpc_reg_operand (rtx, enum machine_mode);
+extern int cc_reg_operand (rtx, enum machine_mode);
+extern int cc_reg_not_cr0_operand (rtx, enum machine_mode);
+extern int reg_or_short_operand (rtx, enum machine_mode);
+extern int reg_or_neg_short_operand (rtx, enum machine_mode);
+extern int reg_or_aligned_short_operand (rtx, enum machine_mode);
+extern int reg_or_u_short_operand (rtx, enum machine_mode);
+extern int reg_or_cint_operand (rtx, enum machine_mode);
+extern int reg_or_arith_cint_operand (rtx, enum machine_mode);
+extern int reg_or_add_cint64_operand (rtx, enum machine_mode);
+extern int reg_or_sub_cint64_operand (rtx, enum machine_mode);
+extern int reg_or_logical_cint_operand (rtx, enum machine_mode);
+extern int got_operand (rtx, enum machine_mode);
+extern int word_offset_memref_operand (rtx, enum machine_mode);
+extern int got_no_const_operand (rtx, enum machine_mode);
+extern int num_insns_constant (rtx, enum machine_mode);
+extern int easy_fp_constant (rtx, enum machine_mode);
+extern int easy_vector_constant (rtx, enum machine_mode);
+extern rtx gen_easy_vector_constant_add_self (rtx);
+extern const char *output_vec_const_move (rtx *);
+extern int zero_fp_constant (rtx, enum machine_mode);
+extern int zero_constant (rtx, enum machine_mode);
+extern int volatile_mem_operand (rtx, enum machine_mode);
+extern int offsettable_mem_operand (rtx, enum machine_mode);
+extern int mem_or_easy_const_operand (rtx, enum machine_mode);
+extern int add_operand (rtx, enum machine_mode);
+extern int non_add_cint_operand (rtx, enum machine_mode);
+extern int non_logical_cint_operand (rtx, enum machine_mode);
+extern int logical_operand (rtx, enum machine_mode);
+extern int mask_operand (rtx, enum machine_mode);
+extern int mask_operand_wrap (rtx, enum machine_mode);
+extern int mask64_operand (rtx, enum machine_mode);
+extern int mask64_2_operand (rtx, enum machine_mode);
+extern void build_mask64_2_operands (rtx, rtx *);
+extern int and64_operand (rtx, enum machine_mode);
+extern int and64_2_operand (rtx, enum machine_mode);
+extern int and_operand (rtx, enum machine_mode);
+extern int count_register_operand (rtx, enum machine_mode);
+extern int xer_operand (rtx, enum machine_mode);
+extern int reg_or_mem_operand (rtx, enum machine_mode);
+extern int lwa_operand (rtx, enum machine_mode);
+extern int call_operand (rtx, enum machine_mode);
+extern int current_file_function_operand (rtx, enum machine_mode);
+extern int input_operand (rtx, enum machine_mode);
+extern int small_data_operand (rtx, enum machine_mode);
+extern int s8bit_cint_operand (rtx, enum machine_mode);
+extern bool legitimate_constant_pool_address_p (rtx);
+extern int expand_block_move (rtx[]);
+extern int load_multiple_operation (rtx, enum machine_mode);
+extern const char * rs6000_output_load_multiple (rtx[]);
+extern int store_multiple_operation (rtx, enum machine_mode);
+extern int branch_comparison_operator (rtx, enum machine_mode);
+extern int branch_positive_comparison_operator (rtx, enum machine_mode);
+extern int scc_comparison_operator (rtx, enum machine_mode);
+extern int trap_comparison_operator (rtx, enum machine_mode);
+extern int boolean_operator (rtx, enum machine_mode);
+extern int boolean_or_operator (rtx, enum machine_mode);
+extern int min_max_operator (rtx, enum machine_mode);
+extern int includes_lshift_p (rtx, rtx);
+extern int includes_rshift_p (rtx, rtx);
+extern int includes_rldic_lshift_p (rtx, rtx);
+extern int includes_rldicr_lshift_p (rtx, rtx);
+extern int registers_ok_for_quad_peep (rtx, rtx);
+extern int addrs_ok_for_quad_peep (rtx, rtx);
+extern bool gpr_or_gpr_p (rtx, rtx);
+extern enum reg_class secondary_reload_class (enum reg_class,
+ enum machine_mode, rtx, int);
+extern int ccr_bit (rtx, int);
+extern int extract_MB (rtx);
+extern int extract_ME (rtx);
+extern void print_operand (FILE *, rtx, int);
+extern void print_operand_address (FILE *, rtx);
+extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
+ enum rtx_code);
+extern void rs6000_emit_sCOND (enum rtx_code, rtx);
+extern void rs6000_emit_cbranch (enum rtx_code, rtx);
+extern char * output_cbranch (rtx, const char *, int, rtx);
+extern char * output_e500_flip_gt_bit (rtx, rtx);
+extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int);
+extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx);
+extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);
+extern void output_toc (FILE *, rtx, int, enum machine_mode);
+extern void rs6000_initialize_trampoline (rtx, rtx, rtx);
+extern struct rtx_def *rs6000_longcall_ref (rtx);
+extern void rs6000_fatal_bad_address (rtx);
+extern int stmw_operation (rtx, enum machine_mode);
+extern int mfcr_operation (rtx, enum machine_mode);
+extern int mtcrf_operation (rtx, enum machine_mode);
+extern int lmw_operation (rtx, enum machine_mode);
+extern struct rtx_def *create_TOC_reference (rtx);
+extern void rs6000_split_multireg_move (rtx, rtx);
+extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
+extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
+extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
+ int, int, int, int *);
+extern int rs6000_legitimate_address (enum machine_mode, rtx, int);
+extern bool rs6000_mode_dependent_address (rtx);
+extern rtx rs6000_return_addr (int, rtx);
+extern void rs6000_output_symbol_ref (FILE*, rtx);
+extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
+
+extern rtx rs6000_machopic_legitimize_pic_address (rtx orig,
+ enum machine_mode mode, rtx reg);
#endif /* RTX_CODE */
#ifdef TREE_CODE
-extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
- tree, int));
-extern int function_arg_boundary PARAMS ((enum machine_mode, tree));
-extern struct rtx_def *function_arg PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern int function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
+extern unsigned int rs6000_special_round_type_align (tree, int, int);
+extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
+extern int function_arg_boundary (enum machine_mode, tree);
+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode,
- tree, int));
-extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree,
- int *, int));
-extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree));
-extern int function_ok_for_sibcall PARAMS ((tree));
+ tree, int);
+extern rtx rs6000_function_value (tree, tree);
+extern rtx rs6000_libcall_value (enum machine_mode);
+extern struct rtx_def *rs6000_va_arg (tree, tree);
+extern int function_ok_for_sibcall (tree);
+extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
-extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
+extern enum direction function_arg_padding (enum machine_mode, tree);
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */
-extern void optimization_options PARAMS ((int, int));
-extern void rs6000_override_options PARAMS ((const char *));
-extern void rs6000_file_start PARAMS ((FILE *, const char *));
-extern int direct_return PARAMS ((void));
-extern union tree_node *rs6000_build_va_list PARAMS ((void));
-extern int first_reg_to_save PARAMS ((void));
-extern int first_fp_reg_to_save PARAMS ((void));
-extern rs6000_stack_t *rs6000_stack_info PARAMS ((void));
-extern void output_ascii PARAMS ((FILE *, const char *, int));
-extern void rs6000_gen_section_name PARAMS ((char **, const char *,
- const char *));
-extern void output_function_profiler PARAMS ((FILE *, int));
-extern void output_profile_hook PARAMS ((int));
-extern int rs6000_trampoline_size PARAMS ((void));
-extern void toc_section PARAMS ((void));
-extern void sdata_section PARAMS ((void));
-extern void sdata2_section PARAMS ((void));
-extern void sbss_section PARAMS ((void));
-extern void private_data_section PARAMS ((void));
-extern void read_only_data_section PARAMS ((void));
-extern void read_only_private_data_section PARAMS ((void));
-extern int get_TOC_alias_set PARAMS ((void));
-extern int uses_TOC PARAMS ((void));
-extern void rs6000_emit_prologue PARAMS ((void));
-extern void rs6000_emit_load_toc_table PARAMS ((int));
-extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void));
-extern void rs6000_emit_epilogue PARAMS ((int));
-extern void debug_stack_info PARAMS ((rs6000_stack_t *));
-extern const char * output_isel PARAMS ((rtx *));
-extern int vrsave_operation PARAMS ((rtx, enum machine_mode));
-extern int rs6000_register_move_cost PARAMS ((enum machine_mode,
- enum reg_class, enum reg_class));
-extern int rs6000_memory_move_cost PARAMS ((enum machine_mode,
- enum reg_class, int));
+extern void optimization_options (int, int);
+extern void rs6000_override_options (const char *);
+extern int direct_return (void);
+extern int first_reg_to_save (void);
+extern int first_fp_reg_to_save (void);
+extern void output_ascii (FILE *, const char *, int);
+extern void rs6000_gen_section_name (char **, const char *, const char *);
+extern void output_function_profiler (FILE *, int);
+extern void output_profile_hook (int);
+extern int rs6000_trampoline_size (void);
+extern void toc_section (void);
+extern void sdata_section (void);
+extern void sdata2_section (void);
+extern void sbss_section (void);
+extern void private_data_section (void);
+extern void read_only_data_section (void);
+extern void read_only_private_data_section (void);
+extern int get_TOC_alias_set (void);
+extern void rs6000_emit_prologue (void);
+extern void rs6000_emit_load_toc_table (int);
+extern void rs6000_aix_emit_builtin_unwind_init (void);
+extern unsigned int rs6000_dbx_register_number (unsigned int);
+extern void rs6000_emit_epilogue (int);
+extern void rs6000_emit_eh_reg_restore (rtx, rtx);
+extern const char * output_isel (rtx *);
+extern int vrsave_operation (rtx, enum machine_mode);
+extern int rs6000_register_move_cost (enum machine_mode,
+ enum reg_class, enum reg_class);
+extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
+extern bool rs6000_tls_referenced_p (rtx);
+extern int rs6000_tls_symbol_ref (rtx, enum machine_mode);
+extern void rs6000_output_dwarf_dtprel (FILE*, int, rtx);
/* Declare functions in rs6000-c.c */
-#ifdef GCC_CPPLIB_H
-extern void rs6000_pragma_longcall PARAMS ((cpp_reader *));
-extern void rs6000_cpu_cpp_builtins PARAMS ((cpp_reader *));
+extern void rs6000_pragma_longcall (struct cpp_reader *);
+extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
+
+#if TARGET_MACHO
+char *output_call (rtx, rtx *, int, int);
#endif
#endif /* rs6000-protos.h */
diff --git a/contrib/gcc/config/rs6000/rs6000.c b/contrib/gcc/config/rs6000/rs6000.c
index 13f4ed3..33f47ce 100644
--- a/contrib/gcc/config/rs6000/rs6000.c
+++ b/contrib/gcc/config/rs6000/rs6000.c
@@ -1,27 +1,29 @@
/* Subroutines used for code generation on IBM RS/6000.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -48,14 +50,66 @@ Boston, MA 02111-1307, USA. */
#include "target-def.h"
#include "langhooks.h"
#include "reload.h"
+#include "cfglayout.h"
+#include "sched-int.h"
+#if TARGET_XCOFF
+#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
+#endif
#ifndef TARGET_NO_PROTOTYPE
#define TARGET_NO_PROTOTYPE 0
#endif
+#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
+#define EASY_VECTOR_15_ADD_SELF(n) ((n) >= 0x10 && (n) <= 0x1e \
+ && !((n) & 1))
+
#define min(A,B) ((A) < (B) ? (A) : (B))
#define max(A,B) ((A) > (B) ? (A) : (B))
+/* Structure used to define the rs6000 stack */
+typedef struct rs6000_stack {
+ int first_gp_reg_save; /* first callee saved GP register used */
+ int first_fp_reg_save; /* first callee saved FP register used */
+ int first_altivec_reg_save; /* first callee saved AltiVec register used */
+ int lr_save_p; /* true if the link reg needs to be saved */
+ int cr_save_p; /* true if the CR reg needs to be saved */
+ unsigned int vrsave_mask; /* mask of vec registers to save */
+ int toc_save_p; /* true if the TOC needs to be saved */
+ int push_p; /* true if we need to allocate stack space */
+ int calls_p; /* true if the function makes any calls */
+ enum rs6000_abi abi; /* which ABI to use */
+ int gp_save_offset; /* offset to save GP regs from initial SP */
+ int fp_save_offset; /* offset to save FP regs from initial SP */
+ int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
+ int lr_save_offset; /* offset to save LR from initial SP */
+ int cr_save_offset; /* offset to save CR from initial SP */
+ int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
+ int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
+ int toc_save_offset; /* offset to save the TOC pointer */
+ int varargs_save_offset; /* offset to save the varargs registers */
+ int ehrd_offset; /* offset to EH return data */
+ int reg_size; /* register size (4 or 8) */
+ int varargs_size; /* size to hold V.4 args passed in regs */
+ HOST_WIDE_INT vars_size; /* variable save area size */
+ int parm_size; /* outgoing parameter size */
+ int save_size; /* save area size */
+ int fixed_size; /* fixed size of stack frame */
+ int gp_size; /* size of saved GP registers */
+ int fp_size; /* size of saved FP registers */
+ int altivec_size; /* size of saved AltiVec registers */
+ int cr_size; /* size to hold CR if not in save_size */
+ int lr_size; /* size to hold LR if not in save_size */
+ int vrsave_size; /* size to hold VRSAVE if not in save_size */
+ int altivec_padding_size; /* size of altivec alignment padding if
+ not in save_size */
+ int spe_gp_size; /* size of 64-bit GPR save size for SPE */
+ int spe_padding_size;
+ int toc_size; /* size to hold TOC if not in save_size */
+ HOST_WIDE_INT total_size; /* total bytes allocated for stack */
+ int spe_64bit_regs_used;
+} rs6000_stack_t;
+
/* Target cpu type */
enum processor_type rs6000_cpu;
@@ -67,6 +121,25 @@ struct rs6000_cpu_select rs6000_select[3] =
{ (const char *)0, "-mtune=", 1, 0 },
};
+/* Always emit branch hint bits. */
+static GTY(()) bool rs6000_always_hint;
+
+/* Schedule instructions for group formation. */
+static GTY(()) bool rs6000_sched_groups;
+
+/* Support adjust_priority scheduler hook
+ and -mprioritize-restricted-insns= option. */
+const char *rs6000_sched_restricted_insns_priority_str;
+int rs6000_sched_restricted_insns_priority;
+
+/* Support for -msched-costly-dep option. */
+const char *rs6000_sched_costly_dep_str;
+enum rs6000_dependence_cost rs6000_sched_costly_dep;
+
+/* Support for -minsert-sched-nops option. */
+const char *rs6000_sched_insert_nops_str;
+enum rs6000_nop_insertion rs6000_sched_insert_nops;
+
/* Size of long double */
const char *rs6000_long_double_size_string;
int rs6000_long_double_type_size;
@@ -86,17 +159,23 @@ int rs6000_spe_abi;
/* Whether isel instructions should be generated. */
int rs6000_isel;
-/* Nonzero if we have FPRs. */
-int rs6000_fprs = 1;
+/* Whether SPE simd instructions should be generated. */
+int rs6000_spe;
+
+/* Nonzero if floating point operations are done in the GPRs. */
+int rs6000_float_gprs = 0;
+
+/* String from -mfloat-gprs=. */
+const char *rs6000_float_gprs_string;
/* String from -misel=. */
const char *rs6000_isel_string;
-/* Set to nonzero once AIX common-mode calls have been defined. */
-static int common_mode_defined;
+/* String from -mspe=. */
+const char *rs6000_spe_string;
-/* Private copy of original value of flag_pic for ABI_AIX. */
-static int rs6000_flag_pic;
+/* Set to nonzero once AIX common-mode calls have been defined. */
+static GTY(()) int common_mode_defined;
/* Save information from a "cmpxx" operation until the branch or scc is
emitted. */
@@ -109,7 +188,7 @@ int rs6000_pic_labelno;
#ifdef USING_ELFOS_H
/* Which abi to adhere to */
-const char *rs6000_abi_name = RS6000_ABI_NAME;
+const char *rs6000_abi_name;
/* Semantics of the small data area */
enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
@@ -121,6 +200,10 @@ const char *rs6000_sdata_name = (char *)0;
int fixuplabelno = 0;
#endif
+/* Bit size of immediate TLS offsets and string from which it is decoded. */
+int rs6000_tls_size = 32;
+const char *rs6000_tls_size_string;
+
/* ABI enumeration available for subtarget to use. */
enum rs6000_abi rs6000_current_abi;
@@ -132,6 +215,11 @@ const char *rs6000_debug_name;
int rs6000_debug_stack; /* debug stack applications */
int rs6000_debug_arg; /* debug argument handling */
+/* Opaque types. */
+static GTY(()) tree opaque_V2SI_type_node;
+static GTY(()) tree opaque_V2SF_type_node;
+static GTY(()) tree opaque_p_V2SI_type_node;
+
const char *rs6000_traceback_name;
static enum {
traceback_default = 0,
@@ -145,7 +233,7 @@ int toc_initialized;
char toc_label_name[10];
/* Alias set for saves and restores from the rs6000 stack. */
-static int rs6000_sr_alias_set;
+static GTY(()) int rs6000_sr_alias_set;
/* Call distance, overridden by -mlongcall and #pragma longcall(1).
The only place that looks at this is rs6000_set_default_type_attributes;
@@ -154,6 +242,11 @@ static int rs6000_sr_alias_set;
int rs6000_default_long_calls;
const char *rs6000_longcall_switch;
+/* Control alignment for fields within structures. */
+/* String from -malign-XXXXX. */
+const char *rs6000_alignment_string;
+int rs6000_alignment_flags;
+
struct builtin_description
{
/* mask is not const because we're going to alter it below. This
@@ -165,105 +258,173 @@ struct builtin_description
const enum rs6000_builtins code;
};
-static void rs6000_add_gc_roots PARAMS ((void));
-static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
-static void validate_condition_mode
- PARAMS ((enum rtx_code, enum machine_mode));
-static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
-static void rs6000_maybe_dead PARAMS ((rtx));
-static void rs6000_emit_stack_tie PARAMS ((void));
-static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
-static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
- unsigned int, int, int));
-static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
-static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
-static unsigned rs6000_hash_constant PARAMS ((rtx));
-static unsigned toc_hash_function PARAMS ((const void *));
-static int toc_hash_eq PARAMS ((const void *, const void *));
-static int toc_hash_mark_entry PARAMS ((void **, void *));
-static void toc_hash_mark_table PARAMS ((void *));
-static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
-static struct machine_function * rs6000_init_machine_status PARAMS ((void));
-static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
+static bool rs6000_function_ok_for_sibcall (tree, tree);
+static int num_insns_constant_wide (HOST_WIDE_INT);
+static void validate_condition_mode (enum rtx_code, enum machine_mode);
+static rtx rs6000_generate_compare (enum rtx_code);
+static void rs6000_maybe_dead (rtx);
+static void rs6000_emit_stack_tie (void);
+static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
+static rtx spe_synthesize_frame_save (rtx);
+static bool spe_func_has_64bit_regs_p (void);
+static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
+ int, HOST_WIDE_INT);
+static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
+static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
+static unsigned rs6000_hash_constant (rtx);
+static unsigned toc_hash_function (const void *);
+static int toc_hash_eq (const void *, const void *);
+static int constant_pool_expr_1 (rtx, int *, int *);
+static bool constant_pool_expr_p (rtx);
+static bool toc_relative_expr_p (rtx);
+static bool legitimate_small_data_p (enum machine_mode, rtx);
+static bool legitimate_offset_address_p (enum machine_mode, rtx, int);
+static bool legitimate_indexed_address_p (rtx, int);
+static bool legitimate_indirect_address_p (rtx, int);
+static bool macho_lo_sum_memory_operand (rtx x, enum machine_mode mode);
+static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
+static struct machine_function * rs6000_init_machine_status (void);
+static bool rs6000_assemble_integer (rtx, unsigned int, int);
#ifdef HAVE_GAS_HIDDEN
-static void rs6000_assemble_visibility PARAMS ((tree, int));
+static void rs6000_assemble_visibility (tree, int);
#endif
-static int rs6000_ra_ever_killed PARAMS ((void));
-static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
-const struct attribute_spec rs6000_attribute_table[];
-static void rs6000_set_default_type_attributes PARAMS ((tree));
-static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
-static rtx rs6000_emit_set_long_const PARAMS ((rtx,
- HOST_WIDE_INT, HOST_WIDE_INT));
+static int rs6000_ra_ever_killed (void);
+static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
+extern const struct attribute_spec rs6000_attribute_table[];
+static void rs6000_set_default_type_attributes (tree);
+static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ tree);
+static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
+static bool rs6000_return_in_memory (tree, tree);
+static void rs6000_file_start (void);
#if TARGET_ELF
-static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
- int));
-static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
-static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
-static void rs6000_elf_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-static void rs6000_elf_unique_section PARAMS ((tree, int));
-static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static void rs6000_elf_encode_section_info PARAMS ((tree, int))
+static unsigned int rs6000_elf_section_type_flags (tree, const char *, int);
+static void rs6000_elf_asm_out_constructor (rtx, int);
+static void rs6000_elf_asm_out_destructor (rtx, int);
+static void rs6000_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
+static void rs6000_elf_unique_section (tree, int);
+static void rs6000_elf_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static void rs6000_elf_encode_section_info (tree, rtx, int)
ATTRIBUTE_UNUSED;
-static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
-static bool rs6000_elf_in_small_data_p PARAMS ((tree));
+static bool rs6000_elf_in_small_data_p (tree);
#endif
#if TARGET_XCOFF
-static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
-static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
-static void rs6000_xcoff_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-static void rs6000_xcoff_unique_section PARAMS ((tree, int));
-static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
-static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
+static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
+static void rs6000_xcoff_asm_named_section (const char *, unsigned int);
+static void rs6000_xcoff_select_section (tree, int, unsigned HOST_WIDE_INT);
+static void rs6000_xcoff_unique_section (tree, int);
+static void rs6000_xcoff_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static const char * rs6000_xcoff_strip_name_encoding (const char *);
+static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
+static void rs6000_xcoff_file_start (void);
+static void rs6000_xcoff_file_end (void);
#endif
-static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
- ATTRIBUTE_UNUSED;
-static bool rs6000_binds_local_p PARAMS ((tree));
-static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int rs6000_adjust_priority PARAMS ((rtx, int));
-static int rs6000_issue_rate PARAMS ((void));
-
-static void rs6000_init_builtins PARAMS ((void));
-static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
-static void altivec_init_builtins PARAMS ((void));
-static void rs6000_common_init_builtins PARAMS ((void));
-
-static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
- int, enum rs6000_builtins,
- enum rs6000_builtins));
-static void spe_init_builtins PARAMS ((void));
-static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
-static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
-static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
-
-static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
-static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
-static void rs6000_parse_abi_options PARAMS ((void));
-static void rs6000_parse_vrsave_option PARAMS ((void));
-static void rs6000_parse_isel_option PARAMS ((void));
-static int first_altivec_reg_to_save PARAMS ((void));
-static unsigned int compute_vrsave_mask PARAMS ((void));
-static void is_altivec_return_reg PARAMS ((rtx, void *));
-static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
-static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
-static int easy_vector_constant PARAMS ((rtx));
+#if TARGET_MACHO
+static bool rs6000_binds_local_p (tree);
+#endif
+static int rs6000_use_dfa_pipeline_interface (void);
+static int rs6000_variable_issue (FILE *, int, rtx, int);
+static bool rs6000_rtx_costs (rtx, int, int, int *);
+static int rs6000_adjust_cost (rtx, rtx, rtx, int);
+static bool is_microcoded_insn (rtx);
+static int is_dispatch_slot_restricted (rtx);
+static bool is_cracked_insn (rtx);
+static bool is_branch_slot_insn (rtx);
+static int rs6000_adjust_priority (rtx, int);
+static int rs6000_issue_rate (void);
+static bool rs6000_is_costly_dependence (rtx, rtx, rtx, int, int);
+static rtx get_next_active_insn (rtx, rtx);
+static bool insn_terminates_group_p (rtx , enum group_termination);
+static bool is_costly_group (rtx *, rtx);
+static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
+static int redefine_groups (FILE *, int, rtx, rtx);
+static int pad_groups (FILE *, int, rtx, rtx);
+static void rs6000_sched_finish (FILE *, int);
+static int rs6000_use_sched_lookahead (void);
+
+static void rs6000_init_builtins (void);
+static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
+static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
+static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void altivec_init_builtins (void);
+static void rs6000_common_init_builtins (void);
+static void rs6000_init_libfuncs (void);
+
+static void enable_mask_for_builtins (struct builtin_description *, int,
+ enum rs6000_builtins,
+ enum rs6000_builtins);
+static void spe_init_builtins (void);
+static rtx spe_expand_builtin (tree, rtx, bool *);
+static rtx spe_expand_stv_builtin (enum insn_code, tree);
+static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
+static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
+static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
+static rs6000_stack_t *rs6000_stack_info (void);
+static void debug_stack_info (rs6000_stack_t *);
+
+static rtx altivec_expand_builtin (tree, rtx, bool *);
+static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
+static rtx altivec_expand_st_builtin (tree, rtx, bool *);
+static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
+static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
+static rtx altivec_expand_predicate_builtin (enum insn_code,
+ const char *, tree, rtx);
+static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
+static rtx altivec_expand_stv_builtin (enum insn_code, tree);
+static void rs6000_parse_abi_options (void);
+static void rs6000_parse_alignment_option (void);
+static void rs6000_parse_tls_size_option (void);
+static void rs6000_parse_yes_no_option (const char *, const char *, int *);
+static int first_altivec_reg_to_save (void);
+static unsigned int compute_vrsave_mask (void);
+static void is_altivec_return_reg (rtx, void *);
+static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
+int easy_vector_constant (rtx, enum machine_mode);
+static int easy_vector_same (rtx, enum machine_mode);
+static int easy_vector_splat_const (int, enum machine_mode);
+static bool is_ev64_opaque_type (tree);
+static rtx rs6000_dwarf_register_span (rtx);
+static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
+static rtx rs6000_tls_get_addr (void);
+static rtx rs6000_got_sym (void);
+static inline int rs6000_tls_symbol_ref_1 (rtx *, void *);
+static const char *rs6000_get_some_local_dynamic_name (void);
+static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
+static rtx rs6000_complex_function_value (enum machine_mode);
+static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode, tree);
+static rtx rs6000_mixed_function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
+static void setup_incoming_varargs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree,
+ int *, int);
+#if TARGET_MACHO
+static void macho_branch_islands (void);
+static void add_compiler_branch_island (tree, tree, int);
+static int no_previous_def (tree function_name);
+static tree get_prev_label (tree function_name);
+#endif
+
+static tree rs6000_build_builtin_va_list (void);
+
+/* Hash table stuff for keeping track of TOC entries. */
+
+struct toc_hash_struct GTY(())
+{
+ /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
+ ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
+ rtx key;
+ enum machine_mode key_mode;
+ int labelno;
+};
+
+static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
/* Default register names. */
char rs6000_reg_names[][8] =
@@ -317,9 +478,16 @@ static const char alt_reg_names[][8] =
#ifndef MASK_STRICT_ALIGN
#define MASK_STRICT_ALIGN 0
#endif
+#ifndef TARGET_PROFILE_KERNEL
+#define TARGET_PROFILE_KERNEL 0
+#endif
/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
+
+/* Return 1 for a symbol ref for a thread-local storage symbol. */
+#define RS6000_SYMBOL_REF_TLS_P(RTX) \
+ (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@@ -361,17 +529,35 @@ static const char alt_reg_names[][8] =
#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
#endif
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS HAVE_AS_TLS
+
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
+
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE rs6000_use_dfa_pipeline_interface
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
+
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
#undef TARGET_SCHED_ADJUST_PRIORITY
#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
+#undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
+#define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
+#undef TARGET_SCHED_FINISH
+#define TARGET_SCHED_FINISH rs6000_sched_finish
+
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS rs6000_init_builtins
@@ -379,18 +565,61 @@ static const char alt_reg_names[][8] =
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
+
+#if TARGET_MACHO
#undef TARGET_BINDS_LOCAL_P
#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
+#endif
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
-/* ??? Should work everywhere, but ask dje@watson.ibm.com before
- enabling for AIX. */
-#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
-#endif
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS rs6000_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
+#undef TARGET_VECTOR_OPAQUE_P
+#define TARGET_VECTOR_OPAQUE_P is_ev64_opaque_type
+
+#undef TARGET_DWARF_REGISTER_SPAN
+#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
+
+/* On rs6000, function arguments are promoted, as are function return
+ values. */
+#undef TARGET_PROMOTE_FUNCTION_ARGS
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#undef TARGET_PROMOTE_FUNCTION_RETURN
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+
+/* Structure return values are passed as an extra parameter. */
+#undef TARGET_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
+
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
+
+#undef TARGET_SETUP_INCOMING_VARARGS
+#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
+
+/* Always strict argument naming on rs6000. */
+#undef TARGET_STRICT_ARGUMENT_NAMING
+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
+#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_SPLIT_COMPLEX_ARG
+#define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
+
+#undef TARGET_BUILD_BUILTIN_VA_LIST
+#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -398,138 +627,117 @@ struct gcc_target targetm = TARGET_INITIALIZER;
type and sometimes adjust other TARGET_ options. */
void
-rs6000_override_options (default_cpu)
- const char *default_cpu;
+rs6000_override_options (const char *default_cpu)
{
size_t i, j;
struct rs6000_cpu_select *ptr;
+ int set_masks;
+
+ /* Simplifications for entries below. */
- /* Simplify the entries below by making a mask for any POWER
- variant and any PowerPC variant. */
+ enum {
+ POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
+ POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
+ };
-#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
-#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
- | MASK_PPC_GFXOPT | MASK_POWERPC64)
-#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
+ /* This table occasionally claims that a processor does not support
+ a particular feature even though it does, but the feature is slower
+ than the alternative. Thus, it shouldn't be relied on as a
+ complete description of the processor's support.
+ Please keep this list in order, and don't forget to update the
+ documentation in invoke.texi when adding a new processor or
+ flag. */
static struct ptt
{
const char *const name; /* Canonical processor name. */
const enum processor_type processor; /* Processor type enum value. */
const int target_enable; /* Target flags to enable. */
- const int target_disable; /* Target flags to disable. */
} const processor_target_table[]
- = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_MASKS},
- {"power", PROCESSOR_POWER,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"403", PROCESSOR_PPC403,
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
+ {"405", PROCESSOR_PPC405, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"405fp", PROCESSOR_PPC405, POWERPC_BASE_MASK},
+ {"440", PROCESSOR_PPC440, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"440fp", PROCESSOR_PPC440, POWERPC_BASE_MASK},
+ {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
+ {"601", PROCESSOR_PPC601,
+ MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
+ {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"620", PROCESSOR_PPC620,
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
+ {"630", PROCESSOR_PPC630,
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
+ {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
+ {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
+ {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"970", PROCESSOR_POWER4,
+ POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
+ {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
+ {"G5", PROCESSOR_POWER4,
+ POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
{"power2", PROCESSOR_POWER,
- MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
- POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
{"power3", PROCESSOR_PPC630,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
{"power4", PROCESSOR_POWER4,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
- {"powerpc", PROCESSOR_POWERPC,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"power5", PROCESSOR_POWER5,
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
{"powerpc64", PROCESSOR_POWERPC64,
- MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS},
- {"rios", PROCESSOR_RIOS1,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rios1", PROCESSOR_RIOS1,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rsc", PROCESSOR_PPC601,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rsc1", PROCESSOR_PPC601,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ POWERPC_BASE_MASK | MASK_POWERPC64},
+ {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
+ {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
{"rios2", PROCESSOR_RIOS2,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
- POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rs64a", PROCESSOR_RS64A,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS},
- {"401", PROCESSOR_PPC403,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"403", PROCESSOR_PPC403,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"405", PROCESSOR_PPC405,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"505", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"601", PROCESSOR_PPC601,
- MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"602", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"603", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"603e", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"ec603e", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"604", PROCESSOR_PPC604,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"604e", PROCESSOR_PPC604e,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"620", PROCESSOR_PPC620,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
- {"630", PROCESSOR_PPC630,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
- {"740", PROCESSOR_PPC750,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"750", PROCESSOR_PPC750,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"7400", PROCESSOR_PPC7400,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"7450", PROCESSOR_PPC7450,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"8540", PROCESSOR_PPC8540,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"801", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"821", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"823", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"860", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
+ MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
+ {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
+ {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
+ {"rs64a", PROCESSOR_RS64A, POWERPC_BASE_MASK | MASK_POWERPC64},
+ };
const size_t ptt_size = ARRAY_SIZE (processor_target_table);
- /* Save current -mmultiple/-mno-multiple status. */
- int multiple = TARGET_MULTIPLE;
- /* Save current -mstring/-mno-string status. */
- int string = TARGET_STRING;
+ /* Some OSs don't support saving the high part of 64-bit registers on
+ context switch. Other OSs don't support saving Altivec registers.
+ On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
+ settings; if the user wants either, the user must explicitly specify
+ them and we won't interfere with the user's specification. */
+
+ enum {
+ POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
+ POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT
+ | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
+ | MASK_MFCRF)
+ };
+ set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
+#ifdef OS_MISSING_POWERPC64
+ if (OS_MISSING_POWERPC64)
+ set_masks &= ~MASK_POWERPC64;
+#endif
+#ifdef OS_MISSING_ALTIVEC
+ if (OS_MISSING_ALTIVEC)
+ set_masks &= ~MASK_ALTIVEC;
+#endif
+
+ /* Don't override these by the processor default if given explicitly. */
+ set_masks &= ~(target_flags_explicit
+ & (MASK_MULTIPLE | MASK_STRING | MASK_SOFT_FLOAT));
/* Identify the processor type. */
rs6000_select[0].string = default_cpu;
@@ -548,8 +756,9 @@ rs6000_override_options (default_cpu)
if (ptr->set_arch_p)
{
- target_flags |= processor_target_table[j].target_enable;
- target_flags &= ~processor_target_table[j].target_disable;
+ target_flags &= ~set_masks;
+ target_flags |= (processor_target_table[j].target_enable
+ & set_masks);
}
break;
}
@@ -559,23 +768,13 @@ rs6000_override_options (default_cpu)
}
}
- if (rs6000_cpu == PROCESSOR_PPC8540)
+ if (TARGET_E500)
rs6000_isel = 1;
/* If we are optimizing big endian systems for space, use the load/store
multiple and string instructions. */
if (BYTES_BIG_ENDIAN && optimize_size)
- target_flags |= MASK_MULTIPLE | MASK_STRING;
-
- /* If -mmultiple or -mno-multiple was explicitly used, don't
- override with the processor default */
- if (TARGET_MULTIPLE_SET)
- target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
-
- /* If -mstring or -mno-string was explicitly used, don't override
- with the processor default. */
- if (TARGET_STRING_SET)
- target_flags = (target_flags & ~MASK_STRING) | string;
+ target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
/* Don't allow -mmultiple or -mstring on little endian systems
unless the cpu is a 750, because the hardware doesn't support the
@@ -583,33 +782,23 @@ rs6000_override_options (default_cpu)
trap. The 750 does not cause an alignment trap (except when the
target is unaligned). */
- if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
+ if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
{
if (TARGET_MULTIPLE)
{
target_flags &= ~MASK_MULTIPLE;
- if (TARGET_MULTIPLE_SET)
+ if ((target_flags_explicit & MASK_MULTIPLE) != 0)
warning ("-mmultiple is not supported on little endian systems");
}
if (TARGET_STRING)
{
target_flags &= ~MASK_STRING;
- if (TARGET_STRING_SET)
+ if ((target_flags_explicit & MASK_STRING) != 0)
warning ("-mstring is not supported on little endian systems");
}
}
- if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
- {
- rs6000_flag_pic = flag_pic;
- flag_pic = 0;
- }
-
- /* For Darwin, always silently make -fpic and -fPIC identical. */
- if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN)
- flag_pic = 2;
-
/* Set debug flags */
if (rs6000_debug_name)
{
@@ -649,14 +838,30 @@ rs6000_override_options (default_cpu)
rs6000_long_double_type_size = size;
}
+ /* Set Altivec ABI as default for powerpc64 linux. */
+ if (TARGET_ELF && TARGET_64BIT)
+ {
+ rs6000_altivec_abi = 1;
+ rs6000_altivec_vrsave = 1;
+ }
+
/* Handle -mabi= options. */
rs6000_parse_abi_options ();
- /* Handle -mvrsave= option. */
- rs6000_parse_vrsave_option ();
+ /* Handle -malign-XXXXX option. */
+ rs6000_parse_alignment_option ();
+
+ /* Handle generic -mFOO=YES/NO options. */
+ rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string,
+ &rs6000_altivec_vrsave);
+ rs6000_parse_yes_no_option ("isel", rs6000_isel_string,
+ &rs6000_isel);
+ rs6000_parse_yes_no_option ("spe", rs6000_spe_string, &rs6000_spe);
+ rs6000_parse_yes_no_option ("float-gprs", rs6000_float_gprs_string,
+ &rs6000_float_gprs);
- /* Handle -misel= option. */
- rs6000_parse_isel_option ();
+ /* Handle -mtls-size option. */
+ rs6000_parse_tls_size_option ();
#ifdef SUBTARGET_OVERRIDE_OPTIONS
SUBTARGET_OVERRIDE_OPTIONS;
@@ -665,6 +870,43 @@ rs6000_override_options (default_cpu)
SUBSUBTARGET_OVERRIDE_OPTIONS;
#endif
+ if (TARGET_E500)
+ {
+ if (TARGET_ALTIVEC)
+ error ("AltiVec and E500 instructions cannot coexist");
+
+ /* The e500 does not have string instructions, and we set
+ MASK_STRING above when optimizing for size. */
+ if ((target_flags & MASK_STRING) != 0)
+ target_flags = target_flags & ~MASK_STRING;
+
+ /* No SPE means 64-bit long doubles, even if an E500. */
+ if (rs6000_spe_string != 0
+ && !strcmp (rs6000_spe_string, "no"))
+ rs6000_long_double_type_size = 64;
+ }
+ else if (rs6000_select[1].string != NULL)
+ {
+ /* For the powerpc-eabispe configuration, we set all these by
+ default, so let's unset them if we manually set another
+ CPU that is not the E500. */
+ if (rs6000_abi_string == 0)
+ rs6000_spe_abi = 0;
+ if (rs6000_spe_string == 0)
+ rs6000_spe = 0;
+ if (rs6000_float_gprs_string == 0)
+ rs6000_float_gprs = 0;
+ if (rs6000_isel_string == 0)
+ rs6000_isel = 0;
+ if (rs6000_long_double_size_string == 0)
+ rs6000_long_double_type_size = 64;
+ }
+
+ rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
+ && rs6000_cpu != PROCESSOR_POWER5);
+ rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
+ || rs6000_cpu == PROCESSOR_POWER5);
+
/* Handle -m(no-)longcall option. This is a bit of a cheap hack,
using TARGET_OPTIONS to handle a toggle switch, but we're out of
bits in target_flags so TARGET_SWITCHES cannot be used.
@@ -681,6 +923,45 @@ rs6000_override_options (default_cpu)
rs6000_default_long_calls = (base[0] != 'n');
}
+ /* Handle -mprioritize-restricted-insns option. */
+ rs6000_sched_restricted_insns_priority
+ = (rs6000_sched_groups ? 1 : 0);
+ if (rs6000_sched_restricted_insns_priority_str)
+ rs6000_sched_restricted_insns_priority =
+ atoi (rs6000_sched_restricted_insns_priority_str);
+
+ /* Handle -msched-costly-dep option. */
+ rs6000_sched_costly_dep
+ = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
+ if (rs6000_sched_costly_dep_str)
+ {
+ if (! strcmp (rs6000_sched_costly_dep_str, "no"))
+ rs6000_sched_costly_dep = no_dep_costly;
+ else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
+ rs6000_sched_costly_dep = all_deps_costly;
+ else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
+ rs6000_sched_costly_dep = true_store_to_load_dep_costly;
+ else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
+ rs6000_sched_costly_dep = store_to_load_dep_costly;
+ else
+ rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
+ }
+
+ /* Handle -minsert-sched-nops option. */
+ rs6000_sched_insert_nops
+ = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
+ if (rs6000_sched_insert_nops_str)
+ {
+ if (! strcmp (rs6000_sched_insert_nops_str, "no"))
+ rs6000_sched_insert_nops = sched_finish_none;
+ else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
+ rs6000_sched_insert_nops = sched_finish_pad_groups;
+ else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
+ rs6000_sched_insert_nops = sched_finish_regroup_exact;
+ else
+ rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
+ }
+
#ifdef TARGET_REGNAMES
/* If the user desires alternate register names, copy in the
alternate names now. */
@@ -691,7 +972,7 @@ rs6000_override_options (default_cpu)
/* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
If -maix-struct-return or -msvr4-struct-return was explicitly
used, don't override with the ABI default. */
- if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
+ if ((target_flags_explicit & MASK_AIX_STRUCT_RET) == 0)
{
if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
@@ -701,10 +982,7 @@ rs6000_override_options (default_cpu)
if (TARGET_LONG_DOUBLE_128
&& (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
- real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
-
- /* Register global variables with the garbage collector. */
- rs6000_add_gc_roots ();
+ REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
/* Allocate an alias set for register saves & restores from stack. */
rs6000_sr_alias_set = new_alias_set ();
@@ -720,76 +998,119 @@ rs6000_override_options (default_cpu)
targetm.asm_out.unaligned_op.di = NULL;
}
+ /* Set maximum branch target alignment at two instructions, eight bytes. */
+ align_jumps_max_skip = 8;
+ align_loops_max_skip = 8;
+
/* Arrange to save and restore machine status around nested functions. */
init_machine_status = rs6000_init_machine_status;
+
+ /* We should always be splitting complex arguments, but we can't break
+ Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
+ if (DEFAULT_ABI != ABI_AIX)
+ targetm.calls.split_complex_arg = NULL;
}
-/* Handle -misel= option. */
+/* Handle generic options of the form -mfoo=yes/no.
+ NAME is the option name.
+ VALUE is the option value.
+ FLAG is the pointer to the flag where to store a 1 or 0, depending on
+ whether the option value is 'yes' or 'no' respectively. */
static void
-rs6000_parse_isel_option ()
+rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
{
- if (rs6000_isel_string == 0)
+ if (value == 0)
return;
- else if (! strcmp (rs6000_isel_string, "yes"))
- rs6000_isel = 1;
- else if (! strcmp (rs6000_isel_string, "no"))
- rs6000_isel = 0;
+ else if (!strcmp (value, "yes"))
+ *flag = 1;
+ else if (!strcmp (value, "no"))
+ *flag = 0;
else
- error ("unknown -misel= option specified: '%s'",
- rs6000_isel_string);
-}
-
-/* Handle -mvrsave= options. */
-static void
-rs6000_parse_vrsave_option ()
-{
- /* Generate VRSAVE instructions by default. */
- if (rs6000_altivec_vrsave_string == 0
- || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
- rs6000_altivec_vrsave = 1;
- else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
- rs6000_altivec_vrsave = 0;
- else
- error ("unknown -mvrsave= option specified: '%s'",
- rs6000_altivec_vrsave_string);
+ error ("unknown -m%s= option specified: '%s'", name, value);
}
/* Handle -mabi= options. */
static void
-rs6000_parse_abi_options ()
+rs6000_parse_abi_options (void)
{
if (rs6000_abi_string == 0)
return;
else if (! strcmp (rs6000_abi_string, "altivec"))
- rs6000_altivec_abi = 1;
+ {
+ rs6000_altivec_abi = 1;
+ rs6000_spe_abi = 0;
+ }
else if (! strcmp (rs6000_abi_string, "no-altivec"))
rs6000_altivec_abi = 0;
else if (! strcmp (rs6000_abi_string, "spe"))
- rs6000_spe_abi = 1;
+ {
+ rs6000_spe_abi = 1;
+ rs6000_altivec_abi = 0;
+ if (!TARGET_SPE_ABI)
+ error ("not configured for ABI: '%s'", rs6000_abi_string);
+ }
+
else if (! strcmp (rs6000_abi_string, "no-spe"))
rs6000_spe_abi = 0;
else
error ("unknown ABI specified: '%s'", rs6000_abi_string);
}
+/* Handle -malign-XXXXXX options. */
+static void
+rs6000_parse_alignment_option (void)
+{
+ if (rs6000_alignment_string == 0)
+ return;
+ else if (! strcmp (rs6000_alignment_string, "power"))
+ rs6000_alignment_flags = MASK_ALIGN_POWER;
+ else if (! strcmp (rs6000_alignment_string, "natural"))
+ rs6000_alignment_flags = MASK_ALIGN_NATURAL;
+ else
+ error ("unknown -malign-XXXXX option specified: '%s'",
+ rs6000_alignment_string);
+}
+
+/* Validate and record the size specified with the -mtls-size option. */
+
+static void
+rs6000_parse_tls_size_option (void)
+{
+ if (rs6000_tls_size_string == 0)
+ return;
+ else if (strcmp (rs6000_tls_size_string, "16") == 0)
+ rs6000_tls_size = 16;
+ else if (strcmp (rs6000_tls_size_string, "32") == 0)
+ rs6000_tls_size = 32;
+ else if (strcmp (rs6000_tls_size_string, "64") == 0)
+ rs6000_tls_size = 64;
+ else
+ error ("bad value `%s' for -mtls-size switch", rs6000_tls_size_string);
+}
+
void
-optimization_options (level, size)
- int level ATTRIBUTE_UNUSED;
- int size ATTRIBUTE_UNUSED;
+optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
{
}
/* Do anything needed at the start of the asm file. */
-void
-rs6000_file_start (file, default_cpu)
- FILE *file;
- const char *default_cpu;
+static void
+rs6000_file_start (void)
{
size_t i;
char buffer[80];
const char *start = buffer;
struct rs6000_cpu_select *ptr;
+ const char *default_cpu = TARGET_CPU_DEFAULT;
+ FILE *file = asm_out_file;
+
+ default_file_start ();
+
+#ifdef TARGET_BI_ARCH
+ if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
+ default_cpu = 0;
+#endif
if (flag_verbose_asm)
{
@@ -817,7 +1138,8 @@ rs6000_file_start (file, default_cpu)
if (rs6000_sdata && g_switch_value)
{
- fprintf (file, "%s -G %d", start, g_switch_value);
+ fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
+ g_switch_value);
start = "";
}
#endif
@@ -830,7 +1152,7 @@ rs6000_file_start (file, default_cpu)
/* Return nonzero if this function is known to have a null epilogue. */
int
-direct_return ()
+direct_return (void)
{
if (reload_completed)
{
@@ -852,18 +1174,15 @@ direct_return ()
/* Returns 1 always. */
int
-any_operand (op, mode)
- rtx op ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+any_operand (rtx op ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
return 1;
}
/* Returns 1 if op is the count register. */
int
-count_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+count_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != REG)
return 0;
@@ -879,9 +1198,7 @@ count_register_operand (op, mode)
/* Returns 1 if op is an altivec register. */
int
-altivec_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+altivec_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (register_operand (op, mode)
@@ -891,9 +1208,7 @@ altivec_register_operand (op, mode)
}
int
-xer_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+xer_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != REG)
return 0;
@@ -908,9 +1223,7 @@ xer_operand (op, mode)
by such constants completes more quickly. */
int
-s8bit_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+s8bit_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ( GET_CODE (op) == CONST_INT
&& (INTVAL (op) >= -128 && INTVAL (op) <= 127));
@@ -919,9 +1232,7 @@ s8bit_cint_operand (op, mode)
/* Return 1 if OP is a constant that can fit in a D field. */
int
-short_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+short_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
@@ -930,9 +1241,7 @@ short_cint_operand (op, mode)
/* Similar for an unsigned D field. */
int
-u_short_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+u_short_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
@@ -941,9 +1250,7 @@ u_short_cint_operand (op, mode)
/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
int
-non_short_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+non_short_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
@@ -953,9 +1260,7 @@ non_short_cint_operand (op, mode)
and an exact power of 2. */
int
-exact_log2_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+exact_log2_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& INTVAL (op) > 0
@@ -966,9 +1271,7 @@ exact_log2_cint_operand (op, mode)
ctr, or lr). */
int
-gpc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gpc_reg_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
&& (GET_CODE (op) != REG
@@ -981,9 +1284,7 @@ gpc_reg_operand (op, mode)
CR field. */
int
-cc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cc_reg_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
&& (GET_CODE (op) != REG
@@ -995,9 +1296,7 @@ cc_reg_operand (op, mode)
CR field that isn't CR0. */
int
-cc_reg_not_cr0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cc_reg_not_cr0_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
&& (GET_CODE (op) != REG
@@ -1010,23 +1309,22 @@ cc_reg_not_cr0_operand (op, mode)
mode unless MODE is VOIDmode. */
int
-reg_or_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_short_operand (rtx op, enum machine_mode mode)
{
return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
}
/* Similar, except check if the negation of the constant would be
- valid for a D-field. */
+ valid for a D-field. Don't allow a constant zero, since all the
+ patterns that call this predicate use "addic r1,r2,-constant" on
+ a constant value to set a carry when r2 is greater or equal to
+ "constant". That doesn't work for zero. */
int
-reg_or_neg_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_neg_short_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
- return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
+ return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P') && INTVAL (op) != 0;
return gpc_reg_operand (op, mode);
}
@@ -1036,9 +1334,7 @@ reg_or_neg_short_operand (op, mode)
mode unless MODE is VOIDmode. */
int
-reg_or_aligned_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_aligned_short_operand (rtx op, enum machine_mode mode)
{
if (gpc_reg_operand (op, mode))
return 1;
@@ -1053,9 +1349,7 @@ reg_or_aligned_short_operand (op, mode)
high-order 16 bits are zero. */
int
-reg_or_u_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_u_short_operand (rtx op, enum machine_mode mode)
{
return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
}
@@ -1064,9 +1358,7 @@ reg_or_u_short_operand (op, mode)
constant integer. */
int
-reg_or_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_cint_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
}
@@ -1075,9 +1367,7 @@ reg_or_cint_operand (op, mode)
32-bit signed constant integer. */
int
-reg_or_arith_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_arith_cint_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -1092,9 +1382,7 @@ reg_or_arith_cint_operand (op, mode)
signed constant integer valid for 64-bit addition. */
int
-reg_or_add_cint64_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_add_cint64_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -1111,9 +1399,7 @@ reg_or_add_cint64_operand (op, mode)
signed constant integer valid for 64-bit subtraction. */
int
-reg_or_sub_cint64_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_sub_cint64_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -1130,9 +1416,7 @@ reg_or_sub_cint64_operand (op, mode)
32-bit unsigned constant integer. */
int
-reg_or_logical_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_logical_cint_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1163,9 +1447,7 @@ reg_or_logical_cint_operand (op, mode)
/* Return 1 if the operand is an operand that can be loaded via the GOT. */
int
-got_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+got_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == CONST
@@ -1176,9 +1458,7 @@ got_operand (op, mode)
the GOT (labels involving addition aren't allowed). */
int
-got_no_const_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+got_no_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
}
@@ -1187,8 +1467,7 @@ got_no_const_operand (op, mode)
integer register. */
static int
-num_insns_constant_wide (value)
- HOST_WIDE_INT value;
+num_insns_constant_wide (HOST_WIDE_INT value)
{
/* signed constant loadable with {cal|addi} */
if (CONST_OK_FOR_LETTER_P (value, 'I'))
@@ -1222,9 +1501,7 @@ num_insns_constant_wide (value)
}
int
-num_insns_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+num_insns_constant (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1301,9 +1578,7 @@ num_insns_constant (op, mode)
safely read CONST_DOUBLE_{LOW,HIGH}. */
int
-easy_fp_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+easy_fp_constant (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != CONST_DOUBLE
|| GET_MODE (op) != mode
@@ -1374,65 +1649,228 @@ easy_fp_constant (op, mode)
abort ();
}
-/* Return 1 if the operand is a CONST_INT and can be put into a
- register with one instruction. */
+/* Returns the constant for the splat instrunction, if exists. */
static int
-easy_vector_constant (op)
- rtx op;
+easy_vector_splat_const (int cst, enum machine_mode mode)
{
- rtx elt;
- int units, i;
+ switch (mode)
+ {
+ case V4SImode:
+ if (EASY_VECTOR_15 (cst)
+ || EASY_VECTOR_15_ADD_SELF (cst))
+ return cst;
+ if ((cst & 0xffff) != ((cst >> 16) & 0xffff))
+ break;
+ cst = cst >> 16;
+ case V8HImode:
+ if (EASY_VECTOR_15 (cst)
+ || EASY_VECTOR_15_ADD_SELF (cst))
+ return cst;
+ if ((cst & 0xff) != ((cst >> 8) & 0xff))
+ break;
+ cst = cst >> 8;
+ case V16QImode:
+ if (EASY_VECTOR_15 (cst)
+ || EASY_VECTOR_15_ADD_SELF (cst))
+ return cst;
+ default:
+ break;
+ }
+ return 0;
+}
- if (GET_CODE (op) != CONST_VECTOR)
- return 0;
+
+/* Return nonzero if all elements of a vector have the same value. */
+
+static int
+easy_vector_same (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ int units, i, cst;
units = CONST_VECTOR_NUNITS (op);
- /* We can generate 0 easily. Look for that. */
- for (i = 0; i < units; ++i)
+ cst = INTVAL (CONST_VECTOR_ELT (op, 0));
+ for (i = 1; i < units; ++i)
+ if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst)
+ break;
+ if (i == units && easy_vector_splat_const (cst, mode))
+ return 1;
+ return 0;
+}
+
+/* Return 1 if the operand is a CONST_INT and can be put into a
+ register without using memory. */
+
+int
+easy_vector_constant (rtx op, enum machine_mode mode)
+{
+ int cst, cst2;
+
+ if (GET_CODE (op) != CONST_VECTOR
+ || (!TARGET_ALTIVEC
+ && !TARGET_SPE))
+ return 0;
+
+ if (zero_constant (op, mode)
+ && ((TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
+ || (TARGET_SPE && SPE_VECTOR_MODE (mode))))
+ return 1;
+
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+ return 0;
+
+ if (TARGET_SPE && mode == V1DImode)
+ return 0;
+
+ cst = INTVAL (CONST_VECTOR_ELT (op, 0));
+ cst2 = INTVAL (CONST_VECTOR_ELT (op, 1));
+
+ /* Limit SPE vectors to 15 bits signed. These we can generate with:
+ li r0, CONSTANT1
+ evmergelo r0, r0, r0
+ li r0, CONSTANT2
+
+ I don't know how efficient it would be to allow bigger constants,
+ considering we'll have an extra 'ori' for every 'li'. I doubt 5
+ instructions is better than a 64-bit memory load, but I don't
+ have the e500 timing specs. */
+ if (TARGET_SPE && mode == V2SImode
+ && cst >= -0x7fff && cst <= 0x7fff
+ && cst2 >= -0x7fff && cst2 <= 0x7fff)
+ return 1;
+
+ if (TARGET_ALTIVEC
+ && easy_vector_same (op, mode))
{
- elt = CONST_VECTOR_ELT (op, i);
+ cst = easy_vector_splat_const (cst, mode);
+ if (EASY_VECTOR_15_ADD_SELF (cst)
+ || EASY_VECTOR_15 (cst))
+ return 1;
+ }
+ return 0;
+}
+
+/* Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF. */
- /* We could probably simplify this by just checking for equality
- with CONST0_RTX for the current mode, but let's be safe
- instead. */
+int
+easy_vector_constant_add_self (rtx op, enum machine_mode mode)
+{
+ int cst;
+ if (TARGET_ALTIVEC
+ && GET_CODE (op) == CONST_VECTOR
+ && easy_vector_same (op, mode))
+ {
+ cst = easy_vector_splat_const (INTVAL (CONST_VECTOR_ELT (op, 0)), mode);
+ if (EASY_VECTOR_15_ADD_SELF (cst))
+ return 1;
+ }
+ return 0;
+}
+
+/* Generate easy_vector_constant out of a easy_vector_constant_add_self. */
+
+rtx
+gen_easy_vector_constant_add_self (rtx op)
+{
+ int i, units;
+ rtvec v;
+ units = GET_MODE_NUNITS (GET_MODE (op));
+ v = rtvec_alloc (units);
+
+ for (i = 0; i < units; i++)
+ RTVEC_ELT (v, i) =
+ GEN_INT (INTVAL (CONST_VECTOR_ELT (op, i)) >> 1);
+ return gen_rtx_raw_CONST_VECTOR (GET_MODE (op), v);
+}
+
+const char *
+output_vec_const_move (rtx *operands)
+{
+ int cst, cst2;
+ enum machine_mode mode;
+ rtx dest, vec;
- switch (GET_CODE (elt))
+ dest = operands[0];
+ vec = operands[1];
+
+ cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
+ cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
+ mode = GET_MODE (dest);
+
+ if (TARGET_ALTIVEC)
+ {
+ if (zero_constant (vec, mode))
+ return "vxor %0,%0,%0";
+ else if (easy_vector_constant (vec, mode))
{
- case CONST_INT:
- if (INTVAL (elt) != 0)
- return 0;
- break;
- case CONST_DOUBLE:
- if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
- return 0;
- break;
- default:
- return 0;
+ operands[1] = GEN_INT (cst);
+ switch (mode)
+ {
+ case V4SImode:
+ if (EASY_VECTOR_15 (cst))
+ {
+ operands[1] = GEN_INT (cst);
+ return "vspltisw %0,%1";
+ }
+ else if (EASY_VECTOR_15_ADD_SELF (cst))
+ return "#";
+ cst = cst >> 16;
+ case V8HImode:
+ if (EASY_VECTOR_15 (cst))
+ {
+ operands[1] = GEN_INT (cst);
+ return "vspltish %0,%1";
+ }
+ else if (EASY_VECTOR_15_ADD_SELF (cst))
+ return "#";
+ cst = cst >> 8;
+ case V16QImode:
+ if (EASY_VECTOR_15 (cst))
+ {
+ operands[1] = GEN_INT (cst);
+ return "vspltisb %0,%1";
+ }
+ else if (EASY_VECTOR_15_ADD_SELF (cst))
+ return "#";
+ default:
+ abort ();
+ }
}
+ else
+ abort ();
}
- /* We could probably generate a few other constants trivially, but
- gcc doesn't generate them yet. FIXME later. */
- return 1;
+ if (TARGET_SPE)
+ {
+ /* Vector constant 0 is handled as a splitter of V2SI, and in the
+ pattern of V1DI, V4HI, and V2SF.
+
+ FIXME: We should probably return # and add post reload
+ splitters for these, but this way is so easy ;-).
+ */
+ operands[1] = GEN_INT (cst);
+ operands[2] = GEN_INT (cst2);
+ if (cst == cst2)
+ return "li %0,%1\n\tevmergelo %0,%0,%0";
+ else
+ return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
+ }
+
+ abort ();
}
/* Return 1 if the operand is the constant 0. This works for scalars
as well as vectors. */
int
-zero_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+zero_constant (rtx op, enum machine_mode mode)
{
return op == CONST0_RTX (mode);
}
/* Return 1 if the operand is 0.0. */
int
-zero_fp_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+zero_fp_constant (rtx op, enum machine_mode mode)
{
return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
}
@@ -1443,9 +1881,7 @@ zero_fp_constant (op, mode)
recognize volatile references where its safe. */
int
-volatile_mem_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+volatile_mem_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
return 0;
@@ -1468,9 +1904,7 @@ volatile_mem_operand (op, mode)
/* Return 1 if the operand is an offsettable memory operand. */
int
-offsettable_mem_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+offsettable_mem_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == MEM)
&& offsettable_address_p (reload_completed || reload_in_progress,
@@ -1481,9 +1915,7 @@ offsettable_mem_operand (op, mode)
memory. */
int
-mem_or_easy_const_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+mem_or_easy_const_operand (rtx op, enum machine_mode mode)
{
return memory_operand (op, mode) || easy_fp_constant (op, mode);
}
@@ -1492,9 +1924,7 @@ mem_or_easy_const_operand (op, mode)
that can be used as the operand of a `mode' add insn. */
int
-add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+add_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
@@ -1506,9 +1936,7 @@ add_operand (op, mode)
/* Return 1 if OP is a constant but not a valid add_operand. */
int
-non_add_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+non_add_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
@@ -1519,9 +1947,7 @@ non_add_cint_operand (op, mode)
can be used as the operand of an OR or XOR insn on the RS/6000. */
int
-logical_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+logical_operand (rtx op, enum machine_mode mode)
{
HOST_WIDE_INT opl, oph;
@@ -1558,9 +1984,7 @@ logical_operand (op, mode)
above), but could be split into one. */
int
-non_logical_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+non_logical_cint_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
&& ! logical_operand (op, mode)
@@ -1573,9 +1997,7 @@ non_logical_cint_operand (op, mode)
away and confuse the making of MB and ME. */
int
-mask_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT c, lsb;
@@ -1617,9 +2039,7 @@ mask_operand (op, mode)
/* Return 1 for the PowerPC64 rlwinm corner case. */
int
-mask_operand_wrap (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask_operand_wrap (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT c, lsb;
@@ -1648,9 +2068,7 @@ mask_operand_wrap (op, mode)
confuses the making of MB and ME. */
int
-mask64_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask64_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1669,6 +2087,8 @@ mask64_operand (op, mode)
/* Find the transition, and check that all bits above are 1's. */
lsb = c & -c;
+
+ /* Match if all the bits above are 1's (or c is zero). */
return c == -lsb;
}
return 0;
@@ -1679,9 +2099,7 @@ mask64_operand (op, mode)
rldicr machine insns. */
int
-mask64_2_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1728,9 +2146,7 @@ mask64_2_operand (op, mode)
/* Generates shifts and masks for a pair of rldicl or rldicr insns to
implement ANDing by the mask IN. */
void
-build_mask64_2_operands (in, out)
- rtx in;
- rtx *out;
+build_mask64_2_operands (rtx in, rtx *out)
{
#if HOST_BITS_PER_WIDE_INT >= 64
unsigned HOST_WIDE_INT c, lsb, m1, m2;
@@ -1801,9 +2217,7 @@ build_mask64_2_operands (in, out)
that can be used as the operand of a PowerPC64 logical AND insn. */
int
-and64_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+and64_operand (rtx op, enum machine_mode mode)
{
if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
@@ -1815,11 +2229,9 @@ and64_operand (op, mode)
with two rldicl or rldicr insns. */
int
-and64_2_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+and64_2_operand (rtx op, enum machine_mode mode)
{
- if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
+ if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
return logical_operand (op, mode) || mask64_2_operand (op, mode);
@@ -1829,9 +2241,7 @@ and64_2_operand (op, mode)
constant that can be used as the operand of an RS/6000 logical AND insn. */
int
-and_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+and_operand (rtx op, enum machine_mode mode)
{
if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
@@ -1842,12 +2252,11 @@ and_operand (op, mode)
/* Return 1 if the operand is a general register or memory operand. */
int
-reg_or_mem_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_mem_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| memory_operand (op, mode)
+ || macho_lo_sum_memory_operand (op, mode)
|| volatile_mem_operand (op, mode));
}
@@ -1856,9 +2265,7 @@ reg_or_mem_operand (op, mode)
instruction. */
int
-lwa_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+lwa_operand (rtx op, enum machine_mode mode)
{
rtx inner = op;
@@ -1877,23 +2284,20 @@ lwa_operand (op, mode)
/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
int
-symbol_ref_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+symbol_ref_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
- return (GET_CODE (op) == SYMBOL_REF);
+ return (GET_CODE (op) == SYMBOL_REF
+ && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)));
}
/* Return 1 if the operand, used inside a MEM, is a valid first argument
to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
@@ -1906,25 +2310,22 @@ call_operand (op, mode)
}
/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
- this file and the function is not weakly defined. */
+ this file. */
int
-current_file_function_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+current_file_function_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (op)
- || (op == XEXP (DECL_RTL (current_function_decl), 0)
- && ! DECL_WEAK (current_function_decl))));
+ && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
+ && (SYMBOL_REF_LOCAL_P (op)
+ || (op == XEXP (DECL_RTL (current_function_decl), 0))));
}
/* Return 1 if this operand is a valid input for a move insn. */
int
-input_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+input_operand (rtx op, enum machine_mode mode)
{
/* Memory is always valid. */
if (memory_operand (op, mode))
@@ -1946,6 +2347,11 @@ input_operand (op, mode)
|| GET_CODE (op) == CONST_DOUBLE))
return 1;
+ /* Allow easy vector constants. */
+ if (GET_CODE (op) == CONST_VECTOR
+ && easy_vector_constant (op, mode))
+ return 1;
+
/* For floating-point or multi-word mode, the only remaining valid type
is a register. */
if (GET_MODE_CLASS (mode) == MODE_FLOAT
@@ -1959,11 +2365,11 @@ input_operand (op, mode)
return 1;
/* A SYMBOL_REF referring to the TOC is valid. */
- if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
+ if (legitimate_constant_pool_address_p (op))
return 1;
/* A constant pool expression (relative to the TOC) is valid */
- if (TOC_RELATIVE_EXPR_P (op))
+ if (toc_relative_expr_p (op))
return 1;
/* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
@@ -1976,12 +2382,31 @@ input_operand (op, mode)
return 0;
}
+
+/* Darwin, AIX increases natural record alignment to doubleword if the first
+ field is an FP double while the FP fields remain word aligned. */
+
+unsigned int
+rs6000_special_round_type_align (tree type, int computed, int specified)
+{
+ tree field = TYPE_FIELDS (type);
+
+ /* Skip all the static variables only if ABI is greater than
+ 1 or equal to 0. */
+ while (field != NULL && TREE_CODE (field) == VAR_DECL)
+ field = TREE_CHAIN (field);
+
+ if (field == NULL || field == type || DECL_MODE (field) != DFmode)
+ return MAX (computed, specified);
+
+ return MAX (MAX (computed, specified), 64);
+}
+
/* Return 1 for an operand in small memory on V.4/eabi. */
int
-small_data_operand (op, mode)
- rtx op ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_data_operand (rtx op ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
#if TARGET_ELF
rtx sym_ref;
@@ -2009,32 +2434,97 @@ small_data_operand (op, mode)
/* We have to be careful here, because it is the referenced address
that must be 32k from _SDA_BASE_, not just the symbol. */
summand = INTVAL (XEXP (sum, 1));
- if (summand < 0 || summand > g_switch_value)
+ if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
return 0;
sym_ref = XEXP (sum, 0);
}
- if (*XSTR (sym_ref, 0) != '@')
- return 0;
-
- return 1;
-
+ return SYMBOL_REF_SMALL_P (sym_ref);
#else
return 0;
#endif
}
+
+/* Return true, if operand is a memory operand and has a
+ displacement divisible by 4. */
+
+int
+word_offset_memref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ rtx addr;
+ int off = 0;
+
+ if (!memory_operand (op, mode))
+ return 0;
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 0)) == REG
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ off = INTVAL (XEXP (addr, 1));
+
+ return (off % 4) == 0;
+}
+
+/* Return true if operand is a (MEM (PLUS (REG) (offset))) where offset
+ is not divisible by four. */
+
+int
+invalid_gpr_mem (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ rtx addr;
+ long off;
+
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) != PLUS
+ || GET_CODE (XEXP (addr, 0)) != REG
+ || GET_CODE (XEXP (addr, 1)) != CONST_INT)
+ return 0;
+
+ off = INTVAL (XEXP (addr, 1));
+ return (off & 3) != 0;
+}
+
+/* Return true if operand is a hard register that can be used as a base
+ register. */
+
+int
+base_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ unsigned int regno;
+
+ if (!REG_P (op))
+ return 0;
+
+ regno = REGNO (op);
+ return regno != 0 && regno <= 31;
+}
+
+/* Return true if either operand is a general purpose register. */
+
+bool
+gpr_or_gpr_p (rtx op0, rtx op1)
+{
+ return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
+ || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
+}
+
+/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
+
static int
-constant_pool_expr_1 (op, have_sym, have_toc)
- rtx op;
- int *have_sym;
- int *have_toc;
+constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
{
switch (GET_CODE(op))
{
case SYMBOL_REF:
- if (CONSTANT_POOL_ADDRESS_P (op))
+ if (RS6000_SYMBOL_REF_TLS_P (op))
+ return 0;
+ else if (CONSTANT_POOL_ADDRESS_P (op))
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
{
@@ -2064,24 +2554,176 @@ constant_pool_expr_1 (op, have_sym, have_toc)
}
}
-int
-constant_pool_expr_p (op)
- rtx op;
+static bool
+constant_pool_expr_p (rtx op)
{
int have_sym = 0;
int have_toc = 0;
return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
}
-int
-toc_relative_expr_p (op)
- rtx op;
+static bool
+toc_relative_expr_p (rtx op)
+{
+ int have_sym = 0;
+ int have_toc = 0;
+ return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
+}
+
+/* SPE offset addressing is limited to 5-bits worth of double words. */
+#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
+
+bool
+legitimate_constant_pool_address_p (rtx x)
+{
+ return (TARGET_TOC
+ && GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
+ && constant_pool_expr_p (XEXP (x, 1)));
+}
+
+static bool
+legitimate_small_data_p (enum machine_mode mode, rtx x)
+{
+ return (DEFAULT_ABI == ABI_V4
+ && !flag_pic && !TARGET_TOC
+ && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
+ && small_data_operand (x, mode));
+}
+
+static bool
+legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
+{
+ unsigned HOST_WIDE_INT offset, extra;
+
+ if (GET_CODE (x) != PLUS)
+ return false;
+ if (GET_CODE (XEXP (x, 0)) != REG)
+ return false;
+ if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
+ return false;
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ return false;
+
+ offset = INTVAL (XEXP (x, 1));
+ extra = 0;
+ switch (mode)
+ {
+ case V16QImode:
+ case V8HImode:
+ case V4SFmode:
+ case V4SImode:
+ /* AltiVec vector modes. Only reg+reg addressing is valid here,
+ which leaves the only valid constant offset of zero, which by
+ canonicalization rules is also invalid. */
+ return false;
+
+ case V4HImode:
+ case V2SImode:
+ case V1DImode:
+ case V2SFmode:
+ /* SPE vector modes. */
+ return SPE_CONST_OFFSET_OK (offset);
+
+ case DFmode:
+ case DImode:
+ /* Both DFmode and DImode may end up in gprs. If gprs are 32-bit,
+ then we need to load/store at both offset and offset+4. */
+ if (!TARGET_POWERPC64)
+ extra = 4;
+ break;
+
+ case TFmode:
+ case TImode:
+ if (!TARGET_POWERPC64)
+ extra = 12;
+ else
+ extra = 8;
+ break;
+
+ default:
+ break;
+ }
+
+ offset += 0x8000;
+ return (offset < 0x10000) && (offset + extra < 0x10000);
+}
+
+static bool
+legitimate_indexed_address_p (rtx x, int strict)
{
- int have_sym = 0;
- int have_toc = 0;
- return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
+ rtx op0, op1;
+
+ if (GET_CODE (x) != PLUS)
+ return false;
+ op0 = XEXP (x, 0);
+ op1 = XEXP (x, 1);
+
+ if (!REG_P (op0) || !REG_P (op1))
+ return false;
+
+ return ((INT_REG_OK_FOR_BASE_P (op0, strict)
+ && INT_REG_OK_FOR_INDEX_P (op1, strict))
+ || (INT_REG_OK_FOR_BASE_P (op1, strict)
+ && INT_REG_OK_FOR_INDEX_P (op0, strict)));
}
+static inline bool
+legitimate_indirect_address_p (rtx x, int strict)
+{
+ return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
+}
+
+static bool
+macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
+{
+ if (!TARGET_MACHO || !flag_pic
+ || mode != SImode || GET_CODE(x) != MEM)
+ return false;
+ x = XEXP (x, 0);
+
+ if (GET_CODE (x) != LO_SUM)
+ return false;
+ if (GET_CODE (XEXP (x, 0)) != REG)
+ return false;
+ if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
+ return false;
+ x = XEXP (x, 1);
+
+ return CONSTANT_P (x);
+}
+
+static bool
+legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
+{
+ if (GET_CODE (x) != LO_SUM)
+ return false;
+ if (GET_CODE (XEXP (x, 0)) != REG)
+ return false;
+ if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
+ return false;
+ x = XEXP (x, 1);
+
+ if (TARGET_ELF || TARGET_MACHO)
+ {
+ if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
+ return false;
+ if (TARGET_TOC)
+ return false;
+ if (GET_MODE_NUNITS (mode) != 1)
+ return false;
+ if (GET_MODE_BITSIZE (mode) > 32
+ && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode))
+ return false;
+
+ return CONSTANT_P (x);
+ }
+
+ return false;
+}
+
+
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This is used from only one place: `memory_address' in explow.c.
@@ -2104,12 +2746,18 @@ toc_relative_expr_p (op)
Then check for the sum of a register and something not constant, try to
load the other things into a register and return the sum. */
+
rtx
-rs6000_legitimize_address (x, oldx, mode)
- rtx x;
- rtx oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode;
+rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
+ if (model != 0)
+ return rs6000_legitimize_tls_address (x, model);
+ }
+
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE (XEXP (x, 1)) == CONST_INT
@@ -2169,7 +2817,10 @@ rs6000_legitimize_address (x, oldx, mode)
return force_reg (Pmode, x);
}
- else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
+ else if (TARGET_ELF
+ && TARGET_32BIT
+ && TARGET_NO_TOC
+ && ! flag_pic
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x)
@@ -2178,11 +2829,14 @@ rs6000_legitimize_address (x, oldx, mode)
|| ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
{
rtx reg = gen_reg_rtx (Pmode);
- emit_insn (gen_elf_high (reg, (x)));
- return gen_rtx_LO_SUM (Pmode, reg, (x));
+ emit_insn (gen_elf_high (reg, x));
+ return gen_rtx_LO_SUM (Pmode, reg, x);
}
else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
&& ! flag_pic
+#if TARGET_MACHO
+ && ! MACHO_DYNAMIC_NO_PIC_P
+#endif
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x)
@@ -2191,11 +2845,11 @@ rs6000_legitimize_address (x, oldx, mode)
&& mode != TImode)
{
rtx reg = gen_reg_rtx (Pmode);
- emit_insn (gen_macho_high (reg, (x)));
- return gen_rtx_LO_SUM (Pmode, reg, (x));
+ emit_insn (gen_macho_high (reg, x));
+ return gen_rtx_LO_SUM (Pmode, reg, x);
}
else if (TARGET_TOC
- && CONSTANT_POOL_EXPR_P (x)
+ && constant_pool_expr_p (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
{
return create_TOC_reference (x);
@@ -2204,6 +2858,270 @@ rs6000_legitimize_address (x, oldx, mode)
return NULL_RTX;
}
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ switch (size)
+ {
+ case 4:
+ fputs ("\t.long\t", file);
+ break;
+ case 8:
+ fputs (DOUBLE_INT_ASM_OP, file);
+ break;
+ default:
+ abort ();
+ }
+ output_addr_const (file, x);
+ fputs ("@dtprel+0x8000", file);
+}
+
+/* Construct the SYMBOL_REF for the tls_get_addr function. */
+
+static GTY(()) rtx rs6000_tls_symbol;
+static rtx
+rs6000_tls_get_addr (void)
+{
+ if (!rs6000_tls_symbol)
+ rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
+
+ return rs6000_tls_symbol;
+}
+
+/* Construct the SYMBOL_REF for TLS GOT references. */
+
+static GTY(()) rtx rs6000_got_symbol;
+static rtx
+rs6000_got_sym (void)
+{
+ if (!rs6000_got_symbol)
+ {
+ rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
+ SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
+ }
+
+ return rs6000_got_symbol;
+}
+
+/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
+ this (thread-local) address. */
+
+static rtx
+rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
+{
+ rtx dest, insn;
+
+ dest = gen_reg_rtx (Pmode);
+ if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
+ {
+ rtx tlsreg;
+
+ if (TARGET_64BIT)
+ {
+ tlsreg = gen_rtx_REG (Pmode, 13);
+ insn = gen_tls_tprel_64 (dest, tlsreg, addr);
+ }
+ else
+ {
+ tlsreg = gen_rtx_REG (Pmode, 2);
+ insn = gen_tls_tprel_32 (dest, tlsreg, addr);
+ }
+ emit_insn (insn);
+ }
+ else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
+ {
+ rtx tlsreg, tmp;
+
+ tmp = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ {
+ tlsreg = gen_rtx_REG (Pmode, 13);
+ insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
+ }
+ else
+ {
+ tlsreg = gen_rtx_REG (Pmode, 2);
+ insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
+ }
+ emit_insn (insn);
+ if (TARGET_64BIT)
+ insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
+ else
+ insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
+ emit_insn (insn);
+ }
+ else
+ {
+ rtx r3, got, tga, tmp1, tmp2, eqv;
+
+ if (TARGET_64BIT)
+ got = gen_rtx_REG (Pmode, TOC_REGISTER);
+ else
+ {
+ if (flag_pic == 1)
+ got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+ else
+ {
+ rtx gsym = rs6000_got_sym ();
+ got = gen_reg_rtx (Pmode);
+ if (flag_pic == 0)
+ rs6000_emit_move (got, gsym, Pmode);
+ else
+ {
+ char buf[30];
+ static int tls_got_labelno = 0;
+ rtx tempLR, lab, tmp3, mem;
+ rtx first, last;
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LTLS", tls_got_labelno++);
+ lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
+ tempLR = gen_reg_rtx (Pmode);
+ tmp1 = gen_reg_rtx (Pmode);
+ tmp2 = gen_reg_rtx (Pmode);
+ tmp3 = gen_reg_rtx (Pmode);
+ mem = gen_rtx_MEM (Pmode, tmp1);
+ RTX_UNCHANGING_P (mem) = 1;
+
+ first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, lab,
+ gsym));
+ emit_move_insn (tmp1, tempLR);
+ emit_move_insn (tmp2, mem);
+ emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
+ last = emit_move_insn (got, tmp3);
+ REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, gsym,
+ REG_NOTES (last));
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
+ REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
+ REG_NOTES (last));
+ }
+ }
+ }
+
+ if (model == TLS_MODEL_GLOBAL_DYNAMIC)
+ {
+ r3 = gen_rtx_REG (Pmode, 3);
+ if (TARGET_64BIT)
+ insn = gen_tls_gd_64 (r3, got, addr);
+ else
+ insn = gen_tls_gd_32 (r3, got, addr);
+ start_sequence ();
+ emit_insn (insn);
+ tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
+ insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
+ insn = emit_call_insn (insn);
+ CONST_OR_PURE_CALL_P (insn) = 1;
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
+ insn = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insn, dest, r3, addr);
+ }
+ else if (model == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ r3 = gen_rtx_REG (Pmode, 3);
+ if (TARGET_64BIT)
+ insn = gen_tls_ld_64 (r3, got);
+ else
+ insn = gen_tls_ld_32 (r3, got);
+ start_sequence ();
+ emit_insn (insn);
+ tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
+ insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
+ insn = emit_call_insn (insn);
+ CONST_OR_PURE_CALL_P (insn) = 1;
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
+ insn = get_insns ();
+ end_sequence ();
+ tmp1 = gen_reg_rtx (Pmode);
+ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_TLSLD);
+ emit_libcall_block (insn, tmp1, r3, eqv);
+ if (rs6000_tls_size == 16)
+ {
+ if (TARGET_64BIT)
+ insn = gen_tls_dtprel_64 (dest, tmp1, addr);
+ else
+ insn = gen_tls_dtprel_32 (dest, tmp1, addr);
+ }
+ else if (rs6000_tls_size == 32)
+ {
+ tmp2 = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
+ else
+ insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
+ emit_insn (insn);
+ if (TARGET_64BIT)
+ insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
+ else
+ insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
+ }
+ else
+ {
+ tmp2 = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
+ else
+ insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
+ emit_insn (insn);
+ insn = gen_rtx_SET (Pmode, dest,
+ gen_rtx_PLUS (Pmode, tmp2, tmp1));
+ }
+ emit_insn (insn);
+ }
+ else
+ {
+ /* IE, or 64 bit offset LE. */
+ tmp2 = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ insn = gen_tls_got_tprel_64 (tmp2, got, addr);
+ else
+ insn = gen_tls_got_tprel_32 (tmp2, got, addr);
+ emit_insn (insn);
+ if (TARGET_64BIT)
+ insn = gen_tls_tls_64 (dest, tmp2, addr);
+ else
+ insn = gen_tls_tls_32 (dest, tmp2, addr);
+ emit_insn (insn);
+ }
+ }
+
+ return dest;
+}
+
+/* Return 1 if X is a SYMBOL_REF for a TLS symbol. This is used in
+ instruction definitions. */
+
+int
+rs6000_tls_symbol_ref (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return RS6000_SYMBOL_REF_TLS_P (x);
+}
+
+/* Return 1 if X contains a thread-local symbol. */
+
+bool
+rs6000_tls_referenced_p (rtx x)
+{
+ if (! TARGET_HAVE_TLS)
+ return false;
+
+ return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
+}
+
+/* Return 1 if *X is a thread-local symbol. This is the same as
+ rs6000_tls_symbol_ref except for the type of the unused argument. */
+
+static inline int
+rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
+{
+ return RS6000_SYMBOL_REF_TLS_P (*x);
+}
+
/* The convention appears to be to define this wherever it is used.
With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
is now used here. */
@@ -2225,13 +3143,8 @@ rs6000_legitimize_address (x, oldx, mode)
The Darwin code is inside #if TARGET_MACHO because only then is
machopic_function_base_name() defined. */
rtx
-rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
- rtx x;
- enum machine_mode mode;
- int opnum;
- int type;
- int ind_levels ATTRIBUTE_UNUSED;
- int *win;
+rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
+ int opnum, int type, int ind_levels ATTRIBUTE_UNUSED, int *win)
{
/* We must recognize output that we have already generated ourselves. */
if (GET_CODE (x) == PLUS
@@ -2306,25 +3219,33 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
if (GET_CODE (x) == SYMBOL_REF
&& DEFAULT_ABI == ABI_DARWIN
&& !ALTIVEC_VECTOR_MODE (mode)
- && flag_pic)
- {
- /* Darwin load of floating point constant. */
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode, x,
- gen_rtx (SYMBOL_REF, Pmode,
- machopic_function_base_name ())));
- x = gen_rtx (LO_SUM, GET_MODE (x),
- gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset)), offset);
+ && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+ /* Don't do this for TFmode, since the result isn't offsettable. */
+ && mode != TFmode)
+ {
+ if (flag_pic)
+ {
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode, x,
+ gen_rtx_SYMBOL_REF (Pmode,
+ machopic_function_base_name ())));
+ x = gen_rtx_LO_SUM (GET_MODE (x),
+ gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ gen_rtx_HIGH (Pmode, offset)), offset);
+ }
+ else
+ x = gen_rtx_LO_SUM (GET_MODE (x),
+ gen_rtx_HIGH (Pmode, x), x);
+
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
- BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
- opnum, (enum reload_type)type);
+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
+ opnum, (enum reload_type)type);
*win = 1;
return x;
}
#endif
if (TARGET_TOC
- && CONSTANT_POOL_EXPR_P (x)
+ && constant_pool_expr_p (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
{
(x) = create_TOC_reference (x);
@@ -2344,7 +3265,7 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
refers to a constant pool entry of an address (or the sum of it
plus a constant), a short (16-bit signed) constant plus a register,
the sum of two registers, or a register indirect, possibly with an
- auto-increment. For DFmode and DImode with an constant plus register,
+ auto-increment. For DFmode and DImode with a constant plus register,
we must ensure that both words are addressable or PowerPC64 with offset
word aligned.
@@ -2353,43 +3274,81 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */
int
-rs6000_legitimate_address (mode, x, reg_ok_strict)
- enum machine_mode mode;
- rtx x;
- int reg_ok_strict;
+rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
{
- if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
+ if (RS6000_SYMBOL_REF_TLS_P (x))
+ return 0;
+ if (legitimate_indirect_address_p (x, reg_ok_strict))
return 1;
if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
&& !ALTIVEC_VECTOR_MODE (mode)
&& !SPE_VECTOR_MODE (mode)
&& TARGET_UPDATE
- && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
+ && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
return 1;
- if (LEGITIMATE_SMALL_DATA_P (mode, x))
+ if (legitimate_small_data_p (mode, x))
return 1;
- if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
+ if (legitimate_constant_pool_address_p (x))
return 1;
/* If not REG_OK_STRICT (before reload) let pass any stack offset. */
if (! reg_ok_strict
&& GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
- && XEXP (x, 0) == virtual_stack_vars_rtx
+ && (XEXP (x, 0) == virtual_stack_vars_rtx
+ || XEXP (x, 0) == arg_pointer_rtx)
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
return 1;
- if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
+ if (legitimate_offset_address_p (mode, x, reg_ok_strict))
return 1;
if (mode != TImode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
|| (mode != DFmode && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
- && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
+ && legitimate_indexed_address_p (x, reg_ok_strict))
return 1;
- if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
+ if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
return 1;
return 0;
}
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for.
+
+ On the RS/6000 this is true of all integral offsets (since AltiVec
+ modes don't allow them) or is a pre-increment or decrement.
+
+ ??? Except that due to conceptual problems in offsettable_address_p
+ we can't really report the problems of integral offsets. So leave
+ this assuming that the adjustable offset must be valid for the
+ sub-words of a TFmode operand, which is what we had before. */
+
+bool
+rs6000_mode_dependent_address (rtx addr)
+{
+ switch (GET_CODE (addr))
+ {
+ case PLUS:
+ if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ {
+ unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
+ return val + 12 + 0x8000 >= 0x10000;
+ }
+ break;
+
+ case LO_SUM:
+ return true;
+
+ case PRE_INC:
+ case PRE_DEC:
+ return TARGET_UPDATE;
+
+ default:
+ break;
+ }
+
+ return false;
+}
/* Try to output insns to set TARGET equal to the constant C if it can
be done in less than N insns. Do all computations in MODE.
@@ -2398,10 +3357,8 @@ rs6000_legitimate_address (mode, x, reg_ok_strict)
insns, zero is returned and no insns and emitted. */
rtx
-rs6000_emit_set_const (dest, mode, source, n)
- rtx dest, source;
- enum machine_mode mode;
- int n ATTRIBUTE_UNUSED;
+rs6000_emit_set_const (rtx dest, enum machine_mode mode,
+ rtx source, int n ATTRIBUTE_UNUSED)
{
rtx result, insn, set;
HOST_WIDE_INT c0, c1;
@@ -2463,9 +3420,7 @@ rs6000_emit_set_const (dest, mode, source, n)
exponential run times encountered when looking for longer sequences
with rs6000_emit_set_const. */
static rtx
-rs6000_emit_set_long_const (dest, c1, c2)
- rtx dest;
- HOST_WIDE_INT c1, c2;
+rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
{
if (!TARGET_POWERPC64)
{
@@ -2494,7 +3449,7 @@ rs6000_emit_set_long_const (dest, c1, c2)
|| (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
{
if (ud1 & 0x8000)
- emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
+ emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
else
emit_move_insn (dest, GEN_INT (ud1));
}
@@ -2549,10 +3504,7 @@ rs6000_emit_set_long_const (dest, c1, c2)
/* Emit a move from SOURCE to DEST in mode MODE. */
void
-rs6000_emit_move (dest, source, mode)
- rtx dest;
- rtx source;
- enum machine_mode mode;
+rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
{
rtx operands[2];
operands[0] = dest;
@@ -2640,6 +3592,15 @@ rs6000_emit_move (dest, source, mode)
}
}
+ /* Recognize the case where operand[1] is a reference to thread-local
+ data and load its address to a register. */
+ if (GET_CODE (operands[1]) == SYMBOL_REF)
+ {
+ enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
+ if (model != 0)
+ operands[1] = rs6000_legitimize_tls_address (operands[1], model);
+ }
+
/* Handle the case where reload calls us with an invalid address. */
if (reload_in_progress && mode == Pmode
&& (! general_operand (operands[1], mode)
@@ -2649,7 +3610,26 @@ rs6000_emit_move (dest, source, mode)
/* Handle the case of CONSTANT_P_RTX. */
if (GET_CODE (operands[1]) == CONSTANT_P_RTX)
goto emit_set;
-
+
+ /* 128-bit constant floating-point values on Darwin should really be
+ loaded as two parts. */
+ if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
+ && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
+ know how to get a DFmode SUBREG of a TFmode. */
+ rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
+ simplify_gen_subreg (DImode, operands[1], mode, 0),
+ DImode);
+ rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
+ GET_MODE_SIZE (DImode)),
+ simplify_gen_subreg (DImode, operands[1], mode,
+ GET_MODE_SIZE (DImode)),
+ DImode);
+ return;
+ }
+
/* FIXME: In the long term, this switch statement should go away
and be replaced by a sequence of tests based on things like
mode == Pmode. */
@@ -2679,7 +3659,7 @@ rs6000_emit_move (dest, source, mode)
case V2SImode:
case V1DImode:
if (CONSTANT_P (operands[1])
- && !easy_vector_constant (operands[1]))
+ && !easy_vector_constant (operands[1], mode))
operands[1] = force_const_mem (mode, operands[1]);
break;
@@ -2706,7 +3686,8 @@ rs6000_emit_move (dest, source, mode)
}
if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_NO_TOC && ! flag_pic
+ && TARGET_NO_TOC
+ && ! flag_pic
&& mode == Pmode
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
@@ -2727,13 +3708,26 @@ rs6000_emit_move (dest, source, mode)
new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
CONSTANT_POOL_ADDRESS_P (new_ref)
= CONSTANT_POOL_ADDRESS_P (operands[1]);
- SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
+ SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
+ SYMBOL_REF_DECL (new_ref) = SYMBOL_REF_DECL (operands[1]);
operands[1] = new_ref;
}
if (DEFAULT_ABI == ABI_DARWIN)
{
+#if TARGET_MACHO
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ {
+ /* Take care of any required data indirection. */
+ operands[1] = rs6000_machopic_legitimize_pic_address (
+ operands[1], mode, operands[0]);
+ if (operands[0] != operands[1])
+ emit_insn (gen_rtx_SET (VOIDmode,
+ operands[0], operands[1]));
+ return;
+ }
+#endif
emit_insn (gen_macho_high (target, operands[1]));
emit_insn (gen_macho_low (operands[0], target, operands[1]));
return;
@@ -2749,7 +3743,7 @@ rs6000_emit_move (dest, source, mode)
reference to it. */
if (TARGET_TOC
&& GET_CODE (operands[1]) == SYMBOL_REF
- && CONSTANT_POOL_EXPR_P (operands[1])
+ && constant_pool_expr_p (operands[1])
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
get_pool_mode (operands[1])))
{
@@ -2764,8 +3758,8 @@ rs6000_emit_move (dest, source, mode)
|| (GET_CODE (operands[0]) == REG
&& FP_REGNO_P (REGNO (operands[0]))))
&& GET_CODE (operands[1]) != HIGH
- && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
- && ! TOC_RELATIVE_EXPR_P (operands[1]))
+ && ! legitimate_constant_pool_address_p (operands[1])
+ && ! toc_relative_expr_p (operands[1]))
{
/* Emit a USE operation so that the constant isn't deleted if
expensive optimizations are turned on because nobody
@@ -2778,7 +3772,7 @@ rs6000_emit_move (dest, source, mode)
#if TARGET_MACHO
/* Darwin uses a special PIC legitimizer. */
- if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
+ if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
{
operands[1] =
rs6000_machopic_legitimize_pic_address (operands[1], mode,
@@ -2816,7 +3810,7 @@ rs6000_emit_move (dest, source, mode)
operands[1] = force_const_mem (mode, operands[1]);
if (TARGET_TOC
- && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
+ && constant_pool_expr_p (XEXP (operands[1], 0))
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
get_pool_constant (XEXP (operands[1], 0)),
get_pool_mode (XEXP (operands[1], 0))))
@@ -2845,7 +3839,7 @@ rs6000_emit_move (dest, source, mode)
= replace_equiv_address (operands[1],
copy_addr_to_reg (XEXP (operands[1], 0)));
if (TARGET_POWER)
- {
+ {
emit_insn (gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (2,
gen_rtx_SET (VOIDmode,
@@ -2870,6 +3864,52 @@ rs6000_emit_move (dest, source, mode)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
}
+/* Nonzero if we can use a floating-point register to pass this arg. */
+#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
+ (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ && (CUM)->fregno <= FP_ARG_MAX_REG \
+ && TARGET_HARD_FLOAT && TARGET_FPRS)
+
+/* Nonzero if we can use an AltiVec register to pass this arg. */
+#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
+ (ALTIVEC_VECTOR_MODE (MODE) \
+ && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
+ && TARGET_ALTIVEC_ABI \
+ && (NAMED))
+
+/* Return a nonzero value to say to return the function value in
+ memory, just as large structures are always returned. TYPE will be
+ the data type of the value, and FNTYPE will be the type of the
+ function doing the returning, or @code{NULL} for libcalls.
+
+ The AIX ABI for the RS/6000 specifies that all structures are
+ returned in memory. The Darwin ABI does the same. The SVR4 ABI
+ specifies that structures <= 8 bytes are returned in r3/r4, but a
+ draft put them in memory, and GCC used to implement the draft
+ instead of the final standard. Therefore, TARGET_AIX_STRUCT_RET
+ controls this instead of DEFAULT_ABI; V.4 targets needing backward
+ compatibility can change DRAFT_V4_STRUCT_RET to override the
+ default, and -m switches get the final word. See
+ rs6000_override_options for more details.
+
+ The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
+ long double support is enabled. These values are returned in memory.
+
+ int_size_in_bytes returns -1 for variable size objects, which go in
+ memory always. The cast to unsigned makes -1 > 8. */
+
+static bool
+rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+{
+ if (AGGREGATE_TYPE_P (type)
+ && (TARGET_AIX_STRUCT_RET
+ || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
+ return true;
+ if (DEFAULT_ABI == ABI_V4 && TYPE_MODE (type) == TFmode)
+ return true;
+ return false;
+}
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0.
@@ -2878,12 +3918,9 @@ rs6000_emit_move (dest, source, mode)
so we never return a PARALLEL. */
void
-init_cumulative_args (cum, fntype, libname, incoming, libcall)
- CUMULATIVE_ARGS *cum;
- tree fntype;
- rtx libname ATTRIBUTE_UNUSED;
- int incoming;
- int libcall;
+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
+ rtx libname ATTRIBUTE_UNUSED, int incoming,
+ int libcall, int n_named_args)
{
static CUMULATIVE_ARGS zero_cumulative;
@@ -2895,19 +3932,14 @@ init_cumulative_args (cum, fntype, libname, incoming, libcall)
cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
? CALL_LIBCALL : CALL_NORMAL);
cum->sysv_gregno = GP_ARG_MIN_REG;
+ cum->stdarg = fntype
+ && (TYPE_ARG_TYPES (fntype) != 0
+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
+ != void_type_node));
- if (incoming)
- cum->nargs_prototype = 1000; /* don't return a PARALLEL */
-
- else if (cum->prototype)
- cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
- + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
- || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
-
- else
- cum->nargs_prototype = 0;
-
- cum->orig_nargs = cum->nargs_prototype;
+ cum->nargs_prototype = 0;
+ if (incoming || cum->prototype)
+ cum->nargs_prototype = n_named_args;
/* Check for a longcall attribute. */
if (fntype
@@ -2931,6 +3963,16 @@ init_cumulative_args (cum, fntype, libname, incoming, libcall)
fprintf (stderr, " proto = %d, nargs = %d\n",
cum->prototype, cum->nargs_prototype);
}
+
+ if (fntype
+ && !TARGET_ALTIVEC
+ && TARGET_ALTIVEC_ABI
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
+ {
+ error ("Cannot return value in vector register because"
+ " altivec instructions are disabled, use -maltivec"
+ " to enable them.");
+ }
}
/* If defined, a C expression which determines whether, and in which
@@ -2943,21 +3985,52 @@ init_cumulative_args (cum, fntype, libname, incoming, libcall)
argument slot. */
enum direction
-function_arg_padding (mode, type)
- enum machine_mode mode;
- tree type;
+function_arg_padding (enum machine_mode mode, tree type)
{
- if (type != 0 && AGGREGATE_TYPE_P (type))
- return upward;
+#ifndef AGGREGATE_PADDING_FIXED
+#define AGGREGATE_PADDING_FIXED 0
+#endif
+#ifndef AGGREGATES_PAD_UPWARD_ALWAYS
+#define AGGREGATES_PAD_UPWARD_ALWAYS 0
+#endif
+
+ if (!AGGREGATE_PADDING_FIXED)
+ {
+ /* GCC used to pass structures of the same size as integer types as
+ if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
+ ie. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
+ passed padded downward, except that -mstrict-align further
+ muddied the water in that multi-component structures of 2 and 4
+ bytes in size were passed padded upward.
+
+ The following arranges for best compatibility with previous
+ versions of gcc, but removes the -mstrict-align dependency. */
+ if (BYTES_BIG_ENDIAN)
+ {
+ HOST_WIDE_INT size = 0;
+
+ if (mode == BLKmode)
+ {
+ if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+ size = int_size_in_bytes (type);
+ }
+ else
+ size = GET_MODE_SIZE (mode);
+
+ if (size == 1 || size == 2 || size == 4)
+ return downward;
+ }
+ return upward;
+ }
+
+ if (AGGREGATES_PAD_UPWARD_ALWAYS)
+ {
+ if (type != 0 && AGGREGATE_TYPE_P (type))
+ return upward;
+ }
- /* This is the default definition. */
- return (! BYTES_BIG_ENDIAN
- ? upward
- : ((mode == BLKmode
- ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
- : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
- ? downward : upward));
+ /* Fall back to the default. */
+ return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
}
/* If defined, a C expression that gives the alignment boundary, in bits,
@@ -2967,42 +4040,102 @@ function_arg_padding (mode, type)
V.4 wants long longs to be double word aligned. */
int
-function_arg_boundary (mode, type)
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
+function_arg_boundary (enum machine_mode mode, tree type ATTRIBUTE_UNUSED)
{
- if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
+ if (DEFAULT_ABI == ABI_V4 && GET_MODE_SIZE (mode) == 8)
return 64;
- else if (SPE_VECTOR_MODE (mode))
- return 64;
- else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ else if (SPE_VECTOR_MODE (mode))
+ return 64;
+ else if (ALTIVEC_VECTOR_MODE (mode))
return 128;
else
return PARM_BOUNDARY;
}
+
+/* Compute the size (in words) of a function argument. */
+
+static unsigned long
+rs6000_arg_size (enum machine_mode mode, tree type)
+{
+ unsigned long size;
+
+ if (mode != BLKmode)
+ size = GET_MODE_SIZE (mode);
+ else
+ size = int_size_in_bytes (type);
+
+ if (TARGET_32BIT)
+ return (size + 3) >> 2;
+ else
+ return (size + 7) >> 3;
+}
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
+ (TYPE is null for libcalls where that information may not be available.)
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
void
-function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
{
cum->nargs_prototype--;
if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
- if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
- cum->vregno++;
+ bool stack = false;
+
+ if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
+ {
+ cum->vregno++;
+ if (!TARGET_ALTIVEC)
+ error ("Cannot pass argument in vector register because"
+ " altivec instructions are disabled, use -maltivec"
+ " to enable them.");
+
+ /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
+ even if it is going to be passed in a vector register.
+ Darwin does the same for variable-argument functions. */
+ if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
+ || (cum->stdarg && DEFAULT_ABI != ABI_V4))
+ stack = true;
+ }
else
- cum->words += RS6000_ARG_SIZE (mode, type);
+ stack = true;
+
+ if (stack)
+ {
+ int align;
+
+ /* Vector parameters must be 16-byte aligned. This places
+ them at 2 mod 4 in terms of words in 32-bit mode, since
+ the parameter save area starts at offset 24 from the
+ stack. In 64-bit mode, they just have to start on an
+ even word, since the parameter save area is 16-byte
+ aligned. Space for GPRs is reserved even if the argument
+ will be passed in memory. */
+ if (TARGET_32BIT)
+ align = (2 - cum->words) & 3;
+ else
+ align = cum->words & 1;
+ cum->words += align + rs6000_arg_size (mode, type);
+
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "function_adv: words = %2d, align=%d, ",
+ cum->words, align);
+ fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
+ cum->nargs_prototype, cum->prototype,
+ GET_MODE_NAME (mode));
+ }
+ }
}
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
- && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
+ && !cum->stdarg
+ && cum->sysv_gregno <= GP_ARG_MAX_REG)
cum->sysv_gregno++;
else if (DEFAULT_ABI == ABI_V4)
{
@@ -3015,30 +4148,26 @@ function_arg_advance (cum, mode, type, named)
{
if (mode == DFmode)
cum->words += cum->words & 1;
- cum->words += RS6000_ARG_SIZE (mode, type);
+ cum->words += rs6000_arg_size (mode, type);
}
}
else
{
- int n_words;
+ int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno;
- /* Aggregates and IEEE quad get passed by reference. */
- if ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode)
- n_words = 1;
- else
- n_words = RS6000_ARG_SIZE (mode, type);
-
- /* Long long and SPE vectors are put in odd registers. */
- if (n_words == 2 && (gregno & 1) == 0)
- gregno += 1;
+ /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+ (r7,r8) or (r9,r10). As does any other 2 word item such
+ as complex int due to a historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
- /* Long long and SPE vectors are not split between registers
- and stack. */
+ /* Multi-reg args are not split between registers and stack. */
if (gregno + n_words - 1 > GP_ARG_MAX_REG)
{
- /* Long long is aligned on the stack. */
+ /* Long long and SPE vectors are aligned on the stack.
+ So are other 2 word items such as complex int due to
+ a historical mistake. */
if (n_words == 2)
cum->words += cum->words & 1;
cum->words += n_words;
@@ -3062,14 +4191,20 @@ function_arg_advance (cum, mode, type, named)
}
else
{
- int align = (TARGET_32BIT && (cum->words & 1) != 0
- && function_arg_boundary (mode, type) == 64) ? 1 : 0;
+ int n_words = rs6000_arg_size (mode, type);
+ int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
- cum->words += align + RS6000_ARG_SIZE (mode, type);
+ /* The simple alignment calculation here works because
+ function_arg_boundary / PARM_BOUNDARY will only be 1 or 2.
+ If we ever want to handle alignments larger than 8 bytes for
+ 32-bit or 16 bytes for 64-bit, then we'll need to take into
+ account the offset to the start of the parm save area. */
+ align &= cum->words;
+ cum->words += align + n_words;
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& TARGET_HARD_FLOAT && TARGET_FPRS)
- cum->fregno += (mode == TFmode ? 2 : 1);
+ cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
if (TARGET_DEBUG_ARG)
{
@@ -3081,7 +4216,149 @@ function_arg_advance (cum, mode, type, named)
}
}
}
-
+
+/* Determine where to put a SIMD argument on the SPE. */
+
+static rtx
+rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type)
+{
+ if (cum->stdarg)
+ {
+ int gregno = cum->sysv_gregno;
+ int n_words = rs6000_arg_size (mode, type);
+
+ /* SPE vectors are put in odd registers. */
+ if (n_words == 2 && (gregno & 1) == 0)
+ gregno += 1;
+
+ if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
+ {
+ rtx r1, r2;
+ enum machine_mode m = SImode;
+
+ r1 = gen_rtx_REG (m, gregno);
+ r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
+ r2 = gen_rtx_REG (m, gregno + 1);
+ r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
+ return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
+ }
+ else
+ return NULL_RTX;
+ }
+ else
+ {
+ if (cum->sysv_gregno <= GP_ARG_MAX_REG)
+ return gen_rtx_REG (mode, cum->sysv_gregno);
+ else
+ return NULL_RTX;
+ }
+}
+
+/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
+
+static rtx
+rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int align_words)
+{
+ if (mode == DFmode)
+ {
+ /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
+ in vararg list into zero, one or two GPRs */
+ if (align_words >= GP_ARG_NUM_REG)
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode,
+ cum->fregno),
+ const0_rtx)));
+ else if (align_words + rs6000_arg_size (mode, type)
+ > GP_ARG_NUM_REG)
+ /* If this is partially on the stack, then we only
+ include the portion actually in registers here. */
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode,
+ cum->fregno),
+ const0_rtx)));
+
+ /* split a DFmode arg into two GPRs */
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (3,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4)),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->fregno),
+ const0_rtx)));
+ }
+ /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
+ or two GPRs */
+ else if (mode == DImode)
+ {
+ if (align_words < GP_ARG_NUM_REG - 1)
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4))));
+ else if (align_words == GP_ARG_NUM_REG - 1)
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx)));
+ }
+ else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
+ {
+ int k;
+ int size = int_size_in_bytes (type);
+ int no_units = ((size - 1) / 4) + 1;
+ int max_no_words = GP_ARG_NUM_REG - align_words;
+ int rtlvec_len = no_units < max_no_words ? no_units : max_no_words;
+ rtx *rtlvec = (rtx *) alloca (rtlvec_len * sizeof (rtx));
+
+ memset ((char *) rtlvec, 0, rtlvec_len * sizeof (rtx));
+
+ for (k=0; k < rtlvec_len; k++)
+ rtlvec[k] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + k),
+ k == 0 ? const0_rtx : GEN_INT (k*4));
+
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
+ }
+
+ return NULL_RTX;
+}
+
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -3103,14 +4380,15 @@ function_arg_advance (cum, mode, type, named)
both an FP and integer register (or possibly FP reg and stack). Library
functions (when CALL_LIBCALL is set) always have the proper types for args,
so we can pass the FP value just in one register. emit_library_function
- doesn't support PARALLEL anyway. */
+ doesn't support PARALLEL anyway.
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
struct rtx_def *
-function_arg (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
{
enum rs6000_abi abi = DEFAULT_ABI;
@@ -3138,20 +4416,72 @@ function_arg (cum, mode, type, named)
return GEN_INT (cum->call_cookie);
}
- if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
- {
- if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
- return gen_rtx_REG (mode, cum->vregno);
- else
- return NULL;
- }
- else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
+ if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
+ if (TARGET_64BIT && ! cum->prototype)
+ {
+ /* Vector parameters get passed in vector register
+ and also in GPRs or memory, in absence of prototype. */
+ int align_words;
+ rtx slot;
+ align_words = (cum->words + 1) & ~1;
+
+ if (align_words >= GP_ARG_NUM_REG)
+ {
+ slot = NULL_RTX;
+ }
+ else
+ {
+ slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ }
+ return gen_rtx_PARALLEL (mode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ slot, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->vregno),
+ const0_rtx)));
+ }
+ else
+ return gen_rtx_REG (mode, cum->vregno);
+ else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
- if (cum->sysv_gregno <= GP_ARG_MAX_REG)
- return gen_rtx_REG (mode, cum->sysv_gregno);
+ if (named || abi == ABI_V4)
+ return NULL_RTX;
else
- return NULL;
+ {
+ /* Vector parameters to varargs functions under AIX or Darwin
+ get passed in memory and possibly also in GPRs. */
+ int align, align_words;
+ enum machine_mode part_mode = mode;
+
+ /* Vector parameters must be 16-byte aligned. This places them at
+ 2 mod 4 in terms of words in 32-bit mode, since the parameter
+ save area starts at offset 24 from the stack. In 64-bit mode,
+ they just have to start on an even word, since the parameter
+ save area is 16-byte aligned. */
+ if (TARGET_32BIT)
+ align = (2 - cum->words) & 3;
+ else
+ align = cum->words & 1;
+ align_words = cum->words + align;
+
+ /* Out of registers? Memory, then. */
+ if (align_words >= GP_ARG_NUM_REG)
+ return NULL_RTX;
+
+ /* The vector value goes in GPRs. Only the part of the
+ value in GPRs is reported here. */
+ if (align_words + CLASS_MAX_NREGS (mode, GENERAL_REGS)
+ > GP_ARG_NUM_REG)
+ /* Fortunately, there are only two possibilities, the value
+ is either wholly in GPRs or half in GPRs and half not. */
+ part_mode = DImode;
+
+ return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
+ }
}
+ else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
+ return rs6000_spe_function_arg (cum, mode, type);
else if (abi == ABI_V4)
{
if (TARGET_HARD_FLOAT && TARGET_FPRS
@@ -3160,90 +4490,105 @@ function_arg (cum, mode, type, named)
if (cum->fregno <= FP_ARG_V4_MAX_REG)
return gen_rtx_REG (mode, cum->fregno);
else
- return NULL;
+ return NULL_RTX;
}
else
{
- int n_words;
+ int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno;
- /* Aggregates and IEEE quad get passed by reference. */
- if ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode)
- n_words = 1;
- else
- n_words = RS6000_ARG_SIZE (mode, type);
+ /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+ (r7,r8) or (r9,r10). As does any other 2 word item such
+ as complex int due to a historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
- /* Long long and SPE vectors are put in odd registers. */
- if (n_words == 2 && (gregno & 1) == 0)
- gregno += 1;
-
- /* Long long and SPE vectors are not split between registers
- and stack. */
+ /* Multi-reg args are not split between registers and stack. */
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
- {
- /* SPE vectors in ... get split into 2 registers. */
- if (TARGET_SPE && TARGET_SPE_ABI
- && SPE_VECTOR_MODE (mode) && !named)
- {
- rtx r1, r2;
- enum machine_mode m = SImode;
-
- r1 = gen_rtx_REG (m, gregno);
- r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
- r2 = gen_rtx_REG (m, gregno + 1);
- r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
- return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
- }
- return gen_rtx_REG (mode, gregno);
- }
+ return gen_rtx_REG (mode, gregno);
else
- return NULL;
+ return NULL_RTX;
}
}
else
{
- int align = (TARGET_32BIT && (cum->words & 1) != 0
- && function_arg_boundary (mode, type) == 64) ? 1 : 0;
- int align_words = cum->words + align;
-
- if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return NULL_RTX;
+ int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
+ int align_words = cum->words + (cum->words & align);
- if (USE_FP_FOR_ARG_P (*cum, mode, type))
+ if (USE_FP_FOR_ARG_P (cum, mode, type))
{
- if (! type
- || ((cum->nargs_prototype > 0)
- /* IBM AIX extended its linkage convention definition always
- to require FP args after register save area hole on the
- stack. */
- && (DEFAULT_ABI != ABI_AIX
- || ! TARGET_XL_CALL
- || (align_words < GP_ARG_NUM_REG))))
- return gen_rtx_REG (mode, cum->fregno);
+ rtx fpr[2];
+ rtx *r;
+ bool needs_psave;
+ enum machine_mode fmode = mode;
+ int n;
+ unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
+
+ if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
+ {
+ /* Long double split over regs and memory. */
+ if (fmode == TFmode)
+ fmode = DFmode;
+
+ /* Currently, we only ever need one reg here because complex
+ doubles are split. */
+ if (cum->fregno != FP_ARG_MAX_REG - 1)
+ abort ();
+ }
+ fpr[1] = gen_rtx_REG (fmode, cum->fregno);
+
+ /* Do we also need to pass this arg in the parameter save
+ area? */
+ needs_psave = (type
+ && (cum->nargs_prototype <= 0
+ || (DEFAULT_ABI == ABI_AIX
+ && TARGET_XL_CALL
+ && align_words >= GP_ARG_NUM_REG)));
- return gen_rtx_PARALLEL (mode,
- gen_rtvec (2,
- gen_rtx_EXPR_LIST (VOIDmode,
- ((align_words >= GP_ARG_NUM_REG)
- ? NULL_RTX
- : (align_words
- + RS6000_ARG_SIZE (mode, type)
- > GP_ARG_NUM_REG
- /* If this is partially on the stack, then
- we only include the portion actually
- in registers here. */
- ? gen_rtx_REG (SImode,
- GP_ARG_MIN_REG + align_words)
- : gen_rtx_REG (mode,
- GP_ARG_MIN_REG + align_words))),
- const0_rtx),
- gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode, cum->fregno),
- const0_rtx)));
+ if (!needs_psave && mode == fmode)
+ return fpr[1];
+
+ if (TARGET_32BIT && TARGET_POWERPC64
+ && mode == DFmode && cum->stdarg)
+ return rs6000_mixed_function_arg (cum, mode, type, align_words);
+
+ /* Describe where this piece goes. */
+ r = fpr + 1;
+ *r = gen_rtx_EXPR_LIST (VOIDmode, *r, const0_rtx);
+ n = 1;
+
+ if (needs_psave)
+ {
+ /* Now describe the part that goes in gprs or the stack.
+ This piece must come first, before the fprs. */
+ rtx reg = NULL_RTX;
+ if (align_words < GP_ARG_NUM_REG)
+ {
+ unsigned long n_words = rs6000_arg_size (mode, type);
+ enum machine_mode rmode = mode;
+
+ if (align_words + n_words > GP_ARG_NUM_REG)
+ /* If this is partially on the stack, then we only
+ include the portion actually in registers here.
+ We know this can only be one register because
+ complex doubles are splt. */
+ rmode = Pmode;
+ reg = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
+ }
+ *--r = gen_rtx_EXPR_LIST (VOIDmode, reg, const0_rtx);
+ ++n;
+ }
+
+ return gen_rtx_PARALLEL (mode, gen_rtvec_v (n, r));
}
else if (align_words < GP_ARG_NUM_REG)
- return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ {
+ if (TARGET_32BIT && TARGET_POWERPC64
+ && (mode == DImode || mode == BLKmode))
+ return rs6000_mixed_function_arg (cum, mode, type, align_words);
+
+ return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ }
else
return NULL_RTX;
}
@@ -3254,33 +4599,34 @@ function_arg (cum, mode, type, named)
For args passed entirely in registers or entirely in memory, zero. */
int
-function_arg_partial_nregs (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
{
+ int ret = 0;
+
if (DEFAULT_ABI == ABI_V4)
return 0;
- if (USE_FP_FOR_ARG_P (*cum, mode, type)
- || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
+ if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
+ && cum->nargs_prototype >= 0)
+ return 0;
+
+ if (USE_FP_FOR_ARG_P (cum, mode, type))
{
- if (cum->nargs_prototype >= 0)
+ if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
+ ret = FP_ARG_MAX_REG - cum->fregno;
+ else if (cum->nargs_prototype >= 0)
return 0;
}
if (cum->words < GP_ARG_NUM_REG
- && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
- {
- int ret = GP_ARG_NUM_REG - cum->words;
- if (ret && TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
+ && GP_ARG_NUM_REG < cum->words + rs6000_arg_size (mode, type))
+ ret = GP_ARG_NUM_REG - cum->words;
- return ret;
- }
+ if (ret != 0 && TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
- return 0;
+ return ret;
}
/* A C expression that indicates when an argument must be passed by
@@ -3289,29 +4635,63 @@ function_arg_partial_nregs (cum, mode, type, named)
the argument itself. The pointer is passed in whatever way is
appropriate for passing a pointer to that type.
- Under V.4, structures and unions are passed by reference.
+ Under V.4, aggregates and long double are passed by reference.
+
+ As an extension to all 32-bit ABIs, AltiVec vectors are passed by
+ reference unless the AltiVec vector extension ABI is in force.
As an extension to all ABIs, variable sized types are passed by
reference. */
int
-function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, int named ATTRIBUTE_UNUSED)
{
- if (DEFAULT_ABI == ABI_V4
- && ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode))
+ if ((DEFAULT_ABI == ABI_V4
+ && ((type && AGGREGATE_TYPE_P (type))
+ || mode == TFmode))
+ || (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ || (type && int_size_in_bytes (type) < 0))
{
if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
+ fprintf (stderr, "function_arg_pass_by_reference\n");
return 1;
}
- return type && int_size_in_bytes (type) < 0;
+ return 0;
}
+
+static void
+rs6000_move_block_from_reg (int regno, rtx x, int nregs)
+{
+ int i;
+ enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
+
+ if (nregs == 0)
+ return;
+
+ for (i = 0; i < nregs; i++)
+ {
+ rtx tem = adjust_address_nv (x, reg_mode, i*GET_MODE_SIZE(reg_mode));
+ if (reload_completed)
+ {
+ if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
+ tem = NULL_RTX;
+ else
+ tem = simplify_gen_subreg (reg_mode, x, BLKmode,
+ i * GET_MODE_SIZE(reg_mode));
+ }
+ else
+ tem = replace_equiv_address (tem, XEXP (tem, 0));
+
+ if (tem == NULL_RTX)
+ abort ();
+
+ emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
+ }
+}
+
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
@@ -3327,32 +4707,18 @@ function_arg_pass_by_reference (cum, mode, type, named)
Normally, this macro will push all remaining incoming registers on the
stack and set PRETEND_SIZE to the length of the registers pushed. */
-void
-setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int *pretend_size;
- int no_rtl;
-
+static void
+setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl)
{
CUMULATIVE_ARGS next_cum;
int reg_size = TARGET_32BIT ? 4 : 8;
rtx save_area = NULL_RTX, mem;
int first_reg_offset, set;
- tree fntype;
- int stdarg_p;
-
- fntype = TREE_TYPE (current_function_decl);
- stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
- && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
- != void_type_node));
- /* For varargs, we do not want to skip the dummy va_dcl argument.
- For stdargs, we do want to skip the last named argument. */
+ /* Skip the last named argument. */
next_cum = *cum;
- if (stdarg_p)
- function_arg_advance (&next_cum, mode, type, 1);
+ function_arg_advance (&next_cum, mode, type, 1);
if (DEFAULT_ABI == ABI_V4)
{
@@ -3371,7 +4737,7 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
cfun->machine->sysv_varargs_p = 0;
if (MUST_PASS_IN_STACK (mode, type))
- first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
+ first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
}
set = get_varargs_alias_set ();
@@ -3383,13 +4749,8 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
set_mem_alias_set (mem, set);
set_mem_align (mem, BITS_PER_WORD);
- move_block_from_reg
- (GP_ARG_MIN_REG + first_reg_offset, mem,
- GP_ARG_NUM_REG - first_reg_offset,
- (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
-
- /* ??? Does ABI_V4 need this at all? */
- *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
+ rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
+ GP_ARG_NUM_REG - first_reg_offset);
}
/* Save FP registers if needed. */
@@ -3426,10 +4787,10 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
/* Create the va_list data type. */
-tree
-rs6000_build_va_list ()
+static tree
+rs6000_build_builtin_va_list (void)
{
- tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
/* For AIX, prefer 'char *' because that's what the system
header files like. */
@@ -3443,6 +4804,10 @@ rs6000_build_va_list ()
unsigned_char_type_node);
f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
unsigned_char_type_node);
+ /* Give the two bytes of padding a name, so that -Wpadded won't warn on
+ every user file. */
+ f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
+ short_unsigned_type_node);
f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
ptr_type_node);
f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
@@ -3450,6 +4815,7 @@ rs6000_build_va_list ()
DECL_FIELD_CONTEXT (f_gpr) = record;
DECL_FIELD_CONTEXT (f_fpr) = record;
+ DECL_FIELD_CONTEXT (f_res) = record;
DECL_FIELD_CONTEXT (f_ovf) = record;
DECL_FIELD_CONTEXT (f_sav) = record;
@@ -3457,7 +4823,8 @@ rs6000_build_va_list ()
TYPE_NAME (record) = type_decl;
TYPE_FIELDS (record) = f_gpr;
TREE_CHAIN (f_gpr) = f_fpr;
- TREE_CHAIN (f_fpr) = f_ovf;
+ TREE_CHAIN (f_fpr) = f_res;
+ TREE_CHAIN (f_res) = f_ovf;
TREE_CHAIN (f_ovf) = f_sav;
layout_type (record);
@@ -3469,12 +4836,10 @@ rs6000_build_va_list ()
/* Implement va_start. */
void
-rs6000_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+rs6000_va_start (tree valist, rtx nextarg)
{
HOST_WIDE_INT words, n_gpr, n_fpr;
- tree f_gpr, f_fpr, f_ovf, f_sav;
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, t;
/* Only SVR4 needs something special. */
@@ -3486,7 +4851,8 @@ rs6000_va_start (valist, nextarg)
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
- f_ovf = TREE_CHAIN (f_fpr);
+ f_res = TREE_CHAIN (f_fpr);
+ f_ovf = TREE_CHAIN (f_res);
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
@@ -3501,15 +4867,9 @@ rs6000_va_start (valist, nextarg)
n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
if (TARGET_DEBUG_ARG)
- {
- fputs ("va_start: words = ", stderr);
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
- fputs (", n_gpr = ", stderr);
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
- fputs (", n_fpr = ", stderr);
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
- putc ('\n', stderr);
- }
+ fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
+ HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
+ words, n_gpr, n_fpr);
t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
TREE_SIDE_EFFECTS (t) = 1;
@@ -3540,18 +4900,22 @@ rs6000_va_start (valist, nextarg)
/* Implement va_arg. */
rtx
-rs6000_va_arg (valist, type)
- tree valist, type;
+rs6000_va_arg (tree valist, tree type)
{
- tree f_gpr, f_fpr, f_ovf, f_sav;
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, reg, t, u;
int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
rtx lab_false, lab_over, addr_rtx, r;
+ int align;
if (DEFAULT_ABI != ABI_V4)
{
- /* Variable sized types are passed by reference. */
- if (int_size_in_bytes (type) < 0)
+ /* Variable sized types are passed by reference, as are AltiVec
+ vectors when 32-bit and not using the AltiVec ABI extension. */
+ if (int_size_in_bytes (type) < 0
+ || (TARGET_32BIT
+ && !TARGET_ALTIVEC_ABI
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
{
u = build_pointer_type (type);
@@ -3568,13 +4932,48 @@ rs6000_va_arg (valist, type)
return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL);
}
- else
- return std_expand_builtin_va_arg (valist, type);
+ if (targetm.calls.split_complex_arg
+ && TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ tree elem_type = TREE_TYPE (type);
+ enum machine_mode elem_mode = TYPE_MODE (elem_type);
+ int elem_size = GET_MODE_SIZE (elem_mode);
+
+ if (elem_size < UNITS_PER_WORD)
+ {
+ rtx real_part, imag_part, dest_real, rr;
+
+ real_part = rs6000_va_arg (valist, elem_type);
+ imag_part = rs6000_va_arg (valist, elem_type);
+
+ /* We're not returning the value here, but the address.
+ real_part and imag_part are not contiguous, and we know
+ there is space available to pack real_part next to
+ imag_part. float _Complex is not promoted to
+ double _Complex by the default promotion rules that
+ promote float to double. */
+ if (2 * elem_size > UNITS_PER_WORD)
+ abort ();
+
+ real_part = gen_rtx_MEM (elem_mode, real_part);
+ imag_part = gen_rtx_MEM (elem_mode, imag_part);
+
+ dest_real = adjust_address (imag_part, elem_mode, -elem_size);
+ rr = gen_reg_rtx (elem_mode);
+ emit_move_insn (rr, real_part);
+ emit_move_insn (dest_real, rr);
+
+ return XEXP (dest_real, 0);
+ }
+ }
+
+ return std_expand_builtin_va_arg (valist, type);
}
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
- f_ovf = TREE_CHAIN (f_fpr);
+ f_res = TREE_CHAIN (f_fpr);
+ f_ovf = TREE_CHAIN (f_res);
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
@@ -3584,20 +4983,25 @@ rs6000_va_arg (valist, type)
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
size = int_size_in_bytes (type);
- rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ rsize = (size + 3) / 4;
+ align = 1;
- if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
+ if (AGGREGATE_TYPE_P (type)
+ || TYPE_MODE (type) == TFmode
+ || (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
{
- /* Aggregates and long doubles are passed by reference. */
+ /* Aggregates, long doubles, and AltiVec vectors are passed by
+ reference. */
indirect_p = 1;
reg = gpr;
n_reg = 1;
sav_ofs = 0;
sav_scale = 4;
- size = UNITS_PER_WORD;
+ size = 4;
rsize = 1;
}
- else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ else if (TARGET_HARD_FLOAT && TARGET_FPRS
+ && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
{
/* FP args go in FP registers, if present. */
indirect_p = 0;
@@ -3605,6 +5009,8 @@ rs6000_va_arg (valist, type)
n_reg = 1;
sav_ofs = 8*4;
sav_scale = 8;
+ if (TYPE_MODE (type) == DFmode)
+ align = 8;
}
else
{
@@ -3614,38 +5020,43 @@ rs6000_va_arg (valist, type)
n_reg = rsize;
sav_ofs = 0;
sav_scale = 4;
+ if (n_reg == 2)
+ align = 8;
}
- /* Pull the value out of the saved registers ... */
+ /* Pull the value out of the saved registers.... */
- lab_false = gen_label_rtx ();
- lab_over = gen_label_rtx ();
+ lab_over = NULL_RTX;
addr_rtx = gen_reg_rtx (Pmode);
- /* AltiVec vectors never go in registers. */
- if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
+ /* AltiVec vectors never go in registers when -mabi=altivec. */
+ if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ align = 16;
+ else
{
- TREE_THIS_VOLATILE (reg) = 1;
- emit_cmp_and_jump_insns
- (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
- GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
- lab_false);
+ lab_false = gen_label_rtx ();
+ lab_over = gen_label_rtx ();
- /* Long long is aligned in the registers. */
- if (n_reg > 1)
+ /* Long long and SPE vectors are aligned in the registers.
+ As are any other 2 gpr item such as complex int due to a
+ historical mistake. */
+ u = reg;
+ if (n_reg == 2)
{
u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg - 1, 0));
- u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
- u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
+ u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
TREE_SIDE_EFFECTS (u) = 1;
- expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
+ emit_cmp_and_jump_insns
+ (expand_expr (u, NULL_RTX, QImode, EXPAND_NORMAL),
+ GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
+ lab_false);
+
+ t = sav;
if (sav_ofs)
t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
- else
- t = sav;
u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg, 0));
@@ -3666,40 +5077,26 @@ rs6000_va_arg (valist, type)
emit_jump_insn (gen_jump (lab_over));
emit_barrier ();
- }
- emit_label (lab_false);
+ emit_label (lab_false);
+ if (n_reg > 2)
+ {
+ /* Ensure that we don't find any more args in regs.
+ Alignment has taken care of the n_reg == 2 case. */
+ t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+ }
/* ... otherwise out of the overflow area. */
- /* Make sure we don't find reg 7 for the next int arg.
-
- All AltiVec vectors go in the overflow area. So in the AltiVec
- case we need to get the vectors from the overflow area, but
- remember where the GPRs and FPRs are. */
- if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
- || !TARGET_ALTIVEC))
- {
- t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
-
/* Care for on-stack alignment if needed. */
- if (rsize <= 1)
- t = ovf;
- else
+ t = ovf;
+ if (align != 1)
{
- int align;
-
- /* AltiVec vectors are 16 byte aligned. */
- if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
- align = 15;
- else
- align = 7;
-
- t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
- t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
+ t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (align - 1, 0));
+ t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
}
t = save_expr (t);
@@ -3712,7 +5109,8 @@ rs6000_va_arg (valist, type)
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- emit_label (lab_over);
+ if (lab_over)
+ emit_label (lab_over);
if (indirect_p)
{
@@ -4032,7 +5430,7 @@ static struct builtin_description bdesc_2arg[] =
{ 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
/* Place-holder. Leave as last binary SPE builtin. */
- { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
+ { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
};
/* AltiVec predicates. */
@@ -4099,7 +5497,7 @@ static struct builtin_description bdesc_spe_evsel[] =
{ 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
};
-/* ABS* opreations. */
+/* ABS* operations. */
static const struct builtin_description bdesc_abs[] =
{
@@ -4160,23 +5558,18 @@ static struct builtin_description bdesc_1arg[] =
{ 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
{ 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
{ 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
- { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
+ { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
{ 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
{ 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
{ 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
{ 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
- { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
- { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
/* Place-holder. Leave as last unary SPE builtin. */
{ 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
};
static rtx
-rs6000_expand_unop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+rs6000_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -4225,10 +5618,7 @@ rs6000_expand_unop_builtin (icode, arglist, target)
}
static rtx
-altivec_expand_abs_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+altivec_expand_abs_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat, scratch1, scratch2;
tree arg0 = TREE_VALUE (arglist);
@@ -4260,10 +5650,7 @@ altivec_expand_abs_builtin (icode, arglist, target)
}
static rtx
-rs6000_expand_binop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+rs6000_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -4304,6 +5691,7 @@ rs6000_expand_binop_builtin (icode, arglist, target)
|| icode == CODE_FOR_spe_evrlwi
|| icode == CODE_FOR_spe_evslwi
|| icode == CODE_FOR_spe_evsrwis
+ || icode == CODE_FOR_spe_evsubifw
|| icode == CODE_FOR_spe_evsrwiu)
{
/* Only allow 5-bit unsigned literals. */
@@ -4334,11 +5722,8 @@ rs6000_expand_binop_builtin (icode, arglist, target)
}
static rtx
-altivec_expand_predicate_builtin (icode, opcode, arglist, target)
- enum insn_code icode;
- const char *opcode;
- tree arglist;
- rtx target;
+altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
+ tree arglist, rtx target)
{
rtx pat, scratch;
tree cr6_form = TREE_VALUE (arglist);
@@ -4415,9 +5800,53 @@ altivec_expand_predicate_builtin (icode, opcode, arglist, target)
}
static rtx
-altivec_expand_stv_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+altivec_expand_lv_builtin (enum insn_code icode, tree arglist, rtx target)
+{
+ rtx pat, addr;
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode0 = Pmode;
+ enum machine_mode mode1 = Pmode;
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return const0_rtx;
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ if (op0 == const0_rtx)
+ {
+ addr = gen_rtx_MEM (tmode, op1);
+ }
+ else
+ {
+ op0 = copy_to_mode_reg (mode0, op0);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+}
+
+static rtx
+spe_expand_stv_builtin (enum insn_code icode, tree arglist)
{
tree arg0 = TREE_VALUE (arglist);
tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
@@ -4450,10 +5879,48 @@ altivec_expand_stv_builtin (icode, arglist)
}
static rtx
-rs6000_expand_ternop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+altivec_expand_stv_builtin (enum insn_code icode, tree arglist)
+{
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
+ rtx pat, addr;
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode1 = Pmode;
+ enum machine_mode mode2 = Pmode;
+
+ /* Invalid arguments. Bail before doing anything stoopid! */
+ if (arg0 == error_mark_node
+ || arg1 == error_mark_node
+ || arg2 == error_mark_node)
+ return const0_rtx;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
+ op0 = copy_to_mode_reg (tmode, op0);
+
+ op2 = copy_to_mode_reg (mode2, op2);
+
+ if (op1 == const0_rtx)
+ {
+ addr = gen_rtx_MEM (tmode, op2);
+ }
+ else
+ {
+ op1 = copy_to_mode_reg (mode1, op1);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
+ }
+
+ pat = GEN_FCN (icode) (addr, op0);
+ if (pat)
+ emit_insn (pat);
+ return NULL_RTX;
+}
+
+static rtx
+rs6000_expand_ternop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -4513,10 +5980,7 @@ rs6000_expand_ternop_builtin (icode, arglist, target)
/* Expand the lvx builtins. */
static rtx
-altivec_expand_ld_builtin (exp, target, expandedp)
- tree exp;
- rtx target;
- bool *expandedp;
+altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4569,10 +6033,8 @@ altivec_expand_ld_builtin (exp, target, expandedp)
/* Expand the stvx builtins. */
static rtx
-altivec_expand_st_builtin (exp, target, expandedp)
- tree exp;
- rtx target ATTRIBUTE_UNUSED;
- bool *expandedp;
+altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+ bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4623,10 +6085,8 @@ altivec_expand_st_builtin (exp, target, expandedp)
/* Expand the dst builtins. */
static rtx
-altivec_expand_dst_builtin (exp, target, expandedp)
- tree exp;
- rtx target ATTRIBUTE_UNUSED;
- bool *expandedp;
+altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+ bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4668,7 +6128,7 @@ altivec_expand_dst_builtin (exp, target, expandedp)
}
if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
+ op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
@@ -4686,10 +6146,7 @@ altivec_expand_dst_builtin (exp, target, expandedp)
/* Expand the builtin in EXP and store the result in TARGET. Store
true in *EXPANDEDP if we found a builtin to expand. */
static rtx
-altivec_expand_builtin (exp, target, expandedp)
- tree exp;
- rtx target;
- bool *expandedp;
+altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
{
struct builtin_description *d;
struct builtin_description_predicates *dp;
@@ -4806,25 +6263,25 @@ altivec_expand_builtin (exp, target, expandedp)
switch (fcode)
{
case ALTIVEC_BUILTIN_LVSL:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
arglist, target);
case ALTIVEC_BUILTIN_LVSR:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
arglist, target);
case ALTIVEC_BUILTIN_LVEBX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
arglist, target);
case ALTIVEC_BUILTIN_LVEHX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
arglist, target);
case ALTIVEC_BUILTIN_LVEWX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
arglist, target);
case ALTIVEC_BUILTIN_LVXL:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
arglist, target);
case ALTIVEC_BUILTIN_LVX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
arglist, target);
default:
break;
@@ -4869,10 +6326,7 @@ static struct builtin_description bdesc_2arg_spe[] =
This expands the SPE builtins that are not simple unary and binary
operations. */
static rtx
-spe_expand_builtin (exp, target, expandedp)
- tree exp;
- rtx target;
- bool *expandedp;
+spe_expand_builtin (tree exp, rtx target, bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4908,6 +6362,19 @@ spe_expand_builtin (exp, target, expandedp)
break;
}
+ /* The evsplat*i instructions are not quite generic. */
+ switch (fcode)
+ {
+ case SPE_BUILTIN_EVSPLATFI:
+ return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
+ arglist, target);
+ case SPE_BUILTIN_EVSPLATI:
+ return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
+ arglist, target);
+ default:
+ break;
+ }
+
d = (struct builtin_description *) bdesc_2arg_spe;
for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
if (d->code == fcode)
@@ -4926,33 +6393,33 @@ spe_expand_builtin (exp, target, expandedp)
switch (fcode)
{
case SPE_BUILTIN_EVSTDDX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
case SPE_BUILTIN_EVSTDHX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
case SPE_BUILTIN_EVSTDWX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
case SPE_BUILTIN_EVSTWHEX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
case SPE_BUILTIN_EVSTWHOX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
case SPE_BUILTIN_EVSTWWEX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
case SPE_BUILTIN_EVSTWWOX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
case SPE_BUILTIN_EVSTDD:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
case SPE_BUILTIN_EVSTDH:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
case SPE_BUILTIN_EVSTDW:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
case SPE_BUILTIN_EVSTWHE:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
case SPE_BUILTIN_EVSTWHO:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
case SPE_BUILTIN_EVSTWWE:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
case SPE_BUILTIN_EVSTWWO:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
case SPE_BUILTIN_MFSPEFSCR:
icode = CODE_FOR_spe_mfspefscr;
tmode = insn_data[icode].operand[0].mode;
@@ -4992,10 +6459,7 @@ spe_expand_builtin (exp, target, expandedp)
}
static rtx
-spe_expand_predicate_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+spe_expand_predicate_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat, scratch, tmp;
tree form = TREE_VALUE (arglist);
@@ -5104,10 +6568,7 @@ spe_expand_predicate_builtin (icode, arglist, target)
*/
static rtx
-spe_expand_evsel_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+spe_expand_evsel_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat, scratch;
tree arg0 = TREE_VALUE (arglist);
@@ -5164,12 +6625,9 @@ spe_expand_evsel_builtin (icode, arglist, target)
IGNORE is nonzero if the value is to be ignored. */
static rtx
-rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -5220,8 +6678,12 @@ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
}
static void
-rs6000_init_builtins ()
+rs6000_init_builtins (void)
{
+ opaque_V2SI_type_node = copy_node (V2SI_type_node);
+ opaque_V2SF_type_node = copy_node (V2SF_type_node);
+ opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
+
if (TARGET_SPE)
spe_init_builtins ();
if (TARGET_ALTIVEC)
@@ -5232,14 +6694,13 @@ rs6000_init_builtins ()
/* Search through a set of builtins and enable the mask bits.
DESC is an array of builtins.
- SIZE is the totaly number of builtins.
+ SIZE is the total number of builtins.
START is the builtin enum at which to start.
END is the builtin enum at which to end. */
static void
-enable_mask_for_builtins (desc, size, start, end)
- struct builtin_description *desc;
- int size;
- enum rs6000_builtins start, end;
+enable_mask_for_builtins (struct builtin_description *desc, int size,
+ enum rs6000_builtins start,
+ enum rs6000_builtins end)
{
int i;
@@ -5260,52 +6721,51 @@ enable_mask_for_builtins (desc, size, start, end)
}
static void
-spe_init_builtins ()
+spe_init_builtins (void)
{
tree endlink = void_list_node;
tree puint_type_node = build_pointer_type (unsigned_type_node);
tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
- tree pv2si_type_node = build_pointer_type (V2SI_type_node);
struct builtin_description *d;
size_t i;
tree v2si_ftype_4_v2si
= build_function_type
- (V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ (opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
endlink)))));
tree v2sf_ftype_4_v2sf
= build_function_type
- (V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
+ (opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
endlink)))));
tree int_ftype_int_v2si_v2si
= build_function_type
(integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
endlink))));
tree int_ftype_int_v2sf_v2sf
= build_function_type
(integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
endlink))));
tree void_ftype_v2si_puint_int
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
tree_cons (NULL_TREE, puint_type_node,
tree_cons (NULL_TREE,
integer_type_node,
@@ -5313,7 +6773,7 @@ spe_init_builtins ()
tree void_ftype_v2si_puint_char
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
tree_cons (NULL_TREE, puint_type_node,
tree_cons (NULL_TREE,
char_type_node,
@@ -5321,16 +6781,16 @@ spe_init_builtins ()
tree void_ftype_v2si_pv2si_int
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, pv2si_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree void_ftype_v2si_pv2si_char
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, pv2si_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
tree_cons (NULL_TREE,
char_type_node,
endlink))));
@@ -5340,27 +6800,31 @@ spe_init_builtins ()
tree_cons (NULL_TREE, integer_type_node, endlink));
tree int_ftype_void
- = build_function_type (integer_type_node,
- tree_cons (NULL_TREE, void_type_node, endlink));
+ = build_function_type (integer_type_node, endlink);
tree v2si_ftype_pv2si_int
- = build_function_type (V2SI_type_node,
- tree_cons (NULL_TREE, pv2si_type_node,
+ = build_function_type (opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_puint_int
- = build_function_type (V2SI_type_node,
+ = build_function_type (opaque_V2SI_type_node,
tree_cons (NULL_TREE, puint_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_pushort_int
- = build_function_type (V2SI_type_node,
+ = build_function_type (opaque_V2SI_type_node,
tree_cons (NULL_TREE, pushort_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
+ tree v2si_ftype_signed_char
+ = build_function_type (opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, signed_char_type_node,
+ endlink));
+
/* The initialization of the simple binary and unary builtins is
done in rs6000_common_init_builtins, but we have to enable the
mask bits here manually because we have run out of `target_flags'
@@ -5383,6 +6847,10 @@ spe_init_builtins ()
SPE_BUILTIN_EVSEL_CMPGTS,
SPE_BUILTIN_EVSEL_FSTSTEQ);
+ (*lang_hooks.decls.pushdecl)
+ (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
+ opaque_V2SI_type_node));
+
/* Initialize irregular SPE builtins. */
def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
@@ -5401,6 +6869,8 @@ spe_init_builtins ()
def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
+ def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
+ def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
/* Loads. */
def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
@@ -5470,7 +6940,7 @@ spe_init_builtins ()
}
static void
-altivec_init_builtins ()
+altivec_init_builtins (void)
{
struct builtin_description *d;
struct builtin_description_predicates *dp;
@@ -5522,27 +6992,27 @@ altivec_init_builtins ()
tree void_ftype_qi
= build_function_type_list (void_type_node, char_type_node, NULL_TREE);
- tree v16qi_ftype_int_pcvoid
+ tree v16qi_ftype_long_pcvoid
= build_function_type_list (V16QI_type_node,
- integer_type_node, pcvoid_type_node, NULL_TREE);
- tree v8hi_ftype_int_pcvoid
+ long_integer_type_node, pcvoid_type_node, NULL_TREE);
+ tree v8hi_ftype_long_pcvoid
= build_function_type_list (V8HI_type_node,
- integer_type_node, pcvoid_type_node, NULL_TREE);
- tree v4si_ftype_int_pcvoid
+ long_integer_type_node, pcvoid_type_node, NULL_TREE);
+ tree v4si_ftype_long_pcvoid
= build_function_type_list (V4SI_type_node,
- integer_type_node, pcvoid_type_node, NULL_TREE);
+ long_integer_type_node, pcvoid_type_node, NULL_TREE);
- tree void_ftype_v4si_int_pvoid
+ tree void_ftype_v4si_long_pvoid
= build_function_type_list (void_type_node,
- V4SI_type_node, integer_type_node,
+ V4SI_type_node, long_integer_type_node,
pvoid_type_node, NULL_TREE);
- tree void_ftype_v16qi_int_pvoid
+ tree void_ftype_v16qi_long_pvoid
= build_function_type_list (void_type_node,
- V16QI_type_node, integer_type_node,
+ V16QI_type_node, long_integer_type_node,
pvoid_type_node, NULL_TREE);
- tree void_ftype_v8hi_int_pvoid
+ tree void_ftype_v8hi_long_pvoid
= build_function_type_list (void_type_node,
- V8HI_type_node, integer_type_node,
+ V8HI_type_node, long_integer_type_node,
pvoid_type_node, NULL_TREE);
tree int_ftype_int_v8hi_v8hi
= build_function_type_list (integer_type_node,
@@ -5589,18 +7059,18 @@ altivec_init_builtins ()
def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSL);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSR);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEBX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEHX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEWX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVXL);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
/* Add the DST variants. */
d = (struct builtin_description *) bdesc_dst;
@@ -5669,7 +7139,7 @@ altivec_init_builtins ()
}
static void
-rs6000_common_init_builtins ()
+rs6000_common_init_builtins (void)
{
struct builtin_description *d;
size_t i;
@@ -5702,43 +7172,48 @@ rs6000_common_init_builtins ()
= build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
tree v2si_ftype_v2si_v2si
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, V2SI_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SI_type_node,
+ opaque_V2SI_type_node, NULL_TREE);
tree v2sf_ftype_v2sf_v2sf
- = build_function_type_list (V2SF_type_node,
- V2SF_type_node, V2SF_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SF_type_node,
+ opaque_V2SF_type_node,
+ opaque_V2SF_type_node, NULL_TREE);
tree v2si_ftype_int_int
- = build_function_type_list (V2SI_type_node,
+ = build_function_type_list (opaque_V2SI_type_node,
integer_type_node, integer_type_node,
NULL_TREE);
tree v2si_ftype_v2si
- = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SI_type_node, NULL_TREE);
tree v2sf_ftype_v2sf
- = build_function_type_list (V2SF_type_node,
- V2SF_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SF_type_node,
+ opaque_V2SF_type_node, NULL_TREE);
tree v2sf_ftype_v2si
- = build_function_type_list (V2SF_type_node,
- V2SI_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SF_type_node,
+ opaque_V2SI_type_node, NULL_TREE);
tree v2si_ftype_v2sf
- = build_function_type_list (V2SI_type_node,
- V2SF_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SF_type_node, NULL_TREE);
tree v2si_ftype_v2si_char
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, char_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SI_type_node,
+ char_type_node, NULL_TREE);
tree v2si_ftype_int_char
- = build_function_type_list (V2SI_type_node,
+ = build_function_type_list (opaque_V2SI_type_node,
integer_type_node, char_type_node, NULL_TREE);
tree v2si_ftype_char
- = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ char_type_node, NULL_TREE);
tree int_ftype_int_int
= build_function_type_list (integer_type_node,
@@ -6122,6 +7597,57 @@ rs6000_common_init_builtins ()
}
}
+static void
+rs6000_init_libfuncs (void)
+{
+ if (!TARGET_HARD_FLOAT)
+ return;
+
+ if (DEFAULT_ABI != ABI_V4)
+ {
+ if (TARGET_XCOFF && ! TARGET_POWER2 && ! TARGET_POWERPC)
+ {
+ /* AIX library routines for float->int conversion. */
+ set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
+ set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
+ set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
+ set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
+ }
+
+ /* Standard AIX/Darwin/64-bit SVR4 quad floating point routines. */
+ set_optab_libfunc (add_optab, TFmode, "_xlqadd");
+ set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
+ set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
+ set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
+ }
+ else
+ {
+ /* 32-bit SVR4 quad floating point routines. */
+
+ set_optab_libfunc (add_optab, TFmode, "_q_add");
+ set_optab_libfunc (sub_optab, TFmode, "_q_sub");
+ set_optab_libfunc (neg_optab, TFmode, "_q_neg");
+ set_optab_libfunc (smul_optab, TFmode, "_q_mul");
+ set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
+ if (TARGET_PPC_GPOPT || TARGET_POWER2)
+ set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
+
+ set_optab_libfunc (eq_optab, TFmode, "_q_feq");
+ set_optab_libfunc (ne_optab, TFmode, "_q_fne");
+ set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
+ set_optab_libfunc (ge_optab, TFmode, "_q_fge");
+ set_optab_libfunc (lt_optab, TFmode, "_q_flt");
+ set_optab_libfunc (le_optab, TFmode, "_q_fle");
+
+ set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
+ set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
+ set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
+ set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
+ set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
+ set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
+ set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
+ }
+}
/* Expand a block move operation, and return 1 if successful. Return 0
if we should let the compiler generate normal code.
@@ -6134,8 +7660,7 @@ rs6000_common_init_builtins ()
#define MAX_MOVE_REG 4
int
-expand_block_move (operands)
- rtx operands[];
+expand_block_move (rtx operands[])
{
rtx orig_dest = operands[0];
rtx orig_src = operands[1];
@@ -6146,6 +7671,8 @@ expand_block_move (operands)
int bytes;
int offset;
int move_bytes;
+ rtx stores[MAX_MOVE_REG];
+ int num_reg = 0;
/* If this is not a fixed size move, just call memcpy */
if (! constp)
@@ -6166,182 +7693,130 @@ expand_block_move (operands)
if (bytes > (TARGET_POWERPC64 ? 64 : 32))
return 0;
- if (TARGET_STRING) /* string instructions are available */
- {
- for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
- {
- union {
- rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
- rtx (*mov) PARAMS ((rtx, rtx));
- } gen_func;
- enum machine_mode mode = BLKmode;
- rtx src, dest;
-
- if (bytes > 24 /* move up to 32 bytes at a time */
- && ! fixed_regs[5]
- && ! fixed_regs[6]
- && ! fixed_regs[7]
- && ! fixed_regs[8]
- && ! fixed_regs[9]
- && ! fixed_regs[10]
- && ! fixed_regs[11]
- && ! fixed_regs[12])
- {
- move_bytes = (bytes > 32) ? 32 : bytes;
- gen_func.movstrsi = gen_movstrsi_8reg;
- }
- else if (bytes > 16 /* move up to 24 bytes at a time */
- && ! fixed_regs[5]
- && ! fixed_regs[6]
- && ! fixed_regs[7]
- && ! fixed_regs[8]
- && ! fixed_regs[9]
- && ! fixed_regs[10])
- {
- move_bytes = (bytes > 24) ? 24 : bytes;
- gen_func.movstrsi = gen_movstrsi_6reg;
- }
- else if (bytes > 8 /* move up to 16 bytes at a time */
- && ! fixed_regs[5]
- && ! fixed_regs[6]
- && ! fixed_regs[7]
- && ! fixed_regs[8])
- {
- move_bytes = (bytes > 16) ? 16 : bytes;
- gen_func.movstrsi = gen_movstrsi_4reg;
- }
- else if (bytes >= 8 && TARGET_POWERPC64
- /* 64-bit loads and stores require word-aligned
- displacements. */
- && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
- {
- move_bytes = 8;
- mode = DImode;
- gen_func.mov = gen_movdi;
- }
- else if (bytes > 4 && !TARGET_POWERPC64)
- { /* move up to 8 bytes at a time */
- move_bytes = (bytes > 8) ? 8 : bytes;
- gen_func.movstrsi = gen_movstrsi_2reg;
- }
- else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
- { /* move 4 bytes */
- move_bytes = 4;
- mode = SImode;
- gen_func.mov = gen_movsi;
- }
- else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
- { /* move 2 bytes */
- move_bytes = 2;
- mode = HImode;
- gen_func.mov = gen_movhi;
- }
- else if (bytes == 1) /* move 1 byte */
- {
- move_bytes = 1;
- mode = QImode;
- gen_func.mov = gen_movqi;
- }
- else
- { /* move up to 4 bytes at a time */
- move_bytes = (bytes > 4) ? 4 : bytes;
- gen_func.movstrsi = gen_movstrsi_1reg;
- }
-
- src = adjust_address (orig_src, mode, offset);
- dest = adjust_address (orig_dest, mode, offset);
-
- if (mode == BLKmode)
- {
- /* Move the address into scratch registers. The movstrsi
- patterns require zero offset. */
- if (!REG_P (XEXP (src, 0)))
- {
- rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
- src = replace_equiv_address (src, src_reg);
- }
- set_mem_size (src, GEN_INT (move_bytes));
-
- if (!REG_P (XEXP (dest, 0)))
- {
- rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
- dest = replace_equiv_address (dest, dest_reg);
- }
- set_mem_size (dest, GEN_INT (move_bytes));
-
- emit_insn ((*gen_func.movstrsi) (dest, src,
- GEN_INT (move_bytes & 31),
- align_rtx));
- }
- else
- {
- rtx tmp_reg = gen_reg_rtx (mode);
-
- emit_insn ((*gen_func.mov) (tmp_reg, src));
- emit_insn ((*gen_func.mov) (dest, tmp_reg));
- }
- }
- }
-
- else /* string instructions not available */
+ for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
{
- rtx stores[MAX_MOVE_REG];
- int num_reg = 0;
- int i;
+ union {
+ rtx (*movstrsi) (rtx, rtx, rtx, rtx);
+ rtx (*mov) (rtx, rtx);
+ } gen_func;
+ enum machine_mode mode = BLKmode;
+ rtx src, dest;
+
+ if (TARGET_STRING
+ && bytes > 24 /* move up to 32 bytes at a time */
+ && ! fixed_regs[5]
+ && ! fixed_regs[6]
+ && ! fixed_regs[7]
+ && ! fixed_regs[8]
+ && ! fixed_regs[9]
+ && ! fixed_regs[10]
+ && ! fixed_regs[11]
+ && ! fixed_regs[12])
+ {
+ move_bytes = (bytes > 32) ? 32 : bytes;
+ gen_func.movstrsi = gen_movstrsi_8reg;
+ }
+ else if (TARGET_STRING
+ && bytes > 16 /* move up to 24 bytes at a time */
+ && ! fixed_regs[5]
+ && ! fixed_regs[6]
+ && ! fixed_regs[7]
+ && ! fixed_regs[8]
+ && ! fixed_regs[9]
+ && ! fixed_regs[10])
+ {
+ move_bytes = (bytes > 24) ? 24 : bytes;
+ gen_func.movstrsi = gen_movstrsi_6reg;
+ }
+ else if (TARGET_STRING
+ && bytes > 8 /* move up to 16 bytes at a time */
+ && ! fixed_regs[5]
+ && ! fixed_regs[6]
+ && ! fixed_regs[7]
+ && ! fixed_regs[8])
+ {
+ move_bytes = (bytes > 16) ? 16 : bytes;
+ gen_func.movstrsi = gen_movstrsi_4reg;
+ }
+ else if (bytes >= 8 && TARGET_POWERPC64
+ /* 64-bit loads and stores require word-aligned
+ displacements. */
+ && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
+ {
+ move_bytes = 8;
+ mode = DImode;
+ gen_func.mov = gen_movdi;
+ }
+ else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
+ { /* move up to 8 bytes at a time */
+ move_bytes = (bytes > 8) ? 8 : bytes;
+ gen_func.movstrsi = gen_movstrsi_2reg;
+ }
+ else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
+ { /* move 4 bytes */
+ move_bytes = 4;
+ mode = SImode;
+ gen_func.mov = gen_movsi;
+ }
+ else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
+ { /* move 2 bytes */
+ move_bytes = 2;
+ mode = HImode;
+ gen_func.mov = gen_movhi;
+ }
+ else if (TARGET_STRING && bytes > 1)
+ { /* move up to 4 bytes at a time */
+ move_bytes = (bytes > 4) ? 4 : bytes;
+ gen_func.movstrsi = gen_movstrsi_1reg;
+ }
+ else /* move 1 byte at a time */
+ {
+ move_bytes = 1;
+ mode = QImode;
+ gen_func.mov = gen_movqi;
+ }
+
+ src = adjust_address (orig_src, mode, offset);
+ dest = adjust_address (orig_dest, mode, offset);
+
+ if (mode != BLKmode)
+ {
+ rtx tmp_reg = gen_reg_rtx (mode);
+
+ emit_insn ((*gen_func.mov) (tmp_reg, src));
+ stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
+ }
- for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
+ if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
{
- rtx (*gen_mov_func) PARAMS ((rtx, rtx));
- enum machine_mode mode;
- rtx src, dest, tmp_reg;
+ int i;
+ for (i = 0; i < num_reg; i++)
+ emit_insn (stores[i]);
+ num_reg = 0;
+ }
- /* Generate the appropriate load and store, saving the stores
- for later. */
- if (bytes >= 8 && TARGET_POWERPC64
- /* 64-bit loads and stores require word-aligned
- displacements. */
- && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
- {
- move_bytes = 8;
- mode = DImode;
- gen_mov_func = gen_movdi;
- }
- else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
- {
- move_bytes = 4;
- mode = SImode;
- gen_mov_func = gen_movsi;
- }
- else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
- {
- move_bytes = 2;
- mode = HImode;
- gen_mov_func = gen_movhi;
- }
- else
+ if (mode == BLKmode)
+ {
+ /* Move the address into scratch registers. The movstrsi
+ patterns require zero offset. */
+ if (!REG_P (XEXP (src, 0)))
{
- move_bytes = 1;
- mode = QImode;
- gen_mov_func = gen_movqi;
+ rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
+ src = replace_equiv_address (src, src_reg);
}
-
- src = adjust_address (orig_src, mode, offset);
- dest = adjust_address (orig_dest, mode, offset);
- tmp_reg = gen_reg_rtx (mode);
-
- emit_insn ((*gen_mov_func) (tmp_reg, src));
- stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
-
- if (num_reg >= MAX_MOVE_REG)
+ set_mem_size (src, GEN_INT (move_bytes));
+
+ if (!REG_P (XEXP (dest, 0)))
{
- for (i = 0; i < num_reg; i++)
- emit_insn (stores[i]);
- num_reg = 0;
+ rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
+ dest = replace_equiv_address (dest, dest_reg);
}
+ set_mem_size (dest, GEN_INT (move_bytes));
+
+ emit_insn ((*gen_func.movstrsi) (dest, src,
+ GEN_INT (move_bytes & 31),
+ align_rtx));
}
-
- for (i = 0; i < num_reg; i++)
- emit_insn (stores[i]);
}
return 1;
@@ -6352,9 +7827,7 @@ expand_block_move (operands)
PARALLEL and the first section will be tested. */
int
-load_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int dest_regno;
@@ -6395,9 +7868,7 @@ load_multiple_operation (op, mode)
is a CLOBBER. It will be tested later. */
int
-store_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0) - 1;
unsigned int src_regno;
@@ -6440,8 +7911,7 @@ store_multiple_operation (op, mode)
operands[2] is the first destination register. */
const char *
-rs6000_output_load_multiple (operands)
- rtx operands[3];
+rs6000_output_load_multiple (rtx operands[3])
{
/* We have to handle the case where the pseudo used to contain the address
is assigned to one of the output registers. */
@@ -6495,9 +7965,7 @@ rs6000_output_load_multiple (operands)
/* Return 1 for a parallel vrsave operation. */
int
-vrsave_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+vrsave_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int dest_regno, src_regno;
@@ -6528,12 +7996,58 @@ vrsave_operation (op, mode)
return 1;
}
+/* Return 1 for an PARALLEL suitable for mfcr. */
+
+int
+mfcr_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* Perform a quick check so we don't blow up below. */
+ if (count < 1
+ || GET_CODE (XVECEXP (op, 0, 0)) != SET
+ || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
+ || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
+ return 0;
+
+ for (i = 0; i < count; i++)
+ {
+ rtx exp = XVECEXP (op, 0, i);
+ rtx unspec;
+ int maskval;
+ rtx src_reg;
+
+ src_reg = XVECEXP (SET_SRC (exp), 0, 0);
+
+ if (GET_CODE (src_reg) != REG
+ || GET_MODE (src_reg) != CCmode
+ || ! CR_REGNO_P (REGNO (src_reg)))
+ return 0;
+
+ if (GET_CODE (exp) != SET
+ || GET_CODE (SET_DEST (exp)) != REG
+ || GET_MODE (SET_DEST (exp)) != SImode
+ || ! INT_REGNO_P (REGNO (SET_DEST (exp))))
+ return 0;
+ unspec = SET_SRC (exp);
+ maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg));
+
+ if (GET_CODE (unspec) != UNSPEC
+ || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR
+ || XVECLEN (unspec, 0) != 2
+ || XVECEXP (unspec, 0, 0) != src_reg
+ || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
+ || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
+ return 0;
+ }
+ return 1;
+}
+
/* Return 1 for an PARALLEL suitable for mtcrf. */
int
-mtcrf_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mtcrf_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
int i;
@@ -6567,7 +8081,7 @@ mtcrf_operation (op, mode)
maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
if (GET_CODE (unspec) != UNSPEC
- || XINT (unspec, 1) != 20
+ || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR
|| XVECLEN (unspec, 0) != 2
|| XVECEXP (unspec, 0, 0) != src_reg
|| GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
@@ -6580,9 +8094,7 @@ mtcrf_operation (op, mode)
/* Return 1 for an PARALLEL suitable for lmw. */
int
-lmw_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+lmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int dest_regno;
@@ -6605,14 +8117,14 @@ lmw_operation (op, mode)
|| count != 32 - (int) dest_regno)
return 0;
- if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
+ if (legitimate_indirect_address_p (src_addr, 0))
{
offset = 0;
base_regno = REGNO (src_addr);
if (base_regno == 0)
return 0;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
+ else if (legitimate_offset_address_p (SImode, src_addr, 0))
{
offset = INTVAL (XEXP (src_addr, 1));
base_regno = REGNO (XEXP (src_addr, 0));
@@ -6635,12 +8147,12 @@ lmw_operation (op, mode)
|| GET_MODE (SET_SRC (elt)) != SImode)
return 0;
newaddr = XEXP (SET_SRC (elt), 0);
- if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
+ if (legitimate_indirect_address_p (newaddr, 0))
{
newoffset = 0;
addr_reg = newaddr;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
+ else if (legitimate_offset_address_p (SImode, newaddr, 0))
{
addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1));
@@ -6658,9 +8170,7 @@ lmw_operation (op, mode)
/* Return 1 for an PARALLEL suitable for stmw. */
int
-stmw_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+stmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int src_regno;
@@ -6683,14 +8193,14 @@ stmw_operation (op, mode)
|| count != 32 - (int) src_regno)
return 0;
- if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
+ if (legitimate_indirect_address_p (dest_addr, 0))
{
offset = 0;
base_regno = REGNO (dest_addr);
if (base_regno == 0)
return 0;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
+ else if (legitimate_offset_address_p (SImode, dest_addr, 0))
{
offset = INTVAL (XEXP (dest_addr, 1));
base_regno = REGNO (XEXP (dest_addr, 0));
@@ -6713,12 +8223,12 @@ stmw_operation (op, mode)
|| GET_MODE (SET_DEST (elt)) != SImode)
return 0;
newaddr = XEXP (SET_DEST (elt), 0);
- if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
+ if (legitimate_indirect_address_p (newaddr, 0))
{
newoffset = 0;
addr_reg = newaddr;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
+ else if (legitimate_offset_address_p (SImode, newaddr, 0))
{
addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1));
@@ -6738,9 +8248,7 @@ stmw_operation (op, mode)
never be generated. */
static void
-validate_condition_mode (code, mode)
- enum rtx_code code;
- enum machine_mode mode;
+validate_condition_mode (enum rtx_code code, enum machine_mode mode)
{
if (GET_RTX_CLASS (code) != '<'
|| GET_MODE_CLASS (mode) != MODE_CC)
@@ -6763,9 +8271,8 @@ validate_condition_mode (code, mode)
abort ();
/* These should never be generated except for
- flag_unsafe_math_optimizations and flag_finite_math_only. */
+ flag_finite_math_only. */
if (mode == CCFPmode
- && ! flag_unsafe_math_optimizations
&& ! flag_finite_math_only
&& (code == LE || code == GE
|| code == UNEQ || code == LTGT
@@ -6782,9 +8289,7 @@ validate_condition_mode (code, mode)
We only check the opcode against the mode of the CC value here. */
int
-branch_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+branch_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
enum machine_mode cc_mode;
@@ -6806,9 +8311,7 @@ branch_comparison_operator (op, mode)
is set. */
int
-branch_positive_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+branch_positive_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code;
@@ -6817,45 +8320,21 @@ branch_positive_comparison_operator (op, mode)
code = GET_CODE (op);
return (code == EQ || code == LT || code == GT
- || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
|| code == LTU || code == GTU
|| code == UNORDERED);
}
-/* Return 1 if OP is a comparison operation that is valid for an scc insn.
- We check the opcode against the mode of the CC value and disallow EQ or
- NE comparisons for integers. */
+/* Return 1 if OP is a comparison operation that is valid for an scc
+ insn: it must be a positive comparison. */
int
-scc_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+scc_comparison_operator (rtx op, enum machine_mode mode)
{
- enum rtx_code code = GET_CODE (op);
- enum machine_mode cc_mode;
-
- if (GET_MODE (op) != mode && mode != VOIDmode)
- return 0;
-
- if (GET_RTX_CLASS (code) != '<')
- return 0;
-
- cc_mode = GET_MODE (XEXP (op, 0));
- if (GET_MODE_CLASS (cc_mode) != MODE_CC)
- return 0;
-
- validate_condition_mode (code, cc_mode);
-
- if (code == NE && cc_mode != CCFPmode)
- return 0;
-
- return 1;
+ return branch_positive_comparison_operator (op, mode);
}
int
-trap_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+trap_comparison_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -6863,27 +8342,21 @@ trap_comparison_operator (op, mode)
}
int
-boolean_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+boolean_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
return (code == AND || code == IOR || code == XOR);
}
int
-boolean_or_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+boolean_or_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
return (code == IOR || code == XOR);
}
int
-min_max_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+min_max_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
@@ -6894,9 +8367,7 @@ min_max_operator (op, mode)
left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
int
-includes_lshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_lshift_p (rtx shiftop, rtx andop)
{
unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
@@ -6908,9 +8379,7 @@ includes_lshift_p (shiftop, andop)
/* Similar, but for right shift. */
int
-includes_rshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_rshift_p (rtx shiftop, rtx andop)
{
unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
@@ -6921,12 +8390,10 @@ includes_rshift_p (shiftop, andop)
/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
to perform a left shift. It must have exactly SHIFTOP least
- signifigant 0's, then one or more 1's, then zero or more 0's. */
+ significant 0's, then one or more 1's, then zero or more 0's. */
int
-includes_rldic_lshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_rldic_lshift_p (rtx shiftop, rtx andop)
{
if (GET_CODE (andop) == CONST_INT)
{
@@ -6939,7 +8406,7 @@ includes_rldic_lshift_p (shiftop, andop)
shift_mask = ~0;
shift_mask <<= INTVAL (shiftop);
- /* Find the least signifigant one bit. */
+ /* Find the least significant one bit. */
lsb = c & -c;
/* It must coincide with the LSB of the shift mask. */
@@ -7016,12 +8483,10 @@ includes_rldic_lshift_p (shiftop, andop)
/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
to perform a left shift. It must have SHIFTOP or more least
- signifigant 0's, with the remainder of the word 1's. */
+ significant 0's, with the remainder of the word 1's. */
int
-includes_rldicr_lshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_rldicr_lshift_p (rtx shiftop, rtx andop)
{
if (GET_CODE (andop) == CONST_INT)
{
@@ -7031,7 +8496,7 @@ includes_rldicr_lshift_p (shiftop, andop)
shift_mask <<= INTVAL (shiftop);
c = INTVAL (andop);
- /* Find the least signifigant one bit. */
+ /* Find the least significant one bit. */
lsb = c & -c;
/* It must be covered by the shift mask.
@@ -7093,8 +8558,7 @@ includes_rldicr_lshift_p (shiftop, andop)
abort if we are passed pseudo registers. */
int
-registers_ok_for_quad_peep (reg1, reg2)
- rtx reg1, reg2;
+registers_ok_for_quad_peep (rtx reg1, rtx reg2)
{
/* We might have been passed a SUBREG. */
if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
@@ -7108,9 +8572,7 @@ registers_ok_for_quad_peep (reg1, reg2)
(addr2 == addr1 + 8). */
int
-addrs_ok_for_quad_peep (addr1, addr2)
- rtx addr1;
- rtx addr2;
+addrs_ok_for_quad_peep (rtx addr1, rtx addr2)
{
unsigned int reg1;
int offset1;
@@ -7139,7 +8601,11 @@ addrs_ok_for_quad_peep (addr1, addr2)
offset1 = 0;
}
- /* Make sure the second address is a (mem (plus (reg) (const_int))). */
+ /* Make sure the second address is a (mem (plus (reg) (const_int)))
+ or if it is (mem (reg)) then make sure that offset1 is -8 and the same
+ register as addr1. */
+ if (offset1 == -8 && GET_CODE (addr2) == REG && reg1 == REGNO (addr2))
+ return 1;
if (GET_CODE (addr2) != PLUS)
return 0;
@@ -7161,17 +8627,22 @@ addrs_ok_for_quad_peep (addr1, addr2)
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
- NO_REGS is returned. */
+ NO_REGS is returned. INP is nonzero if we are loading the reg, zero
+ for storing. */
enum reg_class
-secondary_reload_class (class, mode, in)
- enum reg_class class;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx in;
+secondary_reload_class (enum reg_class class,
+ enum machine_mode mode,
+ rtx in,
+ int inp)
{
int regno;
- if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
+ if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
+#if TARGET_MACHO
+ && MACHOPIC_INDIRECT
+#endif
+ ))
{
/* We cannot copy a symbolic operand directly into anything
other than BASE_REGS for TARGET_ELF. So indicate that a
@@ -7188,6 +8659,14 @@ secondary_reload_class (class, mode, in)
return BASE_REGS;
}
+ /* A 64-bit gpr load or store using an offset that isn't a multiple of
+ four needs a secondary reload. */
+ if (TARGET_POWERPC64
+ && GET_MODE_UNIT_SIZE (mode) >= 8
+ && (!inp || class != BASE_REGS)
+ && invalid_gpr_mem (in, mode))
+ return BASE_REGS;
+
if (GET_CODE (in) == REG)
{
regno = REGNO (in);
@@ -7241,9 +8720,7 @@ secondary_reload_class (class, mode, in)
Return -1 if OP isn't a valid comparison for some reason. */
int
-ccr_bit (op, scc_p)
- rtx op;
- int scc_p;
+ccr_bit (rtx op, int scc_p)
{
enum rtx_code code = GET_CODE (op);
enum machine_mode cc_mode;
@@ -7266,15 +8743,17 @@ ccr_bit (op, scc_p)
validate_condition_mode (code, cc_mode);
+ /* When generating a sCOND operation, only positive conditions are
+ allowed. */
+ if (scc_p && code != EQ && code != GT && code != LT && code != UNORDERED
+ && code != GTU && code != LTU)
+ abort ();
+
switch (code)
{
case NE:
- if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- return base_bit + 1;
return scc_p ? base_bit + 3 : base_bit + 2;
case EQ:
- if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- return base_bit + 1;
return base_bit + 2;
case GT: case GTU: case UNLE:
return base_bit + 1;
@@ -7300,8 +8779,7 @@ ccr_bit (op, scc_p)
/* Return the GOT register. */
struct rtx_def *
-rs6000_got_register (value)
- rtx value ATTRIBUTE_UNUSED;
+rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
{
/* The second flow pass currently (June 1999) can't update
regs_ever_live without disturbing other parts of the compiler, so
@@ -7319,7 +8797,7 @@ rs6000_got_register (value)
from push_function_context. */
static struct machine_function *
-rs6000_init_machine_status ()
+rs6000_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (machine_function));
}
@@ -7333,8 +8811,7 @@ rs6000_init_machine_status ()
(GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
int
-extract_MB (op)
- rtx op;
+extract_MB (rtx op)
{
int i;
unsigned long val = INT_LOWPART (op);
@@ -7367,8 +8844,7 @@ extract_MB (op)
}
int
-extract_ME (op)
- rtx op;
+extract_ME (rtx op)
{
int i;
unsigned long val = INT_LOWPART (op);
@@ -7401,6 +8877,46 @@ extract_ME (op)
return i;
}
+/* Locate some local-dynamic symbol still in use by this function
+ so that we can print its name in some tls_ld pattern. */
+
+static const char *
+rs6000_get_some_local_dynamic_name (void)
+{
+ rtx insn;
+
+ if (cfun->machine->some_ld_name)
+ return cfun->machine->some_ld_name;
+
+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && for_each_rtx (&PATTERN (insn),
+ rs6000_get_some_local_dynamic_name_1, 0))
+ return cfun->machine->some_ld_name;
+
+ abort ();
+}
+
+/* Helper function for rs6000_get_some_local_dynamic_name. */
+
+static int
+rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
+{
+ rtx x = *px;
+
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ const char *str = XSTR (x, 0);
+ if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ cfun->machine->some_ld_name = str;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* Print an operand. Recognize special options, documented below. */
#if TARGET_ELF
@@ -7412,10 +8928,7 @@ extract_ME (op)
#endif
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
int i;
HOST_WIDE_INT val;
@@ -7460,40 +8973,24 @@ print_operand (file, x, code)
/* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
output_operand. */
- case 'D':
- /* There used to be a comment for 'C' reading "This is an
- optional cror needed for certain floating-point
- comparisons. Otherwise write nothing." */
-
- /* Similar, except that this is for an scc, so we must be able to
- encode the test in a single bit that is one. We do the above
- for any LE, GE, GEU, or LEU and invert the bit for NE. */
- if (GET_CODE (x) == LE || GET_CODE (x) == GE
- || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
- {
- int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
-
- fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
- base_bit + 2,
- base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
- }
+ case 'c':
+ /* X is a CR register. Print the number of the GT bit of the CR. */
+ if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+ output_operand_lossage ("invalid %%E value");
+ else
+ fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
+ return;
- else if (GET_CODE (x) == NE)
- {
- int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
+ case 'D':
+ /* Like 'J' but get to the GT bit. */
+ if (GET_CODE (x) != REG)
+ abort ();
- fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
- base_bit + 2, base_bit + 2);
- }
- else if (TARGET_SPE && TARGET_HARD_FLOAT
- && GET_CODE (x) == EQ
- && GET_MODE (XEXP (x, 0)) == CCFPmode)
- {
- int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
+ /* Bit 1 is GT bit. */
+ i = 4 * (REGNO (x) - CR0_REGNO) + 1;
- fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
- base_bit + 1, base_bit + 1);
- }
+ /* If we want bit 31, write a shift count of zero, not 32. */
+ fprintf (file, "%d", i == 31 ? 0 : i + 1);
return;
case 'E':
@@ -7731,6 +9228,13 @@ print_operand (file, x, code)
}
return;
+ case 'Q':
+ if (TARGET_MFCRF)
+ fputc (',',file);
+ /* FALLTHRU */
+ else
+ return;
+
case 'R':
/* X is a CR register. Print the mask for `mtcrf'. */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
@@ -7758,13 +9262,17 @@ print_operand (file, x, code)
if (uval & 1) /* Clear Left */
{
- uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
+#if HOST_BITS_PER_WIDE_INT > 64
+ uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
+#endif
i = 64;
}
else /* Clear Right */
{
uval = ~uval;
- uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
+#if HOST_BITS_PER_WIDE_INT > 64
+ uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
+#endif
i = 63;
}
while (uval != 0)
@@ -7907,7 +9415,7 @@ print_operand (file, x, code)
case 'X':
if (GET_CODE (x) == MEM
- && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
+ && legitimate_indexed_address_p (XEXP (x, 0), 0))
putc ('x', file);
return;
@@ -7949,16 +9457,14 @@ print_operand (file, x, code)
break;
case ABI_V4:
- case ABI_AIX_NODESC:
case ABI_DARWIN:
break;
}
}
-#if TARGET_AIX
- RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
-#else
- assemble_name (file, XSTR (x, 0));
-#endif
+ if (TARGET_AIX)
+ RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
+ else
+ assemble_name (file, XSTR (x, 0));
return;
case 'Z':
@@ -7988,7 +9494,7 @@ print_operand (file, x, code)
tmp = XEXP (x, 0);
- if (TARGET_SPE)
+ if (TARGET_E500)
{
/* Handle [reg]. */
if (GET_CODE (tmp) == REG)
@@ -8048,6 +9554,10 @@ print_operand (file, x, code)
output_addr_const (file, x);
return;
+ case '&':
+ assemble_name (file, rs6000_get_some_local_dynamic_name ());
+ return;
+
default:
output_operand_lossage ("invalid %%xn code");
}
@@ -8056,9 +9566,7 @@ print_operand (file, x, code)
/* Print the address of an operand. */
void
-print_operand_address (file, x)
- FILE *file;
- rtx x;
+print_operand_address (FILE *file, rtx x)
{
if (GET_CODE (x) == REG)
fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
@@ -8082,10 +9590,8 @@ print_operand_address (file, x)
reg_names[ REGNO (XEXP (x, 1)) ]);
}
else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
- {
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
- fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
- }
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
+ INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
#if TARGET_ELF
else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
&& CONSTANT_P (XEXP (x, 1)))
@@ -8103,7 +9609,7 @@ print_operand_address (file, x)
fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
}
#endif
- else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
+ else if (legitimate_constant_pool_address_p (x))
{
if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
{
@@ -8149,16 +9655,13 @@ print_operand_address (file, x)
targets. */
static bool
-rs6000_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
#ifdef RELOCATABLE_NEEDS_FIXUP
/* Special handling for SI values. */
if (size == 4 && aligned_p)
{
- extern int in_toc_section PARAMS ((void));
+ extern int in_toc_section (void);
static int recurse = 0;
/* For -mrelocatable, we mark all addresses that need to be fixed up
@@ -8212,9 +9715,7 @@ rs6000_assemble_integer (x, size, aligned_p)
VISIBILITY_TYPE. */
static void
-rs6000_assemble_visibility (decl, vis)
- tree decl;
- int vis;
+rs6000_assemble_visibility (tree decl, int vis)
{
/* Functions need to have their entry point symbol visibility set as
well as their descriptor symbol visibility. */
@@ -8239,13 +9740,14 @@ rs6000_assemble_visibility (decl, vis)
#endif
enum rtx_code
-rs6000_reverse_condition (mode, code)
- enum machine_mode mode;
- enum rtx_code code;
+rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
{
/* Reversal of FP compares takes care -- an ordered compare
becomes an unordered compare and vice versa. */
- if (mode == CCFPmode && !flag_unsafe_math_optimizations)
+ if (mode == CCFPmode
+ && (!flag_finite_math_only
+ || code == UNLT || code == UNLE || code == UNGT || code == UNGE
+ || code == UNEQ || code == LTGT))
return reverse_condition_maybe_unordered (code);
else
return reverse_condition (code);
@@ -8255,8 +9757,7 @@ rs6000_reverse_condition (mode, code)
represents the result of the compare. */
static rtx
-rs6000_generate_compare (code)
- enum rtx_code code;
+rs6000_generate_compare (enum rtx_code code)
{
enum machine_mode comp_mode;
rtx compare_result;
@@ -8273,41 +9774,32 @@ rs6000_generate_compare (code)
compare_result = gen_reg_rtx (comp_mode);
/* SPE FP compare instructions on the GPRs. Yuck! */
- if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
+ if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT)
+ && rs6000_compare_fp_p)
{
rtx cmp, or1, or2, or_result, compare_result2;
+ /* Note: The E500 comparison instructions set the GT bit (x +
+ 1), on success. This explains the mess. */
+
switch (code)
{
- case EQ:
- case UNEQ:
- case NE:
- case LTGT:
- cmp = flag_unsafe_math_optimizations
+ case EQ: case UNEQ: case NE: case LTGT:
+ cmp = flag_finite_math_only
? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
- case GT:
- case GTU:
- case UNGT:
- case UNGE:
- case GE:
- case GEU:
- cmp = flag_unsafe_math_optimizations
+ case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
+ cmp = flag_finite_math_only
? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
- case LT:
- case LTU:
- case UNLT:
- case UNLE:
- case LE:
- case LEU:
- cmp = flag_unsafe_math_optimizations
+ case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
+ cmp = flag_finite_math_only
? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
@@ -8320,8 +9812,6 @@ rs6000_generate_compare (code)
/* Synthesize LE and GE from LT/GT || EQ. */
if (code == LE || code == GE || code == LEU || code == GEU)
{
- /* Synthesize GE/LE frome GT/LT || EQ. */
-
emit_insn (cmp);
switch (code)
@@ -8339,30 +9829,15 @@ rs6000_generate_compare (code)
compare_result2 = gen_reg_rtx (CCFPmode);
/* Do the EQ. */
- cmp = flag_unsafe_math_optimizations
+ cmp = flag_finite_math_only
? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
rs6000_compare_op1);
emit_insn (cmp);
- /* The MC8540 FP compare instructions set the CR bits
- differently than other PPC compare instructions. For
- that matter, there is no generic test instruction, but a
- testgt, testlt, and testeq. For a true condition, bit 2
- is set (x1xx) in the CR. Following the traditional CR
- values:
-
- LT GT EQ OV
- bit3 bit2 bit1 bit0
-
- ... bit 2 would be a GT CR alias, so later on we
- look in the GT bits for the branch instructins.
- However, we must be careful to emit correct RTL in
- the meantime, so optimizations don't get confused. */
-
- or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
- or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
+ or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
+ or2 = gen_rtx_GT (SImode, compare_result2, const0_rtx);
/* OR them together. */
cmp = gen_rtx_SET (VOIDmode, or_result,
@@ -8374,16 +9849,10 @@ rs6000_generate_compare (code)
}
else
{
- /* We only care about 1 bit (x1xx), so map everything to NE to
- maintain rtl sanity. We'll get to the right bit (x1xx) at
- code output time. */
if (code == NE || code == LTGT)
- /* Do the inverse here because we have no cmpne
- instruction. We use the cmpeq instruction and expect
- to get a 0 instead. */
- code = EQ;
- else
code = NE;
+ else
+ code = EQ;
}
emit_insn (cmp);
@@ -8395,10 +9864,10 @@ rs6000_generate_compare (code)
rs6000_compare_op1)));
/* Some kinds of FP comparisons need an OR operation;
- except for flag_unsafe_math_optimizations we don't bother. */
+ under flag_finite_math_only we don't bother. */
if (rs6000_compare_fp_p
- && ! flag_unsafe_math_optimizations
- && ! (TARGET_HARD_FLOAT && TARGET_SPE)
+ && ! flag_finite_math_only
+ && ! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)
&& (code == LE || code == GE
|| code == UNEQ || code == LTGT
|| code == UNGT || code == UNLT))
@@ -8439,14 +9908,50 @@ rs6000_generate_compare (code)
/* Emit the RTL for an sCOND pattern. */
void
-rs6000_emit_sCOND (code, result)
- enum rtx_code code;
- rtx result;
+rs6000_emit_sCOND (enum rtx_code code, rtx result)
{
rtx condition_rtx;
enum machine_mode op_mode;
+ enum rtx_code cond_code;
condition_rtx = rs6000_generate_compare (code);
+ cond_code = GET_CODE (condition_rtx);
+
+ if (TARGET_E500 && rs6000_compare_fp_p
+ && !TARGET_FPRS && TARGET_HARD_FLOAT)
+ {
+ rtx t;
+
+ PUT_MODE (condition_rtx, SImode);
+ t = XEXP (condition_rtx, 0);
+
+ if (cond_code != NE && cond_code != EQ)
+ abort ();
+
+ if (cond_code == NE)
+ emit_insn (gen_e500_flip_gt_bit (t, t));
+
+ emit_insn (gen_move_from_CR_gt_bit (result, t));
+ return;
+ }
+
+ if (cond_code == NE
+ || cond_code == GE || cond_code == LE
+ || cond_code == GEU || cond_code == LEU
+ || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
+ {
+ rtx not_result = gen_reg_rtx (CCEQmode);
+ rtx not_op, rev_cond_rtx;
+ enum machine_mode cc_mode;
+
+ cc_mode = GET_MODE (XEXP (condition_rtx, 0));
+
+ rev_cond_rtx = gen_rtx (rs6000_reverse_condition (cc_mode, cond_code),
+ SImode, XEXP (condition_rtx, 0), const0_rtx);
+ not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
+ condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
+ }
op_mode = GET_MODE (rs6000_compare_op0);
if (op_mode == VOIDmode)
@@ -8467,9 +9972,7 @@ rs6000_emit_sCOND (code, result)
/* Emit a branch of kind CODE to location LOC. */
void
-rs6000_emit_cbranch (code, loc)
- enum rtx_code code;
- rtx loc;
+rs6000_emit_cbranch (enum rtx_code code, rtx loc)
{
rtx condition_rtx, loc_ref;
@@ -8493,11 +9996,7 @@ rs6000_emit_cbranch (code, loc)
INSN is the insn. */
char *
-output_cbranch (op, label, reversed, insn)
- rtx op;
- const char * label;
- int reversed;
- rtx insn;
+output_cbranch (rtx op, const char *label, int reversed, rtx insn)
{
static char string[64];
enum rtx_code code = GET_CODE (op);
@@ -8526,15 +10025,15 @@ output_cbranch (op, label, reversed, insn)
code = reverse_condition (code);
}
- if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
+ if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
{
/* The efscmp/tst* instructions twiddle bit 2, which maps nicely
to the GT bit. */
if (code == EQ)
/* Opposite of GT. */
- code = UNLE;
- else if (code == NE)
code = GT;
+ else if (code == NE)
+ code = UNLE;
else
abort ();
}
@@ -8571,7 +10070,6 @@ output_cbranch (op, label, reversed, insn)
{
/* PROB is the difference from 50%. */
int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
- bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
/* Only hint for highly probable/improbable branches on newer
cpus as static prediction overrides processor dynamic
@@ -8579,12 +10077,12 @@ output_cbranch (op, label, reversed, insn)
assume not taken for branches that are very close to 50% as a
mispredicted taken branch is more expensive than a
mispredicted not-taken branch. */
- if (always_hint
+ if (rs6000_always_hint
|| abs (prob) > REG_BR_PROB_BASE / 100 * 48)
{
if (abs (prob) > REG_BR_PROB_BASE / 20
&& ((prob > 0) ^ need_longbranch))
- pred = "+";
+ pred = "+";
else
pred = "-";
}
@@ -8596,7 +10094,7 @@ output_cbranch (op, label, reversed, insn)
s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
/* We need to escape any '%' characters in the reg_names string.
- Assume they'd only be the first character... */
+ Assume they'd only be the first character.... */
if (reg_names[cc_regno + CR0_REGNO][0] == '%')
*s++ = '%';
s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
@@ -8614,16 +10112,31 @@ output_cbranch (op, label, reversed, insn)
return string;
}
+/* Return the string to flip the GT bit on a CR. */
+char *
+output_e500_flip_gt_bit (rtx dst, rtx src)
+{
+ static char string[64];
+ int a, b;
+
+ if (GET_CODE (dst) != REG || ! CR_REGNO_P (REGNO (dst))
+ || GET_CODE (src) != REG || ! CR_REGNO_P (REGNO (src)))
+ abort ();
+
+ /* GT bit. */
+ a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
+ b = 4 * (REGNO (src) - CR0_REGNO) + 1;
+
+ sprintf (string, "crnot %d,%d", a, b);
+ return string;
+}
+
/* Emit a conditional move: move TRUE_COND to DEST if OP of the
operands of the last comparison is nonzero/true, FALSE_COND if it
is zero/false. Return 0 if the hardware has no such operation. */
int
-rs6000_emit_cmove (dest, op, true_cond, false_cond)
- rtx dest;
- rtx op;
- rtx true_cond;
- rtx false_cond;
+rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
{
enum rtx_code code = GET_CODE (op);
rtx op0 = rs6000_compare_op0;
@@ -8633,7 +10146,7 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
enum machine_mode result_mode = GET_MODE (dest);
rtx temp;
- /* These modes should always match. */
+ /* These modes should always match. */
if (GET_MODE (op1) != compare_mode
/* In the isel case however, we can use a compare immediate, so
op1 may be a small constant. */
@@ -8645,18 +10158,21 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
return 0;
/* First, work out if the hardware can do this at all, or
- if it's too slow... */
+ if it's too slow.... */
if (! rs6000_compare_fp_p)
{
if (TARGET_ISEL)
return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
return 0;
}
+ else if (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS
+ && GET_MODE_CLASS (compare_mode) == MODE_FLOAT)
+ return 0;
/* Eliminate half of the comparisons by switching operands, this
makes the remaining code simpler. */
if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
- || code == LTGT || code == LT)
+ || code == LTGT || code == LT || code == UNLE)
{
code = reverse_condition_maybe_unordered (code);
temp = true_cond;
@@ -8666,18 +10182,18 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
/* UNEQ and LTGT take four instructions for a comparison with zero,
it'll probably be faster to use a branch here too. */
- if (code == UNEQ)
+ if (code == UNEQ && HONOR_NANS (compare_mode))
return 0;
if (GET_CODE (op1) == CONST_DOUBLE)
REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
- /* We're going to try to implement comparions by performing
+ /* We're going to try to implement comparisons by performing
a subtract, then comparing against zero. Unfortunately,
Inf - Inf is NaN which is not zero, and so if we don't
know that the operand is finite and the comparison
would treat EQ different to UNORDERED, we can't do it. */
- if (! flag_unsafe_math_optimizations
+ if (HONOR_INFINITIES (compare_mode)
&& code != GT && code != UNGE
&& (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
/* Constructs of the form (a OP b ? a : b) are safe. */
@@ -8696,7 +10212,7 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
/* If we don't care about NaNs we can reduce some of the comparisons
down to faster ones. */
- if (flag_unsafe_math_optimizations)
+ if (! HONOR_NANS (compare_mode))
switch (code)
{
case GT:
@@ -8742,14 +10258,15 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
break;
case UNGE:
+ /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
temp = gen_reg_rtx (result_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp,
gen_rtx_IF_THEN_ELSE (result_mode,
gen_rtx_GE (VOIDmode,
op0, op1),
true_cond, false_cond)));
- false_cond = temp;
- true_cond = false_cond;
+ false_cond = true_cond;
+ true_cond = temp;
temp = gen_reg_rtx (compare_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
@@ -8757,14 +10274,15 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
break;
case GT:
+ /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
temp = gen_reg_rtx (result_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp,
gen_rtx_IF_THEN_ELSE (result_mode,
gen_rtx_GE (VOIDmode,
op0, op1),
true_cond, false_cond)));
- true_cond = temp;
- false_cond = true_cond;
+ true_cond = false_cond;
+ false_cond = temp;
temp = gen_reg_rtx (compare_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
@@ -8786,11 +10304,7 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
/* Same as above, but for ints (isel). */
static int
-rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
- rtx dest;
- rtx op;
- rtx true_cond;
- rtx false_cond;
+rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
{
rtx condition_rtx, cr;
@@ -8815,8 +10329,7 @@ rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
}
const char *
-output_isel (operands)
- rtx *operands;
+output_isel (rtx *operands)
{
enum rtx_code code;
@@ -8831,11 +10344,7 @@ output_isel (operands)
}
void
-rs6000_emit_minmax (dest, code, op0, op1)
- rtx dest;
- enum rtx_code code;
- rtx op0;
- rtx op1;
+rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
{
enum machine_mode mode = GET_MODE (op0);
enum rtx_code c;
@@ -8857,6 +10366,145 @@ rs6000_emit_minmax (dest, code, op0, op1)
if (target != dest)
emit_move_insn (dest, target);
}
+
+/* Emit instructions to move SRC to DST. Called by splitters for
+ multi-register moves. It will emit at most one instruction for
+ each register that is accessed; that is, it won't emit li/lis pairs
+ (or equivalent for 64-bit code). One of SRC or DST must be a hard
+ register. */
+
+void
+rs6000_split_multireg_move (rtx dst, rtx src)
+{
+ /* The register number of the first register being moved. */
+ int reg;
+ /* The mode that is to be moved. */
+ enum machine_mode mode;
+ /* The mode that the move is being done in, and its size. */
+ enum machine_mode reg_mode;
+ int reg_mode_size;
+ /* The number of registers that will be moved. */
+ int nregs;
+
+ reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
+ mode = GET_MODE (dst);
+ nregs = HARD_REGNO_NREGS (reg, mode);
+ if (FP_REGNO_P (reg))
+ reg_mode = DFmode;
+ else if (ALTIVEC_REGNO_P (reg))
+ reg_mode = V16QImode;
+ else
+ reg_mode = word_mode;
+ reg_mode_size = GET_MODE_SIZE (reg_mode);
+
+ if (reg_mode_size * nregs != GET_MODE_SIZE (mode))
+ abort ();
+
+ if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
+ {
+ /* Move register range backwards, if we might have destructive
+ overlap. */
+ int i;
+ for (i = nregs - 1; i >= 0; i--)
+ emit_insn (gen_rtx_SET (VOIDmode,
+ simplify_gen_subreg (reg_mode, dst, mode,
+ i * reg_mode_size),
+ simplify_gen_subreg (reg_mode, src, mode,
+ i * reg_mode_size)));
+ }
+ else
+ {
+ int i;
+ int j = -1;
+ bool used_update = false;
+
+ if (GET_CODE (src) == MEM && INT_REGNO_P (reg))
+ {
+ rtx breg;
+
+ if (GET_CODE (XEXP (src, 0)) == PRE_INC
+ || GET_CODE (XEXP (src, 0)) == PRE_DEC)
+ {
+ rtx delta_rtx;
+ breg = XEXP (XEXP (src, 0), 0);
+ delta_rtx = GET_CODE (XEXP (src, 0)) == PRE_INC
+ ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
+ : GEN_INT (-GET_MODE_SIZE (GET_MODE (src)));
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (breg, breg, delta_rtx)
+ : gen_adddi3 (breg, breg, delta_rtx));
+ src = gen_rtx_MEM (mode, breg);
+ }
+
+ /* We have now address involving an base register only.
+ If we use one of the registers to address memory,
+ we have change that register last. */
+
+ breg = (GET_CODE (XEXP (src, 0)) == PLUS
+ ? XEXP (XEXP (src, 0), 0)
+ : XEXP (src, 0));
+
+ if (!REG_P (breg))
+ abort();
+
+ if (REGNO (breg) >= REGNO (dst)
+ && REGNO (breg) < REGNO (dst) + nregs)
+ j = REGNO (breg) - REGNO (dst);
+ }
+
+ if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
+ {
+ rtx breg;
+
+ if (GET_CODE (XEXP (dst, 0)) == PRE_INC
+ || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
+ {
+ rtx delta_rtx;
+ breg = XEXP (XEXP (dst, 0), 0);
+ delta_rtx = GET_CODE (XEXP (dst, 0)) == PRE_INC
+ ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
+ : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst)));
+
+ /* We have to update the breg before doing the store.
+ Use store with update, if available. */
+
+ if (TARGET_UPDATE)
+ {
+ rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
+ emit_insn (TARGET_32BIT
+ ? gen_movsi_update (breg, breg, delta_rtx, nsrc)
+ : gen_movdi_update (breg, breg, delta_rtx, nsrc));
+ used_update = true;
+ }
+ else
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (breg, breg, delta_rtx)
+ : gen_adddi3 (breg, breg, delta_rtx));
+ dst = gen_rtx_MEM (mode, breg);
+ }
+ }
+
+ for (i = 0; i < nregs; i++)
+ {
+ /* Calculate index to next subword. */
+ ++j;
+ if (j == nregs)
+ j = 0;
+
+ /* If compiler already emited move of first word by
+ store with update, no need to do anything. */
+ if (j == 0 && used_update)
+ continue;
+
+ emit_insn (gen_rtx_SET (VOIDmode,
+ simplify_gen_subreg (reg_mode, dst, mode,
+ j * reg_mode_size),
+ simplify_gen_subreg (reg_mode, src, mode,
+ j * reg_mode_size)));
+ }
+ }
+}
+
/* This page contains routines that are used to determine what the
function prologue and epilogue code will do and write them out. */
@@ -8865,7 +10513,7 @@ rs6000_emit_minmax (dest, code, op0, op1)
saved. 32 if none. */
int
-first_reg_to_save ()
+first_reg_to_save (void)
{
int first_reg;
@@ -8891,7 +10539,7 @@ first_reg_to_save ()
/* Similar, for FP regs. */
int
-first_fp_reg_to_save ()
+first_fp_reg_to_save (void)
{
int first_reg;
@@ -8906,7 +10554,7 @@ first_fp_reg_to_save ()
/* Similar, for AltiVec regs. */
static int
-first_altivec_reg_to_save ()
+first_altivec_reg_to_save (void)
{
int i;
@@ -8927,7 +10575,7 @@ first_altivec_reg_to_save ()
the 32-bit word is 0. */
static unsigned int
-compute_vrsave_mask ()
+compute_vrsave_mask (void)
{
unsigned int i, mask = 0;
@@ -8939,25 +10587,12 @@ compute_vrsave_mask ()
if (mask == 0)
return mask;
- /* Next, add all registers that are call-clobbered. We do this
- because post-reload register optimizers such as regrename_optimize
- may choose to use them. They never change the register class
- chosen by reload, so cannot create new uses of altivec registers
- if there were none before, so the early exit above is safe. */
- /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
- altivec registers not saved in the mask, which might well make the
- adjustments below more effective in eliding the save/restore of
- VRSAVE in small functions. */
- for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
- if (call_used_regs[i])
- mask |= ALTIVEC_REG_BIT (i);
-
/* Next, remove the argument registers from the set. These must
be in the VRSAVE mask set by the caller, so we don't need to add
them in again. More importantly, the mask we compute here is
used to generate CLOBBERs in the set_vrsave insn, and we do not
wish the argument registers to die. */
- for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
+ for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
mask &= ~ALTIVEC_REG_BIT (i);
/* Similarly, remove the return value from the set. */
@@ -8972,9 +10607,7 @@ compute_vrsave_mask ()
}
static void
-is_altivec_return_reg (reg, xyes)
- rtx reg;
- void *xyes;
+is_altivec_return_reg (rtx reg, void *xyes)
{
bool *yes = (bool *) xyes;
if (REGNO (reg) == ALTIVEC_ARG_RETURN)
@@ -9069,8 +10702,7 @@ is_altivec_return_reg (reg, xyes)
align the stack at program startup. A happy side-effect is that
-mno-eabi libraries can be used with -meabi programs.)
- The EABI configuration defaults to the V.4 layout, unless
- -mcall-aix is used, in which case the AIX layout is used. However,
+ The EABI configuration defaults to the V.4 layout. However,
the stack alignment requirements may differ. If -mno-eabi is not
given, the required stack alignment is 8 bytes; if -mno-eabi is
given, the required alignment is 16 bytes. (But see V.4 comment
@@ -9080,29 +10712,38 @@ is_altivec_return_reg (reg, xyes)
#define ABI_STACK_BOUNDARY STACK_BOUNDARY
#endif
-rs6000_stack_t *
-rs6000_stack_info ()
+static rs6000_stack_t *
+rs6000_stack_info (void)
{
static rs6000_stack_t info, zero_info;
rs6000_stack_t *info_ptr = &info;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
- enum rs6000_abi abi;
+ int reg_size = TARGET_32BIT ? 4 : 8;
int ehrd_size;
- int total_raw_size;
+ HOST_WIDE_INT non_fixed_size;
/* Zero all fields portably. */
info = zero_info;
+ if (TARGET_SPE)
+ {
+ /* Cache value so we don't rescan instruction chain over and over. */
+ if (cfun->machine->insn_chain_scanned_p == 0)
+ {
+ cfun->machine->insn_chain_scanned_p = 1;
+ info_ptr->spe_64bit_regs_used = (int) spe_func_has_64bit_regs_p ();
+ }
+ }
+
/* Select which calling sequence. */
- info_ptr->abi = abi = DEFAULT_ABI;
+ info_ptr->abi = DEFAULT_ABI;
/* Calculate which registers need to be saved & save area size. */
info_ptr->first_gp_reg_save = first_reg_to_save ();
/* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
even if it currently looks like we won't. */
if (((TARGET_TOC && TARGET_MINIMAL_TOC)
- || (flag_pic == 1 && abi == ABI_V4)
- || (flag_pic && abi == ABI_DARWIN))
+ || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
+ || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
&& info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
else
@@ -9114,12 +10755,13 @@ rs6000_stack_info ()
registers live (not the size they are used in), this proves
difficult because we'd have to traverse the instruction chain at
the right time, taking reload into account. This is a real pain,
- so we opt to save the GPRs in 64-bits always. Anyone overly
- concerned with frame size can fix this. ;-).
+ so we opt to save the GPRs in 64-bits always if but one register
+ gets used in 64-bits. Otherwise, all the registers in the frame
+ get saved in 32-bits.
- So... since we save all GPRs (except the SP) in 64-bits, the
+ So... since when we save all GPRs (except the SP) in 64-bits, the
traditional GP save area will be empty. */
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
info_ptr->gp_size = 0;
info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
@@ -9135,14 +10777,16 @@ rs6000_stack_info ()
/* Determine if we need to save the link register. */
if (rs6000_ra_ever_killed ()
- || (DEFAULT_ABI == ABI_AIX && current_function_profile)
+ || (DEFAULT_ABI == ABI_AIX
+ && current_function_profile
+ && !TARGET_PROFILE_KERNEL)
#ifdef TARGET_RELOCATABLE
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
#endif
|| (info_ptr->first_fp_reg_save != 64
&& !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
|| info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
- || (abi == ABI_V4 && current_function_calls_alloca)
+ || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
|| (DEFAULT_ABI == ABI_DARWIN
&& flag_pic
&& current_function_uses_pic_offset_table)
@@ -9158,7 +10802,7 @@ rs6000_stack_info ()
|| regs_ever_live[CR4_REGNO])
{
info_ptr->cr_save_p = 1;
- if (abi == ABI_V4)
+ if (DEFAULT_ABI == ABI_V4)
info_ptr->cr_size = reg_size;
}
@@ -9172,7 +10816,9 @@ rs6000_stack_info ()
continue;
/* SPE saves EH registers in 64-bits. */
- ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
+ ehrd_size = i * (TARGET_SPE_ABI
+ && info_ptr->spe_64bit_regs_used != 0
+ ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
}
else
ehrd_size = 0;
@@ -9183,33 +10829,31 @@ rs6000_stack_info ()
info_ptr->varargs_size = RS6000_VARARGS_AREA;
info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
- 8);
+ TARGET_ALTIVEC ? 16 : 8);
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
else
info_ptr->spe_gp_size = 0;
- if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
- {
- info_ptr->vrsave_mask = compute_vrsave_mask ();
- info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
- }
+ if (TARGET_ALTIVEC_ABI)
+ info_ptr->vrsave_mask = compute_vrsave_mask ();
else
- {
- info_ptr->vrsave_mask = 0;
- info_ptr->vrsave_size = 0;
- }
+ info_ptr->vrsave_mask = 0;
+
+ if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
+ info_ptr->vrsave_size = 4;
+ else
+ info_ptr->vrsave_size = 0;
/* Calculate the offsets. */
- switch (abi)
+ switch (DEFAULT_ABI)
{
case ABI_NONE:
default:
abort ();
case ABI_AIX:
- case ABI_AIX_NODESC:
case ABI_DARWIN:
info_ptr->fp_save_offset = - info_ptr->fp_size;
info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
@@ -9245,7 +10889,7 @@ rs6000_stack_info ()
info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
{
/* Align stack so SPE GPR save area is aligned on a
double-word boundary. */
@@ -9296,24 +10940,23 @@ rs6000_stack_info ()
+ info_ptr->gp_size
+ info_ptr->altivec_size
+ info_ptr->altivec_padding_size
- + info_ptr->vrsave_size
+ info_ptr->spe_gp_size
+ info_ptr->spe_padding_size
+ ehrd_size
+ info_ptr->cr_size
+ info_ptr->lr_size
+ + info_ptr->vrsave_size
+ info_ptr->toc_size,
(TARGET_ALTIVEC_ABI || ABI_DARWIN)
? 16 : 8);
- total_raw_size = (info_ptr->vars_size
+ non_fixed_size = (info_ptr->vars_size
+ info_ptr->parm_size
+ info_ptr->save_size
- + info_ptr->varargs_size
- + info_ptr->fixed_size);
+ + info_ptr->varargs_size);
- info_ptr->total_size =
- RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
+ info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
+ ABI_STACK_BOUNDARY / BITS_PER_UNIT);
/* Determine if we need to allocate any stack frame:
@@ -9330,14 +10973,17 @@ rs6000_stack_info ()
if (info_ptr->calls_p)
info_ptr->push_p = 1;
- else if (abi == ABI_V4)
- info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
+ else if (DEFAULT_ABI == ABI_V4)
+ info_ptr->push_p = non_fixed_size != 0;
+
+ else if (frame_pointer_needed)
+ info_ptr->push_p = 1;
+
+ else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
+ info_ptr->push_p = 1;
else
- info_ptr->push_p = (frame_pointer_needed
- || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
- || ((total_raw_size - info_ptr->fixed_size)
- > (TARGET_32BIT ? 220 : 288)));
+ info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
/* Zero offsets if we're not saving those registers. */
if (info_ptr->fp_size == 0)
@@ -9352,7 +10998,9 @@ rs6000_stack_info ()
if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
info_ptr->vrsave_save_offset = 0;
- if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
+ if (! TARGET_SPE_ABI
+ || info_ptr->spe_64bit_regs_used == 0
+ || info_ptr->spe_gp_size == 0)
info_ptr->spe_gp_save_offset = 0;
if (! info_ptr->lr_save_p)
@@ -9367,9 +11015,41 @@ rs6000_stack_info ()
return info_ptr;
}
-void
-debug_stack_info (info)
- rs6000_stack_t *info;
+/* Return true if the current function uses any GPRs in 64-bit SIMD
+ mode. */
+
+static bool
+spe_func_has_64bit_regs_p (void)
+{
+ rtx insns, insn;
+
+ /* Functions that save and restore all the call-saved registers will
+ need to save/restore the registers in 64-bits. */
+ if (current_function_calls_eh_return
+ || current_function_calls_setjmp
+ || current_function_has_nonlocal_goto)
+ return true;
+
+ insns = get_insns ();
+
+ for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ {
+ rtx i;
+
+ i = PATTERN (insn);
+ if (GET_CODE (i) == SET
+ && SPE_VECTOR_MODE (GET_MODE (SET_SRC (i))))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void
+debug_stack_info (rs6000_stack_t *info)
{
const char *abi_string;
@@ -9385,8 +11065,7 @@ debug_stack_info (info)
{
default: abi_string = "Unknown"; break;
case ABI_NONE: abi_string = "NONE"; break;
- case ABI_AIX:
- case ABI_AIX_NODESC: abi_string = "AIX"; break;
+ case ABI_AIX: abi_string = "AIX"; break;
case ABI_DARWIN: abi_string = "Darwin"; break;
case ABI_V4: abi_string = "V.4"; break;
}
@@ -9458,13 +11137,15 @@ debug_stack_info (info)
fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
if (info->total_size)
- fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
+ fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
+ info->total_size);
if (info->varargs_size)
fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
if (info->vars_size)
- fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
+ fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
+ info->vars_size);
if (info->parm_size)
fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
@@ -9514,14 +11195,12 @@ debug_stack_info (info)
}
rtx
-rs6000_return_addr (count, frame)
- int count;
- rtx frame;
+rs6000_return_addr (int count, rtx frame)
{
/* Currently we don't optimize very well between prolog and body
code and for PIC code the code can be actually quite bad, so
don't try to be too clever here. */
- if (count != 0 || flag_pic != 0)
+ if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
{
cfun->machine->ra_needs_full_frame = 1;
@@ -9536,6 +11215,7 @@ rs6000_return_addr (count, frame)
RETURN_ADDRESS_OFFSET)));
}
+ cfun->machine->ra_need_lr = 1;
return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
}
@@ -9546,53 +11226,48 @@ rs6000_return_addr (count, frame)
vector parameters are required to have a prototype, so the argument
type info must be available here. (The tail recursion case can work
with vector parameters, but there's no way to distinguish here.) */
-int
-function_ok_for_sibcall (fndecl)
- tree fndecl;
+static bool
+rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
tree type;
- if (fndecl)
+ if (decl)
{
if (TARGET_ALTIVEC_VRSAVE)
{
- for (type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
type; type = TREE_CHAIN (type))
{
if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
- return 0;
+ return false;
}
}
if (DEFAULT_ABI == ABI_DARWIN
- || (*targetm.binds_local_p) (fndecl))
+ || (*targetm.binds_local_p) (decl))
{
- tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
+ tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
if (!lookup_attribute ("longcall", attr_list)
|| lookup_attribute ("shortcall", attr_list))
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
static int
-rs6000_ra_ever_killed ()
+rs6000_ra_ever_killed (void)
{
rtx top;
rtx reg;
rtx insn;
- /* Irritatingly, there are two kinds of thunks -- those created with
- TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
- through the regular part of the compiler. This is a very hacky
- way to tell them apart. */
- if (current_function_is_thunk && !no_new_pseudos)
+ if (current_function_is_thunk)
return 0;
/* regs_ever_live has LR marked as used if any sibcalls are present,
but this should not force saving and restoring in the
pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
- clobbers LR, so that is inappropriate. */
+ clobbers LR, so that is inappropriate. */
/* Also, the prologue can generate a store into LR that
doesn't really count, like this:
@@ -9629,8 +11304,7 @@ rs6000_ra_ever_killed ()
/* Add a REG_MAYBE_DEAD note to the insn. */
static void
-rs6000_maybe_dead (insn)
- rtx insn;
+rs6000_maybe_dead (rtx insn)
{
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
const0_rtx,
@@ -9642,8 +11316,7 @@ rs6000_maybe_dead (insn)
a constant pool; or for SVR4 -fpic. */
void
-rs6000_emit_load_toc_table (fromprolog)
- int fromprolog;
+rs6000_emit_load_toc_table (int fromprolog)
{
rtx dest, insn;
dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
@@ -9741,42 +11414,86 @@ rs6000_emit_load_toc_table (fromprolog)
abort ();
}
+/* Emit instructions to restore the link register after determining where
+ its value has been stored. */
+
+void
+rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
+{
+ rs6000_stack_t *info = rs6000_stack_info ();
+ rtx operands[2];
+
+ operands[0] = source;
+ operands[1] = scratch;
+
+ if (info->lr_save_p)
+ {
+ rtx frame_rtx = stack_pointer_rtx;
+ HOST_WIDE_INT sp_offset = 0;
+ rtx tmp;
+
+ if (frame_pointer_needed
+ || current_function_calls_alloca
+ || info->total_size > 32767)
+ {
+ emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
+ frame_rtx = operands[1];
+ }
+ else if (info->push_p)
+ sp_offset = info->total_size;
+
+ tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
+ tmp = gen_rtx_MEM (Pmode, tmp);
+ emit_move_insn (tmp, operands[0]);
+ }
+ else
+ emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
+}
+
+static GTY(()) int set = -1;
+
int
-get_TOC_alias_set ()
+get_TOC_alias_set (void)
{
- static int set = -1;
- if (set == -1)
- set = new_alias_set ();
- return set;
+ if (set == -1)
+ set = new_alias_set ();
+ return set;
}
-/* This retuns nonzero if the current function uses the TOC. This is
- determined by the presence of (unspec ... 7), which is generated by
- the various load_toc_* patterns. */
-
-int
-uses_TOC ()
+/* This returns nonzero if the current function uses the TOC. This is
+ determined by the presence of (use (unspec ... UNSPEC_TOC)), which
+ is generated by the ABI_V4 load_toc_* patterns. */
+#if TARGET_ELF
+static int
+uses_TOC (void)
{
- rtx insn;
+ rtx insn;
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- {
- rtx pat = PATTERN (insn);
- int i;
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ {
+ rtx pat = PATTERN (insn);
+ int i;
- if (GET_CODE (pat) == PARALLEL)
- for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
- if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
- && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
- return 1;
- }
- return 0;
+ if (GET_CODE (pat) == PARALLEL)
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx sub = XVECEXP (pat, 0, i);
+ if (GET_CODE (sub) == USE)
+ {
+ sub = XEXP (sub, 0);
+ if (GET_CODE (sub) == UNSPEC
+ && XINT (sub, 1) == UNSPEC_TOC)
+ return 1;
+ }
+ }
+ }
+ return 0;
}
+#endif
rtx
-create_TOC_reference (symbol)
- rtx symbol;
+create_TOC_reference (rtx symbol)
{
return gen_rtx_PLUS (Pmode,
gen_rtx_REG (Pmode, TOC_REGISTER),
@@ -9785,141 +11502,47 @@ create_TOC_reference (symbol)
gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
}
-#if TARGET_AIX
-/* __throw will restore its own return address to be the same as the
- return address of the function that the throw is being made to.
- This is unfortunate, because we want to check the original
- return address to see if we need to restore the TOC.
- So we have to squirrel it away here.
- This is used only in compiling __throw and __rethrow.
-
- Most of this code should be removed by CSE. */
-static rtx insn_after_throw;
+/* If _Unwind_* has been called from within the same module,
+ toc register is not guaranteed to be saved to 40(1) on function
+ entry. Save it there in that case. */
-/* This does the saving... */
void
-rs6000_aix_emit_builtin_unwind_init ()
+rs6000_aix_emit_builtin_unwind_init (void)
{
rtx mem;
rtx stack_top = gen_reg_rtx (Pmode);
rtx opcode_addr = gen_reg_rtx (Pmode);
-
- insn_after_throw = gen_reg_rtx (SImode);
+ rtx opcode = gen_reg_rtx (SImode);
+ rtx tocompare = gen_reg_rtx (SImode);
+ rtx no_toc_save_needed = gen_label_rtx ();
mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
emit_move_insn (stack_top, mem);
- mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, stack_top,
+ mem = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode, stack_top,
GEN_INT (2 * GET_MODE_SIZE (Pmode))));
emit_move_insn (opcode_addr, mem);
- emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
-}
-
-/* Emit insns to _restore_ the TOC register, at runtime (specifically
- in _eh.o). Only used on AIX.
-
- The idea is that on AIX, function calls look like this:
- bl somefunction-trampoline
- lwz r2,20(sp)
-
- and later,
- somefunction-trampoline:
- stw r2,20(sp)
- ... load function address in the count register ...
- bctr
- or like this, if the linker determines that this is not a cross-module call
- and so the TOC need not be restored:
- bl somefunction
- nop
- or like this, if the compiler could determine that this is not a
- cross-module call:
- bl somefunction
- now, the tricky bit here is that register 2 is saved and restored
- by the _linker_, so we can't readily generate debugging information
- for it. So we need to go back up the call chain looking at the
- insns at return addresses to see which calls saved the TOC register
- and so see where it gets restored from.
-
- Oh, and all this gets done in RTL inside the eh_epilogue pattern,
- just before the actual epilogue.
-
- On the bright side, this incurs no space or time overhead unless an
- exception is thrown, except for the extra code in libgcc.a.
-
- The parameter STACKSIZE is a register containing (at runtime)
- the amount to be popped off the stack in addition to the stack frame
- of this routine (which will be __throw or __rethrow, and so is
- guaranteed to have a stack frame). */
-
-void
-rs6000_emit_eh_toc_restore (stacksize)
- rtx stacksize;
-{
- rtx top_of_stack;
- rtx bottom_of_stack = gen_reg_rtx (Pmode);
- rtx tocompare = gen_reg_rtx (SImode);
- rtx opcode = gen_reg_rtx (SImode);
- rtx opcode_addr = gen_reg_rtx (Pmode);
- rtx mem;
- rtx loop_start = gen_label_rtx ();
- rtx no_toc_restore_needed = gen_label_rtx ();
- rtx loop_exit = gen_label_rtx ();
-
- mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
- set_mem_alias_set (mem, rs6000_sr_alias_set);
- emit_move_insn (bottom_of_stack, mem);
-
- top_of_stack = expand_binop (Pmode, add_optab,
- bottom_of_stack, stacksize,
- NULL_RTX, 1, OPTAB_WIDEN);
-
- emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
+ emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
+ emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
: 0xE8410028, SImode));
- if (insn_after_throw == NULL_RTX)
- abort ();
- emit_move_insn (opcode, insn_after_throw);
-
- emit_note (NULL, NOTE_INSN_LOOP_BEG);
- emit_label (loop_start);
-
- do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
+ do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
SImode, NULL_RTX, NULL_RTX,
- no_toc_restore_needed);
-
- mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, bottom_of_stack,
- GEN_INT (5 * GET_MODE_SIZE (Pmode))));
- emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
-
- emit_label (no_toc_restore_needed);
- do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
- Pmode, NULL_RTX, NULL_RTX,
- loop_exit);
+ no_toc_save_needed);
- mem = gen_rtx_MEM (Pmode, bottom_of_stack);
- set_mem_alias_set (mem, rs6000_sr_alias_set);
- emit_move_insn (bottom_of_stack, mem);
-
- mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, bottom_of_stack,
- GEN_INT (2 * GET_MODE_SIZE (Pmode))));
- emit_move_insn (opcode_addr, mem);
- emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
-
- emit_note (NULL, NOTE_INSN_LOOP_CONT);
- emit_jump (loop_start);
- emit_note (NULL, NOTE_INSN_LOOP_END);
- emit_label (loop_exit);
+ mem = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode, stack_top,
+ GEN_INT (5 * GET_MODE_SIZE (Pmode))));
+ emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
+ emit_label (no_toc_save_needed);
}
-#endif /* TARGET_AIX */
/* This ties together stack memory (MEM with an alias set of
rs6000_sr_alias_set) and the change to the stack pointer. */
static void
-rs6000_emit_stack_tie ()
+rs6000_emit_stack_tie (void)
{
rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
@@ -9932,9 +11555,7 @@ rs6000_emit_stack_tie ()
The generated code may use hard register 0 as a temporary. */
static void
-rs6000_emit_allocate_stack (size, copy_r12)
- HOST_WIDE_INT size;
- int copy_r12;
+rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
{
rtx insn;
rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
@@ -9947,14 +11568,14 @@ rs6000_emit_allocate_stack (size, copy_r12)
&& REGNO (stack_limit_rtx) > 1
&& REGNO (stack_limit_rtx) <= 31)
{
- emit_insn (Pmode == SImode
+ emit_insn (TARGET_32BIT
? gen_addsi3 (tmp_reg,
stack_limit_rtx,
GEN_INT (size))
: gen_adddi3 (tmp_reg,
stack_limit_rtx,
GEN_INT (size)));
-
+
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
const0_rtx));
}
@@ -9966,7 +11587,7 @@ rs6000_emit_allocate_stack (size, copy_r12)
gen_rtx_PLUS (Pmode,
stack_limit_rtx,
GEN_INT (size)));
-
+
emit_insn (gen_elf_high (tmp_reg, toload));
emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
@@ -9985,29 +11606,27 @@ rs6000_emit_allocate_stack (size, copy_r12)
{
/* Need a note here so that try_split doesn't get confused. */
if (get_last_insn() == NULL_RTX)
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
insn = emit_move_insn (tmp_reg, todec);
try_split (PATTERN (insn), insn, 0);
todec = tmp_reg;
}
-
- if (Pmode == SImode)
- insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
- todec, stack_reg));
- else
- insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
+
+ insn = emit_insn (TARGET_32BIT
+ ? gen_movsi_update (stack_reg, stack_reg,
+ todec, stack_reg)
+ : gen_movdi_update (stack_reg, stack_reg,
todec, stack_reg));
}
else
{
- if (Pmode == SImode)
- insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
- else
- insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
+ insn = emit_insn (TARGET_32BIT
+ ? gen_addsi3 (stack_reg, stack_reg, todec)
+ : gen_adddi3 (stack_reg, stack_reg, todec));
emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
gen_rtx_REG (Pmode, 12));
}
-
+
RTX_FRAME_RELATED_P (insn) = 1;
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
@@ -10017,32 +11636,6 @@ rs6000_emit_allocate_stack (size, copy_r12)
REG_NOTES (insn));
}
-/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
- knows that:
-
- (mem (plus (blah) (regXX)))
-
- is really:
-
- (mem (plus (blah) (const VALUE_OF_REGXX))). */
-
-static void
-altivec_frame_fixup (insn, reg, val)
- rtx insn, reg;
- HOST_WIDE_INT val;
-{
- rtx real;
-
- real = copy_rtx (PATTERN (insn));
-
- real = replace_rtx (real, reg, GEN_INT (val));
-
- RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- real,
- REG_NOTES (insn));
-}
-
/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
is not NULL. It would be nice if dwarf2out_frame_debug_expr could
@@ -10050,12 +11643,8 @@ altivec_frame_fixup (insn, reg, val)
its hand so much. */
static void
-rs6000_frame_related (insn, reg, val, reg2, rreg)
- rtx insn;
- rtx reg;
- HOST_WIDE_INT val;
- rtx reg2;
- rtx rreg;
+rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
+ rtx reg2, rtx rreg)
{
rtx real, temp;
@@ -10123,21 +11712,84 @@ rs6000_frame_related (insn, reg, val, reg2, rreg)
}
else
abort ();
-
+
+ if (TARGET_SPE)
+ real = spe_synthesize_frame_save (real);
+
RTX_FRAME_RELATED_P (insn) = 1;
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
real,
REG_NOTES (insn));
}
+/* Given an SPE frame note, return a PARALLEL of SETs with the
+ original note, plus a synthetic register save. */
+
+static rtx
+spe_synthesize_frame_save (rtx real)
+{
+ rtx synth, offset, reg, real2;
+
+ if (GET_CODE (real) != SET
+ || GET_MODE (SET_SRC (real)) != V2SImode)
+ return real;
+
+ /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
+ frame related note. The parallel contains a set of the register
+ being saved, and another set to a synthetic register (n+1200).
+ This is so we can differentiate between 64-bit and 32-bit saves.
+ Words cannot describe this nastiness. */
+
+ if (GET_CODE (SET_DEST (real)) != MEM
+ || GET_CODE (XEXP (SET_DEST (real), 0)) != PLUS
+ || GET_CODE (SET_SRC (real)) != REG)
+ abort ();
+
+ /* Transform:
+ (set (mem (plus (reg x) (const y)))
+ (reg z))
+ into:
+ (set (mem (plus (reg x) (const y+4)))
+ (reg z+1200))
+ */
+
+ real2 = copy_rtx (real);
+ PUT_MODE (SET_DEST (real2), SImode);
+ reg = SET_SRC (real2);
+ real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
+ synth = copy_rtx (real2);
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
+ real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
+ }
+
+ reg = SET_SRC (synth);
+
+ synth = replace_rtx (synth, reg,
+ gen_rtx_REG (SImode, REGNO (reg) + 1200));
+
+ offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
+ synth = replace_rtx (synth, offset,
+ GEN_INT (INTVAL (offset)
+ + (BYTES_BIG_ENDIAN ? 0 : 4)));
+
+ RTX_FRAME_RELATED_P (synth) = 1;
+ RTX_FRAME_RELATED_P (real2) = 1;
+ if (BYTES_BIG_ENDIAN)
+ real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
+ else
+ real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
+
+ return real;
+}
+
/* Returns an insn that has a vrsave set operation with the
appropriate CLOBBERs. */
static rtx
-generate_set_vrsave (reg, info, epiloguep)
- rtx reg;
- rs6000_stack_t *info;
- int epiloguep;
+generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
{
int nclobs, i;
rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
@@ -10167,7 +11819,7 @@ generate_set_vrsave (reg, info, epiloguep)
need an unspec use/set of the register. */
for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
- if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
+ if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
if (!epiloguep || call_used_regs [i])
clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
@@ -10196,13 +11848,8 @@ generate_set_vrsave (reg, info, epiloguep)
Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
static void
-emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
- rtx frame_reg;
- rtx frame_ptr;
- enum machine_mode mode;
- unsigned int regno;
- int offset;
- int total_size;
+emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
+ unsigned int regno, int offset, HOST_WIDE_INT total_size)
{
rtx reg, offset_rtx, insn, mem, addr, int_rtx;
rtx replacea, replaceb;
@@ -10244,10 +11891,7 @@ emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
converting to a valid addressing mode. */
static rtx
-gen_frame_mem_offset (mode, reg, offset)
- enum machine_mode mode;
- rtx reg;
- int offset;
+gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
{
rtx int_rtx, offset_rtx;
@@ -10267,34 +11911,39 @@ gen_frame_mem_offset (mode, reg, offset)
/* Emit function prologue as insns. */
void
-rs6000_emit_prologue ()
+rs6000_emit_prologue (void)
{
rs6000_stack_t *info = rs6000_stack_info ();
- enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
+ enum machine_mode reg_mode = Pmode;
+ int reg_size = TARGET_32BIT ? 4 : 8;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
rtx frame_reg_rtx = sp_reg_rtx;
- rtx cr_save_rtx = NULL;
+ rtx cr_save_rtx = NULL_RTX;
rtx insn;
int saving_FPRs_inline;
int using_store_multiple;
HOST_WIDE_INT sp_offset = 0;
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
reg_mode = V2SImode;
reg_size = 8;
}
using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
- && !TARGET_SPE_ABI
+ && (!TARGET_SPE_ABI
+ || info->spe_64bit_regs_used == 0)
&& info->first_gp_reg_save < 31);
saving_FPRs_inline = (info->first_fp_reg_save == 64
- || FP_SAVE_INLINE (info->first_fp_reg_save));
+ || FP_SAVE_INLINE (info->first_fp_reg_save)
+ || current_function_calls_eh_return
+ || cfun->machine->ra_need_lr);
/* For V.4, update stack before we do any saving and set back pointer. */
- if (info->push_p && DEFAULT_ABI == ABI_V4)
+ if (info->push_p
+ && (DEFAULT_ABI == ABI_V4
+ || current_function_calls_eh_return))
{
if (info->total_size < 32767)
sp_offset = info->total_size;
@@ -10340,7 +11989,8 @@ rs6000_emit_prologue ()
insn = emit_move_insn (mem, savereg);
- altivec_frame_fixup (insn, areg, offset);
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ areg, GEN_INT (offset));
}
}
@@ -10351,7 +12001,8 @@ rs6000_emit_prologue ()
used in this function, and do the corresponding magic in the
epilogue. */
- if (TARGET_ALTIVEC && info->vrsave_mask != 0)
+ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
+ && info->vrsave_mask != 0)
{
rtx reg, mem, vrsave;
int offset;
@@ -10474,7 +12125,7 @@ rs6000_emit_prologue ()
rtx addr, reg, mem;
reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
rtx b;
@@ -10521,6 +12172,23 @@ rs6000_emit_prologue ()
{
unsigned int i, regno;
+ /* In AIX ABI we need to pretend we save r2 here. */
+ if (TARGET_AIX)
+ {
+ rtx addr, reg, mem;
+
+ reg = gen_rtx_REG (reg_mode, 2);
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (sp_offset + 5 * reg_size));
+ mem = gen_rtx_MEM (reg_mode, addr);
+ set_mem_alias_set (mem, rs6000_sr_alias_set);
+
+ insn = emit_move_insn (mem, reg);
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ NULL_RTX, NULL_RTX);
+ PATTERN (insn) = gen_blockage ();
+ }
+
for (i = 0; ; ++i)
{
regno = EH_RETURN_DATA_REGNO (i);
@@ -10568,9 +12236,9 @@ rs6000_emit_prologue ()
insn = emit_move_insn (mem, cr_save_rtx);
/* Now, there's no way that dwarf2out_frame_debug_expr is going
- to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
- OK. All we have to do is specify that _one_ condition code
- register is saved in this stack slot. The thrower's epilogue
+ to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
+ But that's OK. All we have to do is specify that _one_ condition
+ code register is saved in this stack slot. The thrower's epilogue
will then restore all the call-saved registers.
We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
@@ -10579,7 +12247,8 @@ rs6000_emit_prologue ()
/* Update stack and set back pointer unless this is V.4,
for which it was done previously. */
- if (info->push_p && DEFAULT_ABI != ABI_V4)
+ if (info->push_p
+ && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
rs6000_emit_allocate_stack (info->total_size, FALSE);
/* Set frame pointer, if needed. */
@@ -10596,21 +12265,23 @@ rs6000_emit_prologue ()
&& regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
{
/* If emit_load_toc_table will use the link register, we need to save
- it. We use R11 for this purpose because emit_load_toc_table
+ it. We use R12 for this purpose because emit_load_toc_table
can use register 0. This allows us to use a plain 'blr' to return
from the procedure more often. */
- int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
+ int save_LR_around_toc_setup = (TARGET_ELF
+ && DEFAULT_ABI != ABI_AIX
+ && flag_pic
&& ! info->lr_save_p
&& EXIT_BLOCK_PTR->pred != NULL);
if (save_LR_around_toc_setup)
- emit_move_insn (gen_rtx_REG (Pmode, 11),
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
-
- rs6000_emit_load_toc_table (TRUE);
-
- if (save_LR_around_toc_setup)
- emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
- gen_rtx_REG (Pmode, 11));
+ {
+ rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
+ rs6000_maybe_dead (emit_move_insn (frame_ptr_rtx, lr));
+ rs6000_emit_load_toc_table (TRUE);
+ rs6000_maybe_dead (emit_move_insn (lr, frame_ptr_rtx));
+ }
+ else
+ rs6000_emit_load_toc_table (TRUE);
}
#if TARGET_MACHO
@@ -10618,8 +12289,8 @@ rs6000_emit_prologue ()
&& flag_pic && current_function_uses_pic_offset_table)
{
rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
- char *picbase = machopic_function_base_name ();
- rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
+ const char *picbase = machopic_function_base_name ();
+ rtx src = gen_rtx_SYMBOL_REF (Pmode, picbase);
rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
@@ -10633,9 +12304,8 @@ rs6000_emit_prologue ()
/* Write function prologue. */
static void
-rs6000_output_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+rs6000_output_function_prologue (FILE *file,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
rs6000_stack_t *info = rs6000_stack_info ();
@@ -10669,11 +12339,11 @@ rs6000_output_function_prologue (file, size)
/* A NOTE_INSN_DELETED is supposed to be at the start and end of
the "toplevel" insn chain. */
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
rs6000_emit_prologue ();
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
- /* Expand INSN_ADDRESSES so final() doesn't crash. */
+ /* Expand INSN_ADDRESSES so final() doesn't crash. */
{
rtx insn;
unsigned addr = 0;
@@ -10701,8 +12371,7 @@ rs6000_output_function_prologue (file, size)
need special notes to explain where r11 is in relation to the stack. */
void
-rs6000_emit_epilogue (sibcall)
- int sibcall;
+rs6000_emit_epilogue (int sibcall)
{
rs6000_stack_t *info;
int restoring_FPRs_inline;
@@ -10712,19 +12381,21 @@ rs6000_emit_epilogue (sibcall)
int sp_offset = 0;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
rtx frame_reg_rtx = sp_reg_rtx;
- enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
+ enum machine_mode reg_mode = Pmode;
+ int reg_size = TARGET_32BIT ? 4 : 8;
int i;
- if (TARGET_SPE_ABI)
+ info = rs6000_stack_info ();
+
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
reg_mode = V2SImode;
reg_size = 8;
}
- info = rs6000_stack_info ();
using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
- && !TARGET_SPE_ABI
+ && (!TARGET_SPE_ABI
+ || info->spe_64bit_regs_used == 0)
&& info->first_gp_reg_save < 31);
restoring_FPRs_inline = (sibcall
|| current_function_calls_eh_return
@@ -10754,7 +12425,8 @@ rs6000_emit_epilogue (sibcall)
}
else if (info->push_p)
{
- if (DEFAULT_ABI == ABI_V4)
+ if (DEFAULT_ABI == ABI_V4
+ || current_function_calls_eh_return)
sp_offset = info->total_size;
else
{
@@ -10792,7 +12464,8 @@ rs6000_emit_epilogue (sibcall)
}
/* Restore VRSAVE if needed. */
- if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
+ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
+ && info->vrsave_mask != 0)
{
rtx addr, mem, reg;
@@ -10839,6 +12512,17 @@ rs6000_emit_epilogue (sibcall)
{
unsigned int i, regno;
+ if (TARGET_AIX)
+ {
+ rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (sp_offset + 5 * reg_size));
+ rtx mem = gen_rtx_MEM (reg_mode, addr);
+
+ set_mem_alias_set (mem, rs6000_sr_alias_set);
+
+ emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
+ }
+
for (i = 0; ; ++i)
{
rtx mem;
@@ -10894,7 +12578,7 @@ rs6000_emit_epilogue (sibcall)
rtx mem = gen_rtx_MEM (reg_mode, addr);
/* Restore 64-bit quantities for SPE. */
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
rtx b;
@@ -10967,7 +12651,7 @@ rs6000_emit_epilogue (sibcall)
RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
RTVEC_ELT (p, ndx) =
gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
- gen_rtx_UNSPEC (CCmode, r, 20));
+ gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
ndx++;
}
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -10990,7 +12674,8 @@ rs6000_emit_epilogue (sibcall)
(which may not have any obvious dependency on the stack). This
doesn't hurt performance, because there is no scheduling that can
be done after this point. */
- if (DEFAULT_ABI == ABI_V4)
+ if (DEFAULT_ABI == ABI_V4
+ || current_function_calls_eh_return)
{
if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie ();
@@ -11001,7 +12686,7 @@ rs6000_emit_epilogue (sibcall)
}
else if (sp_offset != 0)
{
- emit_insn (Pmode == SImode
+ emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (sp_offset))
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
@@ -11012,7 +12697,7 @@ rs6000_emit_epilogue (sibcall)
if (current_function_calls_eh_return)
{
rtx sa = EH_RETURN_STACKADJ_RTX;
- emit_insn (Pmode == SImode
+ emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
}
@@ -11067,9 +12752,8 @@ rs6000_emit_epilogue (sibcall)
/* Write function epilogue. */
static void
-rs6000_output_function_epilogue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+rs6000_output_function_epilogue (FILE *file,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
rs6000_stack_t *info = rs6000_stack_info ();
@@ -11088,11 +12772,11 @@ rs6000_output_function_epilogue (file, size)
/* A NOTE_INSN_DELETED is supposed to be at the start
and end of the "toplevel" insn chain. */
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
rs6000_emit_epilogue (FALSE);
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
- /* Expand INSN_ADDRESSES so final() doesn't crash. */
+ /* Expand INSN_ADDRESSES so final() doesn't crash. */
{
rtx insn;
unsigned addr = 0;
@@ -11110,7 +12794,8 @@ rs6000_output_function_epilogue (file, size)
}
}
-#if TARGET_OBJECT_FORMAT == OBJECT_MACHO
+#if TARGET_MACHO
+ macho_branch_islands ();
/* Mach-O doesn't support labels at the end of objects, so if
it looks like we might want one, insert a NOP. */
{
@@ -11185,27 +12870,25 @@ rs6000_output_function_epilogue (file, size)
/* Tbtab format type. Use format type 0. */
fputs ("\t.byte 0,", file);
- /* Language type. Unfortunately, there doesn't seem to be any
- official way to get this info, so we use language_string. C
- is 0. C++ is 9. No number defined for Obj-C, so use the
- value for C for now. There is no official value for Java,
- although IBM appears to be using 13. There is no official value
- for Chill, so we've chosen 44 pseudo-randomly. */
- if (! strcmp (language_string, "GNU C")
- || ! strcmp (language_string, "GNU Objective-C"))
+ /* Language type. Unfortunately, there does not seem to be any
+ official way to discover the language being compiled, so we
+ use language_string.
+ C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
+ Java is 13. Objective-C is 14. */
+ if (! strcmp (language_string, "GNU C"))
i = 0;
else if (! strcmp (language_string, "GNU F77"))
i = 1;
- else if (! strcmp (language_string, "GNU Ada"))
- i = 3;
else if (! strcmp (language_string, "GNU Pascal"))
i = 2;
+ else if (! strcmp (language_string, "GNU Ada"))
+ i = 3;
else if (! strcmp (language_string, "GNU C++"))
i = 9;
else if (! strcmp (language_string, "GNU Java"))
i = 13;
- else if (! strcmp (language_string, "GNU CHILL"))
- i = 44;
+ else if (! strcmp (language_string, "GNU Objective-C"))
+ i = 14;
else
abort ();
fprintf (file, "%d,", i);
@@ -11388,163 +13071,103 @@ rs6000_output_function_epilogue (file, size)
not support varargs. */
static void
-rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
- FILE *file;
- tree thunk_fndecl ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
-{
- const char *this_reg =
- reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
- const char *prefix;
- const char *fname;
- const char *r0 = reg_names[0];
- const char *toc = reg_names[2];
- const char *schain = reg_names[11];
- const char *r12 = reg_names[12];
- char buf[512];
- static int labelno = 0;
-
- /* Small constants that can be done by one add instruction. */
- if (delta >= -32768 && delta <= 32767)
- {
- if (! TARGET_NEW_MNEMONICS)
- fprintf (file, "\tcal %s,%d(%s)\n", this_reg, (int) delta, this_reg);
- else
- fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, (int) delta);
- }
+rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
+{
+ rtx this, insn, funexp;
- /* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
- else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
- abort ();
+ reload_completed = 1;
+ epilogue_completed = 1;
+ no_new_pseudos = 1;
- /* Large constants that can be done by one addis instruction. */
- else if ((delta & 0xffff) == 0)
- asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
- (int) (delta >> 16));
+ /* Mark the end of the (empty) prologue. */
+ emit_note (NOTE_INSN_PROLOGUE_END);
- /* 32-bit constants that can be done by an add and addis instruction. */
+ /* Find the "this" pointer. If the function returns a structure,
+ the structure return pointer is in r3. */
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
+ this = gen_rtx_REG (Pmode, 4);
else
- {
- /* Break into two pieces, propagating the sign bit from the low
- word to the upper word. */
- int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
- int delta_high = (delta - delta_low) >> 16;
-
- asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
- delta_high);
+ this = gen_rtx_REG (Pmode, 3);
- if (! TARGET_NEW_MNEMONICS)
- fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
- else
- fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
+ /* Apply the constant offset, if required. */
+ if (delta)
+ {
+ rtx delta_rtx = GEN_INT (delta);
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (this, this, delta_rtx)
+ : gen_adddi3 (this, this, delta_rtx));
}
- /* Get the prefix in front of the names. */
- switch (DEFAULT_ABI)
+ /* Apply the offset from the vtable, if required. */
+ if (vcall_offset)
{
- default:
- abort ();
+ rtx vcall_offset_rtx = GEN_INT (vcall_offset);
+ rtx tmp = gen_rtx_REG (Pmode, 12);
- case ABI_AIX:
- prefix = ".";
- break;
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
+ if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
+ {
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
+ : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
+ }
+ else
+ {
+ rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
- case ABI_V4:
- case ABI_AIX_NODESC:
- case ABI_DARWIN:
- prefix = "";
- break;
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
+ }
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (this, this, tmp)
+ : gen_adddi3 (this, this, tmp));
}
- /* If the function is compiled in this module, jump to it directly.
- Otherwise, load up its address and jump to it. */
-
- fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
-
- if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
- && (! lookup_attribute ("longcall",
- TYPE_ATTRIBUTES (TREE_TYPE (function)))
- || lookup_attribute ("shortcall",
- TYPE_ATTRIBUTES (TREE_TYPE (function)))))
+ /* Generate a tail call to the target function. */
+ if (!TREE_USED (function))
{
- fprintf (file, "\tb %s", prefix);
- assemble_name (file, fname);
- if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
- putc ('\n', file);
+ assemble_external (function);
+ TREE_USED (function) = 1;
}
-
- else
- {
- switch (DEFAULT_ABI)
- {
- default:
- abort ();
-
- case ABI_AIX:
- /* Set up a TOC entry for the function. */
- ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
- toc_section ();
- ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
- labelno++;
-
- if (TARGET_MINIMAL_TOC)
- fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
- else
- {
- fputs ("\t.tc ", file);
- assemble_name (file, fname);
- fputs ("[TC],", file);
- }
- assemble_name (file, fname);
- putc ('\n', file);
- function_section (current_function_decl);
- if (TARGET_MINIMAL_TOC)
- asm_fprintf (file, (TARGET_32BIT)
- ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
- TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
- asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
- assemble_name (file, buf);
- if (TARGET_ELF && TARGET_MINIMAL_TOC)
- fputs ("-(.LCTOC1)", file);
- asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
- asm_fprintf (file,
- (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
- r0, r12);
-
- asm_fprintf (file,
- (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
- toc, r12);
-
- asm_fprintf (file, "\tmtctr %s\n", r0);
- asm_fprintf (file,
- (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
- schain, r12);
-
- asm_fprintf (file, "\tbctr\n");
- break;
-
- case ABI_AIX_NODESC:
- case ABI_V4:
- fprintf (file, "\tb %s", prefix);
- assemble_name (file, fname);
- if (flag_pic) fputs ("@plt", file);
- putc ('\n', file);
- break;
+ funexp = XEXP (DECL_RTL (function), 0);
+ funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
#if TARGET_MACHO
- case ABI_DARWIN:
- fprintf (file, "\tb %s", prefix);
- if (flag_pic && !machopic_name_defined_p (fname))
- assemble_name (file, machopic_stub_name (fname));
- else
- assemble_name (file, fname);
- putc ('\n', file);
- break;
+ if (MACHOPIC_INDIRECT)
+ funexp = machopic_indirect_call_target (funexp);
#endif
- }
- }
+
+ /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
+ generate sibcall RTL explicitly to avoid constraint abort. */
+ insn = emit_call_insn (
+ gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (4,
+ gen_rtx_CALL (VOIDmode,
+ funexp, const0_rtx),
+ gen_rtx_USE (VOIDmode, const0_rtx),
+ gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (SImode,
+ LINK_REGISTER_REGNUM)),
+ gen_rtx_RETURN (VOIDmode))));
+ SIBLING_CALL_P (insn) = 1;
+ 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. Note that use_thunk calls
+ assemble_start_function and assemble_end_function. */
+ insn = get_insns ();
+ insn_locators_initialize ();
+ shorten_branches (insn);
+ final_start_function (insn, file, 1);
+ final (insn, file, 1, 0);
+ final_end_function ();
+
+ reload_completed = 0;
+ epilogue_completed = 0;
+ no_new_pseudos = 0;
}
/* A quick summary of the various types of 'constant-pool tables'
@@ -11574,24 +13197,10 @@ rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
*/
-/* Hash table stuff for keeping track of TOC entries. */
-
-struct toc_hash_struct
-{
- /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
- ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
- rtx key;
- enum machine_mode key_mode;
- int labelno;
-};
-
-static htab_t toc_hash_table;
-
/* Hash functions for the hash table. */
static unsigned
-rs6000_hash_constant (k)
- rtx k;
+rs6000_hash_constant (rtx k)
{
enum rtx_code code = GET_CODE (k);
enum machine_mode mode = GET_MODE (k);
@@ -11654,6 +13263,8 @@ rs6000_hash_constant (k)
>> CHAR_BIT * i);
}
break;
+ case '0':
+ break;
default:
abort ();
}
@@ -11662,8 +13273,7 @@ rs6000_hash_constant (k)
}
static unsigned
-toc_hash_function (hash_entry)
- const void * hash_entry;
+toc_hash_function (const void *hash_entry)
{
const struct toc_hash_struct *thc =
(const struct toc_hash_struct *) hash_entry;
@@ -11673,9 +13283,7 @@ toc_hash_function (hash_entry)
/* Compare H1 and H2 for equivalence. */
static int
-toc_hash_eq (h1, h2)
- const void * h1;
- const void * h2;
+toc_hash_eq (const void *h1, const void *h2)
{
rtx r1 = ((const struct toc_hash_struct *) h1)->key;
rtx r2 = ((const struct toc_hash_struct *) h2)->key;
@@ -11687,39 +13295,6 @@ toc_hash_eq (h1, h2)
return rtx_equal_p (r1, r2);
}
-/* Mark the hash table-entry HASH_ENTRY. */
-
-static int
-toc_hash_mark_entry (hash_slot, unused)
- void ** hash_slot;
- void * unused ATTRIBUTE_UNUSED;
-{
- const struct toc_hash_struct * hash_entry =
- *(const struct toc_hash_struct **) hash_slot;
- rtx r = hash_entry->key;
- ggc_set_mark (hash_entry);
- /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
- if (GET_CODE (r) == LABEL_REF)
- {
- ggc_set_mark (r);
- ggc_set_mark (XEXP (r, 0));
- }
- else
- ggc_mark_rtx (r);
- return 1;
-}
-
-/* Mark all the elements of the TOC hash-table *HT. */
-
-static void
-toc_hash_mark_table (vht)
- void *vht;
-{
- htab_t *ht = vht;
-
- htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
-}
-
/* These are the names given by the C++ front-end to vtables, and
vtable-like objects. Ideally, this logic should not be here;
instead, there should be some programmatic way of inquiring as
@@ -11729,12 +13304,11 @@ toc_hash_mark_table (vht)
(strncmp ("_vt.", name, strlen("_vt.")) == 0 \
|| strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
|| strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
+ || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
|| strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
void
-rs6000_output_symbol_ref (file, x)
- FILE *file;
- rtx x;
+rs6000_output_symbol_ref (FILE *file, rtx x)
{
/* Currently C++ toc references to vtables can be emitted before it
is decided whether the vtable is public or private. If this is
@@ -11756,11 +13330,7 @@ rs6000_output_symbol_ref (file, x)
written. */
void
-output_toc (file, x, labelno, mode)
- FILE *file;
- rtx x;
- int labelno;
- enum machine_mode mode;
+output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
{
char buf[256];
const char *name = buf;
@@ -11773,12 +13343,19 @@ output_toc (file, x, labelno, mode)
/* When the linker won't eliminate them, don't output duplicate
TOC entries (this happens on AIX if there is any kind of TOC,
- and on SVR4 under -fPIC or -mrelocatable). */
- if (TARGET_TOC)
+ and on SVR4 under -fPIC or -mrelocatable). Don't do this for
+ CODE_LABELs. */
+ if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
{
struct toc_hash_struct *h;
void * * found;
+ /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
+ time because GGC is not initialized at that point. */
+ if (toc_hash_table == NULL)
+ toc_hash_table = htab_create_ggc (1021, toc_hash_function,
+ toc_hash_eq, NULL);
+
h = ggc_alloc (sizeof (*h));
h->key = x;
h->key_mode = mode;
@@ -11809,7 +13386,7 @@ output_toc (file, x, labelno, mode)
ASM_OUTPUT_ALIGN (file, 3);
}
- ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
+ (*targetm.asm_out.internal_label) (file, "LC", labelno);
/* Handle FP constants specially. Note that if we have a minimal
TOC, things we put here aren't actually in the TOC, so we can allow
@@ -12053,10 +13630,7 @@ output_toc (file, x, labelno, mode)
so we must artificially break them up early. */
void
-output_ascii (file, p, n)
- FILE *file;
- const char *p;
- int n;
+output_ascii (FILE *file, const char *p, int n)
{
char c;
int i, count_string;
@@ -12127,10 +13701,8 @@ output_ascii (file, p, n)
the name. */
void
-rs6000_gen_section_name (buf, filename, section_desc)
- char **buf;
- const char *filename;
- const char *section_desc;
+rs6000_gen_section_name (char **buf, const char *filename,
+ const char *section_desc)
{
const char *q, *after_last_slash, *last_period = 0;
char *p;
@@ -12157,6 +13729,7 @@ rs6000_gen_section_name (buf, filename, section_desc)
{
strcpy (p, section_desc);
p += strlen (section_desc);
+ break;
}
else if (ISALNUM (*q))
@@ -12172,25 +13745,31 @@ rs6000_gen_section_name (buf, filename, section_desc)
/* Emit profile function. */
void
-output_profile_hook (labelno)
- int labelno ATTRIBUTE_UNUSED;
+output_profile_hook (int labelno ATTRIBUTE_UNUSED)
{
+ if (TARGET_PROFILE_KERNEL)
+ return;
+
if (DEFAULT_ABI == ABI_AIX)
{
-#ifdef NO_PROFILE_COUNTERS
- emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
-#else
- char buf[30];
- const char *label_name;
- rtx fun;
+#ifndef NO_PROFILE_COUNTERS
+# define NO_PROFILE_COUNTERS 0
+#endif
+ if (NO_PROFILE_COUNTERS)
+ emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
+ else
+ {
+ char buf[30];
+ const char *label_name;
+ rtx fun;
- ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
- label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
- fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
+ label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
+ fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
- emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
- fun, Pmode);
-#endif
+ emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
+ fun, Pmode);
+ }
}
else if (DEFAULT_ABI == ABI_DARWIN)
{
@@ -12203,7 +13782,7 @@ output_profile_hook (labelno)
#if TARGET_MACHO
/* For PIC code, set up a stub and collect the caller's address
from r0, which is where the prologue puts it. */
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
{
mcount_name = machopic_stub_name (mcount_name);
if (current_function_uses_pic_offset_table)
@@ -12219,14 +13798,11 @@ output_profile_hook (labelno)
/* Write function profiler code. */
void
-output_function_profiler (file, labelno)
- FILE *file;
- int labelno;
+output_function_profiler (FILE *file, int labelno)
{
char buf[100];
int save_lr = 8;
- ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
switch (DEFAULT_ABI)
{
default:
@@ -12234,14 +13810,12 @@ output_function_profiler (file, labelno)
case ABI_V4:
save_lr = 4;
- /* Fall through. */
-
- case ABI_AIX_NODESC:
if (!TARGET_32BIT)
{
warning ("no profiling of 64-bit code for this ABI");
return;
}
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
fprintf (file, "\tmflr %s\n", reg_names[0]);
if (flag_pic == 1)
{
@@ -12279,37 +13853,80 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "@l(%s)\n", reg_names[12]);
}
- if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
- {
- asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
- reg_names[STATIC_CHAIN_REGNUM],
- 12, reg_names[1]);
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
- asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
- reg_names[STATIC_CHAIN_REGNUM],
- 12, reg_names[1]);
- }
- else
- /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
+ fprintf (file, "\tbl %s%s\n",
+ RS6000_MCOUNT, flag_pic ? "@plt" : "");
+
break;
case ABI_AIX:
case ABI_DARWIN:
- /* Don't do anything, done in output_profile_hook (). */
+ if (!TARGET_PROFILE_KERNEL)
+ {
+ /* Don't do anything, done in output_profile_hook (). */
+ }
+ else
+ {
+ if (TARGET_32BIT)
+ abort ();
+
+ asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
+ asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
+
+ if (current_function_needs_context)
+ {
+ asm_fprintf (file, "\tstd %s,24(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ asm_fprintf (file, "\tld %s,24(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
+ }
+ else
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ }
break;
}
}
+
+static int
+rs6000_use_dfa_pipeline_interface (void)
+{
+ return 1;
+}
+
+/* Power4 load update and store update instructions are cracked into a
+ load or store and an integer insn which are executed in the same cycle.
+ Branches have their own dispatch slot which does not count against the
+ GCC issue rate, but it changes the program flow so there are no other
+ instructions to issue in this cycle. */
+
+static int
+rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
+ int verbose ATTRIBUTE_UNUSED,
+ rtx insn, int more)
+{
+ if (GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return more;
+
+ if (rs6000_sched_groups)
+ {
+ if (is_microcoded_insn (insn))
+ return 0;
+ else if (is_cracked_insn (insn))
+ return more > 2 ? more - 2 : 0;
+ }
+
+ return more - 1;
+}
+
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
static int
-rs6000_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn ATTRIBUTE_UNUSED;
- int cost;
+rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn ATTRIBUTE_UNUSED,
+ int cost)
{
if (! recog_memoized (insn))
return 0;
@@ -12341,13 +13958,18 @@ rs6000_adjust_cost (insn, link, dep_insn, cost)
|| rs6000_cpu_attr == CPU_PPC750
|| rs6000_cpu_attr == CPU_PPC7400
|| rs6000_cpu_attr == CPU_PPC7450
- || rs6000_cpu_attr == CPU_POWER4)
+ || rs6000_cpu_attr == CPU_POWER4
+ || rs6000_cpu_attr == CPU_POWER5)
&& recog_memoized (dep_insn)
&& (INSN_CODE (dep_insn) >= 0)
- && (get_attr_type (dep_insn) == TYPE_COMPARE
+ && (get_attr_type (dep_insn) == TYPE_CMP
+ || get_attr_type (dep_insn) == TYPE_COMPARE
|| get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
+ || get_attr_type (dep_insn) == TYPE_IMUL_COMPARE
+ || get_attr_type (dep_insn) == TYPE_LMUL_COMPARE
|| get_attr_type (dep_insn) == TYPE_FPCOMPARE
- || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
+ || get_attr_type (dep_insn) == TYPE_CR_LOGICAL
+ || get_attr_type (dep_insn) == TYPE_DELAYED_CR))
return cost + 2;
default:
break;
@@ -12358,16 +13980,133 @@ rs6000_adjust_cost (insn, link, dep_insn, cost)
return cost;
}
+/* The function returns a true if INSN is microcoded.
+ Return false otherwise. */
+
+static bool
+is_microcoded_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn)
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return false;
+
+ if (rs6000_sched_groups)
+ {
+ enum attr_type type = get_attr_type (insn);
+ if (type == TYPE_LOAD_EXT_U
+ || type == TYPE_LOAD_EXT_UX
+ || type == TYPE_LOAD_UX
+ || type == TYPE_STORE_UX
+ || type == TYPE_MFCR)
+ return true;
+ }
+
+ return false;
+}
+
+/* The function returns a nonzero value if INSN can be scheduled only
+ as the first insn in a dispatch group ("dispatch-slot restricted").
+ In this case, the returned value indicates how many dispatch slots
+ the insn occupies (at the beginning of the group).
+ Return 0 otherwise. */
+
+static int
+is_dispatch_slot_restricted (rtx insn)
+{
+ enum attr_type type;
+
+ if (!rs6000_sched_groups)
+ return 0;
+
+ if (!insn
+ || insn == NULL_RTX
+ || GET_CODE (insn) == NOTE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return 0;
+
+ type = get_attr_type (insn);
+
+ switch (type)
+ {
+ case TYPE_MFCR:
+ case TYPE_MFCRF:
+ case TYPE_MTCR:
+ case TYPE_DELAYED_CR:
+ case TYPE_CR_LOGICAL:
+ case TYPE_MTJMPR:
+ case TYPE_MFJMPR:
+ return 1;
+ case TYPE_IDIV:
+ case TYPE_LDIV:
+ return 2;
+ default:
+ if (rs6000_cpu == PROCESSOR_POWER5
+ && is_cracked_insn (insn))
+ return 2;
+ return 0;
+ }
+}
+
+/* The function returns true if INSN is cracked into 2 instructions
+ by the processor (and therefore occupies 2 issue slots). */
+
+static bool
+is_cracked_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn)
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return false;
+
+ if (rs6000_sched_groups)
+ {
+ enum attr_type type = get_attr_type (insn);
+ if (type == TYPE_LOAD_U || type == TYPE_STORE_U
+ || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
+ || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
+ || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
+ || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
+ || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
+ || type == TYPE_IDIV || type == TYPE_LDIV
+ || type == TYPE_INSERT_WORD)
+ return true;
+ }
+
+ return false;
+}
+
+/* The function returns true if INSN can be issued only from
+ the branch slot. */
+
+static bool
+is_branch_slot_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn)
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return false;
+
+ if (rs6000_sched_groups)
+ {
+ enum attr_type type = get_attr_type (insn);
+ if (type == TYPE_BRANCH || type == TYPE_JMPREG)
+ return true;
+ return false;
+ }
+
+ return false;
+}
+
/* A C statement (sans semicolon) to update the integer scheduling
- priority INSN_PRIORITY (INSN). Reduce the priority to execute the
- INSN earlier, increase the priority to execute INSN later. Do not
+ priority INSN_PRIORITY (INSN). Increase the priority to execute the
+ INSN earlier, reduce the priority to execute INSN later. Do not
define this macro if you do not need to adjust the scheduling
priorities of insns. */
static int
-rs6000_adjust_priority (insn, priority)
- rtx insn ATTRIBUTE_UNUSED;
- int priority;
+rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
{
/* On machines (like the 750) which have asymmetric integer units,
where one integer unit can do multiply and divides and the other
@@ -12399,41 +14138,637 @@ rs6000_adjust_priority (insn, priority)
}
#endif
+ if (is_dispatch_slot_restricted (insn)
+ && reload_completed
+ && current_sched_info->sched_max_insns_priority
+ && rs6000_sched_restricted_insns_priority)
+ {
+
+ /* Prioritize insns that can be dispatched only in the first dispatch slot. */
+ if (rs6000_sched_restricted_insns_priority == 1)
+ /* Attach highest priority to insn. This means that in
+ haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
+ precede 'priority' (critical path) considerations. */
+ return current_sched_info->sched_max_insns_priority;
+ else if (rs6000_sched_restricted_insns_priority == 2)
+ /* Increase priority of insn by a minimal amount. This means that in
+ haifa-sched.c:ready_sort(), only 'priority' (critical path) considerations
+ precede dispatch-slot restriction considerations. */
+ return (priority + 1);
+ }
+
return priority;
}
/* Return how many instructions the machine can issue per cycle. */
static int
-rs6000_issue_rate ()
+rs6000_issue_rate (void)
{
+ /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
+ if (!reload_completed)
+ return 1;
+
switch (rs6000_cpu_attr) {
case CPU_RIOS1: /* ? */
case CPU_RS64A:
case CPU_PPC601: /* ? */
case CPU_PPC7450:
return 3;
+ case CPU_PPC440:
case CPU_PPC603:
case CPU_PPC750:
case CPU_PPC7400:
+ case CPU_PPC8540:
return 2;
case CPU_RIOS2:
case CPU_PPC604:
case CPU_PPC604E:
case CPU_PPC620:
case CPU_PPC630:
- case CPU_POWER4:
return 4;
+ case CPU_POWER4:
+ case CPU_POWER5:
+ return 5;
default:
return 1;
}
}
+/* Return how many instructions to look ahead for better insn
+ scheduling. */
+
+static int
+rs6000_use_sched_lookahead (void)
+{
+ if (rs6000_cpu_attr == CPU_PPC8540)
+ return 4;
+ return 0;
+}
+
+/* Determine is PAT refers to memory. */
+
+static bool
+is_mem_ref (rtx pat)
+{
+ const char * fmt;
+ int i, j;
+ bool ret = false;
+
+ if (GET_CODE (pat) == MEM)
+ return true;
+
+ /* Recursively process the pattern. */
+ fmt = GET_RTX_FORMAT (GET_CODE (pat));
+
+ for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
+ {
+ if (fmt[i] == 'e')
+ ret |= is_mem_ref (XEXP (pat, i));
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ ret |= is_mem_ref (XVECEXP (pat, i, j));
+ }
+
+ return ret;
+}
+
+/* Determine if PAT is a PATTERN of a load insn. */
+
+static bool
+is_load_insn1 (rtx pat)
+{
+ if (!pat || pat == NULL_RTX)
+ return false;
+
+ if (GET_CODE (pat) == SET)
+ return is_mem_ref (SET_SRC (pat));
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ if (is_load_insn1 (XVECEXP (pat, 0, i)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Determine if INSN loads from memory. */
+
+static bool
+is_load_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn))
+ return false;
+
+ if (GET_CODE (insn) == CALL_INSN)
+ return false;
+
+ return is_load_insn1 (PATTERN (insn));
+}
+
+/* Determine if PAT is a PATTERN of a store insn. */
+
+static bool
+is_store_insn1 (rtx pat)
+{
+ if (!pat || pat == NULL_RTX)
+ return false;
+
+ if (GET_CODE (pat) == SET)
+ return is_mem_ref (SET_DEST (pat));
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ if (is_store_insn1 (XVECEXP (pat, 0, i)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Determine if INSN stores to memory. */
+
+static bool
+is_store_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn))
+ return false;
+
+ return is_store_insn1 (PATTERN (insn));
+}
+
+/* Returns whether the dependence between INSN and NEXT is considered
+ costly by the given target. */
+
+static bool
+rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost, int distance)
+{
+ /* If the flag is not enbled - no dependence is considered costly;
+ allow all dependent insns in the same group.
+ This is the most aggressive option. */
+ if (rs6000_sched_costly_dep == no_dep_costly)
+ return false;
+
+ /* If the flag is set to 1 - a dependence is always considered costly;
+ do not allow dependent instructions in the same group.
+ This is the most conservative option. */
+ if (rs6000_sched_costly_dep == all_deps_costly)
+ return true;
+
+ if (rs6000_sched_costly_dep == store_to_load_dep_costly
+ && is_load_insn (next)
+ && is_store_insn (insn))
+ /* Prevent load after store in the same group. */
+ return true;
+
+ if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
+ && is_load_insn (next)
+ && is_store_insn (insn)
+ && (!link || (int) REG_NOTE_KIND (link) == 0))
+ /* Prevent load after store in the same group if it is a true dependence. */
+ return true;
+
+ /* The flag is set to X; dependences with latency >= X are considered costly,
+ and will not be scheduled in the same group. */
+ if (rs6000_sched_costly_dep <= max_dep_latency
+ && ((cost - distance) >= (int)rs6000_sched_costly_dep))
+ return true;
+
+ return false;
+}
+
+/* Return the next insn after INSN that is found before TAIL is reached,
+ skipping any "non-active" insns - insns that will not actually occupy
+ an issue slot. Return NULL_RTX if such an insn is not found. */
+
+static rtx
+get_next_active_insn (rtx insn, rtx tail)
+{
+ rtx next_insn;
+
+ if (!insn || insn == tail)
+ return NULL_RTX;
+
+ next_insn = NEXT_INSN (insn);
+
+ while (next_insn
+ && next_insn != tail
+ && (GET_CODE(next_insn) == NOTE
+ || GET_CODE (PATTERN (next_insn)) == USE
+ || GET_CODE (PATTERN (next_insn)) == CLOBBER))
+ {
+ next_insn = NEXT_INSN (next_insn);
+ }
+
+ if (!next_insn || next_insn == tail)
+ return NULL_RTX;
+
+ return next_insn;
+}
+
+/* Return whether the presence of INSN causes a dispatch group termination
+ of group WHICH_GROUP.
+
+ If WHICH_GROUP == current_group, this function will return true if INSN
+ causes the termination of the current group (i.e, the dispatch group to
+ which INSN belongs). This means that INSN will be the last insn in the
+ group it belongs to.
+
+ If WHICH_GROUP == previous_group, this function will return true if INSN
+ causes the termination of the previous group (i.e, the dispatch group that
+ precedes the group to which INSN belongs). This means that INSN will be
+ the first insn in the group it belongs to). */
+
+static bool
+insn_terminates_group_p (rtx insn, enum group_termination which_group)
+{
+ enum attr_type type;
+
+ if (! insn)
+ return false;
+
+ type = get_attr_type (insn);
+
+ if (is_microcoded_insn (insn))
+ return true;
+
+ if (which_group == current_group)
+ {
+ if (is_branch_slot_insn (insn))
+ return true;
+ return false;
+ }
+ else if (which_group == previous_group)
+ {
+ if (is_dispatch_slot_restricted (insn))
+ return true;
+ return false;
+ }
+
+ return false;
+}
+
+/* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
+ dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
+
+static bool
+is_costly_group (rtx *group_insns, rtx next_insn)
+{
+ int i;
+ rtx link;
+ int cost;
+ int issue_rate = rs6000_issue_rate ();
+
+ for (i = 0; i < issue_rate; i++)
+ {
+ rtx insn = group_insns[i];
+ if (!insn)
+ continue;
+ for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
+ {
+ rtx next = XEXP (link, 0);
+ if (next == next_insn)
+ {
+ cost = insn_cost (insn, link, next_insn);
+ if (rs6000_is_costly_dependence (insn, next_insn, link, cost, 0))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/* Utility of the function redefine_groups.
+ Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
+ in the same dispatch group. If so, insert nops before NEXT_INSN, in order
+ to keep it "far" (in a separate group) from GROUP_INSNS, following
+ one of the following schemes, depending on the value of the flag
+ -minsert_sched_nops = X:
+ (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
+ in order to force NEXT_INSN into a separate group.
+ (2) X < sched_finish_regroup_exact: insert exactly X nops.
+ GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
+ insertion (has a group just ended, how many vacant issue slots remain in the
+ last group, and how many dispatch groups were encountered so far). */
+
+static int
+force_new_group (int sched_verbose, FILE *dump, rtx *group_insns, rtx next_insn,
+ bool *group_end, int can_issue_more, int *group_count)
+{
+ rtx nop;
+ bool force;
+ int issue_rate = rs6000_issue_rate ();
+ bool end = *group_end;
+ int i;
+
+ if (next_insn == NULL_RTX)
+ return can_issue_more;
+
+ if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
+ return can_issue_more;
+
+ force = is_costly_group (group_insns, next_insn);
+ if (!force)
+ return can_issue_more;
+
+ if (sched_verbose > 6)
+ fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
+ *group_count ,can_issue_more);
+
+ if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
+ {
+ if (*group_end)
+ can_issue_more = 0;
+
+ /* Since only a branch can be issued in the last issue_slot, it is
+ sufficient to insert 'can_issue_more - 1' nops if next_insn is not
+ a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
+ in this case the last nop will start a new group and the branch will be
+ forced to the new group. */
+ if (can_issue_more && !is_branch_slot_insn (next_insn))
+ can_issue_more--;
+
+ while (can_issue_more > 0)
+ {
+ nop = gen_nop();
+ emit_insn_before (nop, next_insn);
+ can_issue_more--;
+ }
+
+ *group_end = true;
+ return 0;
+ }
+
+ if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
+ {
+ int n_nops = rs6000_sched_insert_nops;
+
+ /* Nops can't be issued from the branch slot, so the effective
+ issue_rate for nops is 'issue_rate - 1'. */
+ if (can_issue_more == 0)
+ can_issue_more = issue_rate;
+ can_issue_more--;
+ if (can_issue_more == 0)
+ {
+ can_issue_more = issue_rate - 1;
+ (*group_count)++;
+ end = true;
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ }
+
+ while (n_nops > 0)
+ {
+ nop = gen_nop ();
+ emit_insn_before (nop, next_insn);
+ if (can_issue_more == issue_rate - 1) /* new group begins */
+ end = false;
+ can_issue_more--;
+ if (can_issue_more == 0)
+ {
+ can_issue_more = issue_rate - 1;
+ (*group_count)++;
+ end = true;
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ }
+ n_nops--;
+ }
+
+ /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
+ can_issue_more++;
+
+ *group_end = /* Is next_insn going to start a new group? */
+ (end
+ || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
+ || (can_issue_more <= 2 && is_cracked_insn (next_insn))
+ || (can_issue_more < issue_rate &&
+ insn_terminates_group_p (next_insn, previous_group)));
+ if (*group_end && end)
+ (*group_count)--;
+
+ if (sched_verbose > 6)
+ fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
+ *group_count, can_issue_more);
+ return can_issue_more;
+ }
+
+ return can_issue_more;
+}
+
+/* This function tries to synch the dispatch groups that the compiler "sees"
+ with the dispatch groups that the processor dispatcher is expected to
+ form in practice. It tries to achieve this synchronization by forcing the
+ estimated processor grouping on the compiler (as opposed to the function
+ 'pad_goups' which tries to force the scheduler's grouping on the processor).
+
+ The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
+ examines the (estimated) dispatch groups that will be formed by the processor
+ dispatcher. It marks these group boundaries to reflect the estimated
+ processor grouping, overriding the grouping that the scheduler had marked.
+ Depending on the value of the flag '-minsert-sched-nops' this function can
+ force certain insns into separate groups or force a certain distance between
+ them by inserting nops, for example, if there exists a "costly dependence"
+ between the insns.
+
+ The function estimates the group boundaries that the processor will form as
+ folllows: It keeps track of how many vacant issue slots are available after
+ each insn. A subsequent insn will start a new group if one of the following
+ 4 cases applies:
+ - no more vacant issue slots remain in the current dispatch group.
+ - only the last issue slot, which is the branch slot, is vacant, but the next
+ insn is not a branch.
+ - only the last 2 or less issue slots, including the branch slot, are vacant,
+ which means that a cracked insn (which occupies two issue slots) can't be
+ issued in this group.
+ - less than 'issue_rate' slots are vacant, and the next insn always needs to
+ start a new group. */
+
+static int
+redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
+{
+ rtx insn, next_insn;
+ int issue_rate;
+ int can_issue_more;
+ int slot, i;
+ bool group_end;
+ int group_count = 0;
+ rtx *group_insns;
+
+ /* Initialize. */
+ issue_rate = rs6000_issue_rate ();
+ group_insns = alloca (issue_rate * sizeof (rtx));
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ can_issue_more = issue_rate;
+ slot = 0;
+ insn = get_next_active_insn (prev_head_insn, tail);
+ group_end = false;
+
+ while (insn != NULL_RTX)
+ {
+ slot = (issue_rate - can_issue_more);
+ group_insns[slot] = insn;
+ can_issue_more =
+ rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
+ if (insn_terminates_group_p (insn, current_group))
+ can_issue_more = 0;
+
+ next_insn = get_next_active_insn (insn, tail);
+ if (next_insn == NULL_RTX)
+ return group_count + 1;
+
+ group_end = /* Is next_insn going to start a new group? */
+ (can_issue_more == 0
+ || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
+ || (can_issue_more <= 2 && is_cracked_insn (next_insn))
+ || (can_issue_more < issue_rate &&
+ insn_terminates_group_p (next_insn, previous_group)));
+
+ can_issue_more = force_new_group (sched_verbose, dump, group_insns,
+ next_insn, &group_end, can_issue_more, &group_count);
+
+ if (group_end)
+ {
+ group_count++;
+ can_issue_more = 0;
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ }
+
+ if (GET_MODE (next_insn) == TImode && can_issue_more)
+ PUT_MODE(next_insn, VOIDmode);
+ else if (!can_issue_more && GET_MODE (next_insn) != TImode)
+ PUT_MODE (next_insn, TImode);
+
+ insn = next_insn;
+ if (can_issue_more == 0)
+ can_issue_more = issue_rate;
+ } /* while */
+
+ return group_count;
+}
+
+/* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
+ dispatch group boundaries that the scheduler had marked. Pad with nops
+ any dispatch groups which have vacant issue slots, in order to force the
+ scheduler's grouping on the processor dispatcher. The function
+ returns the number of dispatch groups found. */
+
+static int
+pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
+{
+ rtx insn, next_insn;
+ rtx nop;
+ int issue_rate;
+ int can_issue_more;
+ int group_end;
+ int group_count = 0;
+
+ /* Initialize issue_rate. */
+ issue_rate = rs6000_issue_rate ();
+ can_issue_more = issue_rate;
+
+ insn = get_next_active_insn (prev_head_insn, tail);
+ next_insn = get_next_active_insn (insn, tail);
+
+ while (insn != NULL_RTX)
+ {
+ can_issue_more =
+ rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
+
+ group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
+
+ if (next_insn == NULL_RTX)
+ break;
+
+ if (group_end)
+ {
+ /* If the scheduler had marked group termination at this location
+ (between insn and next_indn), and neither insn nor next_insn will
+ force group termination, pad the group with nops to force group
+ termination. */
+ if (can_issue_more
+ && (rs6000_sched_insert_nops == sched_finish_pad_groups)
+ && !insn_terminates_group_p (insn, current_group)
+ && !insn_terminates_group_p (next_insn, previous_group))
+ {
+ if (!is_branch_slot_insn(next_insn))
+ can_issue_more--;
+
+ while (can_issue_more)
+ {
+ nop = gen_nop ();
+ emit_insn_before (nop, next_insn);
+ can_issue_more--;
+ }
+ }
+
+ can_issue_more = issue_rate;
+ group_count++;
+ }
+
+ insn = next_insn;
+ next_insn = get_next_active_insn (insn, tail);
+ }
+
+ return group_count;
+}
+
+/* The following function is called at the end of scheduling BB.
+ After reload, it inserts nops at insn group bundling. */
+
+static void
+rs6000_sched_finish (FILE *dump, int sched_verbose)
+{
+ int n_groups;
+
+ if (sched_verbose)
+ fprintf (dump, "=== Finishing schedule.\n");
+
+ if (reload_completed && rs6000_sched_groups)
+ {
+ if (rs6000_sched_insert_nops == sched_finish_none)
+ return;
+
+ if (rs6000_sched_insert_nops == sched_finish_pad_groups)
+ n_groups = pad_groups (dump, sched_verbose,
+ current_sched_info->prev_head,
+ current_sched_info->next_tail);
+ else
+ n_groups = redefine_groups (dump, sched_verbose,
+ current_sched_info->prev_head,
+ current_sched_info->next_tail);
+
+ if (sched_verbose >= 6)
+ {
+ fprintf (dump, "ngroups = %d\n", n_groups);
+ print_rtl (dump, current_sched_info->prev_head);
+ fprintf (dump, "Done finish_sched\n");
+ }
+ }
+}
/* Length in units of the trampoline for entering a nested function. */
int
-rs6000_trampoline_size ()
+rs6000_trampoline_size (void)
{
int ret = 0;
@@ -12448,7 +14783,6 @@ rs6000_trampoline_size ()
case ABI_DARWIN:
case ABI_V4:
- case ABI_AIX_NODESC:
ret = (TARGET_32BIT) ? 40 : 48;
break;
}
@@ -12461,10 +14795,7 @@ rs6000_trampoline_size ()
CXT is an RTX for the static chain value for the function. */
void
-rs6000_initialize_trampoline (addr, fnaddr, cxt)
- rtx addr;
- rtx fnaddr;
- rtx cxt;
+rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
{
enum machine_mode pmode = Pmode;
int regsize = (TARGET_32BIT) ? 4 : 8;
@@ -12496,7 +14827,6 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt)
/* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
case ABI_DARWIN:
case ABI_V4:
- case ABI_AIX_NODESC:
emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
FALSE, VOIDmode, 4,
addr, pmode,
@@ -12524,12 +14854,10 @@ const struct attribute_spec rs6000_attribute_table[] =
struct attribute_spec.handler. */
static tree
-rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+rs6000_handle_longcall_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_TYPE
&& TREE_CODE (*node) != FIELD_DECL
@@ -12546,8 +14874,7 @@ rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
/* Set longcall attributes on all functions declared when
rs6000_default_long_calls is true. */
static void
-rs6000_set_default_type_attributes (type)
- tree type;
+rs6000_set_default_type_attributes (tree type)
{
if (rs6000_default_long_calls
&& (TREE_CODE (type) == FUNCTION_TYPE
@@ -12561,8 +14888,7 @@ rs6000_set_default_type_attributes (type)
longcall attribute. */
struct rtx_def *
-rs6000_longcall_ref (call_ref)
- rtx call_ref;
+rs6000_longcall_ref (rtx call_ref)
{
const char *call_name;
tree node;
@@ -12583,7 +14909,6 @@ rs6000_longcall_ref (call_ref)
return force_reg (Pmode, call_ref);
}
-
#ifdef USING_ELFOS_H
@@ -12597,10 +14922,8 @@ rs6000_longcall_ref (call_ref)
data section. */
static void
-rs6000_elf_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
toc_section ();
@@ -12614,11 +14937,13 @@ rs6000_elf_select_rtx_section (mode, x, align)
the initial value of DECL requires link-time relocations. */
static void
-rs6000_elf_select_section (decl, reloc, align)
- tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align;
+rs6000_elf_select_section (tree decl, int reloc,
+ unsigned HOST_WIDE_INT align)
{
+ /* Pretend that we're always building for a shared library when
+ ABI_AIX, because otherwise we end up with dynamic relocations
+ in read-only sections. This happens for function pointers,
+ references to vtables in typeinfo, and probably other cases. */
default_elf_select_section_1 (decl, reloc, align,
flag_pic || DEFAULT_ABI == ABI_AIX);
}
@@ -12632,110 +14957,43 @@ rs6000_elf_select_section (decl, reloc, align)
initialized data and functions. */
static void
-rs6000_elf_unique_section (decl, reloc)
- tree decl;
- int reloc;
+rs6000_elf_unique_section (tree decl, int reloc)
{
+ /* As above, pretend that we're always building for a shared library
+ when ABI_AIX, to avoid dynamic relocations in read-only sections. */
default_unique_section_1 (decl, reloc,
flag_pic || DEFAULT_ABI == ABI_AIX);
}
-
-/* If we are referencing a function that is static or is known to be
- in this file, make the SYMBOL_REF special. We can use this to indicate
- that we can branch to this function without emitting a no-op after the
- call. For real AIX calling sequences, we also replace the
- function name with the real name (1 or 2 leading .'s), rather than
- the function descriptor name. This saves a lot of overriding code
- to read the prefixes. */
+/* For a SYMBOL_REF, set generic flags and then perform some
+ target-specific processing.
+
+ When the AIX ABI is requested on a non-AIX system, replace the
+ function name with the real name (with a leading .) rather than the
+ function descriptor name. This saves a lot of overriding code to
+ read the prefixes. */
static void
-rs6000_elf_encode_section_info (decl, first)
- tree decl;
- int first;
+rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
{
- if (!first)
- return;
+ default_encode_section_info (decl, rtl, first);
- if (TREE_CODE (decl) == FUNCTION_DECL)
+ if (first
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && !TARGET_AIX
+ && DEFAULT_ABI == ABI_AIX)
{
- rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- if ((*targetm.binds_local_p) (decl))
- SYMBOL_REF_FLAG (sym_ref) = 1;
-
- if (DEFAULT_ABI == ABI_AIX)
- {
- size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
- size_t len2 = strlen (XSTR (sym_ref, 0));
- char *str = alloca (len1 + len2 + 1);
- str[0] = '.';
- str[1] = '.';
- memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
-
- XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
- }
+ rtx sym_ref = XEXP (rtl, 0);
+ size_t len = strlen (XSTR (sym_ref, 0));
+ char *str = alloca (len + 2);
+ str[0] = '.';
+ memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
+ XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
}
- else if (rs6000_sdata != SDATA_NONE
- && DEFAULT_ABI == ABI_V4
- && TREE_CODE (decl) == VAR_DECL)
- {
- rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- int size = int_size_in_bytes (TREE_TYPE (decl));
- tree section_name = DECL_SECTION_NAME (decl);
- const char *name = (char *)0;
- int len = 0;
-
- if ((*targetm.binds_local_p) (decl))
- SYMBOL_REF_FLAG (sym_ref) = 1;
-
- if (section_name)
- {
- if (TREE_CODE (section_name) == STRING_CST)
- {
- name = TREE_STRING_POINTER (section_name);
- len = TREE_STRING_LENGTH (section_name);
- }
- else
- abort ();
- }
-
- if ((size > 0 && size <= g_switch_value)
- || (name
- && ((len == sizeof (".sdata") - 1
- && strcmp (name, ".sdata") == 0)
- || (len == sizeof (".sdata2") - 1
- && strcmp (name, ".sdata2") == 0)
- || (len == sizeof (".sbss") - 1
- && strcmp (name, ".sbss") == 0)
- || (len == sizeof (".sbss2") - 1
- && strcmp (name, ".sbss2") == 0)
- || (len == sizeof (".PPC.EMB.sdata0") - 1
- && strcmp (name, ".PPC.EMB.sdata0") == 0)
- || (len == sizeof (".PPC.EMB.sbss0") - 1
- && strcmp (name, ".PPC.EMB.sbss0") == 0))))
- {
- size_t len = strlen (XSTR (sym_ref, 0));
- char *str = alloca (len + 2);
-
- str[0] = '@';
- memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
- XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
- }
- }
-}
-
-static const char *
-rs6000_elf_strip_name_encoding (str)
- const char *str;
-{
- while (*str == '*' || *str == '@')
- str++;
- return str;
}
static bool
-rs6000_elf_in_small_data_p (decl)
- tree decl;
+rs6000_elf_in_small_data_p (tree decl)
{
if (rs6000_sdata == SDATA_NONE)
return false;
@@ -12745,7 +15003,10 @@ rs6000_elf_in_small_data_p (decl)
const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
if (strcmp (section, ".sdata") == 0
|| strcmp (section, ".sdata2") == 0
- || strcmp (section, ".sbss") == 0)
+ || strcmp (section, ".sbss") == 0
+ || strcmp (section, ".sbss2") == 0
+ || strcmp (section, ".PPC.EMB.sdata0") == 0
+ || strcmp (section, ".PPC.EMB.sbss0") == 0)
return true;
}
else
@@ -12753,7 +15014,9 @@ rs6000_elf_in_small_data_p (decl)
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
if (size > 0
- && size <= g_switch_value
+ && (unsigned HOST_WIDE_INT) size <= g_switch_value
+ /* If it's not public, and we're not going to reference it there,
+ there's no need to put it in the small data section. */
&& (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
return true;
}
@@ -12772,8 +15035,7 @@ rs6000_elf_in_small_data_p (decl)
increment the returned register via an "la" instruction. */
struct rtx_def *
-find_addr_reg (addr)
- rtx addr;
+find_addr_reg (rtx addr)
{
while (GET_CODE (addr) == PLUS)
{
@@ -12796,23 +15058,11 @@ find_addr_reg (addr)
}
void
-rs6000_fatal_bad_address (op)
- rtx op;
+rs6000_fatal_bad_address (rtx op)
{
fatal_insn ("bad address", op);
}
-/* Called to register all of our global variables with the garbage
- collector. */
-
-static void
-rs6000_add_gc_roots ()
-{
- toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
- ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
- toc_hash_mark_table);
-}
-
#if TARGET_MACHO
#if 0
@@ -12820,8 +15070,7 @@ rs6000_add_gc_roots ()
reference and a constant. */
int
-symbolic_operand (op)
- rtx op;
+symbolic_operand (rtx op)
{
switch (GET_CODE (op))
{
@@ -12840,87 +15089,118 @@ symbolic_operand (op)
}
#endif
-#ifdef RS6000_LONG_BRANCH
+#if TARGET_MACHO
-static tree stub_list = 0;
+static tree branch_island_list = 0;
-/* ADD_COMPILER_STUB adds the compiler generated stub for handling
- procedure calls to the linked list. */
+/* Remember to generate a branch island for far calls to the given
+ function. */
-void
-add_compiler_stub (label_name, function_name, line_number)
- tree label_name;
- tree function_name;
- int line_number;
+static void
+add_compiler_branch_island (tree label_name, tree function_name, int line_number)
{
- tree stub = build_tree_list (function_name, label_name);
- TREE_TYPE (stub) = build_int_2 (line_number, 0);
- TREE_CHAIN (stub) = stub_list;
- stub_list = stub;
+ tree branch_island = build_tree_list (function_name, label_name);
+ TREE_TYPE (branch_island) = build_int_2 (line_number, 0);
+ TREE_CHAIN (branch_island) = branch_island_list;
+ branch_island_list = branch_island;
}
-#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
-#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
-#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
-
-/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
- handling procedure calls from the linked list and initializes the
- linked list. */
+#define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
+#define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
+#define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
+ TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
-void
-output_compiler_stub ()
-{
- char tmp_buf[256];
- char label_buf[256];
- tree stub;
-
- if (!flag_pic)
- for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
- {
- fprintf (asm_out_file,
- "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
+/* Generate far-jump branch islands for everything on the
+ branch_island_list. Invoked immediately after the last instruction
+ of the epilogue has been emitted; the branch-islands must be
+ appended to, and contiguous with, the function body. Mach-O stubs
+ are generated in machopic_output_stub(). */
+static void
+macho_branch_islands (void)
+{
+ char tmp_buf[512];
+ tree branch_island;
+
+ for (branch_island = branch_island_list;
+ branch_island;
+ branch_island = TREE_CHAIN (branch_island))
+ {
+ const char *label =
+ IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
+ const char *name =
+ darwin_strip_name_encoding (
+ IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island)));
+ char name_buf[512];
+ /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
+ if (name[0] == '*' || name[0] == '&')
+ strcpy (name_buf, name+1);
+ else
+ {
+ name_buf[0] = '_';
+ strcpy (name_buf+1, name);
+ }
+ strcpy (tmp_buf, "\n");
+ strcat (tmp_buf, label);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
+ if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
+ fprintf (asm_out_file, "\t.stabd 68,0," HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ BRANCH_ISLAND_LINE_NUMBER(branch_island));
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
-
- if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
- strcpy (label_buf,
- IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
- else
- {
- label_buf[0] = '_';
- strcpy (label_buf+1,
- IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
- }
-
- strcpy (tmp_buf, "lis r12,hi16(");
- strcat (tmp_buf, label_buf);
- strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
- strcat (tmp_buf, label_buf);
- strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
- output_asm_insn (tmp_buf, 0);
-
+ if (flag_pic)
+ {
+ strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic\n");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic:\n\tmflr r11\n");
+
+ strcat (tmp_buf, "\taddis r11,r11,ha16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, " - ");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic)\n");
+
+ strcat (tmp_buf, "\tmtlr r0\n");
+
+ strcat (tmp_buf, "\taddi r12,r11,lo16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, " - ");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic)\n");
+
+ strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
+ }
+ else
+ {
+ strcat (tmp_buf, ":\nlis r12,hi16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
+ }
+ output_asm_insn (tmp_buf, 0);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
+ if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
+ fprintf(asm_out_file, "\t.stabd 68,0," HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ BRANCH_ISLAND_LINE_NUMBER (branch_island));
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
- }
+ }
- stub_list = 0;
+ branch_island_list = 0;
}
/* NO_PREVIOUS_DEF checks in the link list whether the function name is
already there or not. */
-int
-no_previous_def (function_name)
- tree function_name;
+static int
+no_previous_def (tree function_name)
{
- tree stub;
- for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
- if (function_name == STUB_FUNCTION_NAME (stub))
+ tree branch_island;
+ for (branch_island = branch_island_list;
+ branch_island;
+ branch_island = TREE_CHAIN (branch_island))
+ if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
return 0;
return 1;
}
@@ -12928,14 +15208,15 @@ no_previous_def (function_name)
/* GET_PREV_LABEL gets the label name from the previous definition of
the function. */
-tree
-get_prev_label (function_name)
- tree function_name;
-{
- tree stub;
- for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
- if (function_name == STUB_FUNCTION_NAME (stub))
- return STUB_LABEL_NAME (stub);
+static tree
+get_prev_label (tree function_name)
+{
+ tree branch_island;
+ for (branch_island = branch_island_list;
+ branch_island;
+ branch_island = TREE_CHAIN (branch_island))
+ if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
+ return BRANCH_ISLAND_LABEL_NAME (branch_island);
return 0;
}
@@ -12945,16 +15226,14 @@ get_prev_label (function_name)
CALL_DEST is the routine we are calling. */
char *
-output_call (insn, call_dest, operand_number)
- rtx insn;
- rtx call_dest;
- int operand_number;
+output_call (rtx insn, rtx *operands, int dest_operand_number, int cookie_operand_number)
{
static char buf[256];
- if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
+ if (GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
+ && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
{
tree labelname;
- tree funname = get_identifier (XSTR (call_dest, 0));
+ tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
if (no_previous_def (funname))
{
@@ -12968,49 +15247,30 @@ output_call (insn, call_dest, operand_number)
for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
if (insn)
line_number = NOTE_LINE_NUMBER (insn);
- add_compiler_stub (labelname, funname, line_number);
+ add_compiler_branch_island (labelname, funname, line_number);
}
else
labelname = get_prev_label (funname);
+ /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
+ instruction will reach 'foo', otherwise link as 'bl L42'".
+ "L42" should be a 'branch island', that will do a far jump to
+ 'foo'. Branch islands are generated in
+ macho_branch_islands(). */
sprintf (buf, "jbsr %%z%d,%.246s",
- operand_number, IDENTIFIER_POINTER (labelname));
- return buf;
+ dest_operand_number, IDENTIFIER_POINTER (labelname));
}
else
- {
- sprintf (buf, "bl %%z%d", operand_number);
- return buf;
- }
+ sprintf (buf, "bl %%z%d", dest_operand_number);
+ return buf;
}
-#endif /* RS6000_LONG_BRANCH */
-
-#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
- do { \
- const char *const symbol_ = (SYMBOL); \
- char *buffer_ = (BUF); \
- if (symbol_[0] == '"') \
- { \
- sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
- } \
- else if (name_needs_quotes(symbol_)) \
- { \
- sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
- } \
- else \
- { \
- sprintf(buffer_, "L%d$%s", (N), symbol_); \
- } \
- } while (0)
-
+#endif /* TARGET_MACHO */
/* Generate PIC and indirect symbol stubs. */
void
-machopic_output_stub (file, symb, stub)
- FILE *file;
- const char *symb, *stub;
+machopic_output_stub (FILE *file, const char *symb, const char *stub)
{
unsigned int length;
char *symbol_name, *lazy_ptr_name;
@@ -13020,7 +15280,6 @@ machopic_output_stub (file, symb, stub)
/* Lose our funky encoding stuff so it doesn't contaminate the stub. */
symb = (*targetm.strip_name_encoding) (symb);
- label += 1;
length = strlen (symb);
symbol_name = alloca (length + 32);
@@ -13029,34 +15288,39 @@ machopic_output_stub (file, symb, stub)
lazy_ptr_name = alloca (length + 32);
GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
- local_label_0 = alloca (length + 32);
- GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
-
if (flag_pic == 2)
- machopic_picsymbol_stub_section ();
+ machopic_picsymbol_stub1_section ();
else
- machopic_symbol_stub_section ();
+ machopic_symbol_stub1_section ();
+ fprintf (file, "\t.align 2\n");
fprintf (file, "%s:\n", stub);
fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
if (flag_pic == 2)
{
+ label++;
+ local_label_0 = alloca (sizeof("\"L0000000000$spb\""));
+ sprintf (local_label_0, "\"L%011d$spb\"", label);
+
fprintf (file, "\tmflr r0\n");
fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
lazy_ptr_name, local_label_0);
fprintf (file, "\tmtlr r0\n");
- fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
+ fprintf (file, "\tlwzu r12,lo16(%s-%s)(r11)\n",
lazy_ptr_name, local_label_0);
fprintf (file, "\tmtctr r12\n");
- fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
- lazy_ptr_name, local_label_0);
fprintf (file, "\tbctr\n");
}
else
- fprintf (file, "non-pure not supported\n");
+ {
+ fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
+ fprintf (file, "\tlwzu r12,lo16(%s)(r11)\n", lazy_ptr_name);
+ fprintf (file, "\tmtctr r12\n");
+ fprintf (file, "\tbctr\n");
+ }
machopic_lazy_symbol_ptr_section ();
fprintf (file, "%s:\n", lazy_ptr_name);
@@ -13072,10 +15336,8 @@ machopic_output_stub (file, symb, stub)
#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
rtx
-rs6000_machopic_legitimize_pic_address (orig, mode, reg)
- rtx orig;
- enum machine_mode mode;
- rtx reg;
+rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
+ rtx reg)
{
rtx base, offset;
@@ -13090,9 +15352,13 @@ rs6000_machopic_legitimize_pic_address (orig, mode, reg)
if (GET_CODE (XEXP (orig, 0)) == PLUS)
{
+ /* Use a different reg for the intermediate value, as
+ it will be marked UNCHANGING. */
+ rtx reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
+
base =
rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
- Pmode, reg);
+ Pmode, reg_temp);
offset =
rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
Pmode, reg);
@@ -13125,7 +15391,7 @@ rs6000_machopic_legitimize_pic_address (orig, mode, reg)
real definition. */
void
-toc_section ()
+toc_section (void)
{
}
@@ -13133,19 +15399,10 @@ toc_section ()
#if TARGET_ELF
static unsigned int
-rs6000_elf_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
{
- unsigned int flags
- = default_section_type_flags_1 (decl, name, reloc,
- flag_pic || DEFAULT_ABI == ABI_AIX);
-
- if (TARGET_RELOCATABLE)
- flags |= SECTION_WRITE;
-
- return flags;
+ return default_section_type_flags_1 (decl, name, reloc,
+ flag_pic || DEFAULT_ABI == ABI_AIX);
}
/* Record an element in the table of global constructors. SYMBOL is
@@ -13156,9 +15413,7 @@ rs6000_elf_section_type_flags (decl, name, reloc)
that we have special handling for -mrelocatable. */
static void
-rs6000_elf_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority;
+rs6000_elf_asm_out_constructor (rtx symbol, int priority)
{
const char *section = ".ctors";
char buf[16];
@@ -13187,9 +15442,7 @@ rs6000_elf_asm_out_constructor (symbol, priority)
}
static void
-rs6000_elf_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority;
+rs6000_elf_asm_out_destructor (rtx symbol, int priority)
{
const char *section = ".dtors";
char buf[16];
@@ -13216,13 +15469,81 @@ rs6000_elf_asm_out_destructor (symbol, priority)
else
assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
}
+
+void
+rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
+{
+ if (TARGET_64BIT)
+ {
+ fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
+ ASM_OUTPUT_LABEL (file, name);
+ fputs (DOUBLE_INT_ASM_OP, file);
+ putc ('.', file);
+ assemble_name (file, name);
+ fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", file);
+ assemble_name (file, name);
+ fputs (",24\n\t.type\t.", file);
+ assemble_name (file, name);
+ fputs (",@function\n", file);
+ if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+ {
+ fputs ("\t.globl\t.", file);
+ assemble_name (file, name);
+ putc ('\n', file);
+ }
+ ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
+ putc ('.', file);
+ ASM_OUTPUT_LABEL (file, name);
+ return;
+ }
+
+ if (TARGET_RELOCATABLE
+ && (get_pool_size () != 0 || current_function_profile)
+ && uses_TOC ())
+ {
+ char buf[256];
+
+ (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
+ fprintf (file, "\t.long ");
+ assemble_name (file, buf);
+ putc ('-', file);
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+ assemble_name (file, buf);
+ putc ('\n', file);
+ }
+
+ ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
+ ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
+
+ if (DEFAULT_ABI == ABI_AIX)
+ {
+ const char *desc_name, *orig_name;
+
+ orig_name = (*targetm.strip_name_encoding) (name);
+ desc_name = orig_name;
+ while (*desc_name == '.')
+ desc_name++;
+
+ if (TREE_PUBLIC (decl))
+ fprintf (file, "\t.globl %s\n", desc_name);
+
+ fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
+ fprintf (file, "%s:\n", desc_name);
+ fprintf (file, "\t.long %s\n", orig_name);
+ fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
+ if (DEFAULT_ABI == ABI_AIX)
+ fputs ("\t.long 0\n", file);
+ fprintf (file, "\t.previous\n");
+ }
+ ASM_OUTPUT_LABEL (file, name);
+}
#endif
#if TARGET_XCOFF
static void
-rs6000_xcoff_asm_globalize_label (stream, name)
- FILE *stream;
- const char *name;
+rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
{
fputs (GLOBAL_ASM_OP, stream);
RS6000_OUTPUT_BASENAME (stream, name);
@@ -13230,9 +15551,7 @@ rs6000_xcoff_asm_globalize_label (stream, name)
}
static void
-rs6000_xcoff_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+rs6000_xcoff_asm_named_section (const char *name, unsigned int flags)
{
int smclass;
static const char * const suffix[3] = { "PR", "RO", "RW" };
@@ -13250,10 +15569,8 @@ rs6000_xcoff_asm_named_section (name, flags)
}
static void
-rs6000_xcoff_select_section (decl, reloc, align)
- tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+rs6000_xcoff_select_section (tree decl, int reloc,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (decl_readonly_section_1 (decl, reloc, 1))
{
@@ -13272,9 +15589,7 @@ rs6000_xcoff_select_section (decl, reloc, align)
}
static void
-rs6000_xcoff_unique_section (decl, reloc)
- tree decl;
- int reloc ATTRIBUTE_UNUSED;
+rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
{
const char *name;
@@ -13299,10 +15614,8 @@ rs6000_xcoff_unique_section (decl, reloc)
toc entry. */
static void
-rs6000_xcoff_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
toc_section ();
@@ -13313,8 +15626,7 @@ rs6000_xcoff_select_rtx_section (mode, x, align)
/* Remove any trailing [DS] or the like from the symbol name. */
static const char *
-rs6000_xcoff_strip_name_encoding (name)
- const char *name;
+rs6000_xcoff_strip_name_encoding (const char *name)
{
size_t len;
if (*name == '*')
@@ -13329,10 +15641,7 @@ rs6000_xcoff_strip_name_encoding (name)
/* Section attributes. AIX is always PIC. */
static unsigned int
-rs6000_xcoff_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
{
unsigned int align;
unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
@@ -13349,37 +15658,297 @@ rs6000_xcoff_section_type_flags (decl, name, reloc)
return flags | (exact_log2 (align) & SECTION_ENTSIZE);
}
-#endif /* TARGET_XCOFF */
+/* Output at beginning of assembler file.
+
+ Initialize the section names for the RS/6000 at this point.
+
+ Specify filename, including full path, to assembler.
-/* Note that this is also used for PPC64 Linux. */
+ We want to go into the TOC section so at least one .toc will be emitted.
+ Also, in order to output proper .bs/.es pairs, we need at least one static
+ [RW] section emitted.
+
+ Finally, declare mcount when profiling to make the assembler happy. */
+
+static void
+rs6000_xcoff_file_start (void)
+{
+ rs6000_gen_section_name (&xcoff_bss_section_name,
+ main_input_filename, ".bss_");
+ rs6000_gen_section_name (&xcoff_private_data_section_name,
+ main_input_filename, ".rw_");
+ rs6000_gen_section_name (&xcoff_read_only_section_name,
+ main_input_filename, ".ro_");
+
+ fputs ("\t.file\t", asm_out_file);
+ output_quoted_string (asm_out_file, main_input_filename);
+ fputc ('\n', asm_out_file);
+ toc_section ();
+ if (write_symbols != NO_DEBUG)
+ private_data_section ();
+ text_section ();
+ if (profile_flag)
+ fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
+ rs6000_file_start ();
+}
+
+/* Output at end of assembler file.
+ On the RS/6000, referencing data should automatically pull in text. */
static void
-rs6000_xcoff_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+rs6000_xcoff_file_end (void)
{
- if (TREE_CODE (decl) == FUNCTION_DECL
- && (*targetm.binds_local_p) (decl))
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+ text_section ();
+ fputs ("_section_.text:\n", asm_out_file);
+ data_section ();
+ fputs (TARGET_32BIT
+ ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
+ asm_out_file);
}
+#endif /* TARGET_XCOFF */
+
+#if TARGET_MACHO
+/* Cross-module name binding. Darwin does not support overriding
+ functions at dynamic-link time. */
+
+static bool
+rs6000_binds_local_p (tree decl)
+{
+ return default_binds_local_p_1 (decl, 0);
+}
+#endif
-/* Cross-module name binding. For AIX and PPC64 Linux, which always are
- PIC, use private copy of flag_pic. */
+/* 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. */
static bool
-rs6000_binds_local_p (decl)
- tree decl;
+rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+ int *total)
{
- return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
+ switch (code)
+ {
+ /* On the RS/6000, if it is valid in the insn, it is free.
+ So this always returns 0. */
+ case CONST_INT:
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ case HIGH:
+ *total = 0;
+ return true;
+
+ case PLUS:
+ *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1))
+ + 0x8000) >= 0x10000)
+ && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
+ ? COSTS_N_INSNS (2)
+ : COSTS_N_INSNS (1));
+ return true;
+
+ case AND:
+ case IOR:
+ case XOR:
+ *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0
+ && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
+ ? COSTS_N_INSNS (2)
+ : COSTS_N_INSNS (1));
+ return true;
+
+ case MULT:
+ if (optimize_size)
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ switch (rs6000_cpu)
+ {
+ case PROCESSOR_RIOS1:
+ case PROCESSOR_PPC405:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (5)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
+ return true;
+
+ case PROCESSOR_PPC440:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (3)
+ : COSTS_N_INSNS (2));
+ return true;
+
+ case PROCESSOR_RS64A:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12));
+ return true;
+
+ case PROCESSOR_RIOS2:
+ case PROCESSOR_MPCCORE:
+ case PROCESSOR_PPC604e:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PROCESSOR_PPC601:
+ *total = COSTS_N_INSNS (5);
+ return true;
+
+ case PROCESSOR_PPC603:
+ case PROCESSOR_PPC7400:
+ case PROCESSOR_PPC750:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (5)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3));
+ return true;
+
+ case PROCESSOR_PPC7450:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (4)
+ : COSTS_N_INSNS (3));
+ return true;
+
+ case PROCESSOR_PPC403:
+ case PROCESSOR_PPC604:
+ case PROCESSOR_PPC8540:
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case PROCESSOR_PPC620:
+ case PROCESSOR_PPC630:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
+ return true;
+
+ case PROCESSOR_POWER4:
+ case PROCESSOR_POWER5:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)
+ : COSTS_N_INSNS (2));
+ return true;
+
+ default:
+ abort ();
+ }
+
+ case DIV:
+ case MOD:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ /* FALLTHRU */
+
+ case UDIV:
+ case UMOD:
+ switch (rs6000_cpu)
+ {
+ case PROCESSOR_RIOS1:
+ *total = COSTS_N_INSNS (19);
+ return true;
+
+ case PROCESSOR_RIOS2:
+ *total = COSTS_N_INSNS (13);
+ return true;
+
+ case PROCESSOR_RS64A:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (65)
+ : COSTS_N_INSNS (67));
+ return true;
+
+ case PROCESSOR_MPCCORE:
+ *total = COSTS_N_INSNS (6);
+ return true;
+
+ case PROCESSOR_PPC403:
+ *total = COSTS_N_INSNS (33);
+ return true;
+
+ case PROCESSOR_PPC405:
+ *total = COSTS_N_INSNS (35);
+ return true;
+
+ case PROCESSOR_PPC440:
+ *total = COSTS_N_INSNS (34);
+ return true;
+
+ case PROCESSOR_PPC601:
+ *total = COSTS_N_INSNS (36);
+ return true;
+
+ case PROCESSOR_PPC603:
+ *total = COSTS_N_INSNS (37);
+ return true;
+
+ case PROCESSOR_PPC604:
+ case PROCESSOR_PPC604e:
+ *total = COSTS_N_INSNS (20);
+ return true;
+
+ case PROCESSOR_PPC620:
+ case PROCESSOR_PPC630:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (21)
+ : COSTS_N_INSNS (37));
+ return true;
+
+ case PROCESSOR_PPC750:
+ case PROCESSOR_PPC8540:
+ case PROCESSOR_PPC7400:
+ *total = COSTS_N_INSNS (19);
+ return true;
+
+ case PROCESSOR_PPC7450:
+ *total = COSTS_N_INSNS (23);
+ return true;
+
+ case PROCESSOR_POWER4:
+ case PROCESSOR_POWER5:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (18)
+ : COSTS_N_INSNS (34));
+ return true;
+
+ default:
+ abort ();
+ }
+
+ case FFS:
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case MEM:
+ /* MEM should be slightly more expensive than (plus (reg) (const)). */
+ *total = 5;
+ return true;
+
+ default:
+ return false;
+ }
}
/* A C expression returning the cost of moving data from a register of class
CLASS1 to one of CLASS2. */
int
-rs6000_register_move_cost (mode, from, to)
- enum machine_mode mode;
- enum reg_class from, to;
+rs6000_register_move_cost (enum machine_mode mode,
+ enum reg_class from, enum reg_class to)
{
/* Moves from/to GENERAL_REGS. */
if (reg_classes_intersect_p (to, GENERAL_REGS)
@@ -13392,7 +15961,7 @@ rs6000_register_move_cost (mode, from, to)
return (rs6000_memory_move_cost (mode, from, 0)
+ rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
-/* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
+/* It's more expensive to move CR_REGS than CR0_REGS because of the shift.... */
else if (from == CR_REGS)
return 4;
@@ -13415,10 +15984,8 @@ rs6000_register_move_cost (mode, from, to)
or from memory. */
int
-rs6000_memory_move_cost (mode, class, in)
- enum machine_mode mode;
- enum reg_class class;
- int in ATTRIBUTE_UNUSED;
+rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
+ int in ATTRIBUTE_UNUSED)
{
if (reg_classes_intersect_p (class, GENERAL_REGS))
return 4 * HARD_REGNO_NREGS (0, mode);
@@ -13430,3 +15997,199 @@ rs6000_memory_move_cost (mode, class, in)
return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
}
+/* Return an RTX representing where to find the function value of a
+ function returning MODE. */
+static rtx
+rs6000_complex_function_value (enum machine_mode mode)
+{
+ unsigned int regno;
+ rtx r1, r2;
+ enum machine_mode inner = GET_MODE_INNER (mode);
+ unsigned int inner_bytes = GET_MODE_SIZE (inner);
+
+ if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ regno = FP_ARG_RETURN;
+ else
+ {
+ regno = GP_ARG_RETURN;
+
+ /* 32-bit is OK since it'll go in r3/r4. */
+ if (TARGET_32BIT && inner_bytes >= 4)
+ return gen_rtx_REG (mode, regno);
+ }
+
+ if (inner_bytes >= 8)
+ return gen_rtx_REG (mode, regno);
+
+ r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
+ const0_rtx);
+ r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
+ GEN_INT (inner_bytes));
+ return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
+}
+
+/* Define how to find the value returned by a function.
+ VALTYPE is the data type of the value (as a tree).
+ If the precise function being called is known, FUNC is its FUNCTION_DECL;
+ otherwise, FUNC is 0.
+
+ On the SPE, both FPs and vectors are returned in r3.
+
+ On RS/6000 an integer value is in r3 and a floating-point value is in
+ fp1, unless -msoft-float. */
+
+rtx
+rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
+{
+ enum machine_mode mode;
+ unsigned int regno;
+
+ if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
+ {
+ /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode, GP_ARG_RETURN),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_RETURN + 1),
+ GEN_INT (4))));
+ }
+
+ if ((INTEGRAL_TYPE_P (valtype)
+ && TYPE_PRECISION (valtype) < BITS_PER_WORD)
+ || POINTER_TYPE_P (valtype))
+ mode = TARGET_32BIT ? SImode : DImode;
+ else
+ mode = TYPE_MODE (valtype);
+
+ if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ regno = FP_ARG_RETURN;
+ else if (TREE_CODE (valtype) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg)
+ return rs6000_complex_function_value (mode);
+ else if (TREE_CODE (valtype) == VECTOR_TYPE
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
+ regno = ALTIVEC_ARG_RETURN;
+ else
+ regno = GP_ARG_RETURN;
+
+ return gen_rtx_REG (mode, regno);
+}
+
+/* Define how to find the value returned by a library function
+ assuming the value has mode MODE. */
+rtx
+rs6000_libcall_value (enum machine_mode mode)
+{
+ unsigned int regno;
+
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && TARGET_HARD_FLOAT && TARGET_FPRS)
+ regno = FP_ARG_RETURN;
+ else if (ALTIVEC_VECTOR_MODE (mode)
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
+ regno = ALTIVEC_ARG_RETURN;
+ else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
+ return rs6000_complex_function_value (mode);
+ else
+ regno = GP_ARG_RETURN;
+
+ return gen_rtx_REG (mode, regno);
+}
+
+/* Define the offset between two registers, FROM to be eliminated and its
+ replacement TO, at the start of a routine. */
+HOST_WIDE_INT
+rs6000_initial_elimination_offset (int from, int to)
+{
+ rs6000_stack_t *info = rs6000_stack_info ();
+ HOST_WIDE_INT offset;
+
+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ offset = info->push_p ? 0 : -info->total_size;
+ else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
+ offset = info->total_size;
+ else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ offset = info->push_p ? info->total_size : 0;
+ else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
+ offset = 0;
+ else
+ abort ();
+
+ return offset;
+}
+
+/* Return true if TYPE is of type __ev64_opaque__. */
+
+static bool
+is_ev64_opaque_type (tree type)
+{
+ return (TARGET_SPE
+ && (type == opaque_V2SI_type_node
+ || type == opaque_V2SF_type_node
+ || type == opaque_p_V2SI_type_node));
+}
+
+static rtx
+rs6000_dwarf_register_span (rtx reg)
+{
+ unsigned regno;
+
+ if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
+ return NULL_RTX;
+
+ regno = REGNO (reg);
+
+ /* The duality of the SPE register size wreaks all kinds of havoc.
+ This is a way of distinguishing r0 in 32-bits from r0 in
+ 64-bits. */
+ return
+ gen_rtx_PARALLEL (VOIDmode,
+ BYTES_BIG_ENDIAN
+ ? gen_rtvec (2,
+ gen_rtx_REG (SImode, regno + 1200),
+ gen_rtx_REG (SImode, regno))
+ : gen_rtvec (2,
+ gen_rtx_REG (SImode, regno),
+ gen_rtx_REG (SImode, regno + 1200)));
+}
+
+/* Map internal gcc register numbers to DWARF2 register numbers. */
+
+unsigned int
+rs6000_dbx_register_number (unsigned int regno)
+{
+ if (regno <= 63 || write_symbols != DWARF2_DEBUG)
+ return regno;
+ if (regno == MQ_REGNO)
+ return 100;
+ if (regno == LINK_REGISTER_REGNUM)
+ return 108;
+ if (regno == COUNT_REGISTER_REGNUM)
+ return 109;
+ if (CR_REGNO_P (regno))
+ return regno - CR0_REGNO + 86;
+ if (regno == XER_REGNO)
+ return 101;
+ if (ALTIVEC_REGNO_P (regno))
+ return regno - FIRST_ALTIVEC_REGNO + 1124;
+ if (regno == VRSAVE_REGNO)
+ return 356;
+ if (regno == VSCR_REGNO)
+ return 67;
+ if (regno == SPE_ACC_REGNO)
+ return 99;
+ if (regno == SPEFSCR_REGNO)
+ return 612;
+ /* SPE high reg number. We get these values of regno from
+ rs6000_dwarf_register_span. */
+ if (regno >= 1200 && regno < 1232)
+ return regno;
+
+ abort ();
+}
+
+#include "gt-rs6000.h"
diff --git a/contrib/gcc/config/rs6000/rs6000.h b/contrib/gcc/config/rs6000/rs6000.h
index 957fcec..d3a66dd 100644
--- a/contrib/gcc/config/rs6000/rs6000.h
+++ b/contrib/gcc/config/rs6000/rs6000.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Note that some other tm.h files include this one and then override
many of the definitions. */
@@ -52,23 +51,29 @@ Boston, MA 02111-1307, USA. */
"%{!mcpu*: \
%{mpower: %{!mpower2: -mpwr}} \
%{mpower2: -mpwrx} \
- %{mpowerpc*: -mppc} \
+ %{mpowerpc64*: -mppc64} \
+ %{!mpowerpc64*: %{mpowerpc*: -mppc}} \
%{mno-power: %{!mpowerpc*: -mcom}} \
- %{!mno-power: %{!mpower2: %(asm_default)}}} \
+ %{!mno-power: %{!mpower*: %(asm_default)}}} \
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwrx} \
-%{mcpu=power3: -m604} \
+%{mcpu=power3: -mppc64} \
%{mcpu=power4: -mpower4} \
+%{mcpu=power5: -mpower4} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
%{mcpu=rios2: -mpwrx} \
%{mcpu=rsc: -mpwr} \
%{mcpu=rsc1: -mpwr} \
+%{mcpu=rs64a: -mppc64} \
%{mcpu=401: -mppc} \
%{mcpu=403: -m403} \
%{mcpu=405: -m405} \
+%{mcpu=405fp: -m405} \
+%{mcpu=440: -m440} \
+%{mcpu=440fp: -m440} \
%{mcpu=505: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=602: -mppc} \
@@ -77,18 +82,23 @@ Boston, MA 02111-1307, USA. */
%{mcpu=ec603e: -mppc} \
%{mcpu=604: -mppc} \
%{mcpu=604e: -mppc} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604} \
+%{mcpu=620: -mppc64} \
+%{mcpu=630: -mppc64} \
%{mcpu=740: -mppc} \
-%{mcpu=7400: -mppc} \
-%{mcpu=7450: -mppc} \
%{mcpu=750: -mppc} \
+%{mcpu=G3: -mppc} \
+%{mcpu=7400: -mppc -maltivec} \
+%{mcpu=7450: -mppc -maltivec} \
+%{mcpu=G4: -mppc -maltivec} \
%{mcpu=801: -mppc} \
%{mcpu=821: -mppc} \
%{mcpu=823: -mppc} \
%{mcpu=860: -mppc} \
+%{mcpu=970: -mpower4 -maltivec} \
+%{mcpu=G5: -mpower4 -maltivec} \
%{mcpu=8540: -me500} \
-%{maltivec: -maltivec}"
+%{maltivec: -maltivec} \
+-many"
#define CPP_DEFAULT_SPEC ""
@@ -99,7 +109,7 @@ Boston, MA 02111-1307, USA. */
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -154,39 +164,42 @@ extern int target_flags;
function, and one less allocable register. */
#define MASK_MINIMAL_TOC 0x00000200
-/* Nonzero for the 64bit model: longs and pointers are 64 bits. */
+/* Nonzero for the 64 bit ABIs: longs and pointers are 64 bits. The
+ chip is running in "64-bit mode", in which CR0 is set in dot
+ operations based on all 64 bits of the register, bdnz works on 64-bit
+ ctr, lr is 64 bits, and so on. Requires MASK_POWERPC64. */
#define MASK_64BIT 0x00000400
/* Disable use of FPRs. */
#define MASK_SOFT_FLOAT 0x00000800
/* Enable load/store multiple, even on PowerPC */
-#define MASK_MULTIPLE 0x00001000
-#define MASK_MULTIPLE_SET 0x00002000
+#define MASK_MULTIPLE 0x00001000
/* Use string instructions for block moves */
-#define MASK_STRING 0x00004000
-#define MASK_STRING_SET 0x00008000
+#define MASK_STRING 0x00002000
/* Disable update form of load/store */
-#define MASK_NO_UPDATE 0x00010000
+#define MASK_NO_UPDATE 0x00004000
/* Disable fused multiply/add operations */
-#define MASK_NO_FUSED_MADD 0x00020000
+#define MASK_NO_FUSED_MADD 0x00008000
/* Nonzero if we need to schedule the prolog and epilog. */
-#define MASK_SCHED_PROLOG 0x00040000
+#define MASK_SCHED_PROLOG 0x00010000
/* Use AltiVec instructions. */
-#define MASK_ALTIVEC 0x00080000
+#define MASK_ALTIVEC 0x00020000
/* Return small structures in memory (as the AIX ABI requires). */
-#define MASK_AIX_STRUCT_RET 0x00100000
-#define MASK_AIX_STRUCT_RET_SET 0x00200000
+#define MASK_AIX_STRUCT_RET 0x00040000
+
+/* Use single field mfcr instruction. */
+#define MASK_MFCRF 0x00080000
-/* The only remaining free bit is 0x00400000. sysv4.h uses
- 0x00800000 -> 0x40000000, and 0x80000000 is not available
- because target_flags is signed. */
+/* The only remaining free bits are 0x00600000. linux64.h uses
+ 0x00100000, and sysv4.h uses 0x00800000 -> 0x40000000.
+ 0x80000000 is not available because target_flags is signed. */
#define TARGET_POWER (target_flags & MASK_POWER)
#define TARGET_POWER2 (target_flags & MASK_POWER2)
@@ -199,21 +212,41 @@ extern int target_flags;
#define TARGET_MINIMAL_TOC (target_flags & MASK_MINIMAL_TOC)
#define TARGET_64BIT (target_flags & MASK_64BIT)
#define TARGET_SOFT_FLOAT (target_flags & MASK_SOFT_FLOAT)
-#define TARGET_MULTIPLE (target_flags & MASK_MULTIPLE)
-#define TARGET_MULTIPLE_SET (target_flags & MASK_MULTIPLE_SET)
+#define TARGET_MULTIPLE (target_flags & MASK_MULTIPLE)
#define TARGET_STRING (target_flags & MASK_STRING)
-#define TARGET_STRING_SET (target_flags & MASK_STRING_SET)
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
#define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG)
#define TARGET_ALTIVEC (target_flags & MASK_ALTIVEC)
#define TARGET_AIX_STRUCT_RET (target_flags & MASK_AIX_STRUCT_RET)
+/* Define TARGET_MFCRF if the target assembler supports the optional
+ field operand for mfcr and the target processor supports the
+ instruction. */
+
+#ifdef HAVE_AS_MFCRF
+#define TARGET_MFCRF (target_flags & MASK_MFCRF)
+#else
+#define TARGET_MFCRF 0
+#endif
+
+
#define TARGET_32BIT (! TARGET_64BIT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
#define TARGET_UPDATE (! TARGET_NO_UPDATE)
#define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD)
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ rs6000_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
+#ifndef HAVE_AS_TLS
+#define HAVE_AS_TLS 0
+#endif
+
#ifdef IN_LIBGCC2
/* For libgcc2 we make sure this is a compile time constant */
#if defined (__64BIT__) || defined (__powerpc64__)
@@ -254,19 +287,19 @@ extern int target_flags;
{"powerpc-gpopt", MASK_POWERPC | MASK_PPC_GPOPT, \
N_("Use PowerPC General Purpose group optional instructions")},\
{"no-powerpc-gpopt", - MASK_PPC_GPOPT, \
- N_("Don't use PowerPC General Purpose group optional instructions")},\
+ N_("Do not use PowerPC General Purpose group optional instructions")},\
{"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT, \
N_("Use PowerPC Graphics group optional instructions")},\
{"no-powerpc-gfxopt", - MASK_PPC_GFXOPT, \
- N_("Don't use PowerPC Graphics group optional instructions")},\
+ N_("Do not use PowerPC Graphics group optional instructions")},\
{"powerpc64", MASK_POWERPC64, \
N_("Use PowerPC-64 instruction set")}, \
{"no-powerpc64", - MASK_POWERPC64, \
- N_("Don't use PowerPC-64 instruction set")}, \
+ N_("Do not use PowerPC-64 instruction set")}, \
{"altivec", MASK_ALTIVEC , \
N_("Use AltiVec instructions")}, \
{"no-altivec", - MASK_ALTIVEC , \
- N_("Don't use AltiVec instructions")}, \
+ N_("Do not use AltiVec instructions")}, \
{"new-mnemonics", MASK_NEW_MNEMONICS, \
N_("Use new mnemonics for PowerPC architecture")},\
{"old-mnemonics", -MASK_NEW_MNEMONICS, \
@@ -277,11 +310,11 @@ extern int target_flags;
{"fp-in-toc", - MASK_NO_FP_IN_TOC, \
N_("Place floating point constants in TOC")}, \
{"no-fp-in-toc", MASK_NO_FP_IN_TOC, \
- N_("Don't place floating point constants in TOC")},\
+ N_("Do not place floating point constants in TOC")},\
{"sum-in-toc", - MASK_NO_SUM_IN_TOC, \
N_("Place symbol+offset constants in TOC")}, \
{"no-sum-in-toc", MASK_NO_SUM_IN_TOC, \
- N_("Don't place symbol+offset constants in TOC")},\
+ N_("Do not place symbol+offset constants in TOC")},\
{"minimal-toc", MASK_MINIMAL_TOC, \
"Use only one TOC entry per procedure"}, \
{"minimal-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC), \
@@ -289,21 +322,17 @@ extern int target_flags;
{"no-minimal-toc", - MASK_MINIMAL_TOC, \
N_("Place variable addresses in the regular TOC")},\
{"hard-float", - MASK_SOFT_FLOAT, \
- N_("Use hardware fp")}, \
+ N_("Use hardware floating point")}, \
{"soft-float", MASK_SOFT_FLOAT, \
- N_("Do not use hardware fp")}, \
- {"multiple", MASK_MULTIPLE | MASK_MULTIPLE_SET, \
+ N_("Do not use hardware floating point")}, \
+ {"multiple", MASK_MULTIPLE, \
N_("Generate load/store multiple instructions")}, \
{"no-multiple", - MASK_MULTIPLE, \
N_("Do not generate load/store multiple instructions")},\
- {"no-multiple", MASK_MULTIPLE_SET, \
- ""}, \
- {"string", MASK_STRING | MASK_STRING_SET, \
+ {"string", MASK_STRING, \
N_("Generate string instructions for block moves")},\
{"no-string", - MASK_STRING, \
N_("Do not generate string instructions for block moves")},\
- {"no-string", MASK_STRING_SET, \
- ""}, \
{"update", - MASK_NO_UPDATE, \
N_("Generate load/store with update instructions")},\
{"no-update", MASK_NO_UPDATE, \
@@ -311,27 +340,27 @@ extern int target_flags;
{"fused-madd", - MASK_NO_FUSED_MADD, \
N_("Generate fused multiply/add instructions")},\
{"no-fused-madd", MASK_NO_FUSED_MADD, \
- N_("Don't generate fused multiply/add instructions")},\
+ N_("Do not generate fused multiply/add instructions")},\
{"sched-prolog", MASK_SCHED_PROLOG, \
""}, \
{"no-sched-prolog", -MASK_SCHED_PROLOG, \
- N_("Don't schedule the start and end of the procedure")},\
+ N_("Do not schedule the start and end of the procedure")},\
{"sched-epilog", MASK_SCHED_PROLOG, \
""}, \
{"no-sched-epilog", -MASK_SCHED_PROLOG, \
""}, \
- {"aix-struct-return", MASK_AIX_STRUCT_RET | MASK_AIX_STRUCT_RET_SET, \
+ {"aix-struct-return", MASK_AIX_STRUCT_RET, \
N_("Return all structures in memory (AIX default)")},\
- {"svr4-struct-return", - MASK_AIX_STRUCT_RET,\
+ {"svr4-struct-return", - MASK_AIX_STRUCT_RET, \
N_("Return small structures in registers (SVR4 default)")},\
- {"svr4-struct-return",MASK_AIX_STRUCT_RET_SET,\
- ""},\
- {"no-aix-struct-return", - MASK_AIX_STRUCT_RET,\
- ""},\
- {"no-aix-struct-return", MASK_AIX_STRUCT_RET_SET,\
- ""},\
- {"no-svr4-struct-return", MASK_AIX_STRUCT_RET | MASK_AIX_STRUCT_RET_SET,\
- ""},\
+ {"no-aix-struct-return", - MASK_AIX_STRUCT_RET, \
+ ""}, \
+ {"no-svr4-struct-return", MASK_AIX_STRUCT_RET, \
+ ""}, \
+ {"mfcrf", MASK_MFCRF, \
+ N_("Generate single field mfcr instruction")}, \
+ {"no-mfcrf", - MASK_MFCRF, \
+ N_("Do not generate single field mfcr instruction")},\
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT | MASK_SCHED_PROLOG, \
""}}
@@ -350,6 +379,7 @@ enum processor_type
PROCESSOR_MPCCORE,
PROCESSOR_PPC403,
PROCESSOR_PPC405,
+ PROCESSOR_PPC440,
PROCESSOR_PPC601,
PROCESSOR_PPC603,
PROCESSOR_PPC604,
@@ -360,7 +390,8 @@ enum processor_type
PROCESSOR_PPC7400,
PROCESSOR_PPC7450,
PROCESSOR_PPC8540,
- PROCESSOR_POWER4
+ PROCESSOR_POWER4,
+ PROCESSOR_POWER5
};
extern enum processor_type rs6000_cpu;
@@ -382,31 +413,78 @@ extern enum processor_type rs6000_cpu;
and the old mnemonics are dialect zero. */
#define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0)
+/* Types of costly dependences. */
+enum rs6000_dependence_cost
+ {
+ max_dep_latency = 1000,
+ no_dep_costly,
+ all_deps_costly,
+ true_store_to_load_dep_costly,
+ store_to_load_dep_costly
+ };
+
+/* Types of nop insertion schemes in sched target hook sched_finish. */
+enum rs6000_nop_insertion
+ {
+ sched_finish_regroup_exact = 1000,
+ sched_finish_pad_groups,
+ sched_finish_none
+ };
+
+/* Dispatch group termination caused by an insn. */
+enum group_termination
+ {
+ current_group,
+ previous_group
+ };
+
/* This is meant to be overridden in target specific files. */
#define SUBTARGET_OPTIONS
#define TARGET_OPTIONS \
{ \
{"cpu=", &rs6000_select[1].string, \
- N_("Use features of and schedule code for given CPU") }, \
+ N_("Use features of and schedule code for given CPU"), 0}, \
{"tune=", &rs6000_select[2].string, \
- N_("Schedule code for given CPU") }, \
- {"debug=", &rs6000_debug_name, N_("Enable debug output") }, \
+ N_("Schedule code for given CPU"), 0}, \
+ {"debug=", &rs6000_debug_name, N_("Enable debug output"), 0}, \
{"traceback=", &rs6000_traceback_name, \
- N_("Select full, part, or no traceback table") }, \
- {"abi=", &rs6000_abi_string, N_("Specify ABI to use") }, \
+ N_("Select full, part, or no traceback table"), 0}, \
+ {"abi=", &rs6000_abi_string, N_("Specify ABI to use"), 0}, \
{"long-double-", &rs6000_long_double_size_string, \
- N_("Specify size of long double (64 or 128 bits)") }, \
+ N_("Specify size of long double (64 or 128 bits)"), 0}, \
{"isel=", &rs6000_isel_string, \
- N_("Specify yes/no if isel instructions should be generated") }, \
- {"vrsave=", &rs6000_altivec_vrsave_string, \
- N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec") }, \
+ N_("Specify yes/no if isel instructions should be generated"), 0}, \
+ {"spe=", &rs6000_spe_string, \
+ N_("Specify yes/no if SPE SIMD instructions should be generated"), 0},\
+ {"float-gprs=", &rs6000_float_gprs_string, \
+ N_("Specify yes/no if using floating point in the GPRs"), 0}, \
+ {"vrsave=", &rs6000_altivec_vrsave_string, \
+ N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec"), 0}, \
{"longcall", &rs6000_longcall_switch, \
- N_("Avoid all range limits on call instructions") }, \
- {"no-longcall", &rs6000_longcall_switch, "" }, \
+ N_("Avoid all range limits on call instructions"), 0}, \
+ {"no-longcall", &rs6000_longcall_switch, "", 0}, \
+ {"sched-costly-dep=", &rs6000_sched_costly_dep_str, \
+ N_("Determine which dependences between insns are considered costly"), 0}, \
+ {"insert-sched-nops=", &rs6000_sched_insert_nops_str, \
+ N_("Specify which post scheduling nop insertion scheme to apply"), 0}, \
+ {"align-", &rs6000_alignment_string, \
+ N_("Specify alignment of structure fields default/natural"), 0}, \
+ {"prioritize-restricted-insns=", &rs6000_sched_restricted_insns_priority_str, \
+ N_("Specify scheduling priority for dispatch slot restricted insns"), 0}, \
SUBTARGET_OPTIONS \
}
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float or -msoft-float are
+ specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
+
/* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
struct rs6000_cpu_select
{
@@ -436,12 +514,40 @@ extern int rs6000_long_double_type_size;
extern int rs6000_altivec_abi;
extern int rs6000_spe_abi;
extern int rs6000_isel;
-extern int rs6000_fprs;
+extern int rs6000_spe;
+extern int rs6000_float_gprs;
+extern const char *rs6000_float_gprs_string;
extern const char *rs6000_isel_string;
+extern const char *rs6000_spe_string;
extern const char *rs6000_altivec_vrsave_string;
extern int rs6000_altivec_vrsave;
extern const char *rs6000_longcall_switch;
extern int rs6000_default_long_calls;
+extern const char* rs6000_alignment_string;
+extern int rs6000_alignment_flags;
+extern const char *rs6000_sched_restricted_insns_priority_str;
+extern int rs6000_sched_restricted_insns_priority;
+extern const char *rs6000_sched_costly_dep_str;
+extern enum rs6000_dependence_cost rs6000_sched_costly_dep;
+extern const char *rs6000_sched_insert_nops_str;
+extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
+
+/* Alignment options for fields in structures for sub-targets following
+ AIX-like ABI.
+ ALIGN_POWER word-aligns FP doubles (default AIX ABI).
+ ALIGN_NATURAL doubleword-aligns FP doubles (align to object size).
+
+ Override the macro definitions when compiling libobjc to avoid undefined
+ reference to rs6000_alignment_flags due to library's use of GCC alignment
+ macros which use the macros below. */
+
+#ifndef IN_TARGET_LIBS
+#define MASK_ALIGN_POWER 0x00000000
+#define MASK_ALIGN_NATURAL 0x00000001
+#define TARGET_ALIGN_NATURAL (rs6000_alignment_flags & MASK_ALIGN_NATURAL)
+#else
+#define TARGET_ALIGN_NATURAL 0
+#endif
#define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
#define TARGET_ALTIVEC_ABI rs6000_altivec_abi
@@ -449,6 +555,7 @@ extern int rs6000_default_long_calls;
#define TARGET_SPE_ABI 0
#define TARGET_SPE 0
+#define TARGET_E500 0
#define TARGET_ISEL 0
#define TARGET_FPRS 1
@@ -458,7 +565,7 @@ extern int rs6000_default_long_calls;
defined, is executed once just after all the command options have
been parsed.
- Don't use this macro to turn on various extra optimizations for
+ Do not use this macro to turn on various extra optimizations for
`-O'. That is what `OPTIMIZATION_OPTIONS' is for.
On the RS/6000 this is used to define the target cpu type. */
@@ -472,8 +579,8 @@ extern int rs6000_default_long_calls;
#define CAN_DEBUG_WITHOUT_FP
/* Target pragma. */
-#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
- cpp_register_pragma (PFILE, 0, "longcall", rs6000_pragma_longcall); \
+#define REGISTER_TARGET_PRAGMAS() do { \
+ c_register_pragma (0, "longcall", rs6000_pragma_longcall); \
} while (0)
/* Target #defines. */
@@ -511,16 +618,7 @@ extern int rs6000_default_long_calls;
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
- (MODE) = word_mode;
-
-/* Define this if function arguments should also be promoted using the above
- procedure. */
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted. */
-
-#define PROMOTE_FUNCTION_RETURN
+ (MODE) = TARGET_32BIT ? SImode : DImode;
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
@@ -622,7 +720,8 @@ extern int rs6000_default_long_calls;
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define STACK_BOUNDARY \
+ ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -697,7 +796,8 @@ extern int rs6000_default_long_calls;
RS/6000 has 32 fixed-point registers, 32 floating-point registers,
an MQ register, a count register, a link register, and 8 condition
- register fields, which we view here as separate registers.
+ register fields, which we view here as separate registers. AltiVec
+ adds 32 vector registers and a VRsave register.
In addition, the difference between the frame and argument pointers is
a function of the number of registers saved, so we need to have a
@@ -714,6 +814,28 @@ extern int rs6000_default_long_calls;
/* This must be included for pre gcc 3.0 glibc compatibility. */
#define PRE_GCC3_DWARF_FRAME_REGISTERS 77
+/* Add 32 dwarf columns for synthetic SPE registers. */
+#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 32)
+
+/* The SPE has an additional 32 synthetic registers, with DWARF debug
+ info numbering for these registers starting at 1200. While eh_frame
+ register numbering need not be the same as the debug info numbering,
+ we choose to number these regs for eh_frame at 1200 too. This allows
+ future versions of the rs6000 backend to add hard registers and
+ continue to use the gcc hard register numbering for eh_frame. If the
+ extra SPE registers in eh_frame were numbered starting from the
+ current value of FIRST_PSEUDO_REGISTER, then if FIRST_PSEUDO_REGISTER
+ changed we'd need to introduce a mapping in DWARF_FRAME_REGNUM to
+ avoid invalidating older SPE eh_frame info.
+
+ We must map them here to avoid huge unwinder tables mostly consisting
+ of unused space. */
+#define DWARF_REG_TO_UNWIND_COLUMN(r) \
+ ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER) : (r))
+
+/* Use gcc hard register numbering for eh_frame. */
+#define DWARF_FRAME_REGNUM(REGNO) (REGNO)
+
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
@@ -824,6 +946,13 @@ extern int rs6000_default_long_calls;
v31 - v20 (saved; order given to save least number)
*/
+#if FIXED_R2 == 1
+#define MAYBE_R2_AVAILABLE
+#define MAYBE_R2_FIXED 2,
+#else
+#define MAYBE_R2_AVAILABLE 2,
+#define MAYBE_R2_FIXED
+#endif
#define REG_ALLOC_ORDER \
{32, \
@@ -832,13 +961,13 @@ extern int rs6000_default_long_calls;
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
50, 49, 48, 47, 46, \
75, 74, 69, 68, 72, 71, 70, \
- 0, \
+ 0, MAYBE_R2_AVAILABLE \
9, 11, 10, 8, 7, 6, 5, 4, \
3, \
31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
18, 17, 16, 15, 14, 13, 12, \
64, 66, 65, \
- 73, 1, 2, 67, 76, \
+ 73, 1, MAYBE_R2_FIXED 67, 76, \
/* AltiVec registers. */ \
77, 78, \
90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
@@ -891,6 +1020,11 @@ extern int rs6000_default_long_calls;
? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ ((TARGET_32BIT && TARGET_POWERPC64 \
+ && (MODE == DImode || MODE == DFmode) \
+ && INT_REGNO_P (REGNO)) ? 1 : 0)
+
#define ALTIVEC_VECTOR_MODE(MODE) \
((MODE) == V16QImode \
|| (MODE) == V8HImode \
@@ -912,22 +1046,25 @@ extern int rs6000_default_long_calls;
|| (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
- For POWER and PowerPC, the GPRs can hold any mode, but the float
+ For POWER and PowerPC, the GPRs can hold any mode, but values bigger
+ than one register cannot go past R31. The float
registers only can hold floating modes and DImode, and CR register only
can hold CC modes. We cannot put TImode anywhere except general
register and it must be able to fit within the register set. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- (FP_REGNO_P (REGNO) ? \
- (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
+ (INT_REGNO_P (REGNO) ? \
+ INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1) \
+ : FP_REGNO_P (REGNO) ? \
+ ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ && FP_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)) \
+ || (GET_MODE_CLASS (MODE) == MODE_INT \
+ && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
: ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE) \
: SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
: CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
: XER_REGNO_P (REGNO) ? (MODE) == PSImode \
- : ! INT_REGNO_P (REGNO) ? GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \
- : 1)
+ : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
@@ -942,12 +1079,22 @@ extern int rs6000_default_long_calls;
? GET_MODE_CLASS (MODE2) == MODE_CC \
: GET_MODE_CLASS (MODE2) == MODE_CC \
? GET_MODE_CLASS (MODE1) == MODE_CC \
+ : SPE_VECTOR_MODE (MODE1) \
+ ? SPE_VECTOR_MODE (MODE2) \
+ : SPE_VECTOR_MODE (MODE2) \
+ ? SPE_VECTOR_MODE (MODE1) \
: ALTIVEC_VECTOR_MODE (MODE1) \
? ALTIVEC_VECTOR_MODE (MODE2) \
: ALTIVEC_VECTOR_MODE (MODE2) \
? ALTIVEC_VECTOR_MODE (MODE1) \
: 1)
+/* Post-reload, we can't use any new AltiVec registers, as we already
+ emitted the vrsave mask. */
+
+#define HARD_REGNO_RENAME_OK(SRC, DST) \
+ (! ALTIVEC_REGNO_P (DST) || regs_ever_live[DST])
+
/* A C expression returning the cost of moving data from a register of class
CLASS1 to one of CLASS2. */
@@ -966,6 +1113,10 @@ extern int rs6000_default_long_calls;
#define BRANCH_COST 3
+/* Override BRANCH_COST heuristic which empirically produces worse
+ performance for fold_range_test(). */
+
+#define RANGE_TEST_NON_SHORT_CIRCUIT 0
/* A fixed register used at prologue and epilogue generation to fix
addressing modes. The SPE needs heavy addressing fixes at the last
@@ -976,7 +1127,7 @@ extern int rs6000_default_long_calls;
we end up clobbering r11.
The AltiVec case needs to be fixed. Dunno if we should break ABI
- compatability and reserve a register for it as well.. */
+ compatibility and reserve a register for it as well.. */
#define FIXED_SCRATCH (TARGET_SPE ? 14 : 11)
@@ -1063,11 +1214,6 @@ extern int rs6000_default_long_calls;
/* Count register number. */
#define COUNT_REGISTER_REGNUM 66
-
-/* Place that structure value return address is placed.
-
- On the RS/6000, it is passed as an extra parameter. */
-#define STRUCT_VALUE 0
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
@@ -1091,7 +1237,7 @@ extern int rs6000_default_long_calls;
/* The RS/6000 has three types of registers, fixed-point, floating-point,
and condition registers, plus three special registers, MQ, CTR, and the
- link register.
+ link register. AltiVec adds a vector register class.
However, r0 is special in that it cannot be used as a base register.
So make a class for registers valid as base registers.
@@ -1273,11 +1419,13 @@ enum reg_class
'S' is a constant that can be placed into a 64-bit mask operand
'T' is a constant that can be placed into a 32-bit mask operand
'U' is for V.4 small data references.
+ 'W' is a vector constant that can be easily generated (no mem refs).
+ 'Y' is a indexed or word-aligned displacement memory operand.
't' is for AND masks that can be performed by two rldic{l,r} insns. */
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
- : (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \
+ : (C) == 'R' ? legitimate_constant_pool_address_p (OP) \
: (C) == 'S' ? mask64_operand (OP, DImode) \
: (C) == 'T' ? mask_operand (OP, SImode) \
: (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \
@@ -1286,8 +1434,17 @@ enum reg_class
&& (fixed_regs[CR0_REGNO] \
|| !logical_operand (OP, DImode)) \
&& !mask64_operand (OP, DImode)) \
+ : (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP))) \
+ : (C) == 'Y' ? (word_offset_memref_operand (OP, GET_MODE (OP))) \
: 0)
+/* Defining, which contraints are memory contraints. Tells reload,
+ that any memory address can be reloaded by copying the
+ memory address into a base register if required. */
+
+#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
+ ((C) == 'Q' || (C) == 'Y')
+
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
@@ -1315,12 +1472,22 @@ enum reg_class
? GENERAL_REGS \
: (CLASS)))
+#define DISPARAGE_RELOAD_CLASS(X, CLASS) \
+ (GET_CODE (X) == REG \
+ && REGNO (X) < FIRST_PSEUDO_REGISTER \
+ && SECONDARY_MEMORY_NEEDED (GET_MODE_CLASS (GET_MODE (X)), \
+ CLASS, GET_MODE (X)) \
+ ? 6 : 0)
+
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
NO_REGS is returned. */
-#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
- secondary_reload_class (CLASS, MODE, IN)
+#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \
+ secondary_reload_class (CLASS, MODE, IN, 1)
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \
+ secondary_reload_class (CLASS, MODE, IN, 0)
/* If we are copying between FP or AltiVec registers and anything
else, we need a memory location. */
@@ -1344,11 +1511,14 @@ enum reg_class
/* Return a class of registers that cannot change FROM mode to TO mode. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \
- : (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1 \
- ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) \
+ && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8) \
+ ? 0 \
+ : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \
+ : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \
+ ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
: 0)
/* Stack layout; function entry, exit and calling. */
@@ -1357,60 +1527,19 @@ enum reg_class
enum rs6000_abi {
ABI_NONE,
ABI_AIX, /* IBM's AIX */
- ABI_AIX_NODESC, /* AIX calling sequence minus
- function descriptors */
ABI_V4, /* System V.4/eabi */
ABI_DARWIN /* Apple's Darwin (OS X kernel) */
};
extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
-/* Structure used to define the rs6000 stack */
-typedef struct rs6000_stack {
- int first_gp_reg_save; /* first callee saved GP register used */
- int first_fp_reg_save; /* first callee saved FP register used */
- int first_altivec_reg_save; /* first callee saved AltiVec register used */
- int lr_save_p; /* true if the link reg needs to be saved */
- int cr_save_p; /* true if the CR reg needs to be saved */
- unsigned int vrsave_mask; /* mask of vec registers to save */
- int toc_save_p; /* true if the TOC needs to be saved */
- int push_p; /* true if we need to allocate stack space */
- int calls_p; /* true if the function makes any calls */
- enum rs6000_abi abi; /* which ABI to use */
- int gp_save_offset; /* offset to save GP regs from initial SP */
- int fp_save_offset; /* offset to save FP regs from initial SP */
- int altivec_save_offset; /* offset to save AltiVec regs from inital SP */
- int lr_save_offset; /* offset to save LR from initial SP */
- int cr_save_offset; /* offset to save CR from initial SP */
- int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
- int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
- int toc_save_offset; /* offset to save the TOC pointer */
- int varargs_save_offset; /* offset to save the varargs registers */
- int ehrd_offset; /* offset to EH return data */
- int reg_size; /* register size (4 or 8) */
- int varargs_size; /* size to hold V.4 args passed in regs */
- int vars_size; /* variable save area size */
- int parm_size; /* outgoing parameter size */
- int save_size; /* save area size */
- int fixed_size; /* fixed size of stack frame */
- int gp_size; /* size of saved GP registers */
- int fp_size; /* size of saved FP registers */
- int altivec_size; /* size of saved AltiVec registers */
- int cr_size; /* size to hold CR if not in save_size */
- int lr_size; /* size to hold LR if not in save_size */
- int vrsave_size; /* size to hold VRSAVE if not in save_size */
- int altivec_padding_size; /* size of altivec alignment padding if
- not in save_size */
- int spe_gp_size; /* size of 64-bit GPR save size for SPE */
- int spe_padding_size;
- int toc_size; /* size to hold TOC if not in save_size */
- int total_size; /* total bytes allocated for stack */
-} rs6000_stack_t;
-
/* Define this if pushing a word on the stack
makes the stack pointer a smaller address. */
#define STACK_GROWS_DOWNWARD
+/* Offsets recorded in opcodes are a multiple of this alignment factor. */
+#define DWARF_CIE_DATA_ALIGNMENT (-((int) (TARGET_32BIT ? 4 : 8)))
+
/* Define this if the nominal address of the stack frame
is at the high-address end of the local variables;
that is, each additional local variable allocated
@@ -1422,14 +1551,13 @@ typedef struct rs6000_stack {
/* Size of the outgoing register save area */
#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_AIX_NODESC \
|| DEFAULT_ABI == ABI_DARWIN) \
? (TARGET_64BIT ? 64 : 32) \
: 0)
/* Size of the fixed area on the stack */
#define RS6000_SAVE_AREA \
- (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \
+ (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \
<< (TARGET_64BIT ? 1 : 0))
/* MEM representing address to save the TOC register */
@@ -1519,57 +1647,14 @@ typedef struct rs6000_stack {
/* Define how to find the value returned by a function.
VALTYPE is the data type of the value (as a tree).
If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0.
-
- On the SPE, both FPs and vectors are returned in r3.
-
- On RS/6000 an integer value is in r3 and a floating-point value is in
- fp1, unless -msoft-float. */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- || POINTER_TYPE_P (VALTYPE) \
- ? word_mode : TYPE_MODE (VALTYPE), \
- TREE_CODE (VALTYPE) == VECTOR_TYPE \
- && TARGET_ALTIVEC ? ALTIVEC_ARG_RETURN \
- : TREE_CODE (VALTYPE) == REAL_TYPE \
- && TARGET_SPE_ABI && !TARGET_FPRS \
- ? GP_ARG_RETURN \
- : TREE_CODE (VALTYPE) == REAL_TYPE \
- && TARGET_HARD_FLOAT && TARGET_FPRS \
- ? FP_ARG_RETURN : GP_ARG_RETURN)
+ otherwise, FUNC is 0. */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) rs6000_function_value ((VALTYPE), (FUNC))
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN \
- : GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && TARGET_HARD_FLOAT && TARGET_FPRS \
- ? FP_ARG_RETURN : GP_ARG_RETURN)
-
-/* The AIX ABI for the RS/6000 specifies that all structures are
- returned in memory. The Darwin ABI does the same. The SVR4 ABI
- specifies that structures <= 8 bytes are returned in r3/r4, but a
- draft put them in memory, and GCC used to implement the draft
- instead of the final standard. Therefore, TARGET_AIX_STRUCT_RET
- controls this instead of DEFAULT_ABI; V.4 targets needing backward
- compatibility can change DRAFT_V4_STRUCT_RET to override the
- default, and -m switches get the final word. See
- rs6000_override_options for more details.
-
- The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
- long double support is enabled. These values are returned in memory.
-
- int_size_in_bytes returns -1 for variable size objects, which go in
- memory always. The cast to unsigned makes -1 > 8. */
-
-#define RETURN_IN_MEMORY(TYPE) \
- ((AGGREGATE_TYPE_P (TYPE) \
- && (TARGET_AIX_STRUCT_RET \
- || (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 8)) \
- || (DEFAULT_ABI == ABI_V4 && TYPE_MODE (TYPE) == TFmode))
+#define LIBCALL_VALUE(MODE) rs6000_libcall_value ((MODE))
/* DRAFT_V4_STRUCT_RET defaults off. */
#define DRAFT_V4_STRUCT_RET 0
@@ -1595,7 +1680,6 @@ typedef struct rs6000_stack {
#define FP_ARG_AIX_MAX_REG 45
#define FP_ARG_V4_MAX_REG 40
#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_AIX_NODESC \
|| DEFAULT_ABI == ABI_DARWIN) \
? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
@@ -1625,7 +1709,7 @@ typedef struct rs6000_stack {
#define FUNCTION_VALUE_REGNO_P(N) \
((N) == GP_ARG_RETURN \
|| ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT) \
- || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC))
+ || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI))
/* 1 if N is a possible register number for function argument passing.
On RS/6000, these are r3-r10 and fp1-fp13.
@@ -1633,7 +1717,7 @@ typedef struct rs6000_stack {
#define FUNCTION_ARG_REGNO_P(N) \
((unsigned) (N) - GP_ARG_MIN_REG < GP_ARG_NUM_REG \
|| ((unsigned) (N) - ALTIVEC_ARG_MIN_REG < ALTIVEC_ARG_NUM_REG \
- && TARGET_ALTIVEC) \
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI) \
|| ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG \
&& TARGET_HARD_FLOAT))
@@ -1645,6 +1729,12 @@ typedef struct machine_function GTY(())
int sysv_varargs_p;
/* Flags if __builtin_return_address (n) with n >= 1 was used. */
int ra_needs_full_frame;
+ /* Some local-dynamic symbol. */
+ const char *some_ld_name;
+ /* Whether the instruction chain has been scanned already. */
+ int insn_chain_scanned_p;
+ /* Flags if __builtin_return_address (0) was used. */
+ int ra_need_lr;
} machine_function;
/* Define a data type for recording info about an argument list
@@ -1659,7 +1749,7 @@ typedef struct machine_function GTY(())
have prototype types for.
For ABI_V4, we treat these slightly differently -- `sysv_gregno' is
- the next availible GP register, `fregno' is the next available FP
+ the next available GP register, `fregno' is the next available FP
register, and `words' is the number of words used on the stack.
The varargs/stdarg support requires that this structure's size
@@ -1671,37 +1761,29 @@ typedef struct rs6000_args
int fregno; /* next available FP register */
int vregno; /* next available AltiVec register */
int nargs_prototype; /* # args left in the current prototype */
- int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */
+ int stdarg; /* Whether function is a stdarg function. */
int call_cookie; /* Do special things for this call */
int sysv_gregno; /* next available GP register */
} CUMULATIVE_ARGS;
-/* Define intermediate macro to compute the size (in registers) of an argument
- for the RS/6000. */
-
-#define RS6000_ARG_SIZE(MODE, TYPE) \
-((MODE) != BLKmode \
- ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
- : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
-
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
- init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+ init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE, N_NAMED_ARGS)
/* Similar, but when scanning the definition of a procedure. We always
set NARGS_PROTOTYPE large so we never return an EXPR_LIST. */
-#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,LIBNAME) \
- init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE)
+#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
+ init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE, 1000)
/* Like INIT_CUMULATIVE_ARGS' but only used for outgoing libcalls. */
#define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
- init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE)
+ init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, 0)
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
@@ -1710,18 +1792,6 @@ typedef struct rs6000_args
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
function_arg_advance (&CUM, MODE, TYPE, NAMED)
-/* Nonzero if we can use a floating-point register to pass this arg. */
-#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
- (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && (CUM).fregno <= FP_ARG_MAX_REG \
- && TARGET_HARD_FLOAT && TARGET_FPRS)
-
-/* Nonzero if we can use an AltiVec register to pass this arg. */
-#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE) \
- (ALTIVEC_VECTOR_MODE (MODE) \
- && (CUM).vregno <= ALTIVEC_ARG_MAX_REG \
- && TARGET_ALTIVEC_ABI)
-
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -1778,27 +1848,6 @@ typedef struct rs6000_args
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
function_arg_boundary (MODE, TYPE)
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as above.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed. */
-
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
- setup_incoming_varargs (&CUM, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
-
-/* Define the `__builtin_va_list' type for the ABI. */
-#define BUILD_VA_LIST_TYPE(VALIST) \
- (VALIST) = rs6000_build_va_list ()
-
/* Implement `va_start' for varargs and stdarg. */
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
rs6000_va_start (valist, nextarg)
@@ -1807,22 +1856,13 @@ typedef struct rs6000_args
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
rs6000_va_arg (valist, type)
-/* For AIX, the rule is that structures are passed left-aligned in
- their stack slot. However, GCC does not presently do this:
- structures which are the same size as integer types are passed
- right-aligned, as if they were in fact integers. This only
- matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
- ABI_V4 does not use std_expand_builtin_va_arg. */
-#define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
+#define PAD_VARARGS_DOWN \
+ (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
/* Define this macro to be a nonzero value if the location where a function
argument is passed depends on whether or not it is a named argument. */
#define STRICT_ARGUMENT_NAMING 1
-/* We do not allow indirect calls to be optimized into sibling calls, nor
- do we allow calls with vector parameters. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) function_ok_for_sibcall ((DECL))
-
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
@@ -1878,8 +1918,7 @@ typedef struct rs6000_args
abi's store the return address. */
#define RETURN_ADDRESS_OFFSET \
((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_DARWIN \
- || DEFAULT_ABI == ABI_AIX_NODESC) ? (TARGET_32BIT ? 8 : 16) : \
+ || DEFAULT_ABI == ABI_DARWIN) ? (TARGET_32BIT ? 8 : 16) : \
(DEFAULT_ABI == ABI_V4) ? 4 : \
(internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0))
@@ -1930,27 +1969,11 @@ typedef struct rs6000_args
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-{ \
- rs6000_stack_t *info = rs6000_stack_info (); \
- \
- if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
- (OFFSET) = (info->push_p) ? 0 : - info->total_size; \
- else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \
- (OFFSET) = info->total_size; \
- else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
- (OFFSET) = (info->push_p) ? info->total_size : 0; \
- else if ((FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM) \
- (OFFSET) = 0; \
- else \
- abort (); \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ ((OFFSET) = rs6000_initial_elimination_offset(FROM, TO))
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
#define HAVE_PRE_DECREMENT 1
#define HAVE_PRE_INCREMENT 1
@@ -1993,9 +2016,13 @@ typedef struct rs6000_args
acceptable. */
#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode \
- || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \
- || easy_fp_constant (X, GET_MODE (X)))
+ (((GET_CODE (X) != CONST_DOUBLE \
+ && GET_CODE (X) != CONST_VECTOR) \
+ || GET_MODE (X) == VOIDmode \
+ || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \
+ || easy_fp_constant (X, GET_MODE (X)) \
+ || easy_vector_constant (X, GET_MODE (X))) \
+ && !rs6000_tls_referenced_p (X))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@@ -2042,7 +2069,7 @@ typedef struct rs6000_args
refers to a constant pool entry of an address (or the sum of it
plus a constant), a short (16-bit signed) constant plus a register,
the sum of two registers, or a register indirect, possibly with an
- auto-increment. For DFmode and DImode with an constant plus register,
+ auto-increment. For DFmode and DImode with a constant plus register,
we must ensure that both words are addressable or PowerPC64 with offset
word aligned.
@@ -2051,73 +2078,6 @@ typedef struct rs6000_args
adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */
-#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X))
-
-#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
-
-/* SPE offset addressing is limited to 5-bits worth of double words. */
-#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
-
-#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \
- (TARGET_TOC \
- && GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER) \
- && CONSTANT_POOL_EXPR_P (XEXP (X, 1)))
-
-#define LEGITIMATE_SMALL_DATA_P(MODE, X) \
- (DEFAULT_ABI == ABI_V4 \
- && !flag_pic && !TARGET_TOC \
- && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST) \
- && small_data_operand (X, MODE))
-
-#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET) \
- (GET_CODE (X) == CONST_INT \
- && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
-
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT) \
- (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
- && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
- && (! ALTIVEC_VECTOR_MODE (MODE) \
- || (GET_CODE (XEXP (X,1)) == CONST_INT && INTVAL (XEXP (X,1)) == 0)) \
- && (! SPE_VECTOR_MODE (MODE) \
- || (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && SPE_CONST_OFFSET_OK (INTVAL (XEXP (X, 1))))) \
- && (((MODE) != DFmode && (MODE) != DImode) \
- || (TARGET_32BIT \
- ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
- : ! (INTVAL (XEXP (X, 1)) & 3))) \
- && (((MODE) != TFmode && (MODE) != TImode) \
- || (TARGET_32BIT \
- ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
- : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
- && ! (INTVAL (XEXP (X, 1)) & 3)))))
-
-#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT) \
- (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == REG \
- && ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
- && INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT))) \
- || (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
- && INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
-
-#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT) \
- (GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
-
-#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT) \
- (TARGET_ELF \
- && ! flag_pic && ! TARGET_TOC \
- && GET_MODE_NUNITS (MODE) == 1 \
- && (GET_MODE_BITSIZE (MODE) <= 32 \
- || (TARGET_HARD_FLOAT && TARGET_FPRS && (MODE) == DFmode)) \
- && GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == REG \
- && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
- && CONSTANT_P (XEXP (X, 1)))
-
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
goto ADDR; \
@@ -2172,27 +2132,13 @@ do { \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
- has an effect that depends on the machine mode it is used for.
-
- On the RS/6000 this is true if the address is valid with a zero offset
- but not with an offset of four (this means it cannot be used as an
- address for DImode or DFmode) or is a pre-increment or decrement. Since
- we know it is valid, we just check for an address that is not valid with
- an offset of four. */
+ has an effect that depends on the machine mode it is used for. */
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
-{ if (GET_CODE (ADDR) == PLUS \
- && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), 0) \
- && ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), \
- (TARGET_32BIT ? 4 : 8))) \
+do { \
+ if (rs6000_mode_dependent_address (ADDR)) \
goto LABEL; \
- if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_INC) \
- goto LABEL; \
- if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_DEC) \
- goto LABEL; \
- if (GET_CODE (ADDR) == LO_SUM) \
- goto LABEL; \
-}
+} while (0)
/* The register number of the register used to address a table of
static data addresses in memory. In some cases this register is
@@ -2239,14 +2185,6 @@ do { \
generating position independent code. */
/* #define LEGITIMATE_PIC_OPERAND_P (X) */
-
-/* In rare cases, correct code generation requires extra machine
- dependent processing between the second jump optimization pass and
- delayed branch scheduling. On those machines, define this macro
- as a C statement to act on the code starting at INSN. */
-
-/* #define MACHINE_DEPENDENT_REORG(INSN) */
-
/* Define this if some processing needs to be done immediately before
emitting code for an insn. */
@@ -2298,14 +2236,24 @@ do { \
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+/* The cntlzw and cntlzd instructions return 32 and 64 for input of zero. */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
+ ((VALUE) = ((MODE) == SImode ? 32 : 64))
+
+/* The CTZ patterns return -1 for input of zero. */
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1)
+
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
#define Pmode (TARGET_32BIT ? SImode : DImode)
+/* Supply definition of STACK_SIZE_MODE for allocate_dynamic_stack_space. */
+#define STACK_SIZE_MODE (TARGET_32BIT ? SImode : DImode)
+
/* Mode of a function address in a call instruction (for indexing purposes).
Doesn't matter on RS/6000. */
-#define FUNCTION_MODE (TARGET_32BIT ? SImode : DImode)
+#define FUNCTION_MODE SImode
/* Define this if addresses of constant functions
shouldn't be put through pseudo regs where they can be cse'd.
@@ -2321,155 +2269,6 @@ do { \
#define SHIFT_COUNT_TRUNCATED (TARGET_POWER ? 1 : 0)
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- On the RS/6000, if it is valid in the insn, it is free. So this
- always returns 0. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- case HIGH: \
- return 0;
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case PLUS: \
- return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) \
- + 0x8000) >= 0x10000) \
- && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \
- ? COSTS_N_INSNS (2) \
- : COSTS_N_INSNS (1)); \
- case AND: \
- case IOR: \
- case XOR: \
- return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0 \
- && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \
- ? COSTS_N_INSNS (2) \
- : COSTS_N_INSNS (1)); \
- case MULT: \
- if (optimize_size) \
- return COSTS_N_INSNS (2); \
- switch (rs6000_cpu) \
- { \
- case PROCESSOR_RIOS1: \
- case PROCESSOR_PPC405: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (5) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
- case PROCESSOR_RS64A: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12)); \
- case PROCESSOR_RIOS2: \
- case PROCESSOR_MPCCORE: \
- case PROCESSOR_PPC604e: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_PPC601: \
- return COSTS_N_INSNS (5); \
- case PROCESSOR_PPC603: \
- case PROCESSOR_PPC7400: \
- case PROCESSOR_PPC750: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (5) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \
- case PROCESSOR_PPC7450: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (4) \
- : COSTS_N_INSNS (3)); \
- case PROCESSOR_PPC403: \
- case PROCESSOR_PPC604: \
- case PROCESSOR_PPC8540: \
- return COSTS_N_INSNS (4); \
- case PROCESSOR_PPC620: \
- case PROCESSOR_PPC630: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
- case PROCESSOR_POWER4: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4) \
- : COSTS_N_INSNS (2)); \
- } \
- case DIV: \
- case MOD: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \
- return COSTS_N_INSNS (2); \
- /* otherwise fall through to normal divide. */ \
- case UDIV: \
- case UMOD: \
- switch (rs6000_cpu) \
- { \
- case PROCESSOR_RIOS1: \
- return COSTS_N_INSNS (19); \
- case PROCESSOR_RIOS2: \
- return COSTS_N_INSNS (13); \
- case PROCESSOR_RS64A: \
- return (GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (65) \
- : COSTS_N_INSNS (67)); \
- case PROCESSOR_MPCCORE: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_PPC403: \
- return COSTS_N_INSNS (33); \
- case PROCESSOR_PPC405: \
- return COSTS_N_INSNS (35); \
- case PROCESSOR_PPC601: \
- return COSTS_N_INSNS (36); \
- case PROCESSOR_PPC603: \
- return COSTS_N_INSNS (37); \
- case PROCESSOR_PPC604: \
- case PROCESSOR_PPC604e: \
- return COSTS_N_INSNS (20); \
- case PROCESSOR_PPC620: \
- case PROCESSOR_PPC630: \
- case PROCESSOR_POWER4: \
- return (GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (21) \
- : COSTS_N_INSNS (37)); \
- case PROCESSOR_PPC750: \
- case PROCESSOR_PPC8540: \
- case PROCESSOR_PPC7400: \
- return COSTS_N_INSNS (19); \
- case PROCESSOR_PPC7450: \
- return COSTS_N_INSNS (23); \
- } \
- case FFS: \
- return COSTS_N_INSNS (4); \
- case MEM: \
- /* MEM should be slightly more expensive than (plus (reg) (const)) */ \
- return 5;
-
-/* Compute the cost of an address. This is meant to approximate the size
- and/or execution delay of an insn using that address. If the cost is
- approximated by the RTL complexity, including CONST_COSTS above, as
- is usually the case for CISC machines, this macro should not be defined.
- For aggressively RISCy machines, only one insn format is allowed, so
- this macro should be a constant. The value of this macro only matters
- for valid addresses.
-
- For the RS/6000, everything is cost 0. */
-
-#define ADDRESS_COST(RTX) 0
-
/* Adjust the length of an INSN. LENGTH is the currently-computed length and
should be adjusted to reflect any required changes. This macro is used when
there is some systematic length adjustment required that would be difficult
@@ -2490,9 +2289,16 @@ do { \
: (((OP) == EQ || (OP) == NE) && GET_RTX_CLASS (GET_CODE (X)) == '<' \
? CCEQmode : CCmode))
+/* Can the condition code MODE be safely reversed? This is safe in
+ all cases on this port, because at present it doesn't use the
+ trapping FP comparisons (fcmpo). */
+#define REVERSIBLE_CC_MODE(MODE) 1
+
+/* Given a condition code and a mode, return the inverse condition. */
+#define REVERSE_CONDITION(CODE, MODE) rs6000_reverse_condition (MODE, CODE)
+
/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
+ stored from the compare operation. */
extern GTY(()) rtx rs6000_compare_op0;
extern GTY(()) rtx rs6000_compare_op1;
@@ -2599,6 +2405,8 @@ extern int toc_initialized;
} \
while (0)
+#define TARGET_ASM_FILE_START rs6000_file_start
+
/* Output to assembler file text saying following lines
may contain character constants, extra white space, comments, etc. */
@@ -2736,31 +2544,6 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
&rs6000_reg_names[112][0], /* spefscr */ \
}
-/* print-rtl can't handle the above REGISTER_NAMES, so define the
- following for it. Switch to use the alternate names since
- they are more mnemonic. */
-
-#define DEBUG_REGISTER_NAMES \
-{ \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
- "mq", "lr", "ctr", "ap", \
- "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "xer", \
- "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
- "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
- "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
- "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", \
- "vrsave", "vscr", \
- "spe_acc", "spefscr" \
-}
-
/* Table of additional register names to use in user input. */
#define ADDITIONAL_REGISTER_NAMES \
@@ -2820,14 +2603,6 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
if ((LOG) != 0) \
fprintf (FILE, "\t.align %d\n", (LOG))
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
/* Pick up the return address upon entry to a procedure. Used for
dwarf2 unwind information. This also enables the table driven
mechanism. */
@@ -2848,7 +2623,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
/* Define which CODE values are valid. */
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
- ((CODE) == '.')
+ ((CODE) == '.' || (CODE) == '&')
/* Print a memory address as an operand to reference that memory location. */
@@ -2880,11 +2655,15 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \
{"easy_fp_constant", {CONST_DOUBLE}}, \
+ {"easy_vector_constant", {CONST_VECTOR}}, \
+ {"easy_vector_constant_add_self", {CONST_VECTOR}}, \
{"zero_fp_constant", {CONST_DOUBLE}}, \
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"lwa_operand", {SUBREG, MEM, REG}}, \
{"volatile_mem_operand", {MEM}}, \
{"offsettable_mem_operand", {MEM}}, \
+ {"invalid_gpr_mem", {MEM}}, \
+ {"base_reg_operand", {REG}}, \
{"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \
{"add_operand", {SUBREG, REG, CONST_INT}}, \
{"non_add_cint_operand", {CONST_INT}}, \
@@ -2900,6 +2679,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"count_register_operand", {REG}}, \
{"xer_operand", {REG}}, \
{"symbol_ref_operand", {SYMBOL_REF}}, \
+ {"rs6000_tls_symbol_ref", {SYMBOL_REF}}, \
{"call_operand", {SYMBOL_REF, REG}}, \
{"current_file_function_operand", {SYMBOL_REF}}, \
{"input_operand", {SUBREG, MEM, REG, CONST_INT, \
diff --git a/contrib/gcc/config/rs6000/rs6000.md b/contrib/gcc/config/rs6000/rs6000.md
index 4d5ef9d..0fc4c04 100644
--- a/contrib/gcc/config/rs6000/rs6000.md
+++ b/contrib/gcc/config/rs6000/rs6000.md
@@ -1,45 +1,70 @@
;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
-;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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 2, or (at your option)
-;; any later version.
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, or (at your
+;; option) any later version.
-;; GNU CC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-;; `unspec' values used in rs6000.md:
-;; Number Use
-;; 0 frsp for POWER machines
-;; 0/v blockage
-;; 5 used to tie the stack contents and the stack pointer
-;; 6 address of a word pointing to the TOC
-;; 7 address of the TOC (more-or-less)
-;; 8 movsi_got
-;; 9/v eh_reg_restore
-;; 10 fctiwz
-;; 15 load_macho_picbase
-;; 16 macho_correct_pic
-;; 19 movesi_from_cr
-;; 20 movesi_to_cr
+;;
+;; UNSPEC usage
+;;
+
+(define_constants
+ [(UNSPEC_FRSP 0) ; frsp for POWER machines
+ (UNSPEC_TIE 5) ; tie stack contents and stack pointer
+ (UNSPEC_TOCPTR 6) ; address of a word pointing to the TOC
+ (UNSPEC_TOC 7) ; address of the TOC (more-or-less)
+ (UNSPEC_MOVSI_GOT 8)
+ (UNSPEC_MV_CR_OV 9) ; move_from_CR_ov_bit
+ (UNSPEC_FCTIWZ 10)
+ (UNSPEC_LD_MPIC 15) ; load_macho_picbase
+ (UNSPEC_MPIC_CORRECT 16) ; macho_correct_pic
+ (UNSPEC_TLSGD 17)
+ (UNSPEC_TLSLD 18)
+ (UNSPEC_MOVESI_FROM_CR 19)
+ (UNSPEC_MOVESI_TO_CR 20)
+ (UNSPEC_TLSDTPREL 21)
+ (UNSPEC_TLSDTPRELHA 22)
+ (UNSPEC_TLSDTPRELLO 23)
+ (UNSPEC_TLSGOTDTPREL 24)
+ (UNSPEC_TLSTPREL 25)
+ (UNSPEC_TLSTPRELHA 26)
+ (UNSPEC_TLSTPRELLO 27)
+ (UNSPEC_TLSGOTTPREL 28)
+ (UNSPEC_TLSTLS 29)
+ (UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero
+ (UNSPEC_MV_CR_GT 31) ; move_from_CR_gt_bit
+ ])
+
+;;
+;; UNSPEC_VOLATILE usage
+;;
+
+(define_constants
+ [(UNSPECV_BLOCK 0)
+ (UNSPECV_EH_RR 9) ; eh_reg_restore
+ ])
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "integer,load,store,fpload,fpstore,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,vecsimple,veccomplex,veccmp,vecperm,vecfloat,altivec"
+(define_attr "type" "integer,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv"
(const_string "integer"))
;; Length (in bytes).
@@ -58,800 +83,24 @@
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5"
(const (symbol_ref "rs6000_cpu_attr")))
-; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
-; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
-
-; Load/Store Unit -- pure PowerPC only
-; (POWER and 601 use Integer Unit)
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "rs64a,mpccore,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "load,vecload")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rs64a,mpccore,ppc603,ppc604,ppc604e,ppc620,ppc630"))
- 1 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,vecstore")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpstore")
- (eq_attr "cpu" "ppc7450"))
- 3 3)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "mpccore,ppc603,ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "ppc7450"))
- 4 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "rs64a,ppc604,ppc604e,ppc620,ppc630"))
- 3 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "rios1,ppc403,ppc405,ppc601"))
- 2 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rios1,ppc403,ppc405,ppc601"))
- 1 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpstore")
- (eq_attr "cpu" "rios1,ppc601"))
- 0 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "rios1"))
- 2 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "ppc601"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "load,fpload")
- (eq_attr "cpu" "rios2"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rios2"))
- 1 1)
-
-; Integer Unit (RIOS1, PPC601, PPC603, RS64a)
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "rios1,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
- 1 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "mpccore,ppc403,ppc405,ppc601"))
- 1 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc403"))
- 4 4)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc405"))
- 4 3)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "ppc405"))
- 3 2)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "rios1"))
- 5 5)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "rios1"))
- 4 4)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "rios1"))
- 3 3)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc601,ppc603"))
- 5 5)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "rs64a"))
- 20 20)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "rs64a"))
- 12 12)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "rs64a"))
- 8 8)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "rs64a"))
- 34 34)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios1"))
- 19 19)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rs64a"))
- 66 66)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "rs64a"))
- 66 66)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc403"))
- 33 33)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc405"))
- 35 35)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc601"))
- 36 36)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc603"))
- 37 36)
-
-; RIOS2 has two integer units: a primary one which can perform all
-; operations and a secondary one which is fed in lock step with the first
-; and can perform "simple" integer operations.
-; To catch this we define a 'dummy' imuldiv-unit that is also needed
-; for the complex insns.
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "rios2"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "rios2"))
- 2 2)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios2"))
- 13 13)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "rios2"))
- 2 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios2"))
- 13 13)
-
-; MPCCORE has separate IMUL/IDIV unit for multicycle instructions
-; Divide latency varies greatly from 2-11, use 6 as average
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "mpccore"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "mpccore"))
- 6 6)
-
-; PPC604{,e} has two units that perform integer operations
-; and one unit for divide/multiply operations (and move
-; from/to spr).
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
- 1 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc604"))
- 4 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc604e"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc620,ppc630"))
- 5 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc620,ppc630"))
- 4 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc620,ppc630"))
- 3 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "ppc620,ppc630"))
- 7 5)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc604,ppc604e"))
- 20 19)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc620"))
- 37 36)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc630"))
- 21 20)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "ppc620,ppc630"))
- 37 36)
-
-; PPC7450 has 3 integer units (for most integer insns) and one mul/div
-; unit, which also does CR-logical insns and move to/from SPR.
-; It also has 4 vector units, one for each type of vector instruction.
-; However, we can only dispatch 2 instructions per cycle.
-; We model this as saying that dispatching two of the same type of instruction
-; in a row incurs a single cycle delay.
-(define_function_unit "iu3" 3 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc7450"))
- 4 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc7450"))
- 23 23)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecsimple")
- (eq_attr "cpu" "ppc7450"))
- 1 2 [(eq_attr "type" "vecsimple")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecsimple")
- (eq_attr "cpu" "ppc7450"))
- 1 1 [(eq_attr "type" "!vecsimple")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccomplex")
- (eq_attr "cpu" "ppc7450"))
- 4 2 [(eq_attr "type" "veccomplex")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccomplex")
- (eq_attr "cpu" "ppc7450"))
- 4 1 [(eq_attr "type" "!veccomplex")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccmp")
- (eq_attr "cpu" "ppc7450"))
- 2 2 [(eq_attr "type" "veccmp")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccmp")
- (eq_attr "cpu" "ppc7450"))
- 2 1 [(eq_attr "type" "!veccmp")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecfloat")
- (eq_attr "cpu" "ppc7450"))
- 4 2 [(eq_attr "type" "vecfloat")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecfloat")
- (eq_attr "cpu" "ppc7450"))
- 4 1 [(eq_attr "type" "!vecfloat")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecperm")
- (eq_attr "cpu" "ppc7450"))
- 2 2 [(eq_attr "type" "vecperm")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecperm")
- (eq_attr "cpu" "ppc7450"))
- 2 1 [(eq_attr "type" "!vecperm")])
-
-; PPC750 has two integer units: a primary one which can perform all
-; operations and a secondary one which is fed in lock step with the first
-; and can perform "simple" integer operations.
-; To catch this we define a 'dummy' imuldiv-unit that is also needed
-; for the complex insns.
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 4 4)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 3 2)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 19 19)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 4 4)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 3 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 19 19)
-
-; CR-logical operations are execute-serialized, that is they don't
-; start (and block the function unit) until all preceding operations
-; have finished. They don't block dispatch of other insns, though.
-; I've imitated this by giving them longer latency.
-(define_function_unit "sru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc603,ppc750,ppc7400"))
- 3 2)
-
-; compare is done on integer unit, but feeds insns which
-; execute on the branch unit.
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "compare")
- (eq_attr "cpu" "rios1"))
- 4 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "delayed_compare")
- (eq_attr "cpu" "rios1"))
- 5 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
- 3 1)
-
-; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
-; and a following branch, to reduce mispredicts
-(define_function_unit "iu3" 3 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "rios2"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400"))
- 1 1)
-
-; fp compare uses fp unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rios1"))
- 9 1)
-
-; rios1 and rios2 have different fpcompare delays
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rios2,ppc630"))
- 5 1)
-
-; on ppc601 and ppc603, fpcompare takes also 2 cycles from
-; the integer unit
-; here we do not define delays, just occupy the unit. The dependencies
-; will be assigned by the fpcompare definition in the fpu.
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "ppc601,ppc603"))
- 0 2)
-
-; fp compare uses fp unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rs64a,ppc601,ppc603,ppc604,ppc604e,ppc620"))
- 5 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "ppc750,ppc7400,ppc7450"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "mpccore"))
- 1 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "rios1,rios2,rs64a"))
- 5 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630"))
- 4 1)
-
-(define_function_unit "sru" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "ppc7450"))
- 2 2)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "rios1,rios2,ppc604"))
- 4 1)
-
-(define_function_unit "cru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc604e,ppc620,ppc630,rs64a"))
- 1 1)
-
-; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
-(define_function_unit "bpu" 1 0
- (eq_attr "type" "jmpreg")
- 1 1)
-
-(define_function_unit "bpu" 1 0
- (eq_attr "type" "branch")
- 1 1)
-
-; Floating Point Unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "rios1"))
- 2 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "rs64a,mpccore"))
- 4 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc601"))
- 4 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620,ppc750,ppc7400"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "ppc7450"))
- 5 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "rs64a"))
- 7 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "mpccore"))
- 5 5)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc601"))
- 5 2)
-
-; is this true?
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc603,ppc750"))
- 4 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc7400"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "rios1"))
- 19 19)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "rs64a"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc601,ppc750,ppc7400"))
- 17 17)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc7450"))
- 21 21)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "mpccore"))
- 10 10)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620"))
- 18 18)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "mpccore"))
- 17 17)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "rs64a,ppc601,ppc750,ppc604,ppc604e,ppc620,ppc7400"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc7450"))
- 35 35)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc603"))
- 33 33)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ssqrt")
- (eq_attr "cpu" "ppc620"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "ppc620"))
- 31 31)
-
-; RIOS2 has two symmetric FPUs.
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "rios2"))
- 2 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "ppc630"))
- 3 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "rios2"))
- 17 17)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc630"))
- 17 17)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc630"))
- 21 21)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt,dsqrt")
- (eq_attr "cpu" "rios2"))
- 26 26)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt")
- (eq_attr "cpu" "ppc630"))
- 18 18)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "ppc630"))
- 26 26)
-
-;; Power4
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "power4"))
- 5 1)
-
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "power4"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "power4"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "power4"))
- 7 6)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "power4"))
- 5 4)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "power4"))
- 4 3)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "power4"))
- 36 35)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "power4"))
- 68 67)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "power4"))
- 36 35)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "power4"))
- 68 67)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "delayed_compare")
- (eq_attr "cpu" "power4"))
- 4 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "jmpreg,branch")
- (eq_attr "cpu" "power4"))
- 2 1)
-
-(define_function_unit "cru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "power4"))
- 4 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "power4"))
- 6 1)
-
-; adjust_cost increases the cost of dependent branches,
-; so shave a few cycles off for fpcompare.
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "power4"))
- 5 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "power4"))
- 33 28)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt,dsqrt")
- (eq_attr "cpu" "power4"))
- 40 35)
+(automata_option "ndfa")
+
+(include "rios1.md")
+(include "rios2.md")
+(include "rs64.md")
+(include "mpc.md")
+(include "40x.md")
+(include "440.md")
+(include "603.md")
+(include "6xx.md")
+(include "7xx.md")
+(include "7450.md")
+(include "8540.md")
+(include "power4.md")
+(include "power5.md")
;; Start with fixed-point load and store insns. Here we put only the more
@@ -877,7 +126,7 @@
(compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %2,%1,0,56
#"
@@ -903,7 +152,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %0,%1,0,56
#"
@@ -935,7 +184,7 @@
(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsb. %2,%1
#"
@@ -961,7 +210,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsb. %0,%1
#"
@@ -1002,7 +251,7 @@
(compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %2,%1,0,48
#"
@@ -1028,7 +277,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %0,%1,0,48
#"
@@ -1062,14 +311,14 @@
"@
lha%U1%X1 %0,%1
extsh %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsh. %2,%1
#"
@@ -1095,7 +344,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsh. %0,%1
#"
@@ -1136,7 +385,7 @@
(compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %2,%1,0,32
#"
@@ -1162,7 +411,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %0,%1,0,32
#"
@@ -1196,14 +445,14 @@
"@
lwa%U1%X1 %0,%1
extsw %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsw. %2,%1
#"
@@ -1229,7 +478,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsw. %0,%1
#"
@@ -1664,7 +913,7 @@
"@
lha%U1%X1 %0,%1
{exts|extsh} %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -1774,13 +1023,13 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{cax.|add.} %3,%1,%2
{ai.|addic.} %3,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -1789,7 +1038,7 @@
(match_operand:SI 2 "reg_or_short_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(plus:SI (match_dup 1)
(match_dup 2)))
@@ -1806,13 +1055,13 @@
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(plus:SI (match_dup 1)
(match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{cax.|add.} %0,%1,%2
{ai.|addic.} %0,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -1822,7 +1071,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (match_dup 1)
(match_dup 2)))
@@ -1863,7 +1112,7 @@
(compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
nor. %2,%1,%1
#"
@@ -1875,7 +1124,7 @@
(compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 2)
(not:SI (match_dup 1)))
(set (match_dup 0)
@@ -1889,7 +1138,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(not:SI (match_dup 1)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
nor. %0,%1,%1
#"
@@ -1902,7 +1151,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(not:SI (match_dup 1)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(not:SI (match_dup 1)))
(set (match_dup 2)
@@ -1945,11 +1194,11 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "TARGET_POWERPC && ! TARGET_POWERPC64"
+ "TARGET_POWERPC && TARGET_32BIT"
"@
subf. %3,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -1958,7 +1207,7 @@
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(minus:SI (match_dup 1)
(match_dup 2)))
@@ -1989,11 +1238,11 @@
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(minus:SI (match_dup 1)
(match_dup 2)))]
- "TARGET_POWERPC && ! TARGET_POWERPC64"
+ "TARGET_POWERPC && TARGET_32BIT"
"@
subf. %0,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2004,7 +1253,7 @@
(set (match_operand:SI 0 "gpc_reg_operand" "")
(minus:SI (match_dup 1)
(match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(minus:SI (match_dup 1)
(match_dup 2)))
@@ -2260,7 +1509,7 @@
(define_insn_and_split "abssi2_isel"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(abs:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
- (clobber (match_scratch:SI 2 "=b"))
+ (clobber (match_scratch:SI 2 "=&b"))
(clobber (match_scratch:CC 3 "=y"))]
"TARGET_ISEL"
"#"
@@ -2317,11 +1566,11 @@
(compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
neg. %2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2329,7 +1578,7 @@
(compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 2)
(neg:SI (match_dup 1)))
(set (match_dup 0)
@@ -2343,11 +1592,11 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(neg:SI (match_dup 1)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
neg. %0,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2356,7 +1605,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(neg:SI (match_dup 1)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(neg:SI (match_dup 1)))
(set (match_dup 2)
@@ -2364,13 +1613,44 @@
(const_int 0)))]
"")
-(define_insn "ffssi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
- (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
+(define_insn "clzsi2"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (clz:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
""
- "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
- [(set_attr "length" "16")])
+ "{cntlz|cntlzw} %0,%1")
+(define_expand "ctzsi2"
+ [(set (match_dup 2)
+ (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:SI (match_dup 3)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (minus:SI (const_int 31) (match_dup 4)))]
+ ""
+ {
+ operands[2] = gen_reg_rtx (SImode);
+ operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_reg_rtx (SImode);
+ })
+
+(define_expand "ffssi2"
+ [(set (match_dup 2)
+ (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:SI (match_dup 3)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (minus:SI (const_int 32) (match_dup 4)))]
+ ""
+ {
+ operands[2] = gen_reg_rtx (SImode);
+ operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_reg_rtx (SImode);
+ })
+
(define_expand "mulsi3"
[(use (match_operand:SI 0 "gpc_reg_operand" ""))
(use (match_operand:SI 1 "gpc_reg_operand" ""))
@@ -2416,7 +1696,7 @@
(const_string "imul2")]
(const_string "imul")))])
-(define_insn ""
+(define_insn "*mulsi3_mq_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2427,7 +1707,7 @@
"@
{muls.|mullw.} %3,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2446,7 +1726,7 @@
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_no_mq_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2456,7 +1736,7 @@
"@
{muls.|mullw.} %3,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2473,7 +1753,7 @@
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_mq_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2485,7 +1765,7 @@
"@
{muls.|mullw.} %0,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2505,7 +1785,7 @@
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_no_mq_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2516,7 +1796,7 @@
"@
{muls.|mullw.} %0,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2542,7 +1822,7 @@
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
(div:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "")))
- (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (set (match_operand:SI 3 "register_operand" "")
(mod:SI (match_dup 1) (match_dup 2)))])]
"TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
"
@@ -2558,11 +1838,11 @@
}
}")
-(define_insn ""
+(define_insn "*divmodsi4_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "gpc_reg_operand" "r")))
- (set (match_operand:SI 3 "gpc_reg_operand" "=q")
+ (set (match_operand:SI 3 "register_operand" "=q")
(mod:SI (match_dup 1) (match_dup 2)))]
"TARGET_POWER"
"divs %0,%1,%2"
@@ -2948,7 +2228,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
and. %3,%1,%2
{andil.|andi.} %3,%1,%b2
@@ -2968,7 +2248,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
#
{andil.|andi.} %3,%1,%b2
@@ -3027,7 +2307,7 @@
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
and. %0,%1,%2
{andil.|andi.} %0,%1,%b2
@@ -3049,7 +2329,7 @@
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
#
{andil.|andi.} %0,%1,%b2
@@ -3239,7 +2519,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %3,%1,%2
#"
@@ -3253,7 +2533,7 @@
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
@@ -3268,7 +2548,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %0,%1,%2
#"
@@ -3283,14 +2563,14 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
-;; Split an logical operation that we can't do in one insn into two insns,
+;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
@@ -3327,7 +2607,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %3,%2,%1
#"
@@ -3341,7 +2621,7 @@
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
@@ -3356,7 +2636,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %0,%2,%1
#"
@@ -3371,7 +2651,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
@@ -3393,7 +2673,7 @@
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %3,%1,%2
#"
@@ -3407,7 +2687,7 @@
(not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
@@ -3422,7 +2702,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %0,%1,%2
#"
@@ -3437,7 +2717,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
@@ -3674,7 +2954,8 @@
operands[4] = GEN_INT (32 - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal1"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3692,7 +2973,8 @@
operands[4] = GEN_INT (shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal2"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3710,7 +2992,8 @@
operands[4] = GEN_INT (32 - shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal3"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3728,7 +3011,8 @@
operands[4] = GEN_INT (32 - shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal4"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3749,7 +3033,8 @@
operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
operands[1] = GEN_INT (insert_start + insert_size - 1);
return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "insvdi"
[(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
@@ -3941,7 +3226,7 @@
(match_operand:SI 3 "const_int_operand" "i"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"*
{
int start = INTVAL (operands[3]) & 63;
@@ -3963,7 +3248,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"*
{
int start = INTVAL (operands[3]) & 63;
@@ -4336,7 +3621,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
{sl|slw}%I2. %3,%1,%h2
#"
@@ -4349,7 +3634,7 @@
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(ashift:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
@@ -4398,7 +3683,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(ashift:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
{sl|slw}%I2. %0,%1,%h2
#"
@@ -4412,7 +3697,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(ashift:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(ashift:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -4569,7 +3854,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=X,r,X,r"))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
mr. %1,%1
{sr|srw}%I2. %3,%1,%h2
@@ -4584,7 +3869,7 @@
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(lshiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
@@ -4635,7 +3920,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
mr. %0,%1
{sr|srw}%I2. %0,%1,%h2
@@ -4651,7 +3936,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(lshiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -5109,7 +4394,7 @@
(define_insn "aux_truncdfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
- (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
+ (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
"! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
"frsp %0,%1"
[(set_attr "type" "fp")])
@@ -5678,9 +4963,9 @@
;; Conversions to and from floating-point.
-(define_expand "fixunssfsi2"
+(define_expand "fixuns_truncsfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
- (unsigned_fix:SI (fix:SF (match_operand:SF 1 "gpc_reg_operand" ""))))]
+ (unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"")
@@ -5728,8 +5013,8 @@
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:DF 4 "memory_operand" "=o"))
- (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))
- (clobber (match_operand:SI 6 "gpc_reg_operand" "=r"))]
+ (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
+ (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
[(set_attr "length" "24")])
@@ -5810,7 +5095,7 @@
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:DF 4 "memory_operand" "=o"))
- (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))]
+ (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
[(set_attr "length" "20")])
@@ -5895,13 +5180,14 @@
DONE;
}")
-; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] 10))
+; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
; rather than (set (subreg:SI (reg)) (fix:SI ...))
; because the first makes it clear that operand 0 is not live
; before the instruction.
(define_insn "fctiwz"
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
- (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))]
+ (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
+ UNSPEC_FCTIWZ))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
"{fcirz|fctiwz} %0,%1"
[(set_attr "type" "fp")])
@@ -5927,7 +5213,7 @@
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
- ""
+ "&& 1"
[(set (match_dup 3) (sign_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
@@ -5942,7 +5228,7 @@
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
- ""
+ "&& 1"
[(set (match_dup 3) (zero_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
@@ -5959,7 +5245,7 @@
(define_expand "floatdisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
- "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
"
{
if (!flag_unsafe_math_optimizations)
@@ -5989,7 +5275,7 @@
"")
;; Twiddles bits to avoid double rounding.
-;; Bits that might be trucated when converting to DFmode are replaced
+;; Bits that might be truncated when converting to DFmode are replaced
;; by a bit that won't be lost at that stage, but is below the SFmode
;; rounding position.
(define_expand "floatdisf2_internal2"
@@ -6010,7 +5296,7 @@
(pc)))
(set (match_dup 0) (xor:DI (match_dup 0) (match_dup 2)))
(set (match_dup 0) (ior:DI (match_dup 0) (const_int 2048)))]
- "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
"
{
operands[2] = gen_reg_rtx (DImode);
@@ -6350,11 +5636,26 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "M,i")))]
- "TARGET_32BIT && !TARGET_POWER"
+ "TARGET_32BIT && !TARGET_POWERPC64 && !TARGET_POWER && WORDS_BIG_ENDIAN"
"@
{srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
{sri|srwi} %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;{srai|srawi} %0,%1,%h2"
[(set_attr "length" "8,12")])
+
+(define_insn "*ashrdisi3_noppc64"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+ (const_int 32)) 4))]
+ "TARGET_32BIT && !TARGET_POWERPC64"
+ "*
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return \"\";
+ else
+ return \"mr %0,%1\";
+}"
+ [(set_attr "length" "4")])
+
;; PowerPC64 DImode operations.
@@ -6413,13 +5714,13 @@
(match_operand:DI 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
add. %3,%1,%2
addic. %3,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -6443,13 +5744,13 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
add. %0,%1,%2
addic. %0,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -6509,7 +5810,7 @@
(compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
nor. %2,%1,%1
#"
@@ -6535,7 +5836,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(not:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
nor. %0,%1,%1
#"
@@ -6571,11 +5872,11 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf. %3,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6599,11 +5900,11 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(minus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf. %0,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6677,11 +5978,11 @@
(compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
neg. %2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6703,11 +6004,11 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(neg:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
neg. %0,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6724,12 +6025,43 @@
(const_int 0)))]
"")
-(define_insn "ffsdi2"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
- (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
+(define_insn "clzdi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (clz:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64"
- "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
- [(set_attr "length" "16")])
+ "cntlzd %0,%1")
+
+(define_expand "ctzdi2"
+ [(set (match_dup 2)
+ (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:DI (match_dup 3)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (minus:DI (const_int 63) (match_dup 4)))]
+ "TARGET_POWERPC64"
+ {
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
+
+(define_expand "ffsdi2"
+ [(set (match_dup 2)
+ (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:DI (match_dup 3)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (minus:DI (const_int 64) (match_dup 4)))]
+ "TARGET_POWERPC64"
+ {
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
(define_insn "muldi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
@@ -6739,6 +6071,62 @@
"mulld %0,%1,%2"
[(set_attr "type" "lmul")])
+(define_insn "*muldi3_internal1"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 3 "=r,r"))]
+ "TARGET_POWERPC64"
+ "@
+ mulld. %3,%1,%2
+ #"
+ [(set_attr "type" "lmul_compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:DI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:DI 3 ""))]
+ "TARGET_POWERPC64 && reload_completed"
+ [(set (match_dup 3)
+ (mult:DI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
+
+(define_insn "*muldi3_internal2"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (mult:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "@
+ mulld. %0,%1,%2
+ #"
+ [(set_attr "type" "lmul_compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:DI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "")
+ (mult:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64 && reload_completed"
+ [(set (match_dup 0)
+ (mult:DI (match_dup 1) (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
+
(define_insn "smuldi3_highpart"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(truncate:DI
@@ -6817,7 +6205,7 @@
(match_operand:DI 2 "exact_log2_cint_operand" "N,N"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sradi %3,%1,%p2\;addze. %3,%3
#"
@@ -6845,7 +6233,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(div:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sradi %0,%1,%p2\;addze. %0,%0
#"
@@ -6896,7 +6284,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,0
#"
@@ -6924,7 +6312,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(rotate:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,0
#"
@@ -6962,7 +6350,7 @@
(match_operand:DI 3 "mask64_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2c%B3. %4,%1,%H2,%S3
#"
@@ -6996,7 +6384,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2c%B3. %0,%1,%H2,%S3
#"
@@ -7037,7 +6425,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,56
#"
@@ -7071,7 +6459,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,56
#"
@@ -7112,7 +6500,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,48
#"
@@ -7146,7 +6534,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,48
#"
@@ -7187,7 +6575,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,32
#"
@@ -7221,7 +6609,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,32
#"
@@ -7277,7 +6665,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sld%I2. %3,%1,%H2
#"
@@ -7305,7 +6693,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(ashift:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sld%I2. %0,%1,%H2
#"
@@ -7343,7 +6731,7 @@
(match_operand:DI 3 "const_int_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
- "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %4,%1,%H2,%W3
#"
@@ -7377,7 +6765,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %0,%1,%H2,%W3
#"
@@ -7419,7 +6807,7 @@
(match_operand:DI 3 "mask64_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
- "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
"@
rldicr. %4,%1,%H2,%S3
#"
@@ -7453,7 +6841,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
"@
rldicr. %0,%1,%H2,%S3
#"
@@ -7510,7 +6898,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT "
"@
srd%I2. %3,%1,%H2
#"
@@ -7538,7 +6926,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(lshiftrt:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
srd%I2. %0,%1,%H2
#"
@@ -7564,7 +6952,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")))]
- ""
+ "WORDS_BIG_ENDIAN"
"
{
if (TARGET_POWERPC64)
@@ -7574,7 +6962,8 @@
emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
DONE;
}
- else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
+ else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT
+ && WORDS_BIG_ENDIAN)
{
emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
DONE;
@@ -7596,7 +6985,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
srad%I2. %3,%1,%H2
#"
@@ -7624,7 +7013,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
srad%I2. %0,%1,%H2
#"
@@ -7688,7 +7077,7 @@
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
and. %3,%1,%2
rldic%B2. %3,%1,0,%S2
@@ -7753,7 +7142,7 @@
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
(and:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
and. %0,%1,%2
rldic%B2. %0,%1,0,%S2
@@ -7898,7 +7287,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %3,%1,%2
#"
@@ -7927,7 +7316,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %0,%1,%2
#"
@@ -7949,7 +7338,7 @@
(const_int 0)))]
"")
-;; Split an logical operation that we can't do in one insn into two insns,
+;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
@@ -7998,7 +7387,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %3,%2,%1
#"
@@ -8027,7 +7416,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %0,%2,%1
#"
@@ -8064,7 +7453,7 @@
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %3,%1,%2
#"
@@ -8093,7 +7482,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %0,%1,%2
#"
@@ -8157,7 +7546,7 @@
(define_expand "movsi_got"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_operand" "")
- (match_dup 2)] 8))]
+ (match_dup 2)] UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"
{
@@ -8183,7 +7572,8 @@
(define_insn "*movsi_got_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
- (match_operand:SI 2 "gpc_reg_operand" "b")] 8))]
+ (match_operand:SI 2 "gpc_reg_operand" "b")]
+ UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"{l|lwz} %0,%a1@got(%2)"
[(set_attr "type" "load")])
@@ -8193,12 +7583,14 @@
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
- (match_operand:SI 2 "memory_operand" "")] 8))]
+ (match_operand:SI 2 "memory_operand" "")]
+ UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4
&& flag_pic == 1
&& (reload_in_progress || reload_completed)"
[(set (match_dup 0) (match_dup 2))
- (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 8))]
+ (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
+ UNSPEC_MOVSI_GOT))]
"")
;; For SI, we special-case integers that can't be loaded in one insn. We
@@ -8246,12 +7638,23 @@
operands2[0] = operands[0];
operands2[1] = operands[1];
operands2[2] = operands[2];
- operands2[3] = gen_rtx_REG (SImode, RS6000_PIC_OFFSET_TABLE_REGNUM);
- output_asm_insn (\"{l|lwz} %0,lo16(%2)(%1)\", operands);
- /* We cannot rely on ha16(low half)==ha16(high half), alas,
- although in practice it almost always is. */
- output_asm_insn (\"{cau|addis} %L0,%3,ha16(%2+4)\", operands2);
- return (\"{l|lwz} %L0,lo16(%2+4)(%L0)\");
+ if (TARGET_POWERPC64 && TARGET_32BIT)
+ /* Note, old assemblers didn't support relocation here. */
+ return \"ld %0,lo16(%2)(%1)\";
+ else
+ {
+ operands2[3] = gen_rtx_REG (SImode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+ output_asm_insn (\"{l|lwz} %0,lo16(%2)(%1)\", operands);
+#if TARGET_MACHO
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ output_asm_insn (\"{liu|lis} %L0,ha16(%2+4)\", operands);
+ else
+ /* We cannot rely on ha16(low half)==ha16(high half), alas,
+ although in practice it almost always is. */
+ output_asm_insn (\"{cau|addis} %L0,%3,ha16(%2+4)\", operands2);
+#endif
+ return (\"{l|lwz} %L0,lo16(%2+4)(%L0)\");
+ }
}
default:
abort();
@@ -8310,7 +7713,7 @@
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*,*")
+ [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
(set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
;; Split a load of a large constant into the appropriate two-insn
@@ -8336,29 +7739,30 @@
}")
(define_insn "*movsi_internal2"
- [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
- (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
+ (compare:CC (match_operand:SI 1 "gpc_reg_operand" "0,r,r")
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 1))]
- "! TARGET_POWERPC64"
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
+ "TARGET_32BIT"
"@
+ {cmpi|cmpwi} %2,%0,0
mr. %0,%1
#"
- [(set_attr "type" "compare")
- (set_attr "length" "4,8")])
-
+ [(set_attr "type" "cmp,compare,cmp")
+ (set_attr "length" "4,4,8")])
+
(define_split
[(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
(compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 1))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
-
+
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "any_operand" ""))]
@@ -8379,7 +7783,7 @@
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
+ [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
@@ -8401,7 +7805,7 @@
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
+ [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
;; Here is how to move condition codes around. When we store CC data in
;; an integer register or memory, we store just the high-order 4 bits.
@@ -8413,23 +7817,41 @@
"")
(define_insn "*movcc_internal1"
- [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,cl,q,r,r,m")
- (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,r,r,h,m,r"))]
+ [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,r,r,r,r,q,cl,r,m")
+ (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,h,r,r,m,r"))]
"register_operand (operands[0], CCmode)
|| register_operand (operands[1], CCmode)"
"@
mcrf %0,%1
mtcrf 128,%1
{rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
- mfcr %0
- mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
+ mfcr %0%Q1
+ mfcr %0%Q1\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
mr %0,%1
+ mf%1 %0
mt%0 %1
mt%0 %1
- mf%1 %0
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%U1|stw%U0%U1} %1,%0"
- [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,*,mtjmpr,*,load,store")
+ [(set (attr "type")
+ (cond [(eq_attr "alternative" "0")
+ (const_string "cr_logical")
+ (eq_attr "alternative" "1,2")
+ (const_string "mtcr")
+ (eq_attr "alternative" "5,7")
+ (const_string "integer")
+ (eq_attr "alternative" "6")
+ (const_string "mfjmpr")
+ (eq_attr "alternative" "8")
+ (const_string "mtjmpr")
+ (eq_attr "alternative" "9")
+ (const_string "load")
+ (eq_attr "alternative" "10")
+ (const_string "store")
+ (ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
(set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")])
;; For floating-point, we normally deal with the floating-point registers
@@ -8490,8 +7912,8 @@
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
(define_insn "*movsf_softfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r")
- (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h")
+ (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn,0"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode))
&& (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
@@ -8506,9 +7928,10 @@
{liu|lis} %0,%v1
{cal|la} %0,%a1
#
- #"
- [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
+ #
+ {cror 0,0,0|nop}"
+ [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")])
(define_expand "movdf"
@@ -8581,7 +8004,9 @@
int endian = (WORDS_BIG_ENDIAN == 0);
long l[2];
REAL_VALUE_TYPE rv;
+#if HOST_BITS_PER_WIDE_INT >= 64
HOST_WIDE_INT val;
+#endif
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
@@ -8738,16 +8163,19 @@
[(set_attr "type" "*,load,store,*,*,*")
(set_attr "length" "8,8,8,8,12,16")])
+; ld/std require word-aligned displacements -> 'Y' constraint.
+; List Y->r and r->Y before r->r for reload.
(define_insn "*movdf_hardfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!cl,!r,!r,!r,!r")
- (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,r,h,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,b,!r,f,f,m,!cl,!r,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "r,Y,m,r,f,m,f,r,h,G,H,F"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
- mr %0,%1
- ld%U1%X1 %0,%1
std%U0%X0 %1,%0
+ ld%U1%X1 %0,%1
+ #
+ mr %0,%1
fmr %0,%1
lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0
@@ -8756,180 +8184,148 @@
#
#
#"
- [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,4,8,12,16")])
+ [(set_attr "type" "store,load,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*")
+ (set_attr "length" "4,4,8,4,4,4,4,4,4,8,12,16")])
+
+(define_split
+ [(set (match_operand:DF 0 "base_reg_operand" "")
+ (match_operand:DF 1 "invalid_gpr_mem" ""))]
+ "TARGET_POWERPC64 && no_new_pseudos"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (match_dup 4))]
+ "
+{
+ operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
+ operands[3] = XEXP (operands[1], 0);
+ operands[4] = replace_equiv_address (operands[1], operands[2]);
+}")
+
+(define_expand "reload_outdf"
+ [(parallel [(match_operand:DF 0 "invalid_gpr_mem" "")
+ (match_operand:DF 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[0], 0));
+ operands[0] = replace_equiv_address (operands[0], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "reload_indf"
+ [(parallel [(match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "invalid_gpr_mem" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[1], 0));
+ operands[1] = replace_equiv_address (operands[1], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
(define_insn "*movdf_softfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r")
- (match_operand:DF 1 "input_operand" "r,r,h,m,r,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
+ (match_operand:DF 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))]
"TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
+ ld%U1%X1 %0,%1
+ std%U0%X0 %1,%0
mr %0,%1
mt%0 %1
mf%1 %0
- ld%U1%X1 %0,%1
- std%U0%X0 %1,%0
#
#
- #"
- [(set_attr "type" "*,*,*,load,store,*,*,*")
- (set_attr "length" "4,4,4,4,4,8,12,16")])
+ #
+ nop"
+ [(set_attr "type" "load,store,*,*,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,8,12,16,4")])
(define_expand "movtf"
[(set (match_operand:TF 0 "general_operand" "")
(match_operand:TF 1 "any_operand" ""))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
-(define_insn "*movtf_internal"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r")
- (match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128
+; It's important to list the o->f and f->o moves before f->f because
+; otherwise reload, given m->f, will try to pick f->f and reload it,
+; which doesn't make progress.
+(define_insn_and_split "*movtf_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,rm,r")
+ (match_operand:TF 1 "input_operand" "f,o,f,r,mGHF"))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
&& (gpc_reg_operand (operands[0], TFmode)
|| gpc_reg_operand (operands[1], TFmode))"
- "*
-{
- switch (which_alternative)
- {
- default:
- abort ();
- case 0:
- /* We normally copy the low-numbered register first. However, if
- the first register operand 0 is the same as the second register of
- operand 1, we must copy in the opposite order. */
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"fmr %L0,%L1\;fmr %0,%1\";
- else
- return \"fmr %0,%1\;fmr %L0,%L1\";
- case 1:
- return \"lfd %0,%1\;lfd %L0,%Y1\";
- case 2:
- return \"stfd %1,%0\;stfd %L1,%Y0\";
- case 3:
- case 4:
- case 5:
- return \"#\";
- }
-}"
- [(set_attr "type" "fp,fpload,fpstore,*,*,*")
- (set_attr "length" "8,8,8,12,16,20")])
-
-(define_split
- [(set (match_operand:TF 0 "gpc_reg_operand" "")
- (match_operand:TF 1 "easy_fp_constant" ""))]
+ "#"
+ "&& reload_completed"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
+ [(set_attr "length" "8,8,8,20,20")])
+
+(define_expand "extenddftf2"
+ [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:DF 1 "input_operand" "")))
+ (use (match_dup 2))])]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64
- && TARGET_LONG_DOUBLE_128 && reload_completed
- && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && REGNO (SUBREG_REG (operands[0])) <= 31))"
- [(set (match_dup 2) (match_dup 6))
- (set (match_dup 3) (match_dup 7))
- (set (match_dup 4) (match_dup 8))
- (set (match_dup 5) (match_dup 9))]
- "
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
{
- long l[4];
- REAL_VALUE_TYPE rv;
+ operands[2] = CONST0_RTX (DFmode);
+})
- REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
-
- operands[2] = operand_subword (operands[0], 0, 0, TFmode);
- operands[3] = operand_subword (operands[0], 1, 0, TFmode);
- operands[4] = operand_subword (operands[0], 2, 0, TFmode);
- operands[5] = operand_subword (operands[0], 3, 0, TFmode);
- operands[6] = gen_int_mode (l[0], SImode);
- operands[7] = gen_int_mode (l[1], SImode);
- operands[8] = gen_int_mode (l[2], SImode);
- operands[9] = gen_int_mode (l[3], SImode);
-}")
-
-(define_split
- [(set (match_operand:TF 0 "gpc_reg_operand" "")
- (match_operand:TF 1 "easy_fp_constant" ""))]
+(define_insn_and_split "*extenddftf2_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
+ (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
+ (use (match_operand:DF 2 "input_operand" "rf,m,f,n"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
- && TARGET_LONG_DOUBLE_128 && reload_completed
- && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && REGNO (SUBREG_REG (operands[0])) <= 31))"
- [(set (match_dup 2) (match_dup 4))
- (set (match_dup 3) (match_dup 5))]
- "
-{
- long l[4];
- REAL_VALUE_TYPE rv;
- HOST_WIDE_INT val;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
-
- operands[2] = gen_lowpart (DImode, operands[0]);
- operands[3] = gen_highpart (DImode, operands[0]);
-#if HOST_BITS_PER_WIDE_INT >= 64
- val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32
- | ((HOST_WIDE_INT)(unsigned long)l[1]));
- operands[4] = gen_int_mode (val, DImode);
-
- val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32
- | ((HOST_WIDE_INT)(unsigned long)l[3]));
- operands[5] = gen_int_mode (val, DImode);
-#else
- operands[4] = immed_double_const (l[1], l[0], DImode);
- operands[5] = immed_double_const (l[3], l[2], DImode);
-#endif
-}")
-
-(define_insn "extenddftf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "#"
+ "&& reload_completed"
+ [(pc)]
{
- if (REGNO (operands[0]) == REGNO (operands[1]))
- return \"fsub %L0,%L0,%L0\";
- else
- return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
-}"
- [(set_attr "type" "fp")])
+ const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
+ operands[1]);
+ emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
+ operands[2]);
+ DONE;
+})
-(define_insn "extendsftf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+(define_expand "extendsftf2"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
{
- if (REGNO (operands[0]) == REGNO (operands[1]))
- return \"fsub %L0,%L0,%L0\";
- else
- return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
-}"
- [(set_attr "type" "fp")])
+ rtx tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extendsfdf2 (tmp, operands[1]));
+ emit_insn (gen_extenddftf2 (operands[0], tmp));
+ DONE;
+})
(define_insn "trunctfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"fadd %0,%1,%L1"
[(set_attr "type" "fp")
- (set_attr "length" "8")])
+ (set_attr "length" "4")])
(define_insn_and_split "trunctfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
(clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT
- && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
[(set (match_dup 2)
@@ -8938,67 +8334,80 @@
(float_truncate:SF (match_dup 2)))]
"")
-(define_insn_and_split "floatditf2"
+(define_expand "floatsitf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float:TF (match_operand:DI 1 "gpc_reg_operand" "*f")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+ (float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (float:DF (match_dup 1)))
- (set (match_dup 0)
- (float_extend:TF (match_dup 2)))]
- "")
+{
+ rtx tmp = gen_reg_rtx (DFmode);
+ expand_float (tmp, operands[1], false);
+ emit_insn (gen_extenddftf2 (operands[0], tmp));
+ DONE;
+})
-(define_insn_and_split "floatsitf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (float:DF (match_dup 1)))
- (set (match_dup 0)
- (float_extend:TF (match_dup 2)))]
- "")
+; fadd, but rounding towards zero.
+; This is probably not the optimal code sequence.
+(define_insn "fix_trunc_helper"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
+ UNSPEC_FIX_TRUNC_TF))
+ (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS"
+ "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
+ [(set_attr "type" "fp")
+ (set_attr "length" "20")])
-(define_insn_and_split "fix_trunctfdi2"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
- (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+(define_expand "fix_trunctfsi2"
+ [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
+ (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (match_dup 5))])]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && (TARGET_POWER2 || TARGET_POWERPC)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (float_truncate:DF (match_dup 1)))
- (set (match_dup 0)
- (fix:DI (match_dup 2)))]
- "")
+{
+ operands[2] = gen_reg_rtx (DFmode);
+ operands[3] = gen_reg_rtx (DFmode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
+})
-(define_insn_and_split "fix_trunctfsi2"
+(define_insn_and_split "*fix_trunctfsi2_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
+ (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
+ (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
+ (clobber (match_operand:DI 5 "memory_operand" "=o"))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
- [(set (match_dup 2)
- (float_truncate:DF (match_dup 1)))
- (set (match_dup 0)
- (fix:SI (match_dup 2)))]
- "")
+ [(pc)]
+{
+ rtx lowword;
+ emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
+
+ if (GET_CODE (operands[5]) != MEM)
+ abort();
+ lowword = XEXP (operands[5], 0);
+ if (WORDS_BIG_ENDIAN)
+ lowword = plus_constant (lowword, 4);
+
+ emit_insn (gen_fctiwz (operands[4], operands[2]));
+ emit_move_insn (operands[5], operands[4]);
+ emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword));
+ DONE;
+})
(define_insn "negtf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"*
{
if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
@@ -9009,35 +8418,40 @@
[(set_attr "type" "fp")
(set_attr "length" "8")])
-(define_insn "abstf2"
+(define_expand "abstf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "
{
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"fabs %L0,%L1\;fabs %0,%1\";
- else
- return \"fabs %0,%1\;fabs %L0,%L1\";
-}"
- [(set_attr "type" "fp")
- (set_attr "length" "8")])
+ rtx label = gen_label_rtx ();
+ emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
+ emit_label (label);
+ DONE;
+}")
-(define_insn ""
+(define_expand "abstf2_internal"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (neg:TF (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f"))))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+ (match_operand:TF 1 "gpc_reg_operand" "f"))
+ (set (match_dup 3) (match_dup 5))
+ (set (match_dup 5) (abs:DF (match_dup 5)))
+ (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
+ (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
+ (label_ref (match_operand 2 "" ""))
+ (pc)))
+ (set (match_dup 6) (neg:DF (match_dup 6)))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "
{
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"fnabs %L0,%L1\;fnabs %0,%1\";
- else
- return \"fnabs %0,%1\;fnabs %L0,%L1\";
-}"
- [(set_attr "type" "fp")
- (set_attr "length" "8")])
+ const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ operands[3] = gen_reg_rtx (DFmode);
+ operands[4] = gen_reg_rtx (CCFPmode);
+ operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
+ operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
+}")
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.
@@ -9060,25 +8474,9 @@
default:
abort ();
case 0:
- /* We normally copy the low-numbered register first. However, if
- the first register operand 0 is the same as the second register of
- operand 1, we must copy in the opposite order. */
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\";
case 1:
- /* If the low-address word is used in the address, we must load it
- last. Otherwise, load it first. Note that we cannot have
- auto-increment in that case since the address register is known to be
- dead. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
- else
- return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
case 2:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+ return \"#\";
case 3:
return \"fmr %0,%1\";
case 4:
@@ -9093,8 +8491,7 @@
return \"#\";
}
}"
- [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
- (set_attr "length" "8,8,8,4,4,4,8,12,8,12,16")])
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
@@ -9118,20 +8515,12 @@
}")
(define_split
- [(set (match_operand:DI 0 "gpc_reg_operand" "")
- (match_operand:DI 1 "const_double_operand" ""))]
- "HOST_BITS_PER_WIDE_INT == 32 && ! TARGET_POWERPC64 && reload_completed"
- [(set (match_dup 2) (match_dup 4))
- (set (match_dup 3) (match_dup 5))]
- "
-{
- operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
- DImode);
- operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
- DImode);
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
- operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
-}")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "input_operand" ""))]
+ "reload_completed && !TARGET_POWERPC64
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_split
[(set (match_operand:TI 0 "gpc_reg_operand" "")
@@ -9160,15 +8549,16 @@
}")
(define_insn "*movdi_internal64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,?f,f,m,r,*h,*h")
- (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,b,r,r,r,r,r,??f,f,m,r,*h,*h")
+ (match_operand:DI 1 "input_operand" "r,Y,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
"TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
"@
- mr %0,%1
- ld%U1%X1 %0,%1
std%U0%X0 %1,%0
+ ld%U1%X1 %0,%1
+ #
+ mr %0,%1
li %0,%1
lis %0,%v1
#
@@ -9179,8 +8569,51 @@
mf%1 %0
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
- (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
+ [(set_attr "type" "store,load,load,*,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*")
+ (set_attr "length" "4,4,8,4,4,4,20,4,4,4,4,4,4,4")])
+
+(define_split
+ [(set (match_operand:DI 0 "base_reg_operand" "")
+ (match_operand:DI 1 "invalid_gpr_mem" ""))]
+ "TARGET_POWERPC64 && no_new_pseudos"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (match_dup 4))]
+ "
+{
+ operands[2] = operands[0];
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ operands[3] = XEXP (operands[1], 0);
+ operands[4] = replace_equiv_address (operands[1], operands[2]);
+}")
+
+(define_expand "reload_outdi"
+ [(parallel [(match_operand:DI 0 "invalid_gpr_mem" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[0], 0));
+ operands[0] = replace_equiv_address (operands[0], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "reload_indi"
+ [(parallel [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "invalid_gpr_mem" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[1], 0));
+ operands[1] = replace_equiv_address (operands[1], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
;; immediate value valid for a single instruction hiding in a const_double
(define_insn ""
@@ -9243,18 +8676,18 @@
FAIL;
}")
-;; Split a load of a large constant into the appropriate five-instruction
(define_insn "*movdi_internal2"
- [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
- (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r")
+ [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
+ (compare:CC (match_operand:DI 1 "gpc_reg_operand" "0,r,r")
(const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 1))]
- "TARGET_POWERPC64"
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
+ "TARGET_64BIT"
"@
+ cmpdi %2,%0,0
mr. %0,%1
#"
- [(set_attr "type" "compare")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "cmp,compare,cmp")
+ (set_attr "length" "4,4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
@@ -9275,7 +8708,7 @@
[(parallel [(set (match_operand:TI 0 "general_operand" "")
(match_operand:TI 1 "general_operand" ""))
(clobber (scratch:SI))])]
- "TARGET_STRING || TARGET_POWERPC64"
+ ""
"{ rs6000_emit_move (operands[0], operands[1], TImode); DONE; }")
;; We say that MQ is clobbered in the last alternative because the first
@@ -9283,11 +8716,12 @@
;; while the 2nd alternative would not. We put memory cases first so they
;; are preferred. Otherwise, we'd try to reload the output instead of
;; giving the SCRATCH mq.
+
(define_insn "*movti_power"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
(clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
- "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
+ "TARGET_POWER && ! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
{
@@ -9297,50 +8731,28 @@
abort ();
case 0:
- return \"{stsi|stswi} %1,%P0,16\";
-
+ if (TARGET_STRING)
+ return \"{stsi|stswi} %1,%P0,16\";
case 1:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
-
case 2:
- /* Normally copy registers with lowest numbered register copied first.
- But copy in the other order if the first register of the output
- is the second, third, or fourth register in the input. */
- if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
- && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
- return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
+ return \"#\";
case 3:
/* If the address is not used in the output, we can use lsi. Otherwise,
fall through to generating four loads. */
- if (! reg_overlap_mentioned_p (operands[0], operands[1]))
+ if (TARGET_STRING
+ && ! reg_overlap_mentioned_p (operands[0], operands[1]))
return \"{lsi|lswi} %0,%P1,16\";
/* ... fall through ... */
case 4:
- /* If the address register is the same as the register for the lowest-
- addressed word, load it last. Similarly for the next two words.
- Otherwise load lowest address to highest. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 1,
- REGNO (operands[0]) + 2, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 2,
- REGNO (operands[0]) + 3, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
- else
- return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
+ return \"#\";
}
}"
- [(set_attr "type" "store,store,*,load,load")
- (set_attr "length" "4,16,16,4,16")])
+ [(set_attr "type" "store,store,*,load,load")])
(define_insn "*movti_string"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))]
- "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
+ "! TARGET_POWER && ! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
{
@@ -9348,81 +8760,43 @@
{
default:
abort ();
-
case 0:
- return \"{stsi|stswi} %1,%P0,16\";
+ if (TARGET_STRING)
+ return \"{stsi|stswi} %1,%P0,16\";
case 1:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
case 2:
- /* Normally copy registers with lowest numbered register copied first.
- But copy in the other order if the first register of the output
- is the second, third, or fourth register in the input. */
- if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
- && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
- return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
+ return \"#\";
case 3:
/* If the address is not used in the output, we can use lsi. Otherwise,
fall through to generating four loads. */
- if (! reg_overlap_mentioned_p (operands[0], operands[1]))
+ if (TARGET_STRING
+ && ! reg_overlap_mentioned_p (operands[0], operands[1]))
return \"{lsi|lswi} %0,%P1,16\";
/* ... fall through ... */
case 4:
- /* If the address register is the same as the register for the lowest-
- addressed word, load it last. Similarly for the next two words.
- Otherwise load lowest address to highest. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 1,
- REGNO (operands[0]) + 2, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 2,
- REGNO (operands[0]) + 3, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
- else
- return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
+ return \"#\";
}
}"
- [(set_attr "type" "store,store,*,load,load")
- (set_attr "length" "4,16,16,4,16")])
+ [(set_attr "type" "store,store,*,load,load")])
(define_insn "*movti_ppc64"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
- (match_operand:TI 1 "input_operand" "r,m,r"))]
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=r,m,r")
+ (match_operand:TI 1 "input_operand" "r,r,o"))]
"TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
|| gpc_reg_operand (operands[1], TImode))"
- "*
-{
- switch (which_alternative)
- {
- default:
- abort ();
- case 0:
- /* We normally copy the low-numbered register first. However, if
- the first register operand 0 is the same as the second register of
- operand 1, we must copy in the opposite order. */
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\";
- case 1:
- /* If the low-address word is used in the address, we must load it
- last. Otherwise, load it first. Note that we cannot have
- auto-increment in that case since the address register is known to be
- dead. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"ld %L0,%L1\;ld %0,%1\";
- else
- return \"ld%U1 %0,%1\;ld %L0,%L1\";
- case 2:
- return \"std%U0 %1,%0\;std %L1,%L0\";
- }
-}"
- [(set_attr "type" "*,load,store")
- (set_attr "length" "8,8,8")])
+ "@
+ #
+ #
+ #"
+ [(set_attr "type" "*,load,store")])
+
+(define_split
+ [(set (match_operand:TI 0 "nonimmediate_operand" "")
+ (match_operand:TI 1 "input_operand" ""))]
+ "reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_expand "load_multiple"
[(match_par_dup 3 [(set (match_operand:SI 0 "" "")
@@ -9627,15 +9001,113 @@
"{stsi|stswi} %2,%P1,%O0"
[(set_attr "type" "store")])
-(define_insn "*store_multiple_string"
+(define_insn "*stmsi8"
[(match_parallel 0 "store_multiple_operation"
- [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
- (match_operand:SI 2 "gpc_reg_operand" "r"))
- (clobber (match_scratch:SI 3 "X"))])]
- "TARGET_STRING && ! TARGET_POWER"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 9 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
+ (match_operand:SI 10 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 9"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi7"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 9 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 8"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi6"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 7"
"{stsi|stswi} %2,%1,%O0"
[(set_attr "type" "store")])
+(define_insn "*stmsi5"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 6"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi4"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 5"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi3"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 4"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
;; String/block move insn.
;; Argument 0 is the destination
@@ -10010,18 +9482,7 @@
"@
ldux %3,%0,%2
ldu %3,%2(%0)"
- [(set_attr "type" "load")])
-
-(define_insn "*movdi_update2"
- [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
- (sign_extend:DI
- (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
- (match_operand:DI 2 "gpc_reg_operand" "r")))))
- (set (match_operand:DI 0 "gpc_reg_operand" "=b")
- (plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
- "lwaux %3,%0,%2"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "movdi_update"
[(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
@@ -10033,7 +9494,7 @@
"@
stdux %3,%0,%2
stdu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movsi_update1"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10041,11 +9502,22 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- ""
+ "TARGET_UPDATE"
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
+
+(define_insn "*movsi_update2"
+ [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
+ (sign_extend:DI
+ (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
+ (match_operand:DI 2 "gpc_reg_operand" "r")))))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=b")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "lwaux %3,%0,%2"
+ [(set_attr "type" "load_ext_ux")])
(define_insn "movsi_update"
[(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10057,9 +9529,9 @@
"@
{stux|stwux} %3,%0,%2
{stu|stwu} %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
-(define_insn "*movhi_update"
+(define_insn "*movhi_update1"
[(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
@@ -10069,7 +9541,7 @@
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movhi_update2"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10082,7 +9554,7 @@
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movhi_update3"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10095,7 +9567,7 @@
"@
lhaux %3,%0,%2
lhau %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ext_ux,load_ext_u")])
(define_insn "*movhi_update4"
[(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10107,7 +9579,7 @@
"@
sthux %3,%0,%2
sthu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movqi_update1"
[(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
@@ -10119,7 +9591,7 @@
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movqi_update2"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10132,7 +9604,7 @@
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movqi_update3"
[(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10144,7 +9616,7 @@
"@
stbux %3,%0,%2
stbu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movsf_update1"
[(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
@@ -10156,7 +9628,7 @@
"@
lfsux %3,%0,%2
lfsu %3,%2(%0)"
- [(set_attr "type" "fpload")])
+ [(set_attr "type" "fpload_ux,fpload_u")])
(define_insn "*movsf_update2"
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10168,7 +9640,7 @@
"@
stfsux %3,%0,%2
stfsu %3,%2(%0)"
- [(set_attr "type" "fpstore")])
+ [(set_attr "type" "fpstore_ux,fpstore_u")])
(define_insn "*movsf_update3"
[(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
@@ -10180,7 +9652,7 @@
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movsf_update4"
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10192,7 +9664,7 @@
"@
{stux|stwux} %3,%0,%2
{stu|stwu} %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movdf_update1"
[(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
@@ -10204,7 +9676,7 @@
"@
lfdux %3,%0,%2
lfdu %3,%2(%0)"
- [(set_attr "type" "fpload")])
+ [(set_attr "type" "fpload_ux,fpload_u")])
(define_insn "*movdf_update2"
[(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10216,7 +9688,7 @@
"@
stfdux %3,%0,%2
stfdu %3,%2(%0)"
- [(set_attr "type" "fpstore")])
+ [(set_attr "type" "fpstore_ux,fpstore_u")])
;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
@@ -10244,6 +9716,186 @@
&& addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
"stfq%U0%X0 %1,%0")
+;; TLS support.
+
+;; "b" output constraint here and on tls_ld to support tls linker optimization.
+(define_insn "tls_gd_32"
+ [(set (match_operand:SI 0 "register_operand" "=b")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGD))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@got@tlsgd")
+
+(define_insn "tls_gd_64"
+ [(set (match_operand:DI 0 "register_operand" "=b")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGD))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@got@tlsgd")
+
+(define_insn "tls_ld_32"
+ [(set (match_operand:SI 0 "register_operand" "=b")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")]
+ UNSPEC_TLSLD))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%&@got@tlsld")
+
+(define_insn "tls_ld_64"
+ [(set (match_operand:DI 0 "register_operand" "=b")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")]
+ UNSPEC_TLSLD))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%&@got@tlsld")
+
+(define_insn "tls_dtprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@dtprel")
+
+(define_insn "tls_dtprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@dtprel")
+
+(define_insn "tls_dtprel_ha_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELHA))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addis %0,%1,%2@dtprel@ha")
+
+(define_insn "tls_dtprel_ha_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELHA))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addis %0,%1,%2@dtprel@ha")
+
+(define_insn "tls_dtprel_lo_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELLO))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@dtprel@l")
+
+(define_insn "tls_dtprel_lo_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELLO))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@dtprel@l")
+
+(define_insn "tls_got_dtprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTDTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "lwz %0,%2@got@dtprel(%1)")
+
+(define_insn "tls_got_dtprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTDTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "ld %0,%2@got@dtprel(%1)")
+
+(define_insn "tls_tprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@tprel")
+
+(define_insn "tls_tprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@tprel")
+
+(define_insn "tls_tprel_ha_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELHA))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addis %0,%1,%2@tprel@ha")
+
+(define_insn "tls_tprel_ha_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELHA))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addis %0,%1,%2@tprel@ha")
+
+(define_insn "tls_tprel_lo_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELLO))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@tprel@l")
+
+(define_insn "tls_tprel_lo_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELLO))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@tprel@l")
+
+;; "b" output constraint here and on tls_tls input to support linker tls
+;; optimization. The linker may edit the instructions emitted by a
+;; tls_got_tprel/tls_tls pair to addis,addi.
+(define_insn "tls_got_tprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=b")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "lwz %0,%2@got@tprel(%1)")
+
+(define_insn "tls_got_tprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=b")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "ld %0,%2@got@tprel(%1)")
+
+(define_insn "tls_tls_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTLS))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "add %0,%1,%2@tls")
+
+(define_insn "tls_tls_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTLS))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "add %0,%1,%2@tls")
+
;; Next come insns related to the calling sequence.
;;
;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
@@ -10375,7 +10027,7 @@
(define_insn "load_toc_aix_si"
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(const_int 0)] 7))
+ (unspec:SI [(const_int 0)] UNSPEC_TOC))
(use (reg:SI 2))])]
"DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
"*
@@ -10390,7 +10042,7 @@
(define_insn "load_toc_aix_di"
[(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(const_int 0)] 7))
+ (unspec:DI [(const_int 0)] UNSPEC_TOC))
(use (reg:DI 2))])]
"DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
"*
@@ -10412,7 +10064,7 @@
(define_insn "load_toc_v4_pic_si"
[(set (match_operand:SI 0 "register_operand" "=l")
- (unspec:SI [(const_int 0)] 7))]
+ (unspec:SI [(const_int 0)] UNSPEC_TOC))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
"bl _GLOBAL_OFFSET_TABLE_@local-4"
[(set_attr "type" "branch")
@@ -10421,7 +10073,7 @@
(define_insn "load_toc_v4_PIC_1"
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "immediate_operand" "s"))
- (unspec [(match_dup 1)] 7)]
+ (use (unspec [(match_dup 1)] UNSPEC_TOC))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
"bcl 20,31,%1\\n%1:"
[(set_attr "type" "branch")
@@ -10430,9 +10082,10 @@
(define_insn "load_toc_v4_PIC_1b"
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "immediate_operand" "s"))
- (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] 6)]
+ (use (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")]
+ UNSPEC_TOCPTR))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
- "bcl 20,31,%1\\n\\t.long %2-%1+4\\n%1:"
+ "bcl 20,31,%1+4\\n%1:\\n\\t.long %2-%1"
[(set_attr "type" "branch")
(set_attr "length" "8")])
@@ -10447,7 +10100,8 @@
(define_insn "load_macho_picbase"
[(set (match_operand:SI 0 "register_operand" "=l")
- (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")] 15))]
+ (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")]
+ UNSPEC_LD_MPIC))]
"(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
"bcl 20,31,%1\\n%1:"
[(set_attr "type" "branch")
@@ -10455,12 +10109,12 @@
(define_insn "macho_correct_pic"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (plus:SI (match_operand:SI 1 "gpc_reg_operand" "=r")
+ (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
(match_operand:SI 3 "immediate_operand" "s")]
- 16)))]
+ UNSPEC_MPIC_CORRECT)))]
"DEFAULT_ABI == ABI_DARWIN"
- "addis %0,%1,ha16(%2-%3)\n\taddi %1,%1,lo16(%2-%3)"
+ "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
[(set_attr "length" "8")])
;; If the TOC is shared over a translation unit, as happens with all
@@ -10478,15 +10132,15 @@
#if TARGET_MACHO
if (DEFAULT_ABI == ABI_DARWIN)
{
- char *picbase = machopic_function_base_name ();
- rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
+ const char *picbase = machopic_function_base_name ();
+ rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (picbase));
rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
rtx tmplabrtx;
char tmplab[20];
ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
CODE_LABEL_NUMBER (operands[0]));
- tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (tmplab, -1));
+ tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
emit_insn (gen_load_macho_picbase (picreg, tmplabrtx));
emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
@@ -10603,7 +10257,7 @@
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[0] = machopic_indirect_call_target (operands[0]);
#endif
@@ -10613,13 +10267,13 @@
operands[0] = XEXP (operands[0], 0);
if (GET_CODE (operands[0]) != SYMBOL_REF
- || (INTVAL (operands[2]) & CALL_LONG) != 0)
+ || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
+ || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
{
if (INTVAL (operands[2]) & CALL_LONG)
operands[0] = rs6000_longcall_ref (operands[0]);
if (DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN)
operands[0] = force_reg (Pmode, operands[0]);
@@ -10651,7 +10305,7 @@
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
@@ -10661,15 +10315,15 @@
operands[1] = XEXP (operands[1], 0);
if (GET_CODE (operands[1]) != SYMBOL_REF
- || (INTVAL (operands[3]) & CALL_LONG) != 0)
+ || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
+ || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
{
if (INTVAL (operands[3]) & CALL_LONG)
operands[1] = rs6000_longcall_ref (operands[1]);
if (DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN)
- operands[0] = force_reg (Pmode, operands[0]);
+ operands[1] = force_reg (Pmode, operands[1]);
else if (DEFAULT_ABI == ABI_AIX)
{
@@ -10898,8 +10552,7 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
- "DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
@@ -10918,10 +10571,9 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
- "(DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_DARWIN)
- && (INTVAL (operands[2]) & CALL_LONG) == 0"
+ "(DEFAULT_ABI == ABI_DARWIN
+ || (DEFAULT_ABI == ABI_V4
+ && (INTVAL (operands[2]) & CALL_LONG) == 0))"
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
output_asm_insn ("crxor 6,6,6", operands);
@@ -10929,7 +10581,11 @@
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands);
+#if TARGET_MACHO
+ return output_call(insn, operands, 0, 2);
+#else
return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@plt" : "bl %z0";
+#endif
}
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -10940,8 +10596,7 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
- "DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
@@ -10961,10 +10616,9 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
- "(DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_DARWIN)
- && (INTVAL (operands[3]) & CALL_LONG) == 0"
+ "(DEFAULT_ABI == ABI_DARWIN
+ || (DEFAULT_ABI == ABI_V4
+ && (INTVAL (operands[3]) & CALL_LONG) == 0))"
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
output_asm_insn ("crxor 6,6,6", operands);
@@ -10972,7 +10626,11 @@
else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands);
+#if TARGET_MACHO
+ return output_call(insn, operands, 1, 3);
+#else
return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@plt" : "bl %z1";
+#endif
}
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -11010,13 +10668,13 @@
[(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
- (use (scratch:SI))
+ (use (match_operand 3 "" ""))
(return)])]
""
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[0] = machopic_indirect_call_target (operands[0]);
#endif
@@ -11024,6 +10682,7 @@
abort ();
operands[0] = XEXP (operands[0], 0);
+ operands[3] = gen_reg_rtx (SImode);
}")
@@ -11035,7 +10694,7 @@
[(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"(INTVAL (operands[2]) & CALL_LONG) == 0"
"*
@@ -11055,7 +10714,7 @@
[(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
@@ -11076,7 +10735,7 @@
(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"(INTVAL (operands[3]) & CALL_LONG) == 0"
"*
@@ -11098,7 +10757,7 @@
(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
@@ -11118,7 +10777,7 @@
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
- (use (match_scratch:SI 3 "=l"))
+ (use (match_operand:SI 3 "register_operand" "l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11131,7 +10790,7 @@
[(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
- (use (match_scratch:SI 3 "=l"))
+ (use (match_operand:SI 3 "register_operand" "l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11145,7 +10804,7 @@
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
- (use (match_scratch:SI 4 "=l"))
+ (use (match_operand:SI 4 "register_operand" "l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11159,7 +10818,7 @@
(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
- (use (match_scratch:SI 4 "=l"))
+ (use (match_operand:SI 4 "register_operand" "l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11172,11 +10831,10 @@
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
(match_operand 1 "" ""))
(use (match_operand 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
@@ -11196,13 +10854,13 @@
(call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
- (use (scratch:SI))
+ (use (match_operand 4 "" ""))
(return)])]
""
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
@@ -11210,6 +10868,7 @@
abort ();
operands[1] = XEXP (operands[1], 0);
+ operands[4] = gen_reg_rtx (SImode);
}")
@@ -11218,11 +10877,10 @@
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
(match_operand 2 "" "")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
@@ -11250,7 +10908,7 @@
;; all of memory. This blocks insns from being moved across this point.
(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
""
"")
@@ -11325,8 +10983,8 @@
(define_expand "cmptf"
[(set (cc0) (compare (match_operand:TF 0 "gpc_reg_operand" "")
(match_operand:TF 1 "gpc_reg_operand" "")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT
- && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"
{
rs6000_compare_op0 = operands[0];
@@ -11447,8 +11105,8 @@
DONE;
}")
-;; A > 0 is best done using the portable sequence, so fail in that case.
-(define_expand "sgt"
+;; A >= 0 is best done the portable way for A an integer.
+(define_expand "sge"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"
@@ -11457,26 +11115,26 @@
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (GT, operands[0]);
+ rs6000_emit_sCOND (GE, operands[0]);
DONE;
}")
-;; A < 0 is best done in the portable way for A an integer.
-(define_expand "slt"
+;; A > 0 is best done using the portable sequence, so fail in that case.
+(define_expand "sgt"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"
{
- if (! rs6000_compare_fp_p
+ if (! rs6000_compare_fp_p
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (LT, operands[0]);
+ rs6000_emit_sCOND (GT, operands[0]);
DONE;
}")
-;; A >= 0 is best done the portable way for A an integer.
-(define_expand "sge"
+;; A <= 0 is best done the portable way for A an integer.
+(define_expand "sle"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"
@@ -11485,43 +11143,84 @@
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (GE, operands[0]);
+ rs6000_emit_sCOND (LE, operands[0]);
DONE;
}")
-;; A <= 0 is best done the portable way for A an integer.
-(define_expand "sle"
+;; A < 0 is best done in the portable way for A an integer.
+(define_expand "slt"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"
{
- if (! rs6000_compare_fp_p
+ if (! rs6000_compare_fp_p
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (LE, operands[0]);
+ rs6000_emit_sCOND (LT, operands[0]);
DONE;
}")
+(define_expand "sgeu"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
+
(define_expand "sgtu"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
+(define_expand "sleu"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
+
(define_expand "sltu"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
-(define_expand "sgeu"
+(define_expand "sunordered"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
- "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
+ "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
-(define_expand "sleu"
+(define_expand "sordered"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
- "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
+ "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
+
+(define_expand "suneq"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
+
+(define_expand "sunge"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
+
+(define_expand "sungt"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
+
+(define_expand "sunle"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
+
+(define_expand "sunlt"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
+
+(define_expand "sltgt"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
+
;; Here are the actual compare insns.
(define_insn "*cmpsi_internal1"
@@ -11530,7 +11229,7 @@
(match_operand:SI 2 "reg_or_short_operand" "rI")))]
""
"{cmp%I2|cmpw%I2} %0,%1,%2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
(define_insn "*cmpdi_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
@@ -11538,7 +11237,7 @@
(match_operand:DI 2 "reg_or_short_operand" "rI")))]
"TARGET_POWERPC64"
"cmpd%I2 %0,%1,%2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
;; If we are comparing a register for equality with a large constant,
;; we can do this with an XOR followed by a compare. But we need a scratch
@@ -11574,7 +11273,7 @@
(match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
""
"{cmpl%I2|cmplw%I2} %0,%1,%b2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
(define_insn "*cmpdi_internal2"
[(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
@@ -11582,7 +11281,7 @@
(match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
""
"cmpld%I2 %0,%1,%b2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
;; The following two insns don't exist as single insns, but if we provide
;; them, we can swap an add and compare, which will enable us to overlap more
@@ -11650,9 +11349,9 @@
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
(match_operand:TF 2 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "fcmpu %0,%1,%2\;bne %0,$+4\;fcmpu %0,%L1,%L2"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
[(set_attr "type" "fpcompare")
(set_attr "length" "12")])
@@ -11669,17 +11368,31 @@
[(match_operand 2 "cc_reg_operand" "y")
(const_int 0)]))]
""
- "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1"
+ [(set (attr "type")
+ (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
+ (set_attr "length" "12")])
+
+;; Same as above, but get the GT bit.
+(define_insn "move_from_CR_gt_bit"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
+ "TARGET_E500"
+ "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,1"
+ [(set_attr "type" "mfcr")
(set_attr "length" "12")])
;; Same as above, but get the OV/ORDERED bit.
(define_insn "move_from_CR_ov_bit"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] 724))]
+ (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
"TARGET_ISEL"
- "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
- [(set_attr "length" "12")])
+ "mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
+ [(set_attr "type" "mfcr")
+ (set_attr "length" "12")])
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
@@ -11687,8 +11400,12 @@
[(match_operand 2 "cc_reg_operand" "y")
(const_int 0)]))]
"TARGET_POWERPC64"
- "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1"
+ [(set (attr "type")
+ (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
(set_attr "length" "12")])
(define_insn ""
@@ -11699,9 +11416,9 @@
(const_int 0)))
(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
- %D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1
+ mfcr %3%Q2\;{rlinm.|rlwinm.} %3,%3,%J1,1
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "12,16")])
@@ -11714,7 +11431,7 @@
(const_int 0)))
(set (match_operand:SI 3 "gpc_reg_operand" "")
(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(match_op_dup 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
@@ -11743,9 +11460,13 @@
operands[4] = GEN_INT (count);
operands[5] = GEN_INT (put_bit);
- return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
+ return \"mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
}"
- [(set_attr "type" "cr_logical")
+ [(set (attr "type")
+ (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
(set_attr "length" "12")])
(define_insn ""
@@ -11778,7 +11499,7 @@
operands[5] = GEN_INT (count);
operands[6] = GEN_INT (put_bit);
- return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
+ return \"mfcr %4%Q2\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
}"
[(set_attr "type" "delayed_compare")
(set_attr "length" "12,16")])
@@ -11816,8 +11537,8 @@
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
"REGNO (operands[2]) != REGNO (operands[5])"
- "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
+ [(set_attr "type" "mfcr")
(set_attr "length" "20")])
(define_peephole
@@ -11830,8 +11551,8 @@
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
"TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
- "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
+ [(set_attr "type" "mfcr")
(set_attr "length" "20")])
;; There are some scc insns that can be done directly, without a compare.
@@ -11853,7 +11574,7 @@
(eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")))
(clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
{sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
@@ -11867,7 +11588,7 @@
(eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I")))
(clobber (match_scratch:DI 3 "=r,&r,r,r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
xor %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0
subfic %3,%1,0\;adde %0,%3,%1
@@ -11885,7 +11606,7 @@
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
(eq:SI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:SI 3 "=r,&r,r,r,r,r,&r,r,r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
{sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
@@ -11909,7 +11630,7 @@
(set (match_operand:SI 0 "gpc_reg_operand" "")
(eq:SI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 0)
(eq:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])
@@ -11927,7 +11648,7 @@
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
(eq:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:DI 3 "=r,&r,r,r,r,r,&r,r,r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0
subfic %3,%1,0\;adde. %0,%3,%1
@@ -11951,7 +11672,7 @@
(set (match_operand:DI 0 "gpc_reg_operand" "")
(eq:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(parallel [(set (match_dup 0)
(eq:DI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])
@@ -11980,7 +11701,7 @@
(plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3
{sfi|subfic} %0,%1,0\;{aze|addze} %0,%3
@@ -11998,7 +11719,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
{sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
@@ -12022,7 +11743,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (eq:SI (match_dup 1)
(match_dup 2))
@@ -12042,7 +11763,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r")
(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
{sfi|subfic} %0,%1,0\;{aze.|addze.} %0,%3
@@ -12067,7 +11788,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -12079,7 +11800,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
(neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
{ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
@@ -12095,7 +11816,7 @@
(lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
(const_int 31)))
(clobber (match_scratch:SI 2 "=&r"))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && !TARGET_ISEL"
+ "! TARGET_POWER && TARGET_32BIT && !TARGET_ISEL"
"{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
[(set_attr "length" "8")])
@@ -12104,7 +11825,7 @@
(lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
(const_int 63)))
(clobber (match_scratch:DI 2 "=&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"addic %2,%1,-1\;subfe %0,%2,%1"
[(set_attr "length" "8")])
@@ -12116,7 +11837,7 @@
(const_int 31))
(match_operand:SI 2 "gpc_reg_operand" "r")))
(clobber (match_scratch:SI 3 "=&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
[(set_attr "length" "8")])
@@ -12127,7 +11848,7 @@
(const_int 63))
(match_operand:DI 2 "gpc_reg_operand" "r")))
(clobber (match_scratch:DI 3 "=&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"addic %3,%1,-1\;addze %0,%2"
[(set_attr "length" "8")])
@@ -12141,7 +11862,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 "=&r,&r"))
(clobber (match_scratch:SI 4 "=X,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2
#"
@@ -12158,7 +11879,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 ""))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 3)
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1)))
(const_int 31))
@@ -12178,7 +11899,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %3,%1,-1\;addze. %3,%2
#"
@@ -12194,7 +11915,7 @@
(match_operand:DI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 3)
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1)))
(const_int 63))
@@ -12216,7 +11937,7 @@
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
(match_dup 2)))
(clobber (match_scratch:SI 3 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2
#"
@@ -12235,7 +11956,7 @@
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
(match_dup 2)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 0)
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
(match_dup 2)))
@@ -12257,7 +11978,7 @@
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
(match_dup 2)))
(clobber (match_scratch:DI 3 "=&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %3,%1,-1\;addze. %0,%2
#"
@@ -12276,7 +11997,7 @@
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
(match_dup 2)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(parallel [(set (match_dup 0)
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
(match_dup 2)))
@@ -12427,7 +12148,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
[(set_attr "length" "12")])
@@ -12435,7 +12156,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(leu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_short_operand" "rI")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0"
[(set_attr "length" "12")])
@@ -12447,7 +12168,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(leu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
#"
@@ -12462,7 +12183,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(leu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(leu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -12478,7 +12199,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(leu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
#"
@@ -12493,7 +12214,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(leu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(leu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -12502,26 +12223,11 @@
"")
(define_insn ""
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
- (compare:CC
- (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
- (match_operand:DI 2 "reg_or_short_operand" "rI,rI"))
- (const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
- (leu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
- "@
- subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
- #"
- [(set_attr "type" "compare")
- (set_attr "length" "12,16")])
-
-(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
(plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI"))
(match_operand:SI 3 "gpc_reg_operand" "r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{aze|addze} %0,%3"
[(set_attr "length" "8")])
@@ -12533,7 +12239,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3
#"
@@ -12548,7 +12254,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (leu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -12566,7 +12272,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{aze.|addze.} %0,%3
#"
@@ -12582,7 +12288,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -12594,7 +12300,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
[(set_attr "length" "12")])
@@ -12604,7 +12310,7 @@
(leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI")))
(match_operand:SI 3 "gpc_reg_operand" "r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0"
[(set_attr "length" "12")])
@@ -12617,7 +12323,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
#"
@@ -12633,7 +12339,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
(match_dup 3)))
@@ -12652,7 +12358,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
#"
@@ -12669,7 +12375,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
(match_dup 3)))
@@ -12803,7 +12509,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
@@ -12817,7 +12523,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(ltu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
@@ -12834,7 +12540,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(ltu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(ltu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -12847,7 +12553,7 @@
(plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
(match_operand:SI 3 "reg_or_short_operand" "rI,rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3"
@@ -12861,7 +12567,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
{ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
@@ -12878,7 +12584,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (ltu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -12896,7 +12602,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
@@ -12914,7 +12620,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -12926,7 +12632,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
@@ -13061,7 +12767,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
{ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
@@ -13071,7 +12777,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_neg_short_operand" "r,P")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0
addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0"
@@ -13085,7 +12791,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(geu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
{ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
@@ -13102,7 +12808,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(geu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(geu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13118,7 +12824,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(geu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0
@@ -13135,7 +12841,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(geu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(geu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13148,7 +12854,7 @@
(plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
(match_operand:SI 3 "gpc_reg_operand" "r,r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{aze|addze} %0,%3
{ai|addic} %0,%1,%n2\;{aze|addze} %0,%3"
@@ -13162,7 +12868,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
{ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3
@@ -13179,7 +12885,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (geu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -13197,7 +12903,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{aze.|addze.} %0,%3
{ai|addic} %0,%1,%n2\;{aze.|addze.} %0,%3
@@ -13215,7 +12921,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -13227,7 +12933,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
{sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
@@ -13239,7 +12945,7 @@
(geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
(match_operand:SI 3 "gpc_reg_operand" "r,r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0"
@@ -13254,7 +12960,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
{ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
@@ -13272,7 +12978,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2)))
(match_dup 3)))
@@ -13291,7 +12997,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
@@ -13310,7 +13016,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
(set (match_dup 4)
@@ -13322,7 +13028,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(const_int 0)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
[(set_attr "length" "12")])
@@ -13330,7 +13036,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(const_int 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subfic %0,%1,0\;addme %0,%0\;srdi %0,%0,63"
[(set_attr "length" "12")])
@@ -13342,7 +13048,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(gt:SI (match_dup 1) (const_int 0)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31
#"
@@ -13357,7 +13063,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(gt:SI (match_dup 1) (const_int 0)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(gt:SI (match_dup 1) (const_int 0)))
(set (match_dup 2)
@@ -13373,7 +13079,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(gt:DI (match_dup 1) (const_int 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63
#"
@@ -13388,7 +13094,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(gt:DI (match_dup 1) (const_int 0)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(gt:DI (match_dup 1) (const_int 0)))
(set (match_dup 2)
@@ -13440,7 +13146,7 @@
(plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(const_int 0))
(match_operand:SI 2 "gpc_reg_operand" "r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze|addze} %0,%2"
[(set_attr "length" "12")])
@@ -13449,7 +13155,7 @@
(plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(const_int 0))
(match_operand:DI 2 "gpc_reg_operand" "r")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"addc %0,%1,%1\;subfe %0,%1,%0\;addze %0,%2"
[(set_attr "length" "12")])
@@ -13461,7 +13167,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2
#"
@@ -13476,7 +13182,7 @@
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(plus:SI (gt:SI (match_dup 1) (const_int 0))
(match_dup 2)))
@@ -13493,7 +13199,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
#"
@@ -13508,7 +13214,7 @@
(match_operand:DI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 3)
(plus:DI (gt:DI (match_dup 1) (const_int 0))
(match_dup 2)))
@@ -13526,7 +13232,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze.|addze.} %0,%2
#"
@@ -13542,7 +13248,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
(set (match_dup 3)
@@ -13559,7 +13265,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2
#"
@@ -13575,7 +13281,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
(set (match_dup 3)
@@ -13660,7 +13366,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(const_int 0))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
[(set_attr "length" "12")])
@@ -13668,7 +13374,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(neg:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(const_int 0))))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subfic %0,%1,0\;addme %0,%0\;sradi %0,%0,63"
[(set_attr "length" "12")])
@@ -13684,7 +13390,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
[(set_attr "length" "12")])
@@ -13692,7 +13398,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_short_operand" "rI")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg %0,%0"
[(set_attr "length" "12")])
@@ -13704,7 +13410,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(gtu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
#"
@@ -13719,7 +13425,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(gtu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(gtu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13735,7 +13441,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(gtu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0
#"
@@ -13750,7 +13456,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(gtu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(gtu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13763,7 +13469,7 @@
(plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_short_operand" "I,rI"))
(match_operand:SI 3 "reg_or_short_operand" "r,rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %0,%1,%k2\;{aze|addze} %0,%3
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3"
@@ -13774,7 +13480,7 @@
(plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_short_operand" "I,rI"))
(match_operand:DI 3 "reg_or_short_operand" "r,rI")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %0,%1,%k2\;addze %0,%3
subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subf%I3c %0,%0,%3"
@@ -13788,7 +13494,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3
{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
@@ -13805,7 +13511,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (gtu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -13822,7 +13528,7 @@
(match_operand:DI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=&r,&r,&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %4,%1,%k2\;addze. %4,%3
subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3
@@ -13839,7 +13545,7 @@
(match_operand:DI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 4 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 4)
(plus:DI (gtu:DI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -13857,7 +13563,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %0,%1,%k2\;{aze.|addze.} %0,%3
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
@@ -13875,7 +13581,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -13892,7 +13598,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %0,%1,%k2\;addze. %0,%3
subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subfc. %0,%0,%3
@@ -13910,7 +13616,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -13922,7 +13628,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
[(set_attr "length" "8")])
@@ -13930,7 +13636,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(neg:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_short_operand" "rI"))))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subf%I2c %0,%1,%2\;subfe %0,%0,%0"
[(set_attr "length" "8")])
@@ -13942,7 +13648,7 @@
[(set (pc)
(if_then_else (match_operator 1 "branch_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
@@ -13957,7 +13663,7 @@
[(set (pc)
(if_then_else (match_operator 0 "branch_comparison_operator"
[(match_operand 1
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(return)
(pc)))]
@@ -13973,7 +13679,7 @@
[(set (pc)
(if_then_else (match_operator 1 "branch_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
@@ -13988,7 +13694,7 @@
[(set (pc)
(if_then_else (match_operator 0 "branch_comparison_operator"
[(match_operand 1
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(pc)
(return)))]
@@ -14007,56 +13713,57 @@
; (eq:SI (reg:CCFP 68) (const_int 0)))
; (const_int 1)))
; which are generated by the branch logic.
+; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
-(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+(define_insn "*cceq_ior_compare"
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1 "boolean_operator"
- [(match_operator:SI 2
+ [(match_operator:SI 2
"branch_positive_comparison_operator"
[(match_operand 3
- "cc_reg_operand" "y")
+ "cc_reg_operand" "y,y")
(const_int 0)])
- (match_operator:SI 4
+ (match_operator:SI 4
"branch_positive_comparison_operator"
[(match_operand 5
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])])
(const_int 1)))]
""
"cr%q1 %E0,%j2,%j4"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
; Why is the constant -1 here, but 1 in the previous pattern?
; Because ~1 has all but the low bit set.
(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
- [(not:SI (match_operator:SI 2
+ [(not:SI (match_operator:SI 2
"branch_positive_comparison_operator"
[(match_operand 3
- "cc_reg_operand" "y")
+ "cc_reg_operand" "y,y")
(const_int 0)]))
(match_operator:SI 4
"branch_positive_comparison_operator"
[(match_operand 5
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])])
(const_int -1)))]
""
"cr%q1 %E0,%j2,%j4"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
-(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+(define_insn "*cceq_rev_compare"
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1
"branch_positive_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])
(const_int 0)))]
- "!TARGET_SPE"
+ ""
"{crnor %E0,%j1,%j1|crnot %E0,%j1}"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
;; If we are comparing the result of two comparisons, this can be done
;; using creqv or crxor.
@@ -14237,7 +13944,7 @@
/* Only use this on innermost loops. */
if (INTVAL (operands[3]) > 1)
FAIL;
- if (TARGET_POWERPC64)
+ if (TARGET_64BIT)
{
if (GET_MODE (operands[0]) != DImode)
FAIL;
@@ -14263,7 +13970,7 @@
(const_int -1)))
(clobber (match_scratch:CC 2 ""))
(clobber (match_scratch:SI 3 ""))])]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"")
(define_expand "ctrdi"
@@ -14277,7 +13984,7 @@
(const_int -1)))
(clobber (match_scratch:CC 2 ""))
(clobber (match_scratch:DI 3 ""))])]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"")
;; We need to be able to do this for any operand, including MEM, or we
@@ -14288,16 +13995,16 @@
(define_insn "*ctrsi_internal1"
[(set (pc)
- (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14308,20 +14015,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrsi_internal2"
[(set (pc)
- (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14332,20 +14039,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal1"
[(set (pc)
- (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14356,20 +14063,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal2"
[(set (pc)
- (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14380,22 +14087,22 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
;; Similar, but we can use GE since we have a REG_NONNEG.
(define_insn "*ctrsi_internal3"
[(set (pc)
- (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&X"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14406,20 +14113,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrsi_internal4"
[(set (pc)
- (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&X"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14430,20 +14137,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal3"
[(set (pc)
- (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14454,20 +14161,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal4"
[(set (pc)
- (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14478,22 +14185,22 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
;; Similar but use EQ
(define_insn "*ctrsi_internal5"
[(set (pc)
- (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14504,20 +14211,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrsi_internal6"
[(set (pc)
- (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14528,20 +14235,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal5"
[(set (pc)
- (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14552,20 +14259,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal6"
[(set (pc)
- (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14576,7 +14283,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
;; Now the splitters if we could not allocate the CTR register
@@ -14592,7 +14299,7 @@
(const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 3)
(compare:CC (plus:SI (match_dup 1)
(const_int -1))
@@ -14618,7 +14325,7 @@
(plus:SI (match_dup 1) (const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed
+ "TARGET_32BIT && reload_completed
&& ! gpc_reg_operand (operands[0], SImode)"
[(parallel [(set (match_dup 3)
(compare:CC (plus:SI (match_dup 1)
@@ -14647,7 +14354,7 @@
(const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:DI 4 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(parallel [(set (match_dup 3)
(compare:CC (plus:DI (match_dup 1)
(const_int -1))
@@ -14673,7 +14380,7 @@
(plus:DI (match_dup 1) (const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:DI 4 ""))]
- "TARGET_POWERPC64 && reload_completed
+ "TARGET_64BIT && reload_completed
&& ! gpc_reg_operand (operands[0], DImode)"
[(parallel [(set (match_dup 3)
(compare:CC (plus:DI (match_dup 1)
@@ -14690,7 +14397,6 @@
"
{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
const0_rtx); }")
-
(define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]
@@ -14733,44 +14439,70 @@
DONE;
}")
+(define_insn "*movesi_from_cr_one"
+ [(match_parallel 0 "mfcr_operation"
+ [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
+ (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
+ (match_operand 3 "immediate_operand" "n")]
+ UNSPEC_MOVESI_FROM_CR))])]
+ "TARGET_MFCRF"
+ "*
+{
+ int mask = 0;
+ int i;
+ for (i = 0; i < XVECLEN (operands[0], 0); i++)
+ {
+ mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
+ operands[4] = GEN_INT (mask);
+ output_asm_insn (\"mfcr %1,%4\", operands);
+ }
+ return \"\";
+}"
+ [(set_attr "type" "mfcrf")])
+
(define_insn "movesi_from_cr"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71)
- (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
+ (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)]
+ UNSPEC_MOVESI_FROM_CR))]
""
"mfcr %0"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mfcr")])
(define_insn "*stmw"
- [(match_parallel 0 "stmw_operation"
- [(set (match_operand:SI 1 "memory_operand" "=m")
- (match_operand:SI 2 "gpc_reg_operand" "r"))])]
- "TARGET_MULTIPLE"
- "{stm|stmw} %2,%1")
+ [(match_parallel 0 "stmw_operation"
+ [(set (match_operand:SI 1 "memory_operand" "=m")
+ (match_operand:SI 2 "gpc_reg_operand" "r"))])]
+ "TARGET_MULTIPLE"
+ "{stm|stmw} %2,%1")
(define_insn "*save_fpregs_si"
- [(match_parallel 0 "any_operand"
- [(clobber (match_operand:SI 1 "register_operand" "=l"))
- (use (match_operand:SI 2 "call_operand" "s"))
- (set (match_operand:DF 3 "memory_operand" "=m")
- (match_operand:DF 4 "gpc_reg_operand" "f"))])]
- "TARGET_32BIT"
- "bl %z2")
+ [(match_parallel 0 "any_operand"
+ [(clobber (match_operand:SI 1 "register_operand" "=l"))
+ (use (match_operand:SI 2 "call_operand" "s"))
+ (set (match_operand:DF 3 "memory_operand" "=m")
+ (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+ "TARGET_32BIT"
+ "bl %z2"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
(define_insn "*save_fpregs_di"
- [(match_parallel 0 "any_operand"
- [(clobber (match_operand:DI 1 "register_operand" "=l"))
- (use (match_operand:DI 2 "call_operand" "s"))
- (set (match_operand:DF 3 "memory_operand" "=m")
- (match_operand:DF 4 "gpc_reg_operand" "f"))])]
- "TARGET_64BIT"
- "bl %z2")
+ [(match_parallel 0 "any_operand"
+ [(clobber (match_operand:DI 1 "register_operand" "=l"))
+ (use (match_operand:DI 2 "call_operand" "s"))
+ (set (match_operand:DF 3 "memory_operand" "=m")
+ (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+ "TARGET_64BIT"
+ "bl %z2"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
; These are to explain that changes to the stack pointer should
; not be moved over stores to stack memory.
(define_insn "stack_tie"
[(set (match_operand:BLK 0 "memory_operand" "+m")
- (unspec:BLK [(match_dup 0)] 5))]
+ (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
""
""
[(set_attr "length" "0")])
@@ -14792,7 +14524,7 @@
(define_expand "movsi_to_cr_one"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
- (match_dup 2)] 20))]
+ (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
""
"operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
@@ -14801,7 +14533,7 @@
[(set (match_operand:CC 1 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
(match_operand 3 "immediate_operand" "n")]
- 20))])]
+ UNSPEC_MOVESI_TO_CR))])]
""
"*
{
@@ -14812,18 +14544,19 @@
operands[4] = GEN_INT (mask);
return \"mtcrf %4,%2\";
}"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mtcr")])
-(define_insn ""
+(define_insn "*mtcrfsi"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand 2 "immediate_operand" "n")] 20))]
+ (match_operand 2 "immediate_operand" "n")]
+ UNSPEC_MOVESI_TO_CR))]
"GET_CODE (operands[0]) == REG
&& CR_REGNO_P (REGNO (operands[0]))
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
"mtcrf %R0,%1"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mtcr")])
; The load-multiple instructions have similar properties.
; Note that "load_multiple" is a name known to the machine-independent
@@ -14879,9 +14612,6 @@
""
"
{
-#if TARGET_AIX
- rs6000_emit_eh_toc_restore (EH_RETURN_STACKADJ_RTX);
-#endif
if (TARGET_32BIT)
emit_insn (gen_eh_set_lr_si (operands[0]));
else
@@ -14891,48 +14621,27 @@
; We can't expand this before we know where the link register is stored.
(define_insn "eh_set_lr_si"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 9)
+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
+ UNSPECV_EH_RR)
(clobber (match_scratch:SI 1 "=&b"))]
"TARGET_32BIT"
"#")
(define_insn "eh_set_lr_di"
- [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 9)
+ [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
+ UNSPECV_EH_RR)
(clobber (match_scratch:DI 1 "=&b"))]
"TARGET_64BIT"
"#")
(define_split
- [(unspec_volatile [(match_operand 0 "register_operand" "")] 9)
+ [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
(clobber (match_scratch 1 ""))]
"reload_completed"
[(const_int 0)]
"
{
- rs6000_stack_t *info = rs6000_stack_info ();
-
- if (info->lr_save_p)
- {
- rtx frame_rtx = stack_pointer_rtx;
- int sp_offset = 0;
- rtx tmp;
-
- if (frame_pointer_needed
- || current_function_calls_alloca
- || info->total_size > 32767)
- {
- emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
- frame_rtx = operands[1];
- }
- else if (info->push_p)
- sp_offset = info->total_size;
-
- tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
- tmp = gen_rtx_MEM (Pmode, tmp);
- emit_move_insn (tmp, operands[0]);
- }
- else
- emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
+ rs6000_emit_eh_reg_restore (operands[0], operands[1]);
DONE;
}")
diff --git a/contrib/gcc/config/rs6000/rs64.md b/contrib/gcc/config/rs6000/rs64.md
new file mode 100644
index 0000000..4d99875
--- /dev/null
+++ b/contrib/gcc/config/rs6000/rs64.md
@@ -0,0 +1,128 @@
+;; Scheduling description for IBM RS64 processors.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "rs64,rs64fp")
+(define_cpu_unit "iu_rs64" "rs64")
+(define_cpu_unit "mciu_rs64" "rs64")
+(define_cpu_unit "fpu_rs64" "rs64fp")
+(define_cpu_unit "lsu_rs64,bpu_rs64" "rs64")
+
+;; RS64a 64-bit IU, LSU, FPU, BPU
+
+(define_insn_reservation "rs64a-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-fpload" 3
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "rs64a"))
+ "iu_rs64")
+
+(define_insn_reservation "rs64a-imul" 20
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*13")
+
+(define_insn_reservation "rs64a-imul2" 12
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*5")
+
+(define_insn_reservation "rs64a-imul3" 8
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*2")
+
+(define_insn_reservation "rs64a-lmul" 34
+ (and (eq_attr "type" "lmul,lmul_compare")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*34")
+
+(define_insn_reservation "rs64a-idiv" 66
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*66")
+
+(define_insn_reservation "rs64a-ldiv" 66
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*66")
+
+(define_insn_reservation "rs64a-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "rs64a"))
+ "iu_rs64,nothing,bpu_rs64")
+
+(define_insn_reservation "rs64a-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64,bpu_rs64")
+
+(define_insn_reservation "rs64a-fp" 4
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64")
+
+(define_insn_reservation "rs64a-sdiv" 31
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64*31")
+
+(define_insn_reservation "rs64a-sqrt" 49
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64*49")
+
+(define_insn_reservation "rs64a-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-mtjmpr" 3
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch,cr_logical,delayed_cr")
+ (eq_attr "cpu" "rs64a"))
+ "bpu_rs64")
+
diff --git a/contrib/gcc/config/rs6000/rtems.h b/contrib/gcc/config/rs6000/rtems.h
index 7e75846..0245269 100644
--- a/contrib/gcc/config/rs6000/rtems.h
+++ b/contrib/gcc/config/rs6000/rtems.h
@@ -2,22 +2,22 @@
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Specify predefined symbols in preprocessor. */
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */
builtin_assert ("system=rtems"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
diff --git a/contrib/gcc/config/rs6000/sol-ci.asm b/contrib/gcc/config/rs6000/sol-ci.asm
index b168960..cc97b0a 100644
--- a/contrib/gcc/config/rs6000/sol-ci.asm
+++ b/contrib/gcc/config/rs6000/sol-ci.asm
@@ -39,6 +39,7 @@
.file "scrti.s"
.ident "GNU C scrti.s"
+#ifndef __powerpc64__
# Start of .text
.section ".text"
.globl _ex_text0
@@ -102,3 +103,4 @@ _fini: stwu %r1,-16(%r1)
.space 4
.weak environ
.set environ,_environ
+#endif
diff --git a/contrib/gcc/config/rs6000/sol-cn.asm b/contrib/gcc/config/rs6000/sol-cn.asm
index b1da7d7..673540f 100644
--- a/contrib/gcc/config/rs6000/sol-cn.asm
+++ b/contrib/gcc/config/rs6000/sol-cn.asm
@@ -39,6 +39,7 @@
.file "scrtn.s"
.ident "GNU C scrtn.s"
+#ifndef __powerpc64__
# Default versions of exception handling register/deregister
.weak _ex_register
.weak _ex_deregister
@@ -80,3 +81,4 @@ _ex_range1:
mtlr %r0
addi %r1,%r1,16
blr
+#endif
diff --git a/contrib/gcc/config/rs6000/spe.h b/contrib/gcc/config/rs6000/spe.h
index b15dac5..1676516 100644
--- a/contrib/gcc/config/rs6000/spe.h
+++ b/contrib/gcc/config/rs6000/spe.h
@@ -2,22 +2,22 @@
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* As a special exception, if you include this header file into source
files compiled by GCC, this header file does not by itself cause
@@ -45,242 +45,239 @@ typedef unsigned __vector __ev64_u32__;
typedef long long __vector __ev64_s64__;
typedef unsigned long long __vector __ev64_u64__;
typedef float __vector __ev64_fs__;
-typedef int __vector __ev64_opaque__;
#define __v2si __ev64_opaque__
#define __v2sf __ev64_fs__
-#define __ev_addw(a,b) __builtin_spe_evaddw((__v2si) (a), (__v2si) (b))
-#define __ev_addiw(a,b) __builtin_spe_evaddiw ((__v2si) (a), (b))
-#define __ev_subfw(a,b) __builtin_spe_evsubfw ((__v2si) (a), (__v2si) (b))
-#define __ev_subw(a,b) __builtin_spe_evsubfw ((__v2si) (b), (__v2si) (a))
-/* ??? The spe_evsubifw pattern accepts operands reversed, so we need to also
- reverse them here between the intrinsic and the builtin function. */
-#define __ev_subifw(a,b) __builtin_spe_evsubifw ((__v2si) (b), (a))
-#define __ev_subiw(a,b) __builtin_spe_evsubifw ((__v2si) (a), (b))
-#define __ev_abs(a) __builtin_spe_evabs ((__v2si) (a))
-#define __ev_neg(a) __builtin_spe_evneg ((__v2si) (a))
-#define __ev_extsb(a) __builtin_spe_evextsb ((__v2si) (a))
-#define __ev_extsh(a) __builtin_spe_evextsh ((__v2si) (a))
-#define __ev_and(a,b) __builtin_spe_evand ((__v2si) (a), (__v2si) (b))
-#define __ev_or(a,b) __builtin_spe_evor ((__v2si) (a), (__v2si) (b))
-#define __ev_xor(a,b) __builtin_spe_evxor ((__v2si) (a), (__v2si) (b))
-#define __ev_nand(a,b) __builtin_spe_evnand ((__v2si) (a), (__v2si) (b))
-#define __ev_nor(a,b) __builtin_spe_evnor ((__v2si) (a), (__v2si) (b))
-#define __ev_eqv(a,b) __builtin_spe_eveqv ((__v2si) (a), (__v2si) (b))
-#define __ev_andc(a,b) __builtin_spe_evandc ((__v2si) (a), (__v2si) (b))
-#define __ev_orc(a,b) __builtin_spe_evorc ((__v2si) (a), (__v2si) (b))
-#define __ev_rlw(a,b) __builtin_spe_evrlw ((__v2si) (a), (__v2si) (b))
-#define __ev_rlwi(a,b) __builtin_spe_evrlwi ((__v2si) (a), (b))
-#define __ev_slw(a,b) __builtin_spe_evslw ((__v2si) (a), (__v2si) (b))
-#define __ev_slwi(a,b) __builtin_spe_evslwi ((__v2si) (a), (b))
-#define __ev_srws(a,b) __builtin_spe_evsrws ((__v2si) (a), (__v2si) (b))
-#define __ev_srwu(a,b) __builtin_spe_evsrwu ((__v2si) (a), (__v2si) (b))
-#define __ev_srwis(a,b) __builtin_spe_evsrwis ((__v2si) (a), (b))
-#define __ev_srwiu(a,b) __builtin_spe_evsrwiu ((__v2si) (a), (b))
-#define __ev_cntlzw(a) __builtin_spe_evcntlzw ((__v2si) (a))
-#define __ev_cntlsw(a) __builtin_spe_evcntlsw ((__v2si) (a))
-#define __ev_rndw(a) __builtin_spe_evrndw ((__v2si) (a))
-#define __ev_mergehi(a,b) __builtin_spe_evmergehi ((__v2si) (a), (__v2si) (b))
-#define __ev_mergelo(a,b) __builtin_spe_evmergelo ((__v2si) (a), (__v2si) (b))
-#define __ev_mergelohi(a,b) __builtin_spe_evmergelohi ((__v2si) (a), (__v2si) (b))
-#define __ev_mergehilo(a,b) __builtin_spe_evmergehilo ((__v2si) (a), (__v2si) (b))
-#define __ev_splati(a) __builtin_spe_evsplati ((a))
-#define __ev_splatfi(a) __builtin_spe_evsplatfi ((a))
-#define __ev_divws(a,b) __builtin_spe_evdivws ((__v2si) (a), (__v2si) (b))
-#define __ev_divwu(a,b) __builtin_spe_evdivwu ((__v2si) (a), (__v2si) (b))
-#define __ev_mra(a) __builtin_spe_evmra ((__v2si) (a))
+#define __ev_addw __builtin_spe_evaddw
+#define __ev_addiw __builtin_spe_evaddiw
+#define __ev_subfw(a,b) __builtin_spe_evsubfw ((b), (a))
+#define __ev_subw __builtin_spe_evsubfw
+#define __ev_subifw(a,b) __builtin_spe_evsubifw ((b), (a))
+#define __ev_subiw __builtin_spe_evsubifw
+#define __ev_abs __builtin_spe_evabs
+#define __ev_neg __builtin_spe_evneg
+#define __ev_extsb __builtin_spe_evextsb
+#define __ev_extsh __builtin_spe_evextsh
+#define __ev_and __builtin_spe_evand
+#define __ev_or __builtin_spe_evor
+#define __ev_xor __builtin_spe_evxor
+#define __ev_nand __builtin_spe_evnand
+#define __ev_nor __builtin_spe_evnor
+#define __ev_eqv __builtin_spe_eveqv
+#define __ev_andc __builtin_spe_evandc
+#define __ev_orc __builtin_spe_evorc
+#define __ev_rlw __builtin_spe_evrlw
+#define __ev_rlwi __builtin_spe_evrlwi
+#define __ev_slw __builtin_spe_evslw
+#define __ev_slwi __builtin_spe_evslwi
+#define __ev_srws __builtin_spe_evsrws
+#define __ev_srwu __builtin_spe_evsrwu
+#define __ev_srwis __builtin_spe_evsrwis
+#define __ev_srwiu __builtin_spe_evsrwiu
+#define __ev_cntlzw __builtin_spe_evcntlzw
+#define __ev_cntlsw __builtin_spe_evcntlsw
+#define __ev_rndw __builtin_spe_evrndw
+#define __ev_mergehi __builtin_spe_evmergehi
+#define __ev_mergelo __builtin_spe_evmergelo
+#define __ev_mergelohi __builtin_spe_evmergelohi
+#define __ev_mergehilo __builtin_spe_evmergehilo
+#define __ev_splati __builtin_spe_evsplati
+#define __ev_splatfi __builtin_spe_evsplatfi
+#define __ev_divws __builtin_spe_evdivws
+#define __ev_divwu __builtin_spe_evdivwu
+#define __ev_mra __builtin_spe_evmra
#define __brinc __builtin_spe_brinc
/* Loads. */
-#define __ev_lddx(a,b) __builtin_spe_evlddx ((void *)(a), (b))
-#define __ev_ldwx(a,b) __builtin_spe_evldwx ((void *)(a), (b))
-#define __ev_ldhx(a,b) __builtin_spe_evldhx ((void *)(a), (b))
-#define __ev_lwhex(a,b) __builtin_spe_evlwhex ((a), (b))
-#define __ev_lwhoux(a,b) __builtin_spe_evlwhoux ((a), (b))
-#define __ev_lwhosx(a,b) __builtin_spe_evlwhosx ((a), (b))
-#define __ev_lwwsplatx(a,b) __builtin_spe_evlwwsplatx ((a), (b))
-#define __ev_lwhsplatx(a,b) __builtin_spe_evlwhsplatx ((a), (b))
-#define __ev_lhhesplatx(a,b) __builtin_spe_evlhhesplatx ((a), (b))
-#define __ev_lhhousplatx(a,b) __builtin_spe_evlhhousplatx ((a), (b))
-#define __ev_lhhossplatx(a,b) __builtin_spe_evlhhossplatx ((a), (b))
-#define __ev_ldd(a,b) __builtin_spe_evldd ((void *)(a), (b))
-#define __ev_ldw(a,b) __builtin_spe_evldw ((void *)(a), (b))
-#define __ev_ldh(a,b) __builtin_spe_evldh ((void *)(a), (b))
-#define __ev_lwhe(a,b) __builtin_spe_evlwhe ((a), (b))
-#define __ev_lwhou(a,b) __builtin_spe_evlwhou ((a), (b))
-#define __ev_lwhos(a,b) __builtin_spe_evlwhos ((a), (b))
-#define __ev_lwwsplat(a,b) __builtin_spe_evlwwsplat ((a), (b))
-#define __ev_lwhsplat(a,b) __builtin_spe_evlwhsplat ((a), (b))
-#define __ev_lhhesplat(a,b) __builtin_spe_evlhhesplat ((a), (b))
-#define __ev_lhhousplat(a,b) __builtin_spe_evlhhousplat ((a), (b))
-#define __ev_lhhossplat(a,b) __builtin_spe_evlhhossplat ((a), (b))
+#define __ev_lddx __builtin_spe_evlddx
+#define __ev_ldwx __builtin_spe_evldwx
+#define __ev_ldhx __builtin_spe_evldhx
+#define __ev_lwhex __builtin_spe_evlwhex
+#define __ev_lwhoux __builtin_spe_evlwhoux
+#define __ev_lwhosx __builtin_spe_evlwhosx
+#define __ev_lwwsplatx __builtin_spe_evlwwsplatx
+#define __ev_lwhsplatx __builtin_spe_evlwhsplatx
+#define __ev_lhhesplatx __builtin_spe_evlhhesplatx
+#define __ev_lhhousplatx __builtin_spe_evlhhousplatx
+#define __ev_lhhossplatx __builtin_spe_evlhhossplatx
+#define __ev_ldd __builtin_spe_evldd
+#define __ev_ldw __builtin_spe_evldw
+#define __ev_ldh __builtin_spe_evldh
+#define __ev_lwhe __builtin_spe_evlwhe
+#define __ev_lwhou __builtin_spe_evlwhou
+#define __ev_lwhos __builtin_spe_evlwhos
+#define __ev_lwwsplat __builtin_spe_evlwwsplat
+#define __ev_lwhsplat __builtin_spe_evlwhsplat
+#define __ev_lhhesplat __builtin_spe_evlhhesplat
+#define __ev_lhhousplat __builtin_spe_evlhhousplat
+#define __ev_lhhossplat __builtin_spe_evlhhossplat
/* Stores. */
-#define __ev_stddx(a,b,c) __builtin_spe_evstddx ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdwx(a,b,c) __builtin_spe_evstdwx ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdhx(a,b,c) __builtin_spe_evstdhx ((__v2si)(a), (void *)(b), (c))
-#define __ev_stwwex(a,b,c) __builtin_spe_evstwwex ((__v2si)(a), (b), (c))
-#define __ev_stwwox(a,b,c) __builtin_spe_evstwwox ((__v2si)(a), (b), (c))
-#define __ev_stwhex(a,b,c) __builtin_spe_evstwhex ((__v2si)(a), (b), (c))
-#define __ev_stwhox(a,b,c) __builtin_spe_evstwhox ((__v2si)(a), (b), (c))
-#define __ev_stdd(a,b,c) __builtin_spe_evstdd ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdw(a,b,c) __builtin_spe_evstdw ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdh(a,b,c) __builtin_spe_evstdh ((__v2si)(a), (void *)(b), (c))
-#define __ev_stwwe(a,b,c) __builtin_spe_evstwwe ((__v2si)(a), (b), (c))
-#define __ev_stwwo(a,b,c) __builtin_spe_evstwwo ((__v2si)(a), (b), (c))
-#define __ev_stwhe(a,b,c) __builtin_spe_evstwhe ((__v2si)(a), (b), (c))
-#define __ev_stwho(a,b,c) __builtin_spe_evstwho ((__v2si)(a), (b), (c))
+#define __ev_stddx __builtin_spe_evstddx
+#define __ev_stdwx __builtin_spe_evstdwx
+#define __ev_stdhx __builtin_spe_evstdhx
+#define __ev_stwwex __builtin_spe_evstwwex
+#define __ev_stwwox __builtin_spe_evstwwox
+#define __ev_stwhex __builtin_spe_evstwhex
+#define __ev_stwhox __builtin_spe_evstwhox
+#define __ev_stdd __builtin_spe_evstdd
+#define __ev_stdw __builtin_spe_evstdw
+#define __ev_stdh __builtin_spe_evstdh
+#define __ev_stwwe __builtin_spe_evstwwe
+#define __ev_stwwo __builtin_spe_evstwwo
+#define __ev_stwhe __builtin_spe_evstwhe
+#define __ev_stwho __builtin_spe_evstwho
/* Fixed point complex. */
-#define __ev_mhossf(a, b) __builtin_spe_evmhossf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmf(a, b) __builtin_spe_evmhosmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmi(a, b) __builtin_spe_evmhosmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumi(a, b) __builtin_spe_evmhoumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessf(a, b) __builtin_spe_evmhessf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmf(a, b) __builtin_spe_evmhesmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmi(a, b) __builtin_spe_evmhesmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumi(a, b) __builtin_spe_evmheumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mhossfa(a, b) __builtin_spe_evmhossfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmfa(a, b) __builtin_spe_evmhosmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmia(a, b) __builtin_spe_evmhosmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumia(a, b) __builtin_spe_evmhoumia ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessfa(a, b) __builtin_spe_evmhessfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmfa(a, b) __builtin_spe_evmhesmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmia(a, b) __builtin_spe_evmhesmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumia(a, b) __builtin_spe_evmheumia ((__v2si) (a), (__v2si) (b))
+#define __ev_mhossf __builtin_spe_evmhossf
+#define __ev_mhosmf __builtin_spe_evmhosmf
+#define __ev_mhosmi __builtin_spe_evmhosmi
+#define __ev_mhoumi __builtin_spe_evmhoumi
+#define __ev_mhessf __builtin_spe_evmhessf
+#define __ev_mhesmf __builtin_spe_evmhesmf
+#define __ev_mhesmi __builtin_spe_evmhesmi
+#define __ev_mheumi __builtin_spe_evmheumi
+#define __ev_mhossfa __builtin_spe_evmhossfa
+#define __ev_mhosmfa __builtin_spe_evmhosmfa
+#define __ev_mhosmia __builtin_spe_evmhosmia
+#define __ev_mhoumia __builtin_spe_evmhoumia
+#define __ev_mhessfa __builtin_spe_evmhessfa
+#define __ev_mhesmfa __builtin_spe_evmhesmfa
+#define __ev_mhesmia __builtin_spe_evmhesmia
+#define __ev_mheumia __builtin_spe_evmheumia
#define __ev_mhoumf __ev_mhoumi
#define __ev_mheumf __ev_mheumi
#define __ev_mhoumfa __ev_mhoumia
#define __ev_mheumfa __ev_mheumia
-#define __ev_mhossfaaw(a, b) __builtin_spe_evmhossfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhossiaaw(a, b) __builtin_spe_evmhossiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmfaaw(a, b) __builtin_spe_evmhosmfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmiaaw(a, b) __builtin_spe_evmhosmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhousiaaw(a, b) __builtin_spe_evmhousiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumiaaw(a, b) __builtin_spe_evmhoumiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessfaaw(a, b) __builtin_spe_evmhessfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessiaaw(a, b) __builtin_spe_evmhessiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmfaaw(a, b) __builtin_spe_evmhesmfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmiaaw(a, b) __builtin_spe_evmhesmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheusiaaw(a, b) __builtin_spe_evmheusiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumiaaw(a, b) __builtin_spe_evmheumiaaw ((__v2si) (a), (__v2si) (b))
+#define __ev_mhossfaaw __builtin_spe_evmhossfaaw
+#define __ev_mhossiaaw __builtin_spe_evmhossiaaw
+#define __ev_mhosmfaaw __builtin_spe_evmhosmfaaw
+#define __ev_mhosmiaaw __builtin_spe_evmhosmiaaw
+#define __ev_mhousiaaw __builtin_spe_evmhousiaaw
+#define __ev_mhoumiaaw __builtin_spe_evmhoumiaaw
+#define __ev_mhessfaaw __builtin_spe_evmhessfaaw
+#define __ev_mhessiaaw __builtin_spe_evmhessiaaw
+#define __ev_mhesmfaaw __builtin_spe_evmhesmfaaw
+#define __ev_mhesmiaaw __builtin_spe_evmhesmiaaw
+#define __ev_mheusiaaw __builtin_spe_evmheusiaaw
+#define __ev_mheumiaaw __builtin_spe_evmheumiaaw
#define __ev_mhousfaaw __ev_mhousiaaw
#define __ev_mhoumfaaw __ev_mhoumiaaw
#define __ev_mheusfaaw __ev_mheusiaaw
#define __ev_mheumfaaw __ev_mheumiaaw
-#define __ev_mhossfanw(a, b) __builtin_spe_evmhossfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhossianw(a, b) __builtin_spe_evmhossianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmfanw(a, b) __builtin_spe_evmhosmfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmianw(a, b) __builtin_spe_evmhosmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhousianw(a, b) __builtin_spe_evmhousianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumianw(a, b) __builtin_spe_evmhoumianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessfanw(a, b) __builtin_spe_evmhessfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessianw(a, b) __builtin_spe_evmhessianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmfanw(a, b) __builtin_spe_evmhesmfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmianw(a, b) __builtin_spe_evmhesmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheusianw(a, b) __builtin_spe_evmheusianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumianw(a, b) __builtin_spe_evmheumianw ((__v2si) (a), (__v2si) (b))
+#define __ev_mhossfanw __builtin_spe_evmhossfanw
+#define __ev_mhossianw __builtin_spe_evmhossianw
+#define __ev_mhosmfanw __builtin_spe_evmhosmfanw
+#define __ev_mhosmianw __builtin_spe_evmhosmianw
+#define __ev_mhousianw __builtin_spe_evmhousianw
+#define __ev_mhoumianw __builtin_spe_evmhoumianw
+#define __ev_mhessfanw __builtin_spe_evmhessfanw
+#define __ev_mhessianw __builtin_spe_evmhessianw
+#define __ev_mhesmfanw __builtin_spe_evmhesmfanw
+#define __ev_mhesmianw __builtin_spe_evmhesmianw
+#define __ev_mheusianw __builtin_spe_evmheusianw
+#define __ev_mheumianw __builtin_spe_evmheumianw
#define __ev_mhousfanw __ev_mhousianw
#define __ev_mhoumfanw __ev_mhoumianw
#define __ev_mheusfanw __ev_mheusianw
#define __ev_mheumfanw __ev_mheumianw
-#define __ev_mhogsmfaa(a, b) __builtin_spe_evmhogsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogsmiaa(a, b) __builtin_spe_evmhogsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogumiaa(a, b) __builtin_spe_evmhogumiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmfaa(a, b) __builtin_spe_evmhegsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmiaa(a, b) __builtin_spe_evmhegsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegumiaa(a, b) __builtin_spe_evmhegumiaa ((__v2si) (a), (__v2si) (b))
+#define __ev_mhogsmfaa __builtin_spe_evmhogsmfaa
+#define __ev_mhogsmiaa __builtin_spe_evmhogsmiaa
+#define __ev_mhogumiaa __builtin_spe_evmhogumiaa
+#define __ev_mhegsmfaa __builtin_spe_evmhegsmfaa
+#define __ev_mhegsmiaa __builtin_spe_evmhegsmiaa
+#define __ev_mhegumiaa __builtin_spe_evmhegumiaa
#define __ev_mhogumfaa __ev_mhogumiaa
#define __ev_mhegumfaa __ev_mhegumiaa
-#define __ev_mhogsmfan(a, b) __builtin_spe_evmhogsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogsmian(a, b) __builtin_spe_evmhogsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogumian(a, b) __builtin_spe_evmhogumian ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmfan(a, b) __builtin_spe_evmhegsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmian(a, b) __builtin_spe_evmhegsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegumian(a, b) __builtin_spe_evmhegumian ((__v2si) (a), (__v2si) (b))
+#define __ev_mhogsmfan __builtin_spe_evmhogsmfan
+#define __ev_mhogsmian __builtin_spe_evmhogsmian
+#define __ev_mhogumian __builtin_spe_evmhogumian
+#define __ev_mhegsmfan __builtin_spe_evmhegsmfan
+#define __ev_mhegsmian __builtin_spe_evmhegsmian
+#define __ev_mhegumian __builtin_spe_evmhegumian
#define __ev_mhogumfan __ev_mhogumian
#define __ev_mhegumfan __ev_mhegumian
-#define __ev_mwhssf(a, b) __builtin_spe_evmwhssf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmf(a, b) __builtin_spe_evmwhsmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmi(a, b) __builtin_spe_evmwhsmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumi(a, b) __builtin_spe_evmwhumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssfa(a, b) __builtin_spe_evmwhssfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmfa(a, b) __builtin_spe_evmwhsmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmia(a, b) __builtin_spe_evmwhsmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumia(a, b) __builtin_spe_evmwhumia ((__v2si) (a), (__v2si) (b))
+#define __ev_mwhssf __builtin_spe_evmwhssf
+#define __ev_mwhsmf __builtin_spe_evmwhsmf
+#define __ev_mwhsmi __builtin_spe_evmwhsmi
+#define __ev_mwhumi __builtin_spe_evmwhumi
+#define __ev_mwhssfa __builtin_spe_evmwhssfa
+#define __ev_mwhsmfa __builtin_spe_evmwhsmfa
+#define __ev_mwhsmia __builtin_spe_evmwhsmia
+#define __ev_mwhumia __builtin_spe_evmwhumia
#define __ev_mwhumf __ev_mwhumi
#define __ev_mwhumfa __ev_mwhumia
-#define __ev_mwlumi(a, b) __builtin_spe_evmwlumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlumia(a, b) __builtin_spe_evmwlumia ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlumiaaw(a, b) __builtin_spe_evmwlumiaaw ((__v2si) (a), (__v2si) (b))
-
-#define __ev_mwlssiaaw(a, b) __builtin_spe_evmwlssiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlsmiaaw(a, b) __builtin_spe_evmwlsmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlusiaaw(a, b) __builtin_spe_evmwlusiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlusiaaw(a, b) __builtin_spe_evmwlusiaaw ((__v2si) (a), (__v2si) (b))
-
-#define __ev_mwlssianw(a, b) __builtin_spe_evmwlssianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlsmianw(a, b) __builtin_spe_evmwlsmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlusianw(a, b) __builtin_spe_evmwlusianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlumianw(a, b) __builtin_spe_evmwlumianw ((__v2si) (a), (__v2si) (b))
-
-#define __ev_mwssf(a, b) __builtin_spe_evmwssf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmf(a, b) __builtin_spe_evmwsmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmi(a, b) __builtin_spe_evmwsmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumi(a, b) __builtin_spe_evmwumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwssfa(a, b) __builtin_spe_evmwssfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmfa(a, b) __builtin_spe_evmwsmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmia(a, b) __builtin_spe_evmwsmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumia(a, b) __builtin_spe_evmwumia ((__v2si) (a), (__v2si) (b))
+#define __ev_mwlumi __builtin_spe_evmwlumi
+#define __ev_mwlumia __builtin_spe_evmwlumia
+#define __ev_mwlumiaaw __builtin_spe_evmwlumiaaw
+
+#define __ev_mwlssiaaw __builtin_spe_evmwlssiaaw
+#define __ev_mwlsmiaaw __builtin_spe_evmwlsmiaaw
+#define __ev_mwlusiaaw __builtin_spe_evmwlusiaaw
+#define __ev_mwlusiaaw __builtin_spe_evmwlusiaaw
+
+#define __ev_mwlssianw __builtin_spe_evmwlssianw
+#define __ev_mwlsmianw __builtin_spe_evmwlsmianw
+#define __ev_mwlusianw __builtin_spe_evmwlusianw
+#define __ev_mwlumianw __builtin_spe_evmwlumianw
+
+#define __ev_mwssf __builtin_spe_evmwssf
+#define __ev_mwsmf __builtin_spe_evmwsmf
+#define __ev_mwsmi __builtin_spe_evmwsmi
+#define __ev_mwumi __builtin_spe_evmwumi
+#define __ev_mwssfa __builtin_spe_evmwssfa
+#define __ev_mwsmfa __builtin_spe_evmwsmfa
+#define __ev_mwsmia __builtin_spe_evmwsmia
+#define __ev_mwumia __builtin_spe_evmwumia
#define __ev_mwumf __ev_mwumi
#define __ev_mwumfa __ev_mwumia
-#define __ev_mwssfaa(a, b) __builtin_spe_evmwssfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmfaa(a, b) __builtin_spe_evmwsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmiaa(a, b) __builtin_spe_evmwsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumiaa(a, b) __builtin_spe_evmwumiaa ((__v2si) (a), (__v2si) (b))
+#define __ev_mwssfaa __builtin_spe_evmwssfaa
+#define __ev_mwsmfaa __builtin_spe_evmwsmfaa
+#define __ev_mwsmiaa __builtin_spe_evmwsmiaa
+#define __ev_mwumiaa __builtin_spe_evmwumiaa
#define __ev_mwumfaa __ev_mwumiaa
-#define __ev_mwssfan(a, b) __builtin_spe_evmwssfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmfan(a, b) __builtin_spe_evmwsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmian(a, b) __builtin_spe_evmwsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumian(a, b) __builtin_spe_evmwumian ((__v2si) (a), (__v2si) (b))
+#define __ev_mwssfan __builtin_spe_evmwssfan
+#define __ev_mwsmfan __builtin_spe_evmwsmfan
+#define __ev_mwsmian __builtin_spe_evmwsmian
+#define __ev_mwumian __builtin_spe_evmwumian
#define __ev_mwumfan __ev_mwumian
-#define __ev_addssiaaw(a) __builtin_spe_evaddssiaaw ((__v2si) (a))
-#define __ev_addsmiaaw(a) __builtin_spe_evaddsmiaaw ((__v2si) (a))
-#define __ev_addusiaaw(a) __builtin_spe_evaddusiaaw ((__v2si) (a))
-#define __ev_addumiaaw(a) __builtin_spe_evaddumiaaw ((__v2si) (a))
+#define __ev_addssiaaw __builtin_spe_evaddssiaaw
+#define __ev_addsmiaaw __builtin_spe_evaddsmiaaw
+#define __ev_addusiaaw __builtin_spe_evaddusiaaw
+#define __ev_addumiaaw __builtin_spe_evaddumiaaw
#define __ev_addusfaaw __ev_addusiaaw
#define __ev_addumfaaw __ev_addumiaaw
#define __ev_addsmfaaw __ev_addsmiaaw
#define __ev_addssfaaw __ev_addssiaaw
-#define __ev_subfssiaaw(a) __builtin_spe_evsubfssiaaw ((__v2si) (a))
-#define __ev_subfsmiaaw(a) __builtin_spe_evsubfsmiaaw ((__v2si) (a))
-#define __ev_subfusiaaw(a) __builtin_spe_evsubfusiaaw ((__v2si) (a))
-#define __ev_subfumiaaw(a) __builtin_spe_evsubfumiaaw ((__v2si) (a))
+#define __ev_subfssiaaw __builtin_spe_evsubfssiaaw
+#define __ev_subfsmiaaw __builtin_spe_evsubfsmiaaw
+#define __ev_subfusiaaw __builtin_spe_evsubfusiaaw
+#define __ev_subfumiaaw __builtin_spe_evsubfumiaaw
#define __ev_subfusfaaw __ev_subfusiaaw
#define __ev_subfumfaaw __ev_subfumiaaw
@@ -289,26 +286,23 @@ typedef int __vector __ev64_opaque__;
/* Floating Point SIMD Instructions */
-/* These all return V2SF, but we need to cast them to V2SI
- because the SPE expect all functions to be __ev64_opaque__. */
-
-#define __ev_fsabs(a) ((__v2si) __builtin_spe_evfsabs ((__v2sf) (a)))
-#define __ev_fsnabs(a) ((__v2si) __builtin_spe_evfsnabs ((__v2sf) (a)))
-#define __ev_fsneg(a) ((__v2si) __builtin_spe_evfsneg ((__v2sf) (a)))
-#define __ev_fsadd(a, b) ((__v2si) __builtin_spe_evfsadd ((__v2sf) (a), (__v2sf) (b)))
-#define __ev_fssub(a, b) ((__v2si) __builtin_spe_evfssub ((__v2sf) (a), (__v2sf) (b)))
-#define __ev_fsmul(a, b) ((__v2si) __builtin_spe_evfsmul ((__v2sf) (a), (__v2sf) b))
-#define __ev_fsdiv(a, b) ((__v2si) __builtin_spe_evfsdiv ((__v2sf) (a), (__v2sf) b))
-#define __ev_fscfui(a) ((__v2si) __builtin_spe_evfscfui ((__v2si) (a)))
-#define __ev_fscfsi(a) ((__v2si) __builtin_spe_evfscfsi ((__v2sf) (a)))
-#define __ev_fscfuf(a) ((__v2si) __builtin_spe_evfscfuf ((__v2sf) (a)))
-#define __ev_fscfsf(a) ((__v2si) __builtin_spe_evfscfsf ((__v2sf) (a)))
-#define __ev_fsctui(a) ((__v2si) __builtin_spe_evfsctui ((__v2sf) (a)))
-#define __ev_fsctsi(a) ((__v2si) __builtin_spe_evfsctsi ((__v2sf) (a)))
-#define __ev_fsctuf(a) ((__v2si) __builtin_spe_evfsctuf ((__v2sf) (a)))
-#define __ev_fsctsf(a) ((__v2si) __builtin_spe_evfsctsf ((__v2sf) (a)))
-#define __ev_fsctuiz(a) ((__v2si) __builtin_spe_evfsctuiz ((__v2sf) (a)))
-#define __ev_fsctsiz(a) ((__v2si) __builtin_spe_evfsctsiz ((__v2sf) (a)))
+#define __ev_fsabs __builtin_spe_evfsabs
+#define __ev_fsnabs __builtin_spe_evfsnabs
+#define __ev_fsneg __builtin_spe_evfsneg
+#define __ev_fsadd __builtin_spe_evfsadd
+#define __ev_fssub __builtin_spe_evfssub
+#define __ev_fsmul __builtin_spe_evfsmul
+#define __ev_fsdiv __builtin_spe_evfsdiv
+#define __ev_fscfui __builtin_spe_evfscfui
+#define __ev_fscfsi __builtin_spe_evfscfsi
+#define __ev_fscfuf __builtin_spe_evfscfuf
+#define __ev_fscfsf __builtin_spe_evfscfsf
+#define __ev_fsctui __builtin_spe_evfsctui
+#define __ev_fsctsi __builtin_spe_evfsctsi
+#define __ev_fsctuf __builtin_spe_evfsctuf
+#define __ev_fsctsf __builtin_spe_evfsctsf
+#define __ev_fsctuiz __builtin_spe_evfsctuiz
+#define __ev_fsctsiz __builtin_spe_evfsctsiz
/* NOT SUPPORTED IN FIRST e500, support via two instructions: */
@@ -319,26 +313,26 @@ typedef int __vector __ev64_opaque__;
#define __ev_mwhgumfaa __ev_mwhgumiaa
#define __ev_mwhgumfan __ev_mwhgumian
-#define __ev_mwhgssfaa(a, b) __internal_ev_mwhgssfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmfaa(a, b) __internal_ev_mwhgsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmiaa(a, b) __internal_ev_mwhgsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgumiaa(a, b) __internal_ev_mwhgumiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgssfan(a, b) __internal_ev_mwhgssfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmfan(a, b) __internal_ev_mwhgsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmian(a, b) __internal_ev_mwhgsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgumian(a, b) __internal_ev_mwhgumian ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssiaaw(a, b) __internal_ev_mwhssiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssfaaw(a, b) __internal_ev_mwhssfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmfaaw(a, b) __internal_ev_mwhsmfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmiaaw(a, b) __internal_ev_mwhsmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhusiaaw(a, b) __internal_ev_mwhusiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumiaaw(a, b) __internal_ev_mwhumiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssfanw(a, b) __internal_ev_mwhssfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssianw(a, b) __internal_ev_mwhssianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmfanw(a, b) __internal_ev_mwhsmfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmianw(a, b) __internal_ev_mwhsmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhusianw(a, b) __internal_ev_mwhusianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumianw(a, b) __internal_ev_mwhumianw ((__v2si) (a), (__v2si) (b))
+#define __ev_mwhgssfaa __internal_ev_mwhgssfaa
+#define __ev_mwhgsmfaa __internal_ev_mwhgsmfaa
+#define __ev_mwhgsmiaa __internal_ev_mwhgsmiaa
+#define __ev_mwhgumiaa __internal_ev_mwhgumiaa
+#define __ev_mwhgssfan __internal_ev_mwhgssfan
+#define __ev_mwhgsmfan __internal_ev_mwhgsmfan
+#define __ev_mwhgsmian __internal_ev_mwhgsmian
+#define __ev_mwhgumian __internal_ev_mwhgumian
+#define __ev_mwhssiaaw __internal_ev_mwhssiaaw
+#define __ev_mwhssfaaw __internal_ev_mwhssfaaw
+#define __ev_mwhsmfaaw __internal_ev_mwhsmfaaw
+#define __ev_mwhsmiaaw __internal_ev_mwhsmiaaw
+#define __ev_mwhusiaaw __internal_ev_mwhusiaaw
+#define __ev_mwhumiaaw __internal_ev_mwhumiaaw
+#define __ev_mwhssfanw __internal_ev_mwhssfanw
+#define __ev_mwhssianw __internal_ev_mwhssianw
+#define __ev_mwhsmfanw __internal_ev_mwhsmfanw
+#define __ev_mwhsmianw __internal_ev_mwhsmianw
+#define __ev_mwhusianw __internal_ev_mwhusianw
+#define __ev_mwhumianw __internal_ev_mwhumianw
static inline __ev64_opaque__
__internal_ev_mwhssfaaw (__ev64_opaque__ a, __ev64_opaque__ b)
@@ -665,31 +659,31 @@ __ev_convert_s64 (__ev64_opaque__ a)
/* __ev_get_* functions. */
-#define __ev_get_upper_u32(a) __ev_get_u32_internal ((__ev64_opaque__) (a), 0)
-#define __ev_get_lower_u32(a) __ev_get_u32_internal ((__ev64_opaque__) (a), 1)
-#define __ev_get_upper_s32(a) __ev_get_s32_internal ((__ev64_opaque__) (a), 0)
-#define __ev_get_lower_s32(a) __ev_get_s32_internal ((__ev64_opaque__) (a), 1)
-#define __ev_get_upper_fs(a) __ev_get_fs_internal ((__ev64_opaque__) (a), 0)
-#define __ev_get_lower_fs(a) __ev_get_fs_internal ((__ev64_opaque__) (a), 1)
-#define __ev_get_upper_ufix32_u32(a) __ev_get_upper_u32(a)
-#define __ev_get_lower_ufix32_u32(a) __ev_get_lower_u32(a)
-#define __ev_get_upper_sfix32_s32(a) __ev_get_upper_s32(a)
-#define __ev_get_lower_sfix32_s32(a) __ev_get_lower_s32(a)
-#define __ev_get_upper_sfix32_fs(a) __ev_get_sfix32_fs (a, 0)
-#define __ev_get_lower_sfix32_fs(a) __ev_get_sfix32_fs (a, 1)
-#define __ev_get_upper_ufix32_fs(a) __ev_get_ufix32_fs (a, 0)
-#define __ev_get_lower_ufix32_fs(a) __ev_get_ufix32_fs (a, 1)
-
-#define __ev_get_u32(a, b) __ev_get_u32_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_s32(a, b) __ev_get_s32_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_fs(a, b) __ev_get_fs_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_u16(a, b) __ev_get_u16_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_s16(a, b) __ev_get_s16_internal ((__ev64_opaque__) (a), b)
-
-#define __ev_get_ufix32_u32(a, b) __ev_get_u32 (a, b)
-#define __ev_get_sfix32_s32(a, b) __ev_get_s32 (a, b)
-#define __ev_get_ufix32_fs(a, b) __ev_get_ufix32_fs_internal ((__ev64_opaque__)(a), b)
-#define __ev_get_sfix32_fs(a, b) __ev_get_sfix32_fs_internal ((__ev64_opaque__)(a), b)
+#define __ev_get_upper_u32(a) __ev_get_u32_internal ((a), 0)
+#define __ev_get_lower_u32(a) __ev_get_u32_internal ((a), 1)
+#define __ev_get_upper_s32(a) __ev_get_s32_internal ((a), 0)
+#define __ev_get_lower_s32(a) __ev_get_s32_internal ((a), 1)
+#define __ev_get_upper_fs(a) __ev_get_fs_internal ((a), 0)
+#define __ev_get_lower_fs(a) __ev_get_fs_internal ((a), 1)
+#define __ev_get_upper_ufix32_u32 __ev_get_upper_u32
+#define __ev_get_lower_ufix32_u32 __ev_get_lower_u32
+#define __ev_get_upper_sfix32_s32 __ev_get_upper_s32
+#define __ev_get_lower_sfix32_s32 __ev_get_lower_s32
+#define __ev_get_upper_sfix32_fs(a) __ev_get_sfix32_fs ((a), 0)
+#define __ev_get_lower_sfix32_fs(a) __ev_get_sfix32_fs ((a), 1)
+#define __ev_get_upper_ufix32_fs(a) __ev_get_ufix32_fs ((a), 0)
+#define __ev_get_lower_ufix32_fs(a) __ev_get_ufix32_fs ((a), 1)
+
+#define __ev_get_u32 __ev_get_u32_internal
+#define __ev_get_s32 __ev_get_s32_internal
+#define __ev_get_fs __ev_get_fs_internal
+#define __ev_get_u16 __ev_get_u16_internal
+#define __ev_get_s16 __ev_get_s16_internal
+
+#define __ev_get_ufix32_u32 __ev_get_u32
+#define __ev_get_sfix32_s32 __ev_get_s32
+#define __ev_get_ufix32_fs __ev_get_ufix32_fs_internal
+#define __ev_get_sfix32_fs __ev_get_sfix32_fs_internal
static inline uint32_t
__ev_get_u32_internal (__ev64_opaque__ a, uint32_t pos)
@@ -776,17 +770,17 @@ __ev_get_s16_internal (__ev64_opaque__ a, uint32_t pos)
/* __ev_set_* functions. */
-#define __ev_set_u32(a, b, c) __ev_set_u32_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_s32(a, b, c) __ev_set_s32_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_fs(a, b, c) __ev_set_fs_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_u16(a, b, c) __ev_set_u16_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_s16(a, b, c) __ev_set_s16_internal ((__ev64_opaque__) a, b, c)
+#define __ev_set_u32 __ev_set_u32_internal
+#define __ev_set_s32 __ev_set_s32_internal
+#define __ev_set_fs __ev_set_fs_internal
+#define __ev_set_u16 __ev_set_u16_internal
+#define __ev_set_s16 __ev_set_s16_internal
#define __ev_set_ufix32_u32 __ev_set_u32
#define __ev_set_sfix32_s32 __ev_set_s32
-#define __ev_set_sfix32_fs(a, b, c) __ev_set_sfix32_fs_internal ((__ev64_opaque__) (a), b, c)
-#define __ev_set_ufix32_fs(a, b, c) __ev_set_ufix32_fs_internal ((__ev64_opaque__) (a), b, c)
+#define __ev_set_sfix32_fs __ev_set_sfix32_fs_internal
+#define __ev_set_ufix32_fs __ev_set_ufix32_fs_internal
#define __ev_set_upper_u32(a, b) __ev_set_u32 (a, b, 0)
#define __ev_set_lower_u32(a, b) __ev_set_u32 (a, b, 1)
@@ -803,7 +797,7 @@ __ev_get_s16_internal (__ev64_opaque__ a, uint32_t pos)
#define __ev_set_upper_ufix32_fs(a, b) __ev_set_ufix32_fs (a, b, 0)
#define __ev_set_lower_ufix32_fs(a, b) __ev_set_ufix32_fs (a, b, 1)
-#define __ev_set_acc_vec64(a) __builtin_spe_evmra ((__ev64_opaque__)(a))
+#define __ev_set_acc_vec64 __builtin_spe_evmra
static inline __ev64_opaque__
__ev_set_acc_u64 (uint64_t a)
@@ -932,72 +926,72 @@ __ev_set_s16_internal (__ev64_opaque__ a, int16_t b, uint32_t pos)
#define __pred_upper 2
#define __pred_lower 3
-#define __ev_any_gts(a, b) __builtin_spe_evcmpgts (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_gts(a, b) __builtin_spe_evcmpgts (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_gts(a, b) __builtin_spe_evcmpgts (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_gts(a, b) __builtin_spe_evcmpgts (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_gts(a, b, c, d) ((__v2si) __builtin_spe_evsel_gts ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_gtu(a, b) __builtin_spe_evcmpgtu (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_gtu(a, b) __builtin_spe_evcmpgtu (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_gtu(a, b) __builtin_spe_evcmpgtu (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_gtu(a, b) __builtin_spe_evcmpgtu (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_gtu(a, b, c, d) ((__v2si) __builtin_spe_evsel_gtu ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_lts(a, b) __builtin_spe_evcmplts (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_lts(a, b) __builtin_spe_evcmplts (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_lts(a, b) __builtin_spe_evcmplts (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_lts(a, b) __builtin_spe_evcmplts (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_lts(a, b, c, d) ((__v2si) __builtin_spe_evsel_lts ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_ltu(a, b) __builtin_spe_evcmpltu (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_ltu(a, b) __builtin_spe_evcmpltu (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_ltu(a, b) __builtin_spe_evcmpltu (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_ltu(a, b) __builtin_spe_evcmpltu (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_ltu(a, b, c, d) ((__v2si) __builtin_spe_evsel_ltu ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-#define __ev_any_eq(a, b) __builtin_spe_evcmpeq (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_eq(a, b) __builtin_spe_evcmpeq (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_eq(a, b) __builtin_spe_evcmpeq (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_eq(a, b) __builtin_spe_evcmpeq (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_eq(a, b, c, d) ((__v2si) __builtin_spe_evsel_eq ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_gt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fsgt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_lt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fslt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_eq(a, b, c, d) ((__v2si) __builtin_spe_evsel_fseq ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_tst_gt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fststgt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_tst_lt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fststlt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_tst_eq(a, b, c, d) ((__v2si) __builtin_spe_evsel_fststeq ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-/* SPEFSCR accesor functions. */
+#define __ev_any_gts(a, b) __builtin_spe_evcmpgts (__pred_any, (a), (b))
+#define __ev_all_gts(a, b) __builtin_spe_evcmpgts (__pred_all, (a), (b))
+#define __ev_upper_gts(a, b) __builtin_spe_evcmpgts (__pred_upper, (a), (b))
+#define __ev_lower_gts(a, b) __builtin_spe_evcmpgts (__pred_lower, (a), (b))
+#define __ev_select_gts __builtin_spe_evsel_gts
+
+#define __ev_any_gtu(a, b) __builtin_spe_evcmpgtu (__pred_any, (a), (b))
+#define __ev_all_gtu(a, b) __builtin_spe_evcmpgtu (__pred_all, (a), (b))
+#define __ev_upper_gtu(a, b) __builtin_spe_evcmpgtu (__pred_upper, (a), (b))
+#define __ev_lower_gtu(a, b) __builtin_spe_evcmpgtu (__pred_lower, (a), (b))
+#define __ev_select_gtu __builtin_spe_evsel_gtu
+
+#define __ev_any_lts(a, b) __builtin_spe_evcmplts (__pred_any, (a), (b))
+#define __ev_all_lts(a, b) __builtin_spe_evcmplts (__pred_all, (a), (b))
+#define __ev_upper_lts(a, b) __builtin_spe_evcmplts (__pred_upper, (a), (b))
+#define __ev_lower_lts(a, b) __builtin_spe_evcmplts (__pred_lower, (a), (b))
+#define __ev_select_lts(a, b, c, d) ((__v2si) __builtin_spe_evsel_lts ((a), (b), (c), (d)))
+
+#define __ev_any_ltu(a, b) __builtin_spe_evcmpltu (__pred_any, (a), (b))
+#define __ev_all_ltu(a, b) __builtin_spe_evcmpltu (__pred_all, (a), (b))
+#define __ev_upper_ltu(a, b) __builtin_spe_evcmpltu (__pred_upper, (a), (b))
+#define __ev_lower_ltu(a, b) __builtin_spe_evcmpltu (__pred_lower, (a), (b))
+#define __ev_select_ltu __builtin_spe_evsel_ltu
+#define __ev_any_eq(a, b) __builtin_spe_evcmpeq (__pred_any, (a), (b))
+#define __ev_all_eq(a, b) __builtin_spe_evcmpeq (__pred_all, (a), (b))
+#define __ev_upper_eq(a, b) __builtin_spe_evcmpeq (__pred_upper, (a), (b))
+#define __ev_lower_eq(a, b) __builtin_spe_evcmpeq (__pred_lower, (a), (b))
+#define __ev_select_eq __builtin_spe_evsel_eq
+
+#define __ev_any_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_any, (a), (b))
+#define __ev_all_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_all, (a), (b))
+#define __ev_upper_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_upper, (a), (b))
+#define __ev_lower_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_lower, (a), (b))
+#define __ev_select_fs_gt __builtin_spe_evsel_fsgt
+
+#define __ev_any_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_any, (a), (b))
+#define __ev_all_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_all, (a), (b))
+#define __ev_upper_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_upper, (a), (b))
+#define __ev_lower_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_lower, (a), (b))
+#define __ev_select_fs_lt __builtin_spe_evsel_fslt
+
+#define __ev_any_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_any, (a), (b))
+#define __ev_all_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_all, (a), (b))
+#define __ev_upper_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_upper, (a), (b))
+#define __ev_lower_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_lower, (a), (b))
+#define __ev_select_fs_eq __builtin_spe_evsel_fseq
+
+#define __ev_any_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_any, (a), (b))
+#define __ev_all_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_all, (a), (b))
+#define __ev_upper_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_upper, (a), (b))
+#define __ev_lower_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_lower, (a), (b))
+#define __ev_select_fs_tst_gt __builtin_spe_evsel_fststgt
+
+#define __ev_any_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_any, (a), (b))
+#define __ev_all_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_all, (a), (b))
+#define __ev_upper_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_upper, (a), (b))
+#define __ev_lower_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_lower, (a), (b))
+#define __ev_select_fs_tst_lt __builtin_spe_evsel_fststlt
+
+#define __ev_any_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_any, (a), (b))
+#define __ev_all_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_all, (a), (b))
+#define __ev_upper_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_upper, (a), (b))
+#define __ev_lower_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_lower, (a), (b))
+#define __ev_select_fs_tst_eq __builtin_spe_evsel_fststeq
+
+/* SPEFSCR accessor functions. */
#define __SPEFSCR_SOVH 0x80000000
#define __SPEFSCR_OVH 0x40000000
@@ -1091,6 +1085,7 @@ __ev_set_spefscr_frmc (int rnd)
i = __builtin_spe_mfspefscr ();
i &= ~__SPEFSCR_FRMC;
i |= rnd;
+ __builtin_spe_mtspefscr (i);
}
#endif /* _SPE_H */
diff --git a/contrib/gcc/config/rs6000/spe.md b/contrib/gcc/config/rs6000/spe.md
index 3413858..5eb6302 100644
--- a/contrib/gcc/config/rs6000/spe.md
+++ b/contrib/gcc/config/rs6000/spe.md
@@ -1,23 +1,23 @@
;; e500 SPE description
-;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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 2, or (at your option)
-;; any later version.
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, or (at your
+;; option) any later version.
-;; GNU CC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
(define_constants
[(SPE_ACC_REGNO 111)
@@ -28,14 +28,21 @@
(neg:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsneg %0,%1"
- [(set_attr "type" "fp")])
+ [(set_attr "type" "fpsimple")])
(define_insn "*abssf2_gpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
(abs:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsabs %0,%1"
- [(set_attr "type" "fp")])
+ [(set_attr "type" "fpsimple")])
+
+(define_insn "*nabssf2_gpr"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
+ (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "r"))))]
+ "TARGET_HARD_FLOAT && !TARGET_FPRS"
+ "efsnabs %0,%1"
+ [(set_attr "type" "fpsimple")])
(define_insn "*addsf3_gpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
@@ -67,27 +74,20 @@
(match_operand:SF 2 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsdiv %0,%1,%2"
- [(set_attr "type" "fp")])
+ [(set_attr "type" "vecfdiv")])
-(define_insn "spe_efsctuiz"
+(define_insn "spe_fixuns_truncsfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SF 1 "gpc_reg_operand" "r")] 700))]
+ (unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsctuiz %0,%1"
[(set_attr "type" "fp")])
-(define_insn "spe_fixunssfsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unsigned_fix:SI (fix:SF (match_operand:SF 1 "gpc_reg_operand" "r"))))]
- "TARGET_HARD_FLOAT && !TARGET_FPRS"
- "efsctui %0,%1"
- [(set_attr "type" "fp")])
-
(define_insn "spe_fix_truncsfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(fix:SI (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
- "efsctsi %0,%1"
+ "efsctsiz %0,%1"
[(set_attr "type" "fp")])
(define_insn "spe_floatunssisf2"
@@ -283,12 +283,12 @@
(set_attr "length" "4")])
(define_insn "spe_evlhhesplat"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
+ [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
+ (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 509)]
- "TARGET_SPE"
- "evlhhesplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlhhesplat %0,%2*2(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -307,8 +307,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 511)]
- "TARGET_SPE"
- "evlhhossplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlhhossplat %0,%2*2(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -327,8 +327,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 513)]
- "TARGET_SPE"
- "evlhhousplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlhhousplat %0,%2*2(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -347,8 +347,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 515)]
- "TARGET_SPE"
- "evlwhsplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhsplat %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -367,8 +367,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 517)]
- "TARGET_SPE"
- "evlwwsplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwwsplat %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -443,7 +443,7 @@
[(set_attr "type" "vecsimple")
(set_attr "length" "4")])
-(define_insn "spe_evneg"
+(define_insn "negv2si2"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(neg:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
@@ -581,7 +581,9 @@
[(set_attr "type" "vecsimple")
(set_attr "length" "4")])
-(define_insn "spe_evxor"
+;; vector xors
+
+(define_insn "xorv2si3"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(xor:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")))]
@@ -590,12 +592,32 @@
[(set_attr "type" "vecsimple")
(set_attr "length" "4")])
+(define_insn "xorv4hi3"
+ [(set (match_operand:V4HI 0 "gpc_reg_operand" "=r")
+ (xor:V4HI (match_operand:V4HI 1 "gpc_reg_operand" "r")
+ (match_operand:V4HI 2 "gpc_reg_operand" "r")))]
+ "TARGET_SPE"
+ "evxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")
+ (set_attr "length" "4")])
+
+(define_insn "xorv1di3"
+ [(set (match_operand:V1DI 0 "gpc_reg_operand" "=r")
+ (xor:V1DI (match_operand:V1DI 1 "gpc_reg_operand" "r")
+ (match_operand:V1DI 2 "gpc_reg_operand" "r")))]
+ "TARGET_SPE"
+ "evxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")
+ (set_attr "length" "4")])
+
+;; end of vector xors
+
(define_insn "spe_evfsabs"
[(set (match_operand:V2SF 0 "gpc_reg_operand" "=r")
(abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evfsabs %0,%1"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evfsadd"
@@ -617,8 +639,8 @@
(set_attr "length" "4")])
(define_insn "spe_evfscfsi"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (fix:V2SI (match_operand:V2SF 1 "gpc_reg_operand" "r")))]
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r")
+ (float:V2SF (match_operand:V2SI 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evfscfsi %0,%1"
[(set_attr "type" "vecfloat")
@@ -695,7 +717,7 @@
(clobber (reg:SI SPEFSCR_REGNO))]
"TARGET_SPE"
"evfsdiv %0,%1,%2"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecfdiv")
(set_attr "length" "4")])
(define_insn "spe_evfsmul"
@@ -713,7 +735,7 @@
(unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 537))]
"TARGET_SPE"
"evfsnabs %0,%1"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evfsneg"
@@ -721,7 +743,7 @@
(neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evfsneg %0,%1"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evfssub"
@@ -736,7 +758,7 @@
;; SPE SIMD load instructions.
-;; Only the hardware engineer who designed the SPE inderstands the
+;; Only the hardware engineer who designed the SPE understands the
;; plethora of load and store instructions ;-). We have no way of
;; differentiating between them with RTL so use an unspec of const_int 0
;; to avoid identical RTL.
@@ -747,7 +769,7 @@
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 544)]
"TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
- "evldd %0,%1,%2"
+ "evldd %0,%2*8(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -767,7 +789,7 @@
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 546)]
"TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
- "evldh %0,%1,%2"
+ "evldh %0,%2*8(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -786,8 +808,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 548)]
- "TARGET_SPE"
- "evldw %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evldw %0,%2*8(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -806,8 +828,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 550)]
- "TARGET_SPE"
- "evlwhe %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhe %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -826,8 +848,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 552)]
- "TARGET_SPE"
- "evlwhos %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhos %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -846,8 +868,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 554)]
- "TARGET_SPE"
- "evlwhou %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhou %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -867,7 +889,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r")] 556))]
"TARGET_SPE"
"brinc %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "brinc")
(set_attr "length" "4")])
(define_insn "spe_evmhegsmfaa"
@@ -875,7 +897,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 557))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -886,7 +908,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 558))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -897,7 +919,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 559))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -908,7 +930,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 560))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -919,7 +941,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 561))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -930,7 +952,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 562))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -941,7 +963,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 563))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -952,7 +974,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 564))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -962,7 +984,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 565))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -982,7 +1004,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 567))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -993,7 +1015,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 568))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1003,7 +1025,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 569))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1024,7 +1046,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 571))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1036,7 +1058,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 572))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1047,7 +1069,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 573))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1069,7 +1091,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 575))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1081,7 +1103,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 576))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1092,7 +1114,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 577))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheumiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1103,7 +1125,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 578))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheumianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1113,7 +1135,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 579))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1134,7 +1156,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 581))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheusiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1146,7 +1168,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 582))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheusianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1157,7 +1179,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 583))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1168,7 +1190,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 584))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1179,7 +1201,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 585))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1190,7 +1212,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 586))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1201,7 +1223,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 587))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1212,7 +1234,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 588))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1223,7 +1245,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 589))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1234,7 +1256,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 590))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1253,7 +1275,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 592))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmf %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1264,7 +1286,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 593))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1275,7 +1297,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 594))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1285,7 +1307,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 595))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1306,7 +1328,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 597))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1318,7 +1340,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 598))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1330,7 +1352,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 599))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1352,7 +1374,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 601))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1364,7 +1386,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 602))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1375,7 +1397,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 603))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhoumiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1386,7 +1408,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 604))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhoumianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1396,7 +1418,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 605))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhoumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1417,7 +1439,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 607))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhousiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1429,7 +1451,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 608))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhousianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1457,7 +1479,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 611))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1476,7 +1498,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 613))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1496,7 +1518,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 615))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1525,7 +1547,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 629))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1545,7 +1567,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 635))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlsmiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1556,7 +1578,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 636))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlsmianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1568,7 +1590,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 641))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlssiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1580,7 +1602,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 642))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlssianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1591,7 +1613,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 643))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlumiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1602,7 +1624,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 644))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlumianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1612,7 +1634,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 645))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1633,7 +1655,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 647))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlusiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1645,7 +1667,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 648))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlusianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1656,7 +1678,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 649))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1667,7 +1689,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 650))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1677,7 +1699,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 651))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1697,7 +1719,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 653))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1708,7 +1730,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 654))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1718,7 +1740,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 655))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1739,7 +1761,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 657))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwssfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1751,7 +1773,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 658))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwssfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1762,7 +1784,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 659))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwssfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1783,7 +1805,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 661))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1794,7 +1816,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 662))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1804,7 +1826,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 663))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1825,7 +1847,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evaddw %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evaddusiaaw"
@@ -1833,7 +1855,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 673))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddusiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1843,7 +1865,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 674))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddumiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1854,7 +1876,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 675))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddssiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1864,7 +1886,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 676))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddsmiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1876,7 +1898,7 @@
(match_operand:QI 2 "immediate_operand" "i")] 677))]
"TARGET_SPE"
"evaddiw %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evsubifw"
@@ -1893,7 +1915,7 @@
(minus:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")))]
"TARGET_SPE"
- "evsubfw %0,%1,%2"
+ "evsubfw %0,%2,%1"
[(set_attr "type" "veccomplex")
(set_attr "length" "4")])
@@ -1902,7 +1924,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 679))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfusiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1912,7 +1934,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 680))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfumiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1923,7 +1945,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 681))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfssiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1933,7 +1955,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 682))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfsmiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1956,7 +1978,7 @@
(clobber (reg:SI SPEFSCR_REGNO))]
"TARGET_SPE"
"evdivws %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecdiv")
(set_attr "length" "4")])
(define_insn "spe_evdivwu"
@@ -1966,7 +1988,7 @@
(clobber (reg:SI SPEFSCR_REGNO))]
"TARGET_SPE"
"evdivwu %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecdiv")
(set_attr "length" "4")])
(define_insn "spe_evsplatfi"
@@ -1990,8 +2012,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 686)]
- "TARGET_SPE"
- "evstdd %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstdd %2,%1*8(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2010,8 +2032,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 688)]
- "TARGET_SPE"
- "evstdh %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstdh %2,%1*8(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2030,8 +2052,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 690)]
- "TARGET_SPE"
- "evstdw %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstdw %2,%1*8(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2050,8 +2072,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 692)]
- "TARGET_SPE"
- "evstwhe %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwhe %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2070,8 +2092,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 694)]
- "TARGET_SPE"
- "evstwho %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwho %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2090,8 +2112,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 696)]
- "TARGET_SPE"
- "evstwwe %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwwe %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2110,8 +2132,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 698)]
- "TARGET_SPE"
- "evstwwo %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwwo %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2125,36 +2147,6 @@
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
-;; SPE vector clears
-
-(define_insn "*movv2si_const0"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (match_operand:V2SI 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv2sf_const0"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r")
- (match_operand:V2SF 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv4hi_const0"
- [(set (match_operand:V4HI 0 "gpc_reg_operand" "=r")
- (match_operand:V4HI 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv1di_const0"
- [(set (match_operand:V1DI 0 "gpc_reg_operand" "=r")
- (match_operand:V1DI 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
;; Vector move instructions.
(define_expand "movv2si"
@@ -2163,16 +2155,33 @@
"TARGET_SPE"
"{ rs6000_emit_move (operands[0], operands[1], V2SImode); DONE; }")
-
(define_insn "*movv2si_internal"
- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=m,r,r")
- (match_operand:V2SI 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
- "@
- evstdd%X0 %1,%y0
- evldd%X1 %0,%y1
- evor %0,%1,%1"
- [(set_attr "type" "vecload")])
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=m,r,r,r")
+ (match_operand:V2SI 1 "input_operand" "r,m,r,W"))]
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V2SImode)
+ || gpc_reg_operand (operands[1], V2SImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"evstdd%X0 %1,%y0\";
+ case 1: return \"evldd%X1 %0,%y1\";
+ case 2: return \"evor %0,%1,%1\";
+ case 3: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecload,vecstore,*,*")
+ (set_attr "length" "*,*,*,12")])
+
+(define_split
+ [(set (match_operand:V2SI 0 "register_operand" "")
+ (match_operand:V2SI 1 "zero_constant" ""))]
+ "TARGET_SPE && reload_completed"
+ [(set (match_dup 0)
+ (xor:V2SI (match_dup 0) (match_dup 0)))]
+ "")
(define_expand "movv1di"
[(set (match_operand:V1DI 0 "nonimmediate_operand" "")
@@ -2181,14 +2190,18 @@
"{ rs6000_emit_move (operands[0], operands[1], V1DImode); DONE; }")
(define_insn "*movv1di_internal"
- [(set (match_operand:V1DI 0 "nonimmediate_operand" "=m,r,r")
- (match_operand:V1DI 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
+ [(set (match_operand:V1DI 0 "nonimmediate_operand" "=m,r,r,r")
+ (match_operand:V1DI 1 "input_operand" "r,m,r,W"))]
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V1DImode)
+ || gpc_reg_operand (operands[1], V1DImode))"
"@
evstdd%X0 %1,%y0
evldd%X1 %0,%y1
- evor %0,%1,%1"
- [(set_attr "type" "vecload")])
+ evor %0,%1,%1
+ evxor %0,%0,%0"
+ [(set_attr "type" "vecload,vecstore,*,*")
+ (set_attr "length" "*,*,*,*")])
(define_expand "movv4hi"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "")
@@ -2199,7 +2212,9 @@
(define_insn "*movv4hi_internal"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "=m,r,r")
(match_operand:V4HI 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V4HImode)
+ || gpc_reg_operand (operands[1], V4HImode))"
"@
evstdd%X0 %1,%y0
evldd%X1 %0,%y1
@@ -2213,21 +2228,27 @@
"{ rs6000_emit_move (operands[0], operands[1], V2SFmode); DONE; }")
(define_insn "*movv2sf_internal"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,r,r")
- (match_operand:V2SF 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,r,r,r")
+ (match_operand:V2SF 1 "input_operand" "r,m,r,W"))]
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V2SFmode)
+ || gpc_reg_operand (operands[1], V2SFmode))"
"@
evstdd%X0 %1,%y0
evldd%X1 %0,%y1
- evor %0,%1,%1"
- [(set_attr "type" "vecload")])
+ evor %0,%1,%1
+ evxor %0,%0,%0"
+ [(set_attr "type" "vecload,vecstore,*,*")
+ (set_attr "length" "*,*,*,*")])
+
+;; End of vector move instructions.
(define_insn "spe_evmwhssfaa"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 702))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2238,7 +2259,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 703))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssmaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2248,7 +2269,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 704))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2258,7 +2279,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 705))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2269,7 +2290,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 706))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhusiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2279,7 +2300,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 707))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2290,7 +2311,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 708))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2301,7 +2322,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 709))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2311,7 +2332,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 710))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2321,7 +2342,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 711))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2331,7 +2352,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 713))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2342,7 +2363,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 714))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgssfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2352,7 +2373,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 715))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2362,7 +2383,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 716))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2372,7 +2393,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 717))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2383,7 +2404,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 718))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgssfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2393,7 +2414,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 719))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2403,7 +2424,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 720))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2413,7 +2434,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 721))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2434,55 +2455,80 @@
"mfspefscr %0"
[(set_attr "type" "vecsimple")])
+;; FP comparison stuff.
+
+;; Flip the GT bit.
+(define_insn "e500_flip_gt_bit"
+ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+ (unspec:CCFP
+ [(match_operand:CCFP 1 "cc_reg_operand" "y")] 999))]
+ "!TARGET_FPRS && TARGET_HARD_FLOAT"
+ "*
+{
+ return output_e500_flip_gt_bit (operands[0], operands[1]);
+}"
+ [(set_attr "type" "cr_logical")])
+
;; MPC8540 single-precision FP instructions on GPRs.
;; We have 2 variants for each. One for IEEE compliant math and one
;; for non IEEE compliant math.
(define_insn "cmpsfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1000))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmpeq %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmp")])
(define_insn "tstsfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1001))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststeq %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmpsimple")])
(define_insn "cmpsfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1002))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmpgt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmp")])
(define_insn "tstsfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1003))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststgt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmpsimple")])
(define_insn "cmpsflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1004))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmplt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmp")])
(define_insn "tstsflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1005))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststlt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
-
+ [(set_attr "type" "veccmpsimple")])
diff --git a/contrib/gcc/config/rs6000/sysv4.h b/contrib/gcc/config/rs6000/sysv4.h
index 26450e7..ea149f0 100644
--- a/contrib/gcc/config/rs6000/sysv4.h
+++ b/contrib/gcc/config/rs6000/sysv4.h
@@ -1,25 +1,24 @@
/* Target definitions for GNU compiler for PowerPC running System V.4
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Header files should be C++ aware in general. */
#define NO_IMPLICIT_EXTERN_C
@@ -80,17 +79,15 @@ extern enum rs6000_sdata_type rs6000_sdata;
/* Strings provided by SUBTARGET_OPTIONS */
extern const char *rs6000_abi_name;
extern const char *rs6000_sdata_name;
+extern const char *rs6000_tls_size_string; /* For -mtls-size= */
/* Override rs6000.h definition. */
#undef SUBTARGET_OPTIONS
-#define SUBTARGET_OPTIONS \
- { "call-", &rs6000_abi_name, N_("Select ABI calling convention") }, \
- { "sdata=", &rs6000_sdata_name, N_("Select method for sdata handling") }
-
-/* Max # of bytes for variables to automatically be put into the .sdata
- or .sdata2 sections. */
-extern int g_switch_value; /* Value of the -G xx switch. */
-extern int g_switch_set; /* Whether -G xx was passed. */
+#define SUBTARGET_OPTIONS \
+ { "call-", &rs6000_abi_name, N_("Select ABI calling convention"), 0}, \
+ { "sdata=", &rs6000_sdata_name, N_("Select method for sdata handling"), 0}, \
+ { "tls-size=", &rs6000_tls_size_string, \
+ N_("Specify bit size of immediate TLS offsets"), 0 }
#define SDATA_DEFAULT_SIZE 8
@@ -150,9 +147,12 @@ extern int g_switch_set; /* Whether -G xx was passed. */
N_("Link with libmvme.a, libc.a and crt0.o") }, \
{ "emb", 0, \
N_("Set the PPC_EMB bit in the ELF flags header") }, \
- { "vxworks", 0, N_("no description yet") }, \
{ "windiss", 0, N_("Use the WindISS simulator") }, \
{ "shlib", 0, N_("no description yet") }, \
+ { "64", MASK_64BIT | MASK_POWERPC64 | MASK_POWERPC, \
+ N_("Generate 64-bit code") }, \
+ { "32", - (MASK_64BIT | MASK_POWERPC64), \
+ N_("Generate 32-bit code") }, \
EXTRA_SUBTARGET_SWITCHES \
{ "newlib", 0, N_("no description yet") },
@@ -173,6 +173,9 @@ do { \
if (!g_switch_set) \
g_switch_value = SDATA_DEFAULT_SIZE; \
\
+ if (rs6000_abi_name == NULL) \
+ rs6000_abi_name = RS6000_ABI_NAME; \
+ \
if (!strcmp (rs6000_abi_name, "sysv")) \
rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "sysv-noeabi")) \
@@ -186,11 +189,6 @@ do { \
rs6000_current_abi = ABI_V4; \
target_flags |= MASK_EABI; \
} \
- else if (!strcmp (rs6000_abi_name, "aix")) \
- { \
- rs6000_current_abi = ABI_AIX_NODESC; \
- target_flags |= MASK_EABI; \
- } \
else if (!strcmp (rs6000_abi_name, "aixdesc")) \
rs6000_current_abi = ABI_AIX; \
else if (!strcmp (rs6000_abi_name, "freebsd")) \
@@ -201,6 +199,8 @@ do { \
rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "netbsd")) \
rs6000_current_abi = ABI_V4; \
+ else if (!strcmp (rs6000_abi_name, "openbsd")) \
+ rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "i960-old")) \
{ \
rs6000_current_abi = ABI_V4; \
@@ -248,8 +248,9 @@ do { \
rs6000_sdata_name); \
} \
\
- else if (flag_pic && \
- (rs6000_sdata == SDATA_EABI || rs6000_sdata == SDATA_SYSV)) \
+ else if (flag_pic && DEFAULT_ABI != ABI_AIX \
+ && (rs6000_sdata == SDATA_EABI \
+ || rs6000_sdata == SDATA_SYSV)) \
{ \
rs6000_sdata = SDATA_DATA; \
error ("-f%s and -msdata=%s are incompatible", \
@@ -280,7 +281,7 @@ do { \
rs6000_abi_name); \
} \
\
- if (flag_pic > 1 && rs6000_current_abi == ABI_AIX) \
+ if (!TARGET_64BIT && flag_pic > 1 && rs6000_current_abi == ABI_AIX) \
{ \
flag_pic = 0; \
error ("-fPIC and -mcall-%s are incompatible", \
@@ -294,14 +295,21 @@ do { \
} \
\
/* Treat -fPIC the same as -mrelocatable. */ \
- if (flag_pic > 1) \
+ if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX) \
target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \
\
else if (TARGET_RELOCATABLE) \
flag_pic = 2; \
- \
} while (0)
+#ifndef RS6000_BI_ARCH
+# define SUBSUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
+ error ("-m%s not supported in this configuration", \
+ (target_flags & MASK_64BIT) ? "64" : "32"); \
+} while (0)
+#endif
/* Override rs6000.h definition. */
#undef TARGET_DEFAULT
@@ -377,12 +385,6 @@ do { \
#undef STRICT_ALIGNMENT
#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN)
-/* Alignment in bits of the stack boundary. Note, in order to allow building
- one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
- versions, just use 64 as the stack boundary. */
-#undef STACK_BOUNDARY
-#define STACK_BOUNDARY (TARGET_ALTIVEC_ABI ? 128 : 64)
-
/* Define this macro if you wish to preserve a certain alignment for
the stack pointer, greater than what the hardware enforces. The
definition is a C expression for the desired alignment (measured
@@ -399,7 +401,8 @@ do { \
#define PREFERRED_STACK_BOUNDARY 128
/* Real stack boundary as mandated by the appropriate ABI. */
-#define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define ABI_STACK_BOUNDARY \
+ ((TARGET_EABI && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* An expression for the alignment of a structure field FIELD if the
alignment computed in the usual way is COMPUTED. */
@@ -438,7 +441,8 @@ do { \
/* Put PC relative got entries in .got2. */
#define MINIMAL_TOC_SECTION_ASM_OP \
- ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
+ (TARGET_RELOCATABLE || (flag_pic && DEFAULT_ABI != ABI_AIX) \
+ ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\""
#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\""
@@ -461,7 +465,7 @@ do { \
#define TOC_SECTION_FUNCTION \
void \
-toc_section () \
+toc_section (void) \
{ \
if (in_section != in_toc) \
{ \
@@ -474,7 +478,7 @@ toc_section () \
{ \
toc_initialized = 1; \
fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LCTOC", 0); \
+ (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0); \
fprintf (asm_out_file, "\t.tc "); \
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],"); \
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \
@@ -502,15 +506,15 @@ toc_section () \
} \
} \
\
-extern int in_toc_section PARAMS ((void)); \
-int in_toc_section () \
+extern int in_toc_section (void); \
+int in_toc_section (void) \
{ \
return in_section == in_toc; \
}
#define SDATA_SECTION_FUNCTION \
void \
-sdata_section () \
+sdata_section (void) \
{ \
if (in_section != in_sdata) \
{ \
@@ -521,7 +525,7 @@ sdata_section () \
#define SDATA2_SECTION_FUNCTION \
void \
-sdata2_section () \
+sdata2_section (void) \
{ \
if (in_section != in_sdata2) \
{ \
@@ -532,7 +536,7 @@ sdata2_section () \
#define SBSS_SECTION_FUNCTION \
void \
-sbss_section () \
+sbss_section (void) \
{ \
if (in_section != in_sbss) \
{ \
@@ -543,7 +547,7 @@ sbss_section () \
#define INIT_SECTION_FUNCTION \
void \
-init_section () \
+init_section (void) \
{ \
if (in_section != in_init) \
{ \
@@ -554,7 +558,7 @@ init_section () \
#define FINI_SECTION_FUNCTION \
void \
-fini_section () \
+fini_section (void) \
{ \
if (in_section != in_fini) \
{ \
@@ -610,51 +614,7 @@ extern int rs6000_pic_labelno;
/* Override elfos.h definition. */
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do { \
- const char *const init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \
- \
- if (TARGET_RELOCATABLE \
- && (get_pool_size () != 0 || current_function_profile) \
- && uses_TOC()) \
- { \
- char buf[256]; \
- \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LCL", rs6000_pic_labelno); \
- \
- ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); \
- fprintf (FILE, "\t%s ", init_ptr); \
- assemble_name (FILE, buf); \
- putc ('-', FILE); \
- ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); \
- assemble_name (FILE, buf); \
- putc ('\n', FILE); \
- } \
- \
- ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
- ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
- \
- if (DEFAULT_ABI == ABI_AIX) \
- { \
- const char *desc_name, *orig_name; \
- \
- orig_name = (*targetm.strip_name_encoding) (NAME); \
- desc_name = orig_name; \
- while (*desc_name == '.') \
- desc_name++; \
- \
- if (TREE_PUBLIC (DECL)) \
- fprintf (FILE, "\t.globl %s\n", desc_name); \
- \
- fprintf (FILE, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
- fprintf (FILE, "%s:\n", desc_name); \
- fprintf (FILE, "\t%s %s\n", init_ptr, orig_name); \
- fprintf (FILE, "\t%s _GLOBAL_OFFSET_TABLE_\n", init_ptr); \
- if (DEFAULT_ABI == ABI_AIX) \
- fprintf (FILE, "\t%s 0\n", init_ptr); \
- fprintf (FILE, "\t.previous\n"); \
- } \
- ASM_OUTPUT_LABEL (FILE, NAME); \
- } while (0)
+ rs6000_elf_declare_function_name ((FILE), (NAME), (DECL))
/* The USER_LABEL_PREFIX stuff is affected by the -fleading-underscore
flag. The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */
@@ -662,7 +622,7 @@ extern int rs6000_pic_labelno;
#define LOCAL_LABEL_PREFIX "."
#define USER_LABEL_PREFIX ""
-/* svr4.h overrides ASM_OUTPUT_INTERNAL_LABEL. */
+/* svr4.h overrides (*targetm.asm_out.internal_label). */
#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \
asm_fprintf (FILE, "%L%s", PREFIX)
@@ -697,7 +657,8 @@ do { \
{ \
fprintf (FILE, "%s", LCOMM_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
+ (SIZE), (ALIGN) / BITS_PER_UNIT); \
} \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
} while (0)
@@ -708,6 +669,20 @@ do { \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
+#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+/* To support -falign-* switches we need to use .p2align so
+ that alignment directives in code sections will be padded
+ with no-op instructions, rather than zeroes. */
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+ if ((LOG) != 0) \
+ { \
+ if ((MAX_SKIP) == 0) \
+ fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else \
+ fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
+ }
+#endif
+
/* This is how to output code to push a register on the stack.
It need not be very fast code.
@@ -747,16 +722,6 @@ do { \
|| (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \
|| (CHAR) == 'B' || (CHAR) == 'b' || (CHAR) == 'G')
-/* Output .file. */
-/* Override elfos.h definition. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-do { \
- output_file_directive ((FILE), main_input_filename); \
- rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \
-} while (0)
-
-
extern int fixuplabelno;
/* Handle constructors specially for -mrelocatable. */
@@ -772,8 +737,21 @@ extern int fixuplabelno;
/* Historically we have also supported stabs debugging. */
#define DBX_DEBUGGING_INFO 1
+#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+
+/* Map register numbers held in the call frame info that gcc has
+ collected using DWARF_FRAME_REGNUM to those that should be output in
+ .debug_frame and .eh_frame. We continue to use gcc hard reg numbers
+ for .eh_frame, but use the numbers mandated by the various ABIs for
+ .debug_frame. rs6000_emit_prologue has translated any combination of
+ CR2, CR3, CR4 saves to a save of CR2. The actual code emitted saves
+ the whole of CR, so we map CR2_REGNO to the DWARF reg for CR. */
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) \
+ ((FOR_EH) ? (REGNO) \
+ : (REGNO) == CR2_REGNO ? 64 \
+ : DBX_REGISTER_NUMBER (REGNO))
+
#define TARGET_ENCODE_SECTION_INFO rs6000_elf_encode_section_info
-#define TARGET_STRIP_NAME_ENCODING rs6000_elf_strip_name_encoding
#define TARGET_IN_SMALL_DATA_P rs6000_elf_in_small_data_p
#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
@@ -782,25 +760,8 @@ extern int fixuplabelno;
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
assemble_name (FILE, NAME)
-/* This is how to output a reference to a user-level label named NAME.
- `assemble_name' uses this. */
-
-/* Override elfos.h definition. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-do { \
- const char *_name = NAME; \
- if (*_name == '@') \
- _name++; \
- \
- if (*_name == '*') \
- fprintf (FILE, "%s", _name + 1); \
- else \
- asm_fprintf (FILE, "%U%s", _name); \
-} while (0)
-
-/* But, to make this work, we have to output the stabs for the function
- name *first*... */
+/* We have to output the stabs for the function name *first*, before
+ outputting its label. */
#define DBX_FUNCTION_FIRST
@@ -810,6 +771,25 @@ do { \
#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
#endif
+#define TARGET_OS_SYSV_CPP_BUILTINS() \
+ do \
+ { \
+ if (flag_pic == 1) \
+ { \
+ builtin_define ("__pic__=1"); \
+ builtin_define ("__PIC__=1"); \
+ } \
+ else if (flag_pic == 2) \
+ { \
+ builtin_define ("__pic__=2"); \
+ builtin_define ("__PIC__=2"); \
+ } \
+ if (target_flags_explicit \
+ & MASK_RELOCATABLE) \
+ builtin_define ("_RELOCATABLE"); \
+ } \
+ while (0)
+
#ifndef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
@@ -821,6 +801,7 @@ do { \
builtin_assert ("system=svr4"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
#endif
@@ -831,16 +812,17 @@ do { \
#define ASM_SPEC "%(asm_cpu) \
%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
-%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
-%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
-%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
- %{mcall-freebsd: -mbig} \
- %{mcall-i960-old: -mlittle} \
- %{mcall-linux: -mbig} \
- %{mcall-gnu: -mbig} \
- %{mcall-netbsd: -mbig} \
-}}}}"
+%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
+%{memb|msdata|msdata=eabi: -memb} \
+%{mlittle|mlittle-endian:-mlittle; \
+ mbig|mbig-endian :-mbig; \
+ mcall-aixdesc | \
+ mcall-freebsd | \
+ mcall-netbsd | \
+ mcall-openbsd | \
+ mcall-linux | \
+ mcall-gnu :-mbig; \
+ mcall-i960-old :-mlittle}"
#define CC1_ENDIAN_BIG_SPEC ""
@@ -855,19 +837,16 @@ do { \
/* Pass -G xxx to the compiler and set correct endian mode. */
#define CC1_SPEC "%{G*} \
-%{mlittle: %(cc1_endian_little)} %{!mlittle: %{mlittle-endian: %(cc1_endian_little)}} \
-%{mbig: %(cc1_endian_big)} %{!mbig: %{mbig-endian: %(cc1_endian_big)}} \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
- %{mcall-aixdesc: -mbig %(cc1_endian_big) } \
- %{mcall-freebsd: -mbig %(cc1_endian_big) } \
- %{mcall-i960-old: -mlittle %(cc1_endian_little) } \
- %{mcall-linux: -mbig %(cc1_endian_big) } \
- %{mcall-gnu: -mbig %(cc1_endian_big) } \
- %{mcall-netbsd: -mbig %(cc1_endian_big) } \
- %{!mcall-aixdesc: %{!mcall-freebsd: %{!mcall-i960-old: %{!mcall-linux: %{!mcall-gnu: %{!mcall-netbsd: \
- %(cc1_endian_default) \
- }}}}}} \
-}}}} \
+%{mlittle|mlittle-endian: %(cc1_endian_little); \
+ mbig |mbig-endian : %(cc1_endian_big); \
+ mcall-aixdesc | \
+ mcall-freebsd | \
+ mcall-netbsd | \
+ mcall-openbsd | \
+ mcall-linux | \
+ mcall-gnu : -mbig %(cc1_endian_big); \
+ mcall-i960-old : -mlittle %(cc1_endian_little); \
+ : %(cc1_endian_default)} \
%{mno-sdata: -msdata=none } \
%{meabi: %{!mcall-*: -mcall-sysv }} \
%{!meabi: %{!mno-eabi: \
@@ -876,7 +855,8 @@ do { \
%{mcall-i960-old: -meabi } \
%{mcall-linux: -mno-eabi } \
%{mcall-gnu: -mno-eabi } \
- %{mcall-netbsd: -mno-eabi }}} \
+ %{mcall-netbsd: -mno-eabi } \
+ %{mcall-openbsd: -mno-eabi }}} \
%{msdata: -msdata=default} \
%{mno-sdata: -msdata=none} \
%{profile: -p}"
@@ -900,18 +880,17 @@ do { \
/* Default starting address if specified. */
#define LINK_START_SPEC "\
-%{mads: %(link_start_ads) } \
-%{myellowknife: %(link_start_yellowknife) } \
-%{mmvme: %(link_start_mvme) } \
-%{msim: %(link_start_sim) } \
-%{mwindiss: %(link_start_windiss) } \
-%{mcall-freebsd: %(link_start_freebsd) } \
-%{mcall-linux: %(link_start_linux) } \
-%{mcall-gnu: %(link_start_gnu) } \
-%{mcall-netbsd: %(link_start_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-linux: %{!mcall-gnu: %{!mcall-netbsd: \
- %{!mcall-freebsd: %(link_start_default) }}}}}}}}}"
+%{mads : %(link_start_ads) ; \
+ myellowknife : %(link_start_yellowknife) ; \
+ mmvme : %(link_start_mvme) ; \
+ msim : %(link_start_sim) ; \
+ mwindiss : %(link_start_windiss) ; \
+ mcall-freebsd: %(link_start_freebsd) ; \
+ mcall-linux : %(link_start_linux) ; \
+ mcall-gnu : %(link_start_gnu) ; \
+ mcall-netbsd : %(link_start_netbsd) ; \
+ mcall-openbsd: %(link_start_openbsd) ; \
+ : %(link_start_default) }"
#define LINK_START_DEFAULT_SPEC ""
@@ -959,97 +938,85 @@ do { \
/* Any specific OS flags. */
#define LINK_OS_SPEC "\
-%{mads: %(link_os_ads) } \
-%{myellowknife: %(link_os_yellowknife) } \
-%{mmvme: %(link_os_mvme) } \
-%{msim: %(link_os_sim) } \
-%{mwindiss: %(link_os_windiss) } \
-%{mcall-freebsd: %(link_os_freebsd) } \
-%{mcall-linux: %(link_os_linux) } \
-%{mcall-gnu: %(link_os_gnu) } \
-%{mcall-netbsd: %(link_os_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(link_os_default) }}}}}}}}}"
+%{mads : %(link_os_ads) ; \
+ myellowknife : %(link_os_yellowknife) ; \
+ mmvme : %(link_os_mvme) ; \
+ msim : %(link_os_sim) ; \
+ mwindiss : %(link_os_windiss) ; \
+ mcall-freebsd: %(link_os_freebsd) ; \
+ mcall-linux : %(link_os_linux) ; \
+ mcall-gnu : %(link_os_gnu) ; \
+ mcall-netbsd : %(link_os_netbsd) ; \
+ mcall-openbsd: %(link_os_openbsd) ; \
+ : %(link_os_default) }"
#define LINK_OS_DEFAULT_SPEC ""
-#define CPP_SYSV_SPEC \
-"%{mrelocatable*: -D_RELOCATABLE} \
-%{fpic: -D__PIC__=1 -D__pic__=1} \
-%{!fpic: %{fPIC: -D__PIC__=2 -D__pic__=2}}"
-
/* Override rs6000.h definition. */
#undef CPP_SPEC
-#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) \
-%{mads: %(cpp_os_ads) } \
-%{myellowknife: %(cpp_os_yellowknife) } \
-%{mmvme: %(cpp_os_mvme) } \
-%{msim: %(cpp_os_sim) } \
-%{mwindiss: %(cpp_os_windiss) } \
-%{mcall-freebsd: %(cpp_os_freebsd) } \
-%{mcall-linux: %(cpp_os_linux) } \
-%{mcall-gnu: %(cpp_os_gnu) } \
-%{mcall-netbsd: %(cpp_os_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(cpp_os_default) }}}}}}}}}"
+#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
+%{mads : %(cpp_os_ads) ; \
+ myellowknife : %(cpp_os_yellowknife) ; \
+ mmvme : %(cpp_os_mvme) ; \
+ msim : %(cpp_os_sim) ; \
+ mwindiss : %(cpp_os_windiss) ; \
+ mcall-freebsd: %(cpp_os_freebsd) ; \
+ mcall-linux : %(cpp_os_linux) ; \
+ mcall-gnu : %(cpp_os_gnu) ; \
+ mcall-netbsd : %(cpp_os_netbsd) ; \
+ mcall-openbsd: %(cpp_os_openbsd) ; \
+ : %(cpp_os_default) }"
#define CPP_OS_DEFAULT_SPEC ""
/* Override svr4.h definition. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "\
-%{mads: %(startfile_ads) } \
-%{myellowknife: %(startfile_yellowknife) } \
-%{mmvme: %(startfile_mvme) } \
-%{msim: %(startfile_sim) } \
-%{mwindiss: %(startfile_windiss) } \
-%{mcall-freebsd: %(startfile_freebsd) } \
-%{mcall-linux: %(startfile_linux) } \
-%{mcall-gnu: %(startfile_gnu) } \
-%{mcall-netbsd: %(startfile_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(startfile_default) }}}}}}}}}"
+%{mads : %(startfile_ads) ; \
+ myellowknife : %(startfile_yellowknife) ; \
+ mmvme : %(startfile_mvme) ; \
+ msim : %(startfile_sim) ; \
+ mwindiss : %(startfile_windiss) ; \
+ mcall-freebsd: %(startfile_freebsd) ; \
+ mcall-linux : %(startfile_linux) ; \
+ mcall-gnu : %(startfile_gnu) ; \
+ mcall-netbsd : %(startfile_netbsd) ; \
+ mcall-openbsd: %(startfile_openbsd) ; \
+ : %(startfile_default) }"
#define STARTFILE_DEFAULT_SPEC ""
/* Override svr4.h definition. */
#undef LIB_SPEC
#define LIB_SPEC "\
-%{mads: %(lib_ads) } \
-%{myellowknife: %(lib_yellowknife) } \
-%{mmvme: %(lib_mvme) } \
-%{msim: %(lib_sim) } \
-%{mwindiss: %(lib_windiss) } \
-%{mcall-freebsd: %(lib_freebsd) } \
-%{mcall-linux: %(lib_linux) } \
-%{mcall-gnu: %(lib_gnu) } \
-%{mcall-netbsd: %(lib_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(lib_default) }}}}}}}}}"
+%{mads : %(lib_ads) ; \
+ myellowknife : %(lib_yellowknife) ; \
+ mmvme : %(lib_mvme) ; \
+ msim : %(lib_sim) ; \
+ mwindiss : %(lib_windiss) ; \
+ mcall-freebsd: %(lib_freebsd) ; \
+ mcall-linux : %(lib_linux) ; \
+ mcall-gnu : %(lib_gnu) ; \
+ mcall-netbsd : %(lib_netbsd) ; \
+ mcall-openbsd: %(lib_openbsd) ; \
+ : %(lib_default) }"
#define LIB_DEFAULT_SPEC ""
/* Override svr4.h definition. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "\
-%{mads: crtsavres.o%s %(endfile_ads)} \
-%{myellowknife: crtsavres.o%s %(endfile_yellowknife)} \
-%{mmvme: crtsavres.o%s %(endfile_mvme)} \
-%{msim: crtsavres.o%s %(endfile_sim)} \
-%{mwindiss: %(endfile_windiss)} \
-%{mcall-freebsd: crtsavres.o%s %(endfile_freebsd) } \
-%{mcall-linux: crtsavres.o%s %(endfile_linux) } \
-%{mcall-gnu: crtsavres.o%s %(endfile_gnu) } \
-%{mcall-netbsd: crtsavres.o%s %(endfile_netbsd) } \
-%{mvxworks: crtsavres.o%s %(endfile_vxworks) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %{!mvxworks: %(crtsavres_default) \
- %(endfile_default) }}}}}}}}}}"
+%{mads : crtsavres.o%s %(endfile_ads) ; \
+ myellowknife : crtsavres.o%s %(endfile_yellowknife) ; \
+ mmvme : crtsavres.o%s %(endfile_mvme) ; \
+ msim : crtsavres.o%s %(endfile_sim) ; \
+ mwindiss : %(endfile_windiss) ; \
+ mcall-freebsd: crtsavres.o%s %(endfile_freebsd) ; \
+ mcall-linux : crtsavres.o%s %(endfile_linux) ; \
+ mcall-gnu : crtsavres.o%s %(endfile_gnu) ; \
+ mcall-netbsd : crtsavres.o%s %(endfile_netbsd) ; \
+ mcall-openbsd: crtsavres.o%s %(endfile_openbsd) ; \
+ : %(crtsavres_default) %(endfile_default) }"
#define CRTSAVRES_DEFAULT_SPEC "crtsavres.o%s"
@@ -1110,7 +1077,7 @@ do { \
/* FreeBSD support. */
#define CPP_OS_FREEBSD_SPEC "\
- -D__ELF__ -D__PPC__ -D__ppc__ -D__PowerPC__ -D__powerpc__ \
+ -D__PPC__ -D__ppc__ -D__PowerPC__ -D__powerpc__ \
-Acpu=powerpc -Amachine=powerpc"
#define STARTFILE_FREEBSD_SPEC FBSD_STARTFILE_SPEC
@@ -1120,38 +1087,32 @@ do { \
#define LINK_OS_FREEBSD_SPEC "\
%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
- %{Wl,*:%*} \
- %{v:-V} \
- %{assert*} %{R*} %{rpath*} %{defsym*} \
- %{shared:-Bshareable %{h*} %{soname*}} \
- %{!shared: \
- %{!static: \
- %{rdynamic: -export-dynamic} \
- %{!dynamic-linker: -dynamic-linker /usr/libexec/ld-elf.so.1}} \
- %{static:-Bstatic}} \
- %{symbolic:-Bsymbolic}"
+ %{Wl,*:%*} \
+ %{v:-V} \
+ %{assert*} %{R*} %{rpath*} %{defsym*} \
+ %{shared:-Bshareable %{h*} %{soname*}} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic: -export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
+ %{static:-Bstatic}} \
+ %{symbolic:-Bsymbolic}"
/* GNU/Linux support. */
-#ifdef USE_GNULIBC_1
-#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \
-%{!mnewlib: -lc }"
-#else
#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \
-%{!mnewlib: %{shared:-lc} %{!shared: %{pthread:-lpthread } \
-%{profile:-lc_p} %{!profile:-lc}}}"
-#endif
+%{!mnewlib: %{pthread:-lpthread} %{shared:-lc} \
+%{!shared: %{profile:-lc_p} %{!profile:-lc}}}"
-#ifdef USE_GNULIBC_1
+#ifdef HAVE_LD_PIE
#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
-%{mnewlib: ecrti.o%s} %{!mnewlib: crti.o%s} \
-%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
+%{mnewlib:ecrti.o%s;:crti.o%s} \
+%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
-%{mnewlib: ecrti.o%s} %{!mnewlib: crti.o%s} \
-%{static:crtbeginT.o%s} \
-%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}} \
+%{mnewlib:ecrti.o%s;:crti.o%s} \
+%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
#define ENDFILE_LINUX_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
@@ -1163,25 +1124,16 @@ do { \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
-#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
+#if defined(HAVE_LD_EH_FRAME_HDR)
# define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
-#ifdef USE_GNULIBC_1
-#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \
-%{!undef: \
- %{!ansi: \
- %{!std=*:-Dunix -D__unix -Dlinux -D__linux} \
- %{std=gnu*:-Dunix -D__unix -Dlinux -D__linux}}} \
--Asystem=unix -Asystem=posix"
-#else
#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \
%{!undef: \
%{!ansi: \
%{!std=*:-Dunix -D__unix -Dlinux -D__linux} \
%{std=gnu*:-Dunix -D__unix -Dlinux -D__linux}}} \
--Asystem=unix -Asystem=posix %{pthread:-D_REENTRANT}"
-#endif
+-Asystem=linux -Asystem=unix -Asystem=posix %{pthread:-D_REENTRANT}"
/* GNU/Hurd support. */
#define LIB_GNU_SPEC "%{mnewlib: --start-group -lgnu -lc --end-group } \
@@ -1229,64 +1181,35 @@ ncrtn.o%s"
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld.elf_so}}}"
#define CPP_OS_NETBSD_SPEC "\
--D__powerpc__ -D__NetBSD__ -D__ELF__ -D__KPRINTF_ATTRIBUTE__"
-
-/* RTEMS support. */
-
-#define CPP_OS_RTEMS_SPEC "\
-%{!mcpu*: %{!Dppc*: %{!Dmpc*: -Dmpc750} } }\
-%{mcpu=403: %{!Dppc*: %{!Dmpc*: -Dppc403} } } \
-%{mcpu=505: %{!Dppc*: %{!Dmpc*: -Dmpc505} } } \
-%{mcpu=601: %{!Dppc*: %{!Dmpc*: -Dppc601} } } \
-%{mcpu=602: %{!Dppc*: %{!Dmpc*: -Dppc602} } } \
-%{mcpu=603: %{!Dppc*: %{!Dmpc*: -Dppc603} } } \
-%{mcpu=603e: %{!Dppc*: %{!Dmpc*: -Dppc603e} } } \
-%{mcpu=604: %{!Dppc*: %{!Dmpc*: -Dmpc604} } } \
-%{mcpu=750: %{!Dppc*: %{!Dmpc*: -Dmpc750} } } \
-%{mcpu=821: %{!Dppc*: %{!Dmpc*: -Dmpc821} } } \
-%{mcpu=860: %{!Dppc*: %{!Dmpc*: -Dmpc860} } }"
-
-/* VxWorks support. */
-/* VxWorks does all the library stuff itself. */
-#define LIB_VXWORKS_SPEC ""
-
-/* VxWorks provides the functionality of crt0.o and friends itself. */
-
-#define STARTFILE_VXWORKS_SPEC ""
-
-#define ENDFILE_VXWORKS_SPEC ""
-
-/* Because it uses ld -r, vxworks has no start/end files, nor starting
- address. */
-
-#define LINK_START_VXWORKS_SPEC ""
-
-#define LINK_OS_VXWORKS_SPEC "-r"
-
-#define CPP_OS_VXWORKS_SPEC "\
--DCPU_FAMILY=PPC \
-%{!mcpu*: \
- %{mpowerpc*: -DCPU=PPC603} \
- %{!mno-powerpc: -DCPU=PPC603}} \
-%{mcpu=powerpc: -DCPU=PPC603} \
-%{mcpu=401: -DCPU=PPC403} \
-%{mcpu=403: -DCPU=PPC403} \
-%{mcpu=405: -DCPU=PPC405} \
-%{mcpu=601: -DCPU=PPC601} \
-%{mcpu=602: -DCPU=PPC603} \
-%{mcpu=603: -DCPU=PPC603} \
-%{mcpu=603e: -DCPU=PPC603} \
-%{mcpu=ec603e: -DCPU=PPC603} \
-%{mcpu=604: -DCPU=PPC604} \
-%{mcpu=604e: -DCPU=PPC604} \
-%{mcpu=620: -DCPU=PPC604} \
-%{mcpu=740: -DCPU=PPC603} \
-%{mcpu=7450: -DCPU=PPC603} \
-%{mcpu=750: -DCPU=PPC603} \
-%{mcpu=801: -DCPU=PPC603} \
-%{mcpu=821: -DCPU=PPC603} \
-%{mcpu=823: -DCPU=PPC603} \
-%{mcpu=860: -DCPU=PPC603}"
+-D__powerpc__ -D__NetBSD__ -D__KPRINTF_ATTRIBUTE__"
+
+/* OpenBSD support. */
+#ifndef LIB_OPENBSD_SPEC
+#define LIB_OPENBSD_SPEC "%{!shared:%{pthread:-lpthread%{p:_p}%{!p:%{pg:_p}}}} %{!shared:-lc%{p:_p}%{!p:%{pg:_p}}}"
+#endif
+
+#ifndef STARTFILE_OPENBSD_SPEC
+#define STARTFILE_OPENBSD_SPEC "\
+%{!shared: %{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}}} \
+%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#endif
+
+#ifndef ENDFILE_OPENBSD_SPEC
+#define ENDFILE_OPENBSD_SPEC "\
+%{!shared:crtend.o%s} %{shared:crtendS.o%s}"
+#endif
+
+#ifndef LINK_START_OPENBSD_SPEC
+#define LINK_START_OPENBSD_SPEC "-Ttext 0x400074"
+#endif
+
+#ifndef LINK_OS_OPENBSD_SPEC
+#define LINK_OS_OPENBSD_SPEC ""
+#endif
+
+#ifndef CPP_OS_OPENBSD_SPEC
+#define CPP_OS_OPENBSD_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_POSIX_THREADS}"
+#endif
/* WindISS support. */
@@ -1311,7 +1234,6 @@ ncrtn.o%s"
/* Override rs6000.h definition. */
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
- { "cpp_sysv", CPP_SYSV_SPEC }, \
{ "crtsavres_default", CRTSAVRES_DEFAULT_SPEC }, \
{ "lib_ads", LIB_ADS_SPEC }, \
{ "lib_yellowknife", LIB_YELLOWKNIFE_SPEC }, \
@@ -1321,7 +1243,7 @@ ncrtn.o%s"
{ "lib_gnu", LIB_GNU_SPEC }, \
{ "lib_linux", LIB_LINUX_SPEC }, \
{ "lib_netbsd", LIB_NETBSD_SPEC }, \
- { "lib_vxworks", LIB_VXWORKS_SPEC }, \
+ { "lib_openbsd", LIB_OPENBSD_SPEC }, \
{ "lib_windiss", LIB_WINDISS_SPEC }, \
{ "lib_default", LIB_DEFAULT_SPEC }, \
{ "startfile_ads", STARTFILE_ADS_SPEC }, \
@@ -1332,7 +1254,7 @@ ncrtn.o%s"
{ "startfile_gnu", STARTFILE_GNU_SPEC }, \
{ "startfile_linux", STARTFILE_LINUX_SPEC }, \
{ "startfile_netbsd", STARTFILE_NETBSD_SPEC }, \
- { "startfile_vxworks", STARTFILE_VXWORKS_SPEC }, \
+ { "startfile_openbsd", STARTFILE_OPENBSD_SPEC }, \
{ "startfile_windiss", STARTFILE_WINDISS_SPEC }, \
{ "startfile_default", STARTFILE_DEFAULT_SPEC }, \
{ "endfile_ads", ENDFILE_ADS_SPEC }, \
@@ -1343,7 +1265,7 @@ ncrtn.o%s"
{ "endfile_gnu", ENDFILE_GNU_SPEC }, \
{ "endfile_linux", ENDFILE_LINUX_SPEC }, \
{ "endfile_netbsd", ENDFILE_NETBSD_SPEC }, \
- { "endfile_vxworks", ENDFILE_VXWORKS_SPEC }, \
+ { "endfile_openbsd", ENDFILE_OPENBSD_SPEC }, \
{ "endfile_windiss", ENDFILE_WINDISS_SPEC }, \
{ "endfile_default", ENDFILE_DEFAULT_SPEC }, \
{ "link_path", LINK_PATH_SPEC }, \
@@ -1358,7 +1280,7 @@ ncrtn.o%s"
{ "link_start_gnu", LINK_START_GNU_SPEC }, \
{ "link_start_linux", LINK_START_LINUX_SPEC }, \
{ "link_start_netbsd", LINK_START_NETBSD_SPEC }, \
- { "link_start_vxworks", LINK_START_VXWORKS_SPEC }, \
+ { "link_start_openbsd", LINK_START_OPENBSD_SPEC }, \
{ "link_start_windiss", LINK_START_WINDISS_SPEC }, \
{ "link_start_default", LINK_START_DEFAULT_SPEC }, \
{ "link_os", LINK_OS_SPEC }, \
@@ -1370,7 +1292,7 @@ ncrtn.o%s"
{ "link_os_linux", LINK_OS_LINUX_SPEC }, \
{ "link_os_gnu", LINK_OS_GNU_SPEC }, \
{ "link_os_netbsd", LINK_OS_NETBSD_SPEC }, \
- { "link_os_vxworks", LINK_OS_VXWORKS_SPEC }, \
+ { "link_os_openbsd", LINK_OS_OPENBSD_SPEC }, \
{ "link_os_windiss", LINK_OS_WINDISS_SPEC }, \
{ "link_os_default", LINK_OS_DEFAULT_SPEC }, \
{ "cc1_endian_big", CC1_ENDIAN_BIG_SPEC }, \
@@ -1384,10 +1306,13 @@ ncrtn.o%s"
{ "cpp_os_gnu", CPP_OS_GNU_SPEC }, \
{ "cpp_os_linux", CPP_OS_LINUX_SPEC }, \
{ "cpp_os_netbsd", CPP_OS_NETBSD_SPEC }, \
- { "cpp_os_rtems", CPP_OS_RTEMS_SPEC }, \
- { "cpp_os_vxworks", CPP_OS_VXWORKS_SPEC }, \
+ { "cpp_os_openbsd", CPP_OS_OPENBSD_SPEC }, \
{ "cpp_os_windiss", CPP_OS_WINDISS_SPEC }, \
- { "cpp_os_default", CPP_OS_DEFAULT_SPEC },
+ { "cpp_os_default", CPP_OS_DEFAULT_SPEC }, \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }, \
+ SUBSUBTARGET_EXTRA_SPECS
+
+#define SUBSUBTARGET_EXTRA_SPECS
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
@@ -1420,63 +1345,6 @@ ncrtn.o%s"
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-/* Define library calls for quad FP operations. These are all part of the
- PowerPC 32bit ABI. */
-#define ADDTF3_LIBCALL "_q_add"
-#define DIVTF3_LIBCALL "_q_div"
-#define EXTENDDFTF2_LIBCALL "_q_dtoq"
-#define EQTF2_LIBCALL "_q_feq"
-#define GETF2_LIBCALL "_q_fge"
-#define GTTF2_LIBCALL "_q_fgt"
-#define LETF2_LIBCALL "_q_fle"
-#define LTTF2_LIBCALL "_q_flt"
-#define NETF2_LIBCALL "_q_fne"
-#define FLOATSITF2_LIBCALL "_q_itoq"
-#define MULTF3_LIBCALL "_q_mul"
-#define NEGTF2_LIBCALL "_q_neg"
-#define TRUNCTFDF2_LIBCALL "_q_qtod"
-#define FIX_TRUNCTFSI2_LIBCALL "_q_qtoi"
-#define TRUNCTFSF2_LIBCALL "_q_qtos"
-#define FIXUNS_TRUNCTFSI2_LIBCALL "_q_qtou"
-#define SQRTTF_LIBCALL "_q_sqrt"
-#define EXTENDSFTF2_LIBCALL "_q_stoq"
-#define SUBTF3_LIBCALL "_q_sub"
-#define FLOATUNSSITF2_LIBCALL "_q_utoq"
-
-#define INIT_TARGET_OPTABS \
- do { \
- if (TARGET_HARD_FLOAT) \
- { \
- add_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (ADDTF3_LIBCALL); \
- sub_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SUBTF3_LIBCALL); \
- neg_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (NEGTF2_LIBCALL); \
- smul_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (MULTF3_LIBCALL); \
- sdiv_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (DIVTF3_LIBCALL); \
- eqtf2_libfunc = init_one_libfunc (EQTF2_LIBCALL); \
- netf2_libfunc = init_one_libfunc (NETF2_LIBCALL); \
- gttf2_libfunc = init_one_libfunc (GTTF2_LIBCALL); \
- getf2_libfunc = init_one_libfunc (GETF2_LIBCALL); \
- lttf2_libfunc = init_one_libfunc (LTTF2_LIBCALL); \
- letf2_libfunc = init_one_libfunc (LETF2_LIBCALL); \
- trunctfsf2_libfunc = init_one_libfunc (TRUNCTFSF2_LIBCALL); \
- trunctfdf2_libfunc = init_one_libfunc (TRUNCTFDF2_LIBCALL); \
- extendsftf2_libfunc = init_one_libfunc (EXTENDSFTF2_LIBCALL); \
- extenddftf2_libfunc = init_one_libfunc (EXTENDDFTF2_LIBCALL); \
- floatsitf_libfunc = init_one_libfunc (FLOATSITF2_LIBCALL); \
- fixtfsi_libfunc = init_one_libfunc (FIX_TRUNCTFSI2_LIBCALL); \
- fixunstfsi_libfunc \
- = init_one_libfunc (FIXUNS_TRUNCTFSI2_LIBCALL); \
- if (TARGET_PPC_GPOPT || TARGET_POWER2) \
- sqrt_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SQRTTF_LIBCALL); \
- } \
- } while (0)
-
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. */
diff --git a/contrib/gcc/config/rs6000/sysv4le.h b/contrib/gcc/config/rs6000/sysv4le.h
index fda8477..38be8a6 100644
--- a/contrib/gcc/config/rs6000/sysv4le.h
+++ b/contrib/gcc/config/rs6000/sysv4le.h
@@ -1,26 +1,26 @@
-/* Target definitions for GNU compiler for a little endian PowerPC
+/* Target definitions for GCC for a little endian PowerPC
running System V.4
- Copyright (C) 1995, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2000, 2003 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_DEFAULT
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_LITTLE_ENDIAN)
#undef CC1_ENDIAN_DEFAULT_SPEC
@@ -33,14 +33,5 @@ Boston, MA 02111-1307, USA. */
%{mcall-linux: --oformat elf32-powerpc} \
}}}}"
-/* Define this macro as a C expression for the initializer of an
- array of string to tell the driver program which options are
- defaults for this target and thus do not need to be handled
- specially when using `MULTILIB_OPTIONS'.
-
- Do not define this macro if `MULTILIB_OPTIONS' is not defined in
- the target makefile fragment or if none of the options listed in
- `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
-
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" }
diff --git a/contrib/gcc/config/rs6000/t-beos b/contrib/gcc/config/rs6000/t-beos
index 1d4fbf7..badffef 100644
--- a/contrib/gcc/config/rs6000/t-beos
+++ b/contrib/gcc/config/rs6000/t-beos
@@ -1,23 +1,8 @@
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-# Build the libraries for both hard and soft floating point
+# Build the libraries for both hard & soft floating point and ppc/common.
MULTILIB_OPTIONS = msoft-float mcpu=common
MULTILIB_DIRNAMES = soft-float common
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
-
# This is probably the correct define, to override the Makefile
# default, but using it causes more problems than it solves.
#
diff --git a/contrib/gcc/config/rs6000/t-darwin b/contrib/gcc/config/rs6000/t-darwin
index 7aca023..185bb00 100644
--- a/contrib/gcc/config/rs6000/t-darwin
+++ b/contrib/gcc/config/rs6000/t-darwin
@@ -1,2 +1,7 @@
-# Library code must include trampoline support.
-LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-tramp.asm
+# Add trampoline and long double support to libgcc.
+LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-tramp.asm \
+ $(srcdir)/config/rs6000/darwin-ldouble.c
+
+# For libgcc, we always want 128-bit long double, since a libgcc built with
+# that will work without it.
+TARGET_LIBGCC2_CFLAGS = -mlong-double-128
diff --git a/contrib/gcc/config/rs6000/t-fprules b/contrib/gcc/config/rs6000/t-fprules
new file mode 100644
index 0000000..4fb09a2
--- /dev/null
+++ b/contrib/gcc/config/rs6000/t-fprules
@@ -0,0 +1,29 @@
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \
+ msoft-float=mcpu?403 \
+ msoft-float=mcpu?405 \
+ msoft-float=mcpu?ec603e \
+ msoft-float=mcpu?801 \
+ msoft-float=mcpu?821 \
+ msoft-float=mcpu?823 \
+ msoft-float=mcpu?860
+
+# Build the libraries for both hard and soft floating point by default
+
+MULTILIB_OPTIONS = msoft-float
+MULTILIB_DIRNAMES = soft-float
+MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT}
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/contrib/gcc/config/rs6000/t-linux64 b/contrib/gcc/config/rs6000/t-linux64
index af7b44b..77ba93e 100644
--- a/contrib/gcc/config/rs6000/t-linux64
+++ b/contrib/gcc/config/rs6000/t-linux64
@@ -1,19 +1,44 @@
-# Override t-linux. We don't want -fPIC.
-CRTSTUFF_T_CFLAGS_S =
-TARGET_LIBGCC2_CFLAGS =
-EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
- crtsavres.o
+#rs6000/t-linux64
-# These functions are needed for soft-float on powerpc64-linux.
-LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/ppc64-fp.c
+LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
+ $(srcdir)/config/rs6000/darwin-ldouble.c
-# ld provides these functions as needed.
-crtsavres.S:
- echo >crtsavres.S
+TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC -specs=bispecs
-$(T)crtsavres.o: crtsavres.S
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavres.S -o $(T)crtsavres.o
+SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-ppc64.ver
-# Modify the shared lib version file
-SHLIB_MKMAP_OPTS = -v dotsyms=1
+MULTILIB_OPTIONS = m64/m32 msoft-float
+MULTILIB_DIRNAMES = 64 32 nof
+MULTILIB_EXTRA_OPTS = fPIC mstrict-align
+MULTILIB_EXCEPTIONS = m64/msoft-float
+MULTILIB_EXCLUSIONS = m64/!m32/msoft-float
+MULTILIB_OSDIRNAMES = ../lib64 ../lib nof
+MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT)
+
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+# fp-bit is only to be used by 32-bit multilibs
+FPBIT = fp-bit32.c
+DPBIT = dp-bit32.c
+
+dp-bit32.c: $(srcdir)/config/fp-bit.c
+ ( echo '#ifndef __powerpc64__'; \
+ cat $(srcdir)/config/fp-bit.c; \
+ echo '#endif' ) > dp-bit32.c
+
+fp-bit32.c: $(srcdir)/config/fp-bit.c
+ ( echo '#ifndef __powerpc64__'; \
+ echo '#define FLOAT'; \
+ cat $(srcdir)/config/fp-bit.c; \
+ echo '#endif' ) > fp-bit32.c
+
+# Hack to use -mlong-double-128 just for compiling 64 bit libgcc
+mklibgcc: bispecs
+
+bispecs: specs
+ if [ x`$(GCC_FOR_TARGET) -print-multi-os-directory` = x../lib ]; then \
+ sed -e '/cc1_options/{ n; s/$$/ %{m64:-mlong-double-128}/; }' < specs > $@; \
+ else \
+ sed -e '/cc1_options/{ n; s/$$/ %{!m32:-mlong-double-128}/; }' < specs > $@; \
+ fi
diff --git a/contrib/gcc/config/rs6000/t-newas b/contrib/gcc/config/rs6000/t-newas
index b8e715a..a26ce39 100644
--- a/contrib/gcc/config/rs6000/t-newas
+++ b/contrib/gcc/config/rs6000/t-newas
@@ -1,15 +1,3 @@
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
# Build the libraries for both hard and soft floating point and all of the
# different processor models
@@ -19,7 +7,7 @@ MULTILIB_OPTIONS = msoft-float \
MULTILIB_DIRNAMES = soft-float \
common power powerpc
-MULTILIB_MATCHES = msoft-float=mcpu?403 \
+MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) \
mcpu?power=mpower \
mcpu?power=mrios1 \
mcpu?power=mcpu?rios1 \
@@ -39,9 +27,6 @@ MULTILIB_MATCHES = msoft-float=mcpu?403 \
mcpu?powerpc=mpowerpc-gpopt \
mcpu?powerpc=mpowerpc-gfxopt
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
-
# Aix 3.2.x needs milli.exp for -mcpu=common
EXTRA_PARTS = milli.exp
milli.exp: $(srcdir)/config/rs6000/milli.exp
diff --git a/contrib/gcc/config/rs6000/t-ppccomm b/contrib/gcc/config/rs6000/t-ppccomm
index f4fcdce..eaa3252 100644
--- a/contrib/gcc/config/rs6000/t-ppccomm
+++ b/contrib/gcc/config/rs6000/t-ppccomm
@@ -5,19 +5,6 @@ LIB2FUNCS_EXTRA = tramp.S
# This one can't end up in shared libgcc
LIB2FUNCS_STATIC_EXTRA = eabi.S
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
eabi.S: $(srcdir)/config/rs6000/eabi.asm
cat $(srcdir)/config/rs6000/eabi.asm > eabi.S
@@ -25,19 +12,9 @@ tramp.S: $(srcdir)/config/rs6000/tramp.asm
cat $(srcdir)/config/rs6000/tramp.asm > tramp.S
# Switch synonyms
-MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \
- msoft-float=mcpu?403 \
- msoft-float=mcpu?405 \
- msoft-float=mcpu?ec603e \
- msoft-float=mcpu?801 \
- msoft-float=mcpu?821 \
- msoft-float=mcpu?823 \
- msoft-float=mcpu?860
MULTILIB_MATCHES_ENDIAN = mlittle=mlittle-endian mbig=mbig-endian
MULTILIB_MATCHES_SYSV = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi mcall-sysv=mcall-linux mcall-sysv=mcall-netbsd
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS = crtbegin$(objext) crtend$(objext) \
crtbeginS$(objext) crtendS$(objext) crtbeginT$(objext) \
ecrti$(objext) ecrtn$(objext) \
diff --git a/contrib/gcc/config/rs6000/t-ppcgas b/contrib/gcc/config/rs6000/t-ppcgas
index 9b82b9f..120aef4 100644
--- a/contrib/gcc/config/rs6000/t-ppcgas
+++ b/contrib/gcc/config/rs6000/t-ppcgas
@@ -2,18 +2,13 @@
MULTILIB_OPTIONS = msoft-float \
mlittle/mbig \
- mcall-sysv/mcall-aix \
fleading-underscore
MULTILIB_DIRNAMES = nof \
le be \
- cs ca \
und
MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align
-MULTILIB_EXCEPTIONS = *mcall-aix/*fleading-underscore* \
- *mlittle/*mcall-aix*
MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \
- ${MULTILIB_MATCHES_ENDIAN} \
- ${MULTILIB_MATCHES_SYSV}
+ ${MULTILIB_MATCHES_ENDIAN}
diff --git a/contrib/gcc/config/rs6000/t-rs6000 b/contrib/gcc/config/rs6000/t-rs6000
index f50ef17..caa0715 100644
--- a/contrib/gcc/config/rs6000/t-rs6000
+++ b/contrib/gcc/config/rs6000/t-rs6000
@@ -1,19 +1,20 @@
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
+# General rules that all rs6000/ targets must have.
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
+gt-rs6000.h: s-gtype ; @true
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+rs6000.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(REGS_H) hard-reg-set.h \
+ real.h insn-config.h conditions.h insn-attr.h flags.h $(RECOG_H) \
+ $(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \
+ output.h $(BASIC_BLOCK_H) $(INTEGRATE_H) toplev.h $(GGC_H) $(HASHTAB_H) \
+ $(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h gt-rs6000.h \
+ cfglayout.h
-# Build the libraries for both hard and soft floating point
+rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
+ $(srcdir)/config/rs6000/rs6000-protos.h \
+ $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPPLIB_H) \
+ $(TM_P_H) c-pragma.h errors.h coretypes.h $(TM_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/rs6000/rs6000-c.c
-MULTILIB_OPTIONS = msoft-float
-MULTILIB_DIRNAMES = soft-float
-
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
+# The rs6000 backend doesn't cause warnings in these files.
+insn-conditions.o-warn =
diff --git a/contrib/gcc/config/rs6000/t-spe b/contrib/gcc/config/rs6000/t-spe
new file mode 100644
index 0000000..bd0b795
--- /dev/null
+++ b/contrib/gcc/config/rs6000/t-spe
@@ -0,0 +1,68 @@
+# Multilibs for e500
+
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+# What we really want are these variants:
+# -mcpu=7400
+# -mcpu=7400 -maltivec -mabi=altivec
+# -mcpu=7400 -msoft-float
+# -msoft-float
+# -mspe=no -mabi=no-spe -misel=no
+# so we'll need to create exceptions later below.
+
+MULTILIB_OPTIONS = mcpu=7400 \
+ maltivec \
+ mabi=altivec \
+ msoft-float \
+ mspe=no \
+ mabi=no-spe \
+ misel=no \
+ mlittle
+
+MULTILIB_DIRNAMES = mpc7400 altivec abi-altivec \
+ nof no-spe no-abi-spe no-isel le
+
+MULTILIB_EXCEPTIONS = maltivec mabi=altivec mspe=no mabi=no-spe misel=no \
+ maltivec/mabi=altivec \
+ mcpu=7400/maltivec \
+ mcpu=7400/mabi=altivec \
+ *mcpu=7400/*mspe=no* \
+ *mcpu=7400/*mabi=no-spe* \
+ *mcpu=7400/*misel=no* \
+ *maltivec/*msoft-float* \
+ *maltivec/*mspe=no* \
+ *maltivec/*mabi=no-spe* \
+ *maltivec/*misel=no* \
+ *mabi=altivec/*msoft-float* \
+ *mabi=altivec/*mspe=no* \
+ *mabi=altivec/*mabi=no-spe* \
+ *mabi=altivec/*misel=no* \
+ *msoft-float/*mspe=no* \
+ *msoft-float/*mabi=no-spe* \
+ *msoft-float/*misel=no* \
+ mspe=no/mabi=no-spe \
+ mspe=no/misel=no \
+ mabi=no-spe/misel=no \
+ misel=no/mlittle \
+ mabi=no-spe/misel=no/mlittle \
+ mspe=no/mlittle \
+ mabi=spe/mlittle \
+ mcpu=7400/mabi=altivec/mlittle \
+ mcpu=7400/maltivec/mlittle \
+ mabi=no-spe/mlittle \
+ mspe=no/misel=no/mlittle \
+ mspe=no/mabi=no-spe/mlittle \
+ mabi=altivec/mlittle \
+ maltivec/mlittle \
+ maltivec/mabi=altivec/mlittle
diff --git a/contrib/gcc/config/rs6000/t-vxworks b/contrib/gcc/config/rs6000/t-vxworks
new file mode 100644
index 0000000..e89e47b
--- /dev/null
+++ b/contrib/gcc/config/rs6000/t-vxworks
@@ -0,0 +1,10 @@
+# Multilibs for VxWorks.
+
+MULTILIB_OPTIONS = t403/t405/t440/t603/t604/t860
+MULTILIB_DIRNAMES = PPC403gnu PPC405gnu PPC440gnu \
+ PPC603gnu PPC604gnu PPC860gnu
+
+MULTILIB_MATCHES = t604=
+
+# Put vxlib.c back in LIB2FUNCS_EXTRA (t-ppccomm clobbers it).
+LIB2FUNCS_EXTRA += $(srcdir)/config/vxlib.c
diff --git a/contrib/gcc/config/rs6000/tramp.asm b/contrib/gcc/config/rs6000/tramp.asm
index c2a38d1..284f938 100644
--- a/contrib/gcc/config/rs6000/tramp.asm
+++ b/contrib/gcc/config/rs6000/tramp.asm
@@ -39,6 +39,7 @@
.section ".text"
#include "ppc-asm.h"
+#ifndef __powerpc64__
.type trampoline_initial,@object
.align 2
trampoline_initial:
@@ -107,3 +108,4 @@ FUNC_START(__trampoline_setup)
bl JUMP_TARGET(abort)
FUNC_END(__trampoline_setup)
+#endif
diff --git a/contrib/gcc/config/rs6000/vxworks.h b/contrib/gcc/config/rs6000/vxworks.h
new file mode 100644
index 0000000..e7a7092
--- /dev/null
+++ b/contrib/gcc/config/rs6000/vxworks.h
@@ -0,0 +1,82 @@
+/* Definitions of target machine for GNU compiler. Vxworks PowerPC version.
+ Copyright (C) 1996, 2000, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__vxworks"); \
+ builtin_define ("__vxworks__"); \
+ } \
+ while (0)
+
+/* We have to kill off the entire specs set created by rs6000/sysv4.h
+ and substitute our own set. The top level vxworks.h has done some
+ of this for us. */
+
+#undef SUBTARGET_EXTRA_SPECS
+#undef CPP_SPEC
+#undef CC1_SPEC
+#undef ASM_SPEC
+
+#define SUBTARGET_EXTRA_SPECS /* none needed */
+
+#define CPP_SPEC \
+"-DCPU_FAMILY=PPC -D__ppc -D__EABI__ \
+ %{t403: -DCPU=PPC403 -D_SOFT_FLOAT ; \
+ t405: -DCPU=PPC405 -D_SOFT_FLOAT ; \
+ t440: -DCPU=PPC440 -D_SOFT_FLOAT ; \
+ t603: -DCPU=PPC603 ; \
+ t604: -DCPU=PPC604 ; \
+ t860: -DCPU=PPC860 -D_SOFT_FLOAT ; \
+ : -DCPU=PPC604} \
+ %{!msoft-float:-D__hardfp} \
+ %{fpic|fpie: -D__PIC__=1 -D__pic__=1 ; \
+ fPIC|fPIE: -D__PIC__=2 -D__pic__=2 } \
+ %(cpp_cpu)"
+
+#define CC1_SPEC \
+"%{t403: -mcpu=403 -mstrict-align ; \
+ t405: -mcpu=405 -mstrict-align ; \
+ t440: -mcpu=440 -mstrict-align ; \
+ t603: -mcpu=603 -mstrict-align ; \
+ t604: -mcpu=604 -mstrict-align ; \
+ t860: -mcpu=860 ; \
+ : -mcpu=604 -mstrict-align } \
+ %{G*} %{mno-sdata:-msdata=none} %{msdata:-msdata=default} \
+ %{mlittle|mlittle-endian:-mstrict-align} \
+ %{profile: -p} \
+ %{fvec:-maltivec} %{fvec-eabi:-maltivec -mabi=altivec}"
+
+#define ASM_SPEC "%(asm_cpu) \
+%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
+%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
+%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} -mbig"
+
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS { "t604" }
+
+/* We can't use .ctors/.dtors sections. */
+#undef TARGET_ASM_OUTPUT_CONSTRUCTOR
+#undef TARGET_ASM_OUTPUT_DESTRUCTOR
+
+/* Nor sdata. */
+#undef SDATA_DEFAULT_SIZE
+#define SDATA_DEFAULT_SIZE 0
diff --git a/contrib/gcc/config/rs6000/windiss.h b/contrib/gcc/config/rs6000/windiss.h
index 7aacb23..e66d128 100644
--- a/contrib/gcc/config/rs6000/windiss.h
+++ b/contrib/gcc/config/rs6000/windiss.h
@@ -1,34 +1,34 @@
/* Support for GCC on PowerPC using WindISS simulator.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by CodeSourcery, LLC.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC WindISS)");
-#undef LIB_DEFAULT_SPEC
+#undef LIB_DEFAULT_SPEC
#define LIB_DEFAULT_SPEC "%(lib_windiss)"
-#undef STARTFILE_DEFAULT_SPEC
+#undef STARTFILE_DEFAULT_SPEC
#define STARTFILE_DEFAULT_SPEC "%(startfile_windiss)"
-#undef ENDFILE_DEFAULT_SPEC
+#undef ENDFILE_DEFAULT_SPEC
#define ENDFILE_DEFAULT_SPEC "%(endfile_windiss)"
#undef LINK_START_DEFAULT_SPEC
@@ -37,11 +37,11 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_windiss)"
-#undef CRTSAVRES_DEFAULT_SPEC
+#undef CRTSAVRES_DEFAULT_SPEC
#define CRTSAVRES_DEFAULT_SPEC ""
-#undef WCHAR_TYPE
+#undef WCHAR_TYPE
#define WCHAR_TYPE "short unsigned int"
-#undef WCHAR_TYPE_SIZE
+#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 16
diff --git a/contrib/gcc/config/rs6000/x-darwin b/contrib/gcc/config/rs6000/x-darwin
new file mode 100644
index 0000000..f7242a7
--- /dev/null
+++ b/contrib/gcc/config/rs6000/x-darwin
@@ -0,0 +1,4 @@
+host-darwin.o : $(srcdir)/config/rs6000/host-darwin.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/rs6000/host-darwin.c
diff --git a/contrib/gcc/config/rs6000/x-linux64 b/contrib/gcc/config/rs6000/x-linux64
new file mode 100644
index 0000000..4371ca3
--- /dev/null
+++ b/contrib/gcc/config/rs6000/x-linux64
@@ -0,0 +1,2 @@
+# parts of gcc need more than a 64k TOC.
+X_CFLAGS = -mminimal-toc
diff --git a/contrib/gcc/config/rs6000/xcoff.h b/contrib/gcc/config/rs6000/xcoff.h
index 21d74a9..d4e056b 100644
--- a/contrib/gcc/config/rs6000/xcoff.h
+++ b/contrib/gcc/config/rs6000/xcoff.h
@@ -1,24 +1,23 @@
/* Definitions of target machine for GNU compiler,
for some generic XCOFF file format
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#define TARGET_OBJECT_FORMAT OBJECT_XCOFF
@@ -70,9 +69,14 @@ Boston, MA 02111-1307, USA. */
BIGGEST_ALIGNMENT is 64, so align the sections that much. */
#define EXTRA_SECTION_FUNCTIONS \
- \
+ READ_ONLY_DATA_SECTION_FUNCTION \
+ PRIVATE_DATA_SECTION_FUNCTION \
+ READ_ONLY_PRIVATE_DATA_SECTION_FUNCTION \
+ TOC_SECTION_FUNCTION
+
+#define READ_ONLY_DATA_SECTION_FUNCTION \
void \
-read_only_data_section () \
+read_only_data_section (void) \
{ \
if (in_section != read_only_data) \
{ \
@@ -80,10 +84,11 @@ read_only_data_section () \
xcoff_read_only_section_name); \
in_section = read_only_data; \
} \
-} \
- \
+}
+
+#define PRIVATE_DATA_SECTION_FUNCTION \
void \
-private_data_section () \
+private_data_section (void) \
{ \
if (in_section != private_data) \
{ \
@@ -91,10 +96,11 @@ private_data_section () \
xcoff_private_data_section_name); \
in_section = private_data; \
} \
-} \
- \
+}
+
+#define READ_ONLY_PRIVATE_DATA_SECTION_FUNCTION \
void \
-read_only_private_data_section () \
+read_only_private_data_section (void) \
{ \
if (in_section != read_only_private_data) \
{ \
@@ -102,16 +108,18 @@ read_only_private_data_section () \
xcoff_private_data_section_name); \
in_section = read_only_private_data; \
} \
-} \
- \
+}
+
+#define TOC_SECTION_FUNCTION \
void \
-toc_section () \
+toc_section (void) \
{ \
if (TARGET_MINIMAL_TOC) \
{ \
- /* toc_section is always called at least once from ASM_FILE_START, \
- so this is guaranteed to always be defined once and only once \
- in each file. */ \
+ /* toc_section is always called at least once \
+ from rs6000_xcoff_file_start, so this is \
+ guaranteed to always be defined once and \
+ only once in each file. */ \
if (! toc_initialized) \
{ \
fputs ("\t.toc\nLCTOC..1:\n", asm_out_file); \
@@ -164,7 +172,6 @@ toc_section () \
#define TARGET_ASM_SELECT_SECTION rs6000_xcoff_select_section
#define TARGET_ASM_SELECT_RTX_SECTION rs6000_xcoff_select_rtx_section
#define TARGET_ASM_UNIQUE_SECTION rs6000_xcoff_unique_section
-#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info
#define TARGET_STRIP_NAME_ENCODING rs6000_xcoff_strip_name_encoding
#define TARGET_SECTION_TYPE_FLAGS rs6000_xcoff_section_type_flags
@@ -175,16 +182,9 @@ toc_section () \
#define RESTORE_FP_SUFFIX ""
/* Function name to call to do profiling. */
-#undef RS6000_MCOUNT
+#undef RS6000_MCOUNT
#define RS6000_MCOUNT ".__mcount"
-/* Function names to call to do floating point truncation. */
-
-#undef RS6000_ITRUNC
-#define RS6000_ITRUNC "__itrunc"
-#undef RS6000_UITRUNC
-#define RS6000_UITRUNC "__uitrunc"
-
/* This outputs NAME to FILE up to the first null or '['. */
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
@@ -202,53 +202,11 @@ toc_section () \
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP "\t.globl "
-/* Output at beginning of assembler file.
-
- Initialize the section names for the RS/6000 at this point.
-
- Specify filename, including full path, to assembler.
-
- We want to go into the TOC section so at least one .toc will be emitted.
- Also, in order to output proper .bs/.es pairs, we need at least one static
- [RW] section emitted.
-
- Finally, declare mcount when profiling to make the assembler happy. */
-
-#define ASM_FILE_START(FILE) \
-{ \
- rs6000_gen_section_name (&xcoff_bss_section_name, \
- main_input_filename, ".bss_"); \
- rs6000_gen_section_name (&xcoff_private_data_section_name, \
- main_input_filename, ".rw_"); \
- rs6000_gen_section_name (&xcoff_read_only_section_name, \
- main_input_filename, ".ro_"); \
- \
- fputs ("\t.file\t", FILE); \
- output_quoted_string (FILE, main_input_filename); \
- fputc ('\n', FILE); \
- if (TARGET_64BIT) \
- fputs ("\t.machine\t\"ppc64\"\n", FILE); \
- toc_section (); \
- if (write_symbols != NO_DEBUG) \
- private_data_section (); \
- text_section (); \
- if (profile_flag) \
- fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT); \
- rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \
-}
-
-/* Output at end of assembler file.
-
- On the RS/6000, referencing data should automatically pull in text. */
-
-#define ASM_FILE_END(FILE) \
-{ \
- text_section (); \
- fputs ("_section_.text:\n", FILE); \
- data_section (); \
- fputs (TARGET_32BIT \
- ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", FILE); \
-}
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START rs6000_xcoff_file_start
+#define TARGET_ASM_FILE_END rs6000_xcoff_file_end
+#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE false
/* This macro produces the initial definition of a function name.
On the RS/6000, we need to place an extra '.' in the function name and
@@ -258,17 +216,11 @@ toc_section () \
`text_section' call previously done. We do have to go back to that
csect, however.
- We also record that the function exists in the current compilation
- unit, reachable by short branch, by setting SYMBOL_REF_FLAG.
-
The third and fourth parameters to the .function pseudo-op (16 and 044)
are placeholders which no longer have any use. */
#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
-{ rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \
- if ((*targetm.binds_local_p) (DECL)) \
- SYMBOL_REF_FLAG (sym_ref) = 1; \
- if (TREE_PUBLIC (DECL)) \
+{ if (TREE_PUBLIC (DECL)) \
{ \
if (!RS6000_WEAK || !DECL_WEAK (decl)) \
{ \
@@ -296,11 +248,7 @@ toc_section () \
putc ('.', FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \
fputs (":\n", FILE); \
- if (write_symbols == XCOFF_DEBUG \
- /* When called before targetm.asm_out.output_mi_thunk, \
- we won't be emitting the rest of the debug info that \
- goes along with this, leading to assembler errors. */ \
- && !(current_function_is_thunk && !no_new_pseudos)) \
+ if (write_symbols != NO_DEBUG) \
xcoffout_declare_function (FILE, DECL, NAME); \
}
@@ -311,7 +259,7 @@ toc_section () \
/* This says how to output an external. */
-#undef ASM_OUTPUT_EXTERNAL
+#undef ASM_OUTPUT_EXTERNAL
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \
if ((TREE_CODE (DECL) == VAR_DECL \
@@ -325,12 +273,6 @@ toc_section () \
} \
}
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s..%u:\n", (PREFIX), (unsigned) (NUM))
-
/* This is how to output an internal label prefix. rs6000.c uses this
when generating traceback tables. */
@@ -338,11 +280,11 @@ toc_section () \
fprintf (FILE, "%s..", PREFIX)
/* This is how to output a label for a jump table. Arguments are the same as
- for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+ for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
-{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+{ ASM_OUTPUT_ALIGN (FILE, 2); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
@@ -362,7 +304,7 @@ toc_section () \
#define SKIP_ASM_OP "\t.space "
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "%s%u\n", SKIP_ASM_OP, (SIZE))
+ fprintf (FILE, "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n", SKIP_ASM_OP, (SIZE))
/* This says how to output an assembler line
to define a global common symbol. */
@@ -373,12 +315,12 @@ toc_section () \
do { fputs (COMMON_ASM_OP, (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
if ((ALIGN) > 32) \
- fprintf ((FILE), ",%u,%u\n", (SIZE), \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \
exact_log2 ((ALIGN) / BITS_PER_UNIT)); \
else if ((SIZE) > 4) \
- fprintf ((FILE), ",%u,3\n", (SIZE)); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",3\n", (SIZE)); \
else \
- fprintf ((FILE), ",%u\n", (SIZE)); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \
} while (0)
/* This says how to output an assembler line
@@ -392,7 +334,8 @@ toc_section () \
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%s\n", (TARGET_32BIT ? (SIZE) : (ROUNDED)), \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s\n", \
+ (TARGET_32BIT ? (SIZE) : (ROUNDED)), \
xcoff_bss_section_name); \
} while (0)
diff --git a/contrib/gcc/config/rtems.h b/contrib/gcc/config/rtems.h
index a3f9ba3..8063643 100644
--- a/contrib/gcc/config/rtems.h
+++ b/contrib/gcc/config/rtems.h
@@ -1,20 +1,20 @@
/* Configuration common to all targets running RTEMS.
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -35,3 +35,17 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC ""
+
+/*
+ * Some targets do not set up LIB_SPECS, override it, here.
+ */
+#define STD_LIB_SPEC \
+ "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{!qrtems: " STD_LIB_SPEC "} " \
+"%{!nostdlib: %{qrtems: --start-group \
+ %{!qrtems_debug: -lrtemsbsp -lrtemscpu} \
+ %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
+ -lc -lgcc --end-group %{!qnolinkcmds: -T linkcmds%s}}}"
+
diff --git a/contrib/gcc/config/s390/2064.md b/contrib/gcc/config/s390/2064.md
new file mode 100644
index 0000000..143cd1b
--- /dev/null
+++ b/contrib/gcc/config/s390/2064.md
@@ -0,0 +1,131 @@
+;; Scheduling description for z900 (cpu 2064).
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
+;; Ulrich Weigand (uweigand@de.ibm.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 2, 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 COPYING. If not, write to the Free
+;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;
+;; References:
+;; The microarchitecture of the IBM eServer z900 processor.
+;; E.M. Schwarz et al.
+;; IBM Journal of Research and Development Vol. 46 No 4/5, 2002.
+;;
+;; z900 (cpu 2064) pipeline
+;;
+;; dec
+;; --> | <---
+;; LA bypass | agen |
+;; | | |
+;; --- c1 | Load bypass
+;; | |
+;; c2----
+;; |
+;; e1
+;; |
+;; wr
+
+(define_automaton "z_ipu")
+(define_cpu_unit "z_e1" "z_ipu")
+(define_cpu_unit "z_wr" "z_ipu")
+
+
+(define_insn_reservation "z_la" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "la"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_larl" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "larl"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_load" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "load"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_store" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "store"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_call" 5
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "jsr"))
+ "z_e1*5,z_wr")
+
+(define_insn_reservation "z_o2" 2
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "o2"))
+ "z_e1*2,z_wr")
+
+(define_insn_reservation "z_o3" 3
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "o3"))
+ "z_e1*3,z_wr")
+
+;
+; Insn still not mentioned are check for
+; the usage of the agen unit
+;
+
+(define_insn_reservation "z_int" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "atype" "reg"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_agen" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "atype" "agen"))
+ "z_e1,z_wr")
+
+
+;;
+;; s390_agen_dep_p returns 1, if a register is set in the
+;; first insn and used in the dependent insn to form a address.
+;;
+
+;;
+;; If an instruction uses a register to address memory, it needs
+;; to be set 5 cycles in advance.
+;;
+
+(define_bypass 5 "z_int,z_agen"
+ "z_agen,z_la,z_call,z_load,z_store" "s390_agen_dep_p")
+
+;;
+;; A load type instruction uses a bypass to feed the result back
+;; to the address generation pipeline stage.
+;;
+
+(define_bypass 3 "z_load"
+ "z_agen,z_la,z_call,z_load,z_store" "s390_agen_dep_p")
+
+;;
+;; A load address type instruction uses a bypass to feed the
+;; result back to the address generation pipeline stage.
+;;
+
+(define_bypass 2 "z_larl,z_la"
+ "z_agen,z_la,z_call,z_load,z_store" "s390_agen_dep_p")
+
+
+
+
+
diff --git a/contrib/gcc/config/s390/2084.md b/contrib/gcc/config/s390/2084.md
new file mode 100644
index 0000000..a74ffbf
--- /dev/null
+++ b/contrib/gcc/config/s390/2084.md
@@ -0,0 +1,262 @@
+;; Scheduling description for z990 (cpu 2084).
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
+;; Ulrich Weigand (uweigand@de.ibm.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 2, 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 COPYING. If not, write to the Free
+;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+(define_automaton "x_ipu")
+
+(define_cpu_unit "x_e1_r,x_e1_s,x_e1_t" "x_ipu")
+(define_cpu_unit "x_wr_r,x_wr_s,x_wr_t,x_wr_fp" "x_ipu")
+(define_cpu_unit "x_s1,x_s2,x_s3,x_s4" "x_ipu")
+(define_cpu_unit "x_t1,x_t2,x_t3,x_t4" "x_ipu")
+(define_cpu_unit "x_f1,x_f2,x_f3,x_f4,x_f5,x_f6" "x_ipu")
+(define_cpu_unit "x_store_tok" "x_ipu")
+(define_cpu_unit "x_ms,x_mt" "x_ipu")
+
+(define_reservation "x-e1-st" "(x_e1_s | x_e1_t)")
+
+(define_reservation "x-e1-np" "(x_e1_r + x_e1_s + x_e1_t)")
+
+(absence_set "x_e1_r" "x_e1_s,x_e1_t")
+(absence_set "x_e1_s" "x_e1_t")
+
+;; Try to avoid int <-> fp transitions.
+
+(define_reservation "x-x" "x_s1|x_t1,x_s2|x_t2,x_s3|x_t3,x_s4|x_t4")
+(define_reservation "x-f" "x_f1,x_f2,x_f3,x_f4,x_f5,x_f6")
+(define_reservation "x-wr-st" "((x_wr_s | x_wr_t),x-x)")
+(define_reservation "x-wr-np" "((x_wr_r + x_wr_s + x_wr_t),x-x)")
+(define_reservation "x-wr-fp" "x_wr_fp,x-f")
+(define_reservation "x-mem" "x_ms|x_mt")
+
+(absence_set "x_wr_fp"
+ "x_s1,x_s2,x_s3,x_s4,x_t1,x_t2,x_t3,x_t4,x_wr_s,x_wr_t")
+
+(absence_set "x_e1_r,x_wr_r,x_wr_s,x_wr_t"
+ "x_f1,x_f2,x_f3,x_f4,x_f5,x_f6,x_wr_fp")
+
+;; Don't have any load type insn in same group as store
+
+(absence_set "x_ms,x_mt" "x_store_tok")
+
+
+;;
+;; Simple insns
+;;
+
+(define_insn_reservation "x_lr" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "lr"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_la" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "la"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_larl" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "larl"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_load" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "load"))
+ "x-e1-st+x-mem,x-wr-st")
+
+(define_insn_reservation "x_store" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "store"))
+ "x-e1-st+x_store_tok,x-wr-st")
+
+(define_insn_reservation "x_branch" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "branch"))
+ "x_e1_r,x_wr_r")
+
+(define_insn_reservation "x_call" 5
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "jsr"))
+ "x-e1-np*5,x-wr-np")
+
+;;
+;; Multicycle insns
+;;
+
+(define_insn_reservation "x_ss" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "op_type" "SS"))
+ "x-e1-np,x-wr-np")
+
+(define_insn_reservation "x_stm" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "stm"))
+ "(x-e1-np+x_store_tok)*10,x-wr-np")
+
+(define_insn_reservation "x_lm" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "lm"))
+ "x-e1-np*10,x-wr-np")
+
+(define_insn_reservation "x_nn" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "op_type" "NN"))
+ "x-e1-np,x-wr-np")
+
+(define_insn_reservation "x_o2" 2
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "o2"))
+ "x-e1-np*2,x-wr-np")
+
+(define_insn_reservation "x_o3" 3
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "o3"))
+ "x-e1-np*3,x-wr-np")
+
+;;
+;; Floating point insns
+;;
+
+(define_insn_reservation "x_fsimpd" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fsimpd,fmuld"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fsimps" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fsimps,fmuls"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fdivd" 36
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fdivd"))
+ "x_e1_t*30,x-wr-fp")
+
+(define_insn_reservation "x_fdivs" 36
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fdivs"))
+ "x_e1_t*30,x-wr-fp")
+
+(define_insn_reservation "x_floadd" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "floadd"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_floads" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "floads"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fstored" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fstored"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fstores" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fstores"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_ftoi" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "ftoi"))
+ "x_e1_t*3,x-wr-fp")
+
+(define_insn_reservation "x_itof" 7
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "itof"))
+ "x_e1_t*3,x-wr-fp")
+
+(define_bypass 1 "x_fsimpd" "x_fstored")
+
+(define_bypass 1 "x_fsimps" "x_fstores")
+
+(define_bypass 1 "x_floadd" "x_fsimpd,x_fstored,x_floadd")
+
+(define_bypass 1 "x_floads" "x_fsimps,x_fstores,x_floads")
+
+;;
+;; Insns still not mentioned are checked for
+;; the usage of the agen unit
+;;
+
+(define_insn_reservation "x_int" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "atype" "reg"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_agen" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "atype" "agen"))
+ "x-e1-st+x-mem,x-wr-st")
+
+;;
+;; s390_agen_dep_p returns 1, if a register is set in the
+;; first insn and used in the dependent insn to form a address.
+;;
+
+;;
+;; If an instruction uses a register to address memory, it needs
+;; to be set 5 cycles in advance.
+;;
+
+(define_bypass 5 "x_int,x_agen,x_lr"
+ "x_agen,x_la,x_call,x_load,x_store,x_ss,x_stm,x_lm"
+ "s390_agen_dep_p")
+
+(define_bypass 9 "x_int,x_agen,x_lr"
+ "x_floadd, x_floads, x_fstored, x_fstores,\
+ x_fsimpd, x_fsimps, x_fdivd, x_fdivs"
+ "s390_agen_dep_p")
+;;
+;; A load type instruction uses a bypass to feed the result back
+;; to the address generation pipeline stage.
+;;
+
+(define_bypass 4 "x_load"
+ "x_agen,x_la,x_call,x_load,x_store,x_ss,x_stm,x_lm"
+ "s390_agen_dep_p")
+
+(define_bypass 5 "x_load"
+ "x_floadd, x_floads, x_fstored, x_fstores,\
+ x_fsimpd, x_fsimps, x_fdivd, x_fdivs"
+ "s390_agen_dep_p")
+
+;;
+;; A load address type instruction uses a bypass to feed the
+;; result back to the address generation pipeline stage.
+;;
+
+(define_bypass 3 "x_larl,x_la"
+ "x_agen,x_la,x_call,x_load,x_store,x_ss,x_stm,x_lm"
+ "s390_agen_dep_p")
+
+(define_bypass 5 "x_larl, x_la"
+ "x_floadd, x_floads, x_fstored, x_fstores,\
+ x_fsimpd, x_fsimps, x_fdivd, x_fdivs"
+ "s390_agen_dep_p")
+
+;;
+;; Operand forwarding
+;;
+
+(define_bypass 0 "x_lr,x_la,x_load" "x_int,x_lr")
+
+
diff --git a/contrib/gcc/config/s390/fixdfdi.h b/contrib/gcc/config/s390/fixdfdi.h
index 1f82a9c..a5b9212 100644
--- a/contrib/gcc/config/s390/fixdfdi.h
+++ b/contrib/gcc/config/s390/fixdfdi.h
@@ -3,22 +3,22 @@
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifdef L_fixunsdfdi
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
diff --git a/contrib/gcc/config/s390/linux.h b/contrib/gcc/config/s390/linux.h
index cbb7710..9a6db9d 100644
--- a/contrib/gcc/config/s390/linux.h
+++ b/contrib/gcc/config/s390/linux.h
@@ -3,22 +3,22 @@
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifndef _LINUX_H
#define _LINUX_H
@@ -53,12 +53,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_assert ("system=linux"); \
- builtin_assert ("system=unix"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__gnu_linux__"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
@@ -70,13 +65,8 @@ Boston, MA 02111-1307, USA. */
/* Target specific assembler settings. */
-#ifdef DEFAULT_TARGET_64BIT
-#undef ASM_SPEC
-#define ASM_SPEC "%{m31:-m31 -Aesa}"
-#else
#undef ASM_SPEC
-#define ASM_SPEC "%{m64:-m64 -Aesame}"
-#endif
+#define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*}"
/* Target specific linker settings. */
@@ -87,41 +77,20 @@ Boston, MA 02111-1307, USA. */
#define MULTILIB_DEFAULTS { "m31" }
#endif
-#define LINK_ARCH31_SPEC \
- "-m elf_s390 \
- %{shared:-shared} \
- %{!shared: \
- %{static:-static} \
- %{!static: \
- %{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
-
-#define LINK_ARCH64_SPEC \
- "-m elf64_s390 \
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "%{m31:-m elf_s390}%{m64:-m elf64_s390} \
%{shared:-shared} \
%{!shared: \
%{static:-static} \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/ld64.so.1}}}"
-
-#ifdef DEFAULT_TARGET_64BIT
-#undef LINK_SPEC
-#define LINK_SPEC "%{m31:%(link_arch31)} %{!m31:%(link_arch64)}"
-#else
-#undef LINK_SPEC
-#define LINK_SPEC "%{m64:%(link_arch64)} %{!m64:%(link_arch31)}"
-#endif
-
-
-/* This macro defines names of additional specifications to put in the specs
- that can be used in various specifications like CC1_SPEC. Its definition
- is an initializer with a subgrouping for each command option. */
+ %{!dynamic-linker: \
+ %{m31:-dynamic-linker /lib/ld.so.1} \
+ %{m64:-dynamic-linker /lib/ld64.so.1}}}}"
-#define EXTRA_SPECS \
- { "link_arch31", LINK_ARCH31_SPEC }, \
- { "link_arch64", LINK_ARCH64_SPEC }, \
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
diff --git a/contrib/gcc/config/s390/s390-modes.def b/contrib/gcc/config/s390/s390-modes.def
index 9f9d526..0875955 100644
--- a/contrib/gcc/config/s390/s390-modes.def
+++ b/contrib/gcc/config/s390/s390-modes.def
@@ -1,38 +1,42 @@
/* Definitions of target machine for GNU compiler, for IBM S/390
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
-GNU CC 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 2, or (at your option)
-any later version.
+This file is part of GCC.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is 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 2, 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */
+INT_MODE (OI, 32);
/* Add any extra modes needed to represent the condition code. */
-CC (CCZ)
-CC (CCA)
-CC (CCAP)
-CC (CCAN)
-CC (CCL)
-CC (CCL1)
-CC (CCL2)
-CC (CCU)
-CC (CCUR)
-CC (CCS)
-CC (CCSR)
-CC (CCT)
-CC (CCT1)
-CC (CCT2)
-CC (CCT3)
+CC_MODE (CCZ);
+CC_MODE (CCA);
+CC_MODE (CCAP);
+CC_MODE (CCAN);
+CC_MODE (CCL);
+CC_MODE (CCL1);
+CC_MODE (CCL2);
+CC_MODE (CCU);
+CC_MODE (CCUR);
+CC_MODE (CCS);
+CC_MODE (CCSR);
+CC_MODE (CCT);
+CC_MODE (CCT1);
+CC_MODE (CCT2);
+CC_MODE (CCT3);
diff --git a/contrib/gcc/config/s390/s390-protos.h b/contrib/gcc/config/s390/s390-protos.h
index 1f8b144..90815a8 100644
--- a/contrib/gcc/config/s390/s390-protos.h
+++ b/contrib/gcc/config/s390/s390-protos.h
@@ -1,96 +1,105 @@
/* Definitions of target machine for GNU compiler, for IBM S/390.
- Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
/* Declare functions in s390.c. */
-extern void optimization_options PARAMS ((int, int));
-extern void override_options PARAMS ((void));
-extern int s390_arg_frame_offset PARAMS ((void));
-extern void s390_emit_prologue PARAMS ((void));
-extern void s390_emit_epilogue PARAMS ((void));
-extern void s390_function_profiler PARAMS ((FILE *, int));
+extern void optimization_options (int, int);
+extern void override_options (void);
+extern HOST_WIDE_INT s390_arg_frame_offset (void);
+extern void s390_load_got (int);
+extern void s390_emit_prologue (void);
+extern void s390_emit_epilogue (void);
+extern void s390_function_profiler (FILE *, int);
#ifdef RTX_CODE
-extern int s390_address_cost PARAMS ((rtx));
-extern int q_constraint PARAMS ((rtx));
-extern int const0_operand PARAMS ((rtx, enum machine_mode));
-extern int consttable_operand PARAMS ((rtx, enum machine_mode));
-extern int larl_operand PARAMS ((rtx, enum machine_mode));
-extern int s_operand PARAMS ((rtx, enum machine_mode));
-extern int s_imm_operand PARAMS ((rtx, enum machine_mode));
-extern int bras_sym_operand PARAMS ((rtx, enum machine_mode));
-extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int s390_single_hi PARAMS ((rtx, enum machine_mode, int));
-extern int s390_extract_hi PARAMS ((rtx, enum machine_mode, int));
-extern int s390_single_qi PARAMS ((rtx, enum machine_mode, int));
-extern int s390_extract_qi PARAMS ((rtx, enum machine_mode, int));
-extern bool s390_split_ok_p PARAMS ((rtx, rtx, enum machine_mode, int));
-extern int tls_symbolic_operand PARAMS ((rtx));
+extern int s390_extra_constraint_str (rtx, int, const char *);
+extern int s390_const_ok_for_constraint_p (HOST_WIDE_INT, int, const char *);
+extern int const0_operand (rtx, enum machine_mode);
+extern int consttable_operand (rtx, enum machine_mode);
+extern int larl_operand (rtx, enum machine_mode);
+extern int s_operand (rtx, enum machine_mode);
+extern int s_imm_operand (rtx, enum machine_mode);
+extern int shift_count_operand (rtx, enum machine_mode);
+extern int bras_sym_operand (rtx, enum machine_mode);
+extern int load_multiple_operation (rtx, enum machine_mode);
+extern int store_multiple_operation (rtx, enum machine_mode);
+extern int s390_single_part (rtx, enum machine_mode, enum machine_mode, int);
+extern unsigned HOST_WIDE_INT s390_extract_part (rtx, enum machine_mode, int);
+extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int);
+extern int tls_symbolic_operand (rtx);
-extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode));
-extern enum machine_mode s390_tm_ccmode PARAMS ((rtx, rtx, int));
-extern enum machine_mode s390_select_ccmode PARAMS ((enum rtx_code, rtx, rtx));
-extern int symbolic_reference_mentioned_p PARAMS ((rtx));
-extern int tls_symbolic_reference_mentioned_p PARAMS ((rtx));
-extern rtx s390_tls_get_offset PARAMS ((void));
-extern int legitimate_la_operand_p PARAMS ((rtx));
-extern int preferred_la_operand_p PARAMS ((rtx));
-extern int legitimate_pic_operand_p PARAMS ((rtx));
-extern int legitimate_constant_p PARAMS ((rtx));
-extern int legitimate_reload_constant_p PARAMS ((rtx));
-extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
-extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
-extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-extern enum reg_class s390_preferred_reload_class PARAMS ((rtx, enum reg_class));
-extern enum reg_class s390_secondary_input_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx));
-extern enum reg_class s390_secondary_output_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx));
-extern int s390_plus_operand PARAMS ((rtx, enum machine_mode));
-extern void s390_expand_plus_operand PARAMS ((rtx, rtx, rtx));
-extern void emit_symbolic_move PARAMS ((rtx *));
-extern void s390_load_address PARAMS ((rtx, rtx));
-extern void s390_expand_movstr PARAMS ((rtx, rtx, rtx));
-extern void s390_expand_clrstr PARAMS ((rtx, rtx));
-extern void s390_expand_cmpstr PARAMS ((rtx, rtx, rtx, rtx));
-extern rtx s390_return_addr_rtx PARAMS ((int, rtx));
+extern int s390_match_ccmode (rtx, enum machine_mode);
+extern enum machine_mode s390_tm_ccmode (rtx, rtx, int);
+extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx);
+extern int s390_alc_comparison (rtx op, enum machine_mode mode);
+extern int s390_slb_comparison (rtx op, enum machine_mode mode);
+extern int symbolic_reference_mentioned_p (rtx);
+extern int tls_symbolic_reference_mentioned_p (rtx);
+extern rtx s390_tls_get_offset (void);
+extern int legitimate_la_operand_p (rtx);
+extern int preferred_la_operand_p (rtx);
+extern int legitimate_pic_operand_p (rtx);
+extern int legitimate_constant_p (rtx);
+extern int legitimate_reload_constant_p (rtx);
+extern int legitimate_address_p (enum machine_mode, rtx, int);
+extern rtx legitimize_pic_address (rtx, rtx);
+extern rtx legitimize_address (rtx, rtx, enum machine_mode);
+extern enum reg_class s390_preferred_reload_class (rtx, enum reg_class);
+extern enum reg_class s390_secondary_input_reload_class (enum reg_class,
+ enum machine_mode,
+ rtx);
+extern enum reg_class s390_secondary_output_reload_class (enum reg_class,
+ enum machine_mode,
+ rtx);
+extern int s390_plus_operand (rtx, enum machine_mode);
+extern void s390_expand_plus_operand (rtx, rtx, rtx);
+extern void emit_symbolic_move (rtx *);
+extern void s390_load_address (rtx, rtx);
+extern void s390_expand_movstr (rtx, rtx, rtx);
+extern void s390_expand_clrstr (rtx, rtx);
+extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
+extern rtx s390_return_addr_rtx (int, rtx);
+
+extern void s390_output_symbolic_const (FILE *, rtx);
+extern void print_operand_address (FILE *, rtx);
+extern void print_operand (FILE *, rtx, int);
+extern void s390_output_constant_pool (rtx, rtx);
+extern void s390_output_pool_entry (FILE *, rtx, enum machine_mode,
+ unsigned int);
+extern void s390_trampoline_template (FILE *);
+extern void s390_initialize_trampoline (rtx, rtx, rtx);
+extern rtx s390_gen_rtx_const_DI (int, int);
+extern void s390_output_dwarf_dtprel (FILE*, int, rtx);
+extern int s390_agen_dep_p (rtx, rtx);
-extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
-extern void print_operand_address PARAMS ((FILE *, rtx));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern void s390_output_constant_pool PARAMS ((rtx, rtx));
-extern void s390_trampoline_template PARAMS ((FILE *));
-extern void s390_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern rtx s390_gen_rtx_const_DI PARAMS ((int, int));
-extern rtx s390_simplify_dwarf_addr PARAMS ((rtx));
-extern void s390_machine_dependent_reorg PARAMS ((rtx));
#endif /* RTX_CODE */
#ifdef TREE_CODE
-extern int s390_function_arg_pass_by_reference PARAMS ((enum machine_mode, tree));
-extern void s390_function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
-extern tree s390_build_va_list PARAMS ((void));
+extern int s390_function_arg_pass_by_reference (enum machine_mode, tree);
+extern void s390_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
#ifdef RTX_CODE
-extern rtx s390_function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
-extern void s390_va_start PARAMS ((tree, rtx));
-extern rtx s390_va_arg PARAMS ((tree, tree));
+extern rtx s390_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
+extern rtx s390_function_value (tree, enum machine_mode);
+extern void s390_va_start (tree, rtx);
+extern rtx s390_va_arg (tree, tree);
#endif /* RTX_CODE */
#endif /* TREE_CODE */
-
diff --git a/contrib/gcc/config/s390/s390.c b/contrib/gcc/config/s390/s390.c
index d6fda65..ced0bf9 100644
--- a/contrib/gcc/config/s390/s390.c
+++ b/contrib/gcc/config/s390/s390.c
@@ -1,27 +1,30 @@
/* Subroutines used for code generation on IBM S/390 and zSeries
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
@@ -48,19 +51,34 @@ Boston, MA 02111-1307, USA. */
#include "langhooks.h"
#include "optabs.h"
-static bool s390_assemble_integer PARAMS ((rtx, unsigned int, int));
-static int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int s390_adjust_priority PARAMS ((rtx, int));
-static void s390_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static void s390_encode_section_info PARAMS ((tree, int));
-static const char *s390_strip_name_encoding PARAMS ((const char *));
-static bool s390_cannot_force_const_mem PARAMS ((rtx));
-static void s390_init_builtins PARAMS ((void));
-static rtx s390_expand_builtin PARAMS ((tree, rtx, rtx,
- enum machine_mode, int));
-static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
+/* Machine-specific symbol_ref flags. */
+#define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
+
+
+static bool s390_assemble_integer (rtx, unsigned int, int);
+static void s390_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static void s390_encode_section_info (tree, rtx, int);
+static bool s390_cannot_force_const_mem (rtx);
+static rtx s390_delegitimize_address (rtx);
+static bool s390_return_in_memory (tree, tree);
+static void s390_init_builtins (void);
+static rtx s390_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void s390_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+static enum attr_type s390_safe_attr_type (rtx);
+
+static int s390_adjust_cost (rtx, rtx, rtx, int);
+static int s390_adjust_priority (rtx, int);
+static int s390_issue_rate (void);
+static int s390_use_dfa_pipeline_interface (void);
+static int s390_first_cycle_multipass_dfa_lookahead (void);
+static int s390_sched_reorder2 (FILE *, int, rtx *, int *, int);
+static bool s390_rtx_costs (rtx, int, int, int *);
+static int s390_address_cost (rtx);
+static void s390_reorg (void);
+static bool s390_valid_pointer_mode (enum machine_mode);
+static tree s390_build_builtin_va_list (void);
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
@@ -78,16 +96,8 @@ static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION s390_select_rtx_section
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST s390_adjust_cost
-
-#undef TARGET_SCHED_ADJUST_PRIORITY
-#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
-
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING s390_strip_name_encoding
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
@@ -96,6 +106,12 @@ static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
+#undef TARGET_DELEGITIMIZE_ADDRESS
+#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
+
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
+
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS s390_init_builtins
#undef TARGET_EXPAND_BUILTIN
@@ -106,6 +122,33 @@ static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST s390_adjust_cost
+#undef TARGET_SCHED_ADJUST_PRIORITY
+#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE s390_issue_rate
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE s390_use_dfa_pipeline_interface
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
+#undef TARGET_SCHED_REORDER2
+#define TARGET_SCHED_REORDER2 s390_sched_reorder2
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS s390_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST s390_address_cost
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
+
+#undef TARGET_VALID_POINTER_MODE
+#define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
+
+#undef TARGET_BUILD_BUILTIN_VA_LIST
+#define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
+
struct gcc_target targetm = TARGET_INITIALIZER;
extern int reload_completed;
@@ -117,9 +160,6 @@ static int s390_sr_alias_set = 0;
emitted. */
rtx s390_compare_op0, s390_compare_op1;
-/* The encoding characters for the four TLS models present in ELF. */
-static char const tls_model_chars[] = " GLil";
-
/* Structure used to hold the components of a S/390 memory
address. A legitimate address on S/390 is of the general
form
@@ -137,16 +177,27 @@ struct s390_address
int pointer;
};
+/* Which cpu are we tuning for. */
+enum processor_type s390_tune;
+enum processor_flags s390_tune_flags;
+/* Which instruction set architecture to use. */
+enum processor_type s390_arch;
+enum processor_flags s390_arch_flags;
+
+/* Strings to hold which cpu and instruction set architecture to use. */
+const char *s390_tune_string; /* for -mtune=<xxx> */
+const char *s390_arch_string; /* for -march=<xxx> */
+
/* Define the structure for the machine field in struct function. */
struct machine_function GTY(())
{
- /* Label of start of initial literal pool. */
- rtx literal_pool_label;
-
/* Set, if some of the fprs 8-15 need to be saved (64 bit abi). */
int save_fprs_p;
+ /* Set if return address needs to be saved. */
+ bool save_return_addr_p;
+
/* Number of first and last gpr to be saved, restored. */
int first_save_gpr;
int first_restore_gpr;
@@ -159,43 +210,47 @@ struct machine_function GTY(())
const char *some_ld_name;
};
-static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode));
-static int s390_branch_condition_mask PARAMS ((rtx));
-static const char *s390_branch_condition_mnemonic PARAMS ((rtx, int));
-static int check_mode PARAMS ((rtx, enum machine_mode *));
-static int general_s_operand PARAMS ((rtx, enum machine_mode, int));
-static int s390_decompose_address PARAMS ((rtx, struct s390_address *));
-static rtx get_thread_pointer PARAMS ((void));
-static rtx legitimize_tls_address PARAMS ((rtx, rtx));
-static const char *get_some_local_dynamic_name PARAMS ((void));
-static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
-static int reg_used_in_mem_p PARAMS ((int, rtx));
-static int addr_generation_dependency_p PARAMS ((rtx, rtx));
-static int s390_split_branches PARAMS ((rtx, bool *));
-static void find_constant_pool_ref PARAMS ((rtx, rtx *));
-static void replace_constant_pool_ref PARAMS ((rtx *, rtx, rtx));
-static int find_base_register_in_addr PARAMS ((struct s390_address *));
-static bool find_base_register_ref PARAMS ((rtx));
-static void replace_base_register_ref PARAMS ((rtx *, rtx));
-static void s390_optimize_prolog PARAMS ((int));
-static bool s390_fixup_clobbered_return_reg PARAMS ((rtx));
-static int find_unused_clobbered_reg PARAMS ((void));
-static void s390_frame_info PARAMS ((void));
-static rtx save_fpr PARAMS ((rtx, int, int));
-static rtx restore_fpr PARAMS ((rtx, int, int));
-static rtx save_gprs PARAMS ((rtx, int, int, int));
-static rtx restore_gprs PARAMS ((rtx, int, int, int));
-static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
-static struct machine_function * s390_init_machine_status PARAMS ((void));
-
+static int s390_match_ccmode_set (rtx, enum machine_mode);
+static int s390_branch_condition_mask (rtx);
+static const char *s390_branch_condition_mnemonic (rtx, int);
+static int check_mode (rtx, enum machine_mode *);
+static int general_s_operand (rtx, enum machine_mode, int);
+static int s390_short_displacement (rtx);
+static int s390_decompose_address (rtx, struct s390_address *);
+static rtx get_thread_pointer (void);
+static rtx legitimize_tls_address (rtx, rtx);
+static void print_shift_count_operand (FILE *, rtx);
+static const char *get_some_local_dynamic_name (void);
+static int get_some_local_dynamic_name_1 (rtx *, void *);
+static int reg_used_in_mem_p (int, rtx);
+static int addr_generation_dependency_p (rtx, rtx);
+static int s390_split_branches (void);
+static void find_constant_pool_ref (rtx, rtx *);
+static void replace_constant_pool_ref (rtx *, rtx, rtx);
+static rtx find_ltrel_base (rtx);
+static void replace_ltrel_base (rtx *, rtx);
+static void s390_optimize_prolog (bool);
+static int find_unused_clobbered_reg (void);
+static void s390_frame_info (void);
+static rtx save_fpr (rtx, int, int);
+static rtx restore_fpr (rtx, int, int);
+static rtx save_gprs (rtx, int, int, int);
+static rtx restore_gprs (rtx, int, int, int);
+static int s390_function_arg_size (enum machine_mode, tree);
+static bool s390_function_arg_float (enum machine_mode, tree);
+static struct machine_function * s390_init_machine_status (void);
+
+/* Check whether integer displacement is in range. */
+#define DISP_IN_RANGE(d) \
+ (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
+ : ((d) >= 0 && (d) <= 4095))
+
/* Return true if SET either doesn't set the CC register, or else
- the source and destination have matching CC modes and that
+ the source and destination have matching CC modes and that
CC mode is at least as constrained as REQ_MODE. */
-
+
static int
-s390_match_ccmode_set (set, req_mode)
- rtx set;
- enum machine_mode req_mode;
+s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
{
enum machine_mode set_mode;
@@ -233,23 +288,21 @@ s390_match_ccmode_set (set, req_mode)
if (req_mode != CCAmode)
return 0;
break;
-
+
default:
abort ();
}
-
+
return (GET_MODE (SET_SRC (set)) == set_mode);
}
-/* Return true if every SET in INSN that sets the CC register
- has source and destination with matching CC modes and that
- CC mode is at least as constrained as REQ_MODE.
+/* Return true if every SET in INSN that sets the CC register
+ has source and destination with matching CC modes and that
+ CC mode is at least as constrained as REQ_MODE.
If REQ_MODE is VOIDmode, always return false. */
-
+
int
-s390_match_ccmode (insn, req_mode)
- rtx insn;
- enum machine_mode req_mode;
+s390_match_ccmode (rtx insn, enum machine_mode req_mode)
{
int i;
@@ -272,18 +325,15 @@ s390_match_ccmode (insn, req_mode)
return 1;
}
-/* If a test-under-mask instruction can be used to implement
+/* If a test-under-mask instruction can be used to implement
(compare (and ... OP1) OP2), return the CC mode required
- to do that. Otherwise, return VOIDmode.
+ to do that. Otherwise, return VOIDmode.
MIXED is true if the instruction can distinguish between
CC1 and CC2 for mixed selected bits (TMxx), it is false
if the instruction cannot (TM). */
enum machine_mode
-s390_tm_ccmode (op1, op2, mixed)
- rtx op1;
- rtx op2;
- int mixed;
+s390_tm_ccmode (rtx op1, rtx op2, int mixed)
{
int bit0, bit1;
@@ -311,25 +361,23 @@ s390_tm_ccmode (op1, op2, mixed)
return VOIDmode;
}
-/* Given a comparison code OP (EQ, NE, etc.) and the operands
- OP0 and OP1 of a COMPARE, return the mode to be used for the
+/* Given a comparison code OP (EQ, NE, etc.) and the operands
+ OP0 and OP1 of a COMPARE, return the mode to be used for the
comparison. */
enum machine_mode
-s390_select_ccmode (code, op0, op1)
- enum rtx_code code;
- rtx op0;
- rtx op1;
+s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
{
switch (code)
{
case EQ:
case NE:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
return CCAPmode;
- if (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
- || GET_CODE (op1) == NEG)
+ if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
+ || GET_CODE (op1) == NEG)
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
return CCLmode;
if (GET_CODE (op0) == AND)
@@ -345,11 +393,11 @@ s390_select_ccmode (code, op0, op1)
}
}
- if (register_operand (op0, HImode)
+ if (register_operand (op0, HImode)
&& GET_CODE (op1) == CONST_INT
&& (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
return CCT3mode;
- if (register_operand (op0, QImode)
+ if (register_operand (op0, QImode)
&& GET_CODE (op1) == CONST_INT
&& (INTVAL (op1) == -1 || INTVAL (op1) == 255))
return CCT3mode;
@@ -361,7 +409,7 @@ s390_select_ccmode (code, op0, op1)
case GE:
case GT:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
{
if (INTVAL (XEXP((op0), 1)) < 0)
return CCANmode;
@@ -383,7 +431,8 @@ s390_select_ccmode (code, op0, op1)
case LTU:
case GEU:
- if (GET_CODE (op0) == PLUS)
+ if (GET_CODE (op0) == PLUS
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
return CCL1mode;
if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
@@ -393,7 +442,8 @@ s390_select_ccmode (code, op0, op1)
case LEU:
case GTU:
- if (GET_CODE (op0) == MINUS)
+ if (GET_CODE (op0) == MINUS
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
return CCL2mode;
if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
@@ -406,13 +456,96 @@ s390_select_ccmode (code, op0, op1)
}
}
-/* Return branch condition mask to implement a branch
+/* Return nonzero if OP is a valid comparison operator
+ for an ALC condition in mode MODE. */
+
+int
+s390_alc_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == LTU;
+
+ case CCL2mode:
+ return GET_CODE (op) == LEU;
+
+ case CCUmode:
+ return GET_CODE (op) == GTU;
+
+ case CCURmode:
+ return GET_CODE (op) == LTU;
+
+ case CCSmode:
+ return GET_CODE (op) == UNGT;
+
+ case CCSRmode:
+ return GET_CODE (op) == UNLT;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return nonzero if OP is a valid comparison operator
+ for an SLB condition in mode MODE. */
+
+int
+s390_slb_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == GEU;
+
+ case CCL2mode:
+ return GET_CODE (op) == GTU;
+
+ case CCUmode:
+ return GET_CODE (op) == LEU;
+
+ case CCURmode:
+ return GET_CODE (op) == GEU;
+
+ case CCSmode:
+ return GET_CODE (op) == LE;
+
+ case CCSRmode:
+ return GET_CODE (op) == GE;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return branch condition mask to implement a branch
specified by CODE. */
static int
-s390_branch_condition_mask (code)
- rtx code;
-{
+s390_branch_condition_mask (rtx code)
+{
const int CC0 = 1 << 3;
const int CC1 = 1 << 2;
const int CC2 = 1 << 1;
@@ -600,14 +733,12 @@ s390_branch_condition_mask (code)
}
}
-/* If INV is false, return assembler mnemonic string to implement
- a branch specified by CODE. If INV is true, return mnemonic
+/* If INV is false, return assembler mnemonic string to implement
+ a branch specified by CODE. If INV is true, return mnemonic
for the corresponding inverted branch. */
static const char *
-s390_branch_condition_mnemonic (code, inv)
- rtx code;
- int inv;
+s390_branch_condition_mnemonic (rtx code, int inv)
{
static const char *const mnemonic[16] =
{
@@ -628,228 +759,82 @@ s390_branch_condition_mnemonic (code, inv)
return mnemonic[mask];
}
-/* If OP is an integer constant of mode MODE with exactly one
- HImode subpart unequal to DEF, return the number of that
- subpart. As a special case, all HImode subparts of OP are
- equal to DEF, return zero. Otherwise, return -1. */
+/* Return the part of op which has a value different from def.
+ The size of the part is determined by mode.
+ Use this function only if you already know that op really
+ contains such a part. */
-int
-s390_single_hi (op, mode, def)
- rtx op;
- enum machine_mode mode;
- int def;
+unsigned HOST_WIDE_INT
+s390_extract_part (rtx op, enum machine_mode mode, int def)
{
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode) / 2;
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) INTVAL (op);
- else
- value >>= 16;
-
- if ((value & 0xffff) != (unsigned)(def & 0xffff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode) / 2;
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
- else if (i == HOST_BITS_PER_WIDE_INT / 16)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
- else
- value >>= 16;
-
- if ((value & 0xffff) != (unsigned)(def & 0xffff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- return -1;
-}
-
-/* Extract the HImode part number PART from integer
- constant OP of mode MODE. */
-
-int
-s390_extract_hi (op, mode, part)
- rtx op;
- enum machine_mode mode;
- int part;
-{
- int n_parts = GET_MODE_SIZE (mode) / 2;
- if (part < 0 || part >= n_parts)
- abort();
- else
- part = n_parts - 1 - part;
-
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
- return ((value >> (16 * part)) & 0xffff);
- }
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
+ unsigned HOST_WIDE_INT value = 0;
+ int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
+ int part_bits = GET_MODE_BITSIZE (mode);
+ unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
+ int i;
+
+ for (i = 0; i < max_parts; i++)
{
- unsigned HOST_WIDE_INT value;
- if (part < HOST_BITS_PER_WIDE_INT / 16)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ if (i == 0)
+ value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
- part -= HOST_BITS_PER_WIDE_INT / 16;
-
- return ((value >> (16 * part)) & 0xffff);
+ value >>= part_bits;
+
+ if ((value & part_mask) != (def & part_mask))
+ return value & part_mask;
}
-
+
abort ();
}
/* If OP is an integer constant of mode MODE with exactly one
- QImode subpart unequal to DEF, return the number of that
- subpart. As a special case, all QImode subparts of OP are
- equal to DEF, return zero. Otherwise, return -1. */
+ part of mode PART_MODE unequal to DEF, return the number of that
+ part. Otherwise, return -1. */
int
-s390_single_qi (op, mode, def)
- rtx op;
- enum machine_mode mode;
- int def;
+s390_single_part (rtx op,
+ enum machine_mode mode,
+ enum machine_mode part_mode,
+ int def)
{
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode);
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) INTVAL (op);
- else
- value >>= 8;
-
- if ((value & 0xff) != (unsigned)(def & 0xff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode);
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
- else if (i == HOST_BITS_PER_WIDE_INT / 8)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
- else
- value >>= 8;
+ unsigned HOST_WIDE_INT value = 0;
+ int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
+ unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
+ int i, part = -1;
- if ((value & 0xff) != (unsigned)(def & 0xff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- return -1;
-}
-
-/* Extract the QImode part number PART from integer
- constant OP of mode MODE. */
-
-int
-s390_extract_qi (op, mode, part)
- rtx op;
- enum machine_mode mode;
- int part;
-{
- int n_parts = GET_MODE_SIZE (mode);
- if (part < 0 || part >= n_parts)
- abort();
- else
- part = n_parts - 1 - part;
-
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
- return ((value >> (8 * part)) & 0xff);
- }
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
+ if (GET_CODE (op) != CONST_INT)
+ return -1;
+
+ for (i = 0; i < n_parts; i++)
{
- unsigned HOST_WIDE_INT value;
- if (part < HOST_BITS_PER_WIDE_INT / 8)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ if (i == 0)
+ value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
- part -= HOST_BITS_PER_WIDE_INT / 8;
-
- return ((value >> (8 * part)) & 0xff);
+ value >>= GET_MODE_BITSIZE (part_mode);
+
+ if ((value & part_mask) != (def & part_mask))
+ {
+ if (part != -1)
+ return -1;
+ else
+ part = i;
+ }
}
-
- abort ();
+ return part == -1 ? -1 : n_parts - 1 - part;
}
-/* Check whether we can (and want to) split a double-word
- move in mode MODE from SRC to DST into two single-word
+/* Check whether we can (and want to) split a double-word
+ move in mode MODE from SRC to DST into two single-word
moves, moving the subword FIRST_SUBWORD first. */
bool
-s390_split_ok_p (dst, src, mode, first_subword)
- rtx dst;
- rtx src;
- enum machine_mode mode;
- int first_subword;
+s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
{
/* Floating point registers cannot be split. */
if (FP_REG_P (src) || FP_REG_P (dst))
return false;
- /* We don't need to split if operands are directly accessable. */
+ /* We don't need to split if operands are directly accessible. */
if (s_operand (src, mode) || s_operand (dst, mode))
return false;
@@ -871,7 +856,7 @@ s390_split_ok_p (dst, src, mode, first_subword)
}
-/* Change optimizations to be performed, depending on the
+/* Change optimizations to be performed, depending on the
optimization level.
LEVEL is the optimization level specified; 2 if `-O2' is
@@ -880,9 +865,7 @@ s390_split_ok_p (dst, src, mode, first_subword)
SIZE is nonzero if `-Os' is specified and zero otherwise. */
void
-optimization_options (level, size)
- int level ATTRIBUTE_UNUSED;
- int size ATTRIBUTE_UNUSED;
+optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
{
/* ??? There are apparently still problems with -fcaller-saves. */
flag_caller_saves = 0;
@@ -893,13 +876,80 @@ optimization_options (level, size)
}
void
-override_options ()
+override_options (void)
{
+ int i;
+ static struct pta
+ {
+ const char *const name; /* processor name or nickname. */
+ const enum processor_type processor;
+ const enum processor_flags flags;
+ }
+ const processor_alias_table[] =
+ {
+ {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
+ {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
+ {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
+ {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
+ | PF_LONG_DISPLACEMENT},
+ };
+
+ int const pta_size = ARRAY_SIZE (processor_alias_table);
+
/* Acquire a unique set number for our register saves and restores. */
s390_sr_alias_set = new_alias_set ();
/* Set up function hooks. */
init_machine_status = s390_init_machine_status;
+
+ /* Architecture mode defaults according to ABI. */
+ if (!(target_flags_explicit & MASK_ZARCH))
+ {
+ if (TARGET_64BIT)
+ target_flags |= MASK_ZARCH;
+ else
+ target_flags &= ~MASK_ZARCH;
+ }
+
+ /* Determine processor architectural level. */
+ if (!s390_arch_string)
+ s390_arch_string = TARGET_ZARCH? "z900" : "g5";
+
+ for (i = 0; i < pta_size; i++)
+ if (! strcmp (s390_arch_string, processor_alias_table[i].name))
+ {
+ s390_arch = processor_alias_table[i].processor;
+ s390_arch_flags = processor_alias_table[i].flags;
+ break;
+ }
+ if (i == pta_size)
+ error ("Unknown cpu used in -march=%s.", s390_arch_string);
+
+ /* Determine processor to tune for. */
+ if (!s390_tune_string)
+ {
+ s390_tune = s390_arch;
+ s390_tune_flags = s390_arch_flags;
+ s390_tune_string = s390_arch_string;
+ }
+ else
+ {
+ for (i = 0; i < pta_size; i++)
+ if (! strcmp (s390_tune_string, processor_alias_table[i].name))
+ {
+ s390_tune = processor_alias_table[i].processor;
+ s390_tune_flags = processor_alias_table[i].flags;
+ break;
+ }
+ if (i == pta_size)
+ error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
+ }
+
+ /* Sanity checks. */
+ if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
+ error ("z/Architecture mode not supported on %s.", s390_arch_string);
+ if (TARGET_64BIT && !TARGET_ZARCH)
+ error ("64-bit ABI not supported in ESA/390 mode.");
}
/* Map for smallest class containing reg regno. */
@@ -913,18 +963,26 @@ const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- ADDR_REGS, NO_REGS, ADDR_REGS
+ ADDR_REGS, NO_REGS, ADDR_REGS
};
+/* Return attribute type of insn. */
+
+static enum attr_type
+s390_safe_attr_type (rtx insn)
+{
+ if (recog_memoized (insn) >= 0)
+ return get_attr_type (insn);
+ else
+ return TYPE_NONE;
+}
/* Return true if OP a (const_int 0) operand.
OP is the current operation.
MODE is the current operation mode. */
-
+
int
-const0_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+const0_operand (register rtx op, enum machine_mode mode)
{
return op == CONST0_RTX (mode);
}
@@ -934,20 +992,16 @@ const0_operand (op, mode)
MODE is the current operation mode. */
int
-consttable_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return CONSTANT_P (op);
}
/* Return true if the mode of operand OP matches MODE.
- If MODE is set to VOIDmode, set it to the mode of OP. */
+ If MODE is set to VOIDmode, set it to the mode of OP. */
static int
-check_mode (op, mode)
- register rtx op;
- enum machine_mode *mode;
+check_mode (register rtx op, enum machine_mode *mode)
{
if (*mode == VOIDmode)
*mode = GET_MODE (op);
@@ -964,9 +1018,7 @@ check_mode (op, mode)
MODE is the current operation mode. */
int
-larl_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+larl_operand (register rtx op, enum machine_mode mode)
{
if (! check_mode (op, &mode))
return 0;
@@ -974,44 +1026,45 @@ larl_operand (op, mode)
/* Allow labels and local symbols. */
if (GET_CODE (op) == LABEL_REF)
return 1;
- if (GET_CODE (op) == SYMBOL_REF
- && XSTR (op, 0)[0] != '@'
- && !tls_symbolic_operand (op)
- && (!flag_pic || SYMBOL_REF_FLAG (op)
- || CONSTANT_POOL_ADDRESS_P (op)))
- return 1;
+ if (GET_CODE (op) == SYMBOL_REF)
+ return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
+ && SYMBOL_REF_TLS_MODEL (op) == 0
+ && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
/* Everything else must have a CONST, so strip it. */
if (GET_CODE (op) != CONST)
return 0;
op = XEXP (op, 0);
- /* Allow adding *even* constants. */
+ /* Allow adding *even* in-range constants. */
if (GET_CODE (op) == PLUS)
{
if (GET_CODE (XEXP (op, 1)) != CONST_INT
|| (INTVAL (XEXP (op, 1)) & 1) != 0)
return 0;
+#if HOST_BITS_PER_WIDE_INT > 32
+ if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
+ || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
+ return 0;
+#endif
op = XEXP (op, 0);
}
/* Labels and local symbols allowed here as well. */
if (GET_CODE (op) == LABEL_REF)
return 1;
- if (GET_CODE (op) == SYMBOL_REF
- && XSTR (op, 0)[0] != '@'
- && !tls_symbolic_operand (op)
- && (!flag_pic || SYMBOL_REF_FLAG (op)
- || CONSTANT_POOL_ADDRESS_P (op)))
- return 1;
+ if (GET_CODE (op) == SYMBOL_REF)
+ return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
+ && SYMBOL_REF_TLS_MODEL (op) == 0
+ && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
/* Now we must have a @GOTENT offset or @PLT stub
or an @INDNTPOFF TLS offset. */
if (GET_CODE (op) == UNSPEC
- && XINT (op, 1) == 111)
+ && XINT (op, 1) == UNSPEC_GOTENT)
return 1;
if (GET_CODE (op) == UNSPEC
- && XINT (op, 1) == 113)
+ && XINT (op, 1) == UNSPEC_PLT)
return 1;
if (GET_CODE (op) == UNSPEC
&& XINT (op, 1) == UNSPEC_INDNTPOFF)
@@ -1027,10 +1080,8 @@ larl_operand (op, mode)
be accepted or not. */
static int
-general_s_operand (op, mode, allow_immediate)
- register rtx op;
- enum machine_mode mode;
- int allow_immediate;
+general_s_operand (register rtx op, enum machine_mode mode,
+ int allow_immediate)
{
struct s390_address addr;
@@ -1041,37 +1092,37 @@ general_s_operand (op, mode, allow_immediate)
/* Just like memory_operand, allow (subreg (mem ...))
after reload. */
- if (reload_completed
- && GET_CODE (op) == SUBREG
+ if (reload_completed
+ && GET_CODE (op) == SUBREG
&& GET_CODE (SUBREG_REG (op)) == MEM)
op = SUBREG_REG (op);
switch (GET_CODE (op))
{
- /* Constants that we are sure will be forced to the
- literal pool in reload are OK as s-operand. Note
- that we cannot call s390_preferred_reload_class here
- because it might not be known yet at this point
- whether the current function is a leaf or not. */
+ /* Constants are OK as s-operand if ALLOW_IMMEDIATE
+ is true and we are still before reload. */
case CONST_INT:
case CONST_DOUBLE:
if (!allow_immediate || reload_completed)
- break;
- if (!legitimate_reload_constant_p (op))
- return 1;
- if (!TARGET_64BIT)
- return 1;
- break;
+ return 0;
+ return 1;
/* Memory operands are OK unless they already use an
index register. */
case MEM:
if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
return 1;
- if (s390_decompose_address (XEXP (op, 0), &addr)
- && !addr.indx)
- return 1;
- break;
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (addr.indx)
+ return 0;
+ /* Do not allow literal pool references unless ALLOW_IMMEDIATE
+ is true. This prevents compares between two literal pool
+ entries from being accepted. */
+ if (!allow_immediate
+ && addr.base && REGNO (addr.base) == BASE_REGISTER)
+ return 0;
+ return 1;
default:
break;
@@ -1085,54 +1136,330 @@ general_s_operand (op, mode, allow_immediate)
MODE is the current operation mode. */
int
-s_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+s_operand (register rtx op, enum machine_mode mode)
{
return general_s_operand (op, mode, 0);
}
-/* Return true if OP is a valid S-type operand or an immediate
- operand that can be addressed as S-type operand by forcing
+/* Return true if OP is a valid S-type operand or an immediate
+ operand that can be addressed as S-type operand by forcing
it into the literal pool.
OP is the current operation.
MODE is the current operation mode. */
int
-s_imm_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+s_imm_operand (register rtx op, enum machine_mode mode)
{
return general_s_operand (op, mode, 1);
}
-/* Return true if OP is a valid operand for a 'Q' constraint.
- This differs from s_operand in that only memory operands
- without index register are accepted, nothing else. */
+/* Return true if OP a valid shift count operand.
+ OP is the current operation.
+ MODE is the current operation mode. */
int
-q_constraint (op)
- register rtx op;
+shift_count_operand (rtx op, enum machine_mode mode)
{
- struct s390_address addr;
+ HOST_WIDE_INT offset = 0;
- if (GET_CODE (op) != MEM)
+ if (! check_mode (op, &mode))
return 0;
- if (!s390_decompose_address (XEXP (op, 0), &addr))
+ /* We can have an integer constant, an address register,
+ or a sum of the two. Note that reload already checks
+ that any register present is an address register, so
+ we just check for any register here. */
+ if (GET_CODE (op) == CONST_INT)
+ {
+ offset = INTVAL (op);
+ op = NULL_RTX;
+ }
+ if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+ {
+ offset = INTVAL (XEXP (op, 1));
+ op = XEXP (op, 0);
+ }
+ while (op && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+ if (op && GET_CODE (op) != REG)
return 0;
- if (addr.indx)
+ /* Unfortunately we have to reject constants that are invalid
+ for an address, or else reload will get confused. */
+ if (!DISP_IN_RANGE (offset))
return 0;
return 1;
}
-/* Return the cost of an address rtx ADDR. */
+/* Return true if DISP is a valid short displacement. */
+
+static int
+s390_short_displacement (rtx disp)
+{
+ /* No displacement is OK. */
+ if (!disp)
+ return 1;
+
+ /* Integer displacement in range. */
+ if (GET_CODE (disp) == CONST_INT)
+ return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
+
+ /* GOT offset is not OK, the GOT can be large. */
+ if (GET_CODE (disp) == CONST
+ && GET_CODE (XEXP (disp, 0)) == UNSPEC
+ && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
+ return 0;
+
+ /* All other symbolic constants are literal pool references,
+ which are OK as the literal pool must be small. */
+ if (GET_CODE (disp) == CONST)
+ return 1;
+
+ return 0;
+}
+
+/* Return true if OP is a valid operand for a C constraint. */
int
-s390_address_cost (addr)
- rtx addr;
+s390_extra_constraint_str (rtx op, int c, const char * str)
+{
+ struct s390_address addr;
+
+ if (c != str[0])
+ abort ();
+
+ switch (c)
+ {
+ case 'Q':
+ if (GET_CODE (op) != MEM)
+ return 0;
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (addr.indx)
+ return 0;
+
+ if (TARGET_LONG_DISPLACEMENT)
+ {
+ if (!s390_short_displacement (addr.disp))
+ return 0;
+ }
+ break;
+
+ case 'R':
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ if (TARGET_LONG_DISPLACEMENT)
+ {
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (!s390_short_displacement (addr.disp))
+ return 0;
+ }
+ break;
+
+ case 'S':
+ if (!TARGET_LONG_DISPLACEMENT)
+ return 0;
+ if (GET_CODE (op) != MEM)
+ return 0;
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (addr.indx)
+ return 0;
+ if (s390_short_displacement (addr.disp))
+ return 0;
+ break;
+
+ case 'T':
+ if (!TARGET_LONG_DISPLACEMENT)
+ return 0;
+ if (GET_CODE (op) != MEM)
+ return 0;
+ /* Any invalid address here will be fixed up by reload,
+ so accept it for the most generic constraint. */
+ if (s390_decompose_address (XEXP (op, 0), &addr)
+ && s390_short_displacement (addr.disp))
+ return 0;
+ break;
+
+ case 'U':
+ if (TARGET_LONG_DISPLACEMENT)
+ {
+ if (!s390_decompose_address (op, &addr))
+ return 0;
+ if (!s390_short_displacement (addr.disp))
+ return 0;
+ }
+ break;
+
+ case 'W':
+ if (!TARGET_LONG_DISPLACEMENT)
+ return 0;
+ /* Any invalid address here will be fixed up by reload,
+ so accept it for the most generic constraint. */
+ if (s390_decompose_address (op, &addr)
+ && s390_short_displacement (addr.disp))
+ return 0;
+ break;
+
+ case 'Y':
+ return shift_count_operand (op, VOIDmode);
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Return true if VALUE matches the constraint STR. */
+
+int
+s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
+ int c,
+ const char * str)
+{
+ enum machine_mode mode, part_mode;
+ int def;
+ unsigned char part;
+
+ if (c != str[0])
+ abort ();
+
+ switch (str[0])
+ {
+ case 'I':
+ return (unsigned int)value < 256;
+
+ case 'J':
+ return (unsigned int)value < 4096;
+
+ case 'K':
+ return value >= -32768 && value < 32768;
+
+ case 'L':
+ return (TARGET_LONG_DISPLACEMENT ?
+ (value >= -524288 && value <= 524287)
+ : (value >= 0 && value <= 4095));
+ case 'M':
+ return value == 2147483647;
+
+ case 'N':
+ part = str[1] - '0';
+
+ switch (str[2])
+ {
+ case 'H': part_mode = HImode; break;
+ case 'Q': part_mode = QImode; break;
+ default: return 0;
+ }
+
+ switch (str[3])
+ {
+ case 'H': mode = HImode; break;
+ case 'S': mode = SImode; break;
+ case 'D': mode = DImode; break;
+ default: return 0;
+ }
+
+ switch (str[4])
+ {
+ case '0': def = 0; break;
+ case 'F': def = -1; break;
+ default: return 0;
+ }
+
+ if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
+ return 0;
+
+ if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
+ return 0;
+
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* 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. */
+
+static bool
+s390_rtx_costs (rtx x, int code, int outer_code, int *total)
+{
+ switch (code)
+ {
+ case CONST:
+ if (GET_CODE (XEXP (x, 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
+ *total = 1000;
+ else
+ *total = 0;
+ return true;
+
+ case CONST_INT:
+ /* Force_const_mem does not work out of reload, because the
+ saveable_obstack is set to reload_obstack, which does not
+ live long enough. Because of this we cannot use force_const_mem
+ in addsi3. This leads to problems with gen_add2_insn with a
+ constant greater than a short. Because of that we give an
+ addition of greater constants a cost of 3 (reload1.c 10096). */
+ /* ??? saveable_obstack no longer exists. */
+ if (outer_code == PLUS
+ && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
+ *total = COSTS_N_INSNS (3);
+ else
+ *total = 0;
+ return true;
+
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ *total = 0;
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case PLUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case MINUS:
+ case NEG:
+ case NOT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case MULT:
+ if (GET_MODE (XEXP (x, 0)) == DImode)
+ *total = COSTS_N_INSNS (40);
+ else
+ *total = COSTS_N_INSNS (7);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (33);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Return the cost of an address rtx ADDR. */
+
+static int
+s390_address_cost (rtx addr)
{
struct s390_address ad;
if (!s390_decompose_address (addr, &ad))
@@ -1146,9 +1473,7 @@ s390_address_cost (addr)
MODE is the current operation mode. */
int
-bras_sym_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
register enum rtx_code code = GET_CODE (op);
@@ -1159,7 +1484,7 @@ bras_sym_operand (op, mode)
/* Allow @PLT stubs. */
if (code == CONST
&& GET_CODE (XEXP (op, 0)) == UNSPEC
- && XINT (XEXP (op, 0), 1) == 113)
+ && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
return 1;
return 0;
}
@@ -1168,30 +1493,22 @@ bras_sym_operand (op, mode)
otherwise return 0. */
int
-tls_symbolic_operand (op)
- register rtx op;
+tls_symbolic_operand (register rtx op)
{
- const char *symbol_str;
-
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- symbol_str = XSTR (op, 0);
-
- if (symbol_str[0] != '%')
- return 0;
- return strchr (tls_model_chars, symbol_str[1]) - tls_model_chars;
+ return SYMBOL_REF_TLS_MODEL (op);
}
/* Return true if OP is a load multiple operation. It is known to be a
- PARALLEL and the first section will be tested.
+ PARALLEL and the first section will be tested.
OP is the current operation.
MODE is the current operation mode. */
int
-load_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
+ enum machine_mode elt_mode;
int count = XVECLEN (op, 0);
unsigned int dest_regno;
rtx src_addr;
@@ -1207,13 +1524,14 @@ load_multiple_operation (op, mode)
dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
+ elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
/* Check, is base, or base + displacement. */
if (GET_CODE (src_addr) == REG)
off = 0;
else if (GET_CODE (src_addr) == PLUS
- && GET_CODE (XEXP (src_addr, 0)) == REG
+ && GET_CODE (XEXP (src_addr, 0)) == REG
&& GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
{
off = INTVAL (XEXP (src_addr, 1));
@@ -1231,15 +1549,15 @@ load_multiple_operation (op, mode)
if (GET_CODE (elt) != SET
|| GET_CODE (SET_DEST (elt)) != REG
- || GET_MODE (SET_DEST (elt)) != Pmode
+ || GET_MODE (SET_DEST (elt)) != elt_mode
|| REGNO (SET_DEST (elt)) != dest_regno + i
|| GET_CODE (SET_SRC (elt)) != MEM
- || GET_MODE (SET_SRC (elt)) != Pmode
+ || GET_MODE (SET_SRC (elt)) != elt_mode
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
|| ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
|| GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
|| INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
- != off + i * UNITS_PER_WORD)
+ != off + i * GET_MODE_SIZE (elt_mode))
return 0;
}
@@ -1247,15 +1565,14 @@ load_multiple_operation (op, mode)
}
/* Return true if OP is a store multiple operation. It is known to be a
- PARALLEL and the first section will be tested.
+ PARALLEL and the first section will be tested.
OP is the current operation.
MODE is the current operation mode. */
int
-store_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
+ enum machine_mode elt_mode;
int count = XVECLEN (op, 0);
unsigned int src_regno;
rtx dest_addr;
@@ -1270,13 +1587,14 @@ store_multiple_operation (op, mode)
src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
+ elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
/* Check, is base, or base + displacement. */
if (GET_CODE (dest_addr) == REG)
off = 0;
else if (GET_CODE (dest_addr) == PLUS
- && GET_CODE (XEXP (dest_addr, 0)) == REG
+ && GET_CODE (XEXP (dest_addr, 0)) == REG
&& GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
{
off = INTVAL (XEXP (dest_addr, 1));
@@ -1294,15 +1612,15 @@ store_multiple_operation (op, mode)
if (GET_CODE (elt) != SET
|| GET_CODE (SET_SRC (elt)) != REG
- || GET_MODE (SET_SRC (elt)) != Pmode
+ || GET_MODE (SET_SRC (elt)) != elt_mode
|| REGNO (SET_SRC (elt)) != src_regno + i
|| GET_CODE (SET_DEST (elt)) != MEM
- || GET_MODE (SET_DEST (elt)) != Pmode
+ || GET_MODE (SET_DEST (elt)) != elt_mode
|| GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
|| ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
|| GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
|| INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
- != off + i * UNITS_PER_WORD)
+ != off + i * GET_MODE_SIZE (elt_mode))
return 0;
}
return 1;
@@ -1312,8 +1630,7 @@ store_multiple_operation (op, mode)
/* Return true if OP contains a symbol reference */
int
-symbolic_reference_mentioned_p (op)
- rtx op;
+symbolic_reference_mentioned_p (rtx op)
{
register const char *fmt;
register int i;
@@ -1343,8 +1660,7 @@ symbolic_reference_mentioned_p (op)
/* Return true if OP contains a reference to a thread-local symbol. */
int
-tls_symbolic_reference_mentioned_p (op)
- rtx op;
+tls_symbolic_reference_mentioned_p (rtx op)
{
register const char *fmt;
register int i;
@@ -1372,19 +1688,18 @@ tls_symbolic_reference_mentioned_p (op)
}
-/* Return true if OP is a legitimate general operand when
- generating PIC code. It is given that flag_pic is on
+/* Return true if OP is a legitimate general operand when
+ generating PIC code. It is given that flag_pic is on
and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
int
-legitimate_pic_operand_p (op)
- register rtx op;
+legitimate_pic_operand_p (register rtx op)
{
/* Accept all non-symbolic constants. */
if (!SYMBOLIC_CONST (op))
return 1;
- /* Reject everything else; must be handled
+ /* Reject everything else; must be handled
via emit_symbolic_move. */
return 0;
}
@@ -1393,15 +1708,14 @@ legitimate_pic_operand_p (op)
It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
int
-legitimate_constant_p (op)
- register rtx op;
+legitimate_constant_p (register rtx op)
{
/* Accept all non-symbolic constants. */
if (!SYMBOLIC_CONST (op))
return 1;
/* Accept immediate LARL operands. */
- if (TARGET_64BIT && larl_operand (op, VOIDmode))
+ if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
return 1;
/* Thread-local symbols are never legal constants. This is
@@ -1426,8 +1740,7 @@ legitimate_constant_p (op)
not constant (TLS) or not known at final link time (PIC). */
static bool
-s390_cannot_force_const_mem (x)
- rtx x;
+s390_cannot_force_const_mem (rtx x)
{
switch (GET_CODE (x))
{
@@ -1459,10 +1772,10 @@ s390_cannot_force_const_mem (x)
switch (XINT (x, 1))
{
/* Only lt-relative or GOT-relative UNSPECs are OK. */
- case 100:
- case 104:
- case 112:
- case 114:
+ case UNSPEC_LTREL_OFFSET:
+ case UNSPEC_GOT:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLTOFF:
case UNSPEC_TLSGD:
case UNSPEC_TLSLDM:
case UNSPEC_NTPOFF:
@@ -1482,27 +1795,31 @@ s390_cannot_force_const_mem (x)
}
/* Returns true if the constant value OP is a legitimate general
- operand during and after reload. The difference to
+ operand during and after reload. The difference to
legitimate_constant_p is that this function will not accept
a constant that would need to be forced to the literal pool
before it can be used as operand. */
int
-legitimate_reload_constant_p (op)
- register rtx op;
+legitimate_reload_constant_p (register rtx op)
{
+ /* Accept la(y) operands. */
+ if (GET_CODE (op) == CONST_INT
+ && DISP_IN_RANGE (INTVAL (op)))
+ return 1;
+
/* Accept l(g)hi operands. */
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
return 1;
/* Accept lliXX operands. */
- if (TARGET_64BIT
- && s390_single_hi (op, DImode, 0) >= 0)
+ if (TARGET_ZARCH
+ && s390_single_part (op, DImode, HImode, 0) >= 0)
return 1;
/* Accept larl operands. */
- if (TARGET_64BIT
+ if (TARGET_CPU_ZARCH
&& larl_operand (op, VOIDmode))
return 1;
@@ -1514,9 +1831,7 @@ legitimate_reload_constant_p (op)
return the class of reg to actually use. */
enum reg_class
-s390_preferred_reload_class (op, class)
- rtx op;
- enum reg_class class;
+s390_preferred_reload_class (rtx op, enum reg_class class)
{
/* This can happen if a floating point constant is being
reloaded into an integer register. Leave well alone. */
@@ -1563,10 +1878,8 @@ s390_preferred_reload_class (op, class)
is not a legitimate operand of the LOAD ADDRESS instruction. */
enum reg_class
-s390_secondary_input_reload_class (class, mode, in)
- enum reg_class class ATTRIBUTE_UNUSED;
- enum machine_mode mode;
- rtx in;
+s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
+ enum machine_mode mode, rtx in)
{
if (s390_plus_operand (in, mode))
return ADDR_REGS;
@@ -1577,14 +1890,12 @@ s390_secondary_input_reload_class (class, mode, in)
/* Return the register class of a scratch register needed to
store a register of class CLASS in MODE into OUT:
- We need a temporary when storing a double-word to a
+ We need a temporary when storing a double-word to a
non-offsettable memory address. */
enum reg_class
-s390_secondary_output_reload_class (class, mode, out)
- enum reg_class class;
- enum machine_mode mode;
- rtx out;
+s390_secondary_output_reload_class (enum reg_class class,
+ enum machine_mode mode, rtx out)
{
if ((TARGET_64BIT ? mode == TImode
: (mode == DImode || mode == DFmode))
@@ -1598,14 +1909,12 @@ s390_secondary_output_reload_class (class, mode, out)
}
/* Return true if OP is a PLUS that is not a legitimate
- operand for the LA instruction.
+ operand for the LA instruction.
OP is the current operation.
MODE is the current operation mode. */
int
-s390_plus_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+s390_plus_operand (register rtx op, enum machine_mode mode)
{
if (!check_mode (op, &mode) || mode != Pmode)
return FALSE;
@@ -1624,10 +1933,8 @@ s390_plus_operand (op, mode)
SCRATCH may be used as scratch register. */
void
-s390_expand_plus_operand (target, src, scratch)
- register rtx target;
- register rtx src;
- register rtx scratch;
+s390_expand_plus_operand (register rtx target, register rtx src,
+ register rtx scratch)
{
rtx sum1, sum2;
struct s390_address ad;
@@ -1693,14 +2000,14 @@ s390_expand_plus_operand (target, src, scratch)
canonical form so that they will be recognized. */
static int
-s390_decompose_address (addr, out)
- register rtx addr;
- struct s390_address *out;
+s390_decompose_address (register rtx addr, struct s390_address *out)
{
rtx base = NULL_RTX;
rtx indx = NULL_RTX;
rtx disp = NULL_RTX;
int pointer = FALSE;
+ int base_ptr = FALSE;
+ int indx_ptr = FALSE;
/* Decompose address into base + index + displacement. */
@@ -1746,35 +2053,18 @@ s390_decompose_address (addr, out)
disp = addr; /* displacement */
- /* Prefer to use pointer as base, not index. */
- if (base && indx)
- {
- int base_ptr = GET_CODE (base) == UNSPEC
- || (REG_P (base) && REG_POINTER (base));
- int indx_ptr = GET_CODE (indx) == UNSPEC
- || (REG_P (indx) && REG_POINTER (indx));
-
- if (!base_ptr && indx_ptr)
- {
- rtx tmp = base;
- base = indx;
- indx = tmp;
- }
- }
-
/* Validate base register. */
if (base)
{
if (GET_CODE (base) == UNSPEC)
{
- if (XVECLEN (base, 0) != 1 || XINT (base, 1) != 101)
- return FALSE;
- base = XVECEXP (base, 0, 0);
- pointer = TRUE;
+ if (XVECLEN (base, 0) != 1 || XINT (base, 1) != UNSPEC_LTREL_BASE)
+ return FALSE;
+ base = gen_rtx_REG (Pmode, BASE_REGISTER);
}
if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
- return FALSE;
+ return FALSE;
if (REGNO (base) == BASE_REGISTER
|| REGNO (base) == STACK_POINTER_REGNUM
@@ -1783,11 +2073,9 @@ s390_decompose_address (addr, out)
&& frame_pointer_needed
&& REGNO (base) == HARD_FRAME_POINTER_REGNUM)
|| REGNO (base) == ARG_POINTER_REGNUM
- || (REGNO (base) >= FIRST_VIRTUAL_REGISTER
- && REGNO (base) <= LAST_VIRTUAL_REGISTER)
|| (flag_pic
&& REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
- pointer = TRUE;
+ pointer = base_ptr = TRUE;
}
/* Validate index register. */
@@ -1795,14 +2083,13 @@ s390_decompose_address (addr, out)
{
if (GET_CODE (indx) == UNSPEC)
{
- if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != 101)
- return FALSE;
- indx = XVECEXP (indx, 0, 0);
- pointer = TRUE;
+ if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != UNSPEC_LTREL_BASE)
+ return FALSE;
+ indx = gen_rtx_REG (Pmode, BASE_REGISTER);
}
if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
- return FALSE;
+ return FALSE;
if (REGNO (indx) == BASE_REGISTER
|| REGNO (indx) == STACK_POINTER_REGNUM
@@ -1811,11 +2098,18 @@ s390_decompose_address (addr, out)
&& frame_pointer_needed
&& REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
|| REGNO (indx) == ARG_POINTER_REGNUM
- || (REGNO (indx) >= FIRST_VIRTUAL_REGISTER
- && REGNO (indx) <= LAST_VIRTUAL_REGISTER)
|| (flag_pic
&& REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
- pointer = TRUE;
+ pointer = indx_ptr = TRUE;
+ }
+
+ /* Prefer to use pointer as base, not index. */
+ if (base && indx && !base_ptr
+ && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
+ {
+ rtx tmp = base;
+ base = indx;
+ indx = tmp;
}
/* Validate displacement. */
@@ -1834,16 +2128,16 @@ s390_decompose_address (addr, out)
this is fixed up by reload in any case. */
if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
{
- if (INTVAL (disp) < 0 || INTVAL (disp) >= 4096)
+ if (!DISP_IN_RANGE (INTVAL (disp)))
return FALSE;
}
}
- /* In the small-PIC case, the linker converts @GOT12
+ /* In the small-PIC case, the linker converts @GOT
and @GOTNTPOFF offsets to possible displacements. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
- && (XINT (XEXP (disp, 0), 1) == 110
+ && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
|| XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
{
if (flag_pic != 1)
@@ -1860,7 +2154,7 @@ s390_decompose_address (addr, out)
{
pointer = TRUE;
}
-
+
/* Likewise if a constant offset is present. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == PLUS
@@ -1872,7 +2166,7 @@ s390_decompose_address (addr, out)
pointer = TRUE;
}
- /* We can convert literal pool addresses to
+ /* We can convert literal pool addresses to
displacements by basing them off the base register. */
else
{
@@ -1899,7 +2193,7 @@ s390_decompose_address (addr, out)
if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
return FALSE;
- /* Either base or index must be free to
+ /* Either base or index must be free to
hold the base register. */
if (base && indx)
return FALSE;
@@ -1910,7 +2204,8 @@ s390_decompose_address (addr, out)
else
base = gen_rtx_REG (Pmode, BASE_REGISTER);
- disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp), 100);
+ disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
+ UNSPEC_LTREL_OFFSET);
disp = gen_rtx_CONST (Pmode, disp);
if (offset)
@@ -1922,7 +2217,7 @@ s390_decompose_address (addr, out)
if (!base && !indx)
pointer = TRUE;
-
+
if (out)
{
out->base = base;
@@ -1938,10 +2233,8 @@ s390_decompose_address (addr, out)
STRICT specifies whether strict register checking applies. */
int
-legitimate_address_p (mode, addr, strict)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- register rtx addr;
- int strict;
+legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ register rtx addr, int strict)
{
struct s390_address ad;
if (!s390_decompose_address (addr, &ad))
@@ -1970,8 +2263,7 @@ legitimate_address_p (mode, addr, strict)
address, as LA performs only a 31-bit addition. */
int
-legitimate_la_operand_p (op)
- register rtx op;
+legitimate_la_operand_p (register rtx op)
{
struct s390_address addr;
if (!s390_decompose_address (op, &addr))
@@ -1985,10 +2277,9 @@ legitimate_la_operand_p (op)
/* Return 1 if OP is a valid operand for the LA instruction,
and we prefer to use LA over addition to compute it. */
-
+
int
-preferred_la_operand_p (op)
- register rtx op;
+preferred_la_operand_p (register rtx op)
{
struct s390_address addr;
if (!s390_decompose_address (op, &addr))
@@ -2012,9 +2303,7 @@ preferred_la_operand_p (op)
where legitimate_la_operand_p (SRC) returns false. */
void
-s390_load_address (dst, src)
- rtx dst;
- rtx src;
+s390_load_address (rtx dst, rtx src)
{
if (TARGET_64BIT)
emit_move_insn (dst, src);
@@ -2033,7 +2322,7 @@ s390_load_address (dst, src)
2. Static data references, constant pool addresses, and code labels
compute the address as an offset from the GOT, whose base is in
- the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
+ the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
differentiate them from global data objects. The returned
address is the PIC reg + an unspec constant.
@@ -2041,41 +2330,37 @@ s390_load_address (dst, src)
reg also appears in the address. */
rtx
-legitimize_pic_address (orig, reg)
- rtx orig;
- rtx reg;
+legitimize_pic_address (rtx orig, rtx reg)
{
rtx addr = orig;
rtx new = orig;
rtx base;
if (GET_CODE (addr) == LABEL_REF
- || (GET_CODE (addr) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (addr)
- || CONSTANT_POOL_ADDRESS_P (addr))))
+ || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
{
/* This is a local symbol. */
- if (TARGET_64BIT && larl_operand (addr, VOIDmode))
+ if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
{
- /* Access local symbols PC-relative via LARL.
- This is the same as in the non-PIC case, so it is
+ /* Access local symbols PC-relative via LARL.
+ This is the same as in the non-PIC case, so it is
handled automatically ... */
}
else
{
- /* Access local symbols relative to the literal pool. */
+ /* Access local symbols relative to the GOT. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 100);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
-
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
@@ -2091,12 +2376,12 @@ legitimize_pic_address (orig, reg)
if (flag_pic == 1)
{
/* Assume GOT offset < 4k. This is handled the same way
- in both 31- and 64-bit code (@GOT12). */
+ in both 31- and 64-bit code (@GOT). */
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 110);
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
new = gen_rtx_CONST (Pmode, new);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
new = gen_rtx_MEM (Pmode, new);
@@ -2104,14 +2389,14 @@ legitimize_pic_address (orig, reg)
emit_move_insn (reg, new);
new = reg;
}
- else if (TARGET_64BIT)
+ else if (TARGET_CPU_ZARCH)
{
/* If the GOT offset might be >= 4k, we determine the position
of the GOT entry via a PC-relative LARL (@GOTENT). */
rtx temp = gen_reg_rtx (Pmode);
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 111);
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
new = gen_rtx_CONST (Pmode, new);
emit_move_insn (temp, new);
@@ -2122,7 +2407,7 @@ legitimize_pic_address (orig, reg)
}
else
{
- /* If the GOT offset might be >= 4k, we have to load it
+ /* If the GOT offset might be >= 4k, we have to load it
from the literal pool (@GOT). */
rtx temp = gen_reg_rtx (Pmode);
@@ -2130,7 +2415,7 @@ legitimize_pic_address (orig, reg)
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 112);
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
@@ -2141,7 +2426,7 @@ legitimize_pic_address (orig, reg)
emit_move_insn (reg, new);
new = reg;
}
- }
+ }
else
{
if (GET_CODE (addr) == CONST)
@@ -2153,35 +2438,41 @@ legitimize_pic_address (orig, reg)
abort ();
switch (XINT (addr, 1))
{
- /* If someone moved an @GOT or lt-relative UNSPEC
+ /* If someone moved a GOT-relative UNSPEC
out of the literal pool, force them back in. */
- case 100:
- case 112:
- case 114:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLTOFF:
new = force_const_mem (Pmode, orig);
break;
+ /* @GOT is OK as is if small. */
+ case UNSPEC_GOT:
+ if (flag_pic == 2)
+ new = force_const_mem (Pmode, orig);
+ break;
+
/* @GOTENT is OK as is. */
- case 111:
+ case UNSPEC_GOTENT:
break;
/* @PLT is OK as is on 64-bit, must be converted to
- lt-relative PLT on 31-bit. */
- case 113:
- if (!TARGET_64BIT)
+ GOT-relative @PLTOFF on 31-bit. */
+ case UNSPEC_PLT:
+ if (!TARGET_CPU_ZARCH)
{
rtx temp = reg? reg : gen_reg_rtx (Pmode);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
addr = XVECEXP (addr, 0, 0);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 114);
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
+ UNSPEC_PLTOFF);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
-
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
@@ -2201,23 +2492,21 @@ legitimize_pic_address (orig, reg)
if (GET_CODE (addr) == PLUS)
{
rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
- /* Check first to see if this is a constant offset
+ /* Check first to see if this is a constant offset
from a local symbol reference. */
if ((GET_CODE (op0) == LABEL_REF
- || (GET_CODE (op0) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (op0)
- || CONSTANT_POOL_ADDRESS_P (op0))))
+ || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
&& GET_CODE (op1) == CONST_INT)
{
- if (TARGET_64BIT && larl_operand (op0, VOIDmode))
+ if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
{
if (INTVAL (op1) & 1)
{
- /* LARL can't handle odd offsets, so emit a
+ /* LARL can't handle odd offsets, so emit a
pair of LARL and LA. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- if (INTVAL (op1) < 0 || INTVAL (op1) >= 4096)
+ if (!DISP_IN_RANGE (INTVAL (op1)))
{
int even = INTVAL (op1) - 1;
op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
@@ -2242,20 +2531,21 @@ legitimize_pic_address (orig, reg)
}
else
{
- /* Access local symbols relative to the literal pool. */
+ /* Access local symbols relative to the GOT. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 100);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
+ UNSPEC_GOTOFF);
addr = gen_rtx_PLUS (Pmode, addr, op1);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
- emit_move_insn (temp, addr);
-
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
+ emit_move_insn (temp, addr);
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
@@ -2264,16 +2554,15 @@ legitimize_pic_address (orig, reg)
}
}
- /* Now, check whether it is an LT-relative symbol plus offset
+ /* Now, check whether it is a GOT relative symbol plus offset
that was pulled out of the literal pool. Force it back in. */
else if (GET_CODE (op0) == UNSPEC
- && GET_CODE (op1) == CONST_INT)
+ && GET_CODE (op1) == CONST_INT
+ && XINT (op0, 1) == UNSPEC_GOTOFF)
{
if (XVECLEN (op0, 0) != 1)
abort ();
- if (XINT (op0, 1) != 100)
- abort ();
new = force_const_mem (Pmode, orig);
}
@@ -2308,7 +2597,7 @@ legitimize_pic_address (orig, reg)
/* Load the thread pointer into a register. */
static rtx
-get_thread_pointer ()
+get_thread_pointer (void)
{
rtx tp;
@@ -2323,7 +2612,7 @@ get_thread_pointer ()
static GTY(()) rtx s390_tls_symbol;
rtx
-s390_tls_get_offset ()
+s390_tls_get_offset (void)
{
if (!s390_tls_symbol)
s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
@@ -2335,9 +2624,7 @@ s390_tls_get_offset ()
this (thread-local) address. REG may be used as temporary. */
static rtx
-legitimize_tls_address (addr, reg)
- rtx addr;
- rtx reg;
+legitimize_tls_address (rtx addr, rtx reg)
{
rtx new, tls_call, temp, base, r2, insn;
@@ -2417,7 +2704,7 @@ legitimize_tls_address (addr, reg)
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
}
- else if (TARGET_64BIT)
+ else if (TARGET_CPU_ZARCH)
{
/* If the GOT offset might be >= 4k, we determine the position
of the GOT entry via a PC-relative LARL. */
@@ -2434,7 +2721,7 @@ legitimize_tls_address (addr, reg)
}
else if (flag_pic)
{
- /* If the GOT offset might be >= 4k, we have to load it
+ /* If the GOT offset might be >= 4k, we have to load it
from the literal pool. */
if (reload_in_progress || reload_completed)
@@ -2506,7 +2793,7 @@ legitimize_tls_address (addr, reg)
switch (XINT (XEXP (addr, 0), 1))
{
case UNSPEC_INDNTPOFF:
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
new = addr;
else
abort ();
@@ -2526,8 +2813,7 @@ legitimize_tls_address (addr, reg)
/* Emit insns to move operands[1] into operands[0]. */
void
-emit_symbolic_move (operands)
- rtx *operands;
+emit_symbolic_move (rtx *operands)
{
rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
@@ -2551,10 +2837,8 @@ emit_symbolic_move (operands)
See comments by legitimize_pic_address for details. */
rtx
-legitimize_address (x, oldx, mode)
- register rtx x;
- register rtx oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx constant_term = const0_rtx;
@@ -2568,8 +2852,8 @@ legitimize_address (x, oldx, mode)
else if (flag_pic)
{
if (SYMBOLIC_CONST (x)
- || (GET_CODE (x) == PLUS
- && (SYMBOLIC_CONST (XEXP (x, 0))
+ || (GET_CODE (x) == PLUS
+ && (SYMBOLIC_CONST (XEXP (x, 0))
|| SYMBOLIC_CONST (XEXP (x, 1)))))
x = legitimize_pic_address (x, 0);
@@ -2581,15 +2865,15 @@ legitimize_address (x, oldx, mode)
/* Optimize loading of large displacements by splitting them
into the multiple of 4K and the rest; this allows the
- former to be CSE'd if possible.
+ former to be CSE'd if possible.
Don't do this if the displacement is added to a register
pointing into the stack frame, as the offsets will
change later anyway. */
if (GET_CODE (constant_term) == CONST_INT
- && (INTVAL (constant_term) < 0
- || INTVAL (constant_term) >= 4096)
+ && !TARGET_LONG_DISPLACEMENT
+ && !DISP_IN_RANGE (INTVAL (constant_term))
&& !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
{
HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
@@ -2636,39 +2920,17 @@ legitimize_address (x, oldx, mode)
/* Emit code to move LEN bytes from DST to SRC. */
void
-s390_expand_movstr (dst, src, len)
- rtx dst;
- rtx src;
- rtx len;
+s390_expand_movstr (rtx dst, rtx src, rtx len)
{
- rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_movstr_short_64 : gen_movstr_short_31;
- rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_movstr_long_64 : gen_movstr_long_31;
-
-
if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
{
if (INTVAL (len) > 0)
- emit_insn ((*gen_short) (dst, src, GEN_INT (INTVAL (len) - 1)));
+ emit_insn (gen_movstr_short (dst, src, GEN_INT (INTVAL (len) - 1)));
}
else if (TARGET_MVCLE)
{
- enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
- enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
- rtx reg0 = gen_reg_rtx (double_mode);
- rtx reg1 = gen_reg_rtx (double_mode);
-
- emit_move_insn (gen_highpart (single_mode, reg0),
- force_operand (XEXP (dst, 0), NULL_RTX));
- emit_move_insn (gen_highpart (single_mode, reg1),
- force_operand (XEXP (src, 0), NULL_RTX));
-
- convert_move (gen_lowpart (single_mode, reg0), len, 1);
- convert_move (gen_lowpart (single_mode, reg1), len, 1);
-
- emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
+ emit_insn (gen_movstr_long (dst, src, convert_to_mode (Pmode, len, 1)));
}
else
@@ -2680,9 +2942,9 @@ s390_expand_movstr (dst, src, len)
mode = GET_MODE (len);
if (mode == VOIDmode)
- mode = word_mode;
+ mode = Pmode;
- type = (*lang_hooks.types.type_for_mode) (mode, 1);
+ type = lang_hooks.types.type_for_mode (mode, 1);
if (!type)
abort ();
@@ -2692,14 +2954,14 @@ s390_expand_movstr (dst, src, len)
blocks = gen_reg_rtx (mode);
convert_move (count, len, 1);
- emit_cmp_and_jump_insns (count, const0_rtx,
+ emit_cmp_and_jump_insns (count, const0_rtx,
EQ, NULL_RTX, mode, 1, end_label);
emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
dst = change_address (dst, VOIDmode, dst_addr);
src = change_address (src, VOIDmode, src_addr);
-
+
temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
if (temp != count)
emit_move_insn (count, temp);
@@ -2713,19 +2975,20 @@ s390_expand_movstr (dst, src, len)
make_tree (type, blocks),
make_tree (type, const0_rtx)));
- emit_insn ((*gen_short) (dst, src, GEN_INT (255)));
- s390_load_address (dst_addr,
+ emit_insn (gen_movstr_short (dst, src, GEN_INT (255)));
+ s390_load_address (dst_addr,
gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
- s390_load_address (src_addr,
+ s390_load_address (src_addr,
gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
-
+
temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
if (temp != blocks)
emit_move_insn (blocks, temp);
expand_end_loop ();
- emit_insn ((*gen_short) (dst, src, convert_to_mode (word_mode, count, 1)));
+ emit_insn (gen_movstr_short (dst, src,
+ convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
}
}
@@ -2733,37 +2996,17 @@ s390_expand_movstr (dst, src, len)
/* Emit code to clear LEN bytes at DST. */
void
-s390_expand_clrstr (dst, len)
- rtx dst;
- rtx len;
+s390_expand_clrstr (rtx dst, rtx len)
{
- rtx (*gen_short) PARAMS ((rtx, rtx)) =
- TARGET_64BIT ? gen_clrstr_short_64 : gen_clrstr_short_31;
- rtx (*gen_long) PARAMS ((rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_clrstr_long_64 : gen_clrstr_long_31;
-
-
if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
{
if (INTVAL (len) > 0)
- emit_insn ((*gen_short) (dst, GEN_INT (INTVAL (len) - 1)));
+ emit_insn (gen_clrstr_short (dst, GEN_INT (INTVAL (len) - 1)));
}
else if (TARGET_MVCLE)
{
- enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
- enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
- rtx reg0 = gen_reg_rtx (double_mode);
- rtx reg1 = gen_reg_rtx (double_mode);
-
- emit_move_insn (gen_highpart (single_mode, reg0),
- force_operand (XEXP (dst, 0), NULL_RTX));
- convert_move (gen_lowpart (single_mode, reg0), len, 1);
-
- emit_move_insn (gen_highpart (single_mode, reg1), const0_rtx);
- emit_move_insn (gen_lowpart (single_mode, reg1), const0_rtx);
-
- emit_insn ((*gen_long) (reg0, reg1, reg0));
+ emit_insn (gen_clrstr_long (dst, convert_to_mode (Pmode, len, 1)));
}
else
@@ -2775,9 +3018,9 @@ s390_expand_clrstr (dst, len)
mode = GET_MODE (len);
if (mode == VOIDmode)
- mode = word_mode;
+ mode = Pmode;
- type = (*lang_hooks.types.type_for_mode) (mode, 1);
+ type = lang_hooks.types.type_for_mode (mode, 1);
if (!type)
abort ();
@@ -2787,12 +3030,12 @@ s390_expand_clrstr (dst, len)
blocks = gen_reg_rtx (mode);
convert_move (count, len, 1);
- emit_cmp_and_jump_insns (count, const0_rtx,
+ emit_cmp_and_jump_insns (count, const0_rtx,
EQ, NULL_RTX, mode, 1, end_label);
emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
dst = change_address (dst, VOIDmode, dst_addr);
-
+
temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
if (temp != count)
emit_move_insn (count, temp);
@@ -2806,17 +3049,17 @@ s390_expand_clrstr (dst, len)
make_tree (type, blocks),
make_tree (type, const0_rtx)));
- emit_insn ((*gen_short) (dst, GEN_INT (255)));
- s390_load_address (dst_addr,
+ emit_insn (gen_clrstr_short (dst, GEN_INT (255)));
+ s390_load_address (dst_addr,
gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
-
+
temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
if (temp != blocks)
emit_move_insn (blocks, temp);
expand_end_loop ();
- emit_insn ((*gen_short) (dst, convert_to_mode (word_mode, count, 1)));
+ emit_insn (gen_clrstr_short (dst, convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
}
}
@@ -2825,17 +3068,9 @@ s390_expand_clrstr (dst, len)
and return the result in TARGET. */
void
-s390_expand_cmpstr (target, op0, op1, len)
- rtx target;
- rtx op0;
- rtx op1;
- rtx len;
-{
- rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_cmpstr_short_64 : gen_cmpstr_short_31;
- rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_cmpstr_long_64 : gen_cmpstr_long_31;
- rtx (*gen_result) PARAMS ((rtx)) =
+s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
+{
+ rtx (*gen_result) (rtx) =
GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
op0 = protect_from_queue (op0, 0);
@@ -2846,8 +3081,8 @@ s390_expand_cmpstr (target, op0, op1, len)
{
if (INTVAL (len) > 0)
{
- emit_insn ((*gen_short) (op0, op1, GEN_INT (INTVAL (len) - 1)));
- emit_insn ((*gen_result) (target));
+ emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
+ emit_insn (gen_result (target));
}
else
emit_move_insn (target, const0_rtx);
@@ -2855,21 +3090,8 @@ s390_expand_cmpstr (target, op0, op1, len)
else /* if (TARGET_MVCLE) */
{
- enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
- enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
- rtx reg0 = gen_reg_rtx (double_mode);
- rtx reg1 = gen_reg_rtx (double_mode);
-
- emit_move_insn (gen_highpart (single_mode, reg0),
- force_operand (XEXP (op0, 0), NULL_RTX));
- emit_move_insn (gen_highpart (single_mode, reg1),
- force_operand (XEXP (op1, 0), NULL_RTX));
-
- convert_move (gen_lowpart (single_mode, reg0), len, 1);
- convert_move (gen_lowpart (single_mode, reg1), len, 1);
-
- emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
- emit_insn ((*gen_result) (target));
+ emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
+ emit_insn (gen_result (target));
}
#if 0
@@ -2884,9 +3106,9 @@ s390_expand_cmpstr (target, op0, op1, len)
mode = GET_MODE (len);
if (mode == VOIDmode)
- mode = word_mode;
+ mode = Pmode;
- type = (*lang_hooks.types.type_for_mode) (mode, 1);
+ type = lang_hooks.types.type_for_mode (mode, 1);
if (!type)
abort ();
@@ -2896,14 +3118,14 @@ s390_expand_cmpstr (target, op0, op1, len)
blocks = gen_reg_rtx (mode);
convert_move (count, len, 1);
- emit_cmp_and_jump_insns (count, const0_rtx,
+ emit_cmp_and_jump_insns (count, const0_rtx,
EQ, NULL_RTX, mode, 1, end_label);
emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
op0 = change_address (op0, VOIDmode, addr0);
op1 = change_address (op1, VOIDmode, addr1);
-
+
temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
if (temp != count)
emit_move_insn (count, temp);
@@ -2917,39 +3139,60 @@ s390_expand_cmpstr (target, op0, op1, len)
make_tree (type, blocks),
make_tree (type, const0_rtx)));
- emit_insn ((*gen_short) (op0, op1, GEN_INT (255)));
+ emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
- temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
+ temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
emit_jump_insn (temp);
- s390_load_address (addr0,
+ s390_load_address (addr0,
gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
- s390_load_address (addr1,
+ s390_load_address (addr1,
gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
-
+
temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
if (temp != blocks)
emit_move_insn (blocks, temp);
expand_end_loop ();
- emit_insn ((*gen_short) (op0, op1, convert_to_mode (word_mode, count, 1)));
+ emit_insn (gen_cmpmem_short (op0, op1,
+ convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
- emit_insn ((*gen_result) (target));
+ emit_insn (gen_result (target));
}
#endif
}
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ switch (size)
+ {
+ case 4:
+ fputs ("\t.long\t", file);
+ break;
+ case 8:
+ fputs ("\t.quad\t", file);
+ break;
+ default:
+ abort ();
+ }
+ output_addr_const (file, x);
+ fputs ("@DTPOFF", file);
+}
+
/* In the name of slightly smaller debug output, and to cater to
general assembler losage, recognize various UNSPEC sequences
and turn them back into a direct symbol reference. */
-rtx
-s390_simplify_dwarf_addr (orig_x)
- rtx orig_x;
+static rtx
+s390_delegitimize_address (rtx orig_x)
{
rtx x = orig_x, y;
@@ -2964,7 +3207,7 @@ s390_simplify_dwarf_addr (orig_x)
{
y = XEXP (XEXP (x, 1), 0);
if (GET_CODE (y) == UNSPEC
- && XINT (y, 1) == 110)
+ && XINT (y, 1) == UNSPEC_GOT)
return XVECEXP (y, 0, 0);
return orig_x;
}
@@ -2973,19 +3216,53 @@ s390_simplify_dwarf_addr (orig_x)
{
y = XEXP (x, 0);
if (GET_CODE (y) == UNSPEC
- && XINT (y, 1) == 111)
+ && XINT (y, 1) == UNSPEC_GOTENT)
return XVECEXP (y, 0, 0);
return orig_x;
}
- return orig_x;
+ return orig_x;
+}
+
+/* Output shift count operand OP to stdio stream FILE. */
+
+static void
+print_shift_count_operand (FILE *file, rtx op)
+{
+ HOST_WIDE_INT offset = 0;
+
+ /* We can have an integer constant, an address register,
+ or a sum of the two. */
+ if (GET_CODE (op) == CONST_INT)
+ {
+ offset = INTVAL (op);
+ op = NULL_RTX;
+ }
+ if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+ {
+ offset = INTVAL (XEXP (op, 1));
+ op = XEXP (op, 0);
+ }
+ while (op && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ /* Sanity check. */
+ if (op && (GET_CODE (op) != REG
+ || REGNO (op) >= FIRST_PSEUDO_REGISTER
+ || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
+ abort ();
+
+ /* Shift counts are truncated to the low six bits anyway. */
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
+ if (op)
+ fprintf (file, "(%s)", reg_names[REGNO (op)]);
}
/* Locate some local-dynamic symbol still in use by this function
so that we can print its name in local-dynamic base patterns. */
static const char *
-get_some_local_dynamic_name ()
+get_some_local_dynamic_name (void)
{
rtx insn;
@@ -3001,9 +3278,7 @@ get_some_local_dynamic_name ()
}
static int
-get_some_local_dynamic_name_1 (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
+get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
{
rtx x = *px;
@@ -3023,13 +3298,11 @@ get_some_local_dynamic_name_1 (px, data)
return 0;
}
-/* Output symbolic constant X in assembler syntax to
+/* Output symbolic constant X in assembler syntax to
stdio stream FILE. */
void
-s390_output_symbolic_const (file, x)
- FILE *file;
- rtx x;
+s390_output_symbolic_const (FILE *file, rtx x)
{
switch (GET_CODE (x))
{
@@ -3063,37 +3336,25 @@ s390_output_symbolic_const (file, x)
output_operand_lossage ("invalid UNSPEC as operand (1)");
switch (XINT (x, 1))
{
- case 100:
- case 104:
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "-");
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
- break;
- case 105:
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
- fprintf (file, "-");
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- break;
- case 110:
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "@GOT12");
- break;
- case 111:
+ case UNSPEC_GOTENT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@GOTENT");
break;
- case 112:
+ case UNSPEC_GOT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@GOT");
break;
- case 113:
+ case UNSPEC_GOTOFF:
+ s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
+ fprintf (file, "@GOTOFF");
+ break;
+ case UNSPEC_PLT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@PLT");
break;
- case 114:
+ case UNSPEC_PLTOFF:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "@PLT-");
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
+ fprintf (file, "@PLTOFF");
break;
case UNSPEC_TLSGD:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
@@ -3131,13 +3392,11 @@ s390_output_symbolic_const (file, x)
}
}
-/* Output address operand ADDR in assembler syntax to
+/* Output address operand ADDR in assembler syntax to
stdio stream FILE. */
void
-print_operand_address (file, addr)
- FILE *file;
- rtx addr;
+print_operand_address (FILE *file, rtx addr)
{
struct s390_address ad;
@@ -3145,7 +3404,7 @@ print_operand_address (file, addr)
|| (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
|| (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
output_operand_lossage ("Cannot decompose address.");
-
+
if (ad.disp)
s390_output_symbolic_const (file, ad.disp);
else
@@ -3158,8 +3417,8 @@ print_operand_address (file, addr)
fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
}
-/* Output operand X in assembler syntax to stdio stream FILE.
- CODE specified the format flag. The following format flags
+/* Output operand X in assembler syntax to stdio stream FILE.
+ CODE specified the format flag. The following format flags
are recognized:
'C': print opcode suffix for branch condition.
@@ -3169,16 +3428,16 @@ print_operand_address (file, addr)
'R': print only the base register of a memory reference.
'N': print the second word of a DImode operand.
'M': print the second word of a TImode operand.
+ 'Y': print shift count operand.
'b': print integer X as if it's an unsigned byte.
'x': print integer X as if it's an unsigned word.
- 'h': print integer X as if it's a signed word. */
+ 'h': print integer X as if it's a signed word.
+ 'i': print the first nonzero HImode part of X.
+ 'j': print the first HImode part unequal to 0xffff of X. */
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
switch (code)
{
@@ -3261,6 +3520,10 @@ print_operand (file, x, code)
else
abort ();
break;
+
+ case 'Y':
+ print_shift_count_operand (file, x);
+ return;
}
switch (GET_CODE (x))
@@ -3287,6 +3550,12 @@ print_operand (file, x, code)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
else if (code == 'h')
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
+ else if (code == 'i')
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ s390_extract_part (x, HImode, 0));
+ else if (code == 'j')
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ s390_extract_part (x, HImode, -1));
else
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
break;
@@ -3315,44 +3584,35 @@ print_operand (file, x, code)
handle values smaller than INT_MIN when printed in decimal. */
static bool
-s390_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
if (size == 8 && aligned_p
&& GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
{
- fputs ("\t.quad\t", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
- putc ('\n', asm_out_file);
+ fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
+ INTVAL (x));
return true;
}
return default_assemble_integer (x, size, aligned_p);
}
-
-#define DEBUG_SCHED 0
-
-/* Returns true if register REGNO is used for forming
+/* Returns true if register REGNO is used for forming
a memory address in expression X. */
static int
-reg_used_in_mem_p (regno, x)
- int regno;
- rtx x;
+reg_used_in_mem_p (int regno, rtx x)
{
enum rtx_code code = GET_CODE (x);
int i, j;
const char *fmt;
-
+
if (code == MEM)
{
if (refers_to_regno_p (regno, regno+1,
XEXP (x, 0), 0))
return 1;
}
- else if (code == SET
+ else if (code == SET
&& GET_CODE (SET_DEST (x)) == PC)
{
if (refers_to_regno_p (regno, regno+1,
@@ -3366,7 +3626,7 @@ reg_used_in_mem_p (regno, x)
if (fmt[i] == 'e'
&& reg_used_in_mem_p (regno, XEXP (x, i)))
return 1;
-
+
else if (fmt[i] == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
@@ -3378,13 +3638,14 @@ reg_used_in_mem_p (regno, x)
/* Returns true if expression DEP_RTX sets an address register
used by instruction INSN to address memory. */
-static int
-addr_generation_dependency_p (dep_rtx, insn)
- rtx dep_rtx;
- rtx insn;
+static int
+addr_generation_dependency_p (rtx dep_rtx, rtx insn)
{
rtx target, pat;
+ if (GET_CODE (dep_rtx) == INSN)
+ dep_rtx = PATTERN (dep_rtx);
+
if (GET_CODE (dep_rtx) == SET)
{
target = SET_DEST (dep_rtx);
@@ -3397,7 +3658,7 @@ addr_generation_dependency_p (dep_rtx, insn)
{
int regno = REGNO (target);
- if (get_attr_type (insn) == TYPE_LA)
+ if (s390_safe_attr_type (insn) == TYPE_LA)
{
pat = PATTERN (insn);
if (GET_CODE (pat) == PARALLEL)
@@ -3411,31 +3672,48 @@ addr_generation_dependency_p (dep_rtx, insn)
else
abort();
}
- else if (get_attr_atype (insn) == ATYPE_MEM)
+ else if (get_attr_atype (insn) == ATYPE_AGEN)
return reg_used_in_mem_p (regno, PATTERN (insn));
}
}
return 0;
}
+/* Return 1, if dep_insn sets register used in insn in the agen unit. */
+
+int
+s390_agen_dep_p (rtx dep_insn, rtx insn)
+{
+ rtx dep_rtx = PATTERN (dep_insn);
+ int i;
+
+ if (GET_CODE (dep_rtx) == SET
+ && addr_generation_dependency_p (dep_rtx, insn))
+ return 1;
+ else if (GET_CODE (dep_rtx) == PARALLEL)
+ {
+ for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
+ {
+ if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
+ return 1;
+ }
+ }
+ return 0;
+}
/* Return the modified cost of the dependency of instruction INSN
- on instruction DEP_INSN through the link LINK. COST is the
+ on instruction DEP_INSN through the link LINK. COST is the
default cost of that dependency.
Data dependencies are all handled without delay. However, if a
- register is modified and subsequently used as base or index
+ register is modified and subsequently used as base or index
register of a memory reference, at least 4 cycles need to pass
- between setting and using the register to avoid pipeline stalls.
+ between setting and using the register to avoid pipeline stalls.
An exception is the LA instruction. An address generated by LA can
be used by introducing only a one cycle stall on the pipeline. */
static int
-s390_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
+s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
rtx dep_rtx;
int i;
@@ -3451,100 +3729,117 @@ s390_adjust_cost (insn, link, dep_insn, cost)
if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
return cost;
+ /* DFA based scheduling checks address dependency in md file. */
+ if (s390_use_dfa_pipeline_interface ())
+ {
+ /* Operand forward in case of lr, load and la. */
+ if (s390_tune == PROCESSOR_2084_Z990
+ && cost == 1
+ && (s390_safe_attr_type (dep_insn) == TYPE_LA
+ || s390_safe_attr_type (dep_insn) == TYPE_LR
+ || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
+ return 0;
+ return cost;
+ }
+
dep_rtx = PATTERN (dep_insn);
- if (GET_CODE (dep_rtx) == SET)
- {
- if (addr_generation_dependency_p (dep_rtx, insn))
- {
- cost += (get_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
- if (DEBUG_SCHED)
- {
- fprintf (stderr, "\n\nAddress dependency detected: cost %d\n",
- cost);
- debug_rtx (dep_insn);
- debug_rtx (insn);
- }
- }
- }
+ if (GET_CODE (dep_rtx) == SET
+ && addr_generation_dependency_p (dep_rtx, insn))
+ cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
else if (GET_CODE (dep_rtx) == PARALLEL)
{
for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
{
- if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i),
- insn))
- {
- cost += (get_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
- if (DEBUG_SCHED)
- {
- fprintf (stderr, "\n\nAddress dependency detected: cost %d\n"
- ,cost);
- debug_rtx (dep_insn);
- debug_rtx (insn);
- }
- }
+ if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
+ cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
}
}
return cost;
}
-
-
/* A C statement (sans semicolon) to update the integer scheduling priority
- INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
- increase the priority to execute INSN later. Do not define this macro if
- you do not need to adjust the scheduling priorities of insns.
+ INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
+ reduce the priority to execute INSN later. Do not define this macro if
+ you do not need to adjust the scheduling priorities of insns.
- A LA instruction maybe scheduled later, since the pipeline bypasses the
- calculated value. */
+ A STD instruction should be scheduled earlier,
+ in order to use the bypass. */
static int
-s390_adjust_priority (insn, priority)
- rtx insn ATTRIBUTE_UNUSED;
- int priority;
+s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
{
if (! INSN_P (insn))
return priority;
- if (GET_CODE (PATTERN (insn)) == USE
- || GET_CODE (PATTERN (insn)) == CLOBBER)
+ if (s390_tune != PROCESSOR_2084_Z990)
return priority;
-
- switch (get_attr_type (insn))
+
+ switch (s390_safe_attr_type (insn))
{
- default:
- break;
-
- case TYPE_LA:
- if (priority >= 0 && priority < 0x01000000)
- priority <<= 3;
- break;
- case TYPE_LM:
- /* LM in epilogue should never be scheduled. This
- is due to literal access done in function body.
- The usage of register 13 is not mentioned explicitly,
- leading to scheduling 'LM' accross this instructions.
- */
- priority = 0x7fffffff;
- break;
+ case TYPE_FSTORED:
+ case TYPE_FSTORES:
+ priority = priority << 3;
+ break;
+ case TYPE_STORE:
+ priority = priority << 1;
+ break;
+ default:
+ break;
}
-
return priority;
}
+/* The number of instructions that can be issued per cycle. */
+
+static int
+s390_issue_rate (void)
+{
+ if (s390_tune == PROCESSOR_2084_Z990)
+ return 3;
+ return 1;
+}
+
+/* If the following function returns TRUE, we will use the the DFA
+ insn scheduler. */
+
+static int
+s390_use_dfa_pipeline_interface (void)
+{
+ if (s390_tune == PROCESSOR_2064_Z900
+ || s390_tune == PROCESSOR_2084_Z990)
+ return 1;
+
+ return 0;
+}
+
+static int
+s390_first_cycle_multipass_dfa_lookahead (void)
+{
+ return s390_use_dfa_pipeline_interface () ? 4 : 0;
+}
+
+/* Called after issuing each insn.
+ Triggers default sort algorithm to better slot instructions. */
+
+static int
+s390_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ rtx *ready ATTRIBUTE_UNUSED,
+ int *pn_ready ATTRIBUTE_UNUSED,
+ int clock_var ATTRIBUTE_UNUSED)
+{
+ return s390_issue_rate();
+}
-/* Split all branches that exceed the maximum distance.
- Returns true if this created a new literal pool entry.
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. If this is
- done, TEMP_USED is set to true. */
+/* Split all branches that exceed the maximum distance.
+ Returns true if this created a new literal pool entry. */
-static int
-s390_split_branches (temp_reg, temp_used)
- rtx temp_reg;
- bool *temp_used;
+static int
+s390_split_branches (void)
{
+ rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
int new_literal = 0;
rtx insn, pat, tmp, target;
rtx *label;
@@ -3566,15 +3861,15 @@ s390_split_branches (temp_reg, temp_used)
if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
continue;
- if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
+ if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
{
label = &SET_SRC (pat);
- }
- else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
+ }
+ else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
{
- if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
+ if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
label = &XEXP (SET_SRC (pat), 1);
- else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
+ else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
label = &XEXP (SET_SRC (pat), 2);
else
continue;
@@ -3582,19 +3877,14 @@ s390_split_branches (temp_reg, temp_used)
else
continue;
- if (get_attr_length (insn) <= (TARGET_64BIT ? 6 : 4))
+ if (get_attr_length (insn) <= 4)
continue;
- *temp_used = 1;
-
- if (TARGET_64BIT)
- {
- tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, *label), insn);
- INSN_ADDRESSES_NEW (tmp, -1);
+ /* We are going to use the return register as scratch register,
+ make sure it will be saved/restored by the prologue/epilogue. */
+ cfun->machine->save_return_addr_p = 1;
- target = temp_reg;
- }
- else if (!flag_pic)
+ if (!flag_pic)
{
new_literal = 1;
tmp = force_const_mem (Pmode, *label);
@@ -3606,14 +3896,16 @@ s390_split_branches (temp_reg, temp_used)
else
{
new_literal = 1;
- tmp = gen_rtx_UNSPEC (SImode, gen_rtvec (1, *label), 104);
- tmp = gen_rtx_CONST (SImode, tmp);
- tmp = force_const_mem (SImode, tmp);
- tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
+ target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
+ UNSPEC_LTREL_OFFSET);
+ target = gen_rtx_CONST (Pmode, target);
+ target = force_const_mem (Pmode, target);
+ tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
INSN_ADDRESSES_NEW (tmp, -1);
- target = gen_rtx_REG (Pmode, BASE_REGISTER);
- target = gen_rtx_PLUS (Pmode, target, temp_reg);
+ target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (target, 0)),
+ UNSPEC_LTREL_BASE);
+ target = gen_rtx_PLUS (Pmode, temp_reg, target);
}
if (!validate_change (insn, label, target, 0))
@@ -3624,22 +3916,29 @@ s390_split_branches (temp_reg, temp_used)
}
-/* Find a literal pool symbol referenced in RTX X, and store
- it at REF. Will abort if X contains references to more than
+/* Find a literal pool symbol referenced in RTX X, and store
+ it at REF. Will abort if X contains references to more than
one such pool symbol; multiple references to the same symbol
- are allowed, however.
+ are allowed, however.
- The rtx pointed to by REF must be initialized to NULL_RTX
+ The rtx pointed to by REF must be initialized to NULL_RTX
by the caller before calling this routine. */
static void
-find_constant_pool_ref (x, ref)
- rtx x;
- rtx *ref;
+find_constant_pool_ref (rtx x, rtx *ref)
{
int i, j;
const char *fmt;
+ /* Ignore LTREL_BASE references. */
+ if (GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_LTREL_BASE)
+ return;
+ /* Likewise POOL_ENTRY insns. */
+ if (GET_CODE (x) == UNSPEC_VOLATILE
+ && XINT (x, 1) == UNSPECV_POOL_ENTRY)
+ return;
+
if (GET_CODE (x) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x))
{
@@ -3668,10 +3967,7 @@ find_constant_pool_ref (x, ref)
in X by the address ADDR. Fix up MEMs as required. */
static void
-replace_constant_pool_ref (x, ref, addr)
- rtx *x;
- rtx ref;
- rtx addr;
+replace_constant_pool_ref (rtx *x, rtx ref, rtx addr)
{
int i, j;
const char *fmt;
@@ -3738,135 +4034,55 @@ replace_constant_pool_ref (x, ref, addr)
}
}
-/* Check whether ADDR is an address that uses the base register,
- without actually constituting a literal pool access. (This happens
- in 31-bit PIC mode, where the base register is used as anchor for
- relative addressing of local symbols.)
-
- Returns 1 if the base register occupies the base slot,
- returns 2 if the base register occupies the index slot,
- returns 0 if the address is not of this form. */
-
-static int
-find_base_register_in_addr (addr)
- struct s390_address *addr;
-{
- /* If DISP is complex, we might have a literal pool reference. */
- if (addr->disp && GET_CODE (addr->disp) != CONST_INT)
- return 0;
-
- if (addr->base && REG_P (addr->base) && REGNO (addr->base) == BASE_REGISTER)
- return 1;
-
- if (addr->indx && REG_P (addr->indx) && REGNO (addr->indx) == BASE_REGISTER)
- return 2;
+/* Check whether X contains an UNSPEC_LTREL_BASE.
+ Return its constant pool symbol if found, NULL_RTX otherwise. */
- return 0;
-}
-
-/* Return true if X contains an address that uses the base register,
- without actually constituting a literal pool access. */
-
-static bool
-find_base_register_ref (x)
- rtx x;
+static rtx
+find_ltrel_base (rtx x)
{
- bool retv = FALSE;
- struct s390_address addr;
int i, j;
const char *fmt;
- /* Addresses can only occur inside a MEM ... */
- if (GET_CODE (x) == MEM)
- {
- if (s390_decompose_address (XEXP (x, 0), &addr)
- && find_base_register_in_addr (&addr))
- return TRUE;
- }
-
- /* ... or a load-address type pattern. */
- if (GET_CODE (x) == SET && GET_CODE (SET_DEST (x)) == REG)
- {
- if (s390_decompose_address (SET_SRC (x), &addr)
- && find_base_register_in_addr (&addr))
- return TRUE;
- }
+ if (GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_LTREL_BASE)
+ return XVECEXP (x, 0, 0);
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
- retv |= find_base_register_ref (XEXP (x, i));
+ rtx fnd = find_ltrel_base (XEXP (x, i));
+ if (fnd)
+ return fnd;
}
else if (fmt[i] == 'E')
{
for (j = 0; j < XVECLEN (x, i); j++)
- retv |= find_base_register_ref (XVECEXP (x, i, j));
+ {
+ rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
+ if (fnd)
+ return fnd;
+ }
}
}
- return retv;
+ return NULL_RTX;
}
-/* If X contains an address that uses the base register,
- without actually constituting a literal pool access,
- replace the base register with REPL in all such cases.
-
- Handles both MEMs and load address patterns. */
+/* Replace any occurrence of UNSPEC_LTREL_BASE in X with BASE. */
static void
-replace_base_register_ref (x, repl)
- rtx *x;
- rtx repl;
+replace_ltrel_base (rtx *x, rtx base)
{
- struct s390_address addr;
- rtx new_addr;
- int i, j, pos;
+ int i, j;
const char *fmt;
- /* Addresses can only occur inside a MEM ... */
- if (GET_CODE (*x) == MEM)
- {
- if (s390_decompose_address (XEXP (*x, 0), &addr)
- && (pos = find_base_register_in_addr (&addr)))
- {
- if (pos == 1)
- addr.base = repl;
- else
- addr.indx = repl;
-
- new_addr = addr.base;
- if (addr.indx)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
- if (addr.disp)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
-
- *x = replace_equiv_address (*x, new_addr);
- return;
- }
- }
-
- /* ... or a load-address type pattern. */
- if (GET_CODE (*x) == SET && GET_CODE (SET_DEST (*x)) == REG)
+ if (GET_CODE (*x) == UNSPEC
+ && XINT (*x, 1) == UNSPEC_LTREL_BASE)
{
- if (s390_decompose_address (SET_SRC (*x), &addr)
- && (pos = find_base_register_in_addr (&addr)))
- {
- if (pos == 1)
- addr.base = repl;
- else
- addr.indx = repl;
-
- new_addr = addr.base;
- if (addr.indx)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
- if (addr.disp)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
-
- SET_SRC (*x) = new_addr;
- return;
- }
+ *x = base;
+ return;
}
fmt = GET_RTX_FORMAT (GET_CODE (*x));
@@ -3874,37 +4090,30 @@ replace_base_register_ref (x, repl)
{
if (fmt[i] == 'e')
{
- replace_base_register_ref (&XEXP (*x, i), repl);
+ replace_ltrel_base (&XEXP (*x, i), base);
}
else if (fmt[i] == 'E')
{
for (j = 0; j < XVECLEN (*x, i); j++)
- replace_base_register_ref (&XVECEXP (*x, i, j), repl);
+ replace_ltrel_base (&XVECEXP (*x, i, j), base);
}
}
}
-/* We keep a list of constants we which we have to add to internal
+/* We keep a list of constants which we have to add to internal
constant tables in the middle of large functions. */
-#define NR_C_MODES 6
-enum machine_mode constant_modes[NR_C_MODES] =
+#define NR_C_MODES 7
+enum machine_mode constant_modes[NR_C_MODES] =
{
+ TImode,
DFmode, DImode,
SFmode, SImode,
HImode,
QImode
};
-rtx (*gen_consttable[NR_C_MODES])(rtx) =
-{
- gen_consttable_df, gen_consttable_di,
- gen_consttable_sf, gen_consttable_si,
- gen_consttable_hi,
- gen_consttable_qi
-};
-
struct constant
{
struct constant *next;
@@ -3922,45 +4131,36 @@ struct constant_pool
struct constant *constants[NR_C_MODES];
rtx label;
int size;
- bool anchor;
};
-static struct constant_pool * s390_chunkify_start PARAMS ((rtx, bool *));
-static void s390_chunkify_finish PARAMS ((struct constant_pool *, rtx));
-static void s390_chunkify_cancel PARAMS ((struct constant_pool *));
+static struct constant_pool * s390_mainpool_start (void);
+static void s390_mainpool_finish (struct constant_pool *, rtx base_reg);
+static void s390_mainpool_cancel (struct constant_pool *);
+
+static struct constant_pool * s390_chunkify_start (rtx base_reg);
+static void s390_chunkify_finish (struct constant_pool *, rtx base_reg);
+static void s390_chunkify_cancel (struct constant_pool *);
-static struct constant_pool *s390_start_pool PARAMS ((struct constant_pool **, rtx));
-static void s390_end_pool PARAMS ((struct constant_pool *, rtx));
-static void s390_add_pool_insn PARAMS ((struct constant_pool *, rtx));
-static struct constant_pool *s390_find_pool PARAMS ((struct constant_pool *, rtx));
-static void s390_add_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
-static rtx s390_find_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
-static void s390_add_anchor PARAMS ((struct constant_pool *));
-static rtx s390_dump_pool PARAMS ((struct constant_pool *));
-static void s390_free_pool PARAMS ((struct constant_pool *));
+static struct constant_pool *s390_start_pool (struct constant_pool **, rtx);
+static void s390_end_pool (struct constant_pool *, rtx);
+static void s390_add_pool_insn (struct constant_pool *, rtx);
+static struct constant_pool *s390_find_pool (struct constant_pool *, rtx);
+static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode);
+static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode);
+static rtx s390_dump_pool (struct constant_pool *, bool);
+static struct constant_pool *s390_alloc_pool (void);
+static void s390_free_pool (struct constant_pool *);
/* Create new constant pool covering instructions starting at INSN
and chain it to the end of POOL_LIST. */
static struct constant_pool *
-s390_start_pool (pool_list, insn)
- struct constant_pool **pool_list;
- rtx insn;
+s390_start_pool (struct constant_pool **pool_list, rtx insn)
{
struct constant_pool *pool, **prev;
- int i;
- pool = (struct constant_pool *) xmalloc (sizeof *pool);
- pool->next = NULL;
- for (i = 0; i < NR_C_MODES; i++)
- pool->constants[i] = NULL;
-
- pool->label = gen_label_rtx ();
+ pool = s390_alloc_pool ();
pool->first_insn = insn;
- pool->pool_insn = NULL_RTX;
- pool->insns = BITMAP_XMALLOC ();
- pool->size = 0;
- pool->anchor = FALSE;
for (prev = pool_list; *prev; prev = &(*prev)->next)
;
@@ -3973,9 +4173,7 @@ s390_start_pool (pool_list, insn)
placeholder insn representing the pool. */
static void
-s390_end_pool (pool, insn)
- struct constant_pool *pool;
- rtx insn;
+s390_end_pool (struct constant_pool *pool, rtx insn)
{
rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
@@ -3989,9 +4187,7 @@ s390_end_pool (pool, insn)
/* Add INSN to the list of insns covered by POOL. */
static void
-s390_add_pool_insn (pool, insn)
- struct constant_pool *pool;
- rtx insn;
+s390_add_pool_insn (struct constant_pool *pool, rtx insn)
{
bitmap_set_bit (pool->insns, INSN_UID (insn));
}
@@ -3999,9 +4195,7 @@ s390_add_pool_insn (pool, insn)
/* Return pool out of POOL_LIST that covers INSN. */
static struct constant_pool *
-s390_find_pool (pool_list, insn)
- struct constant_pool *pool_list;
- rtx insn;
+s390_find_pool (struct constant_pool *pool_list, rtx insn)
{
struct constant_pool *pool;
@@ -4015,10 +4209,7 @@ s390_find_pool (pool_list, insn)
/* Add constant VAL of mode MODE to the constant pool POOL. */
static void
-s390_add_constant (pool, val, mode)
- struct constant_pool *pool;
- rtx val;
- enum machine_mode mode;
+s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
{
struct constant *c;
int i;
@@ -4047,77 +4238,55 @@ s390_add_constant (pool, val, mode)
/* Find constant VAL of mode MODE in the constant pool POOL.
Return an RTX describing the distance from the start of
the pool to the location of the new constant. */
-
+
static rtx
-s390_find_constant (pool, val, mode)
- struct constant_pool *pool;
- rtx val;
- enum machine_mode mode;
+s390_find_constant (struct constant_pool *pool, rtx val,
+ enum machine_mode mode)
{
struct constant *c;
rtx offset;
int i;
-
+
for (i = 0; i < NR_C_MODES; i++)
if (constant_modes[i] == mode)
break;
if (i == NR_C_MODES)
abort ();
-
+
for (c = pool->constants[i]; c != NULL; c = c->next)
if (rtx_equal_p (val, c->value))
break;
-
+
if (c == NULL)
abort ();
-
+
offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
gen_rtx_LABEL_REF (Pmode, pool->label));
offset = gen_rtx_CONST (Pmode, offset);
return offset;
}
-/* Set 'anchor' flag in POOL. */
-
-static void
-s390_add_anchor (pool)
- struct constant_pool *pool;
-{
- if (!pool->anchor)
- {
- pool->anchor = TRUE;
- pool->size += 4;
- }
-}
-
-/* Dump out the constants in POOL. */
+/* Dump out the constants in POOL. If REMOTE_LABEL is true,
+ do not emit the pool base label. */
static rtx
-s390_dump_pool (pool)
- struct constant_pool *pool;
+s390_dump_pool (struct constant_pool *pool, bool remote_label)
{
struct constant *c;
rtx insn;
int i;
- /* Pool start insn switches to proper section
+ /* Pool start insn switches to proper section
and guarantees necessary alignment. */
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
else
insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
INSN_ADDRESSES_NEW (insn, -1);
- insn = emit_label_after (pool->label, insn);
- INSN_ADDRESSES_NEW (insn, -1);
-
- /* Emit anchor if we need one. */
- if (pool->anchor)
+ if (!remote_label)
{
- rtx anchor = gen_rtx_LABEL_REF (VOIDmode, pool->label);
- anchor = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, anchor), 105);
- anchor = gen_rtx_CONST (VOIDmode, anchor);
- insn = emit_insn_after (gen_consttable_si (anchor), insn);
+ insn = emit_label_after (pool->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
}
@@ -4126,27 +4295,31 @@ s390_dump_pool (pool)
for (i = 0; i < NR_C_MODES; i++)
for (c = pool->constants[i]; c; c = c->next)
{
- /* Convert 104 unspecs to pool-relative references. */
+ /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
rtx value = c->value;
if (GET_CODE (value) == CONST
&& GET_CODE (XEXP (value, 0)) == UNSPEC
- && XINT (XEXP (value, 0), 1) == 104
+ && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
&& XVECLEN (XEXP (value, 0), 0) == 1)
{
value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
- gen_rtx_LABEL_REF (VOIDmode, pool->label));
+ gen_rtx_LABEL_REF (VOIDmode, pool->label));
value = gen_rtx_CONST (VOIDmode, value);
}
insn = emit_label_after (c->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
- insn = emit_insn_after (gen_consttable[i] (value), insn);
+
+ value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
+ gen_rtvec (1, value),
+ UNSPECV_POOL_ENTRY);
+ insn = emit_insn_after (value, insn);
INSN_ADDRESSES_NEW (insn, -1);
}
- /* Pool end insn switches back to previous section
+ /* Pool end insn switches back to previous section
and guarantees necessary alignment. */
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
insn = emit_insn_after (gen_pool_end_64 (), insn);
else
insn = emit_insn_after (gen_pool_end_31 (), insn);
@@ -4161,11 +4334,32 @@ s390_dump_pool (pool)
return insn;
}
+/* Allocate new constant_pool structure. */
+
+static struct constant_pool *
+s390_alloc_pool (void)
+{
+ struct constant_pool *pool;
+ int i;
+
+ pool = (struct constant_pool *) xmalloc (sizeof *pool);
+ pool->next = NULL;
+ for (i = 0; i < NR_C_MODES; i++)
+ pool->constants[i] = NULL;
+
+ pool->label = gen_label_rtx ();
+ pool->first_insn = NULL_RTX;
+ pool->pool_insn = NULL_RTX;
+ pool->insns = BITMAP_XMALLOC ();
+ pool->size = 0;
+
+ return pool;
+}
+
/* Free all memory used by POOL. */
static void
-s390_free_pool (pool)
- struct constant_pool *pool;
+s390_free_pool (struct constant_pool *pool)
{
int i;
@@ -4182,90 +4376,263 @@ s390_free_pool (pool)
BITMAP_XFREE (pool->insns);
free (pool);
-}
+}
+
+
+/* Collect main literal pool. Return NULL on overflow. */
+
+static struct constant_pool *
+s390_mainpool_start (void)
+{
+ struct constant_pool *pool;
+ rtx insn;
+
+ pool = s390_alloc_pool ();
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
+ && XINT (PATTERN (insn), 1) == UNSPECV_MAIN_POOL)
+ {
+ if (pool->pool_insn)
+ abort ();
+ pool->pool_insn = insn;
+ }
+
+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ {
+ rtx pool_ref = NULL_RTX;
+ find_constant_pool_ref (PATTERN (insn), &pool_ref);
+ if (pool_ref)
+ {
+ rtx constant = get_pool_constant (pool_ref);
+ enum machine_mode mode = get_pool_mode (pool_ref);
+ s390_add_constant (pool, constant, mode);
+ }
+ }
+ }
+
+ if (!pool->pool_insn)
+ abort ();
+
+ if (pool->size >= 4096)
+ {
+ /* We're going to chunkify the pool, so remove the main
+ pool placeholder insn. */
+ remove_insn (pool->pool_insn);
+
+ s390_free_pool (pool);
+ pool = NULL;
+ }
+
+ return pool;
+}
+
+/* POOL holds the main literal pool as collected by s390_mainpool_start.
+ Modify the current function to output the pool constants as well as
+ the pool register setup instruction. BASE_REG is the register to
+ be used as pool base register. */
+
+static void
+s390_mainpool_finish (struct constant_pool *pool, rtx base_reg)
+{
+ rtx insn;
+
+ /* If the pool is empty, we're done. */
+ if (pool->size == 0)
+ {
+ remove_insn (pool->pool_insn);
+ s390_free_pool (pool);
+ return;
+ }
+
+ /* We need correct insn addresses. */
+ shorten_branches (get_insns ());
+
+ /* On zSeries, we use a LARL to load the pool register. The pool is
+ located in the .rodata section, so we emit it after the function. */
+ if (TARGET_CPU_ZARCH)
+ {
+ insn = gen_main_base_64 (base_reg, pool->label);
+ insn = emit_insn_after (insn, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+ remove_insn (pool->pool_insn);
+
+ insn = get_last_insn ();
+ pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
+ INSN_ADDRESSES_NEW (pool->pool_insn, -1);
+
+ s390_dump_pool (pool, 0);
+ }
+
+ /* On S/390, if the total size of the function's code plus literal pool
+ does not exceed 4096 bytes, we use BASR to set up a function base
+ pointer, and emit the literal pool at the end of the function. */
+ else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
+ + pool->size + 8 /* alignment slop */ < 4096)
+ {
+ insn = gen_main_base_31_small (base_reg, pool->label);
+ insn = emit_insn_after (insn, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+ remove_insn (pool->pool_insn);
+
+ insn = emit_label_after (pool->label, insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+
+ insn = get_last_insn ();
+ pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
+ INSN_ADDRESSES_NEW (pool->pool_insn, -1);
+
+ s390_dump_pool (pool, 1);
+ }
+
+ /* Otherwise, we emit an inline literal pool and use BASR to branch
+ over it, setting up the pool register at the same time. */
+ else
+ {
+ rtx pool_end = gen_label_rtx ();
+
+ insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
+ insn = emit_insn_after (insn, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+ remove_insn (pool->pool_insn);
+
+ insn = emit_label_after (pool->label, insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+
+ pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
+ INSN_ADDRESSES_NEW (pool->pool_insn, -1);
+
+ insn = emit_label_after (pool_end, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+
+ s390_dump_pool (pool, 1);
+ }
+
+
+ /* Replace all literal pool references. */
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ replace_ltrel_base (&PATTERN (insn), base_reg);
+
+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ {
+ rtx addr, pool_ref = NULL_RTX;
+ find_constant_pool_ref (PATTERN (insn), &pool_ref);
+ if (pool_ref)
+ {
+ addr = s390_find_constant (pool, get_pool_constant (pool_ref),
+ get_pool_mode (pool_ref));
+ addr = gen_rtx_PLUS (Pmode, base_reg, addr);
+ replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
+ INSN_CODE (insn) = -1;
+ }
+ }
+ }
-/* Chunkify the literal pool if required.
+ /* Free the pool. */
+ s390_free_pool (pool);
+}
+
+/* POOL holds the main literal pool as collected by s390_mainpool_start.
+ We have decided we cannot use this pool, so revert all changes
+ to the current function that were done by s390_mainpool_start. */
+static void
+s390_mainpool_cancel (struct constant_pool *pool)
+{
+ /* We didn't actually change the instruction stream, so simply
+ free the pool memory. */
+ s390_free_pool (pool);
+}
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. If this is
- done, TEMP_USED is set to true. */
+
+/* Chunkify the literal pool. BASE_REG is to be used as pool
+ register. */
#define S390_POOL_CHUNK_MIN 0xc00
#define S390_POOL_CHUNK_MAX 0xe00
-static struct constant_pool *
-s390_chunkify_start (temp_reg, temp_used)
- rtx temp_reg;
- bool *temp_used;
+static struct constant_pool *
+s390_chunkify_start (rtx base_reg)
{
- rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
-
struct constant_pool *curr_pool = NULL, *pool_list = NULL;
int extra_size = 0;
bitmap far_labels;
+ rtx pending_ltrel = NULL_RTX;
rtx insn;
- rtx (*gen_reload_base) PARAMS ((rtx, rtx)) =
- TARGET_64BIT? gen_reload_base_64 : gen_reload_base_31;
-
+ rtx (*gen_reload_base) (rtx, rtx) =
+ TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
- /* Do we need to chunkify the literal pool? */
-
- if (get_pool_size () < S390_POOL_CHUNK_MAX)
- return NULL;
/* We need correct insn addresses. */
shorten_branches (get_insns ());
- /* Scan all insns and move literals to pool chunks.
- Also, emit anchor reload insns before every insn that uses
- the literal pool base register as anchor pointer. */
+ /* Scan all insns and move literals to pool chunks. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
+ /* Check for pending LTREL_BASE. */
+ if (INSN_P (insn))
+ {
+ rtx ltrel_base = find_ltrel_base (PATTERN (insn));
+ if (ltrel_base)
+ {
+ if (ltrel_base == pending_ltrel)
+ pending_ltrel = NULL_RTX;
+ else
+ abort ();
+ }
+ }
+
if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
{
rtx pool_ref = NULL_RTX;
find_constant_pool_ref (PATTERN (insn), &pool_ref);
if (pool_ref)
{
+ rtx constant = get_pool_constant (pool_ref);
+ enum machine_mode mode = get_pool_mode (pool_ref);
+
if (!curr_pool)
curr_pool = s390_start_pool (&pool_list, insn);
- s390_add_constant (curr_pool, get_pool_constant (pool_ref),
- get_pool_mode (pool_ref));
+ s390_add_constant (curr_pool, constant, mode);
s390_add_pool_insn (curr_pool, insn);
- }
- else if (!TARGET_64BIT && flag_pic
- && find_base_register_ref (PATTERN (insn)))
- {
- rtx new = gen_reload_anchor (temp_reg, base_reg);
- new = emit_insn_before (new, insn);
- INSN_ADDRESSES_NEW (new, INSN_ADDRESSES (INSN_UID (insn)));
- extra_size += 8;
- *temp_used = 1;
-
- if (!curr_pool)
- curr_pool = s390_start_pool (&pool_list, new);
-
- s390_add_anchor (curr_pool);
- s390_add_pool_insn (curr_pool, insn);
+ /* Don't split the pool chunk between a LTREL_OFFSET load
+ and the corresponding LTREL_BASE. */
+ if (GET_CODE (constant) == CONST
+ && GET_CODE (XEXP (constant, 0)) == UNSPEC
+ && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
+ {
+ if (pending_ltrel)
+ abort ();
+ pending_ltrel = pool_ref;
+ }
}
}
if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
- if (curr_pool)
- s390_add_pool_insn (curr_pool, insn);
+ {
+ if (curr_pool)
+ s390_add_pool_insn (curr_pool, insn);
+ /* An LTREL_BASE must follow within the same basic block. */
+ if (pending_ltrel)
+ abort ();
+ }
- if (!curr_pool
+ if (!curr_pool
|| INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
|| INSN_ADDRESSES (INSN_UID (insn)) == -1)
continue;
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
{
if (curr_pool->size < S390_POOL_CHUNK_MAX)
continue;
@@ -4276,7 +4643,7 @@ s390_chunkify_start (temp_reg, temp_used)
else
{
int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
- - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
+ - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
+ extra_size;
/* We will later have to insert base register reload insns.
@@ -4310,13 +4677,12 @@ s390_chunkify_start (temp_reg, temp_used)
if (get_attr_length (insn) == 0)
continue;
- /* Don't separate insns created by s390_split_branches. */
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET
- && rtx_equal_p (SET_DEST (PATTERN (insn)), temp_reg))
+ /* Don't separate LTREL_BASE from the corresponding
+ LTREL_OFFSET load. */
+ if (pending_ltrel)
continue;
- label = gen_label_rtx ();
+ label = gen_label_rtx ();
jump = emit_jump_insn_after (gen_jump (label), insn);
barrier = emit_barrier_after (jump);
insn = emit_label_after (label, barrier);
@@ -4336,9 +4702,11 @@ s390_chunkify_start (temp_reg, temp_used)
if (curr_pool)
s390_end_pool (curr_pool, NULL_RTX);
+ if (pending_ltrel)
+ abort ();
- /* Find all labels that are branched into
+ /* Find all labels that are branched into
from an insn belonging to a different chunk. */
far_labels = BITMAP_XMALLOC ();
@@ -4352,11 +4720,11 @@ s390_chunkify_start (temp_reg, temp_used)
Don't do that, however, if it is the label before
a jump table. */
- if (GET_CODE (insn) == CODE_LABEL
+ if (GET_CODE (insn) == CODE_LABEL
&& (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
{
rtx vec_insn = next_real_insn (insn);
- rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
+ rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
PATTERN (vec_insn) : NULL_RTX;
if (!vec_pat
|| !(GET_CODE (vec_pat) == ADDR_VEC
@@ -4366,22 +4734,22 @@ s390_chunkify_start (temp_reg, temp_used)
/* If we have a direct jump (conditional or unconditional)
or a casesi jump, check all potential targets. */
- else if (GET_CODE (insn) == JUMP_INSN)
+ else if (GET_CODE (insn) == JUMP_INSN)
{
rtx pat = PATTERN (insn);
if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
pat = XVECEXP (pat, 0, 0);
- if (GET_CODE (pat) == SET)
+ if (GET_CODE (pat) == SET)
{
rtx label = JUMP_LABEL (insn);
if (label)
{
- if (s390_find_pool (pool_list, label)
+ if (s390_find_pool (pool_list, label)
!= s390_find_pool (pool_list, insn))
bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
}
- }
+ }
else if (GET_CODE (pat) == PARALLEL
&& XVECLEN (pat, 0) == 2
&& GET_CODE (XVECEXP (pat, 0, 0)) == SET
@@ -4391,7 +4759,7 @@ s390_chunkify_start (temp_reg, temp_used)
/* Find the jump table used by this casesi jump. */
rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
rtx vec_insn = next_real_insn (vec_label);
- rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
+ rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
PATTERN (vec_insn) : NULL_RTX;
if (vec_pat
&& (GET_CODE (vec_pat) == ADDR_VEC
@@ -4403,7 +4771,7 @@ s390_chunkify_start (temp_reg, temp_used)
{
rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
- if (s390_find_pool (pool_list, label)
+ if (s390_find_pool (pool_list, label)
!= s390_find_pool (pool_list, insn))
bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
}
@@ -4424,7 +4792,7 @@ s390_chunkify_start (temp_reg, temp_used)
/* Insert base register reload insns at every far label. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == CODE_LABEL
+ if (GET_CODE (insn) == CODE_LABEL
&& bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
{
struct constant_pool *pool = s390_find_pool (pool_list, insn);
@@ -4448,26 +4816,24 @@ s390_chunkify_start (temp_reg, temp_used)
}
/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
- After we have decided to use this list, finish implementing
- all changes to the current function as required.
+ After we have decided to use this list, finish implementing
+ all changes to the current function as required. BASE_REG is
+ to be used as pool base register. */
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. */
-
static void
-s390_chunkify_finish (pool_list, temp_reg)
- struct constant_pool *pool_list;
- rtx temp_reg;
+s390_chunkify_finish (struct constant_pool *pool_list, rtx base_reg)
{
- rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
struct constant_pool *curr_pool = NULL;
rtx insn;
-
-
+
+
/* Replace all literal pool references. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
+ if (INSN_P (insn))
+ replace_ltrel_base (&PATTERN (insn), base_reg);
+
curr_pool = s390_find_pool (pool_list, insn);
if (!curr_pool)
continue;
@@ -4484,20 +4850,14 @@ s390_chunkify_finish (pool_list, temp_reg)
replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
INSN_CODE (insn) = -1;
}
-
- else if (!TARGET_64BIT && flag_pic
- && find_base_register_ref (PATTERN (insn)))
- {
- replace_base_register_ref (&PATTERN (insn), temp_reg);
- }
}
}
/* Dump out all literal pools. */
-
+
for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
- s390_dump_pool (curr_pool);
-
+ s390_dump_pool (curr_pool, 0);
+
/* Free pool list. */
while (pool_list)
@@ -4511,10 +4871,9 @@ s390_chunkify_finish (pool_list, temp_reg)
/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
We have decided we cannot use this list, so revert all changes
to the current function that were done by s390_chunkify_start. */
-
+
static void
-s390_chunkify_cancel (pool_list)
- struct constant_pool *pool_list;
+s390_chunkify_cancel (struct constant_pool *pool_list)
{
struct constant_pool *curr_pool = NULL;
rtx insn;
@@ -4544,7 +4903,7 @@ s390_chunkify_cancel (pool_list)
remove_insn (curr_pool->pool_insn);
}
- /* Remove all base/anchor register reload insns. */
+ /* Remove all base register reload insns. */
for (insn = get_insns (); insn; )
{
@@ -4553,8 +4912,7 @@ s390_chunkify_cancel (pool_list)
if (GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) == SET
&& GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
- && (XINT (SET_SRC (PATTERN (insn)), 1) == 210
- || XINT (SET_SRC (PATTERN (insn)), 1) == 211))
+ && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
remove_insn (insn);
insn = next_insn;
@@ -4571,98 +4929,80 @@ s390_chunkify_cancel (pool_list)
}
-/* Index of constant pool chunk that is currently being processed.
- Set to -1 before function output has started. */
-int s390_pool_count = -1;
-
-/* Number of elements of current constant pool. */
-int s390_nr_constants;
-
-/* Output main constant pool to stdio stream FILE. */
+/* Output to FILE the constant pool entry EXP in mode MODE
+ with alignment ALIGN. */
void
-s390_output_constant_pool (start_label, end_label)
- rtx start_label;
- rtx end_label;
+s390_output_pool_entry (FILE *file, rtx exp, enum machine_mode mode,
+ unsigned int align)
{
- if (TARGET_64BIT)
- {
- readonly_data_section ();
- ASM_OUTPUT_ALIGN (asm_out_file, 3);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (start_label));
- }
- else
- {
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (start_label));
- ASM_OUTPUT_ALIGN (asm_out_file, 2);
- }
+ REAL_VALUE_TYPE r;
- s390_pool_count = 0;
- output_constant_pool (current_function_name, current_function_decl);
- s390_pool_count = -1;
- if (TARGET_64BIT)
- function_section (current_function_decl);
- else
+ switch (GET_MODE_CLASS (mode))
{
- ASM_OUTPUT_ALIGN (asm_out_file, 1);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (end_label));
+ case MODE_FLOAT:
+ if (GET_CODE (exp) != CONST_DOUBLE)
+ abort ();
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
+ assemble_real (r, mode, align);
+ break;
+
+ case MODE_INT:
+ if (GET_CODE (exp) == CONST
+ || GET_CODE (exp) == SYMBOL_REF
+ || GET_CODE (exp) == LABEL_REF)
+ {
+ fputs (integer_asm_op (GET_MODE_SIZE (mode), TRUE), file);
+ s390_output_symbolic_const (file, exp);
+ fputc ('\n', file);
+ }
+ else
+ {
+ assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
+ }
+ break;
+
+ default:
+ abort ();
}
}
+
/* Rework the prolog/epilog to avoid saving/restoring
- registers unnecessarily. If TEMP_REGNO is nonnegative,
- it specifies the number of a caller-saved register used
- as temporary scratch register by code emitted during
- machine dependent reorg. */
+ registers unnecessarily. BASE_USED specifies whether
+ the literal pool base register needs to be saved. */
static void
-s390_optimize_prolog (temp_regno)
- int temp_regno;
+s390_optimize_prolog (bool base_used)
{
int save_first, save_last, restore_first, restore_last;
int i, j;
rtx insn, new_insn, next_insn;
/* Recompute regs_ever_live data for special registers. */
- regs_ever_live[BASE_REGISTER] = 0;
- regs_ever_live[RETURN_REGNUM] = 0;
+ regs_ever_live[BASE_REGISTER] = base_used;
+ regs_ever_live[RETURN_REGNUM] = cfun->machine->save_return_addr_p;
regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
- /* If there is (possibly) any pool entry, we need to
- load the base register.
- ??? FIXME: this should be more precise. */
- if (get_pool_size ())
- regs_ever_live[BASE_REGISTER] = 1;
-
- /* In non-leaf functions, the prolog/epilog code relies
- on RETURN_REGNUM being saved in any case. */
- if (!current_function_is_leaf)
- regs_ever_live[RETURN_REGNUM] = 1;
-
- /* We need to save/restore the temporary register. */
- if (temp_regno >= 0)
- regs_ever_live[temp_regno] = 1;
-
/* Find first and last gpr to be saved. */
-
+
for (i = 6; i < 16; i++)
if (regs_ever_live[i])
if (!global_regs[i]
- || i == STACK_POINTER_REGNUM
+ || i == STACK_POINTER_REGNUM
|| i == RETURN_REGNUM
- || i == BASE_REGISTER
+ || i == BASE_REGISTER
|| (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
break;
for (j = 15; j > i; j--)
if (regs_ever_live[j])
if (!global_regs[j]
- || j == STACK_POINTER_REGNUM
+ || j == STACK_POINTER_REGNUM
|| j == RETURN_REGNUM
- || j == BASE_REGISTER
+ || j == BASE_REGISTER
|| (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
break;
@@ -4691,7 +5031,7 @@ s390_optimize_prolog (temp_regno)
/* If all special registers are in fact used, there's nothing we
can do, so no point in walking the insn list. */
if (i <= BASE_REGISTER && j >= BASE_REGISTER
- && i <= RETURN_REGNUM && j >= RETURN_REGNUM)
+ && (TARGET_CPU_ZARCH || (i <= RETURN_REGNUM && j >= RETURN_REGNUM)))
return;
@@ -4706,10 +5046,9 @@ s390_optimize_prolog (temp_regno)
if (GET_CODE (insn) != INSN)
continue;
- if (GET_CODE (PATTERN (insn)) != PARALLEL)
- continue;
- if (store_multiple_operation (PATTERN (insn), VOIDmode))
+ if (GET_CODE (PATTERN (insn)) == PARALLEL
+ && store_multiple_operation (PATTERN (insn), VOIDmode))
{
set = XVECEXP (PATTERN (insn), 0, 0);
first = REGNO (SET_SRC (set));
@@ -4720,9 +5059,31 @@ s390_optimize_prolog (temp_regno)
if (GET_CODE (base) != REG || off < 0)
continue;
- if (first > BASE_REGISTER && first > RETURN_REGNUM)
+ if (first > BASE_REGISTER || last < BASE_REGISTER)
continue;
- if (last < BASE_REGISTER && last < RETURN_REGNUM)
+
+ if (save_first != -1)
+ {
+ new_insn = save_gprs (base, off, save_first, save_last);
+ new_insn = emit_insn_before (new_insn, insn);
+ INSN_ADDRESSES_NEW (new_insn, -1);
+ }
+
+ remove_insn (insn);
+ continue;
+ }
+
+ if (GET_CODE (PATTERN (insn)) == SET
+ && GET_CODE (SET_SRC (PATTERN (insn))) == REG
+ && REGNO (SET_SRC (PATTERN (insn))) == BASE_REGISTER
+ && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
+ {
+ set = PATTERN (insn);
+ offset = const0_rtx;
+ base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
+ off = INTVAL (offset) - BASE_REGISTER * UNITS_PER_WORD;
+
+ if (GET_CODE (base) != REG || off < 0)
continue;
if (save_first != -1)
@@ -4733,9 +5094,11 @@ s390_optimize_prolog (temp_regno)
}
remove_insn (insn);
+ continue;
}
- if (load_multiple_operation (PATTERN (insn), VOIDmode))
+ if (GET_CODE (PATTERN (insn)) == PARALLEL
+ && load_multiple_operation (PATTERN (insn), VOIDmode))
{
set = XVECEXP (PATTERN (insn), 0, 0);
first = REGNO (SET_DEST (set));
@@ -4746,9 +5109,7 @@ s390_optimize_prolog (temp_regno)
if (GET_CODE (base) != REG || off < 0)
continue;
- if (first > BASE_REGISTER && first > RETURN_REGNUM)
- continue;
- if (last < BASE_REGISTER && last < RETURN_REGNUM)
+ if (first > BASE_REGISTER || last < BASE_REGISTER)
continue;
if (restore_first != -1)
@@ -4759,103 +5120,80 @@ s390_optimize_prolog (temp_regno)
}
remove_insn (insn);
+ continue;
}
- }
-}
-
-/* Check whether any insn in the function makes use of the original
- value of RETURN_REG (e.g. for __builtin_return_address).
- If so, insert an insn reloading that value.
-
- Return true if any such insn was found. */
-
-static bool
-s390_fixup_clobbered_return_reg (return_reg)
- rtx return_reg;
-{
- bool replacement_done = 0;
- rtx insn;
-
- /* If we never called __builtin_return_address, register 14
- might have been used as temp during the prolog; we do
- not want to touch those uses. */
- if (!has_hard_reg_initial_val (Pmode, REGNO (return_reg)))
- return false;
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- rtx reg, off, new_insn;
+ if (GET_CODE (PATTERN (insn)) == SET
+ && GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ && REGNO (SET_DEST (PATTERN (insn))) == BASE_REGISTER
+ && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
+ {
+ set = PATTERN (insn);
+ offset = const0_rtx;
+ base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
+ off = INTVAL (offset) - BASE_REGISTER * UNITS_PER_WORD;
- if (GET_CODE (insn) != INSN)
- continue;
- if (!reg_referenced_p (return_reg, PATTERN (insn)))
- continue;
- if (GET_CODE (PATTERN (insn)) == PARALLEL
- && store_multiple_operation (PATTERN (insn), VOIDmode))
- continue;
+ if (GET_CODE (base) != REG || off < 0)
+ continue;
- if (frame_pointer_needed)
- reg = hard_frame_pointer_rtx;
- else
- reg = stack_pointer_rtx;
+ if (restore_first != -1)
+ {
+ new_insn = restore_gprs (base, off, restore_first, restore_last);
+ new_insn = emit_insn_before (new_insn, insn);
+ INSN_ADDRESSES_NEW (new_insn, -1);
+ }
- off = GEN_INT (cfun->machine->frame_size + REGNO (return_reg) * UNITS_PER_WORD);
- if (INTVAL (off) >= 4096)
- {
- off = force_const_mem (Pmode, off);
- new_insn = gen_rtx_SET (Pmode, return_reg, off);
- new_insn = emit_insn_before (new_insn, insn);
- INSN_ADDRESSES_NEW (new_insn, -1);
- off = return_reg;
+ remove_insn (insn);
+ continue;
}
-
- new_insn = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, reg, off));
- new_insn = gen_rtx_SET (Pmode, return_reg, new_insn);
- new_insn = emit_insn_before (new_insn, insn);
- INSN_ADDRESSES_NEW (new_insn, -1);
-
- replacement_done = 1;
}
-
- return replacement_done;
}
/* Perform machine-dependent processing. */
-void
-s390_machine_dependent_reorg (first)
- rtx first ATTRIBUTE_UNUSED;
+static void
+s390_reorg (void)
{
- bool fixed_up_clobbered_return_reg = 0;
- rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
- bool temp_used = 0;
+ rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
+ bool base_used = false;
+ bool pool_overflow = false;
/* Make sure all splits have been performed; splits after
machine_dependent_reorg might confuse insn length counts. */
split_all_insns_noflow ();
- /* There are two problematic situations we need to correct:
-
+ /* In small leaf functions, try to use an unused call-clobbered
+ register as base register to avoid save/restore overhead. */
+ if (current_function_is_leaf && !regs_ever_live[5])
+ base_reg = gen_rtx_REG (Pmode, 5);
+
+
+ /* Install the main literal pool and the associated base
+ register load insns.
+
+ In addition, there are two problematic situations we need
+ to correct:
+
- the literal pool might be > 4096 bytes in size, so that
some of its elements cannot be directly accessed
-
+
- a branch target might be > 64K away from the branch, so that
it is not possible to use a PC-relative instruction.
-
+
To fix those, we split the single literal pool into multiple
pool chunks, reloading the pool base register at various
points throughout the function to ensure it always points to
the pool chunk the following code expects, and / or replace
PC-relative branches by absolute branches.
-
+
However, the two problems are interdependent: splitting the
literal pool can move a branch further away from its target,
causing the 64K limit to overflow, and on the other hand,
replacing a PC-relative branch by an absolute branch means
we need to put the branch target address into the literal
pool, possibly causing it to overflow.
-
+
So, we loop trying to fix up both problems until we manage
to satisfy both conditions at the same time. Note that the
loop is guaranteed to terminate as every pass of the loop
@@ -4863,49 +5201,52 @@ s390_machine_dependent_reorg (first)
in the function. (This is not completely true as there
might be branch-over-pool insns introduced by chunkify_start.
Those never need to be split however.) */
-
+
for (;;)
{
- struct constant_pool *pool_list;
-
- /* Try to chunkify the literal pool. */
- pool_list = s390_chunkify_start (temp_reg, &temp_used);
+ struct constant_pool *pool = NULL;
+
+ /* Collect the literal pool. */
+ if (!pool_overflow)
+ {
+ pool = s390_mainpool_start ();
+ if (!pool)
+ pool_overflow = true;
+ }
+
+ /* If literal pool overflowed, start to chunkify it. */
+ if (pool_overflow)
+ pool = s390_chunkify_start (base_reg);
/* Split out-of-range branches. If this has created new
literal pool entries, cancel current chunk list and
- recompute it. */
- if (s390_split_branches (temp_reg, &temp_used))
+ recompute it. zSeries machines have large branch
+ instructions, so we never need to split a branch. */
+ if (!TARGET_CPU_ZARCH && s390_split_branches ())
{
- if (pool_list)
- s390_chunkify_cancel (pool_list);
-
+ if (pool_overflow)
+ s390_chunkify_cancel (pool);
+ else
+ s390_mainpool_cancel (pool);
+
continue;
}
- /* Check whether we have clobbered a use of the return
- register (e.g. for __builtin_return_address). If so,
- add insns reloading the register where necessary. */
- if (temp_used && !fixed_up_clobbered_return_reg
- && s390_fixup_clobbered_return_reg (temp_reg))
- {
- fixed_up_clobbered_return_reg = 1;
+ /* If we made it up to here, both conditions are satisfied.
+ Finish up literal pool related changes. */
+ if ((pool_overflow || pool->size > 0)
+ && REGNO (base_reg) == BASE_REGISTER)
+ base_used = true;
- /* The fixup insns might have caused a jump to overflow. */
- if (pool_list)
- s390_chunkify_cancel (pool_list);
+ if (pool_overflow)
+ s390_chunkify_finish (pool, base_reg);
+ else
+ s390_mainpool_finish (pool, base_reg);
- continue;
- }
-
- /* If we made it up to here, both conditions are satisfied.
- Finish up pool chunkification if required. */
- if (pool_list)
- s390_chunkify_finish (pool_list, temp_reg);
-
break;
}
-
- s390_optimize_prolog (temp_used? RETURN_REGNUM : -1);
+
+ s390_optimize_prolog (base_used);
}
@@ -4914,32 +5255,35 @@ s390_machine_dependent_reorg (first)
frame pointer of that frame. */
rtx
-s390_return_addr_rtx (count, frame)
- int count;
- rtx frame;
+s390_return_addr_rtx (int count, rtx frame)
{
rtx addr;
- /* For the current frame, we use the initial value of RETURN_REGNUM.
- This works both in leaf and non-leaf functions. */
+ /* Without backchain, we fail for all but the current frame. */
+
+ if (!TARGET_BACKCHAIN && count > 0)
+ return NULL_RTX;
+
+ /* For the current frame, we need to make sure the initial
+ value of RETURN_REGNUM is actually saved. */
if (count == 0)
- return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
+ cfun->machine->save_return_addr_p = true;
- /* For frames farther back, we read the stack slot where the
+ /* To retrieve the return address we read the stack slot where the
corresponding RETURN_REGNUM value was saved. */
addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
addr = memory_address (Pmode, addr);
return gen_rtx_MEM (Pmode, addr);
-}
+}
/* Find first call clobbered register unsused in a function.
This could be used as base register in a leaf function
or for holding the return address before epilogue. */
static int
-find_unused_clobbered_reg ()
+find_unused_clobbered_reg (void)
{
int i;
for (i = 0; i < 6; i++)
@@ -4951,19 +5295,18 @@ find_unused_clobbered_reg ()
/* Fill FRAME with info about frame of current function. */
static void
-s390_frame_info ()
+s390_frame_info (void)
{
- char gprs_ever_live[16];
int i, j;
HOST_WIDE_INT fsize = get_frame_size ();
- if (fsize > 0x7fff0000)
+ if (!TARGET_64BIT && fsize > 0x7fff0000)
fatal_error ("Total size of local variables exceeds architecture limit.");
/* fprs 8 - 15 are caller saved for 64 Bit ABI. */
cfun->machine->save_fprs_p = 0;
if (TARGET_64BIT)
- for (i = 24; i < 32; i++)
+ for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
{
cfun->machine->save_fprs_p = 1;
@@ -4973,38 +5316,49 @@ s390_frame_info ()
cfun->machine->frame_size = fsize + cfun->machine->save_fprs_p * 64;
/* Does function need to setup frame and save area. */
-
+
if (! current_function_is_leaf
|| cfun->machine->frame_size > 0
- || current_function_calls_alloca
+ || current_function_calls_alloca
|| current_function_stdarg)
cfun->machine->frame_size += STARTING_FRAME_OFFSET;
+ /* If we use the return register, we'll need to make sure
+ it is going to be saved/restored. */
+
+ if (!current_function_is_leaf
+ || regs_ever_live[RETURN_REGNUM])
+ cfun->machine->save_return_addr_p = 1;
+
/* Find first and last gpr to be saved. Note that at this point,
- we assume the return register and the base register always
- need to be saved. This is done because the usage of these
+ we assume the base register and -on S/390- the return register
+ always need to be saved. This is done because the usage of these
register might change even after the prolog was emitted.
If it turns out later that we really don't need them, the
prolog/epilog code is modified again. */
- for (i = 0; i < 16; i++)
- gprs_ever_live[i] = regs_ever_live[i] && !global_regs[i];
+ regs_ever_live[BASE_REGISTER] = 1;
+ if (!TARGET_CPU_ZARCH || cfun->machine->save_return_addr_p)
+ regs_ever_live[RETURN_REGNUM] = 1;
+ regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
- if (flag_pic)
- gprs_ever_live[PIC_OFFSET_TABLE_REGNUM] =
- regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
- gprs_ever_live[BASE_REGISTER] = 1;
- gprs_ever_live[RETURN_REGNUM] = 1;
- gprs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
-
for (i = 6; i < 16; i++)
- if (gprs_ever_live[i])
- break;
+ if (regs_ever_live[i])
+ if (!global_regs[i]
+ || i == STACK_POINTER_REGNUM
+ || i == RETURN_REGNUM
+ || i == BASE_REGISTER
+ || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
+ break;
for (j = 15; j > i; j--)
- if (gprs_ever_live[j])
- break;
-
+ if (regs_ever_live[j])
+ if (!global_regs[j]
+ || j == STACK_POINTER_REGNUM
+ || j == RETURN_REGNUM
+ || j == BASE_REGISTER
+ || (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
+ break;
/* Save / Restore from gpr i to j. */
cfun->machine->first_save_gpr = i;
@@ -5016,11 +5370,11 @@ s390_frame_info ()
cfun->machine->first_save_gpr = 2;
}
-/* Return offset between argument pointer and frame pointer
+/* Return offset between argument pointer and frame pointer
initially after prologue. */
-int
-s390_arg_frame_offset ()
+HOST_WIDE_INT
+s390_arg_frame_offset (void)
{
HOST_WIDE_INT fsize = get_frame_size ();
int save_fprs_p, i;
@@ -5028,7 +5382,7 @@ s390_arg_frame_offset ()
/* fprs 8 - 15 are caller saved for 64 Bit ABI. */
save_fprs_p = 0;
if (TARGET_64BIT)
- for (i = 24; i < 32; i++)
+ for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
{
save_fprs_p = 1;
@@ -5038,23 +5392,20 @@ s390_arg_frame_offset ()
fsize = fsize + save_fprs_p * 64;
/* Does function need to setup frame and save area. */
-
+
if (! current_function_is_leaf
|| fsize > 0
- || current_function_calls_alloca
+ || current_function_calls_alloca
|| current_function_stdarg)
fsize += STARTING_FRAME_OFFSET;
return fsize + STACK_POINTER_OFFSET;
}
/* Emit insn to save fpr REGNUM at offset OFFSET relative
- to register BASE. Return generated insn. */
+ to register BASE. Return generated insn. */
static rtx
-save_fpr (base, offset, regnum)
- rtx base;
- int offset;
- int regnum;
+save_fpr (rtx base, int offset, int regnum)
{
rtx addr;
addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
@@ -5064,13 +5415,10 @@ save_fpr (base, offset, regnum)
}
/* Emit insn to restore fpr REGNUM from offset OFFSET relative
- to register BASE. Return generated insn. */
+ to register BASE. Return generated insn. */
static rtx
-restore_fpr (base, offset, regnum)
- rtx base;
- int offset;
- int regnum;
+restore_fpr (rtx base, int offset, int regnum)
{
rtx addr;
addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
@@ -5080,15 +5428,11 @@ restore_fpr (base, offset, regnum)
}
/* Generate insn to save registers FIRST to LAST into
- the register save area located at offset OFFSET
+ the register save area located at offset OFFSET
relative to register BASE. */
static rtx
-save_gprs (base, offset, first, last)
- rtx base;
- int offset;
- int first;
- int last;
+save_gprs (rtx base, int offset, int first, int last)
{
rtx addr, insn, note;
int i;
@@ -5119,7 +5463,7 @@ save_gprs (base, offset, first, last)
inside the store-multiple pattern.
However, we must not emit DWARF records for registers 2..5
- if they are stored for use by variable arguments ...
+ if they are stored for use by variable arguments ...
??? Unfortunately, it is not enough to simply not the the
FRAME_RELATED flags for those SETs, because the first SET
@@ -5140,13 +5484,13 @@ save_gprs (base, offset, first, last)
else if (last >= 6)
{
addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
- note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
+ note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
gen_rtx_REG (Pmode, 6),
GEN_INT (last - 6 + 1));
note = PATTERN (note);
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
note, REG_NOTES (insn));
for (i = 0; i < XVECLEN (note, 0); i++)
@@ -5160,15 +5504,11 @@ save_gprs (base, offset, first, last)
}
/* Generate insn to restore registers FIRST to LAST from
- the register save area located at offset OFFSET
+ the register save area located at offset OFFSET
relative to register BASE. */
static rtx
-restore_gprs (base, offset, first, last)
- rtx base;
- int offset;
- int first;
- int last;
+restore_gprs (rtx base, int offset, int first, int last)
{
rtx addr, insn;
@@ -5193,82 +5533,98 @@ restore_gprs (base, offset, first, last)
return insn;
}
+/* Emit code to load the GOT register. If MAYBE_DEAD is true,
+ annotate generated insns with REG_MAYBE_DEAD notes. */
+
+static GTY(()) rtx got_symbol;
+void
+s390_load_got (int maybe_dead)
+{
+ if (!got_symbol)
+ {
+ got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
+ }
+
+ if (TARGET_CPU_ZARCH)
+ {
+ rtx insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+ }
+ else
+ {
+ rtx offset, insn;
+
+ offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
+ UNSPEC_LTREL_OFFSET);
+ offset = gen_rtx_CONST (Pmode, offset);
+ offset = force_const_mem (Pmode, offset);
+
+ insn = emit_move_insn (pic_offset_table_rtx, offset);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+
+ offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
+ UNSPEC_LTREL_BASE);
+ offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
+
+ insn = emit_move_insn (pic_offset_table_rtx, offset);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+ }
+}
+
/* Expand the prologue into a bunch of separate insns. */
void
-s390_emit_prologue ()
+s390_emit_prologue (void)
{
rtx insn, addr;
rtx temp_reg;
- rtx pool_start_label, pool_end_label;
int i;
/* Compute frame_info. */
s390_frame_info ();
- /* Choose best register to use for temp use within prologue. */
-
+ /* Choose best register to use for temp use within prologue.
+ See below for why TPF must use the register 1. */
+
if (!current_function_is_leaf
- && !has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
- && get_pool_size () < S390_POOL_CHUNK_MAX / 2)
+ && !TARGET_TPF)
temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
else
temp_reg = gen_rtx_REG (Pmode, 1);
/* Save call saved gprs. */
- insn = save_gprs (stack_pointer_rtx, 0,
+ insn = save_gprs (stack_pointer_rtx, 0,
cfun->machine->first_save_gpr, cfun->machine->last_save_gpr);
emit_insn (insn);
- /* Dump constant pool and set constant pool register. */
+ /* Dummy insn to mark literal pool slot. */
+
+ emit_insn (gen_main_pool ());
- pool_start_label = gen_label_rtx();
- pool_end_label = gen_label_rtx();
- cfun->machine->literal_pool_label = pool_start_label;
-
- if (TARGET_64BIT)
- insn = emit_insn (gen_literal_pool_64 (gen_rtx_REG (Pmode, BASE_REGISTER),
- pool_start_label, pool_end_label));
- else
- insn = emit_insn (gen_literal_pool_31 (gen_rtx_REG (Pmode, BASE_REGISTER),
- pool_start_label, pool_end_label));
-
/* Save fprs for variable args. */
if (current_function_stdarg)
- {
- /* Save fpr 0 and 2. */
-
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 32, 16);
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 24, 17);
-
- if (TARGET_64BIT)
- {
- /* Save fpr 4 and 6. */
-
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19);
- }
- }
+ for (i = 16; i < (TARGET_64BIT ? 20 : 18); i++)
+ save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
/* Save fprs 4 and 6 if used (31 bit ABI). */
if (!TARGET_64BIT)
- {
- /* Save fpr 4 and 6. */
- if (regs_ever_live[18] && !global_regs[18])
- {
- insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- if (regs_ever_live[19] && !global_regs[19])
+ for (i = 18; i < 20; i++)
+ if (regs_ever_live[i] && !global_regs[i])
{
- insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19);
+ insn = save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
RTX_FRAME_RELATED_P (insn) = 1;
}
- }
/* Decrement stack pointer. */
@@ -5277,21 +5633,31 @@ s390_emit_prologue ()
rtx frame_off = GEN_INT (-cfun->machine->frame_size);
/* Save incoming stack pointer into temp reg. */
-
+
if (TARGET_BACKCHAIN || cfun->machine->save_fprs_p)
{
insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
}
-
- /* Substract frame size from stack pointer. */
- frame_off = GEN_INT (-cfun->machine->frame_size);
- if (!CONST_OK_FOR_LETTER_P (-cfun->machine->frame_size, 'K'))
- frame_off = force_const_mem (Pmode, frame_off);
+ /* Subtract frame size from stack pointer. */
+
+ if (DISP_IN_RANGE (INTVAL (frame_off)))
+ {
+ insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ frame_off));
+ insn = emit_insn (insn);
+ }
+ else
+ {
+ if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
+ frame_off = force_const_mem (Pmode, frame_off);
+
+ insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
+ }
- insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) =
+ REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
gen_rtx_SET (VOIDmode, stack_pointer_rtx,
gen_rtx_PLUS (Pmode, stack_pointer_rtx,
@@ -5299,7 +5665,7 @@ s390_emit_prologue ()
REG_NOTES (insn));
/* Set backchain. */
-
+
if (TARGET_BACKCHAIN)
{
addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
@@ -5319,7 +5685,7 @@ s390_emit_prologue ()
}
/* Save fprs 8 - 15 (64 bit ABI). */
-
+
if (cfun->machine->save_fprs_p)
{
insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
@@ -5327,22 +5693,22 @@ s390_emit_prologue ()
for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
{
- rtx addr = plus_constant (stack_pointer_rtx,
+ rtx addr = plus_constant (stack_pointer_rtx,
cfun->machine->frame_size - 64 + (i-24)*8);
insn = save_fpr (temp_reg, (i-24)*8, i);
RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) =
+ REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- gen_rtx_SET (VOIDmode,
+ gen_rtx_SET (VOIDmode,
gen_rtx_MEM (DFmode, addr),
gen_rtx_REG (DFmode, i)),
REG_NOTES (insn));
}
}
-
+
/* Set frame pointer, if needed. */
-
+
if (frame_pointer_needed)
{
insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
@@ -5350,54 +5716,70 @@ s390_emit_prologue ()
}
/* Set up got pointer, if needed. */
-
+
if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ s390_load_got(true);
+
+ if (TARGET_TPF)
{
- rtx got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
- SYMBOL_REF_FLAG (got_symbol) = 1;
+ /* Generate a BAS instruction to serve as a function
+ entry intercept to facilitate the use of tracing
+ algorithms located at the branch target.
- if (TARGET_64BIT)
- {
- insn = emit_insn (gen_movdi (pic_offset_table_rtx,
- got_symbol));
+ This must use register 1. */
+ rtx addr;
+ rtx unkn;
+ rtx link;
- /* It can happen that the GOT pointer isn't really needed ... */
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
- }
- else
- {
- got_symbol = gen_rtx_UNSPEC (VOIDmode,
- gen_rtvec (1, got_symbol), 100);
- got_symbol = gen_rtx_CONST (VOIDmode, got_symbol);
- got_symbol = force_const_mem (Pmode, got_symbol);
- insn = emit_move_insn (pic_offset_table_rtx,
- got_symbol);
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
-
- got_symbol = gen_rtx_REG (Pmode, BASE_REGISTER);
- got_symbol = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol), 101);
- got_symbol = gen_rtx_PLUS (Pmode, got_symbol, pic_offset_table_rtx);
- insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
- }
- }
+ addr = GEN_INT (0xfe0);
+ unkn = CONST0_RTX (SImode);
+ link = gen_rtx_REG (Pmode, 1);
+
+ emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
+
+ /* Emit a blockage here so that all code
+ lies between the profiling mechanisms. */
+ emit_insn (gen_blockage ());
+ }
}
/* Expand the epilogue into a bunch of separate insns. */
void
-s390_emit_epilogue ()
+s390_emit_epilogue (void)
{
rtx frame_pointer, return_reg;
int area_bottom, area_top, offset = 0;
rtvec p;
+ int i;
+
+ if (TARGET_TPF)
+ {
+
+ /* Generate a BAS instruction to serve as a function
+ entry intercept to facilitate the use of tracing
+ algorithms located at the branch target.
+
+ This must use register 1. */
+
+ rtx addr;
+ rtx unkn;
+ rtx link;
+
+ addr = GEN_INT (0xfe6);
+ unkn = CONST0_RTX (SImode);
+ link = gen_rtx_REG (Pmode, 1);
+
+ /* Emit a blockage here so that all code
+ lies between the profiling mechanisms. */
+ emit_insn (gen_blockage ());
+
+ emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
+ }
/* Check whether to use frame or stack pointer for restore. */
- frame_pointer = frame_pointer_needed ?
+ frame_pointer = frame_pointer_needed ?
hard_frame_pointer_rtx : stack_pointer_rtx;
/* Compute which parts of the save area we need to access. */
@@ -5425,31 +5807,25 @@ s390_emit_epilogue ()
}
else
{
- if (regs_ever_live[18] && !global_regs[18])
- {
- if (area_bottom > STACK_POINTER_OFFSET - 16)
- area_bottom = STACK_POINTER_OFFSET - 16;
- if (area_top < STACK_POINTER_OFFSET - 8)
- area_top = STACK_POINTER_OFFSET - 8;
- }
- if (regs_ever_live[19] && !global_regs[19])
- {
- if (area_bottom > STACK_POINTER_OFFSET - 8)
- area_bottom = STACK_POINTER_OFFSET - 8;
- if (area_top < STACK_POINTER_OFFSET)
- area_top = STACK_POINTER_OFFSET;
- }
+ for (i = 18; i < 20; i++)
+ if (regs_ever_live[i] && !global_regs[i])
+ {
+ if (area_bottom > 16*UNITS_PER_WORD + 8*(i-16))
+ area_bottom = 16*UNITS_PER_WORD + 8*(i-16);
+ if (area_top < 16*UNITS_PER_WORD + 8*(i-16) + 8)
+ area_top = 16*UNITS_PER_WORD + 8*(i-16) + 8;
+ }
}
- /* Check whether we can access the register save area.
+ /* Check whether we can access the register save area.
If not, increment the frame pointer as required. */
if (area_top <= area_bottom)
{
/* Nothing to restore. */
}
- else if (cfun->machine->frame_size + area_bottom >= 0
- && cfun->machine->frame_size + area_top <= 4096)
+ else if (DISP_IN_RANGE (cfun->machine->frame_size + area_bottom)
+ && DISP_IN_RANGE (cfun->machine->frame_size + area_top-1))
{
/* Area is in range. */
offset = cfun->machine->frame_size;
@@ -5458,38 +5834,45 @@ s390_emit_epilogue ()
{
rtx insn, frame_off;
- offset = area_bottom < 0 ? -area_bottom : 0;
+ offset = area_bottom < 0 ? -area_bottom : 0;
frame_off = GEN_INT (cfun->machine->frame_size - offset);
- if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
- frame_off = force_const_mem (Pmode, frame_off);
+ if (DISP_IN_RANGE (INTVAL (frame_off)))
+ {
+ insn = gen_rtx_SET (VOIDmode, frame_pointer,
+ gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
+ insn = emit_insn (insn);
+ }
+ else
+ {
+ if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
+ frame_off = force_const_mem (Pmode, frame_off);
- insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
+ insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
+ }
}
/* Restore call saved fprs. */
if (TARGET_64BIT)
{
- int i;
-
if (cfun->machine->save_fprs_p)
for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
- restore_fpr (frame_pointer,
+ restore_fpr (frame_pointer,
offset - 64 + (i-24) * 8, i);
}
else
{
- if (regs_ever_live[18] && !global_regs[18])
- restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 16, 18);
- if (regs_ever_live[19] && !global_regs[19])
- restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 8, 19);
+ for (i = 18; i < 20; i++)
+ if (regs_ever_live[i] && !global_regs[i])
+ restore_fpr (frame_pointer,
+ offset + 16*UNITS_PER_WORD + 8*(i-16), i);
}
/* Return register. */
- return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
+ return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
/* Restore call saved gprs. */
@@ -5498,43 +5881,45 @@ s390_emit_epilogue ()
rtx insn, addr;
int i;
- /* Check for global register and save them
+ /* Check for global register and save them
to stack location from where they get restored. */
- for (i = cfun->machine->first_restore_gpr;
+ for (i = cfun->machine->first_restore_gpr;
i <= cfun->machine->last_save_gpr;
i++)
{
- /* These registers are special and need to be
+ /* These registers are special and need to be
restored in any case. */
- if (i == STACK_POINTER_REGNUM
+ if (i == STACK_POINTER_REGNUM
|| i == RETURN_REGNUM
- || i == BASE_REGISTER
+ || i == BASE_REGISTER
|| (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
continue;
if (global_regs[i])
{
- addr = plus_constant (frame_pointer,
+ addr = plus_constant (frame_pointer,
offset + i * UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, s390_sr_alias_set);
emit_move_insn (addr, gen_rtx_REG (Pmode, i));
- }
+ }
}
/* Fetch return address from stack before load multiple,
this will do good for scheduling. */
- if (!current_function_is_leaf)
+ if (cfun->machine->save_return_addr_p
+ || (cfun->machine->first_restore_gpr < BASE_REGISTER
+ && cfun->machine->last_save_gpr > RETURN_REGNUM))
{
int return_regnum = find_unused_clobbered_reg();
if (!return_regnum)
return_regnum = 4;
return_reg = gen_rtx_REG (Pmode, return_regnum);
-
- addr = plus_constant (frame_pointer,
- offset + RETURN_REGNUM * UNITS_PER_WORD);
+
+ addr = plus_constant (frame_pointer,
+ offset + RETURN_REGNUM * UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, s390_sr_alias_set);
emit_move_insn (return_reg, addr);
@@ -5544,10 +5929,10 @@ s390_emit_epilogue ()
explicit in insn RTX code, we have to add a barrier here
to prevent incorrect scheduling. */
- emit_insn (gen_blockage());
+ emit_insn (gen_blockage());
- insn = restore_gprs (frame_pointer, offset,
- cfun->machine->first_restore_gpr,
+ insn = restore_gprs (frame_pointer, offset,
+ cfun->machine->first_restore_gpr,
cfun->machine->last_save_gpr);
emit_insn (insn);
}
@@ -5555,21 +5940,19 @@ s390_emit_epilogue ()
/* Return to caller. */
p = rtvec_alloc (2);
-
+
RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
-/* Return the size in bytes of a function argument of
+/* Return the size in bytes of a function argument of
type TYPE and/or mode MODE. At least one of TYPE or
MODE must be specified. */
static int
-s390_function_arg_size (mode, type)
- enum machine_mode mode;
- tree type;
+s390_function_arg_size (enum machine_mode mode, tree type)
{
if (type)
return int_size_in_bytes (type);
@@ -5582,6 +5965,83 @@ s390_function_arg_size (mode, type)
abort ();
}
+/* Return true if a function argument of type TYPE and mode MODE
+ is to be passed in a floating-point register, if available. */
+
+static bool
+s390_function_arg_float (enum machine_mode mode, tree type)
+{
+ int size = s390_function_arg_size (mode, type);
+ if (size > 8)
+ return false;
+
+ /* Soft-float changes the ABI: no floating-point registers are used. */
+ if (TARGET_SOFT_FLOAT)
+ return false;
+
+ /* No type info available for some library calls ... */
+ if (!type)
+ return mode == SFmode || mode == DFmode;
+
+ /* The ABI says that record types with a single member are treated
+ just like that member would be. */
+ while (TREE_CODE (type) == RECORD_TYPE)
+ {
+ tree field, single = NULL_TREE;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ if (single == NULL_TREE)
+ single = TREE_TYPE (field);
+ else
+ return false;
+ }
+
+ if (single == NULL_TREE)
+ return false;
+ else
+ type = single;
+ }
+
+ return TREE_CODE (type) == REAL_TYPE;
+}
+
+/* Return true if a function argument of type TYPE and mode MODE
+ is to be passed in an integer register, or a pair of integer
+ registers, if available. */
+
+static bool
+s390_function_arg_integer (enum machine_mode mode, tree type)
+{
+ int size = s390_function_arg_size (mode, type);
+ if (size > 8)
+ return false;
+
+ /* No type info available for some library calls ... */
+ if (!type)
+ return GET_MODE_CLASS (mode) == MODE_INT
+ || (TARGET_SOFT_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT);
+
+ /* We accept small integral (and similar) types. */
+ if (INTEGRAL_TYPE_P (type)
+ || POINTER_TYPE_P (type)
+ || TREE_CODE (type) == OFFSET_TYPE
+ || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
+ return true;
+
+ /* We also accept structs of size 1, 2, 4, 8 that are not
+ passed in floating-point registers. */
+ if (AGGREGATE_TYPE_P (type)
+ && exact_log2 (size) >= 0
+ && !s390_function_arg_float (mode, type))
+ return true;
+
+ return false;
+}
+
/* Return 1 if a function argument of type TYPE and mode MODE
is to be passed by reference. The ABI specifies that only
structures of size 1, 2, 4, or 8 bytes are passed by value,
@@ -5589,23 +6049,23 @@ s390_function_arg_size (mode, type)
reference. */
int
-s390_function_arg_pass_by_reference (mode, type)
- enum machine_mode mode;
- tree type;
+s390_function_arg_pass_by_reference (enum machine_mode mode, tree type)
{
int size = s390_function_arg_size (mode, type);
+ if (size > 8)
+ return true;
if (type)
{
- if (AGGREGATE_TYPE_P (type) &&
- size != 1 && size != 2 && size != 4 && size != 8)
+ if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
return 1;
- if (TREE_CODE (type) == COMPLEX_TYPE)
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
return 1;
}
- return 0;
+ return 0;
}
/* Update the data in CUM to advance over an argument of mode MODE and
@@ -5615,25 +6075,24 @@ s390_function_arg_pass_by_reference (mode, type)
matching an ellipsis). */
void
-s390_function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named ATTRIBUTE_UNUSED)
{
- if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
+ if (s390_function_arg_pass_by_reference (mode, type))
{
- cum->fprs++;
+ cum->gprs += 1;
}
- else if (s390_function_arg_pass_by_reference (mode, type))
+ else if (s390_function_arg_float (mode, type))
{
- cum->gprs += 1;
+ cum->fprs += 1;
}
- else
+ else if (s390_function_arg_integer (mode, type))
{
int size = s390_function_arg_size (mode, type);
cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
}
+ else
+ abort ();
}
/* Define where to put the arguments to a function.
@@ -5647,7 +6106,7 @@ s390_function_arg_advance (cum, mode, type, named)
CUM is a variable of type CUMULATIVE_ARGS which gives info about
the preceding args and about the function being called.
NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis).
+ (otherwise it is an extra parameter matching an ellipsis).
On S/390, we use general purpose registers 2 through 6 to
pass integer, pointer, and certain structure arguments, and
@@ -5656,23 +6115,20 @@ s390_function_arg_advance (cum, mode, type, named)
are pushed to the stack. */
rtx
-s390_function_arg (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
+ int named ATTRIBUTE_UNUSED)
{
if (s390_function_arg_pass_by_reference (mode, type))
return 0;
- if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
+ if (s390_function_arg_float (mode, type))
{
if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
return 0;
else
return gen_rtx (REG, mode, cum->fprs + 16);
}
- else
+ else if (s390_function_arg_integer (mode, type))
{
int size = s390_function_arg_size (mode, type);
int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
@@ -5682,6 +6138,68 @@ s390_function_arg (cum, mode, type, named)
else
return gen_rtx (REG, mode, cum->gprs + 2);
}
+
+ /* After the real arguments, expand_call calls us once again
+ with a void_type_node type. Whatever we return here is
+ passed as operand 2 to the call expanders.
+
+ We don't need this feature ... */
+ else if (type == void_type_node)
+ return const0_rtx;
+
+ abort ();
+}
+
+/* Return true if return values of type TYPE should be returned
+ in a memory buffer whose address is passed by the caller as
+ hidden first argument. */
+
+static bool
+s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
+{
+ /* We accept small integral (and similar) types. */
+ if (INTEGRAL_TYPE_P (type)
+ || POINTER_TYPE_P (type)
+ || TREE_CODE (type) == OFFSET_TYPE
+ || TREE_CODE (type) == REAL_TYPE)
+ return int_size_in_bytes (type) > 8;
+
+ /* Aggregates and similar constructs are always returned
+ in memory. */
+ if (AGGREGATE_TYPE_P (type)
+ || TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
+ return true;
+
+ /* ??? We get called on all sorts of random stuff from
+ aggregate_value_p. We can't abort, but it's not clear
+ what's safe to return. Pretend it's a struct I guess. */
+ return true;
+}
+
+/* Define where to return a (scalar) value of type TYPE.
+ If TYPE is null, define where to return a (scalar)
+ value of mode MODE from a libcall. */
+
+rtx
+s390_function_value (tree type, enum machine_mode mode)
+{
+ if (type)
+ {
+ int unsignedp = TREE_UNSIGNED (type);
+ mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
+ }
+
+ if (GET_MODE_CLASS (mode) != MODE_INT
+ && GET_MODE_CLASS (mode) != MODE_FLOAT)
+ abort ();
+ if (GET_MODE_SIZE (mode) > 8)
+ abort ();
+
+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ return gen_rtx_REG (mode, 16);
+ else
+ return gen_rtx_REG (mode, 2);
}
@@ -5695,31 +6213,30 @@ s390_function_arg (cum, mode, type, named)
long __fpr;
void *__overflow_arg_area;
void *__reg_save_area;
-
} va_list[1];
where __gpr and __fpr hold the number of general purpose
or floating point arguments used up to now, respectively,
- __overflow_arg_area points to the stack location of the
+ __overflow_arg_area points to the stack location of the
next argument passed on the stack, and __reg_save_area
always points to the start of the register area in the
call frame of the current function. The function prologue
saves all registers used for argument passing into this
area if the function uses variable arguments. */
-tree
-s390_build_va_list ()
+static tree
+s390_build_builtin_va_list (void)
{
tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
- record = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ record = lang_hooks.types.make_type (RECORD_TYPE);
type_decl =
build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
- f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
+ f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
long_integer_type_node);
- f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
+ f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
long_integer_type_node);
f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
ptr_type_node);
@@ -5758,9 +6275,7 @@ s390_build_va_list ()
(relative to the virtual arg pointer). */
void
-s390_va_start (valist, nextarg)
- tree valist;
- rtx nextarg ATTRIBUTE_UNUSED;
+s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT n_gpr, n_fpr;
int off;
@@ -5815,15 +6330,15 @@ s390_va_start (valist, nextarg)
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
-/* Implement va_arg by updating the va_list structure
+/* Implement va_arg by updating the va_list structure
VALIST as required to retrieve an argument of type
- TYPE, and returning that argument.
-
+ TYPE, and returning that argument.
+
Generates code equivalent to:
-
+
if (integral value) {
if (size <= 4 && args.gpr < 5 ||
- size > 4 && args.gpr < 4 )
+ size > 4 && args.gpr < 4 )
ret = args.reg_save_area[args.gpr+8]
else
ret = *args.overflow_arg_area++;
@@ -5840,9 +6355,7 @@ s390_va_start (valist, nextarg)
} */
rtx
-s390_va_arg (valist, type)
- tree valist;
- tree type;
+s390_va_arg (tree valist, tree type)
{
tree f_gpr, f_fpr, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, reg, t, u;
@@ -5879,7 +6392,7 @@ s390_va_arg (valist, type)
size = UNITS_PER_WORD;
max_reg = 4;
}
- else if (FLOAT_TYPE_P (type) && ! TARGET_SOFT_FLOAT)
+ else if (s390_function_arg_float (TYPE_MODE (type), type))
{
if (TARGET_DEBUG_ARG)
{
@@ -5909,13 +6422,9 @@ s390_va_arg (valist, type)
reg = gpr;
n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
sav_ofs = 2 * UNITS_PER_WORD;
- if (TARGET_64BIT)
- sav_ofs += TYPE_MODE (type) == SImode ? 4 :
- TYPE_MODE (type) == HImode ? 6 :
- TYPE_MODE (type) == QImode ? 7 : 0;
- else
- sav_ofs += TYPE_MODE (type) == HImode ? 2 :
- TYPE_MODE (type) == QImode ? 3 : 0;
+
+ if (size < UNITS_PER_WORD)
+ sav_ofs += UNITS_PER_WORD - size;
sav_scale = UNITS_PER_WORD;
if (n_reg > 1)
@@ -5982,10 +6491,10 @@ s390_va_arg (valist, type)
emit_label (lab_over);
- /* If less than max_regs a registers are retrieved out
+ /* If less than max_regs a registers are retrieved out
of register save area, increment. */
- u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
+ u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg, 0));
TREE_SIDE_EFFECTS (u) = 1;
expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -6023,7 +6532,7 @@ static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
};
static void
-s390_init_builtins ()
+s390_init_builtins (void)
{
tree ftype;
@@ -6045,16 +6554,13 @@ s390_init_builtins ()
IGNORE is nonzero if the value is to be ignored. */
static rtx
-s390_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
#define MAX_ARGS 2
- unsigned int const *code_for_builtin =
+ unsigned int const *code_for_builtin =
TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
@@ -6137,8 +6643,7 @@ s390_expand_builtin (exp, target, subtarget, mode, ignore)
gpr 0 is used to hold the static chain. */
void
-s390_trampoline_template (file)
- FILE *file;
+s390_trampoline_template (FILE *file)
{
if (TARGET_64BIT)
{
@@ -6165,18 +6670,15 @@ s390_trampoline_template (file)
CXT is an RTX for the static chain value for the function. */
void
-s390_initialize_trampoline (addr, fnaddr, cxt)
- rtx addr;
- rtx fnaddr;
- rtx cxt;
+s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
{
- emit_move_insn (gen_rtx
+ emit_move_insn (gen_rtx
(MEM, Pmode,
- memory_address (Pmode,
+ memory_address (Pmode,
plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
emit_move_insn (gen_rtx
(MEM, Pmode,
- memory_address (Pmode,
+ memory_address (Pmode,
plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
}
@@ -6184,16 +6686,14 @@ s390_initialize_trampoline (addr, fnaddr, cxt)
LOW and HIGH, independent of the host word size. */
rtx
-s390_gen_rtx_const_DI (high, low)
- int high;
- int low;
+s390_gen_rtx_const_DI (int high, int low)
{
#if HOST_BITS_PER_WIDE_INT >= 64
HOST_WIDE_INT val;
val = (HOST_WIDE_INT)high;
val <<= 32;
val |= (HOST_WIDE_INT)low;
-
+
return GEN_INT (val);
#else
#if HOST_BITS_PER_WIDE_INT >= 32
@@ -6202,15 +6702,13 @@ s390_gen_rtx_const_DI (high, low)
abort ();
#endif
#endif
-}
+}
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
void
-s390_function_profiler (file, labelno)
- FILE *file;
- int labelno;
+s390_function_profiler (FILE *file, int labelno)
{
rtx op[7];
@@ -6225,12 +6723,12 @@ s390_function_profiler (file, labelno)
op[2] = gen_rtx_REG (Pmode, 1);
op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
- SYMBOL_REF_FLAG (op[3]) = 1;
+ SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
if (flag_pic)
{
- op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), 113);
+ op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
op[4] = gen_rtx_CONST (Pmode, op[4]);
}
@@ -6249,7 +6747,7 @@ s390_function_profiler (file, labelno)
output_asm_insn ("bras\t%2,%l6", op);
output_asm_insn (".long\t%4", op);
output_asm_insn (".long\t%3", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
output_asm_insn ("l\t%0,0(%2)", op);
output_asm_insn ("l\t%2,4(%2)", op);
output_asm_insn ("basr\t%0,%0", op);
@@ -6262,10 +6760,10 @@ s390_function_profiler (file, labelno)
output_asm_insn ("st\t%0,%1", op);
output_asm_insn ("bras\t%2,%l6", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
output_asm_insn (".long\t%4-%l5", op);
output_asm_insn (".long\t%3-%l5", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
output_asm_insn ("lr\t%0,%2", op);
output_asm_insn ("a\t%0,0(%2)", op);
output_asm_insn ("a\t%2,4(%2)", op);
@@ -6278,144 +6776,57 @@ s390_function_profiler (file, labelno)
constants go in the function section; in 64-bit mode in .rodata. */
static void
-s390_select_rtx_section (mode, x, align)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx x ATTRIBUTE_UNUSED;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
readonly_data_section ();
else
function_section (current_function_decl);
}
/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
- into its name and SYMBOL_REF_FLAG. */
+ into its SYMBOL_REF_FLAGS. */
static void
-s390_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+s390_encode_section_info (tree decl, rtx rtl, int first)
{
- bool local_p = (*targetm.binds_local_p) (decl);
- rtx rtl, symbol;
-
- rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
- if (GET_CODE (rtl) != MEM)
- return;
- symbol = XEXP (rtl, 0);
- if (GET_CODE (symbol) != SYMBOL_REF)
- return;
+ default_encode_section_info (decl, rtl, first);
- /* When using PIC, SYMBOL_REF_FLAG marks non-global symbols
- that can be accessed directly. */
- if (flag_pic)
- SYMBOL_REF_FLAG (symbol) = local_p;
-
- /* Encode thread-local data with %[GLil] for "global dynamic",
- "local dynamic", "initial exec" or "local exec" TLS models,
- respectively. */
-
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
- {
- const char *symbol_str = XSTR (symbol, 0);
- char *newstr;
- size_t len;
- enum tls_model kind = decl_tls_model (decl);
-
- if (!flag_pic)
- {
- /* We don't allow non-pic code for shared libraries,
- so don't generate GD/LD TLS models for non-pic code. */
- switch (kind)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- kind = TLS_MODEL_INITIAL_EXEC; break;
- case TLS_MODEL_LOCAL_DYNAMIC:
- kind = TLS_MODEL_LOCAL_EXEC; break;
- default:
- break;
- }
- }
-
- if (symbol_str[0] == '%')
- {
- if (symbol_str[1] == tls_model_chars[kind])
- return;
- symbol_str += 2;
- }
- len = strlen (symbol_str) + 1;
- newstr = alloca (len + 2);
-
- newstr[0] = '%';
- newstr[1] = tls_model_chars[kind];
- memcpy (newstr + 2, symbol_str, len);
-
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
- }
-
- /* If a variable has a forced alignment to < 2 bytes, mark it
- with '@' to prevent it from being used as LARL operand. */
-
- else if (TREE_CODE (decl) == VAR_DECL
- && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16
- && XSTR (symbol, 0)[0] != '@')
- {
- const char *symbol_str = XSTR (symbol, 0);
- size_t len = strlen (symbol_str) + 1;
- char *newstr = alloca (len + 1);
-
- newstr[0] = '@';
- memcpy (newstr + 1, symbol_str, len);
-
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 1 - 1);
- }
-}
-
-/* Undo the above when printing symbol names. */
-
-static const char *
-s390_strip_name_encoding (str)
- const char *str;
-{
- if (str[0] == '%')
- str += 2;
- if (str[0] == '@')
- str += 1;
- if (str[0] == '*')
- str += 1;
- return str;
+ /* If a variable has a forced alignment to < 2 bytes, mark it with
+ SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
+ if (TREE_CODE (decl) == VAR_DECL
+ && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
+ SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
}
/* Output thunk to FILE that implements a C++ virtual function call (with
- multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
+ multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
stored at VCALL_OFFSET in the vtable whose address is located at offset 0
relative to the resulting this pointer. */
static void
-s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
- FILE *file;
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset;
- tree function;
+s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
{
rtx op[10];
int nonlocal = 0;
/* Operand 0 is the target function. */
op[0] = XEXP (DECL_RTL (function), 0);
- if (flag_pic && !SYMBOL_REF_FLAG (op[0]))
+ if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
{
nonlocal = 1;
op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
- TARGET_64BIT ? 113 : flag_pic == 2 ? 112 : 110);
+ TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
op[0] = gen_rtx_CONST (Pmode, op[0]);
}
/* Operand 1 is the 'this' pointer. */
- if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
op[1] = gen_rtx_REG (Pmode, 3);
else
op[1] = gen_rtx_REG (Pmode, 2);
@@ -6442,8 +6853,10 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (TARGET_64BIT)
{
/* Setup literal pool pointer if required. */
- if (!CONST_OK_FOR_LETTER_P (delta, 'K')
- || !CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ if ((!DISP_IN_RANGE (delta)
+ && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
+ || (!DISP_IN_RANGE (vcall_offset)
+ && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
{
op[5] = gen_label_rtx ();
output_asm_insn ("larl\t%4,%5", op);
@@ -6452,9 +6865,11 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Add DELTA to this pointer. */
if (delta)
{
- if (CONST_OK_FOR_LETTER_P (delta, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
output_asm_insn ("la\t%1,%2(%1)", op);
- else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
+ else if (DISP_IN_RANGE (delta))
+ output_asm_insn ("lay\t%1,%2(%1)", op);
+ else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
output_asm_insn ("aghi\t%1,%2", op);
else
{
@@ -6466,12 +6881,12 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Perform vcall adjustment. */
if (vcall_offset)
{
- if (CONST_OK_FOR_LETTER_P (vcall_offset, 'J'))
+ if (DISP_IN_RANGE (vcall_offset))
{
output_asm_insn ("lg\t%4,0(%1)", op);
output_asm_insn ("ag\t%1,%3(%4)", op);
}
- else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
{
output_asm_insn ("lghi\t%4,%3", op);
output_asm_insn ("ag\t%4,0(%1)", op);
@@ -6485,7 +6900,7 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
output_asm_insn ("ag\t%1,0(%4)", op);
}
}
-
+
/* Jump to target. */
output_asm_insn ("jg\t%0", op);
@@ -6493,16 +6908,19 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (op[5])
{
output_asm_insn (".align\t4", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[5]));
}
if (op[6])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[6]));
output_asm_insn (".long\t%2", op);
}
if (op[7])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[7]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[7]));
output_asm_insn (".long\t%3", op);
}
}
@@ -6510,20 +6928,25 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
{
/* Setup base pointer if required. */
if (!vcall_offset
- || !CONST_OK_FOR_LETTER_P (delta, 'K')
- || !CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ || (!DISP_IN_RANGE (delta)
+ && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
+ || (!DISP_IN_RANGE (delta)
+ && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
{
op[5] = gen_label_rtx ();
output_asm_insn ("basr\t%4,0", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[5]));
}
/* Add DELTA to this pointer. */
if (delta)
{
- if (CONST_OK_FOR_LETTER_P (delta, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
output_asm_insn ("la\t%1,%2(%1)", op);
- else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
+ else if (DISP_IN_RANGE (delta))
+ output_asm_insn ("lay\t%1,%2(%1)", op);
+ else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
output_asm_insn ("ahi\t%1,%2", op);
else
{
@@ -6535,12 +6958,17 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Perform vcall adjustment. */
if (vcall_offset)
{
- if (CONST_OK_FOR_LETTER_P (vcall_offset, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
{
output_asm_insn ("lg\t%4,0(%1)", op);
output_asm_insn ("a\t%1,%3(%4)", op);
}
- else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ else if (DISP_IN_RANGE (vcall_offset))
+ {
+ output_asm_insn ("lg\t%4,0(%1)", op);
+ output_asm_insn ("ay\t%1,%3(%4)", op);
+ }
+ else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
{
output_asm_insn ("lhi\t%4,%3", op);
output_asm_insn ("a\t%4,0(%1)", op);
@@ -6558,7 +6986,8 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
Re-setup the base pointer (with a different base). */
op[5] = gen_label_rtx ();
output_asm_insn ("basr\t%4,0", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[5]));
}
/* Jump to target. */
@@ -6593,10 +7022,10 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (nonlocal)
{
op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
- SYMBOL_REF_FLAG (op[0]) = 1;
+ SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
}
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[8]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
if (!flag_pic)
output_asm_insn (".long\t%0", op);
else
@@ -6604,21 +7033,29 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (op[6])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[6]));
output_asm_insn (".long\t%2", op);
}
if (op[7])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[7]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[7]));
output_asm_insn (".long\t%3", op);
}
}
}
+bool
+s390_valid_pointer_mode (enum machine_mode mode)
+{
+ return (mode == SImode || (TARGET_64BIT && mode == DImode));
+}
+
/* How to allocate a 'struct machine_function'. */
static struct machine_function *
-s390_init_machine_status ()
+s390_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (struct machine_function));
}
diff --git a/contrib/gcc/config/s390/s390.h b/contrib/gcc/config/s390/s390.h
index c3dad68..d2416c8 100644
--- a/contrib/gcc/config/s390/s390.h
+++ b/contrib/gcc/config/s390/s390.h
@@ -1,23 +1,25 @@
/* Definitions of target machine for GNU compiler, for IBM S/390
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
-GNU CC 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 2, or (at your option)
-any later version.
+This file is part of GCC.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is 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 2, 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifndef _S390_H
#define _S390_H
@@ -25,9 +27,49 @@ Boston, MA 02111-1307, USA. */
/* Override the __fixdfdi etc. routines when building libgcc2.
??? This should be done in a cleaner way ... */
#if defined (IN_LIBGCC2) && !defined (__s390x__)
-#include <s390/fixdfdi.h>
+#include <config/s390/fixdfdi.h>
#endif
+/* Which processor to generate code or schedule for. The cpu attribute
+ defines a list that mirrors this list, so changes to s390.md must be
+ made at the same time. */
+
+enum processor_type
+{
+ PROCESSOR_9672_G5,
+ PROCESSOR_9672_G6,
+ PROCESSOR_2064_Z900,
+ PROCESSOR_2084_Z990,
+ PROCESSOR_max
+};
+
+/* Optional architectural facilities supported by the processor. */
+
+enum processor_flags
+{
+ PF_IEEE_FLOAT = 1,
+ PF_ZARCH = 2,
+ PF_LONG_DISPLACEMENT = 4
+};
+
+extern enum processor_type s390_tune;
+extern enum processor_flags s390_tune_flags;
+extern const char *s390_tune_string;
+
+extern enum processor_type s390_arch;
+extern enum processor_flags s390_arch_flags;
+extern const char *s390_arch_string;
+
+#define TARGET_CPU_IEEE_FLOAT \
+ (s390_arch_flags & PF_IEEE_FLOAT)
+#define TARGET_CPU_ZARCH \
+ (s390_arch_flags & PF_ZARCH)
+#define TARGET_CPU_LONG_DISPLACEMENT \
+ (s390_arch_flags & PF_LONG_DISPLACEMENT)
+
+#define TARGET_LONG_DISPLACEMENT \
+ (TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT)
+
/* Run-time target specification. */
@@ -46,39 +88,85 @@ Boston, MA 02111-1307, USA. */
/* Optional target features. */
extern int target_flags;
-#define TARGET_HARD_FLOAT (target_flags & 1)
-#define TARGET_SOFT_FLOAT (!(target_flags & 1))
-#define TARGET_BACKCHAIN (target_flags & 2)
-#define TARGET_SMALL_EXEC (target_flags & 4)
-#define TARGET_DEBUG_ARG (target_flags & 8)
-#define TARGET_64BIT (target_flags & 16)
-#define TARGET_MVCLE (target_flags & 32)
+#define MASK_HARD_FLOAT 0x01
+#define MASK_BACKCHAIN 0x02
+#define MASK_SMALL_EXEC 0x04
+#define MASK_DEBUG_ARG 0x08
+#define MASK_64BIT 0x10
+#define MASK_ZARCH 0x20
+#define MASK_MVCLE 0x40
+#define MASK_TPF 0x80
+#define MASK_NO_FUSED_MADD 0x100
+
+#define TARGET_HARD_FLOAT (target_flags & MASK_HARD_FLOAT)
+#define TARGET_SOFT_FLOAT (!(target_flags & MASK_HARD_FLOAT))
+#define TARGET_BACKCHAIN (target_flags & MASK_BACKCHAIN)
+#define TARGET_SMALL_EXEC (target_flags & MASK_SMALL_EXEC)
+#define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)
+#define TARGET_64BIT (target_flags & MASK_64BIT)
+#define TARGET_ZARCH (target_flags & MASK_ZARCH)
+#define TARGET_MVCLE (target_flags & MASK_MVCLE)
+#define TARGET_TPF (target_flags & MASK_TPF)
+#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
+#define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD)
/* ??? Once this actually works, it could be made a runtime option. */
#define TARGET_IBM_FLOAT 0
#define TARGET_IEEE_FLOAT 1
#ifdef DEFAULT_TARGET_64BIT
-#define TARGET_DEFAULT 0x13
+#define TARGET_DEFAULT 0x31
#else
-#define TARGET_DEFAULT 0x3
+#define TARGET_DEFAULT 0x1
#endif
-#define TARGET_SWITCHES \
-{ { "hard-float", 1, N_("Use hardware fp")}, \
- { "soft-float", -1, N_("Don't use hardware fp")}, \
- { "backchain", 2, N_("Set backchain")}, \
- { "no-backchain", -2, N_("Don't set backchain (faster, but debug harder")}, \
- { "small-exec", 4, N_("Use bras for executable < 64k")}, \
- { "no-small-exec",-4, N_("Don't use bras")}, \
- { "debug", 8, N_("Additional debug prints")}, \
- { "no-debug", -8, N_("Don't print additional debug prints")}, \
- { "64", 16, N_("64 bit mode")}, \
- { "31", -16, N_("31 bit mode")}, \
- { "mvcle", 32, N_("mvcle use")}, \
- { "no-mvcle", -32, N_("mvc&ex")}, \
+#define TARGET_SWITCHES \
+{ { "hard-float", 1, N_("Use hardware fp")}, \
+ { "soft-float", -1, N_("Don't use hardware fp")}, \
+ { "backchain", 2, N_("Set backchain")}, \
+ { "no-backchain", -2, N_("Don't set backchain (faster, but debug harder")},\
+ { "small-exec", 4, N_("Use bras for executable < 64k")}, \
+ { "no-small-exec", -4, N_("Don't use bras")}, \
+ { "debug", 8, N_("Additional debug prints")}, \
+ { "no-debug", -8, N_("Don't print additional debug prints")}, \
+ { "64", 16, N_("64 bit ABI")}, \
+ { "31", -16, N_("31 bit ABI")}, \
+ { "zarch", 32, N_("z/Architecture")}, \
+ { "esa", -32, N_("ESA/390 architecture")}, \
+ { "mvcle", 64, N_("mvcle use")}, \
+ { "no-mvcle", -64, N_("mvc&ex")}, \
+ { "tpf", 128, N_("enable tpf OS code")}, \
+ { "no-tpf", -128, N_("disable tpf OS code")}, \
+ { "no-fused-madd", 256, N_("disable fused multiply/add instructions")},\
+ { "fused-madd", -256, N_("enable fused multiply/add instructions")}, \
{ "", TARGET_DEFAULT, 0 } }
+#define TARGET_OPTIONS \
+{ { "tune=", &s390_tune_string, \
+ N_("Schedule code for given CPU"), 0}, \
+ { "arch=", &s390_arch_string, \
+ N_("Generate code for given CPU"), 0}, \
+}
+
+/* Support for configure-time defaults. */
+#define OPTION_DEFAULT_SPECS \
+ { "mode", "%{!mesa:%{!mzarch:-m%(VALUE)}}" }, \
+ { "arch", "%{!march=*:-march=%(VALUE)}" }, \
+ { "tune", "%{!mtune=*:-mtune=%(VALUE)}" }
+
+/* Defaulting rules. */
+#ifdef DEFAULT_TARGET_64BIT
+#define DRIVER_SELF_SPECS \
+ "%{!m31:%{!m64:-m64}}", \
+ "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
+ "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
+#else
+#define DRIVER_SELF_SPECS \
+ "%{!m31:%{!m64:-m31}}", \
+ "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
+ "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
+#endif
+
/* Target version string. Overridden by the OS header. */
#ifdef DEFAULT_TARGET_64BIT
#define TARGET_VERSION fprintf (stderr, " (zSeries)");
@@ -158,7 +246,7 @@ if (INTEGRAL_MODE_P (MODE) && \
NONLOCAL needs twice Pmode to maintain both backchain and SP. */
#define STACK_SAVEAREA_MODE(LEVEL) \
(LEVEL == SAVE_FUNCTION ? VOIDmode \
- : LEVEL == SAVE_NONLOCAL ? (TARGET_64BIT ? TImode : DImode) : Pmode)
+ : LEVEL == SAVE_NONLOCAL ? (TARGET_64BIT ? OImode : TImode) : Pmode)
/* Define target floating point format. */
#define TARGET_FLOAT_FORMAT \
@@ -186,7 +274,7 @@ if (INTEGRAL_MODE_P (MODE) && \
/* We have 16 general purpose registers (registers 0-15),
and 16 floating point registers (registers 16-31).
(On non-IEEE machines, we have only 4 fp registers.)
-
+
Amongst the general purpose registers, some are used
for specific purposes:
GPR 11: Hard frame pointer (if needed)
@@ -194,7 +282,7 @@ if (INTEGRAL_MODE_P (MODE) && \
GPR 13: Literal pool base register
GPR 14: Return address register
GPR 15: Stack pointer
-
+
Registers 32-34 are 'fake' hard registers that do not
correspond to actual hardware:
Reg 32: Argument pointer
@@ -226,7 +314,7 @@ if (INTEGRAL_MODE_P (MODE) && \
GPRs 6-15 are always call-saved.
GPR 12 is fixed if used as GOT pointer.
GPR 13 is always fixed (as literal pool pointer).
- GPR 14 is always fixed (as return address).
+ GPR 14 is always fixed on S/390 machines (as return address).
GPR 15 is always fixed (as stack pointer).
The 'fake' hard registers are call-clobbered and fixed.
@@ -277,6 +365,11 @@ do \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
} \
+ if (TARGET_CPU_ZARCH) \
+ { \
+ fixed_regs[RETURN_REGNUM] = 0; \
+ call_used_regs[RETURN_REGNUM] = 0; \
+ } \
if (TARGET_64BIT) \
{ \
for (i = 24; i < 32; i++) \
@@ -291,26 +384,26 @@ do \
/* Preferred register allocation order. */
#define REG_ALLOC_ORDER \
-{ 1, 2, 3, 4, 5, 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, \
+{ 1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14, \
16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26, 27, 28, 29, 30, 31, \
15, 32, 33, 34 }
/* Fitting values into registers. */
-
+
/* Integer modes <= word size fit into any GPR.
Integer modes > word size fit into successive GPRs, starting with
an even-numbered register.
SImode and DImode fit into FPRs as well.
-
+
Floating point modes <= word size fit into any FPR or GPR.
Floating point modes > word size (i.e. DFmode on 32-bit) fit
into any FPR, or an even-odd GPR pair.
-
+
Complex floating point modes fit either into two FPRs, or into
successive GPRs (again starting with an even number).
-
+
Condition code modes fit only into the CC register. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
@@ -352,19 +445,19 @@ do \
? reg_classes_intersect_p (FP_REGS, CLASS) : 0)
/* Register classes. */
-
+
/* We use the following register classes:
GENERAL_REGS All general purpose registers
ADDR_REGS All general purpose registers except %r0
(These registers can be used in address generation)
FP_REGS All floating point registers
-
+
GENERAL_FP_REGS Union of GENERAL_REGS and FP_REGS
ADDR_FP_REGS Union of ADDR_REGS and FP_REGS
-
+
NO_REGS No registers
ALL_REGS All registers
-
+
Note that the 'fake' frame pointer and argument pointer registers
are included amongst the address registers here. The condition
code register is only included in ALL_REGS. */
@@ -444,23 +537,23 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
(C) == 'd' ? GENERAL_REGS : \
(C) == 'f' ? FP_REGS : NO_REGS)
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'I' ? (unsigned long) (VALUE) < 256 : \
- (C) == 'J' ? (unsigned long) (VALUE) < 4096 : \
- (C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : \
- (C) == 'L' ? (unsigned long) (VALUE) < 65536 : 0)
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1
+#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
+ s390_const_ok_for_constraint_p ((VALUE), (C), (STR))
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? q_constraint (OP) : \
- (C) == 'S' ? larl_operand (OP, GET_MODE (OP)) : 0)
+#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(VALUE, C, STR) 1
-#define EXTRA_MEMORY_CONSTRAINT(C) ((C) == 'Q')
+#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
+ s390_extra_constraint_str ((OP), (C), (STR))
+#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
+ ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T')
+#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
+ ((C) == 'U' || (C) == 'W' || (C) == 'Y')
+#define CONSTRAINT_LEN(C, STR) \
+ ((C) == 'N' ? 5 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
/* Stack layout and calling conventions. */
-
+
/* Our stack grows from higher to lower addresses. However, local variables
are accessed by positive offsets, and function arguments are stored at
increasing addresses. */
@@ -490,7 +583,7 @@ extern int current_function_outgoing_args_size;
the argument area. */
#define FIRST_PARM_OFFSET(FNDECL) 0
-/* The return address of the current frame is retrieved
+/* The return address of the current frame is retrieved
from the initial value of register RETURN_REGNUM.
For frames farther back, we use the stack slot where
the corresponding RETURN_REGNUM register was saved. */
@@ -498,7 +591,7 @@ extern int current_function_outgoing_args_size;
#define DYNAMIC_CHAIN_ADDRESS(FRAME) \
((FRAME) != hard_frame_pointer_rtx ? (FRAME) : \
plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
-
+
#define RETURN_ADDR_RTX(COUNT, FRAME) \
s390_return_addr_rtx ((COUNT), DYNAMIC_CHAIN_ADDRESS ((FRAME)))
@@ -507,7 +600,7 @@ extern int current_function_outgoing_args_size;
/* Exception handling. */
-
+
/* Describe calling conventions for DWARF-2 exception handling. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, RETURN_REGNUM)
#define INCOMING_FRAME_SP_OFFSET STACK_POINTER_OFFSET
@@ -517,7 +610,7 @@ extern int current_function_outgoing_args_size;
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
#define EH_RETURN_HANDLER_RTX \
gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \
- TARGET_64BIT? -48 : -40))
+ -STACK_POINTER_OFFSET + UNITS_PER_WORD*RETURN_REGNUM))
/* Select a format to encode pointers in exception handling data. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
@@ -533,8 +626,8 @@ extern int current_function_outgoing_args_size;
#define HARD_FRAME_POINTER_REGNUM 11
#define ARG_POINTER_REGNUM 32
-/* The static chain must be call-clobbered, but not used for
- function argument passing. As register 1 is clobbered by
+/* The static chain must be call-clobbered, but not used for
+ function argument passing. As register 1 is clobbered by
the trampoline code, we only have one option. */
#define STATIC_CHAIN_REGNUM 0
@@ -554,7 +647,7 @@ extern int current_function_outgoing_args_size;
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
#define CAN_ELIMINATE(FROM, TO) (1)
@@ -575,7 +668,7 @@ extern int current_function_outgoing_args_size;
/* Stack arguments. */
-
+
/* We need current_function_outgoing_args to be valid. */
#define ACCUMULATE_OUTGOING_ARGS 1
@@ -584,7 +677,7 @@ extern int current_function_outgoing_args_size;
/* Register arguments. */
-
+
typedef struct s390_arg_structure
{
int gprs; /* gpr so far */
@@ -592,7 +685,7 @@ typedef struct s390_arg_structure
}
CUMULATIVE_ARGS;
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, NN) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, NN, N_NAMED_ARGS) \
((CUM).gprs=0, (CUM).fprs=0)
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
@@ -613,41 +706,22 @@ CUMULATIVE_ARGS;
/* Scalar return values. */
-
-/* We return scalars in general purpose register 2 for integral values,
- and floating point register 0 for fp values. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- || POINTER_TYPE_P (VALTYPE) \
- ? word_mode : TYPE_MODE (VALTYPE), \
- TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT ? 16 : 2)
-
-/* Define how to find the value returned by a library function assuming
- the value has mode MODE. */
-#define RET_REG(MODE) ((GET_MODE_CLASS (MODE) == MODE_INT \
- || TARGET_SOFT_FLOAT ) ? 2 : 16)
-#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, RET_REG (MODE))
-
-/* Only gpr 2 and fpr 0 are ever used as return registers. */
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16)
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ s390_function_value ((VALTYPE), VOIDmode)
-/* Aggregate return values. */
+#define LIBCALL_VALUE(MODE) \
+ s390_function_value (NULL, (MODE))
-/* The definition of this macro implies that there are cases where
- a scalar value cannot be returned in registers. */
-#define RETURN_IN_MEMORY(type) \
- (TYPE_MODE (type) == BLKmode || \
- GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_INT || \
- GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT)
+/* Only gpr 2 and fpr 0 are ever used as return registers. */
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16)
/* Structure value address is passed as invisible first argument (gpr 2). */
#define STRUCT_VALUE 0
/* Function entry and exit. */
-
+
/* When returning from a function, the stack pointer does not matter. */
#define EXIT_IGNORE_STACK 1
@@ -662,9 +736,6 @@ CUMULATIVE_ARGS;
/* Implementing the varargs macros. */
-#define BUILD_VA_LIST_TYPE(VALIST) \
- (VALIST) = s390_build_va_list ()
-
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
s390_va_start (valist, nextarg)
@@ -684,7 +755,7 @@ CUMULATIVE_ARGS;
/* Library calls. */
-
+
/* We should use memcpy, not bcopy. */
#define TARGET_MEM_FUNCTIONS
@@ -711,7 +782,7 @@ CUMULATIVE_ARGS;
#define REG_OK_FOR_INDEX_NONSTRICT_P(X) \
((GET_MODE (X) == Pmode) && \
((REGNO (X) >= FIRST_PSEUDO_REGISTER) \
- || REGNO_REG_CLASS (REGNO (X)) == ADDR_REGS))
+ || REGNO_REG_CLASS (REGNO (X)) == ADDR_REGS))
#define REG_OK_FOR_BASE_NONSTRICT_P(X) REG_OK_FOR_INDEX_NONSTRICT_P (X)
@@ -781,7 +852,7 @@ CUMULATIVE_ARGS;
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. */
#define SELECT_CC_MODE(OP, X, Y) s390_select_ccmode ((OP), (X), (Y))
-
+
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
@@ -790,77 +861,6 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
/* Relative costs of operations. */
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-/* Force_const_mem does not work out of reload, because the saveable_obstack
- is set to reload_obstack, which does not live long enough.
- Because of this we cannot use force_const_mem in addsi3.
- This leads to problems with gen_add2_insn with a constant greater
- than a short. Because of that we give an addition of greater
- constants a cost of 3 (reload1.c 10096). */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST: \
- if ((GET_CODE (XEXP (RTX, 0)) == MINUS) && \
- (GET_CODE (XEXP (XEXP (RTX, 0), 1)) != CONST_INT)) \
- return 1000; \
- case CONST_INT: \
- if ((OUTER_CODE == PLUS) && \
- ((INTVAL (RTX) > 32767) || \
- (INTVAL (RTX) < -32768))) \
- return COSTS_N_INSNS (3); \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- return 0; \
-
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast
- instructions. OUTER_CODE is the code of the expression in which X
- is contained. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case PLUS: \
- case AND: \
- case IOR: \
- case XOR: \
- case MINUS: \
- case NEG: \
- case NOT: \
- return COSTS_N_INSNS (1); \
- case MULT: \
- if (GET_MODE (XEXP (X, 0)) == DImode) \
- return COSTS_N_INSNS (40); \
- else \
- return COSTS_N_INSNS (7); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (33);
-
-
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values. */
-#define ADDRESS_COST(RTX) s390_address_cost ((RTX))
-
/* On s390, copy between fprs and gprs is expensive. */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
(( ( reg_classes_intersect_p ((CLASS1), GENERAL_REGS) \
@@ -925,7 +925,7 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
/* Position independent code. */
-extern int flag_pic;
+extern int flag_pic;
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
@@ -950,26 +950,11 @@ extern int flag_pic;
/* Advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
- fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE))
-
-/* Output a reference to a user-level label named NAME. */
-#define ASM_OUTPUT_LABELREF(FILE, NAME) \
- asm_fprintf ((FILE), "%U%s", (*targetm.strip_name_encoding) (NAME))
-
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
- ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+ fprintf ((FILE), "\t.set\t.,.+"HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */
#define LOCAL_LABEL_PREFIX "."
-/* Either simplify a location expression, or return the original. */
-#define ASM_SIMPLIFY_DWARF_ADDR(X) \
- s390_simplify_dwarf_addr (X)
-
/* How to refer to registers in assembler output. This sequence is
indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
@@ -980,6 +965,13 @@ extern int flag_pic;
"%ap", "%cc", "%fp" \
}
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ s390_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
/* Print operand X (an rtx) in assembler syntax to file FILE. */
#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
@@ -1008,71 +1000,13 @@ do { \
} while (0)
-/* Constant Pool for all symbols operands which are changed with
- force_const_mem during insn generation (expand_insn). */
-
-extern int s390_pool_count;
-extern int s390_nr_constants;
-
-#define ASM_OUTPUT_POOL_PROLOGUE(FILE, FUNNAME, fndecl, size) \
-{ \
- struct pool_constant *pool; \
- \
- if (s390_pool_count == -1) \
- { \
- s390_nr_constants = 0; \
- for (pool = first_pool; pool; pool = pool->next) \
- if (pool->mark) s390_nr_constants++; \
- return; \
- } \
-}
-
-#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, EXP, MODE, ALIGN, LABELNO, WIN) \
-{ \
- fprintf (FILE, ".LC%d:\n", LABELNO); \
- \
- /* Output the value of the constant itself. */ \
- switch (GET_MODE_CLASS (MODE)) \
- { \
- case MODE_FLOAT: \
- if (GET_CODE (EXP) != CONST_DOUBLE) \
- abort (); \
- \
- REAL_VALUE_FROM_CONST_DOUBLE (r, EXP); \
- assemble_real (r, MODE, ALIGN); \
- break; \
- \
- case MODE_INT: \
- case MODE_PARTIAL_INT: \
- if (GET_CODE (EXP) == CONST \
- || GET_CODE (EXP) == SYMBOL_REF \
- || GET_CODE (EXP) == LABEL_REF) \
- { \
- fputs (integer_asm_op (UNITS_PER_WORD, TRUE), FILE); \
- s390_output_symbolic_const (FILE, EXP); \
- fputc ('\n', (FILE)); \
- } \
- else \
- { \
- assemble_integer (EXP, GET_MODE_SIZE (MODE), ALIGN, 1); \
- if (GET_MODE_SIZE (MODE) == 1) \
- ASM_OUTPUT_SKIP ((FILE), 1); \
- } \
- break; \
- \
- default: \
- abort (); \
- } \
- goto WIN; \
-}
-
-
/* Miscellaneous parameters. */
/* Define the codes that are matched by predicates in aux-output.c. */
#define PREDICATE_CODES \
{"s_operand", { SUBREG, MEM }}, \
{"s_imm_operand", { CONST_INT, CONST_DOUBLE, SUBREG, MEM }}, \
+ {"shift_count_operand", { REG, SUBREG, PLUS, CONST_INT }}, \
{"bras_sym_operand",{ SYMBOL_REF, CONST }}, \
{"larl_operand", { SYMBOL_REF, CONST, CONST_INT, CONST_DOUBLE }}, \
{"load_multiple_operation", {PARALLEL}}, \
@@ -1080,20 +1014,14 @@ extern int s390_nr_constants;
{"const0_operand", { CONST_INT, CONST_DOUBLE }}, \
{"consttable_operand", { SYMBOL_REF, LABEL_REF, CONST, \
CONST_INT, CONST_DOUBLE }}, \
- {"s390_plus_operand", { PLUS }},
+ {"s390_plus_operand", { PLUS }}, \
+ {"s390_alc_comparison", { LTU, GTU, LEU, GEU }}, \
+ {"s390_slb_comparison", { LTU, GTU, LEU, GEU }},
/* Specify the machine mode that this machine uses for the index in the
tablejump instruction. */
#define CASE_VECTOR_MODE (TARGET_64BIT ? DImode : SImode)
-/* Load from integral MODE < SI from memory into register makes sign_extend
- or zero_extend
- In our case sign_extension happens for Halfwords, other no extension. */
-#define LOAD_EXTEND_OP(MODE) \
-(TARGET_64BIT ? ((MODE) == QImode ? ZERO_EXTEND : \
- (MODE) == HImode ? SIGN_EXTEND : NIL) \
- : ((MODE) == HImode ? SIGN_EXTEND : NIL))
-
/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
@@ -1103,6 +1031,9 @@ extern int s390_nr_constants;
between pointers and any other objects of this machine mode. */
#define Pmode ((enum machine_mode) (TARGET_64BIT ? DImode : SImode))
+/* This is -1 for "pointer mode" extend. See ptr_extend in s390.md. */
+#define POINTERS_EXTEND_UNSIGNED -1
+
/* A function address in a call instruction is a byte address (for
indexing purposes) so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
@@ -1110,10 +1041,4 @@ extern int s390_nr_constants;
/* This macro definition sets up a default value for `main' to return. */
#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
-/* In rare cases, correct code generation requires extra machine dependent
- processing between the second jump optimization pass and delayed branch
- scheduling. On those machines, define this macro as a C statement to act on
- the code starting at INSN. */
-#define MACHINE_DEPENDENT_REORG(INSN) s390_machine_dependent_reorg (INSN)
-
-#endif
+#endif
diff --git a/contrib/gcc/config/s390/s390.md b/contrib/gcc/config/s390/s390.md
index 8178516..ebb8b57 100644
--- a/contrib/gcc/config/s390/s390.md
+++ b/contrib/gcc/config/s390/s390.md
@@ -1,23 +1,25 @@
;;- Machine description for GNU compiler -- S/390 / zSeries version.
-;; Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+;; Free Software Foundation, Inc.
;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
;; Ulrich Weigand (uweigand@de.ibm.com).
-;; This file is part of GNU CC.
-;; GNU CC 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 2, or (at your option)
-;; any later version.
+;; This file is part of GCC.
-;; GNU CC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
+;; GCC is 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 2, 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the Free
+;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
;;
;; Special constraints for s/390 machine description:
@@ -27,17 +29,42 @@
;; I -- An 8-bit constant (0..255).
;; J -- A 12-bit constant (0..4095).
;; K -- A 16-bit constant (-32768..32767).
-;; Q -- A memory reference without index-register.
-;; S -- Valid operand for the LARL instruction.
+;; L -- Value appropriate as displacement.
+;; (0..4095) for short displacement
+;; (-524288..524287) for long displacement
+;; M -- Constant integer with a value of 0x7fffffff.
+;; N -- Multiple letter constraint followed by 4 parameter letters.
+;; 0..9: number of the part counting from most to least significant
+;; H,Q: mode of the part
+;; D,S,H: mode of the containing operand
+;; 0,F: value of the other parts (F - all bits set)
+;;
+;; The constraint matches if the specified part of a constant
+;; has a value different from its other parts.
+;; Q -- Memory reference without index register and with short displacement.
+;; R -- Memory reference with index register and short displacement.
+;; S -- Memory reference without index register but with long displacement.
+;; T -- Memory reference with index register and long displacement.
+;; U -- Pointer with short displacement.
+;; W -- Pointer with long displacement.
+;; Y -- Shift count operand.
;;
;; Special formats used for outputting 390 instructions.
;;
-;; %b -- Print a constant byte integer. xy
-;; %h -- Print a signed 16-bit. wxyz
-;; %N -- Print next register (second word of a DImode reg) or next word.
-;; %M -- Print next register (second word of a TImode reg) or next word.
-;; %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
-;; %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
+;; %C: print opcode suffix for branch condition.
+;; %D: print opcode suffix for inverse branch condition.
+;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
+;; %O: print only the displacement of a memory reference.
+;; %R: print only the base register of a memory reference.
+;; %N: print the second word of a DImode operand.
+;; %M: print the second word of a TImode operand.
+
+;; %b: print integer X as if it's an unsigned byte.
+;; %x: print integer X as if it's an unsigned word.
+;; %h: print integer X as if it's a signed word.
+;; %i: print the first nonzero HImode part of X
+;; %j: print the first HImode part unequal to 0xffff of X
+
;;
;; We have a special constraint for pattern matching.
;;
@@ -49,7 +76,24 @@
;;
(define_constants
- [; TLS relocation specifiers
+ [; Miscellaneous
+ (UNSPEC_ROUND 1)
+ (UNSPEC_SETHIGH 10)
+
+ ; GOT/PLT and lt-relative accesses
+ (UNSPEC_LTREL_OFFSET 100)
+ (UNSPEC_LTREL_BASE 101)
+ (UNSPEC_GOTENT 110)
+ (UNSPEC_GOT 111)
+ (UNSPEC_GOTOFF 112)
+ (UNSPEC_PLT 113)
+ (UNSPEC_PLTOFF 114)
+
+ ; Literal pool
+ (UNSPEC_RELOAD_BASE 210)
+ (UNSPEC_MAIN_BASE 211)
+
+ ; TLS relocation specifiers
(UNSPEC_TLSGD 500)
(UNSPEC_TLSLDM 501)
(UNSPEC_NTPOFF 502)
@@ -61,6 +105,9 @@
(UNSPEC_TP 510)
(UNSPEC_TLSLDM_NTPOFF 511)
(UNSPEC_TLS_LOAD 512)
+
+ ; String Functions
+ (UNSPEC_SRST 600)
])
;;
@@ -68,25 +115,70 @@
;;
(define_constants
- [; TLS support
+ [; Blockage
+ (UNSPECV_BLOCKAGE 0)
+
+ ; Literal pool
+ (UNSPECV_POOL 200)
+ (UNSPECV_POOL_START 201)
+ (UNSPECV_POOL_END 202)
+ (UNSPECV_POOL_ENTRY 203)
+ (UNSPECV_MAIN_POOL 300)
+
+ ; TLS support
(UNSPECV_SET_TP 500)
])
+;; Processor type. This attribute must exactly match the processor_type
+;; enumeration in s390.h.
+
+(define_attr "cpu" "g5,g6,z900,z990"
+ (const (symbol_ref "s390_tune")))
+
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "none,integer,load,lr,la,lm,stm,cs,vs,store,imul,lmul,fmul,idiv,ldiv,fdiv,branch,jsr,other,o2,o3"
+(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
+ cs,vs,store,imul,idiv,
+ branch,jsr,fsimpd,fsimps,
+ floadd,floads,fstored, fstores,
+ fmuld,fmuls,fdivd,fdivs,
+ ftoi,itof,fsqrtd,fsqrts,
+ other,o2,o3"
(const_string "integer"))
-;; Insn are devide in two classes:
-;; mem: Insn accessing memory
-;; reg: Insn operands all in registers
+;; Operand type. Used to default length attribute values
-(define_attr "atype" "reg,mem"
- (const_string "reg"))
+(define_attr "op_type"
+ "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY"
+ (const_string "RX"))
-;; Generic pipeline function unit.
+;; Insn are devide in two classes:
+;; agen: Insn using agen
+;; reg: Insn not using agen
+
+(define_attr "atype" "agen,reg"
+(cond [ (eq_attr "op_type" "E") (const_string "reg")
+ (eq_attr "op_type" "RR") (const_string "reg")
+ (eq_attr "op_type" "RX") (const_string "agen")
+ (eq_attr "op_type" "RI") (const_string "reg")
+ (eq_attr "op_type" "RRE") (const_string "reg")
+ (eq_attr "op_type" "RS") (const_string "agen")
+ (eq_attr "op_type" "RSI") (const_string "agen")
+ (eq_attr "op_type" "S") (const_string "agen")
+ (eq_attr "op_type" "SI") (const_string "agen")
+ (eq_attr "op_type" "SS") (const_string "agen")
+ (eq_attr "op_type" "SSE") (const_string "agen")
+ (eq_attr "op_type" "RXE") (const_string "agen")
+ (eq_attr "op_type" "RSE") (const_string "agen")
+ (eq_attr "op_type" "RIL") (const_string "agen")
+ (eq_attr "op_type" "RXY") (const_string "agen")
+ (eq_attr "op_type" "RSY") (const_string "agen")
+ (eq_attr "op_type" "SIY") (const_string "agen")]
+ (const_string "reg")))
+
+;; Generic pipeline function unit.
(define_function_unit "integer" 1 0
(eq_attr "type" "none") 0 0)
@@ -95,18 +187,42 @@
(eq_attr "type" "integer") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsimpd") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsimps") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "load") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "floadd") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "floads") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "la") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "larl") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "lr") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "branch") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "store") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "fstored") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fstores") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "lm") 2 2)
(define_function_unit "integer" 1 0
@@ -125,13 +241,31 @@
(eq_attr "type" "imul") 7 7)
(define_function_unit "integer" 1 0
- (eq_attr "type" "fmul") 6 6)
+ (eq_attr "type" "fmuld") 6 6)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fmuls") 6 6)
(define_function_unit "integer" 1 0
(eq_attr "type" "idiv") 33 33)
(define_function_unit "integer" 1 0
- (eq_attr "type" "fdiv") 33 33)
+ (eq_attr "type" "fdivd") 33 33)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fdivs") 33 33)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsqrtd") 30 30)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsqrts") 30 30)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "ftoi") 2 2)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "itof") 2 2)
(define_function_unit "integer" 1 0
(eq_attr "type" "o2") 2 2)
@@ -142,11 +276,10 @@
(define_function_unit "integer" 1 0
(eq_attr "type" "other") 5 5)
-;; Operand type. Used to default length attribute values
+;; Pipeline description for z900
-(define_attr "op_type"
- "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE"
- (const_string "RX"))
+(include "2064.md")
+(include "2084.md")
;; Length in bytes.
@@ -158,14 +291,16 @@
(eq_attr "op_type" "RRE") (const_int 4)
(eq_attr "op_type" "RS") (const_int 4)
(eq_attr "op_type" "RSI") (const_int 4)
- (eq_attr "op_type" "RX") (const_int 4)
(eq_attr "op_type" "S") (const_int 4)
(eq_attr "op_type" "SI") (const_int 4)
(eq_attr "op_type" "SS") (const_int 6)
(eq_attr "op_type" "SSE") (const_int 6)
(eq_attr "op_type" "RXE") (const_int 6)
(eq_attr "op_type" "RSE") (const_int 6)
- (eq_attr "op_type" "RIL") (const_int 6)]
+ (eq_attr "op_type" "RIL") (const_int 6)
+ (eq_attr "op_type" "RXY") (const_int 6)
+ (eq_attr "op_type" "RSY") (const_int 6)
+ (eq_attr "op_type" "SIY") (const_int 6)]
(const_int 4)))
;; Define attributes for `asm' insns.
@@ -182,11 +317,11 @@
; CCU: Equal ULess UGreater -- (CL, CLR, CLI, CLM)
; CCS: Equal SLess SGreater -- (C, CR, CH, CHI, ICM)
; CCT: Zero Mixed Mixed Ones (TM, TMH, TML)
-
+
; CCZ -> CCL / CCZ1
; CCZ1 -> CCA/CCU/CCS/CCT
; CCS -> CCA
-
+
; String: CLC, CLCL, CLCLE, CLST, CUSE, MVCL, MVCLE, MVPG, MVST, SRST
; Clobber: CKSM, CFC, CS, CDS, CUUTF, CUTFU, PLO, SPM, STCK, STCKE, TS, TRT, TRE, UPT
@@ -200,48 +335,44 @@
(compare:CC (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "general_operand" "")))]
"TARGET_64BIT"
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
(define_expand "cmpsi"
[(set (reg:CC 33)
(compare:CC (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "general_operand" "")))]
""
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
(define_expand "cmpdf"
[(set (reg:CC 33)
(compare:CC (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "general_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
(define_expand "cmpsf"
[(set (reg:CC 33)
(compare:CC (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "general_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
; Test-under-Mask (zero_extract) instructions
@@ -253,11 +384,10 @@
(match_operand:DI 2 "const_int_operand" "n"))
(const_int 0)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
- && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 64
&& (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
== INTVAL (operands[2]) >> 4"
- "*
{
int part = INTVAL (operands[2]) >> 4;
int block = (1 << INTVAL (operands[1])) - 1;
@@ -267,13 +397,13 @@
switch (part)
{
- case 0: return \"tmhh\\t%0,%x2\";
- case 1: return \"tmhl\\t%0,%x2\";
- case 2: return \"tmlh\\t%0,%x2\";
- case 3: return \"tmll\\t%0,%x2\";
+ case 0: return "tmhh\t%0,%x2";
+ case 1: return "tmhl\t%0,%x2";
+ case 2: return "tmlh\t%0,%x2";
+ case 3: return "tmll\t%0,%x2";
default: abort ();
}
-}"
+}
[(set_attr "op_type" "RI")])
(define_insn "*tmsi_ext"
@@ -283,11 +413,10 @@
(match_operand:SI 2 "const_int_operand" "n"))
(const_int 0)))]
"s390_match_ccmode(insn, CCTmode)
- && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
&& (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
== INTVAL (operands[2]) >> 4"
- "*
{
int part = INTVAL (operands[2]) >> 4;
int block = (1 << INTVAL (operands[1])) - 1;
@@ -297,146 +426,140 @@
switch (part)
{
- case 0: return \"tmh\\t%0,%x2\";
- case 1: return \"tml\\t%0,%x2\";
+ case 0: return "tmh\t%0,%x2";
+ case 1: return "tml\t%0,%x2";
default: abort ();
}
-}"
+}
[(set_attr "op_type" "RI")])
-(define_insn "*tmqi_ext"
+(define_insn "*tmqisi_ext"
[(set (reg 33)
- (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q")
- (match_operand:SI 1 "const_int_operand" "n")
- (match_operand:SI 2 "const_int_operand" "n"))
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,S")
+ (match_operand:SI 1 "const_int_operand" "n,n")
+ (match_operand:SI 2 "const_int_operand" "n,n"))
(const_int 0)))]
- "s390_match_ccmode(insn, CCTmode)
- && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ "!TARGET_64BIT && s390_match_ccmode(insn, CCTmode)
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
- "*
{
int block = (1 << INTVAL (operands[1])) - 1;
int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
operands[2] = GEN_INT (block << shift);
- return \"tm\\t%0,%b2\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b2" : "tmy\t%0,%b2";
+}
+ [(set_attr "op_type" "SI,SIY")])
+
+(define_insn "*tmqidi_ext"
+ [(set (reg 33)
+ (compare (zero_extract:DI (match_operand:QI 0 "memory_operand" "Q,S")
+ (match_operand:SI 1 "const_int_operand" "n,n")
+ (match_operand:SI 2 "const_int_operand" "n,n"))
+ (const_int 0)))]
+ "TARGET_64BIT && s390_match_ccmode(insn, CCTmode)
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
+{
+ int block = (1 << INTVAL (operands[1])) - 1;
+ int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
+
+ operands[2] = GEN_INT (block << shift);
+ return which_alternative == 0 ? "tm\t%0,%b2" : "tmy\t%0,%b2";
+}
+ [(set_attr "op_type" "SI,SIY")])
+
; Test-under-Mask instructions
(define_insn "*tmdi_mem"
[(set (reg 33)
- (compare (and:DI (match_operand:DI 0 "memory_operand" "Q")
- (match_operand:DI 1 "immediate_operand" "n"))
- (match_operand:DI 2 "immediate_operand" "n")))]
- "TARGET_64BIT
- && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], DImode, 0) >= 0"
- "*
+ (compare (and:DI (match_operand:DI 0 "memory_operand" "Q,S")
+ (match_operand:DI 1 "immediate_operand" "n,n"))
+ (match_operand:DI 2 "immediate_operand" "n,n")))]
+ "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
+ && s390_single_part (operands[1], DImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part));
+ int part = s390_single_part (operands[1], DImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
- operands[0] = gen_rtx_MEM (QImode,
+ operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
- return \"tm\\t%0,%b1\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1";
+}
+ [(set_attr "op_type" "SI,SIY")])
(define_insn "*tmsi_mem"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 0 "memory_operand" "Q")
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (match_operand:SI 0 "memory_operand" "Q,S")
+ (match_operand:SI 1 "immediate_operand" "n,n"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], SImode, 0) >= 0"
- "*
+ && s390_single_part (operands[1], SImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part));
+ int part = s390_single_part (operands[1], SImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
- operands[0] = gen_rtx_MEM (QImode,
+ operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
- return \"tm\\t%0,%b1\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1";
+}
+ [(set_attr "op_type" "SI")])
(define_insn "*tmhi_mem"
[(set (reg 33)
- (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "Q") 0)
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "Q,S") 0)
+ (match_operand:SI 1 "immediate_operand" "n,n"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], HImode, 0) >= 0"
- "*
+ && s390_single_part (operands[1], HImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], HImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));
+ int part = s390_single_part (operands[1], HImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
- operands[0] = gen_rtx_MEM (QImode,
+ operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
- return \"tm\\t%0,%b1\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1";
+}
+ [(set_attr "op_type" "SI")])
(define_insn "*tmqi_mem"
[(set (reg 33)
- (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "Q") 0)
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "Q,S") 0)
+ (match_operand:SI 1 "immediate_operand" "n,n"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
- "tm\\t%0,%b1"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ "@
+ tm\t%0,%b1
+ tmy\t%0,%b1"
+ [(set_attr "op_type" "SI,SIY")])
(define_insn "*tmdi_reg"
[(set (reg 33)
- (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d")
- (match_operand:DI 1 "immediate_operand" "n"))
- (match_operand:DI 2 "immediate_operand" "n")))]
+ (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
+ (match_operand:DI 1 "immediate_operand"
+ "N0HD0,N1HD0,N2HD0,N3HD0"))
+ (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
"TARGET_64BIT
&& s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
- && s390_single_hi (operands[1], DImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
-
- switch (part)
- {
- case 0: return \"tmhh\\t%0,%x1\";
- case 1: return \"tmhl\\t%0,%x1\";
- case 2: return \"tmlh\\t%0,%x1\";
- case 3: return \"tmll\\t%0,%x1\";
- default: abort ();
- }
-}"
+ && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
+ "@
+ tmhh\t%0,%i1
+ tmhl\t%0,%i1
+ tmlh\t%0,%i1
+ tmll\t%0,%i1"
[(set_attr "op_type" "RI")])
(define_insn "*tmsi_reg"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d")
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
+ (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
- && s390_single_hi (operands[1], SImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
-
- switch (part)
- {
- case 0: return \"tmh\\t%0,%x1\";
- case 1: return \"tml\\t%0,%x1\";
- default: abort ();
- }
-}"
+ && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
+ "@
+ tmh\t%0,%i1
+ tml\t%0,%i1"
[(set_attr "op_type" "RI")])
(define_insn "*tmhi_full"
@@ -444,7 +567,7 @@
(compare (match_operand:HI 0 "register_operand" "d")
(match_operand:HI 1 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))"
- "tml\\t%0,65535"
+ "tml\t%0,65535"
[(set_attr "op_type" "RX")])
(define_insn "*tmqi_full"
@@ -452,7 +575,7 @@
(compare (match_operand:QI 0 "register_operand" "d")
(match_operand:QI 1 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))"
- "tml\\t%0,255"
+ "tml\t%0,255"
[(set_attr "op_type" "RI")])
@@ -466,7 +589,7 @@
(set (match_operand:DI 2 "register_operand" "=d")
(sign_extend:DI (match_dup 0)))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "ltgfr\\t%2,%0"
+ "ltgfr\t%2,%0"
[(set_attr "op_type" "RRE")])
(define_insn "*tstdi"
@@ -476,7 +599,7 @@
(set (match_operand:DI 2 "register_operand" "=d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "ltgr\\t%2,%0"
+ "ltgr\t%2,%0"
[(set_attr "op_type" "RRE")])
(define_insn "*tstdi_cconly"
@@ -484,7 +607,7 @@
(compare (match_operand:DI 0 "register_operand" "d")
(match_operand:DI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "ltgr\\t%0,%0"
+ "ltgr\t%0,%0"
[(set_attr "op_type" "RRE")])
(define_insn "*tstdi_cconly_31"
@@ -492,132 +615,138 @@
(compare (match_operand:DI 0 "register_operand" "d")
(match_operand:DI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
- "srda\\t%0,0"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
(define_insn "*tstsi"
[(set (reg 33)
- (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
+ (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
(match_operand:SI 1 "const0_operand" "")))
- (set (match_operand:SI 2 "register_operand" "=d,d")
+ (set (match_operand:SI 2 "register_operand" "=d,d,d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode)"
"@
- ltr\\t%2,%0
- icm\\t%2,15,%0"
- [(set_attr "op_type" "RR,RS")
- (set_attr "atype" "reg,mem")])
+ ltr\t%2,%0
+ icm\t%2,15,%0
+ icmy\t%2,15,%0"
+ [(set_attr "op_type" "RR,RS,RSY")])
(define_insn "*tstsi_cconly"
[(set (reg 33)
- (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
+ (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
(match_operand:SI 1 "const0_operand" "")))
- (clobber (match_scratch:SI 2 "=X,d"))]
+ (clobber (match_scratch:SI 2 "=X,d,d"))]
"s390_match_ccmode(insn, CCSmode)"
"@
- ltr\\t%0,%0
- icm\\t%2,15,%0"
- [(set_attr "op_type" "RR,RS")
- (set_attr "atype" "reg,mem")])
+ ltr\t%0,%0
+ icm\t%2,15,%0
+ icmy\t%2,15,%0"
+ [(set_attr "op_type" "RR,RS,RSY")])
(define_insn "*tstsi_cconly2"
[(set (reg 33)
(compare (match_operand:SI 0 "register_operand" "d")
(match_operand:SI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode)"
- "ltr\\t%0,%0"
+ "ltr\t%0,%0"
[(set_attr "op_type" "RR")])
(define_insn "*tsthiCCT"
[(set (reg 33)
- (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,d")
+ (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,?S,d")
(match_operand:HI 1 "const0_operand" "")))
- (set (match_operand:HI 2 "register_operand" "=d,0")
+ (set (match_operand:HI 2 "register_operand" "=d,d,0")
(match_dup 0))]
"s390_match_ccmode(insn, CCTmode)"
"@
- icm\\t%2,3,%0
- tml\\t%0,65535"
- [(set_attr "op_type" "RS,RI")
- (set_attr "atype" "mem,reg")])
+ icm\t%2,3,%0
+ icmy\t%2,3,%0
+ tml\t%0,65535"
+ [(set_attr "op_type" "RS,RSY,RI")])
(define_insn "*tsthiCCT_cconly"
[(set (reg 33)
- (compare (match_operand:HI 0 "nonimmediate_operand" "Q,d")
+ (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
(match_operand:HI 1 "const0_operand" "")))
- (clobber (match_scratch:HI 2 "=d,X"))]
+ (clobber (match_scratch:HI 2 "=d,d,X"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- icm\\t%2,3,%0
- tml\\t%0,65535"
- [(set_attr "op_type" "RS,RI")
- (set_attr "atype" "mem,reg")])
+ icm\t%2,3,%0
+ icmy\t%2,3,%0
+ tml\t%0,65535"
+ [(set_attr "op_type" "RS,RSY,RI")])
(define_insn "*tsthi"
[(set (reg 33)
- (compare (match_operand:HI 0 "s_operand" "Q")
+ (compare (match_operand:HI 0 "s_operand" "Q,S")
(match_operand:HI 1 "const0_operand" "")))
- (set (match_operand:HI 2 "register_operand" "=d")
+ (set (match_operand:HI 2 "register_operand" "=d,d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,3,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,3,%0
+ icmy\t%2,3,%0"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*tsthi_cconly"
[(set (reg 33)
- (compare (match_operand:HI 0 "s_operand" "Q")
+ (compare (match_operand:HI 0 "s_operand" "Q,S")
(match_operand:HI 1 "const0_operand" "")))
- (clobber (match_scratch:HI 2 "=d"))]
+ (clobber (match_scratch:HI 2 "=d,d"))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,3,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,3,%0
+ icmy\t%2,3,%0"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*tstqiCCT"
[(set (reg 33)
- (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+ (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
(match_operand:QI 1 "const0_operand" "")))
- (set (match_operand:QI 2 "register_operand" "=d,0")
+ (set (match_operand:QI 2 "register_operand" "=d,d,0")
(match_dup 0))]
"s390_match_ccmode(insn, CCTmode)"
"@
- icm\\t%2,1,%0
- tml\\t%0,255"
- [(set_attr "op_type" "RS,RI")
- (set_attr "atype" "mem,reg")])
+ icm\t%2,1,%0
+ icmy\t%2,1,%0
+ tml\t%0,255"
+ [(set_attr "op_type" "RS,RSY,RI")])
(define_insn "*tstqiCCT_cconly"
[(set (reg 33)
- (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+ (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
(match_operand:QI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCTmode)"
"@
- cli\\t%0,0
- tml\\t%0,255"
- [(set_attr "op_type" "SI,RI")
- (set_attr "atype" "mem,reg")])
+ cli\t%0,0
+ cliy\t%0,0
+ tml\t%0,255"
+ [(set_attr "op_type" "SI,SIY,RI")])
(define_insn "*tstqi"
[(set (reg 33)
- (compare (match_operand:QI 0 "s_operand" "Q")
+ (compare (match_operand:QI 0 "s_operand" "Q,S")
(match_operand:QI 1 "const0_operand" "")))
- (set (match_operand:QI 2 "register_operand" "=d")
+ (set (match_operand:QI 2 "register_operand" "=d,d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,1,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,1,%0
+ icmy\t%2,1,%0"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*tstqi_cconly"
[(set (reg 33)
- (compare (match_operand:QI 0 "s_operand" "Q")
+ (compare (match_operand:QI 0 "s_operand" "Q,S")
(match_operand:QI 1 "const0_operand" "")))
- (clobber (match_scratch:QI 2 "=d"))]
+ (clobber (match_scratch:QI 2 "=d,d"))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,1,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,1,%0
+ icmy\t%2,1,%0"
+ [(set_attr "op_type" "RS,RSY")])
; Compare (signed) instructions
@@ -628,10 +757,9 @@
(match_operand:DI 0 "register_operand" "d,d")))]
"s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
"@
- cgfr\\t%0,%1
- cgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ cgfr\t%0,%1
+ cgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*cmpdi_ccs"
[(set (reg 33)
@@ -639,33 +767,33 @@
(match_operand:DI 1 "general_operand" "d,K,m")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
"@
- cgr\\t%0,%1
- cghi\\t%0,%c1
- cg\\t%0,%1"
- [(set_attr "op_type" "RRE,RI,RXE")
- (set_attr "atype" "reg,reg,mem")])
-
+ cgr\t%0,%1
+ cghi\t%0,%c1
+ cg\t%0,%1"
+ [(set_attr "op_type" "RRE,RI,RXY")])
+
(define_insn "*cmpsi_ccs_sign"
[(set (reg 33)
- (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))
- (match_operand:SI 0 "register_operand" "d")))]
+ (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T"))
+ (match_operand:SI 0 "register_operand" "d,d")))]
"s390_match_ccmode(insn, CCSRmode)"
- "ch\\t%0,%1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ ch\t%0,%1
+ chy\t%0,%1"
+ [(set_attr "op_type" "RX,RXY")])
(define_insn "*cmpsi_ccs"
[(set (reg 33)
- (compare (match_operand:SI 0 "register_operand" "d,d,d")
- (match_operand:SI 1 "general_operand" "d,K,m")))]
+ (compare (match_operand:SI 0 "register_operand" "d,d,d,d")
+ (match_operand:SI 1 "general_operand" "d,K,R,T")))]
"s390_match_ccmode(insn, CCSmode)"
"@
- cr\\t%0,%1
- chi\\t%0,%c1
- c\\t%0,%1"
- [(set_attr "op_type" "RR,RI,RX")
- (set_attr "atype" "reg,reg,mem")])
-
+ cr\t%0,%1
+ chi\t%0,%c1
+ c\t%0,%1
+ cy\t%0,%1"
+ [(set_attr "op_type" "RR,RI,RX,RXY")])
+
; Compare (unsigned) instructions
@@ -675,10 +803,9 @@
(match_operand:DI 0 "register_operand" "d,d")))]
"s390_match_ccmode(insn, CCURmode) && TARGET_64BIT"
"@
- clgfr\\t%0,%1
- clgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ clgfr\t%0,%1
+ clgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*cmpdi_ccu"
[(set (reg 33)
@@ -686,84 +813,82 @@
(match_operand:DI 1 "general_operand" "d,m")))]
"s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
"@
- clgr\\t%0,%1
- clg\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ clgr\t%0,%1
+ clg\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*cmpsi_ccu"
[(set (reg 33)
- (compare (match_operand:SI 0 "register_operand" "d,d")
- (match_operand:SI 1 "general_operand" "d,m")))]
+ (compare (match_operand:SI 0 "register_operand" "d,d,d")
+ (match_operand:SI 1 "general_operand" "d,R,T")))]
"s390_match_ccmode(insn, CCUmode)"
"@
- clr\\t%0,%1
- cl\\t%0,%1"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ clr\t%0,%1
+ cl\t%0,%1
+ cly\t%0,%1"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*cmphi_ccu"
[(set (reg 33)
- (compare (match_operand:HI 0 "register_operand" "d")
- (match_operand:HI 1 "s_imm_operand" "Q")))]
+ (compare (match_operand:HI 0 "register_operand" "d,d")
+ (match_operand:HI 1 "s_imm_operand" "Q,S")))]
"s390_match_ccmode(insn, CCUmode)"
- "clm\\t%0,3,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ clm\t%0,3,%1
+ clmy\t%0,3,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*cmpqi_ccu"
[(set (reg 33)
- (compare (match_operand:QI 0 "register_operand" "d")
- (match_operand:QI 1 "s_imm_operand" "Q")))]
+ (compare (match_operand:QI 0 "register_operand" "d,d")
+ (match_operand:QI 1 "s_imm_operand" "Q,S")))]
"s390_match_ccmode(insn, CCUmode)"
- "clm\\t%0,1,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ clm\t%0,1,%1
+ clmy\t%0,1,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*cli"
[(set (reg 33)
- (compare (match_operand:QI 0 "memory_operand" "Q")
- (match_operand:QI 1 "immediate_operand" "n")))]
+ (compare (match_operand:QI 0 "memory_operand" "Q,S")
+ (match_operand:QI 1 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, CCUmode)"
- "cli\\t%0,%b1"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ "@
+ cli\t%0,%b1
+ cliy\t%0,%b1"
+ [(set_attr "op_type" "SI,SIY")])
(define_insn "*cmpdi_ccu_mem"
[(set (reg 33)
(compare (match_operand:DI 0 "s_operand" "Q")
(match_operand:DI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*cmpsi_ccu_mem"
[(set (reg 33)
(compare (match_operand:SI 0 "s_operand" "Q")
(match_operand:SI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*cmphi_ccu_mem"
[(set (reg 33)
(compare (match_operand:HI 0 "s_operand" "Q")
(match_operand:HI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*cmpqi_ccu_mem"
[(set (reg 33)
(compare (match_operand:QI 0 "s_operand" "Q")
(match_operand:QI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SS")])
; DF instructions
@@ -773,38 +898,40 @@
(compare (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "ltdbr\\t%0,%0"
- [(set_attr "op_type" "RRE")])
+ "ltdbr\t%0,%0"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
(define_insn "*cmpdf_ccs_0_ibm"
[(set (reg 33)
(compare (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "ltdr\\t%0,%0"
- [(set_attr "op_type" "RR")])
+ "ltdr\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimpd")])
(define_insn "*cmpdf_ccs"
[(set (reg 33)
(compare (match_operand:DF 0 "register_operand" "f,f")
- (match_operand:DF 1 "general_operand" "f,m")))]
+ (match_operand:DF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- cdbr\\t%0,%1
- cdb\\t%0,%1"
+ cdbr\t%0,%1
+ cdb\t%0,%1"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd")])
(define_insn "*cmpdf_ccs_ibm"
[(set (reg 33)
(compare (match_operand:DF 0 "register_operand" "f,f")
- (match_operand:DF 1 "general_operand" "f,m")))]
+ (match_operand:DF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- cdr\\t%0,%1
- cd\\t%0,%1"
+ cdr\t%0,%1
+ cd\t%0,%1"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd")])
; SF instructions
@@ -814,38 +941,40 @@
(compare (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "ltebr\\t%0,%0"
- [(set_attr "op_type" "RRE")])
+ "ltebr\t%0,%0"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
(define_insn "*cmpsf_ccs_0_ibm"
[(set (reg 33)
(compare (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lter\\t%0,%0"
- [(set_attr "op_type" "RR")])
+ "lter\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimps")])
(define_insn "*cmpsf_ccs"
[(set (reg 33)
(compare (match_operand:SF 0 "register_operand" "f,f")
- (match_operand:SF 1 "general_operand" "f,m")))]
+ (match_operand:SF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- cebr\\t%0,%1
- ceb\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ cebr\t%0,%1
+ ceb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps")])
(define_insn "*cmpsf_ccs"
[(set (reg 33)
(compare (match_operand:SF 0 "register_operand" "f,f")
- (match_operand:SF 1 "general_operand" "f,m")))]
+ (match_operand:SF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- cer\\t%0,%1
- ce\\t%0,%1"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ cer\t%0,%1
+ ce\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "type" "fsimps")])
;;
@@ -857,17 +986,17 @@
;
(define_insn "movti"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,o,Q")
- (match_operand:TI 1 "general_operand" "Q,d,dKm,d,Q"))]
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
+ (match_operand:TI 1 "general_operand" "QS,d,dKm,d,Q"))]
"TARGET_64BIT"
"@
- lmg\\t%0,%N0,%1
- stmg\\t%1,%N1,%0
+ lmg\t%0,%N0,%1
+ stmg\t%1,%N1,%0
#
#
- mvc\\t%O0(16,%R0),%1"
- [(set_attr "op_type" "RSE,RSE,NN,NN,SS")
- (set_attr "atype" "mem")])
+ mvc\t%O0(16,%R0),%1"
+ [(set_attr "op_type" "RSY,RSY,NN,NN,SS")
+ (set_attr "type" "lm,stm,*,*,cs")])
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
@@ -929,7 +1058,6 @@
[(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
- "
{
/* Handle symbolic constants. */
if (TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
@@ -938,85 +1066,64 @@
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
- && CONSTANT_P (operands[1])
+ && CONSTANT_P (operands[1])
&& (!legitimate_reload_constant_p (operands[1])
|| FP_REG_P (operands[0])))
operands[1] = force_const_mem (DImode, operands[1]);
-}")
-
-(define_insn "*movdi_lhi"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "immediate_operand" "K"))]
- "TARGET_64BIT
- && GET_CODE (operands[1]) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
- && !FP_REG_P (operands[0])"
- "lghi\\t%0,%h1"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
-
-(define_insn "*movdi_lli"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "immediate_operand" "n"))]
- "TARGET_64BIT && s390_single_hi (operands[1], DImode, 0) >= 0
- && !FP_REG_P (operands[0])"
- "*
-{
- int part = s390_single_hi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
-
- switch (part)
- {
- case 0: return \"llihh\\t%0,%x1\";
- case 1: return \"llihl\\t%0,%x1\";
- case 2: return \"llilh\\t%0,%x1\";
- case 3: return \"llill\\t%0,%x1\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+})
(define_insn "*movdi_larl"
[(set (match_operand:DI 0 "register_operand" "=d")
(match_operand:DI 1 "larl_operand" "X"))]
"TARGET_64BIT
&& !FP_REG_P (operands[0])"
- "larl\\t%0,%1"
+ "larl\t%0,%1"
[(set_attr "op_type" "RIL")
- (set_attr "atype" "reg")
- (set_attr "type" "la")])
+ (set_attr "type" "larl")])
(define_insn "*movdi_64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,?Q")
- (match_operand:DI 1 "general_operand" "d,m,d,*f,m,*f,?Q"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,?Q")
+ (match_operand:DI 1 "general_operand"
+ "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,?Q"))]
"TARGET_64BIT"
"@
- lgr\\t%0,%1
- lg\\t%0,%1
- stg\\t%1,%0
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RRE,RXE,RXE,RR,RX,RX,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ lghi\t%0,%h1
+ llihh\t%0,%i1
+ llihl\t%0,%i1
+ llilh\t%0,%i1
+ llill\t%0,%i1
+ lay\t%0,%a1
+ lgr\t%0,%1
+ lg\t%0,%1
+ stg\t%1,%0
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd,
+ fstored,fstored,cs")])
(define_insn "*movdi_31"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!m,Q")
- (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f,Q"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q")
+ (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,R,T,*f,*f,Q"))]
"!TARGET_64BIT"
"@
- lm\\t%0,%N0,%1
- stm\\t%1,%N1,%0
+ lm\t%0,%N0,%1
+ stm\t%1,%N1,%0
#
#
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX,SS")
- (set_attr "atype" "mem,mem,*,*,reg,mem,mem,mem")])
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "lm,stm,*,*,floadd,floadd,floadd,fstored,fstored,cs")])
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -1083,6 +1190,52 @@
[(set (match_dup 0) (match_dup 2))]
"operands[2] = get_pool_constant (operands[1]);")
+(define_insn "*la_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (match_operand:QI 1 "address_operand" "U,W"))]
+ "TARGET_64BIT"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX,RXY")
+ (set_attr "type" "la")])
+
+(define_peephole2
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT
+ && strict_memory_address_p (VOIDmode, operands[1])
+ && preferred_la_operand_p (operands[1])"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" ""))
+ (parallel
+ [(set (match_dup 0)
+ (plus:DI (match_dup 0)
+ (match_operand:DI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2]))
+ && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))"
+ [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_expand "reload_indi"
+ [(parallel [(match_operand:DI 0 "register_operand" "=a")
+ (match_operand:DI 1 "s390_plus_operand" "")
+ (match_operand:DI 2 "register_operand" "=&a")])]
+ "TARGET_64BIT"
+{
+ s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
;
; movsi instruction pattern(s).
;
@@ -1091,14 +1244,13 @@
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
- "
{
/* Handle symbolic constants. */
if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
emit_symbolic_move (operands);
- /* expr.c tries to load an effective address using
- force_reg. This fails because we don't have a
+ /* expr.c tries to load an effective address using
+ force_reg. This fails because we don't have a
generic load_address pattern. Convert the move
to a proper arithmetic operation instead, unless
it is guaranteed to be OK. */
@@ -1113,54 +1265,61 @@
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
- && CONSTANT_P (operands[1])
+ && CONSTANT_P (operands[1])
&& (!legitimate_reload_constant_p (operands[1])
|| FP_REG_P (operands[0])))
operands[1] = force_const_mem (SImode, operands[1]);
-}")
-
-(define_insn "*movsi_lhi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "immediate_operand" "K"))]
- "GET_CODE (operands[1]) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
- && !FP_REG_P (operands[0])"
- "lhi\\t%0,%h1"
- [(set_attr "op_type" "RI")])
+})
-(define_insn "*movsi_lli"
+(define_insn "*movsi_larl"
[(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "immediate_operand" "n"))]
- "TARGET_64BIT && s390_single_hi (operands[1], SImode, 0) >= 0
+ (match_operand:SI 1 "larl_operand" "X"))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH
&& !FP_REG_P (operands[0])"
- "*
-{
- int part = s390_single_hi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
-
- switch (part)
- {
- case 0: return \"llilh\\t%0,%x1\";
- case 1: return \"llill\\t%0,%x1\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")])
-
-(define_insn "*movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,?Q")
- (match_operand:SI 1 "general_operand" "d,m,d,*f,m,*f,?Q"))]
- ""
- "@
- lr\\t%0,%1
- l\\t%0,%1
- st\\t%1,%0
- ler\\t%0,%1
- le\\t%0,%1
- ste\\t%1,%0
- mvc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ "larl\t%0,%1"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "larl")])
+
+(define_insn "*movsi_zarch"
+ [(set (match_operand:SI 0 "nonimmediate_operand"
+ "=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q")
+ (match_operand:SI 1 "general_operand"
+ "K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,?Q"))]
+ "TARGET_ZARCH"
+ "@
+ lhi\t%0,%h1
+ llilh\t%0,%i1
+ llill\t%0,%i1
+ lay\t%0,%a1
+ lr\t%0,%1
+ l\t%0,%1
+ ly\t%0,%1
+ st\t%1,%0
+ sty\t%1,%0
+ ler\t%0,%1
+ le\t%0,%1
+ ley\t%0,%1
+ ste\t%1,%0
+ stey\t%1,%0
+ mvc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "*,*,*,la,lr,load,load,store,store,floads,floads,floads,fstores,fstores,cs")])
+
+(define_insn "*movsi_esa"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,?Q")
+ (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,?Q"))]
+ "!TARGET_ZARCH"
+ "@
+ lhi\t%0,%h1
+ lr\t%0,%1
+ l\t%0,%1
+ st\t%1,%0
+ ler\t%0,%1
+ le\t%0,%1
+ ste\t%1,%0
+ mvc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,SS")
+ (set_attr "type" "*,lr,load,store,floads,floads,fstores,cs")])
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
@@ -1173,22 +1332,125 @@
[(set (match_dup 0) (match_dup 2))]
"operands[2] = get_pool_constant (operands[1]);")
+(define_insn "*la_31"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (match_operand:QI 1 "address_operand" "U,W"))]
+ "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX,RXY")
+ (set_attr "type" "la")])
+
+(define_peephole2
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT
+ && strict_memory_address_p (VOIDmode, operands[1])
+ && preferred_la_operand_p (operands[1])"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" ""))
+ (parallel
+ [(set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2]))
+ && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))"
+ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_insn "*la_31_and"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (and:SI (match_operand:QI 1 "address_operand" "U,W")
+ (const_int 2147483647)))]
+ "!TARGET_64BIT"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX,RXY")
+ (set_attr "type" "la")])
+
+(define_insn_and_split "*la_31_and_cc"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (and:SI (match_operand:QI 1 "address_operand" "p")
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (and:SI (match_dup 1) (const_int 2147483647)))]
+ ""
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "la")])
+
+(define_insn "force_la_31"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (match_operand:QI 1 "address_operand" "U,W"))
+ (use (const_int 0))]
+ "!TARGET_64BIT"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "la")])
+
+(define_expand "reload_insi"
+ [(parallel [(match_operand:SI 0 "register_operand" "=a")
+ (match_operand:SI 1 "s390_plus_operand" "")
+ (match_operand:SI 2 "register_operand" "=&a")])]
+ "!TARGET_64BIT"
+{
+ s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
;
; movhi instruction pattern(s).
;
-(define_insn "movhi"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,?Q")
- (match_operand:HI 1 "general_operand" "d,n,m,d,?Q"))]
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+{
+ /* Make it explicit that loading a register from memory
+ always sign-extends (at least) to SImode. */
+ if (optimize && !no_new_pseudos
+ && register_operand (operands[0], VOIDmode)
+ && GET_CODE (operands[1]) == MEM
+ && GET_CODE (XEXP (operands[1], 0)) != ADDRESSOF)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
+ emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
+ operands[1] = gen_lowpart (HImode, tmp);
+ }
+})
+
+(define_insn "*movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,T,?Q")
+ (match_operand:HI 1 "general_operand" "d,n,R,T,d,d,?Q"))]
""
"@
- lr\\t%0,%1
- lhi\\t%0,%h1
- lh\\t%0,%1
- sth\\t%1,%0
- mvc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "RR,RI,RX,RX,SS")
- (set_attr "atype" "reg,reg,mem,mem,mem")])
+ lr\t%0,%1
+ lhi\t%0,%h1
+ lh\t%0,%1
+ lhy\t%0,%1
+ sth\t%1,%0
+ sthy\t%1,%0
+ mvc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "lr,*,*,*,store,store,cs")])
(define_peephole2
[(set (match_operand:HI 0 "register_operand" "")
@@ -1204,34 +1466,41 @@
; movqi instruction pattern(s).
;
-(define_insn "movqi_64"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,?Q")
- (match_operand:QI 1 "general_operand" "d,n,m,d,n,?Q"))]
- "TARGET_64BIT"
- "@
- lr\\t%0,%1
- lhi\\t%0,%b1
- llgc\\t%0,%1
- stc\\t%1,%0
- mvi\\t%0,%b1
- mvc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "RR,RI,RXE,RX,SI,SS")
- (set_attr "atype" "reg,reg,mem,mem,mem,mem")])
-
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+{
+ /* On z/Architecture, zero-extending from memory to register
+ is just as fast as a QImode load. */
+ if (TARGET_ZARCH && optimize && !no_new_pseudos
+ && register_operand (operands[0], VOIDmode)
+ && GET_CODE (operands[1]) == MEM
+ && GET_CODE (XEXP (operands[1], 0)) != ADDRESSOF)
+ {
+ rtx tmp = gen_reg_rtx (word_mode);
+ rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+ emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
+ operands[1] = gen_lowpart (QImode, tmp);
+ }
+})
-(define_insn "movqi"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,?Q")
- (match_operand:QI 1 "general_operand" "d,n,m,d,n,?Q"))]
+(define_insn "*movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
+ (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))]
""
"@
- lr\\t%0,%1
- lhi\\t%0,%b1
- ic\\t%0,%1
- stc\\t%1,%0
- mvi\\t%0,%b1
- mvc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "RR,RI,RX,RX,SI,SS")
- (set_attr "atype" "reg,reg,mem,mem,mem,mem")])
+ lr\t%0,%1
+ lhi\t%0,%b1
+ ic\t%0,%1
+ icy\t%0,%1
+ stc\t%1,%0
+ stcy\t%1,%0
+ mvi\t%0,%b1
+ mviy\t%0,%b1
+ mvc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
+ (set_attr "type" "lr,*,*,*,store,store,store,store,cs")])
(define_peephole2
[(set (match_operand:QI 0 "nonimmediate_operand" "")
@@ -1248,41 +1517,42 @@
;
(define_insn "*movstrictqi"
- [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
- (match_operand:QI 1 "memory_operand" "m"))]
+ [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
+ (match_operand:QI 1 "memory_operand" "R,T"))]
""
- "ic\\t%0,%1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ ic\t%0,%1
+ icy\t%0,%1"
+ [(set_attr "op_type" "RX,RXY")])
;
; movstricthi instruction pattern(s).
;
(define_insn "*movstricthi"
- [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
- (match_operand:HI 1 "s_imm_operand" "Q"))
+ [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
+ (match_operand:HI 1 "s_imm_operand" "Q,S"))
(clobber (reg:CC 33))]
""
- "icm\\t%0,3,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
-
+ "@
+ icm\t%0,3,%1
+ icmy\t%0,3,%1"
+ [(set_attr "op_type" "RS,RSY")])
;
; movstrictsi instruction pattern(s).
;
(define_insn "movstrictsi"
- [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d"))
- (match_operand:SI 1 "general_operand" "d,m"))]
+ [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d"))
+ (match_operand:SI 1 "general_operand" "d,R,T"))]
"TARGET_64BIT"
"@
- lr\\t%0,%1
- l\\t%0,%1"
- [(set_attr "op_type" "RR,RS")
- (set_attr "atype" "reg,mem")])
-
+ lr\t%0,%1
+ l\t%0,%1
+ ly\t%0,%1"
+ [(set_attr "op_type" "RR,RX,RXY")
+ (set_attr "type" "lr,load,load")])
;
; movdf instruction pattern(s).
@@ -1292,45 +1562,48 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand:DF 1 "general_operand" ""))]
""
- "
{
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
&& CONSTANT_P (operands[1]))
operands[1] = force_const_mem (DFmode, operands[1]);
-}")
+})
(define_insn "*movdf_64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m,?Q")
- (match_operand:DF 1 "general_operand" "f,m,f,d,m,d,?Q"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,T,d,d,m,?Q")
+ (match_operand:DF 1 "general_operand" "f,R,T,f,f,d,m,d,?Q"))]
"TARGET_64BIT"
"@
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- lgr\\t%0,%1
- lg\\t%0,%1
- stg\\t%1,%0
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RRE,RXE,RXE,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ lgr\t%0,%1
+ lg\t%0,%1
+ stg\t%1,%0
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
+ (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lr,load,store,cs")])
(define_insn "*movdf_31"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,o,Q")
- (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d,Q"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,T,d,Q,d,o,Q")
+ (match_operand:DF 1 "general_operand" "f,R,T,f,f,Q,d,dKm,d,Q"))]
"!TARGET_64BIT"
"@
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- lm\\t%0,%N0,%1
- stm\\t%1,%N1,%0
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ lm\t%0,%N0,%1
+ stm\t%1,%N1,%0
#
#
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN,SS")
- (set_attr "atype" "reg,mem,mem,mem,mem,*,*,mem")])
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RS,RS,NN,NN,SS")
+ (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lm,stm,*,*,cs")])
(define_split
[(set (match_operand:DF 0 "nonimmediate_operand" "")
@@ -1393,41 +1666,47 @@
[(set (match_operand:SF 0 "nonimmediate_operand" "")
(match_operand:SF 1 "general_operand" ""))]
""
- "
{
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
&& CONSTANT_P (operands[1]))
operands[1] = force_const_mem (SFmode, operands[1]);
-}")
+})
(define_insn "*movsf"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m,?Q")
- (match_operand:SF 1 "general_operand" "f,m,f,d,m,d,?Q"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,R,T,d,d,d,R,T,?Q")
+ (match_operand:SF 1 "general_operand" "f,R,T,f,f,d,R,T,d,d,?Q"))]
""
"@
- ler\\t%0,%1
- le\\t%0,%1
- ste\\t%1,%0
- lr\\t%0,%1
- l\\t%0,%1
- st\\t%1,%0
- mvc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ ler\t%0,%1
+ le\t%0,%1
+ ley\t%0,%1
+ ste\t%1,%0
+ stey\t%1,%0
+ lr\t%0,%1
+ l\t%0,%1
+ ly\t%0,%1
+ st\t%1,%0
+ sty\t%1,%0
+ mvc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "floads,floads,floads,fstores,fstores,lr,load,load,store,store,cs")])
;
; load_multiple pattern(s).
;
+; ??? Due to reload problems with replacing registers inside match_parallel
+; we currently support load_multiple/store_multiple only after reload.
+;
(define_expand "load_multiple"
[(match_par_dup 3 [(set (match_operand 0 "" "")
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))])]
- ""
- "
+ "reload_completed"
{
+ enum machine_mode mode;
int regno;
int count;
rtx from;
@@ -1445,6 +1724,9 @@
count = INTVAL (operands[2]);
regno = REGNO (operands[0]);
+ mode = GET_MODE (operands[0]);
+ if (mode != SImode && mode != word_mode)
+ FAIL;
operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
if (no_new_pseudos)
@@ -1475,61 +1757,48 @@
for (i = 0; i < count; i++)
XVECEXP (operands[3], 0, i)
- = gen_rtx_SET (VOIDmode, gen_rtx_REG (Pmode, regno + i),
- change_address (operands[1], Pmode,
- plus_constant (from,
- off + i * UNITS_PER_WORD)));
-}")
+ = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i),
+ change_address (operands[1], mode,
+ plus_constant (from, off + i * GET_MODE_SIZE (mode))));
+})
(define_insn "*load_multiple_di"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:DI 1 "register_operand" "=r")
- (match_operand:DI 2 "s_operand" "Q"))])]
- ""
- "*
+ (match_operand:DI 2 "s_operand" "QS"))])]
+ "reload_completed && word_mode == DImode"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"lg\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
- return \"lmg\\t%1,%0,%2\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return "lmg\t%1,%0,%2";
+}
+ [(set_attr "op_type" "RSY")
(set_attr "type" "lm")])
(define_insn "*load_multiple_si"
[(match_parallel 0 "load_multiple_operation"
- [(set (match_operand:SI 1 "register_operand" "=r")
- (match_operand:SI 2 "s_operand" "Q"))])]
- ""
- "*
+ [(set (match_operand:SI 1 "register_operand" "=r,r")
+ (match_operand:SI 2 "s_operand" "Q,S"))])]
+ "reload_completed"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"l\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
- return \"lm\\t%1,%0,%2\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return which_alternative == 0 ? "lm\t%1,%0,%2" : "lmy\t%1,%0,%2";
+}
+ [(set_attr "op_type" "RS,RSY")
(set_attr "type" "lm")])
;
-; store multiple pattern(s).
+; store multiple pattern(s).
;
(define_expand "store_multiple"
[(match_par_dup 3 [(set (match_operand 0 "" "")
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))])]
- ""
- "
+ "reload_completed"
{
+ enum machine_mode mode;
int regno;
int count;
rtx to;
@@ -1547,6 +1816,9 @@
count = INTVAL (operands[2]);
regno = REGNO (operands[1]);
+ mode = GET_MODE (operands[1]);
+ if (mode != SImode && mode != word_mode)
+ FAIL;
operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
@@ -1570,7 +1842,7 @@
if (to == frame_pointer_rtx || to == arg_pointer_rtx)
FAIL;
}
- else
+ else
{
to = force_reg (Pmode, XEXP (operands[0], 0));
off = 0;
@@ -1579,49 +1851,36 @@
for (i = 0; i < count; i++)
XVECEXP (operands[3], 0, i)
= gen_rtx_SET (VOIDmode,
- change_address (operands[0], Pmode,
- plus_constant (to,
- off + i * UNITS_PER_WORD)),
- gen_rtx_REG (Pmode, regno + i));
-}")
+ change_address (operands[0], mode,
+ plus_constant (to, off + i * GET_MODE_SIZE (mode))),
+ gen_rtx_REG (mode, regno + i));
+})
(define_insn "*store_multiple_di"
[(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:DI 1 "s_operand" "=Q")
+ [(set (match_operand:DI 1 "s_operand" "=QS")
(match_operand:DI 2 "register_operand" "r"))])]
- ""
- "*
+ "reload_completed && word_mode == DImode"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"stg\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
- return \"stmg\\t%2,%0,%1\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return "stmg\t%2,%0,%1";
+}
+ [(set_attr "op_type" "RSY")
(set_attr "type" "stm")])
(define_insn "*store_multiple_si"
[(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:SI 1 "s_operand" "=Q")
- (match_operand:SI 2 "register_operand" "r"))])]
- ""
- "*
+ [(set (match_operand:SI 1 "s_operand" "=Q,S")
+ (match_operand:SI 2 "register_operand" "r,r"))])]
+ "reload_completed"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"st\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
- return \"stm\\t%2,%0,%1\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return which_alternative == 0 ? "stm\t%2,%0,%1" : "stmy\t%2,%0,%1";
+}
+ [(set_attr "op_type" "RS,RSY")
(set_attr "type" "stm")])
;;
@@ -1629,6 +1888,82 @@
;;
;
+; strlenM instruction pattern(s).
+;
+
+(define_expand "strlendi"
+ [(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" ""))
+ (parallel
+ [(set (match_dup 4)
+ (unspec:DI [(const_int 0)
+ (match_operand:BLK 1 "memory_operand" "")
+ (reg:QI 0)
+ (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (scratch:DI))
+ (clobber (reg:CC 33))])
+ (parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (minus:DI (match_dup 4) (match_dup 5)))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT"
+{
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+ emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
+ operands[1] = replace_equiv_address (operands[1], operands[5]);
+})
+
+(define_insn "*strlendi"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (unspec:DI [(match_operand:DI 2 "general_operand" "0")
+ (mem:BLK (match_operand:DI 3 "register_operand" "1"))
+ (reg:QI 0)
+ (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (match_scratch:DI 1 "=a"))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "srst\t%0,%1\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
+
+(define_expand "strlensi"
+ [(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" ""))
+ (parallel
+ [(set (match_dup 4)
+ (unspec:SI [(const_int 0)
+ (match_operand:BLK 1 "memory_operand" "")
+ (reg:QI 0)
+ (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (scratch:SI))
+ (clobber (reg:CC 33))])
+ (parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (minus:SI (match_dup 4) (match_dup 5)))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT"
+{
+ operands[4] = gen_reg_rtx (SImode);
+ operands[5] = gen_reg_rtx (SImode);
+ emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
+ operands[1] = replace_equiv_address (operands[1], operands[5]);
+})
+
+(define_insn "*strlensi"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(match_operand:SI 2 "general_operand" "0")
+ (mem:BLK (match_operand:SI 3 "register_operand" "1"))
+ (reg:QI 0)
+ (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (match_scratch:SI 1 "=a"))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "srst\t%0,%1\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
+
+;
; movstrM instruction pattern(s).
;
@@ -1651,98 +1986,103 @@
; Move a block that is up to 256 bytes in length.
; The block length is taken as (operands[2] % 256) + 1.
-(define_insn "movstr_short_64"
- [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
- (match_operand:BLK 1 "memory_operand" "Q,Q"))
- (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:DI 3 "=X,&a"))]
- "TARGET_64BIT"
- "*
-{
- switch (which_alternative)
- {
- case 0:
- return \"mvc\\t%O0(%b2+1,%R0),%1\";
-
- case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
-
- default:
- abort ();
- }
-}"
- [(set_attr "op_type" "SS,NN")
- (set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
- (set_attr "length" "*,14")])
+(define_expand "movstr_short"
+ [(parallel
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand 2 "nonmemory_operand" ""))
+ (clobber (match_dup 3))])]
+ ""
+ "operands[3] = gen_rtx_SCRATCH (Pmode);")
-(define_insn "movstr_short_31"
+(define_insn "*movstr_short"
[(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
(match_operand:BLK 1 "memory_operand" "Q,Q"))
- (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:SI 3 "=X,&a"))]
- "!TARGET_64BIT"
- "*
+ (use (match_operand 2 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch 3 "=X,&a"))]
+ "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
+ && GET_MODE (operands[3]) == Pmode"
{
switch (which_alternative)
{
case 0:
- return \"mvc\\t%O0(%b2+1,%R0),%1\";
+ return "mvc\t%O0(%b2+1,%R0),%1";
case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
+ output_asm_insn ("bras\t%3,.+10", operands);
+ output_asm_insn ("mvc\t%O0(1,%R0),%1", operands);
+ return "ex\t%2,0(%3)";
default:
abort ();
}
-}"
+}
[(set_attr "op_type" "SS,NN")
(set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
+ (set_attr "atype" "*,agen")
(set_attr "length" "*,14")])
; Move a block of arbitrary length.
-(define_insn "movstr_long_64"
- [(set (match_operand:TI 0 "register_operand" "=d")
- (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
- (lshiftrt:TI (match_dup 2) (const_int 64)))
- (const_int 64)))
- (set (match_operand:TI 1 "register_operand" "=d")
- (ashift:TI (plus:TI (match_operand:TI 3 "register_operand" "1")
- (lshiftrt:TI (match_dup 3) (const_int 64)))
- (const_int 64)))
- (set (mem:BLK (subreg:DI (match_dup 2) 0))
- (mem:BLK (subreg:DI (match_dup 3) 0)))
+(define_expand "movstr_long"
+ [(parallel
+ [(clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand 2 "general_operand" ""))
+ (use (match_dup 3))
+ (clobber (reg:CC 33))])]
+ ""
+{
+ enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
+ rtx reg0 = gen_reg_rtx (dword_mode);
+ rtx reg1 = gen_reg_rtx (dword_mode);
+ rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
+ rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
+ rtx len0 = gen_lowpart (Pmode, reg0);
+ rtx len1 = gen_lowpart (Pmode, reg1);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+ emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
+ emit_move_insn (len0, operands[2]);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
+ emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
+ emit_move_insn (len1, operands[2]);
+
+ operands[0] = replace_equiv_address_nv (operands[0], addr0);
+ operands[1] = replace_equiv_address_nv (operands[1], addr1);
+ operands[2] = reg0;
+ operands[3] = reg1;
+})
+
+(define_insn "*movstr_long_64"
+ [(clobber (match_operand:TI 0 "register_operand" "=d"))
+ (clobber (match_operand:TI 1 "register_operand" "=d"))
+ (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
+ (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0)))
+ (use (match_dup 2))
+ (use (match_dup 3))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
(set_attr "type" "vs")
- (set_attr "atype" "mem")
(set_attr "length" "8")])
-(define_insn "movstr_long_31"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
- (lshiftrt:DI (match_dup 2) (const_int 32)))
- (const_int 32)))
- (set (match_operand:DI 1 "register_operand" "=d")
- (ashift:DI (plus:DI (match_operand:DI 3 "register_operand" "1")
- (lshiftrt:DI (match_dup 3) (const_int 32)))
- (const_int 32)))
- (set (mem:BLK (subreg:SI (match_dup 2) 0))
- (mem:BLK (subreg:SI (match_dup 3) 0)))
+(define_insn "*movstr_long_31"
+ [(clobber (match_operand:DI 0 "register_operand" "=d"))
+ (clobber (match_operand:DI 1 "register_operand" "=d"))
+ (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
+ (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0)))
+ (use (match_dup 2))
+ (use (match_dup 3))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
(set_attr "type" "vs")
- (set_attr "atype" "mem")
(set_attr "length" "8")])
;
@@ -1766,184 +2106,202 @@
"s390_expand_clrstr (operands[0], operands[1]); DONE;")
; Clear a block that is up to 256 bytes in length.
-; The block length is taken as (operands[2] % 256) + 1.
+; The block length is taken as (operands[1] % 256) + 1.
-(define_insn "clrstr_short_64"
+(define_expand "clrstr_short"
+ [(parallel
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (const_int 0))
+ (use (match_operand 1 "nonmemory_operand" ""))
+ (clobber (match_dup 2))
+ (clobber (reg:CC 33))])]
+ ""
+ "operands[2] = gen_rtx_SCRATCH (Pmode);")
+
+(define_insn "*clrstr_short"
[(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
(const_int 0))
- (use (match_operand:DI 1 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:DI 2 "=X,&a"))
+ (use (match_operand 1 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch 2 "=X,&a"))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
- "*
+ "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)
+ && GET_MODE (operands[2]) == Pmode"
{
switch (which_alternative)
{
case 0:
- return \"xc\\t%O0(%b1+1,%R0),%0\";
+ return "xc\t%O0(%b1+1,%R0),%0";
case 1:
- output_asm_insn (\"bras\\t%2,.+10\", operands);
- output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands);
- return \"ex\\t%1,0(%2)\";
+ output_asm_insn ("bras\t%2,.+10", operands);
+ output_asm_insn ("xc\t%O0(1,%R0),%0", operands);
+ return "ex\t%1,0(%2)";
default:
abort ();
}
-}"
+}
[(set_attr "op_type" "SS,NN")
(set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
+ (set_attr "atype" "*,agen")
(set_attr "length" "*,14")])
-(define_insn "clrstr_short_31"
- [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
- (const_int 0))
- (use (match_operand:SI 1 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:SI 2 "=X,&a"))
- (clobber (reg:CC 33))]
- "!TARGET_64BIT"
- "*
+; Clear a block of arbitrary length.
+
+(define_expand "clrstr_long"
+ [(parallel
+ [(clobber (match_dup 1))
+ (set (match_operand:BLK 0 "memory_operand" "")
+ (const_int 0))
+ (use (match_operand 1 "general_operand" ""))
+ (use (match_dup 2))
+ (clobber (reg:CC 33))])]
+ ""
{
- switch (which_alternative)
- {
- case 0:
- return \"xc\\t%O0(%b1+1,%R0),%0\";
+ enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
+ rtx reg0 = gen_reg_rtx (dword_mode);
+ rtx reg1 = gen_reg_rtx (dword_mode);
+ rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
+ rtx len0 = gen_lowpart (Pmode, reg0);
- case 1:
- output_asm_insn (\"bras\\t%2,.+10\", operands);
- output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands);
- return \"ex\\t%1,0(%2)\";
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+ emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
+ emit_move_insn (len0, operands[1]);
- default:
- abort ();
- }
-}"
- [(set_attr "op_type" "SS,NN")
- (set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
- (set_attr "length" "*,14")])
+ emit_move_insn (reg1, const0_rtx);
-; Clear a block of arbitrary length.
+ operands[0] = replace_equiv_address_nv (operands[0], addr0);
+ operands[1] = reg0;
+ operands[2] = reg1;
+})
-(define_insn "clrstr_long_64"
- [(set (match_operand:TI 0 "register_operand" "=d")
- (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
- (lshiftrt:TI (match_dup 2) (const_int 64)))
- (const_int 64)))
- (set (mem:BLK (subreg:DI (match_dup 2) 0))
+(define_insn "*clrstr_long_64"
+ [(clobber (match_operand:TI 0 "register_operand" "=d"))
+ (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
(const_int 0))
+ (use (match_dup 2))
(use (match_operand:TI 1 "register_operand" "d"))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
- (set_attr "atype" "mem")
(set_attr "type" "vs")
(set_attr "length" "8")])
-(define_insn "clrstr_long_31"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
- (lshiftrt:DI (match_dup 2) (const_int 32)))
- (const_int 32)))
- (set (mem:BLK (subreg:SI (match_dup 2) 0))
+(define_insn "*clrstr_long_31"
+ [(clobber (match_operand:DI 0 "register_operand" "=d"))
+ (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
(const_int 0))
+ (use (match_dup 2))
(use (match_operand:DI 1 "register_operand" "d"))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
- (set_attr "atype" "mem")
(set_attr "type" "vs")
(set_attr "length" "8")])
;
-; cmpstrM instruction pattern(s).
+; cmpmemM instruction pattern(s).
;
-(define_expand "cmpstrdi"
+(define_expand "cmpmemdi"
[(set (match_operand:DI 0 "register_operand" "")
(compare:DI (match_operand:BLK 1 "memory_operand" "")
(match_operand:BLK 2 "memory_operand" "") ) )
(use (match_operand:DI 3 "general_operand" ""))
(use (match_operand:DI 4 "" ""))]
"TARGET_64BIT"
- "s390_expand_cmpstr (operands[0], operands[1],
+ "s390_expand_cmpmem (operands[0], operands[1],
operands[2], operands[3]); DONE;")
-(define_expand "cmpstrsi"
+(define_expand "cmpmemsi"
[(set (match_operand:SI 0 "register_operand" "")
(compare:SI (match_operand:BLK 1 "memory_operand" "")
(match_operand:BLK 2 "memory_operand" "") ) )
(use (match_operand:SI 3 "general_operand" ""))
(use (match_operand:SI 4 "" ""))]
""
- "s390_expand_cmpstr (operands[0], operands[1],
+ "s390_expand_cmpmem (operands[0], operands[1],
operands[2], operands[3]); DONE;")
; Compare a block that is up to 256 bytes in length.
; The block length is taken as (operands[2] % 256) + 1.
-(define_insn "cmpstr_short_64"
- [(set (reg:CCS 33)
- (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
- (match_operand:BLK 1 "memory_operand" "Q,Q")))
- (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:DI 3 "=X,&a"))]
- "TARGET_64BIT"
- "*
-{
- switch (which_alternative)
- {
- case 0:
- return \"clc\\t%O0(%b2+1,%R0),%1\";
-
- case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
-
- default:
- abort ();
- }
-}"
- [(set_attr "op_type" "SS,NN")
- (set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
- (set_attr "length" "*,14")])
+(define_expand "cmpmem_short"
+ [(parallel
+ [(set (reg:CCS 33)
+ (compare:CCS (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" "")))
+ (use (match_operand 2 "nonmemory_operand" ""))
+ (clobber (match_dup 3))])]
+ ""
+ "operands[3] = gen_rtx_SCRATCH (Pmode);")
-(define_insn "cmpstr_short_31"
+(define_insn "*cmpmem_short"
[(set (reg:CCS 33)
(compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
(match_operand:BLK 1 "memory_operand" "Q,Q")))
- (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:SI 3 "=X,&a"))]
- "!TARGET_64BIT"
- "*
+ (use (match_operand 2 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch 3 "=X,&a"))]
+ "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
+ && GET_MODE (operands[3]) == Pmode"
{
switch (which_alternative)
{
case 0:
- return \"clc\\t%O0(%b2+1,%R0),%1\";
+ return "clc\t%O0(%b2+1,%R0),%1";
case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
+ output_asm_insn ("bras\t%3,.+10", operands);
+ output_asm_insn ("clc\t%O0(1,%R0),%1", operands);
+ return "ex\t%2,0(%3)";
default:
abort ();
}
-}"
+}
[(set_attr "op_type" "SS,NN")
(set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
+ (set_attr "atype" "*,agen")
(set_attr "length" "*,14")])
; Compare a block of arbitrary length.
-(define_insn "cmpstr_long_64"
+(define_expand "cmpmem_long"
+ [(parallel
+ [(clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (set (reg:CCS 33)
+ (compare:CCS (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" "")))
+ (use (match_operand 2 "general_operand" ""))
+ (use (match_dup 3))])]
+ ""
+{
+ enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
+ rtx reg0 = gen_reg_rtx (dword_mode);
+ rtx reg1 = gen_reg_rtx (dword_mode);
+ rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
+ rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
+ rtx len0 = gen_lowpart (Pmode, reg0);
+ rtx len1 = gen_lowpart (Pmode, reg1);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+ emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
+ emit_move_insn (len0, operands[2]);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
+ emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
+ emit_move_insn (len1, operands[2]);
+
+ operands[0] = replace_equiv_address_nv (operands[0], addr0);
+ operands[1] = replace_equiv_address_nv (operands[1], addr1);
+ operands[2] = reg0;
+ operands[3] = reg1;
+})
+
+(define_insn "*cmpmem_long_64"
[(clobber (match_operand:TI 0 "register_operand" "=d"))
(clobber (match_operand:TI 1 "register_operand" "=d"))
(set (reg:CCS 33)
@@ -1952,12 +2310,12 @@
(use (match_dup 2))
(use (match_dup 3))]
"TARGET_64BIT"
- "clcl\\t%0,%1"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "mem")
- (set_attr "type" "vs")])
+ "clcle\t%0,%1,0\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
-(define_insn "cmpstr_long_31"
+(define_insn "*cmpmem_long_31"
[(clobber (match_operand:DI 0 "register_operand" "=d"))
(clobber (match_operand:DI 1 "register_operand" "=d"))
(set (reg:CCS 33)
@@ -1966,10 +2324,10 @@
(use (match_dup 2))
(use (match_dup 3))]
"!TARGET_64BIT"
- "clcl\\t%0,%1"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "mem")
- (set_attr "type" "vs")])
+ "clcle\t%0,%1,0\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
; Convert condition code to integer in range (-1, 0, 1)
@@ -1977,34 +2335,30 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(compare:SI (reg:CCS 33) (const_int 0)))]
""
- "*
{
- output_asm_insn (\"lhi\\t%0,1\", operands);
- output_asm_insn (\"jh\\t.+12\", operands);
- output_asm_insn (\"jl\\t.+6\", operands);
- output_asm_insn (\"sr\\t%0,%0\", operands);
- return \"lcr\\t%0,%0\";
-}"
+ output_asm_insn ("lhi\t%0,1", operands);
+ output_asm_insn ("jh\t.+12", operands);
+ output_asm_insn ("jl\t.+6", operands);
+ output_asm_insn ("sr\t%0,%0", operands);
+ return "lcr\t%0,%0";
+}
[(set_attr "op_type" "NN")
(set_attr "length" "16")
- (set_attr "atype" "reg")
(set_attr "type" "other")])
(define_insn "cmpint_di"
[(set (match_operand:DI 0 "register_operand" "=d")
(compare:DI (reg:CCS 33) (const_int 0)))]
"TARGET_64BIT"
- "*
{
- output_asm_insn (\"lghi\\t%0,1\", operands);
- output_asm_insn (\"jh\\t.+12\", operands);
- output_asm_insn (\"jl\\t.+6\", operands);
- output_asm_insn (\"sgr\\t%0,%0\", operands);
- return \"lcgr\\t%0,%0\";
-}"
+ output_asm_insn ("lghi\t%0,1", operands);
+ output_asm_insn ("jh\t.+16", operands);
+ output_asm_insn ("jl\t.+8", operands);
+ output_asm_insn ("sgr\t%0,%0", operands);
+ return "lcgr\t%0,%0";
+}
[(set_attr "op_type" "NN")
- (set_attr "length" "22")
- (set_attr "atype" "reg")
+ (set_attr "length" "20")
(set_attr "type" "other")])
@@ -2013,40 +2367,42 @@
;;
(define_insn "*sethighqisi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (unspec:SI [(match_operand:QI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
""
- "icm\\t%0,8,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%0,8,%1
+ icmy\t%0,8,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*sethighhisi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (unspec:SI [(match_operand:HI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
""
- "icm\\t%0,12,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%0,12,%1
+ icmy\t%0,12,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*sethighqidi_64"
[(set (match_operand:DI 0 "register_operand" "=d")
- (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
+ (unspec:DI [(match_operand:QI 1 "s_operand" "QS")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "icmh\\t%0,8,%1"
- [(set_attr "op_type" "RSE")
- (set_attr "atype" "mem")])
+ "icmh\t%0,8,%1"
+ [(set_attr "op_type" "RSY")])
(define_insn "*sethighqidi_31"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (unspec:DI [(match_operand:QI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "icm\\t%0,8,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%0,8,%1
+ icmy\t%0,8,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn_and_split "*extractqi"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -2059,15 +2415,14 @@
"#"
"&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
- "
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], QImode, 0);
-}"
- [(set_attr "atype" "mem")])
+}
+ [(set_attr "atype" "agen")])
(define_insn_and_split "*extracthi"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -2080,15 +2435,14 @@
"#"
"&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
- "
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], HImode, 0);
-}"
- [(set_attr "atype" "mem")])
+}
+ [(set_attr "atype" "agen")])
;
; extendsidi2 instruction pattern(s).
@@ -2116,10 +2470,9 @@
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
"TARGET_64BIT"
"@
- lgfr\\t%0,%1
- lgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ lgfr\t%0,%1
+ lgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
;
; extendhidi2 instruction pattern(s).
@@ -2142,7 +2495,7 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
- emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (48)));
+ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (48)));
DONE;
}
}
@@ -2152,9 +2505,8 @@
[(set (match_operand:DI 0 "register_operand" "=d")
(sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "lgh\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "lgh\t%0,%1"
+ [(set_attr "op_type" "RXY")])
;
; extendqidi2 instruction pattern(s).
@@ -2177,18 +2529,28 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
- emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (56)));
+ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (56)));
DONE;
}
}
")
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:QI 1 "s_operand" "")))]
- "TARGET_64BIT && !reload_completed"
+(define_insn "*extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_64BIT && TARGET_LONG_DISPLACEMENT"
+ "lgb\t%0,%1"
+ [(set_attr "op_type" "RXY")])
+
+(define_insn_and_split "*extendqidi2_short_displ"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:QI 1 "s_operand" "Q")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && !TARGET_LONG_DISPLACEMENT"
+ "#"
+ "&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:DI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(parallel
[(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))
@@ -2207,18 +2569,19 @@
{
operands[1] = gen_lowpart (SImode, operands[1]);
emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (16)));
- emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (16)));
+ emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (16)));
DONE;
}
")
(define_insn "*extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
""
- "lh\\t%0,%1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ lh\t%0,%1
+ lhy\t%0,%1"
+ [(set_attr "op_type" "RX,RXY")])
;
; extendqisi2 instruction pattern(s).
@@ -2232,17 +2595,27 @@
{
operands[1] = gen_lowpart (SImode, operands[1]);
emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (24)));
- emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (24)));
+ emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (24)));
DONE;
}
")
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:QI 1 "s_operand" "")))]
- "!reload_completed"
+(define_insn "*extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_LONG_DISPLACEMENT"
+ "lb\t%0,%1"
+ [(set_attr "op_type" "RXY")])
+
+(define_insn_and_split "*extendsiqi2_short_displ"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI (match_operand:QI 1 "s_operand" "Q")))
+ (clobber (reg:CC 33))]
+ "!TARGET_LONG_DISPLACEMENT"
+ "#"
+ "&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(parallel
[(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))
@@ -2279,10 +2652,9 @@
(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
"TARGET_64BIT"
"@
- llgfr\\t%0,%1
- llgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ llgfr\t%0,%1
+ llgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
;
; zero_extendhidi2 instruction pattern(s).
@@ -2305,7 +2677,7 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
- emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (48)));
+ emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (48)));
DONE;
}
}
@@ -2315,9 +2687,75 @@
[(set (match_operand:DI 0 "register_operand" "=d")
(zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "llgh\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "llgh\t%0,%1"
+ [(set_attr "op_type" "RXY")])
+
+;
+; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
+;
+
+(define_insn "*llgt_sisi"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m")
+ (const_int 2147483647)))]
+ "TARGET_64BIT"
+ "@
+ llgtr\t%0,%1
+ llgt\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && reload_completed"
+ [(set (match_dup 0)
+ (and:SI (match_dup 1)
+ (const_int 2147483647)))]
+ "")
+
+(define_insn "*llgt_didi"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
+ (const_int 2147483647)))]
+ "TARGET_64BIT"
+ "@
+ llgtr\t%0,%1
+ llgt\t%0,%N1"
+ [(set_attr "op_type" "RRE,RXE")])
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && reload_completed"
+ [(set (match_dup 0)
+ (and:DI (match_dup 1)
+ (const_int 2147483647)))]
+ "")
+
+(define_insn "*llgt_sidi"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
+ (const_int 2147483647)))]
+ "TARGET_64BIT"
+ "llgt\t%0,%1"
+ [(set_attr "op_type" "RXE")])
+
+(define_insn_and_split "*llgt_sidi_split"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (and:DI (subreg:DI (match_dup 1) 0)
+ (const_int 2147483647)))]
+ "")
;
; zero_extendqidi2 instruction pattern(s)
@@ -2340,7 +2778,7 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
- emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (56)));
+ emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (56)));
DONE;
}
}
@@ -2350,9 +2788,8 @@
[(set (match_operand:DI 0 "register_operand" "=d")
(zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "llgc\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "llgc\t%0,%1"
+ [(set_attr "op_type" "RXY")])
;
; zero_extendhisi2 instruction pattern(s).
@@ -2374,13 +2811,12 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "llgh\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "llgh\t%0,%1"
+ [(set_attr "op_type" "RXY")])
(define_insn_and_split "*zero_extendhisi2_31"
[(set (match_operand:SI 0 "register_operand" "=&d")
- (zero_extend:SI (match_operand:HI 1 "memory_operand" "Q")))
+ (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
"#"
@@ -2390,8 +2826,8 @@
[(set (strict_low_part (match_dup 2)) (match_dup 1))
(clobber (reg:CC 33))])]
"operands[2] = gen_lowpart (HImode, operands[0]);"
- [(set_attr "atype" "mem")])
-
+ [(set_attr "atype" "agen")])
+
;
; zero_extendqisi2 instruction pattern(s).
;
@@ -2411,22 +2847,21 @@
(define_insn "*zero_extendqisi2_64"
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_64BIT"
- "llgc\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "TARGET_ZARCH"
+ "llgc\t%0,%1"
+ [(set_attr "op_type" "RXY")])
(define_insn_and_split "*zero_extendqisi2_31"
[(set (match_operand:SI 0 "register_operand" "=&d")
(zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "!TARGET_64BIT"
+ "!TARGET_ZARCH"
"#"
"&& reload_completed"
[(set (match_dup 0) (const_int 0))
(set (strict_low_part (match_dup 2)) (match_dup 1))]
"operands[2] = gen_lowpart (QImode, operands[0]);"
- [(set_attr "atype" "mem")])
-
+ [(set_attr "atype" "agen")])
+
;
; zero_extendqihi2 instruction pattern(s).
;
@@ -2434,7 +2869,7 @@
(define_expand "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "")
(zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"
{
operands[1] = gen_lowpart (HImode, operands[1]);
@@ -2446,21 +2881,20 @@
(define_insn "*zero_extendqihi2_64"
[(set (match_operand:HI 0 "register_operand" "=d")
(zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_64BIT"
- "llgc\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "TARGET_ZARCH"
+ "llgc\t%0,%1"
+ [(set_attr "op_type" "RXY")])
(define_insn_and_split "*zero_extendqihi2_31"
[(set (match_operand:HI 0 "register_operand" "=&d")
(zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
- "!TARGET_64BIT"
+ "!TARGET_ZARCH"
"#"
"&& reload_completed"
[(set (match_dup 0) (const_int 0))
(set (strict_low_part (match_dup 2)) (match_dup 1))]
"operands[2] = gen_lowpart (QImode, operands[0]);"
- [(set_attr "atype" "mem")])
+ [(set_attr "atype" "agen")])
;
@@ -2471,20 +2905,19 @@
[(set (match_operand:DI 0 "register_operand" "")
(unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx temp = gen_reg_rtx (DFmode);
operands[1] = force_reg (DFmode, operands[1]);
- emit_insn (gen_cmpdf (operands[1],
+ emit_insn (gen_cmpdf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"9223372036854775808.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("9223372036854775808.0", DFmode), DFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subdf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"18446744073709551616.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("18446744073709551616.0", DFmode), DFmode)));
emit_insn (gen_fix_truncdfdi2_ieee (operands[0], temp, GEN_INT(7)));
emit_jump (label2);
@@ -2492,28 +2925,27 @@
emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncdfdi2"
[(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:DF 1 "nonimmediate_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
operands[1] = force_reg (DFmode, operands[1]);
emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
DONE;
-}")
+})
(define_insn "fix_truncdfdi2_ieee"
[(set (match_operand:DI 0 "register_operand" "=d")
(fix:DI (match_operand:DF 1 "register_operand" "f")))
- (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
+ (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cgdbr\\t%0,%h2,%1"
+ "cgdbr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other")])
+ (set_attr "type" "ftoi")])
;
; fixuns_truncdfsi2 and fix_truncdfsi2 instruction pattern(s).
@@ -2523,20 +2955,19 @@
[(set (match_operand:SI 0 "register_operand" "")
(unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx temp = gen_reg_rtx (DFmode);
operands[1] = force_reg (DFmode,operands[1]);
- emit_insn (gen_cmpdf (operands[1],
+ emit_insn (gen_cmpdf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"2147483648.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("2147483648.0", DFmode), DFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subdf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"4294967296.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("4294967296.0", DFmode), DFmode)));
emit_insn (gen_fix_truncdfsi2_ieee (operands[0], temp, GEN_INT (7)));
emit_jump (label2);
@@ -2544,42 +2975,41 @@
emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncdfsi2"
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
- if (TARGET_IBM_FLOAT)
+ if (TARGET_IBM_FLOAT)
{
/* This is the algorithm from POP chapter A.5.7.2. */
- rtx temp = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
+ rtx temp = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
rtx two32 = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
operands[1] = force_reg (DFmode, operands[1]);
- emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
+ emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
two31r, two32, temp));
- }
- else
+ }
+ else
{
operands[1] = force_reg (DFmode, operands[1]);
emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
}
DONE;
-}")
+})
(define_insn "fix_truncdfsi2_ieee"
[(set (match_operand:SI 0 "register_operand" "=d")
(fix:SI (match_operand:DF 1 "register_operand" "f")))
- (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cfdbr\\t%0,%h2,%1"
+ "cfdbr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "other" )])
@@ -2591,16 +3021,16 @@
(use (match_operand:BLK 4 "memory_operand" "m"))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "*
{
- output_asm_insn (\"sd\\t%1,%2\", operands);
- output_asm_insn (\"aw\\t%1,%3\", operands);
- output_asm_insn (\"std\\t%1,%4\", operands);
- output_asm_insn (\"xi\\t%N4,128\", operands);
- return \"l\\t%0,%N4\";
-}"
+ output_asm_insn ("sd\t%1,%2", operands);
+ output_asm_insn ("aw\t%1,%3", operands);
+ output_asm_insn ("std\t%1,%4", operands);
+ output_asm_insn ("xi\t%N4,128", operands);
+ return "l\t%0,%N4";
+}
[(set_attr "op_type" "NN")
- (set_attr "type" "other")
+ (set_attr "type" "ftoi")
+ (set_attr "atype" "agen")
(set_attr "length" "20")])
;
@@ -2611,21 +3041,20 @@
[(set (match_operand:DI 0 "register_operand" "")
(unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx temp = gen_reg_rtx (SFmode);
operands[1] = force_reg (SFmode, operands[1]);
- emit_insn (gen_cmpsf (operands[1],
+ emit_insn (gen_cmpsf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"9223372036854775808.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("9223372036854775808.0", SFmode), SFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subsf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"18446744073709551616.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("18446744073709551616.0", SFmode), SFmode)));
emit_insn (gen_fix_truncsfdi2_ieee (operands[0], temp, GEN_INT(7)));
emit_jump (label2);
@@ -2633,28 +3062,27 @@
emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncsfdi2"
[(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
operands[1] = force_reg (SFmode, operands[1]);
emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
DONE;
-}")
+})
(define_insn "fix_truncsfdi2_ieee"
[(set (match_operand:DI 0 "register_operand" "=d")
(fix:DI (match_operand:SF 1 "register_operand" "f")))
- (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
+ (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cgebr\\t%0,%h2,%1"
+ "cgebr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other")])
+ (set_attr "type" "ftoi")])
;
; fixuns_truncsfsi2 and fix_truncsfsi2 instruction pattern(s).
@@ -2664,7 +3092,6 @@
[(set (match_operand:SI 0 "register_operand" "")
(unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
@@ -2673,11 +3100,11 @@
operands[1] = force_reg (SFmode, operands[1]);
emit_insn (gen_cmpsf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"2147483648.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("2147483648.0", SFmode), SFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subsf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"4294967296.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("4294967296.0", SFmode), SFmode)));
emit_insn (gen_fix_truncsfsi2_ieee (operands[0], temp, GEN_INT (7)));
emit_jump (label2);
@@ -2685,13 +3112,12 @@
emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncsfsi2"
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
if (TARGET_IBM_FLOAT)
{
@@ -2707,17 +3133,17 @@
}
DONE;
-}")
+})
(define_insn "fix_truncsfsi2_ieee"
[(set (match_operand:SI 0 "register_operand" "=d")
(fix:SI (match_operand:SF 1 "register_operand" "f")))
- (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cfebr\\t%0,%h2,%1"
+ "cfebr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other")])
+ (set_attr "type" "ftoi")])
;
; floatdidf2 instruction pattern(s).
@@ -2728,9 +3154,9 @@
(float:DF (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cdgbr\\t%0,%1"
+ "cdgbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
;
; floatdisf2 instruction pattern(s).
@@ -2741,9 +3167,9 @@
(float:SF (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cegbr\\t%0,%1"
+ "cegbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
;
; floatsidf2 instruction pattern(s).
@@ -2755,28 +3181,27 @@
(float:DF (match_operand:SI 1 "register_operand" "")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
- "
{
- if (TARGET_IBM_FLOAT)
+ if (TARGET_IBM_FLOAT)
{
/* This is the algorithm from POP chapter A.5.7.1. */
- rtx temp = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
- rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
+ rtx temp = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
+ rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
DONE;
}
-}")
+})
(define_insn "floatsidf2_ieee"
[(set (match_operand:DF 0 "register_operand" "=f")
(float:DF (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cdfbr\\t%0,%1"
+ "cdfbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
(define_insn "floatsidf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -2785,16 +3210,16 @@
(use (match_operand:BLK 3 "memory_operand" "m"))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "*
{
- output_asm_insn (\"st\\t%1,%N3\", operands);
- output_asm_insn (\"xi\\t%N3,128\", operands);
- output_asm_insn (\"mvc\\t%O3(4,%R3),%2\", operands);
- output_asm_insn (\"ld\\t%0,%3\", operands);
- return \"sd\\t%0,%2\";
-}"
+ output_asm_insn ("st\t%1,%N3", operands);
+ output_asm_insn ("xi\t%N3,128", operands);
+ output_asm_insn ("mvc\t%O3(4,%R3),%2", operands);
+ output_asm_insn ("ld\t%0,%3", operands);
+ return "sd\t%0,%2";
+}
[(set_attr "op_type" "NN")
(set_attr "type" "other" )
+ (set_attr "atype" "agen")
(set_attr "length" "20")])
;
@@ -2807,7 +3232,6 @@
(float:SF (match_operand:SI 1 "register_operand" "")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
- "
{
if (TARGET_IBM_FLOAT)
{
@@ -2817,16 +3241,16 @@
emit_insn (gen_truncdfsf2 (operands[0], temp));
DONE;
}
-}")
+})
(define_insn "floatsisf2_ieee"
[(set (match_operand:SF 0 "register_operand" "=f")
(float:SF (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cefbr\\t%0,%1"
+ "cefbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
;
; truncdfsf2 instruction pattern(s).
@@ -2842,18 +3266,18 @@
[(set (match_operand:SF 0 "register_operand" "=f")
(float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "ledbr\\t%0,%1"
+ "ledbr\t%0,%1"
[(set_attr "op_type" "RRE")])
(define_insn "truncdfsf2_ibm"
[(set (match_operand:SF 0 "register_operand" "=f,f")
- (float_truncate:SF (match_operand:DF 1 "general_operand" "f,m")))]
+ (float_truncate:SF (match_operand:DF 1 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- lrer\\t%0,%1
- le\\t%0,%1"
+ lrer\t%0,%1
+ le\t%0,%1"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "floads,floads")])
;
; extendsfdf2 instruction pattern(s).
@@ -2863,41 +3287,42 @@
[(set (match_operand:DF 0 "register_operand" "")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
if (TARGET_IBM_FLOAT)
{
emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1]));
DONE;
}
-}")
+})
(define_insn "extendsfdf2_ieee"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- ldebr\\t%0,%1
- ldeb\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")])
+ ldebr\t%0,%1
+ ldeb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "floads,floads")])
(define_insn "extendsfdf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- sdr\\t%0,%0\;ler\\t%0,%1
- sdr\\t%0,%0\;le\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")
- (set_attr "type" "o2,o2")])
+ sdr\t%0,%0\;ler\t%0,%1
+ sdr\t%0,%0\;le\t%0,%1"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "atype" "reg,agen")
+ (set_attr "length" "4,6")
+ (set_attr "type" "o2,o2")])
;;
-;; ARITHMETRIC OPERATIONS
+;; ARITHMETIC OPERATIONS
;;
-; arithmetric operations set the ConditionCode,
+; arithmetic operations set the ConditionCode,
; because of unpredictable Bits in Register for Halfword and Byte
; the ConditionCode can be set wrong in operations for Halfword and Byte
@@ -2916,13 +3341,12 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- agfr\\t%0,%2
- agf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ agfr\t%0,%2
+ agf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_zero_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
(match_operand:DI 1 "register_operand" "0,0"))
(const_int 0)))
@@ -2930,23 +3354,21 @@
(plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algfr\\t%0,%2
- algf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algfr\t%0,%2
+ algf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_zero_cconly"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
(match_operand:DI 1 "register_operand" "0,0"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algfr\\t%0,%2
- algf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algfr\t%0,%2
+ algf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_zero"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -2955,27 +3377,75 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- algfr\\t%0,%2
- algf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algfr\t%0,%2
+ algf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_imm_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0")
(match_operand:DI 2 "const_int_operand" "K"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d")
(plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT
- && s390_match_ccmode (insn, CCAmode)
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
- "aghi\\t%0,%h2"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ "TARGET_64BIT
+ && s390_match_ccmode (insn, CCAmode)
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")"
+ "aghi\t%0,%h2"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*adddi3_carry1_cc"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_carry1_cconly"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_carry2_cc"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 2)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_carry2_cconly"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 2)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(match_operand:DI 2 "general_operand" "d,m"))
(const_int 0)))
@@ -2983,35 +3453,32 @@
(plus:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algr\\t%0,%2
- alg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_cconly"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(match_operand:DI 2 "general_operand" "d,m"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algr\\t%0,%2
- alg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_cconly2"
- [(set (reg 33)
+ [(set (reg 33)
(compare (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(neg:SI (match_operand:DI 2 "general_operand" "d,m"))))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCLmode) && TARGET_64BIT"
"@
- algr\\t%0,%2
- alg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_64"
[(set (match_operand:DI 0 "register_operand" "=d,d,d")
@@ -3020,18 +3487,42 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- agr\\t%0,%2
- aghi\\t%0,%h2
- ag\\t%0,%2"
- [(set_attr "op_type" "RRE,RI,RXE")
- (set_attr "atype" "reg,reg,mem")])
+ agr\t%0,%2
+ aghi\t%0,%h2
+ ag\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RXY")])
+
+(define_insn_and_split "*adddi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL1 33)
+ (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
+ (ltu:SI (reg:CCL1 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
(define_insn_and_split "*adddi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
@@ -3068,277 +3559,138 @@
""
"")
-(define_insn "*la_64"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))]
- "TARGET_64BIT"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_peephole2
- [(parallel
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:QI 1 "address_operand" ""))
- (clobber (reg:CC 33))])]
- "TARGET_64BIT
- && strict_memory_address_p (VOIDmode, operands[1])
- && preferred_la_operand_p (operands[1])"
- [(set (match_dup 0) (match_dup 1))]
- "")
-
-(define_peephole2
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" ""))
- (parallel
- [(set (match_dup 0)
- (plus:DI (match_dup 0)
- (match_operand:DI 2 "nonmemory_operand" "")))
- (clobber (reg:CC 33))])]
- "TARGET_64BIT
- && !reg_overlap_mentioned_p (operands[0], operands[2])
- && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2]))
- && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))"
- [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
- "")
-
-(define_expand "reload_indi"
- [(parallel [(match_operand:DI 0 "register_operand" "=a")
- (match_operand:DI 1 "s390_plus_operand" "")
- (match_operand:DI 2 "register_operand" "=&a")])]
- "TARGET_64BIT"
- "
-{
- s390_expand_plus_operand (operands[0], operands[1], operands[2]);
- DONE;
-}")
-
-
;
; addsi3 instruction pattern(s).
;
(define_insn "*addsi3_imm_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:SI 2 "const_int_operand" "K"))
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode (insn, CCAmode)
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
- "ahi\\t%0,%h2"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")"
+ "ahi\t%0,%h2"
+ [(set_attr "op_type" "RI")])
(define_insn "*addsi3_carry1_cc"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(plus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCL1mode)"
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_carry1_cconly"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCL1mode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_carry2_cc"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 2)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(plus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCL1mode)"
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_carry2_cconly"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 2)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCL1mode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_cc"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(plus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_cconly"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCLmode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCLmode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_cconly2"
- [(set (reg 33)
- (compare (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (neg:SI (match_operand:SI 2 "general_operand" "d,m"))))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode(insn, CCLmode)"
+ [(set (reg 33)
+ (compare (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (neg:SI (match_operand:SI 2 "general_operand" "d,R,T"))))
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCLmode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_sign"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (plus:SI (match_operand:SI 1 "register_operand" "0")
- (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))
- (clobber (reg:CC 33))]
- ""
- "ah\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
-
-(define_insn "*addsi3_sub"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (plus:SI (match_operand:SI 1 "register_operand" "0")
- (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0)))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (match_operand:SI 1 "register_operand" "0,0")
+ (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
(clobber (reg:CC 33))]
""
- "ah\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ ah\t%0,%2
+ ahy\t%0,%2"
+ [(set_attr "op_type" "RX,RXY")])
(define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,K,m")))
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,R,T")))
(clobber (reg:CC 33))]
""
"@
- ar\\t%0,%2
- ahi\\t%0,%h2
- a\\t%0,%2"
- [(set_attr "op_type" "RR,RI,RX")
- (set_attr "atype" "reg,reg,mem")])
-
-(define_insn "*la_31"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))]
- "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:QI 1 "address_operand" ""))
- (clobber (reg:CC 33))])]
- "!TARGET_64BIT
- && strict_memory_address_p (VOIDmode, operands[1])
- && preferred_la_operand_p (operands[1])"
- [(set (match_dup 0) (match_dup 1))]
- "")
-
-(define_peephole2
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" ""))
- (parallel
- [(set (match_dup 0)
- (plus:SI (match_dup 0)
- (match_operand:SI 2 "nonmemory_operand" "")))
- (clobber (reg:CC 33))])]
- "!TARGET_64BIT
- && !reg_overlap_mentioned_p (operands[0], operands[2])
- && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2]))
- && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))"
- [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
- "")
-
-(define_insn "*la_31_and"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (match_operand:QI 1 "address_operand" "p")
- (const_int 2147483647)))]
- "!TARGET_64BIT"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_insn_and_split "*la_31_and_cc"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (match_operand:QI 1 "address_operand" "p")
- (const_int 2147483647)))
- (clobber (reg:CC 33))]
- "!TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (and:SI (match_dup 1) (const_int 2147483647)))]
- ""
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_insn "force_la_31"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))
- (use (const_int 0))]
- "!TARGET_64BIT"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_expand "reload_insi"
- [(parallel [(match_operand:SI 0 "register_operand" "=a")
- (match_operand:SI 1 "s390_plus_operand" "")
- (match_operand:SI 2 "register_operand" "=&a")])]
- "!TARGET_64BIT"
- "
-{
- s390_expand_plus_operand (operands[0], operands[1], operands[2]);
- DONE;
-}")
-
+ ar\t%0,%2
+ ahi\t%0,%h2
+ a\t%0,%2
+ ay\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX,RXY")])
;
; adddf3 instruction pattern(s).
@@ -3348,7 +3700,7 @@
[(parallel
[(set (match_operand:DF 0 "register_operand" "=f,f")
(plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3356,26 +3708,53 @@
(define_insn "*adddf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- adbr\\t%0,%2
- adb\\t%0,%2"
+ adbr\t%0,%2
+ adb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*adddf3_cc"
+ [(set (reg 33)
+ (compare (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ adbr\t%0,%2
+ adb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*adddf3_cconly"
+ [(set (reg 33)
+ (compare (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (clobber (match_scratch:DF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ adbr\t%0,%2
+ adb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
(define_insn "*adddf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- adr\\t%0,%2
- ad\\t%0,%2"
+ adr\t%0,%2
+ ad\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
;
; addsf3 instruction pattern(s).
@@ -3385,7 +3764,7 @@
[(parallel
[(set (match_operand:SF 0 "register_operand" "=f,f")
(plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3393,26 +3772,53 @@
(define_insn "*addsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- aebr\\t%0,%2
- aeb\\t%0,%2"
+ aebr\t%0,%2
+ aeb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*addsf3_cc"
+ [(set (reg 33)
+ (compare (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (set (match_operand:SF 0 "register_operand" "=f,f")
+ (plus:SF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ aebr\t%0,%2
+ aeb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*addsf3_cconly"
+ [(set (reg 33)
+ (compare (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (clobber (match_scratch:SF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ aebr\t%0,%2
+ aeb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
(define_insn "*addsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- aer\\t%0,%2
- ae\\t%0,%2"
+ aer\t%0,%2
+ ae\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
;;
@@ -3430,13 +3836,12 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- sgfr\\t%0,%2
- sgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ sgfr\t%0,%2
+ sgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_zero_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
(zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
(const_int 0)))
@@ -3444,23 +3849,21 @@
(minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgfr\\t%0,%2
- slgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgfr\t%0,%2
+ slgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_zero_cconly"
- [(set (reg 33)
+ [(set (reg 33)
(compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
(zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgfr\\t%0,%2
- slgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgfr\t%0,%2
+ slgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_zero"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -3469,10 +3872,34 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- slgfr\\t%0,%2
- slgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgfr\t%0,%2
+ slgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_borrow_cc"
+ [(set (reg 33)
+ (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCL2mode) && TARGET_64BIT"
+ "@
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_borrow_cconly"
+ [(set (reg 33)
+ (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode (insn, CCL2mode) && TARGET_64BIT"
+ "@
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_cc"
[(set (reg 33)
@@ -3481,12 +3908,11 @@
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d,d")
(minus:DI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgr\\t%0,%2
- slg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_cconly"
[(set (reg 33)
@@ -3494,12 +3920,11 @@
(match_operand:DI 2 "general_operand" "d,m"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgr\\t%0,%2
- slg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_64"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -3508,17 +3933,41 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- sgr\\t%0,%2
- sg\\t%0,%2"
- [(set_attr "op_type" "RRE,RRE")
- (set_attr "atype" "reg,mem")])
+ sgr\t%0,%2
+ sg\t%0,%2"
+ [(set_attr "op_type" "RRE,RRE")])
+
+(define_insn_and_split "*subdi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (minus:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL2 33)
+ (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
+ (gtu:SI (reg:CCL2 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
(define_insn_and_split "*subdi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(minus:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
@@ -3561,89 +4010,80 @@
(define_insn "*subsi3_borrow_cc"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(minus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode(insn, CCL2mode)"
+ "s390_match_ccmode (insn, CCL2mode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_borrow_cconly"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode(insn, CCL2mode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCL2mode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_cc"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(minus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode(insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_cconly"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode(insn, CCLmode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCLmode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_sign"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))
- (clobber (reg:CC 33))]
- ""
- "sh\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
-
-(define_insn "*subsi3_sub"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0)))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+ (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
(clobber (reg:CC 33))]
""
- "sh\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ sh\t%0,%2
+ shy\t%0,%2"
+ [(set_attr "op_type" "RX,RXY")])
(define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T")))
(clobber (reg:CC 33))]
""
"@
- sr\\t%0,%2
- s\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ sr\t%0,%2
+ s\t%0,%2
+ sy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
;
@@ -3654,7 +4094,7 @@
[(parallel
[(set (match_operand:DF 0 "register_operand" "=f,f")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3662,26 +4102,53 @@
(define_insn "*subdf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sdbr\\t%0,%2
- sdb\\t%0,%2"
+ sdbr\t%0,%2
+ sdb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*subdf3_cc"
+ [(set (reg 33)
+ (compare (minus:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sdbr\t%0,%2
+ sdb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*subdf3_cconly"
+ [(set (reg 33)
+ (compare (minus:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (clobber (match_scratch:DF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sdbr\t%0,%2
+ sdb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
(define_insn "*subdf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- sdr\\t%0,%2
- sd\\t%0,%2"
+ sdr\t%0,%2
+ sd\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
;
; subsf3 instruction pattern(s).
@@ -3691,7 +4158,7 @@
[(parallel
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3699,26 +4166,174 @@
(define_insn "*subsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sebr\\t%0,%2
- seb\\t%0,%2"
+ sebr\t%0,%2
+ seb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*subsf3_cc"
+ [(set (reg 33)
+ (compare (minus:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (set (match_operand:SF 0 "register_operand" "=f,f")
+ (minus:SF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sebr\t%0,%2
+ seb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*subsf3_cconly"
+ [(set (reg 33)
+ (compare (minus:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (clobber (match_scratch:SF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sebr\t%0,%2
+ seb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
(define_insn "*subsf3_ibm"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- ser\\t%0,%2
- se\\t%0,%2"
+ ser\t%0,%2
+ se\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
+
+
+;;
+;;- Conditional add/subtract instructions.
+;;
+
+;
+; adddicc instruction pattern(s).
+;
+
+(define_insn "*adddi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_alc"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+;
+; addsicc instruction pattern(s).
+;
+
+(define_insn "*addsi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*addsi3_alc"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
;;
@@ -3735,160 +4350,196 @@
(match_operand:DI 1 "register_operand" "0,0")))]
"TARGET_64BIT"
"@
- msgfr\\t%0,%2
- msgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")
+ msgfr\t%0,%2
+ msgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
(set_attr "type" "imul")])
-
(define_insn "muldi3"
[(set (match_operand:DI 0 "register_operand" "=d,d,d")
(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
(match_operand:DI 2 "general_operand" "d,K,m")))]
"TARGET_64BIT"
"@
- msgr\\t%0,%2
- mghi\\t%0,%h2
- msg\\t%0,%2"
- [(set_attr "op_type" "RRE,RI,RXE")
- (set_attr "atype" "reg,reg,mem")
+ msgr\t%0,%2
+ mghi\t%0,%h2
+ msg\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RXY")
(set_attr "type" "imul")])
;
; mulsi3 instruction pattern(s).
;
+(define_insn "*mulsi3_sign"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
+ (match_operand:SI 1 "register_operand" "0")))]
+ ""
+ "mh\t%0,%2"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "imul")])
+
(define_insn "mulsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,K,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
+ (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,R,T")))]
""
"@
- msr\\t%0,%2
- mhi\\t%0,%h2
- ms\\t%0,%2"
- [(set_attr "op_type" "RRE,RI,RX")
- (set_attr "atype" "reg,reg,mem")
+ msr\t%0,%2
+ mhi\t%0,%h2
+ ms\t%0,%2
+ msy\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RX,RXY")
(set_attr "type" "imul")])
;
; mulsidi3 instruction pattern(s).
;
-(define_expand "mulsidi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))))]
+(define_insn "mulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (mult:DI (sign_extend:DI
+ (match_operand:SI 1 "register_operand" "%0,0"))
+ (sign_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
"!TARGET_64BIT"
- "
-{
- rtx insn;
+ "@
+ mr\t%0,%2
+ m\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "type" "imul")])
- emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
- insn = emit_insn (gen_mulsi_6432 (operands[0], operands[0], operands[2]));
+;
+; umulsidi3 instruction pattern(s).
+;
- REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_MULT (DImode,
- gen_rtx_SIGN_EXTEND (DImode, operands[1]),
- gen_rtx_SIGN_EXTEND (DImode, operands[2])),
- REG_NOTES (insn));
- DONE;
-}")
-
-(define_insn "mulsi_6432"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (mult:DI (sign_extend:DI
- (truncate:SI (match_operand:DI 1 "register_operand" "0,0")))
- (sign_extend:DI
- (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
- "!TARGET_64BIT"
- "@
- mr\\t%0,%2
- m\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")
+(define_insn "umulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (mult:DI (zero_extend:DI
+ (match_operand:SI 1 "register_operand" "%0,0"))
+ (zero_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "@
+ mlr\t%0,%2
+ ml\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
(set_attr "type" "imul")])
-
+
;
; muldf3 instruction pattern(s).
;
(define_expand "muldf3"
- [(parallel
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*muldf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- mdbr\\t%0,%2
- mdb\\t%0,%2"
+ mdbr\t%0,%2
+ mdb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuld")])
(define_insn "*muldf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- mdr\\t%0,%2
- md\\t%0,%2"
+ mdr\t%0,%2
+ md\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuld")])
+
+(define_insn "*fmadddf"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "%f,f")
+ (match_operand:DF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:DF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ madbr\t%0,%1,%2
+ madb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuld")])
+
+(define_insn "*fmsubdf"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f,f")
+ (match_operand:DF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:DF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ msdbr\t%0,%1,%2
+ msdb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuld")])
;
; mulsf3 instruction pattern(s).
;
(define_expand "mulsf3"
- [(parallel
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*mulsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- meebr\\t%0,%2
- meeb\\t%0,%2"
+ meebr\t%0,%2
+ meeb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuls")])
(define_insn "*mulsf3_ibm"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- mer\\t%0,%2
- me\\t%0,%2"
+ mer\t%0,%2
+ me\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuls")])
+(define_insn "*fmaddsf"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f,f")
+ (match_operand:SF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:SF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ maebr\t%0,%1,%2
+ maeb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuls")])
+
+(define_insn "*fmsubsf"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f,f")
+ (match_operand:SF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:SF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ msebr\t%0,%1,%2
+ mseb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuls")])
;;
;;- Divide and modulo instructions.
@@ -3900,31 +4551,20 @@
(define_expand "divmoddi4"
[(parallel [(set (match_operand:DI 0 "general_operand" "")
- (div:DI (match_operand:DI 1 "general_operand" "")
+ (div:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "general_operand" "")))
(set (match_operand:DI 3 "general_operand" "")
(mod:DI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"TARGET_64BIT"
- "
{
- rtx insn, div_equal, mod_equal, equal;
+ rtx insn, div_equal, mod_equal;
div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
- equal = gen_rtx_IOR (TImode,
- gen_rtx_ZERO_EXTEND (TImode, div_equal),
- gen_rtx_ASHIFT (TImode,
- gen_rtx_ZERO_EXTEND (TImode, mod_equal),
- GEN_INT (64)));
operands[4] = gen_reg_rtx(TImode);
- emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
- emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
- emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
- insn = emit_insn (gen_divmodtidi3 (operands[4], operands[4], operands[2]));
- REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+ emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
REG_NOTES (insn) =
@@ -3935,45 +4575,43 @@
gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
DONE;
-}")
+})
(define_insn "divmodtidi3"
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
- (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
+ (div:DI (match_operand:DI 1 "register_operand" "0,0")
(match_operand:DI 2 "general_operand" "d,m")))
(ashift:TI
(zero_extend:TI
- (mod:DI (truncate:DI (match_dup 1))
+ (mod:DI (match_dup 1)
(match_dup 2)))
(const_int 64))))]
"TARGET_64BIT"
"@
- dsgr\\t%0,%2
- dsg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ dsgr\t%0,%2
+ dsg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
(define_insn "divmodtisi3"
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
- (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
+ (div:DI (match_operand:DI 1 "register_operand" "0,0")
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
(ashift:TI
(zero_extend:TI
- (mod:DI (truncate:DI (match_dup 1))
+ (mod:DI (match_dup 1)
(sign_extend:DI (match_dup 2))))
(const_int 64))))]
"TARGET_64BIT"
"@
- dsgfr\\t%0,%2
- dsgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ dsgfr\t%0,%2
+ dsgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
;
; udivmoddi4 instruction pattern(s).
@@ -3987,7 +4625,6 @@
(umod:DI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"TARGET_64BIT"
- "
{
rtx insn, div_equal, mod_equal, equal;
@@ -4016,11 +4653,11 @@
gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
DONE;
-}")
+})
(define_insn "udivmodtidi3"
[(set (match_operand:TI 0 "register_operand" "=d,d")
- (ior:TI (zero_extend:TI
+ (ior:TI (zero_extend:TI
(truncate:DI
(udiv:TI (match_operand:TI 1 "register_operand" "0,0")
(zero_extend:TI
@@ -4032,11 +4669,10 @@
(const_int 64))))]
"TARGET_64BIT"
"@
- dlgr\\t%0,%2
- dlg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ dlgr\t%0,%2
+ dlg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
;
; divmodsi4 instruction pattern(s).
@@ -4050,7 +4686,6 @@
(mod:SI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"!TARGET_64BIT"
- "
{
rtx insn, div_equal, mod_equal, equal;
@@ -4077,40 +4712,94 @@
gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
DONE;
-}")
+})
(define_insn "divmoddisi3"
[(set (match_operand:DI 0 "register_operand" "=d,d")
(ior:DI (zero_extend:DI
(truncate:SI
(div:DI (match_operand:DI 1 "register_operand" "0,0")
- (sign_extend:DI
- (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
+ (sign_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
(ashift:DI
(zero_extend:DI
(truncate:SI
- (mod:DI (match_dup 1) (sign_extend:SI (match_dup 2)))))
+ (mod:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))
(const_int 32))))]
"!TARGET_64BIT"
"@
- dr\\t%0,%2
- d\\t%0,%2"
+ dr\t%0,%2
+ d\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "idiv")])
;
; udivsi3 and umodsi3 instruction pattern(s).
;
+(define_expand "udivmodsi4"
+ [(parallel [(set (match_operand:SI 0 "general_operand" "")
+ (udiv:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "nonimmediate_operand" "")))
+ (set (match_operand:SI 3 "general_operand" "")
+ (umod:SI (match_dup 1) (match_dup 2)))])
+ (clobber (match_dup 4))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+{
+ rtx insn, div_equal, mod_equal, equal;
+
+ div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
+ mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, div_equal),
+ gen_rtx_ASHIFT (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, mod_equal),
+ GEN_INT (32)));
+
+ operands[4] = gen_reg_rtx(DImode);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
+ emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
+ emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
+ insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
+
+ DONE;
+})
+
+(define_insn "udivmoddisi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ior:DI (zero_extend:DI
+ (truncate:SI
+ (udiv:DI (match_operand:DI 1 "register_operand" "0,0")
+ (zero_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
+ (ashift:DI
+ (zero_extend:DI
+ (truncate:SI
+ (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
+ (const_int 32))))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "@
+ dlr\t%0,%2
+ dl\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
(define_expand "udivsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(udiv:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))
(clobber (match_dup 3))]
- "!TARGET_64BIT"
- "
+ "!TARGET_64BIT && !TARGET_CPU_ZARCH"
{
rtx insn, udiv_equal, umod_equal, equal;
@@ -4139,32 +4828,32 @@
}
else
{
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_lowpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
udiv_equal, REG_NOTES (insn));
}
}
else
- {
+ {
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx label3 = gen_label_rtx ();
- operands[1] = force_reg (SImode, operands[1]);
- operands[1] = make_safe_from (operands[1], operands[0]);
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
emit_move_insn (operands[0], const0_rtx);
emit_insn (gen_cmpsi (operands[2], operands[1]));
@@ -4178,11 +4867,11 @@
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_lowpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
udiv_equal, REG_NOTES (insn));
emit_jump (label3);
emit_label (label1);
@@ -4192,17 +4881,16 @@
emit_move_insn (operands[0], const1_rtx);
emit_label (label3);
}
- emit_move_insn (operands[0], operands[0]);
+ emit_move_insn (operands[0], operands[0]);
DONE;
-}")
+})
(define_expand "umodsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:SI 2 "nonimmediate_operand" "")))
(clobber (match_dup 3))]
- "!TARGET_64BIT"
- "
+ "!TARGET_64BIT && !TARGET_CPU_ZARCH"
{
rtx insn, udiv_equal, umod_equal, equal;
@@ -4232,19 +4920,19 @@
}
else
{
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_highpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
umod_equal, REG_NOTES (insn));
}
}
@@ -4254,12 +4942,12 @@
rtx label2 = gen_label_rtx ();
rtx label3 = gen_label_rtx ();
- operands[1] = force_reg (SImode, operands[1]);
- operands[1] = make_safe_from (operands[1], operands[0]);
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
- emit_move_insn(operands[0], operands[1]);
+ emit_move_insn(operands[0], operands[1]);
emit_insn (gen_cmpsi (operands[2], operands[1]));
emit_jump_insn (gen_bgtu (label3));
emit_insn (gen_cmpsi (operands[2], const1_rtx));
@@ -4271,11 +4959,11 @@
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_highpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
umod_equal, REG_NOTES (insn));
emit_jump (label3);
emit_label (label1);
@@ -4286,85 +4974,73 @@
emit_label (label3);
}
DONE;
-}")
+})
;
; divdf3 instruction pattern(s).
;
(define_expand "divdf3"
- [(parallel
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (div:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*divdf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(div:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- ddbr\\t%0,%2
- ddb\\t%0,%2"
+ ddbr\t%0,%2
+ ddb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivd")])
(define_insn "*divdf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(div:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- ddr\\t%0,%2
- dd\\t%0,%2"
+ ddr\t%0,%2
+ dd\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivd")])
;
; divsf3 instruction pattern(s).
;
(define_expand "divsf3"
- [(parallel
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (div:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*divsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- debr\\t%0,%2
- deb\\t%0,%2"
+ debr\t%0,%2
+ deb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivs")])
(define_insn "*divsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- der\\t%0,%2
- de\\t%0,%2"
+ der\t%0,%2
+ de\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivs")])
;;
@@ -4384,10 +5060,9 @@
(and:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ngr\\t%0,%2
- ng\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ ngr\t%0,%2
+ ng\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*anddi3_cconly"
[(set (reg 33)
@@ -4397,45 +5072,27 @@
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ngr\\t%0,%2
- ng\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
-
-(define_insn "*anddi3_ni"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (and:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], DImode, -1) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], DImode, -1);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
-
- switch (part)
- {
- case 0: return \"nihh\\t%0,%x2\";
- case 1: return \"nihl\\t%0,%x2\";
- case 2: return \"nilh\\t%0,%x2\";
- case 3: return \"nill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ ngr\t%0,%2
+ ng\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "anddi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "d,m")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT"
- "@
- ngr\\t%0,%2
- ng\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d,d,d")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o,0,0,0,0,0,0")
+ (match_operand:DI 2 "general_operand"
+ "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ #
+ #
+ nihh\t%0,%j2
+ nihl\t%0,%j2
+ nilh\t%0,%j2
+ nill\t%0,%j2
+ ngr\t%0,%2
+ ng\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY")])
(define_insn "*anddi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4443,9 +5100,8 @@
(match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*anddi3_ss_inv"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4453,9 +5109,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; andsi3 instruction pattern(s).
@@ -4463,63 +5118,66 @@
(define_insn "*andsi3_cc"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(and:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode)"
"@
- nr\\t%0,%2
- n\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ nr\t%0,%2
+ n\t%0,%2
+ ny\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*andsi3_cconly"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- nr\\t%0,%2
- n\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ nr\t%0,%2
+ n\t%0,%2
+ ny\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
-(define_insn "*andsi3_ni"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:SI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], SImode, -1) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], SImode, -1);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
-
- switch (part)
- {
- case 0: return \"nilh\\t%0,%x2\";
- case 1: return \"nill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+(define_expand "andsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
-(define_insn "andsi3"
+(define_insn "*andsi3_zarch"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d,d")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,o,0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "M,M,N0HSF,N1HSF,d,R,T")))
+ (clobber (reg:CC 33))]
+ "TARGET_ZARCH"
+ "@
+ #
+ #
+ nilh\t%0,%j2
+ nill\t%0,%j2
+ nr\t%0,%2
+ n\t%0,%2
+ ny\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY")])
+
+(define_insn "*andsi3_esa"
[(set (match_operand:SI 0 "register_operand" "=d,d")
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ (match_operand:SI 2 "general_operand" "d,R")))
(clobber (reg:CC 33))]
- ""
+ "!TARGET_ZARCH"
"@
- nr\\t%0,%2
- n\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ nr\t%0,%2
+ n\t%0,%2"
+ [(set_attr "op_type" "RR,RX")])
(define_insn "*andsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4527,9 +5185,8 @@
(match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*andsi3_ss_inv"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4537,9 +5194,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; andhi3 instruction pattern(s).
@@ -4550,12 +5206,11 @@
(and:HI (match_operand:HI 1 "register_operand" "%0,0")
(match_operand:HI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- nr\\t%0,%2
- nill\\t%0,%x2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ nr\t%0,%2
+ nill\t%0,%x2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "andhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
@@ -4563,9 +5218,8 @@
(match_operand:HI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "nr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "nr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*andhi3_ss"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4573,9 +5227,8 @@
(match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*andhi3_ss_inv"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4583,9 +5236,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; andqi3 instruction pattern(s).
@@ -4596,12 +5248,11 @@
(and:QI (match_operand:QI 1 "register_operand" "%0,0")
(match_operand:QI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- nr\\t%0,%2
- nill\\t%0,%b2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ nr\t%0,%2
+ nill\t%0,%b2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "andqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
@@ -4609,33 +5260,32 @@
(match_operand:QI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "nr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "nr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*andqi3_ss"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
(and:QI (match_dup 0)
- (match_operand:QI 1 "s_imm_operand" "n,Q")))
+ (match_operand:QI 1 "s_imm_operand" "n,n,Q")))
(clobber (reg:CC 33))]
""
"@
- ni\\t%0,%b1
- nc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ ni\t%0,%b1
+ niy\t%0,%b1
+ nc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
(define_insn "*andqi3_ss_inv"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
- (and:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
+ (and:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
"@
- ni\\t%0,%b1
- nc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ ni\t%0,%b1
+ niy\t%0,%b1
+ nc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
;;
@@ -4655,10 +5305,9 @@
(ior:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ogr\\t%0,%2
- og\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ ogr\t%0,%2
+ og\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*iordi3_cconly"
[(set (reg 33)
@@ -4668,45 +5317,24 @@
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ogr\\t%0,%2
- og\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
-
-(define_insn "*iordi3_oi"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], DImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], DImode, 0);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
-
- switch (part)
- {
- case 0: return \"oihh\\t%0,%x2\";
- case 1: return \"oihl\\t%0,%x2\";
- case 2: return \"oilh\\t%0,%x2\";
- case 3: return \"oill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ ogr\t%0,%2
+ og\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "iordi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "d,m")))
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d")
+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0")
+ (match_operand:DI 2 "general_operand" "N0HD0,N1HD0,N2HD0,N3HD0,d,m")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- ogr\\t%0,%2
- og\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ oihh\t%0,%i2
+ oihl\t%0,%i2
+ oilh\t%0,%i2
+ oill\t%0,%i2
+ ogr\t%0,%2
+ og\t%0,%2"
+ [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY")])
(define_insn "*iordi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4714,9 +5342,8 @@
(match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*iordi3_ss_inv"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4724,9 +5351,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; iorsi3 instruction pattern(s).
@@ -4734,63 +5360,64 @@
(define_insn "*iorsi3_cc"
[(set (reg 33)
- (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(ior:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode)"
"@
- or\\t%0,%2
- o\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ or\t%0,%2
+ o\t%0,%2
+ oy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*iorsi3_cconly"
[(set (reg 33)
- (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- or\\t%0,%2
- o\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ or\t%0,%2
+ o\t%0,%2
+ oy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
-(define_insn "*iorsi3_oi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:SI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], SImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], SImode, 0);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
+(define_expand "iorsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
- switch (part)
- {
- case 0: return \"oilh\\t%0,%x2\";
- case 1: return \"oill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+(define_insn "iorsi3_zarch"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T")))
+ (clobber (reg:CC 33))]
+ "TARGET_ZARCH"
+ "@
+ oilh\t%0,%i2
+ oill\t%0,%i2
+ or\t%0,%2
+ o\t%0,%2
+ oy\t%0,%2"
+ [(set_attr "op_type" "RI,RI,RR,RX,RXY")])
-(define_insn "iorsi3"
+(define_insn "iorsi3_esa"
[(set (match_operand:SI 0 "register_operand" "=d,d")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,R")))
(clobber (reg:CC 33))]
- ""
+ "!TARGET_ZARCH"
"@
- or\\t%0,%2
- o\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ or\t%0,%2
+ o\t%0,%2"
+ [(set_attr "op_type" "RR,RX")])
(define_insn "*iorsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4798,9 +5425,8 @@
(match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*iorsi3_ss_inv"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4808,9 +5434,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; iorhi3 instruction pattern(s).
@@ -4821,12 +5446,11 @@
(ior:HI (match_operand:HI 1 "register_operand" "%0,0")
(match_operand:HI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- or\\t%0,%2
- oill\\t%0,%x2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ or\t%0,%2
+ oill\t%0,%x2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "iorhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
@@ -4834,9 +5458,8 @@
(match_operand:HI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "or\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "or\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*iorhi3_ss"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4844,9 +5467,8 @@
(match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*iorhi3_ss_inv"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4854,9 +5476,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; iorqi3 instruction pattern(s).
@@ -4867,12 +5488,11 @@
(ior:QI (match_operand:QI 1 "register_operand" "%0,0")
(match_operand:QI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- or\\t%0,%2
- oill\\t%0,%b2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ or\t%0,%2
+ oill\t%0,%b2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "iorqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
@@ -4880,33 +5500,32 @@
(match_operand:QI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "or\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "or\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*iorqi3_ss"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
(ior:QI (match_dup 0)
- (match_operand:QI 1 "s_imm_operand" "n,Q")))
+ (match_operand:QI 1 "s_imm_operand" "n,n,Q")))
(clobber (reg:CC 33))]
""
"@
- oi\\t%0,%b1
- oc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "reg,mem")])
+ oi\t%0,%b1
+ oiy\t%0,%b1
+ oc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
(define_insn "*iorqi3_ss_inv"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
- (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
+ (ior:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
"@
- oi\\t%0,%b1
- oc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "reg,mem")])
+ oi\t%0,%b1
+ oiy\t%0,%b1
+ oc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
;;
@@ -4926,10 +5545,9 @@
(xor:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- xgr\\t%0,%2
- xg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ xgr\t%0,%2
+ xg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*xordi3_cconly"
[(set (reg 33)
@@ -4939,10 +5557,9 @@
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- xgr\\t%0,%2
- xr\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ xgr\t%0,%2
+ xr\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "xordi3"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -4951,10 +5568,9 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- xgr\\t%0,%2
- xg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ xgr\t%0,%2
+ xg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*xordi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4962,9 +5578,8 @@
(match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*xordi3_ss_inv"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4972,9 +5587,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; xorsi3 instruction pattern(s).
@@ -4982,42 +5596,42 @@
(define_insn "*xorsi3_cc"
[(set (reg 33)
- (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(xor:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode)"
"@
- xr\\t%0,%2
- x\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ xr\t%0,%2
+ x\t%0,%2
+ xy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*xorsi3_cconly"
[(set (reg 33)
- (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- xr\\t%0,%2
- x\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ xr\t%0,%2
+ x\t%0,%2
+ xy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T")))
(clobber (reg:CC 33))]
""
"@
- xr\\t%0,%2
- x\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ xr\t%0,%2
+ x\t%0,%2
+ xy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*xorsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -5025,9 +5639,8 @@
(match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*xorsi3_ss_inv"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -5035,9 +5648,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; xorhi3 instruction pattern(s).
@@ -5049,9 +5661,8 @@
(match_operand:HI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "xr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "xr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*xorhi3_ss"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -5059,9 +5670,8 @@
(match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*xorhi3_ss_inv"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -5069,9 +5679,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; xorqi3 instruction pattern(s).
@@ -5083,33 +5692,32 @@
(match_operand:QI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "xr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "xr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*xorqi3_ss"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
(xor:QI (match_dup 0)
- (match_operand:QI 1 "s_imm_operand" "n,Q")))
+ (match_operand:QI 1 "s_imm_operand" "n,n,Q")))
(clobber (reg:CC 33))]
""
"@
- xi\\t%0,%b1
- xc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ xi\t%0,%b1
+ xiy\t%0,%b1
+ xc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
(define_insn "*xorqi3_ss_inv"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
- (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
+ (xor:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
"@
- xi\\t%0,%b1
- xc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ xi\t%0,%b1
+ xiy\t%0,%b1
+ xc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
;;
@@ -5133,7 +5741,7 @@
(neg:DI (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "lcgr\\t%0,%1"
+ "lcgr\t%0,%1"
[(set_attr "op_type" "RR")])
(define_insn "*negdi2_31"
@@ -5141,18 +5749,17 @@
(neg:DI (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "*
{
rtx xop[1];
xop[0] = gen_label_rtx ();
- output_asm_insn (\"lcr\\t%0,%1\", operands);
- output_asm_insn (\"lcr\\t%N0,%N1\", operands);
- output_asm_insn (\"je\\t%l0\", xop);
- output_asm_insn (\"bctr\\t%0,0\", operands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ output_asm_insn ("lcr\t%0,%1", operands);
+ output_asm_insn ("lcr\t%N0,%N1", operands);
+ output_asm_insn ("je\t%l0", xop);
+ output_asm_insn ("bctr\t%0,0", operands);
+ targetm.asm_out.internal_label (asm_out_file, "L",
CODE_LABEL_NUMBER (xop[0]));
- return \"\";
-}"
+ return "";
+}
[(set_attr "op_type" "NN")
(set_attr "type" "other")
(set_attr "length" "10")])
@@ -5166,7 +5773,7 @@
(neg:SI (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
""
- "lcr\\t%0,%1"
+ "lcr\t%0,%1"
[(set_attr "op_type" "RR")])
;
@@ -5186,16 +5793,18 @@
(neg:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lcdbr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lcdbr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
(define_insn "*negdf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lcdr\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lcdr\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimpd")])
;
; negsf2 instruction pattern(s).
@@ -5214,16 +5823,18 @@
(neg:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lcebr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lcebr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
(define_insn "*negsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(neg:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lcer\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lcer\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimps")])
;;
@@ -5239,7 +5850,7 @@
(abs:DI (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "lpgr\\t%0,%1"
+ "lpgr\t%0,%1"
[(set_attr "op_type" "RRE")])
;
@@ -5251,7 +5862,7 @@
(abs:SI (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
""
- "lpr\\t%0,%1"
+ "lpr\t%0,%1"
[(set_attr "op_type" "RR")])
;
@@ -5271,16 +5882,18 @@
(abs:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lpdbr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lpdbr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
(define_insn "*absdf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f")
(abs:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lpdr\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lpdr\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimpd")])
;
; abssf2 instruction pattern(s).
@@ -5299,16 +5912,64 @@
(abs:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lpebr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lpebr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
(define_insn "*abssf2_ibm"
[(set (match_operand:SF 0 "register_operand" "=f")
(abs:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lper\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lper\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimps")])
+
+;;
+;;- Negated absolute value instructions
+;;
+
+;
+; Integer
+;
+
+(define_insn "*negabssi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (neg:SI (abs:SI (match_operand:SI 1 "register_operand" "d"))))
+ (clobber (reg:CC 33))]
+ ""
+ "lnr\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "*negabsdi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (neg:DI (abs:DI (match_operand:DI 1 "register_operand" "d"))))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "lngr\t%0,%1"
+ [(set_attr "op_type" "RRE")])
+
+;
+; Floating point
+;
+
+(define_insn "*negabssf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lnebr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
+
+(define_insn "*negabsdf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lndbr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
;;
;;- Square root instructions.
@@ -5320,12 +5981,12 @@
(define_insn "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (sqrt:DF (match_operand:DF 1 "general_operand" "f,m")))]
+ (sqrt:DF (match_operand:DF 1 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sqdbr\\t%0,%1
- sqdb\\t%0,%1"
- [(set_attr "op_type" "RRE,RSE")])
+ sqdbr\t%0,%1
+ sqdb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
;
; sqrtsf2 instruction pattern(s).
@@ -5333,12 +5994,12 @@
(define_insn "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
- (sqrt:SF (match_operand:SF 1 "general_operand" "f,m")))]
+ (sqrt:SF (match_operand:SF 1 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sqebr\\t%0,%1
- sqeb\\t%0,%1"
- [(set_attr "op_type" "RRE,RSE")])
+ sqebr\t%0,%1
+ sqeb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
;;
;;- One complement instructions.
@@ -5347,7 +6008,7 @@
;
; one_cmpldi2 instruction pattern(s).
;
-
+
(define_expand "one_cmpldi2"
[(parallel
[(set (match_operand:DI 0 "register_operand" "")
@@ -5356,11 +6017,11 @@
(clobber (reg:CC 33))])]
"TARGET_64BIT"
"")
-
+
;
; one_cmplsi2 instruction pattern(s).
;
-
+
(define_expand "one_cmplsi2"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
@@ -5369,11 +6030,11 @@
(clobber (reg:CC 33))])]
""
"")
-
+
;
; one_cmplhi2 instruction pattern(s).
;
-
+
(define_expand "one_cmplhi2"
[(parallel
[(set (match_operand:HI 0 "register_operand" "")
@@ -5382,11 +6043,11 @@
(clobber (reg:CC 33))])]
""
"")
-
+
;
; one_cmplqi2 instruction pattern(s).
;
-
+
(define_expand "one_cmplqi2"
[(parallel
[(set (match_operand:QI 0 "register_operand" "")
@@ -5406,28 +6067,26 @@
;
(define_insn "rotldi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (rotate:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (rotate:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- rllg\\t%0,%1,%c2
- rllg\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "rllg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;
; rotlsi3 instruction pattern(s).
;
(define_insn "rotlsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (rotate:SI (match_operand:SI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
- "TARGET_64BIT"
- "@
- rll\\t%0,%1,%c2
- rll\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (rotate:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
+ "TARGET_CPU_ZARCH"
+ "rll\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;;
@@ -5441,29 +6100,27 @@
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:SI 2 "shift_count_operand" "")))]
""
"")
(define_insn "*ashldi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashift:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"!TARGET_64BIT"
- "@
- sldl\\t%0,%c2
- sldl\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sldl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashldi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashift:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- sllg\\t%0,%1,%2
- sllg\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "sllg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;
; ashrdi3 instruction pattern(s).
@@ -5473,96 +6130,90 @@
[(parallel
[(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))
+ (match_operand:SI 2 "shift_count_operand" "")))
(clobber (reg:CC 33))])]
""
"")
(define_insn "*ashrdi3_cc_31"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=d,d")
+ (set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
- "@
- srda\\t%0,%c2
- srda\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_cconly_31"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:DI 0 "=d,d"))]
+ (clobber (match_scratch:DI 0 "=d"))]
"!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
- "@
- srda\\t%0,%c2
- srda\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "@
- srda\\t%0,%c2
- srda\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_cc_64"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=d,d")
+ (set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "@
- srag\\t%0,%1,%c2
- srag\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_cconly_64"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:DI 0 "=d,d"))]
+ (clobber (match_scratch:DI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "@
- srag\\t%0,%1,%c2
- srag\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "@
- srag\\t%0,%1,%c2
- srag\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
+
;
; ashlsi3 instruction pattern(s).
;
(define_insn "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
""
- "@
- sll\\t%0,%c2
- sll\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sll\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
;
; ashrsi3 instruction pattern(s).
@@ -5570,39 +6221,37 @@
(define_insn "*ashrsi3_cc"
[(set (reg 33)
- (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCSmode)"
- "@
- sra\\t%0,%c2
- sra\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
(define_insn "*ashrsi3_cconly"
[(set (reg 33)
- (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
- "@
- sra\\t%0,%c2
- sra\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
""
- "@
- sra\\t%0,%c2
- sra\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
;;
@@ -5616,43 +6265,40 @@
(define_expand "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "")
(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:SI 2 "shift_count_operand" "")))]
""
"")
(define_insn "*lshrdi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"!TARGET_64BIT"
- "@
- srdl\\t%0,%c2
- srdl\\t%0,0(%2)"
- [(set_attr "op_type" "RS,RS")])
+ "srdl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*lshrdi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- srlg\\t%0,%1,%c2
- srlg\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE,RSE")])
+ "srlg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;
; lshrsi3 instruction pattern(s).
;
(define_insn "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
""
- "@
- srl\\t%0,%c2
- srl\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
;;
@@ -5666,7 +6312,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bne"
[(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2)))
@@ -5675,7 +6321,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bgt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5684,7 +6330,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bgtu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5693,7 +6339,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "blt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5702,7 +6348,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bltu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5711,7 +6357,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bge"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5720,7 +6366,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bgeu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5729,7 +6375,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "ble"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5738,7 +6384,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bleu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5747,7 +6393,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunordered"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5756,7 +6402,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bordered"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5765,7 +6411,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "buneq"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5774,7 +6420,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bungt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5783,7 +6429,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunlt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5792,7 +6438,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunge"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5801,7 +6447,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunle"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5810,7 +6456,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bltgt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5819,7 +6465,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
;;
@@ -5828,25 +6474,25 @@
(define_insn "cjump"
[(set (pc)
- (if_then_else
+ (if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "*
{
if (get_attr_length (insn) == 4)
- return \"j%C1\\t%l0\";
- else if (TARGET_64BIT)
- return \"jg%C1\\t%l0\";
+ return "j%C1\t%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "jg%C1\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 6)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -5855,20 +6501,20 @@
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
- (match_operand 0 "address_operand" "p")
+ (match_operand 0 "address_operand" "U")
(pc)))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"b%C1r\\t%0\";
+ return "b%C1r\t%0";
else
- return \"b%C1\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b%C1\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
;;
@@ -5879,23 +6525,23 @@
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
- (pc)
+ (pc)
(label_ref (match_operand 0 "" ""))))]
""
- "*
-{
+{
if (get_attr_length (insn) == 4)
- return \"j%D1\\t%l0\";
- else if (TARGET_64BIT)
- return \"jg%D1\\t%l0\";
+ return "j%D1\t%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "jg%D1\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 6)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -5905,19 +6551,19 @@
(if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
(pc)
- (match_operand 0 "address_operand" "p")))]
+ (match_operand 0 "address_operand" "U")))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"b%D1r\\t%0\";
+ return "b%D1r\t%0";
else
- return \"b%D1\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b%D1\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
;;
;;- Trap instructions.
@@ -5926,8 +6572,9 @@
(define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]
""
- "j\\t.+2"
- [(set_attr "op_type" "RX")])
+ "j\t.+2"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "branch")])
(define_expand "conditional_trap"
[(set (match_dup 2) (match_dup 3))
@@ -5935,31 +6582,31 @@
[(match_dup 2) (const_int 0)])
(match_operand:SI 1 "general_operand" ""))]
""
- "
{
enum machine_mode ccmode;
- if (operands[1] != const0_rtx) FAIL;
+ if (operands[1] != const0_rtx) FAIL;
- ccmode = s390_select_ccmode (GET_CODE (operands[0]),
- s390_compare_op0, s390_compare_op1);
+ ccmode = s390_select_ccmode (GET_CODE (operands[0]),
+ s390_compare_op0, s390_compare_op1);
operands[2] = gen_rtx_REG (ccmode, 33);
operands[3] = gen_rtx_COMPARE (ccmode, s390_compare_op0, s390_compare_op1);
-}")
+})
(define_insn "*trap"
[(trap_if (match_operator 0 "comparison_operator" [(reg 33) (const_int 0)])
(const_int 0))]
""
- "j%C0\\t.+2";
- [(set_attr "op_type" "RX")])
+ "j%C0\t.+2";
+ [(set_attr "op_type" "RI")
+ (set_attr "type" "branch")])
;;
;;- Loop instructions.
;;
;; This is all complicated by the fact that since this is a jump insn
;; we must handle our own output reloads.
-
+
(define_expand "doloop_end"
[(use (match_operand 0 "" "")) ; loop pseudo
(use (match_operand 1 "" "")) ; iterations; zero if unknown
@@ -5967,7 +6614,6 @@
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
""
- "
{
if (GET_MODE (operands[0]) == SImode)
emit_jump_insn (gen_doloop_si (operands[4], operands[0], operands[0]));
@@ -5977,7 +6623,7 @@
FAIL;
DONE;
-}")
+})
(define_insn "doloop_si"
[(set (pc)
@@ -5991,20 +6637,22 @@
(clobber (match_scratch:SI 3 "=X,&d"))
(clobber (reg:CC 33))]
""
- "*
{
if (which_alternative != 0)
- return \"#\";
+ return "#";
else if (get_attr_length (insn) == 4)
- return \"brct\\t%1,%l0\";
+ return "brct\t%1,%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "ahi\t%1,-1\;jgne\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 10)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -6014,24 +6662,24 @@
(if_then_else
(ne (match_operand:SI 1 "register_operand" "d,d")
(const_int 1))
- (match_operand 0 "address_operand" "p,p")
+ (match_operand 0 "address_operand" "U,U")
(pc)))
(set (match_operand:SI 2 "register_operand" "=1,?*m*d")
(plus:SI (match_dup 1) (const_int -1)))
(clobber (match_scratch:SI 3 "=X,&d"))
(clobber (reg:CC 33))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"bctr\\t%1,%0\";
+ return "bctr\t%1,%0";
else
- return \"bct\\t%1,%a0\";
-}"
- [(set (attr "op_type")
+ return "bct\t%1,%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
(define_split
[(set (pc)
@@ -6069,43 +6717,19 @@
(clobber (match_scratch:DI 3 "=X,&d"))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "*
{
if (which_alternative != 0)
- return \"#\";
+ return "#";
else if (get_attr_length (insn) == 4)
- return \"brctg\\t%1,%l0\";
+ return "brctg\t%1,%l0";
else
- abort ();
-}"
+ return "aghi\t%1,-1\;jgne\t%l0";
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
- (const_int 4) (const_int 12)))])
-
-(define_insn "*doloop_di_long"
- [(set (pc)
- (if_then_else
- (ne (match_operand:DI 1 "register_operand" "d,d")
- (const_int 1))
- (match_operand 0 "address_operand" "p,p")
- (pc)))
- (set (match_operand:DI 2 "register_operand" "=1,?*m*d")
- (plus:DI (match_dup 1) (const_int -1)))
- (clobber (match_scratch:DI 3 "=X,&d"))
- (clobber (reg:CC 33))]
- ""
- "*
-{
- if (get_attr_op_type (insn) == OP_TYPE_RRE)
- return \"bctgr\\t%1,%0\";
- else
- return \"bctg\\t%1,%a0\";
-}"
- [(set (attr "op_type")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "RRE") (const_string "RXE")))
- (set_attr "atype" "mem")])
+ (const_int 4) (const_int 10)))])
(define_split
[(set (pc)
@@ -6142,20 +6766,20 @@
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
- "*
{
if (get_attr_length (insn) == 4)
- return \"j\\t%l0\";
- else if (TARGET_64BIT)
- return \"jg\\t%l0\";
+ return "j\t%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "jg\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 6)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -6165,39 +6789,39 @@
;
(define_insn "indirect_jump"
- [(set (pc) (match_operand 0 "address_operand" "p"))]
+ [(set (pc) (match_operand 0 "address_operand" "U"))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"br\\t%0\";
+ return "br\t%0";
else
- return \"b\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
;
; casesi instruction pattern(s).
;
(define_insn "casesi_jump"
- [(set (pc) (match_operand 0 "address_operand" "p"))
+ [(set (pc) (match_operand 0 "address_operand" "U"))
(use (label_ref (match_operand 1 "" "")))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"br\\t%0\";
+ return "br\t%0";
else
- return \"b\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
(define_expand "casesi"
[(match_operand:SI 0 "general_operand" "")
@@ -6206,7 +6830,6 @@
(label_ref (match_operand 3 "" ""))
(label_ref (match_operand 4 "" ""))]
""
- "
{
rtx index = gen_reg_rtx (SImode);
rtx base = gen_reg_rtx (Pmode);
@@ -6237,7 +6860,7 @@
emit_jump_insn (gen_casesi_jump (target, operands[3]));
DONE;
-}")
+})
;;
@@ -6256,7 +6879,6 @@
(match_operand 1 "" "")
(match_operand 2 "" "")])]
""
- "
{
int i;
@@ -6275,13 +6897,13 @@
emit_insn (gen_blockage ());
DONE;
-}")
+})
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
;; all of memory. This blocks insns from being moved across this point.
(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
""
""
[(set_attr "type" "none")
@@ -6298,9 +6920,8 @@
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))]
""
- "
{
- int plt_call = 0;
+ bool plt_call = false;
rtx insn;
/* Direct function calls need special treatment. */
@@ -6310,22 +6931,22 @@
/* When calling a global routine in PIC mode, we must
replace the symbol itself with the PLT stub. */
- if (flag_pic && !SYMBOL_REF_FLAG (sym))
+ if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
{
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
-
- plt_call = 1;
+ plt_call = true;
}
- /* Unless we can use the bras(l) insn, force the
+ /* Unless we can use the bras(l) insn, force the
routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
- {
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
- }
+ if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
+ {
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
+ }
operands[0] = gen_rtx_MEM (QImode, sym);
}
@@ -6334,14 +6955,12 @@
insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
gen_rtx_REG (Pmode, RETURN_REGNUM)));
- /* In 31-bit, we must load the GOT register even if the
- compiler doesn't know about it, because the PLT glue
- code uses it. In 64-bit, this is not necessary. */
- if (plt_call && !TARGET_64BIT)
+ /* 31-bit PLT stubs use the GOT register implicitly. */
+ if (!TARGET_64BIT && plt_call)
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
+
DONE;
-}")
+})
(define_expand "call_exp"
[(parallel [(call (match_operand 0 "" "")
@@ -6350,64 +6969,40 @@
""
"")
-(define_insn "brasl"
- [(call (mem:QI (match_operand:DI 0 "bras_sym_operand" "X"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:DI 2 "register_operand" "=r"))]
- "TARGET_64BIT"
- "brasl\\t%2,%0"
- [(set_attr "op_type" "RIL")
- (set_attr "type" "jsr")])
-
-(define_insn "bras"
- [(call (mem:QI (match_operand:SI 0 "bras_sym_operand" "X"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "TARGET_SMALL_EXEC"
- "bras\\t%2,%0"
+(define_insn "*bras"
+ [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+ (match_operand 1 "const_int_operand" "n"))
+ (clobber (match_operand 2 "register_operand" "=r"))]
+ "TARGET_SMALL_EXEC && GET_MODE (operands[2]) == Pmode"
+ "bras\t%2,%0"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
-(define_insn "basr_64"
- [(call (mem:QI (match_operand:DI 0 "register_operand" "a"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:DI 2 "register_operand" "=r"))]
- "TARGET_64BIT"
- "basr\\t%2,%0"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "basr_31"
- [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "basr\\t%2,%0"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_64"
- [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:DI 2 "register_operand" "=r"))]
- "TARGET_64BIT"
- "bas\\t%2,%a0"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_31"
- [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "bas\\t%2,%a0"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+(define_insn "*brasl"
+ [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+ (match_operand 1 "const_int_operand" "n"))
+ (clobber (match_operand 2 "register_operand" "=r"))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[2]) == Pmode"
+ "brasl\t%2,%0"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "jsr")])
+(define_insn "*basr"
+ [(call (mem:QI (match_operand 0 "address_operand" "U"))
+ (match_operand 1 "const_int_operand" "n"))
+ (clobber (match_operand 2 "register_operand" "=r"))]
+ "GET_MODE (operands[2]) == Pmode"
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return "basr\t%2,%0";
+ else
+ return "bas\t%2,%a0";
+}
+ [(set (attr "op_type")
+ (if_then_else (match_operand 0 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
;
; call_value instruction pattern(s).
@@ -6419,9 +7014,8 @@
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))]
""
- "
{
- int plt_call = 0;
+ bool plt_call = false;
rtx insn;
/* Direct function calls need special treatment. */
@@ -6431,21 +7025,21 @@
/* When calling a global routine in PIC mode, we must
replace the symbol itself with the PLT stub. */
- if (flag_pic && !SYMBOL_REF_FLAG (sym))
+ if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
{
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
-
- plt_call = 1;
+ plt_call = true;
}
- /* Unless we can use the bras(l) insn, force the
+ /* Unless we can use the bras(l) insn, force the
routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+ if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
{
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
}
operands[1] = gen_rtx_MEM (QImode, sym);
@@ -6456,14 +7050,12 @@
gen_call_value_exp (operands[0], operands[1], operands[2],
gen_rtx_REG (Pmode, RETURN_REGNUM)));
- /* In 31-bit, we must load the GOT register even if the
- compiler doesn't know about it, because the PLT glue
- code uses it. In 64-bit, this is not necessary. */
- if (plt_call && !TARGET_64BIT)
+ /* 31-bit PLT stubs use the GOT register implicitly. */
+ if (!TARGET_64BIT && plt_call)
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
+
DONE;
-}")
+})
(define_expand "call_value_exp"
[(parallel [(set (match_operand 0 "" "")
@@ -6473,68 +7065,43 @@
""
"")
-(define_insn "brasl_r"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))]
- "TARGET_64BIT"
- "brasl\\t%3,%1"
- [(set_attr "op_type" "RIL")
- (set_attr "type" "jsr")])
-
-(define_insn "bras_r"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
+(define_insn "*bras_r"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
(match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "TARGET_SMALL_EXEC"
- "bras\\t%3,%1"
+ (clobber (match_operand 3 "register_operand" "=r"))]
+ "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
+ "bras\t%3,%1"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
-(define_insn "basr_r_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))]
- "TARGET_64BIT"
- "basr\\t%3,%1"
- [(set_attr "op_type" "RR")
+(define_insn "*brasl_r"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+ "brasl\t%3,%1"
+ [(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
-(define_insn "basr_r_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "basr\\t%3,%1"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_r_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))]
- "TARGET_64BIT"
- "bas\\t%3,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_r_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "bas\\t%3,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+(define_insn "*basr_r"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "address_operand" "U"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))]
+ "GET_MODE (operands[3]) == Pmode"
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return "basr\t%3,%1";
+ else
+ return "bas\t%3,%a1";
+}
+ [(set (attr "op_type")
+ (if_then_else (match_operand 1 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
;;
;;- Thread-local storage support.
@@ -6545,10 +7112,10 @@
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_64BIT"
"@
- ear\\t%0,%%a0\;sllg\\t%0,%0,32\;ear\\t%0,%%a1
- stam\\t%%a0,%%a1,%0"
+ ear\t%0,%%a0\;sllg\t%0,%0,32\;ear\t%0,%%a1
+ stam\t%%a0,%%a1,%0"
[(set_attr "op_type" "NN,RS")
- (set_attr "atype" "reg,mem")
+ (set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
@@ -6557,20 +7124,19 @@
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"!TARGET_64BIT"
"@
- ear\\t%0,%%a0
- stam\\t%%a0,%%a0,%0"
- [(set_attr "op_type" "RRE,RS")
- (set_attr "atype" "reg,mem")])
+ ear\t%0,%%a0
+ stam\t%%a0,%%a0,%0"
+ [(set_attr "op_type" "RRE,RS")])
(define_insn "set_tp_64"
[(unspec_volatile [(match_operand:DI 0 "general_operand" "??d,Q")] UNSPECV_SET_TP)
(clobber (match_scratch:SI 1 "=d,X"))]
"TARGET_64BIT"
"@
- sar\\t%%a1,%0\;srlg\\t%1,%0,32\;sar\\t%%a0,%1
- lam\\t%%a0,%%a1,%0"
+ sar\t%%a1,%0\;srlg\t%1,%0,32\;sar\t%%a0,%1
+ lam\t%%a0,%%a1,%0"
[(set_attr "op_type" "NN,RS")
- (set_attr "atype" "reg,mem")
+ (set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
@@ -6578,37 +7144,35 @@
[(unspec_volatile [(match_operand:SI 0 "general_operand" "d,Q")] UNSPECV_SET_TP)]
"!TARGET_64BIT"
"@
- sar\\t%%a0,%0
- lam\\t%%a0,%%a0,%0"
- [(set_attr "op_type" "RRE,RS")
- (set_attr "atype" "reg,mem")])
-
+ sar\t%%a0,%0
+ lam\t%%a0,%%a0,%0"
+ [(set_attr "op_type" "RRE,RS")])
+
(define_insn "*tls_load_64"
[(set (match_operand:DI 0 "register_operand" "=d")
(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
(match_operand:DI 2 "" "")]
UNSPEC_TLS_LOAD))]
"TARGET_64BIT"
- "lg\\t%0,%1%J2"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "lg\t%0,%1%J2"
+ [(set_attr "op_type" "RXE")])
(define_insn "*tls_load_31"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
(match_operand:SI 2 "" "")]
UNSPEC_TLS_LOAD))]
"!TARGET_64BIT"
- "l\\t%0,%1%J2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ l\t%0,%1%J2
+ ly\t%0,%1%J2"
+ [(set_attr "op_type" "RX,RXY")])
(define_expand "call_value_tls"
[(set (match_operand 0 "" "")
(call (const_int 0) (const_int 0)))
(use (match_operand 1 "" ""))]
""
- "
{
rtx insn, sym;
@@ -6616,16 +7180,17 @@
abort ();
sym = s390_tls_get_offset ();
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
- /* Unless we can use the bras(l) insn, force the
+ /* Unless we can use the bras(l) insn, force the
routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+ if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
{
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
}
sym = gen_rtx_MEM (QImode, sym);
@@ -6643,7 +7208,7 @@
CONST_OR_PURE_CALL_P (insn) = 1;
DONE;
-}")
+})
(define_expand "call_value_tls_exp"
[(parallel [(set (match_operand 0 "" "")
@@ -6654,74 +7219,46 @@
""
"")
-(define_insn "brasl_tls"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))
- (use (match_operand:DI 4 "" ""))]
- "TARGET_64BIT"
- "brasl\\t%3,%1%J4"
- [(set_attr "op_type" "RIL")
- (set_attr "type" "jsr")])
-
-(define_insn "bras_tls"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))
- (use (match_operand:SI 4 "" ""))]
- "TARGET_SMALL_EXEC"
- "bras\\t%3,%1%J4"
+(define_insn "*bras_tls"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))
+ (use (match_operand 4 "" ""))]
+ "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
+ "bras\t%3,%1%J4"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
-(define_insn "basr_tls_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))
- (use (match_operand:DI 4 "" ""))]
- "TARGET_64BIT"
- "basr\\t%3,%1%J4"
- [(set_attr "op_type" "RR")
+(define_insn "*brasl_tls"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))
+ (use (match_operand 4 "" ""))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+ "brasl\t%3,%1%J4"
+ [(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
-(define_insn "basr_tls_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))
- (use (match_operand:SI 4 "" ""))]
- "!TARGET_64BIT"
- "basr\\t%3,%1%J4"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_tls_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))
- (use (match_operand:DI 4 "" ""))]
- "TARGET_64BIT"
- "bas\\t%3,%a1%J4"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_tls_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))
- (use (match_operand:SI 4 "" ""))]
- "!TARGET_64BIT"
- "bas\\t%3,%a1%J4"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+(define_insn "*basr_tls"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "address_operand" "U"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))
+ (use (match_operand 4 "" ""))]
+ "GET_MODE (operands[3]) == Pmode"
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return "basr\t%3,%1%J4";
+ else
+ return "bas\t%3,%a1%J4";
+}
+ [(set (attr "op_type")
+ (if_then_else (match_operand 1 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
;;
;;- Miscellaneous instructions.
@@ -6736,13 +7273,12 @@
(plus (reg 15) (match_operand 1 "general_operand" "")))
(set (match_operand 0 "general_operand" "")
(reg 15))]
- ""
- "
+ "TARGET_BACKCHAIN"
{
rtx stack = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);
rtx chain = gen_rtx (MEM, Pmode, stack);
rtx temp = gen_reg_rtx (Pmode);
-
+
emit_move_insn (temp, chain);
if (TARGET_64BIT)
@@ -6752,66 +7288,23 @@
emit_move_insn (chain, temp);
- emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
+ emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
DONE;
-}")
+})
;
-; setjmp/longjmp instruction pattern(s).
+; setjmp instruction pattern.
;
-(define_expand "builtin_setjmp_setup"
- [(unspec [(match_operand 0 "register_operand" "a")] 1)]
- ""
- "
-{
- rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
- rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
-
- emit_move_insn (base, basereg);
- DONE;
-}")
-
(define_expand "builtin_setjmp_receiver"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
+ [(match_operand 0 "" "")]
"flag_pic"
- "
-{
- rtx gotreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
- rtx got = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
- SYMBOL_REF_FLAG (got) = 1;
-
- emit_move_insn (gotreg, got);
- emit_insn (gen_rtx_USE (VOIDmode, gotreg));
- DONE;
-}")
-
-(define_expand "builtin_longjmp"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
- ""
- "
{
- /* The elements of the buffer are, in order: */
- rtx fp = gen_rtx_MEM (Pmode, operands[0]);
- rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], GET_MODE_SIZE (Pmode)));
- rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2 * GET_MODE_SIZE (Pmode)));
- rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
- rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
- rtx jmp = gen_rtx_REG (Pmode, 14);
-
- emit_move_insn (jmp, lab);
- emit_move_insn (basereg, base);
- emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
- emit_move_insn (hard_frame_pointer_rtx, fp);
-
- emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
- emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
- emit_insn (gen_rtx_USE (VOIDmode, basereg));
- emit_indirect_jump (jmp);
+ s390_load_got (false);
+ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
DONE;
-}")
-
+})
;; These patterns say how to save and restore the stack pointer. We need not
;; save the stack pointer at function level since we are careful to
@@ -6840,49 +7333,57 @@
(set (match_dup 0) (match_operand 1 "register_operand" ""))
(set (match_dup 3) (match_dup 2))]
""
- "
{
operands[2] = gen_reg_rtx (Pmode);
operands[3] = gen_rtx_MEM (Pmode, operands[0]);
-}")
+})
(define_expand "save_stack_nonlocal"
[(match_operand 0 "memory_operand" "")
(match_operand 1 "register_operand" "")]
""
- "
{
rtx temp = gen_reg_rtx (Pmode);
- /* Copy the backchain to the first word, sp to the second. */
+ /* Copy the backchain to the first word, sp to the second and the literal pool
+ base to the third. */
+ emit_move_insn (operand_subword (operands[0], 2, 0,
+ TARGET_64BIT ? OImode : TImode),
+ gen_rtx_REG (Pmode, BASE_REGISTER));
emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
emit_move_insn (operand_subword (operands[0], 0, 0,
- TARGET_64BIT ? TImode : DImode),
+ TARGET_64BIT ? OImode : TImode),
temp);
emit_move_insn (operand_subword (operands[0], 1, 0,
- TARGET_64BIT ? TImode : DImode),
+ TARGET_64BIT ? OImode : TImode),
operands[1]);
DONE;
-}")
+})
(define_expand "restore_stack_nonlocal"
[(match_operand 0 "register_operand" "")
(match_operand 1 "memory_operand" "")]
""
- "
{
rtx temp = gen_reg_rtx (Pmode);
+ rtx base = gen_rtx_REG (Pmode, BASE_REGISTER);
- /* Restore the backchain from the first word, sp from the second. */
+ /* Restore the backchain from the first word, sp from the second and the
+ literal pool base from the third. */
emit_move_insn (temp,
operand_subword (operands[1], 0, 0,
- TARGET_64BIT ? TImode : DImode));
+ TARGET_64BIT ? OImode : TImode));
emit_move_insn (operands[0],
operand_subword (operands[1], 1, 0,
- TARGET_64BIT ? TImode : DImode));
+ TARGET_64BIT ? OImode : TImode));
emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
+ emit_move_insn (base,
+ operand_subword (operands[1], 2, 0,
+ TARGET_64BIT ? OImode : TImode));
+ emit_insn (gen_rtx_USE (VOIDmode, base));
+
DONE;
-}")
+})
;
@@ -6892,7 +7393,7 @@
(define_insn "nop"
[(const_int 0)]
""
- "lr\\t0,0"
+ "lr\t0,0"
[(set_attr "op_type" "RR")])
@@ -6900,143 +7401,97 @@
; Special literal pool access instruction pattern(s).
;
-(define_insn "consttable_qi"
- [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")] 200)]
- ""
- "*
-{
- assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "1")])
-
-(define_insn "consttable_hi"
- [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")] 201)]
- ""
- "*
-{
- assemble_integer (operands[0], 2, 2*BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "2")])
-
-(define_insn "consttable_si"
- [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")] 202)]
+(define_insn "*pool_entry"
+ [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
+ UNSPECV_POOL_ENTRY)]
""
- "*
{
- if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[0]))
- return \".long\\t%0\";
-
- assemble_integer (operands[0], 4, 4*BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "4")])
-
-(define_insn "consttable_di"
- [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")] 203)]
- ""
- "*
-{
- assemble_integer (operands[0], 8, 8*BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "8")])
-
-(define_insn "consttable_sf"
- [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")] 204)]
- ""
- "*
-{
- REAL_VALUE_TYPE r;
-
- if (GET_CODE (operands[0]) != CONST_DOUBLE)
- abort ();
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
- assemble_real (r, SFmode, 4*BITS_PER_UNIT);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "4")])
-
-(define_insn "consttable_df"
- [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")] 205)]
- ""
- "*
-{
- REAL_VALUE_TYPE r;
-
- if (GET_CODE (operands[0]) != CONST_DOUBLE)
- abort ();
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
- assemble_real (r, DFmode, 8*BITS_PER_UNIT);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "8")])
+ enum machine_mode mode = GET_MODE (PATTERN (insn));
+ unsigned int align = GET_MODE_BITSIZE (mode);
+ s390_output_pool_entry (asm_out_file, operands[0], mode, align);
+ return "";
+}
+ [(set_attr "op_type" "NN")
+ (set (attr "length")
+ (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
(define_insn "pool_start_31"
- [(unspec_volatile [(const_int 0)] 206)]
- "!TARGET_64BIT"
- ".align\\t4"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
+ "!TARGET_CPU_ZARCH"
+ ".align\t4"
[(set_attr "op_type" "NN")
(set_attr "length" "2")])
(define_insn "pool_end_31"
- [(unspec_volatile [(const_int 0)] 207)]
- "!TARGET_64BIT"
- ".align\\t2"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
+ "!TARGET_CPU_ZARCH"
+ ".align\t2"
[(set_attr "op_type" "NN")
(set_attr "length" "2")])
(define_insn "pool_start_64"
- [(unspec_volatile [(const_int 0)] 206)]
- "TARGET_64BIT"
- ".section\\t.rodata\;.align\\t8"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
+ "TARGET_CPU_ZARCH"
+ ".section\t.rodata\;.align\t8"
[(set_attr "op_type" "NN")
(set_attr "length" "0")])
(define_insn "pool_end_64"
- [(unspec_volatile [(const_int 0)] 207)]
- "TARGET_64BIT"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
+ "TARGET_CPU_ZARCH"
".previous"
[(set_attr "op_type" "NN")
(set_attr "length" "0")])
+(define_insn "main_base_31_small"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
+ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "basr\t%0,0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "la")])
+
+(define_insn "main_base_31_large"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
+ (set (pc) (label_ref (match_operand 2 "" "")))]
+ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "bras\t%0,%2"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "main_base_64"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "larl\t%0,%1"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "larl")])
+
+(define_insn "main_pool"
+ [(unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL)]
+ ""
+ "* abort ();"
+ [(set_attr "op_type" "NN")])
+
(define_insn "reload_base_31"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(label_ref (match_operand 1 "" ""))] 210))]
- "!TARGET_64BIT"
- "basr\\t%0,0\;la\\t%0,%1-.(%0)"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
+ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "basr\t%0,0\;la\t%0,%1-.(%0)"
[(set_attr "op_type" "NN")
(set_attr "type" "la")
(set_attr "length" "6")])
(define_insn "reload_base_64"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec:DI [(label_ref (match_operand 1 "" ""))] 210))]
- "TARGET_64BIT"
- "larl\\t%0,%1"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "larl\t%0,%1"
[(set_attr "op_type" "RIL")
- (set_attr "type" "la")])
-
-(define_insn "reload_anchor"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 211))]
- "!TARGET_64BIT"
- "l\\t%0,0(%1)\;la\\t%0,0(%0,%1)"
- [(set_attr "op_type" "NN")
- (set_attr "type" "la")
- (set_attr "length" "8")])
+ (set_attr "type" "larl")])
(define_insn "pool"
- [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] 220)]
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
""
"* abort ();"
[(set_attr "op_type" "NN")
@@ -7050,78 +7505,33 @@
(define_expand "prologue"
[(use (const_int 0))]
""
- "
-{
- s390_emit_prologue ();
- DONE;
-}")
+ "s390_emit_prologue (); DONE;")
(define_expand "epilogue"
[(use (const_int 1))]
""
- "
-{
- s390_emit_epilogue ();
- DONE;
-}")
-
+ "s390_emit_epilogue (); DONE;")
-(define_insn "*return_si"
+(define_insn "*return"
[(return)
- (use (match_operand:SI 0 "register_operand" "a"))]
- "!TARGET_64BIT"
- "br\\t%0"
+ (use (match_operand 0 "register_operand" "a"))]
+ "GET_MODE (operands[0]) == Pmode"
+ "br\t%0"
[(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
-(define_insn "*return_di"
- [(return)
- (use (match_operand:DI 0 "register_operand" "a"))]
- "TARGET_64BIT"
- "br\\t%0"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-(define_insn "literal_pool_31"
- [(unspec_volatile [(const_int 0)] 300)
- (set (match_operand:SI 0 "register_operand" "=a")
- (label_ref (match_operand 1 "" "")))
- (use (label_ref (match_operand 2 "" "")))]
- ""
-{
- if (s390_nr_constants)
- {
- output_asm_insn ("bras\\t%0,%2", operands);
- s390_output_constant_pool (operands[1], operands[2]);
- }
- else if (flag_pic)
- {
- /* We need the anchor label in any case. */
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (operands[1]));
- }
-
- return "";
-}
- [(set_attr "op_type" "NN")
- (set_attr "type" "la")])
+;; Instruction definition to extend a 31-bit pointer into a 64-bit
+;; pointer. This is used for compatibility.
-(define_insn "literal_pool_64"
- [(unspec_volatile [(const_int 0)] 300)
- (set (match_operand:DI 0 "register_operand" "=a")
- (label_ref (match_operand 1 "" "")))
- (use (label_ref (match_operand 2 "" "")))]
- ""
+(define_expand "ptr_extend"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (match_operand:SI 1 "register_operand" "r"))]
+ "TARGET_64BIT"
{
- if (s390_nr_constants)
- {
- output_asm_insn ("larl\\t%0,%1", operands);
- s390_output_constant_pool (operands[1], operands[2]);
- }
-
- return "";
-}
- [(set_attr "op_type" "NN")
- (set_attr "type" "la")])
+ emit_insn (gen_anddi3 (operands[0],
+ gen_lowpart (DImode, operands[1]),
+ GEN_INT (0x7fffffff)));
+ DONE;
+})
diff --git a/contrib/gcc/config/s390/s390x.h b/contrib/gcc/config/s390/s390x.h
index c79acf5..f9177c1 100644
--- a/contrib/gcc/config/s390/s390x.h
+++ b/contrib/gcc/config/s390/s390x.h
@@ -2,22 +2,23 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
-GNU CC 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 2, or (at your option)
-any later version.
+This file is part of GCC.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is 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 2, 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifndef _S390X_H
#define _S390X_H
diff --git a/contrib/gcc/config/s390/t-tpf b/contrib/gcc/config/s390/t-tpf
new file mode 100644
index 0000000..c04d562
--- /dev/null
+++ b/contrib/gcc/config/s390/t-tpf
@@ -0,0 +1,13 @@
+# Compile crtbeginS.o and crtendS.o with pic.
+CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
+# Compile libgcc2.a with pic.
+TARGET_LIBGCC2_CFLAGS = -fPIC
+
+# Override t-slibgcc-elf-ver to export some libgcc symbols with
+# the symbol versions that glibc used.
+SHLIB_MAPFILES += $(srcdir)/config/s390/libgcc-glibc.ver
+
+# Use unwind-dw2-fde-glibc
+LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
+ $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c gthr-gnat.c
diff --git a/contrib/gcc/config/s390/tpf.h b/contrib/gcc/config/s390/tpf.h
new file mode 100644
index 0000000..ce984e6
--- /dev/null
+++ b/contrib/gcc/config/s390/tpf.h
@@ -0,0 +1,112 @@
+/* Definitions for target OS TPF for GNU compiler, for IBM S/390 hardware
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by P.J. Darcy (darcypj@us.ibm.com),
+ Hartmut Penner (hpenner@de.ibm.com), and
+ Ulrich Weigand (uweigand@de.ibm.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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef _TPF_H
+#define _TPF_H
+
+/* TPF wants the following macros defined/undefined as follows. */
+#undef ASM_APP_ON
+#define ASM_APP_ON "#APP\n"
+#undef ASM_APP_OFF
+#define ASM_APP_OFF "#NO_APP\n"
+#define NO_IMPLICIT_EXTERN_C
+#define TARGET_HAS_F_SETLKW
+#undef MD_EXEC_PREFIX
+#undef MD_STARTFILE_PREFIX
+
+#undef SIZE_TYPE
+#define SIZE_TYPE ("long unsigned int")
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE ("long int")
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 32
+
+
+/* Basic record keeping for the TPF OS name. */
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (TPF: zSeries)");
+
+/* TPF OS specific stack-pointer offset. */
+#undef STACK_POINTER_OFFSET
+#define STACK_POINTER_OFFSET 280
+
+/* When building for TPF, set a generic default target that is 64 bits. */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT 0x33
+
+/* TPF OS specific compiler settings. */
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("tpf"); \
+ builtin_assert ("system=tpf"); \
+ builtin_define ("__ELF__"); \
+ if (flag_pic) \
+ { \
+ builtin_define ("__PIC__"); \
+ builtin_define ("__pic__"); \
+ } \
+ } \
+ while (0)
+
+
+/* Make TPF specific spec file settings here. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared: \
+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
+ %{!p:%{profile:gcrt1.o%s} \
+ %{!profile:crt1.o%s}}}} \
+ crti.o%s %{static:crtbeginT.o%s} \
+ %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+
+/* The GNU C++ standard library requires that these macros be defined. */
+#undef CPLUSPLUS_CPP_SPEC
+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{pthread:-lpthread} -lc"
+
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "-m elf64_s390 \
+ %{shared:-shared} \
+ %{!shared: \
+ %{static:-static} \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld64.so}}}"
+
+#endif /* ! _TPF_H */
+
diff --git a/contrib/gcc/config/sol2.h b/contrib/gcc/config/sol2.h
index c5980fb..955cd0e 100644
--- a/contrib/gcc/config/sol2.h
+++ b/contrib/gcc/config/sol2.h
@@ -1,21 +1,21 @@
/* Operating system specific defines to be used when targeting GCC for any
Solaris 2 system.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -53,6 +53,7 @@ Boston, MA 02111-1307, USA. */
"
/* Names to predefine in the preprocessor for this target machine. */
+#define TARGET_SUB_OS_CPP_BUILTINS()
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_define_std ("unix"); \
@@ -62,24 +63,28 @@ Boston, MA 02111-1307, USA. */
builtin_define ("__PRAGMA_REDEFINE_EXTNAME"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=svr4"); \
- /* For C++ we need to add some additional macro \
+ /* For C++ we need to add some additional macro \
definitions required by the C++ standard \
library. */ \
- if (c_language == clk_cplusplus) \
+ if (c_dialect_cxx ()) \
{ \
builtin_define ("_XOPEN_SOURCE=500"); \
builtin_define ("_LARGEFILE_SOURCE=1"); \
builtin_define ("_LARGEFILE64_SOURCE=1"); \
builtin_define ("__EXTENSIONS__"); \
} \
+ TARGET_SUB_OS_CPP_BUILTINS(); \
} while (0)
+/* The system headers under Solaris 2 are C++-aware since 2.0. */
+#define NO_IMPLICIT_EXTERN_C
+
/* The sun bundled assembler doesn't accept -Yd, (and neither does gas).
It's safe to pass -s always, even if -g is not used. */
#undef ASM_SPEC
#define ASM_SPEC "\
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s \
-%{fpic:-K PIC} %{fPIC:-K PIC} \
+%{fpic|fpie|fPIC|fPIE:-K PIC} \
%(asm_cpu) \
"
@@ -114,8 +119,8 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_ARCH_SPEC
#define STARTFILE_ARCH_SPEC STARTFILE_ARCH32_SPEC
-#undef LINK_ARCH32_SPEC
-#define LINK_ARCH32_SPEC \
+#undef LINK_ARCH32_SPEC_BASE
+#define LINK_ARCH32_SPEC_BASE \
"%{G:-G} \
%{YP,*} \
%{R*} \
@@ -127,6 +132,9 @@ Boston, MA 02111-1307, USA. */
%{!YP,*:%{p|pg:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
%{!p:%{!pg:-Y P,/usr/ccs/lib:/usr/lib}}}}"
+#undef LINK_ARCH32_SPEC
+#define LINK_ARCH32_SPEC LINK_ARCH32_SPEC_BASE
+
#undef LINK_ARCH_SPEC
#define LINK_ARCH_SPEC LINK_ARCH32_SPEC
@@ -155,24 +163,17 @@ Boston, MA 02111-1307, USA. */
/*
* Attempt to turn on access permissions for the stack.
*
- * This code must be defined when compiling gcc but not when compiling
- * libgcc2.a, unless we're generating code for 64-bit SPARC
- *
* _SC_STACK_PROT is only defined for post 2.6, but we want this code
* to run always. 2.6 can change the stack protection but has no way to
* query it.
*
*/
-/* This declares mprotect (used in TRANSFER_FROM_TRAMPOLINE) for
- libgcc2.c. */
-/* We don't want to include this because sys/mman.h is not present on
- some non-Solaris configurations that use sol2.h. */
-#if 0 /* def L_trampoline */
-#include <sys/mman.h>
-#endif
+/* sys/mman.h is not present on some non-Solaris configurations
+ that use sol2.h, so ENABLE_EXECUTE_STACK must use a magic
+ number instead of the appropriate PROT_* flags. */
-#define TRANSFER_FROM_TRAMPOLINE \
+#define ENABLE_EXECUTE_STACK \
\
/* #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) */ \
\
@@ -190,9 +191,9 @@ static void check_enabling(void) \
\
extern void __enable_execute_stack (void *); \
void \
-__enable_execute_stack (addr) \
- void *addr; \
+__enable_execute_stack (void *addr) \
{ \
+ extern int mprotect (void *, size_t, int); \
if (!need_enable_exec_stack) \
return; \
else { \
diff --git a/contrib/gcc/config/sparc/aout.h b/contrib/gcc/config/sparc/aout.h
index 7532281..1031048 100644
--- a/contrib/gcc/config/sparc/aout.h
+++ b/contrib/gcc/config/sparc/aout.h
@@ -1,21 +1,21 @@
-/* Definitions of target machine for GNU compiler, for SPARC using a.out.
+/* Definitions of target machine for GCC, for SPARC using a.out.
Copyright (C) 1994, 1996, 2002 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,14 +23,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fprintf (stderr, " (sparc)");
-/* Names to predefine in the preprocessor for this target machine.
- ??? It would be nice to not include any subtarget specific values here,
- however there's no way to portably provide subtarget values to
- CPP_PREFINES. Also, -D values in CPP_SUBTARGET_SPEC don't get turned into
- foo, __foo and __foo__. */
-
-#define CPP_PREDEFINES "-Dsparc -Acpu=sparc -Amachine=sparc"
-
/* These compiler options take an argument. We ignore -target for now. */
#define WORD_SWITCH_TAKES_ARG(STR) \
@@ -67,8 +59,6 @@ do { \
This is needed for SunOS 4.0, and should not hurt for 3.2
versions either. */
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
- { static int sym_lineno = 1; \
- fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n", \
- line, sym_lineno, sym_lineno); \
- sym_lineno += 1; }
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
+ fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n", \
+ line, counter, counter)
diff --git a/contrib/gcc/config/sparc/biarch64.h b/contrib/gcc/config/sparc/biarch64.h
index f85111ab..b825f4f 100644
--- a/contrib/gcc/config/sparc/biarch64.h
+++ b/contrib/gcc/config/sparc/biarch64.h
@@ -1,21 +1,21 @@
-/* Definitions of target machine for GNU compiler, for Sun SPARC.
+/* Definitions of target machine for GCC, for Sun SPARC.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/sparc/cypress.md b/contrib/gcc/config/sparc/cypress.md
index e9bff6d..c234594 100644
--- a/contrib/gcc/config/sparc/cypress.md
+++ b/contrib/gcc/config/sparc/cypress.md
@@ -1,20 +1,20 @@
;; Scheduling description for SPARC Cypress.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/elf.h b/contrib/gcc/config/sparc/elf.h
index d2d3a0b..5f01a34 100644
--- a/contrib/gcc/config/sparc/elf.h
+++ b/contrib/gcc/config/sparc/elf.h
@@ -1,27 +1,24 @@
-/* Definitions of target machine for GNU compiler,
+/* Definitions of target machine for GCC,
for SPARC running in an embedded environment using the ELF file format.
Copyright (C) 1997 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -D__elf__"
-
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
@@ -45,14 +42,9 @@ Boston, MA 02111-1307, USA. */
#undef STDC_0_IN_SYSTEM_HEADERS
/* We don't want to use the Solaris2 specific long long int conversion
- routines. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS
-
-/* ??? We haven't added Solaris2 equivalent 64 bit library routines to
- lb1sp*.asm, so we need to avoid using them. */
-#undef MULDI3_LIBCALL
-#undef DIVDI3_LIBCALL
-#undef UDIVDI3_LIBCALL
-#undef MODDI3_LIBCALL
-#undef UMODDI3_LIBCALL
+ routines or 64-bit integer multiply and divide routines. */
+#undef SUN_CONVERSION_LIBFUNCS
+#define SUN_CONVERSION_LIBFUNCS 0
+
+#undef SUN_INTEGER_MULTIPLY_64
+#define SUN_INTEGER_MULTIPLY_64 0
diff --git a/contrib/gcc/config/sparc/gmon-sol2.c b/contrib/gcc/config/sparc/gmon-sol2.c
index c577666..9f9f019 100644
--- a/contrib/gcc/config/sparc/gmon-sol2.c
+++ b/contrib/gcc/config/sparc/gmon-sol2.c
@@ -32,8 +32,11 @@
* for Cygnus Support, July 1992.
*/
-#include "config.h"
-#include "system.h"
+#include "tconfig.h"
+#include "tsystem.h"
+#include <fcntl.h> /* for creat() */
+#include "coretypes.h"
+#include "tm.h"
#if 0
#include "sparc/gmon.h"
@@ -85,13 +88,11 @@ static int s_scale;
#define MSG "No space for profiling buffer(s)\n"
-static void moncontrol PARAMS ((int));
-extern void monstartup PARAMS ((char *, char *));
-extern void _mcleanup PARAMS ((void));
+static void moncontrol (int);
+extern void monstartup (char *, char *);
+extern void _mcleanup (void);
-void monstartup(lowpc, highpc)
- char *lowpc;
- char *highpc;
+void monstartup(char *lowpc, char *highpc)
{
int monsize;
char *buffer;
@@ -167,7 +168,7 @@ void monstartup(lowpc, highpc)
}
void
-_mcleanup()
+_mcleanup(void)
{
int fd;
int fromindex;
@@ -266,7 +267,8 @@ _mcleanup()
* -- [eichin:19920702.1107EST]
*/
-static void internal_mcount PARAMS ((char *, unsigned short *)) ATTRIBUTE_UNUSED;
+static void internal_mcount (char *, unsigned short *)
+ __attribute__ ((__unused__));
/* i7 == last ret, -> frompcindex */
/* o7 == current ret, -> selfpc */
@@ -275,9 +277,7 @@ asm(".global _mcount; _mcount: mov %i7,%o1; mov %o7,%o0;b,a internal_mcount");
/* This is for compatibility with old versions of gcc which used mcount. */
asm(".global mcount; mcount: mov %i7,%o1; mov %o7,%o0;b,a internal_mcount");
-static void internal_mcount(selfpc, frompcindex)
- register char *selfpc;
- register unsigned short *frompcindex;
+static void internal_mcount(char *selfpc, unsigned short *frompcindex)
{
register struct tostruct *top;
register struct tostruct *prevtop;
@@ -407,8 +407,7 @@ overflow:
* profiling is what mcount checks to see if
* all the data structures are ready.
*/
-static void moncontrol(mode)
- int mode;
+static void moncontrol(int mode)
{
if (mode) {
/* start */
diff --git a/contrib/gcc/config/sparc/hypersparc.md b/contrib/gcc/config/sparc/hypersparc.md
index d80e51e..d617efd 100644
--- a/contrib/gcc/config/sparc/hypersparc.md
+++ b/contrib/gcc/config/sparc/hypersparc.md
@@ -1,20 +1,20 @@
;; Scheduling description for HyperSPARC.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/linux.h b/contrib/gcc/config/sparc/linux.h
index e4bd7bb..7ddf2a3 100644
--- a/contrib/gcc/config/sparc/linux.h
+++ b/contrib/gcc/config/sparc/linux.h
@@ -1,37 +1,40 @@
/* Definitions for SPARC running Linux-based GNU systems with ELF.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Eddie C. Dost (ecd@skynet.be)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("linux"); \
+ builtin_define ("__gnu_linux__"); \
+ builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } \
+ while (0)
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
- For now, we play safe. It may change later. */
-
-#if 0
-#undef MULTIBYTE_CHARS
-#define MULTIBYTE_CHARS 1
-#endif
-
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
@@ -46,12 +49,14 @@ Boston, MA 02111-1307, USA. */
"%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#elif defined HAVE_LD_PIE
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
- crti.o%s %{static:crtbeginT.o%s}\
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+ "%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
@@ -63,7 +68,7 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
- %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* This is for -profile to use -lc_p instead of -lc. */
#undef CC1_SPEC
@@ -98,17 +103,14 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__sparc__ -D__gnu_linux__ -Dlinux -Asystem=unix -Asystem=posix"
-
#undef CPP_SUBTARGET_SPEC
#ifdef USE_GNULIBC_1
#define CPP_SUBTARGET_SPEC \
-"%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
+"%{fPIC|fPIE|fpic|fpie:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
%{mlong-double-128:-D__LONG_DOUBLE_128__}"
#else
#define CPP_SUBTARGET_SPEC \
-"%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
+"%{fPIC|fPIE|fpic|fpie:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
%{pthread:-D_REENTRANT} %{mlong-double-128:-D__LONG_DOUBLE_128__}"
#endif
@@ -152,15 +154,6 @@ Boston, MA 02111-1307, USA. */
#undef LINK_SPEC
#ifdef USE_GNULIBC_1
-#ifndef LINUX_DEFAULT_ELF
-#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
- %{!shared: \
- %{!ibcs: \
- %{!static: \
- %{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \
- %{!rpath:-rpath /lib/elf/}} %{static:-static}}}"
-#else
#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
%{!shared: \
%{!ibcs: \
@@ -168,7 +161,6 @@ Boston, MA 02111-1307, USA. */
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \
%{static:-static}}}"
-#endif
#else
#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
%{!mno-relax:%{!r:-relax}} \
@@ -184,8 +176,8 @@ Boston, MA 02111-1307, USA. */
It's safe to pass -s always, even if -g is not used. */
#undef ASM_SPEC
#define ASM_SPEC \
- "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} \
- %{fPIC:-K PIC} %(asm_cpu) %(asm_relax)"
+ "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s \
+ %{fpic|fPIC|fpie|fPIE:-K PIC} %(asm_cpu) %(asm_relax)"
/* Same as sparc.h */
#undef DBX_REGISTER_NUMBER
@@ -206,13 +198,6 @@ do { \
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -245,10 +230,20 @@ do { \
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
#endif
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS 1
+
#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
+#ifdef HAVE_AS_TLS
+#undef TARGET_SUN_TLS
+#undef TARGET_GNU_TLS
+#define TARGET_SUN_TLS 0
+#define TARGET_GNU_TLS 1
+#endif
+
/* Don't be different from other Linux platforms in this regard. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
@@ -256,6 +251,14 @@ do { \
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+/* Determine whether the the entire c99 runtime is present in the
+ runtime library. */
+#define TARGET_C99_FUNCTIONS 1
+
+#define TARGET_HAS_F_SETLKW
+
#undef LINK_GCC_C_SEQUENCE_SPEC
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
diff --git a/contrib/gcc/config/sparc/linux64.h b/contrib/gcc/config/sparc/linux64.h
index 27be1d1..bb1c591 100644
--- a/contrib/gcc/config/sparc/linux64.h
+++ b/contrib/gcc/config/sparc/linux64.h
@@ -1,25 +1,37 @@
/* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF.
- Copyright 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by David S. Miller (davem@caip.rutgers.edu)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("linux"); \
+ builtin_define ("_LONGLONG"); \
+ builtin_define ("__gnu_linux__"); \
+ builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } \
+ while (0)
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
@@ -27,7 +39,9 @@ Boston, MA 02111-1307, USA. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
+#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
/* A 64 bit v9 compiler with stack-bias,
in a Medium/Low code model environment. */
@@ -43,8 +57,7 @@ Boston, MA 02111-1307, USA. */
#ifdef SPARC_BI_ARCH
#undef CPP_ARCH32_SPEC
-#define CPP_ARCH32_SPEC "%{mlong-double-128:-D__LONG_DOUBLE_128__} \
--D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
+#define CPP_ARCH32_SPEC "%{mlong-double-128:-D__LONG_DOUBLE_128__}"
#endif
@@ -55,10 +68,15 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
+#ifdef HAVE_LD_PIE
#define STARTFILE_SPEC \
- "%{!shared:%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
- crti.o%s %{static:crtbeginT.o%s}\
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+ "%{!shared:%{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbeginS.o%s}"
+#else
+#define STARTFILE_SPEC \
+ "%{!shared:%{pg|p:gcrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbeginS.o%s}"
+#endif
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
the GNU/Linux magical crtend.o file (see crtstuff.c) which
@@ -69,7 +87,7 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
- "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s\
+ "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s\
%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
/* The GNU C++ standard library requires that these macros be defined. */
@@ -111,13 +129,9 @@ Boston, MA 02111-1307, USA. */
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
#endif
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__ELF__ -Dunix -D_LONGLONG -D__sparc__ -D__gnu_linux__ -Dlinux -Asystem=unix -Asystem=posix"
-
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "\
-%{fPIC:-D__PIC__ -D__pic__} \
-%{fpic:-D__PIC__ -D__pic__} \
+%{fPIC|fpic|fPIE|fpie:-D__PIC__ -D__pic__} \
%{posix:-D_POSIX_SOURCE} \
%{pthread:-D_REENTRANT} \
"
@@ -213,6 +227,27 @@ Boston, MA 02111-1307, USA. */
"
#endif
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float, -msoft-float, -mfpu, or -mno-fpu
+ are specified.
+ In the SPARC_BI_ARCH compiler we cannot pass %{!mcpu=*:-mcpu=%(VALUE)}
+ here, otherwise say -mcpu=v7 would be passed even when -m64.
+ CC1_SPEC above takes care of this instead. */
+#undef OPTION_DEFAULT_SPECS
+#if DEFAULT_ARCH32_P
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m64:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#else
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m32:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#endif
+
#if DEFAULT_ARCH32_P
#define MULTILIB_DEFAULTS { "m32" }
#else
@@ -246,7 +281,7 @@ Boston, MA 02111-1307, USA. */
%{T} \
%{Ym,*} \
%{Wa,*:%*} \
--s %{fpic:-K PIC} %{fPIC:-K PIC} \
+-s %{fpic|fPIC|fpie|fPIE:-K PIC} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) %(asm_relax)"
@@ -254,10 +289,6 @@ Boston, MA 02111-1307, USA. */
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
-/* System V Release 4 uses DWARF debugging info. Buf DWARF1 doesn't do
- 64-bit anything, so we use DWARF2. */
-
-#undef DWARF_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO 1
#define DBX_DEBUGGING_INFO 1
@@ -276,13 +307,6 @@ do { \
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -308,10 +332,20 @@ do { \
/* #define DWARF_OFFSET_SIZE PTR_SIZE */
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS 1
+
#if defined(HAVE_LD_EH_FRAME_HDR)
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
+#ifdef HAVE_AS_TLS
+#undef TARGET_SUN_TLS
+#undef TARGET_GNU_TLS
+#define TARGET_SUN_TLS 0
+#define TARGET_GNU_TLS 1
+#endif
+
/* Don't be different from other Linux platforms in this regard. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
@@ -319,6 +353,14 @@ do { \
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+/* Determine whether the the entire c99 runtime is present in the
+ runtime library. */
+#define TARGET_C99_FUNCTIONS 1
+
+#define TARGET_HAS_F_SETLKW
+
#undef LINK_GCC_C_SEQUENCE_SPEC
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
diff --git a/contrib/gcc/config/sparc/lite.h b/contrib/gcc/config/sparc/lite.h
index 95da781..cac67ec 100644
--- a/contrib/gcc/config/sparc/lite.h
+++ b/contrib/gcc/config/sparc/lite.h
@@ -1,27 +1,24 @@
-/* Definitions of target machine for GNU compiler, for SPARClite w/o FPU.
+/* Definitions of target machine for GCC, for SPARClite w/o FPU.
Copyright (C) 1993, 1996 Free Software Foundation, Inc.
Contributed by Jim Wilson (wilson@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -Dsparclite -Acpu=sparc -Amachine=sparc"
-
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (sparclite)");
@@ -30,6 +27,5 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_APP_REGS
-/* US Software GOFAST library support. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS INIT_GOFAST_OPTABS
+/* Enable US Software GOFAST library support. */
+#define US_SOFTWARE_GOFAST
diff --git a/contrib/gcc/config/sparc/litecoff.h b/contrib/gcc/config/sparc/litecoff.h
index 91808f5..e31a0b4 100644
--- a/contrib/gcc/config/sparc/litecoff.h
+++ b/contrib/gcc/config/sparc/litecoff.h
@@ -1,28 +1,33 @@
-/* Definitions of target machine for GNU compiler, for SPARClite w/o FPU, COFF.
+/* Definitions of target machine for GCC, for SPARClite w/o FPU, COFF.
Copyright (C) 1994, 1996, 2000, 2002 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define BSS_SECTION_ASM_OP "\t.section\t\".bss\""
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -Dsparclite -Acpu=sparc -Amachine=sparc"
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ builtin_define_std ("sparclite"); \
+ } \
+ while (0)
/* Default to stabs in COFF. */
diff --git a/contrib/gcc/config/sparc/liteelf.h b/contrib/gcc/config/sparc/liteelf.h
index 9b6cbaa..49a2089 100644
--- a/contrib/gcc/config/sparc/liteelf.h
+++ b/contrib/gcc/config/sparc/liteelf.h
@@ -1,30 +1,34 @@
-/* Definitions of target machine for GNU compiler, for SPARClite w/o FPU.
+/* Definitions of target machine for GCC, for SPARClite w/o FPU, ELF.
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Stan Cox (scox@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__sparc__ -D__sparclite__ -Acpu=sparc -Amachine=sparc"
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__sparclite__"); \
+ } \
+ while (0)
/* Default to dwarf2 in ELF. */
-#define DWARF_DEBUGGING_INFO 1
#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
@@ -38,9 +42,8 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_APP_REGS
-/* US Software GOFAST library support. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS INIT_GOFAST_OPTABS
+/* Enable US Software GOFAST library support. */
+#define US_SOFTWARE_GOFAST
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crti.o%s crtbegin.o%s"
diff --git a/contrib/gcc/config/sparc/netbsd-elf.h b/contrib/gcc/config/sparc/netbsd-elf.h
index 10788f2..bc92eb2 100644
--- a/contrib/gcc/config/sparc/netbsd-elf.h
+++ b/contrib/gcc/config/sparc/netbsd-elf.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler, for ELF on NetBSD/sparc
+/* Definitions of target machine for GCC, for ELF on NetBSD/sparc
and NetBSD/sparc64.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Matthew Green (mrg@eterna.com.au).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,9 +26,9 @@ Boston, MA 02111-1307, USA. */
NETBSD_OS_CPP_BUILTINS_ELF(); \
if (TARGET_ARCH64) \
{ \
- NETBSD_OS_CPP_BUILTINS_LP64(); \
builtin_define ("__sparc64__"); \
builtin_define ("__sparc_v9__"); \
+ builtin_define ("__sparcv9"); \
} \
else \
builtin_define ("__sparc"); \
@@ -40,9 +40,6 @@ Boston, MA 02111-1307, USA. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-/* Make sure this is undefined. */
-#undef CPP_PREDEFINES
-
/* CPP defines used by all NetBSD targets. */
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "%(netbsd_cpp_spec)"
@@ -69,13 +66,6 @@ Boston, MA 02111-1307, USA. */
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -96,31 +86,18 @@ Boston, MA 02111-1307, USA. */
#define USER_LABEL_PREFIX ""
#undef ASM_SPEC
-#define ASM_SPEC "%{fpic:-K PIC} %{fPIC:-K PIC} %{V} %{v:%{!V:-V}} \
+#define ASM_SPEC "%{fpic|fPIC|fpie|fPIE:-K PIC} %{V} %{v:%{!V:-V}} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) %(asm_relax)"
#undef STDC_0_IN_SYSTEM_HEADERS
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);
-/*
- * Clean up afterwards generic SPARC ELF configuration.
- */
-
-/* FIXME: Aren't these supposed to be available for SPARC ELF? */
-#undef MULDI3_LIBCALL
-#undef DIVDI3_LIBCALL
-#undef UDIVDI3_LIBCALL
-#undef MODDI3_LIBCALL
-#undef UMODDI3_LIBCALL
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS
-
/* Below here exists the merged NetBSD/sparc & NetBSD/sparc64 compiler
description, allowing one to build 32 bit or 64 bit applications
on either. We define the sparc & sparc64 versions of things,
diff --git a/contrib/gcc/config/sparc/openbsd.h b/contrib/gcc/config/sparc/openbsd.h
index a4333df..e36f51e 100644
--- a/contrib/gcc/config/sparc/openbsd.h
+++ b/contrib/gcc/config/sparc/openbsd.h
@@ -1,29 +1,33 @@
/* Configuration file for sparc OpenBSD target.
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Get generic OpenBSD definitions. */
-#define OBSD_OLD_GAS
-#include <openbsd.h>
-
-/* Run-time target specifications. */
-#define CPP_PREDEFINES "-D__unix__ -D__sparc__ -D__OpenBSD__ -Asystem=unix -Asystem=OpenBSD -Acpu=sparc -Amachine=sparc"
+/* Target OS builtins. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__unix__"); \
+ builtin_define ("__OpenBSD__"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=OpenBSD"); \
+ } \
+ while (0)
/* Layout of source language data types */
@@ -58,8 +62,7 @@ Boston, MA 02111-1307, USA. */
/* Assembler format: exception region output. */
/* All configurations that don't use elf must be explicit about not using
- dwarf unwind information. egcs doesn't try too hard to check internal
- configuration files... */
+ dwarf unwind information. */
#define DWARF2_UNWIND_INFO 0
#undef ASM_PREFERRED_EH_DATA_FORMAT
diff --git a/contrib/gcc/config/sparc/openbsd64.h b/contrib/gcc/config/sparc/openbsd64.h
index 4dfe381..e13c886 100644
--- a/contrib/gcc/config/sparc/openbsd64.h
+++ b/contrib/gcc/config/sparc/openbsd64.h
@@ -30,9 +30,20 @@ Boston, MA 02111-1307, USA. */
#undef SPARC_DEFAULT_CMODEL
#define SPARC_DEFAULT_CMODEL CM_MEDMID
-/* Run-time target specifications. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__unix__ -D__sparc__ -D__sparc64__ -D__sparcv9__ -D__sparc_v9__ -D__arch64__ -D__ELF__ -D__OpenBSD__ -Asystem(unix) -Asystem(OpenBSD) -Acpu(sparc) -Amachine(sparc)"
+/* Target OS builtins. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__unix__"); \
+ builtin_define ("__OpenBSD__"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=OpenBSD"); \
+ builtin_define ("__sparc64__"); \
+ builtin_define ("__sparcv9__"); \
+ builtin_define ("__sparc_v9__"); \
+ builtin_define ("__arch64__"); \
+ } \
+ while (0)
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC ""
@@ -42,7 +53,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC "\
-%{v:-V} -s %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{v:-V} -s %{fpic|fPIC|fpie|fPIE:-K PIC} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) \
"
diff --git a/contrib/gcc/config/sparc/pbd.h b/contrib/gcc/config/sparc/pbd.h
index e7c01c0..e9344a0 100644
--- a/contrib/gcc/config/sparc/pbd.h
+++ b/contrib/gcc/config/sparc/pbd.h
@@ -2,28 +2,32 @@
version (using GAS and COFF (encapsulated is unacceptable) )
Copyright (C) 1990, 1996, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
-/* Names to predefine in the preprocessor for this target machine. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -DUnicomPBD -Dunix -D__GCC_NEW_VARARGS__ -Asystem=unix -Acpu=sparc -Amachine=sparc"
+/* Target OS builtins. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("UnicomPBD"); \
+ builtin_assert ("system=unix"); \
+ } \
+ while (0)
/* We want DBX format for use with gdb under COFF. */
@@ -116,18 +120,9 @@ Boston, MA 02111-1307, USA. */
This is suitable for output with `assemble_name'. */
#undef ASM_GENERATE_INTERNAL_LABEL
-
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf (LABEL, "*.%s%ld", PREFIX, (long)(NUM))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
-
/* This is how to output an element of a case-vector that is relative. */
#undef ASM_OUTPUT_ADDR_DIFF_ELT
@@ -145,10 +140,8 @@ Boston, MA 02111-1307, USA. */
/* This is needed for SunOS 4.0, and should not hurt for 3.2
versions either. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
- { static int sym_lineno = 1; \
- fprintf (file, ".stabn 68,0,%d,.LM%d\n.LM%d:\n", \
- line, sym_lineno, sym_lineno); \
- sym_lineno += 1; }
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
+ fprintf (file, ".stabn 68,0,%d,.LM%d\n.LM%d:\n", \
+ line, counter, counter)
#define ASM_INT_OP "\t.long "
diff --git a/contrib/gcc/config/sparc/rtemself.h b/contrib/gcc/config/sparc/rtemself.h
index 4f2cc66..ffb2a72 100644
--- a/contrib/gcc/config/sparc/rtemself.h
+++ b/contrib/gcc/config/sparc/rtemself.h
@@ -2,25 +2,30 @@
Copyright (C) 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -D__GCC_NEW_VARARGS__ -D__rtems__ \
- -D__USE_INIT_FINI__ -Asystem=rtems"
+/* Target OS builtins. */
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ builtin_define ("__rtems__"); \
+ builtin_define ("__USE_INIT_FINI__"); \
+ builtin_assert ("system=rtems"); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/sparc/sol2-64.h b/contrib/gcc/config/sparc/sol2-64.h
index ccdc8f3..d53747a 100644
--- a/contrib/gcc/config/sparc/sol2-64.h
+++ b/contrib/gcc/config/sparc/sol2-64.h
@@ -1,7 +1,16 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2, defaulting to 64-bit code generation. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ + \
MASK_STACK_BIAS + MASK_FPU + MASK_LONG_DOUBLE_128)
+
+/* Target OS builtins. */
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/sparc/sol2-bi.h b/contrib/gcc/config/sparc/sol2-bi.h
index 3f9416d..80ec1da 100644
--- a/contrib/gcc/config/sparc/sol2-bi.h
+++ b/contrib/gcc/config/sparc/sol2-bi.h
@@ -1,4 +1,4 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2 using the system assembler and linker. */
/* The default code model. */
@@ -18,6 +18,7 @@
#undef ASM_CPU32_DEFAULT_SPEC
#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plus"
#endif
+
#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
#undef CPP_CPU64_DEFAULT_SPEC
#define CPP_CPU64_DEFAULT_SPEC ""
@@ -27,6 +28,15 @@
#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "a"
#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
+#undef CPP_CPU64_DEFAULT_SPEC
+#define CPP_CPU64_DEFAULT_SPEC ""
+#undef ASM_CPU32_DEFAULT_SPEC
+#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plusb"
+#undef ASM_CPU64_DEFAULT_SPEC
+#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "b"
+#endif
+
#if DEFAULT_ARCH32_P
#define DEF_ARCH32_SPEC(__str) "%{!m64:" __str "}"
#define DEF_ARCH64_SPEC(__str) "%{m64:" __str "}"
@@ -45,15 +55,16 @@
%{mcpu=sparclite|mcpu-f930|mcpu=f934:-D__sparclite__} \
%{mcpu=v8:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
%{mcpu=supersparc:-D__supersparc__ " DEF_ARCH32_SPEC("-D__sparcv8") "} \
-%{mcpu=v9|mcpu=ultrasparc:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
+%{mcpu=v9|mcpu=ultrasparc|mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
"
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC "\
-%{mcpu=ultrasparc:" DEF_ARCH32_SPEC("-xarch=v8plusa") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "a") "} \
%{mcpu=v9:" DEF_ARCH32_SPEC("-xarch=v8plus") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "} \
-%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}} \
+%{mcpu=ultrasparc:" DEF_ARCH32_SPEC("-xarch=v8plusa") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "a") "} \
+%{mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
+%{!mcpu=ultrasparc3:%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}}} \
%{!mcpu*:%(asm_cpu_default)} \
"
@@ -98,11 +109,9 @@
#define WINT_TYPE_SIZE 32
#undef CPP_ARCH32_SPEC
-#define CPP_ARCH32_SPEC "\
--D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
+#define CPP_ARCH32_SPEC ""
#undef CPP_ARCH64_SPEC
-#define CPP_ARCH64_SPEC "\
--D__arch64__ -Acpu=sparc64 -Amachine=sparcv9 -D__sparcv9"
+#define CPP_ARCH64_SPEC "-D__arch64__ -D__sparcv9"
#undef CPP_ARCH_SPEC
#define CPP_ARCH_SPEC "\
@@ -135,7 +144,7 @@
* This should be the same as in sol2.h, except with "/sparcv9"
* appended to the paths and /usr/ccs/lib is no longer necessary
*/
-#define LINK_ARCH64_SPEC \
+#define LINK_ARCH64_SPEC_BASE \
"%{mcmodel=medlow:-M /usr/lib/ld/sparcv9/map.below4G} \
%{G:-G} \
%{YP,*} \
@@ -143,17 +152,35 @@
%{compat-bsd: \
%{!YP,*:%{p|pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
%{!p:%{!pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/sparcv9}}} \
- -R /usr/ucblib} \
+ -R /usr/ucblib/sparcv9} \
%{!compat-bsd: \
%{!YP,*:%{p|pg:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
%{!p:%{!pg:-Y P,/usr/lib/sparcv9}}}}"
+#define LINK_ARCH64_SPEC LINK_ARCH64_SPEC_BASE
+
#undef LINK_ARCH_SPEC
+#if DISABLE_MULTILIB
+#if DEFAULT_ARCH32_P
#define LINK_ARCH_SPEC "\
%{m32:%(link_arch32)} \
+%{m64:%edoes not support multilib} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:%edoes not support multilib} \
%{m64:%(link_arch64)} \
%{!m32:%{!m64:%(link_arch_default)}} \
"
+#endif
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:%(link_arch32)} \
+%{m64:%(link_arch64)} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#endif
#define LINK_ARCH_DEFAULT_SPEC \
(DEFAULT_ARCH32_P ? LINK_ARCH32_SPEC : LINK_ARCH64_SPEC)
@@ -183,23 +210,36 @@
"
#endif
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float, -msoft-float, -mfpu, or -mno-fpu
+ are specified.
+ In the SPARC_BI_ARCH compiler we cannot pass %{!mcpu=*:-mcpu=%(VALUE)}
+ here, otherwise say -mcpu=v7 would be passed even when -m64.
+ CC1_SPEC above takes care of this instead. */
+#undef OPTION_DEFAULT_SPECS
+#if DEFAULT_ARCH32_P
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m64:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#else
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m32:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#endif
+
#if DEFAULT_ARCH32_P
#define MULTILIB_DEFAULTS { "m32" }
#else
#define MULTILIB_DEFAULTS { "m64" }
#endif
-/* We use stabs-in-elf in 32-bit mode, because that is what the native
- toolchain uses. But gdb can't handle truncated 32-bit stabs so we
- use dwarf2 in 64-bit mode. */
#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE (TARGET_ARCH32 ? DBX_DEBUG : DWARF2_DEBUG)
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-/* We can't use the above definition for the purposes of specs. */
#if defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
-# if DEFAULT_ARCH32_P
-# define ASM_DEBUG_SPEC "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}"
-# else
-# define ASM_DEBUG_SPEC "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}"
-# endif
+# define ASM_DEBUG_SPEC "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}"
#endif
diff --git a/contrib/gcc/config/sparc/sol2-gas-bi.h b/contrib/gcc/config/sparc/sol2-gas-bi.h
index 0b6cb61..88b3954 100644
--- a/contrib/gcc/config/sparc/sol2-gas-bi.h
+++ b/contrib/gcc/config/sparc/sol2-gas-bi.h
@@ -1,5 +1,5 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2 using the GNU assembler. */
-#undef AS_SPARC64_FLAG
-#define AS_SPARC64_FLAG "-64 -Av9"
+#undef AS_SPARC64_FLAG
+#define AS_SPARC64_FLAG "-TSO -64 -Av9"
diff --git a/contrib/gcc/config/sparc/sol2-gld-bi.h b/contrib/gcc/config/sparc/sol2-gld-bi.h
index 81a1ff2..aa9a40b 100644
--- a/contrib/gcc/config/sparc/sol2-gld-bi.h
+++ b/contrib/gcc/config/sparc/sol2-gld-bi.h
@@ -1,9 +1,34 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2 using the GNU linker. */
+#undef LINK_ARCH32_SPEC
+#define LINK_ARCH32_SPEC \
+ LINK_ARCH32_SPEC_BASE "%{!static: -rpath-link %R/usr/lib}"
+
+#undef LINK_ARCH64_SPEC
+#define LINK_ARCH64_SPEC \
+ LINK_ARCH64_SPEC_BASE "%{!static: -rpath-link %R/usr/lib/sparcv9}"
+
#undef LINK_ARCH_SPEC
+#if DISABLE_MULTILIB
+#if DEFAULT_ARCH32_P
#define LINK_ARCH_SPEC "\
%{m32:-m elf32_sparc %(link_arch32)} \
+%{m64:%edoes not support multilib} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:%edoes not support multilib} \
%{m64:-m elf64_sparc %(link_arch64)} \
%{!m32:%{!m64:%(link_arch_default)}} \
"
+#endif
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:-m elf32_sparc %(link_arch32)} \
+%{m64:-m elf64_sparc %(link_arch64)} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#endif
+
diff --git a/contrib/gcc/config/sparc/sol2-gld.h b/contrib/gcc/config/sparc/sol2-gld.h
index 76e034e..eb422cb 100644
--- a/contrib/gcc/config/sparc/sol2-gld.h
+++ b/contrib/gcc/config/sparc/sol2-gld.h
@@ -1,6 +1,9 @@
-/* Definitions of target machine for GNU compiler, for SPARC running Solaris 2
+/* Definitions of target machine for GCC, for SPARC running Solaris 2
using the GNU linker. */
/* Undefine this so that attribute((init_priority)) works. */
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+
+#undef SUPPORTS_INIT_PRIORITY
+#define SUPPORTS_INIT_PRIORITY 1
diff --git a/contrib/gcc/config/sparc/sol2.h b/contrib/gcc/config/sparc/sol2.h
index 3026e40..cbf914e 100644
--- a/contrib/gcc/config/sparc/sol2.h
+++ b/contrib/gcc/config/sparc/sol2.h
@@ -1,31 +1,28 @@
-/* Definitions of target machine for GNU compiler, for SPARC running Solaris 2
- Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+/* Definitions of target machine for GCC, for SPARC running Solaris 2
+ Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@netcom.com).
Additional changes by David V. Henkel-Wallace (gumby@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Supposedly the same as vanilla sparc svr4, except for the stuff below: */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc"
-
/* This is here rather than in sparc.h because it's not known what
other assemblers will accept. */
@@ -39,11 +36,16 @@ Boston, MA 02111-1307, USA. */
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusa"
#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
+#undef ASM_CPU_DEFAULT_SPEC
+#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusb"
+#endif
+
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC "\
-%{mcpu=v8plus:-xarch=v8plus} \
%{mcpu=v9:-xarch=v8plus} \
%{mcpu=ultrasparc:-xarch=v8plusa} \
+%{mcpu=ultrasparc3:-xarch=v8plusb} \
%{!mcpu*:%(asm_cpu_default)} \
"
@@ -63,18 +65,11 @@ Boston, MA 02111-1307, USA. */
/* The Solaris 2 assembler uses .skip, not .zero, so put this back. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.skip %u\n", (SIZE))
+ fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -91,6 +86,33 @@ Boston, MA 02111-1307, USA. */
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf ((LABEL), "*.L%s%ld", (PREFIX), (long)(NUM))
+/* The native TLS-enabled assembler requires the directive #tls_object
+ to be put on objects in TLS sections (as of v7.1). This is not
+ required by the GNU assembler but supported on SPARC. */
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ HOST_WIDE_INT size; \
+ \
+ if (DECL_THREAD_LOCAL (DECL)) \
+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "tls_object"); \
+ else \
+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
+ \
+ size_directive_output = 0; \
+ if (!flag_inhibit_size_directive \
+ && (DECL) && DECL_SIZE (DECL)) \
+ { \
+ size_directive_output = 1; \
+ size = int_size_in_bytes (TREE_TYPE (DECL)); \
+ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
+ } \
+ \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ } \
+ while (0)
+
#undef ENDFILE_SPEC
@@ -108,6 +130,10 @@ Boston, MA 02111-1307, USA. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
((flag_pic || GLOBAL) ? DW_EH_PE_aligned : DW_EH_PE_absptr)
#endif
+
+/* The Solaris linker doesn't understand constructor priorities. */
+#undef SUPPORTS_INIT_PRIORITY
+#define SUPPORTS_INIT_PRIORITY 0
/* ??? This does not work in SunOS 4.x, so it is not enabled in sparc.h.
Instead, it is enabled here, because it does work under Solaris. */
@@ -118,28 +144,20 @@ Boston, MA 02111-1307, USA. */
/* But indicate that it isn't supported by the hardware. */
#define WIDEST_HARDWARE_FP_SIZE 64
-#define MULDI3_LIBCALL "__mul64"
-#define DIVDI3_LIBCALL "__div64"
-#define UDIVDI3_LIBCALL "__udiv64"
-#define MODDI3_LIBCALL "__rem64"
-#define UMODDI3_LIBCALL "__urem64"
-
/* Solaris's _Qp_* library routine implementation clobbers the output
memory before the inputs are fully consumed. */
#undef TARGET_BUGGY_QP_LIB
#define TARGET_BUGGY_QP_LIB 1
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS \
- fixsfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__ftol" : "__ftoll"); \
- fixunssfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__ftoul" : "__ftoull"); \
- fixdfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__dtol" : "__dtoll"); \
- fixunsdfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__dtoul" : "__dtoull")
+#undef SUN_CONVERSION_LIBFUNCS
+#define SUN_CONVERSION_LIBFUNCS 1
+
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS 1
+
+#undef SUN_INTEGER_MULTIPLY_64
+#define SUN_INTEGER_MULTIPLY_64 1
/* Solaris allows 64 bit out and global registers in 32 bit mode.
sparc_override_options will disable V8+ if not generating V9 code. */
diff --git a/contrib/gcc/config/sparc/sol26-sld.h b/contrib/gcc/config/sparc/sol26-sld.h
index 74b5433..2e7fed9 100644
--- a/contrib/gcc/config/sparc/sol26-sld.h
+++ b/contrib/gcc/config/sparc/sol26-sld.h
@@ -1,6 +1,5 @@
-/* Up through Solaris 2.6, the system linker does not work with DWARF
- or DWARF2, since it does not have working support for relocations
- to unaligned data. */
+/* Up through Solaris 2.6, the system linker does not work with DWARF2
+ since it does not have working support for relocations to unaligned
+ data. */
-#undef DWARF_DEBUGGING_INFO
#undef DWARF2_DEBUGGING_INFO
diff --git a/contrib/gcc/config/sparc/sp64-aout.h b/contrib/gcc/config/sparc/sp64-aout.h
index 1af9dea..376cfa8 100644
--- a/contrib/gcc/config/sparc/sp64-aout.h
+++ b/contrib/gcc/config/sparc/sp64-aout.h
@@ -1,21 +1,21 @@
-/* Definitions of target machine for GNU compiler, for SPARC64, a.out.
+/* Definitions of target machine for GCC, for SPARC64, a.out.
Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Doug Evans, dje@cygnus.com.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/sparc/sp64-elf.h b/contrib/gcc/config/sparc/sp64-elf.h
index 18187dc..650c3ff 100644
--- a/contrib/gcc/config/sparc/sp64-elf.h
+++ b/contrib/gcc/config/sparc/sp64-elf.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler, for SPARC64, ELF.
+/* Definitions of target machine for GCC, for SPARC64, ELF.
Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000
Free Software Foundation, Inc.
Contributed by Doug Evans, dje@cygnus.com.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -38,8 +38,14 @@ Boston, MA 02111-1307, USA. */
#undef SPARC_DEFAULT_CMODEL
#define SPARC_DEFAULT_CMODEL CM_EMBMEDANY
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -D__ELF__ -Acpu=sparc -Amachine=sparc"
+/* Target OS builtins for config/sol.h. */
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ } \
+ while (0)
/* __svr4__ is used by the C library (FIXME) */
#undef CPP_SUBTARGET_SPEC
@@ -50,7 +56,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC "\
-%{v:-V} -s %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{v:-V} -s %{fpic|fPIC|fpie|fPIE:-K PIC} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) \
"
diff --git a/contrib/gcc/config/sparc/sp86x-elf.h b/contrib/gcc/config/sparc/sp86x-elf.h
index cb7e8c3..593400d 100644
--- a/contrib/gcc/config/sparc/sp86x-elf.h
+++ b/contrib/gcc/config/sparc/sp86x-elf.h
@@ -1,30 +1,34 @@
-/* Definitions of target machine for GNU compiler, for sparclite 86x w/o FPU.
+/* Definitions of target machine for GCC, for sparclite 86x w/o FPU.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Contributed by Stan Cox (scox@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__sparc__ -D__sparclite86x__ -Acpu=sparc -Amachine=sparc"
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__sparclite86x__"); \
+ } \
+ while (0)
/* Default to dwarf2 in ELF. */
-#define DWARF_DEBUGGING_INFO 1
#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
@@ -41,9 +45,8 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC "%{v:-V} %{mlittle-endian-data:--little-endian-data} %(asm_cpu)"
-/* US Software GOFAST library support. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS INIT_GOFAST_OPTABS
+/* Enable US Software GOFAST library support. */
+#define US_SOFTWARE_GOFAST
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crti.o%s crtbegin.o%s"
diff --git a/contrib/gcc/config/sparc/sparc-modes.def b/contrib/gcc/config/sparc/sparc-modes.def
index 3ebf9c8..ea2a99d 100644
--- a/contrib/gcc/config/sparc/sparc-modes.def
+++ b/contrib/gcc/config/sparc/sparc-modes.def
@@ -1,26 +1,29 @@
-/* Definitions of target machine for GNU compiler, for Sun SPARC.
+/* Definitions of target machine for GCC, for Sun SPARC.
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* 128-bit floating point */
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
/* Add any extra modes needed to represent the condition code.
On the SPARC, we have a "no-overflow" mode which is used when an add or
@@ -34,9 +37,8 @@ Boston, MA 02111-1307, USA. */
CCXmode and CCX_NOOVmode are only used by v9. */
-CC (CCX)
-CC (CC_NOOV)
-CC (CCX_NOOV)
-CC (CCFP)
-CC (CCFPE)
-
+CC_MODE (CCX);
+CC_MODE (CC_NOOV);
+CC_MODE (CCX_NOOV);
+CC_MODE (CCFP);
+CC_MODE (CCFPE);
diff --git a/contrib/gcc/config/sparc/sparc-protos.h b/contrib/gcc/config/sparc/sparc-protos.h
index 0aa6e58..3216f38 100644
--- a/contrib/gcc/config/sparc/sparc-protos.h
+++ b/contrib/gcc/config/sparc/sparc-protos.h
@@ -1,23 +1,23 @@
-/* Prototypes of target machine for GNU compiler, for Sun SPARC.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Prototypes of target machine for SPARC.
+ Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
- 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+ 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,100 +27,101 @@ Boston, MA 02111-1307, USA. */
extern bool sparc_emitting_epilogue;
#ifdef TREE_CODE
-extern struct rtx_def *function_value PARAMS ((tree, enum machine_mode, int));
-extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern struct rtx_def *function_arg PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int, int));
-extern int function_arg_partial_nregs PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern int function_arg_pass_by_reference PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern struct rtx_def *sparc_builtin_saveregs PARAMS ((void));
+extern struct rtx_def *function_value (tree, enum machine_mode, int);
+extern void function_arg_advance (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int, int);
+extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int function_arg_pass_by_reference (const CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern struct rtx_def *sparc_builtin_saveregs (void);
#ifdef RTX_CODE
-extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int));
-extern void sparc_va_start PARAMS ((tree, rtx));
+extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern void sparc_va_start (tree, rtx);
#endif
-extern struct rtx_def *sparc_va_arg PARAMS ((tree, tree));
-extern unsigned long sparc_type_code PARAMS ((tree));
+extern struct rtx_def *sparc_va_arg (tree, tree);
+extern unsigned long sparc_type_code (tree);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
-extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
+extern enum direction function_arg_padding (enum machine_mode, tree);
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */
-extern void load_pic_register PARAMS ((void));
-extern void order_regs_for_local_alloc PARAMS ((void));
-extern int compute_frame_size PARAMS ((int, int));
-extern int check_pic PARAMS ((int));
-extern int short_branch PARAMS ((int, int));
-extern int sparc_flat_epilogue_delay_slots PARAMS ((void));
-extern unsigned long sparc_flat_compute_frame_size PARAMS ((int));
-extern void sparc_profile_hook PARAMS ((int));
-extern void sparc_override_options PARAMS ((void));
-extern int leaf_return_peephole_ok PARAMS ((void));
-extern void sparc_output_scratch_registers PARAMS ((FILE *));
-extern void sparc_flat_save_restore PARAMS ((FILE *, const char *,
- unsigned int, unsigned long,
- unsigned long, const char *,
- const char *, unsigned long));
+extern void load_pic_register (void);
+extern void order_regs_for_local_alloc (void);
+extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT, int);
+extern int check_pic (int);
+extern int short_branch (int, int);
+extern int sparc_flat_epilogue_delay_slots (void);
+extern HOST_WIDE_INT sparc_flat_compute_frame_size (HOST_WIDE_INT);
+extern void sparc_profile_hook (int);
+extern void sparc_override_options (void);
+extern int leaf_return_peephole_ok (void);
+extern void sparc_output_scratch_registers (FILE *);
#ifdef RTX_CODE
-extern enum machine_mode select_cc_mode PARAMS ((enum rtx_code, rtx, rtx));
+extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx);
/* Define the function that build the compare insn for scc and bcc. */
-extern rtx gen_compare_reg PARAMS ((enum rtx_code code, rtx, rtx));
-extern void sparc_emit_float_lib_cmp PARAMS ((rtx, rtx, enum rtx_code));
-extern void sparc_emit_floatunsdi PARAMS ((rtx [2]));
-extern void emit_tfmode_binop PARAMS ((enum rtx_code, rtx *));
-extern void emit_tfmode_unop PARAMS ((enum rtx_code, rtx *));
-extern void emit_tfmode_cvt PARAMS ((enum rtx_code, rtx *));
+extern rtx gen_compare_reg (enum rtx_code code, rtx, rtx);
+extern void sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
+extern void sparc_emit_floatunsdi (rtx [2]);
+extern void emit_tfmode_binop (enum rtx_code, rtx *);
+extern void emit_tfmode_unop (enum rtx_code, rtx *);
+extern void emit_tfmode_cvt (enum rtx_code, rtx *);
/* This function handles all v9 scc insns */
-extern int gen_v9_scc PARAMS ((enum rtx_code, rtx *));
-extern void sparc_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern void sparc64_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
-extern void sparc_defer_case_vector PARAMS ((rtx, rtx, int));
-extern void sparc_emit_set_const32 PARAMS ((rtx, rtx));
-extern void sparc_emit_set_const64 PARAMS ((rtx, rtx));
-extern void sparc_emit_set_symbolic_const64 PARAMS ((rtx, rtx, rtx));
-extern int sparc_splitdi_legitimate PARAMS ((rtx, rtx));
-extern int sparc_absnegfloat_split_legitimate PARAMS ((rtx, rtx));
-extern char *output_cbranch PARAMS ((rtx, rtx, int, int, int, int, rtx));
-extern const char *output_sibcall PARAMS ((rtx, rtx));
-extern char *output_v9branch PARAMS ((rtx, rtx, int, int, int, int, int,
- rtx));
-extern void emit_v9_brxx_insn PARAMS ((enum rtx_code, rtx, rtx));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern int mems_ok_for_ldd_peep PARAMS ((rtx, rtx, rtx));
-extern int arith_double_4096_operand PARAMS ((rtx, enum machine_mode));
-extern int arith_4096_operand PARAMS ((rtx, enum machine_mode));
-extern int zero_operand PARAMS ((rtx, enum machine_mode));
-extern int fp_zero_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
-extern int empty_delay_slot PARAMS ((rtx));
-extern int eligible_for_epilogue_delay PARAMS ((rtx, int));
-extern int eligible_for_sibcall_delay PARAMS ((rtx));
-extern int emit_move_sequence PARAMS ((rtx, enum machine_mode));
-extern int fp_sethi_p PARAMS ((rtx));
-extern int fp_mov_p PARAMS ((rtx));
-extern int fp_high_losum_p PARAMS ((rtx));
-extern int mem_min_alignment PARAMS ((rtx, int));
-extern int pic_address_needs_scratch PARAMS ((rtx));
-extern int reg_unused_after PARAMS ((rtx, rtx));
-extern int register_ok_for_ldd PARAMS ((rtx));
-extern int registers_ok_for_ldd_peep PARAMS ((rtx, rtx));
-extern int sparc_flat_eligible_for_epilogue_delay PARAMS ((rtx, int));
-extern int v9_regcmp_p PARAMS ((enum rtx_code));
-extern char *sparc_v8plus_shift PARAMS ((rtx *, rtx, const char *));
+extern int gen_v9_scc (enum rtx_code, rtx *);
+extern void sparc_initialize_trampoline (rtx, rtx, rtx);
+extern void sparc64_initialize_trampoline (rtx, rtx, rtx);
+extern bool legitimate_constant_p (rtx);
+extern bool constant_address_p (rtx);
+extern bool legitimate_pic_operand_p (rtx);
+extern int legitimate_address_p (enum machine_mode, rtx, int);
+extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern rtx legitimize_tls_address (rtx);
+extern rtx legitimize_address (rtx, rtx, enum machine_mode);
+extern void sparc_defer_case_vector (rtx, rtx, int);
+extern void sparc_emit_set_const32 (rtx, rtx);
+extern void sparc_emit_set_const64 (rtx, rtx);
+extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx);
+extern int sparc_splitdi_legitimate (rtx, rtx);
+extern int sparc_absnegfloat_split_legitimate (rtx, rtx);
+extern const char *output_ubranch (rtx, int, rtx);
+extern char *output_cbranch (rtx, rtx, int, int, int, int, rtx);
+extern const char *output_sibcall (rtx, rtx);
+extern char *output_v9branch (rtx, rtx, int, int, int, int, int, rtx);
+extern void emit_v9_brxx_insn (enum rtx_code, rtx, rtx);
+extern void print_operand (FILE *, rtx, int);
+extern int mems_ok_for_ldd_peep (rtx, rtx, rtx);
+extern int arith_double_4096_operand (rtx, enum machine_mode);
+extern int arith_4096_operand (rtx, enum machine_mode);
+extern int zero_operand (rtx, enum machine_mode);
+extern int fp_zero_operand (rtx, enum machine_mode);
+extern int reg_or_0_operand (rtx, enum machine_mode);
+extern int tls_symbolic_operand (rtx);
+extern int empty_delay_slot (rtx);
+extern int eligible_for_epilogue_delay (rtx, int);
+extern int eligible_for_sibcall_delay (rtx);
+extern int tls_call_delay (rtx);
+extern int emit_move_sequence (rtx, enum machine_mode);
+extern int fp_sethi_p (rtx);
+extern int fp_mov_p (rtx);
+extern int fp_high_losum_p (rtx);
+extern int mem_min_alignment (rtx, int);
+extern int pic_address_needs_scratch (rtx);
+extern int reg_unused_after (rtx, rtx);
+extern int register_ok_for_ldd (rtx);
+extern int registers_ok_for_ldd_peep (rtx, rtx);
+extern int sparc_flat_eligible_for_epilogue_delay (rtx, int);
+extern int v9_regcmp_p (enum rtx_code);
+extern char *sparc_v8plus_shift (rtx *, rtx, const char *);
/* Function used for V8+ code generation. Returns 1 if the high
32 bits of REG are 0 before INSN. */
-extern int sparc_check_64 PARAMS ((rtx, rtx));
-extern rtx gen_df_reg PARAMS ((rtx, int));
-extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
-extern int sparc_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
+extern int sparc_check_64 (rtx, rtx);
+extern rtx gen_df_reg (rtx, int);
+extern int sparc_extra_constraint_check (rtx, int, int);
+extern void sparc_output_dwarf_dtprel (FILE*, int, rtx);
#endif /* RTX_CODE */
#endif /* __SPARC_PROTOS_H__ */
diff --git a/contrib/gcc/config/sparc/sparc.c b/contrib/gcc/config/sparc/sparc.c
index 79022b4..c959370 100644
--- a/contrib/gcc/config/sparc/sparc.c
+++ b/contrib/gcc/config/sparc/sparc.c
@@ -1,29 +1,31 @@
-/* Subroutines for insn-output.c for Sun SPARC.
+/* Subroutines for insn-output.c for SPARC.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
- 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+ 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "regs.h"
@@ -37,7 +39,6 @@ Boston, MA 02111-1307, USA. */
#include "function.h"
#include "expr.h"
#include "optabs.h"
-#include "libfuncs.h"
#include "recog.h"
#include "toplev.h"
#include "ggc.h"
@@ -45,6 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "debug.h"
#include "target.h"
#include "target-def.h"
+#include "cfglayout.h"
/* 1 if the caller has placed an "unimp" insn immediately after the call.
This is used in v8 code when calling a function that returns a structure.
@@ -65,8 +67,8 @@ Boston, MA 02111-1307, USA. */
scheduling (to see what can go in a delay slot).
APPARENT_FSIZE is the size of the stack less the register save area and less
the outgoing argument area. It is used when saving call preserved regs. */
-static int apparent_fsize;
-static int actual_fsize;
+static HOST_WIDE_INT apparent_fsize;
+static HOST_WIDE_INT actual_fsize;
/* Number of live general or floating point registers needed to be
saved (as 4-byte quantities). */
@@ -117,67 +119,81 @@ char sparc_leaf_regs[] =
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1};
+struct machine_function GTY(())
+{
+ /* Some local-dynamic TLS symbol name. */
+ const char *some_ld_name;
+};
+
/* Name of where we pretend to think the frame pointer points.
Normally, this is "%fp", but if we are in a leaf procedure,
this is "%sp+something". We record "something" separately as it may be
too big for reg+constant addressing. */
static const char *frame_base_name;
-static int frame_base_offset;
-
-static void sparc_init_modes PARAMS ((void));
-static int save_regs PARAMS ((FILE *, int, int, const char *,
- int, int, int));
-static int restore_regs PARAMS ((FILE *, int, int, const char *, int, int));
-static void build_big_number PARAMS ((FILE *, int, const char *));
-static int function_arg_slotno PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode, tree, int, int,
- int *, int *));
-
-static int supersparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int hypersparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-
-static void sparc_output_addr_vec PARAMS ((rtx));
-static void sparc_output_addr_diff_vec PARAMS ((rtx));
-static void sparc_output_deferred_case_vectors PARAMS ((void));
-static int check_return_regs PARAMS ((rtx));
-static int epilogue_renumber PARAMS ((rtx *, int));
-static bool sparc_assemble_integer PARAMS ((rtx, unsigned int, int));
-static int set_extends PARAMS ((rtx));
-static void output_restore_regs PARAMS ((FILE *, int));
-static void sparc_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_flat_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_flat_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_nonflat_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT,
- int));
-static void sparc_nonflat_function_prologue PARAMS ((FILE *, HOST_WIDE_INT,
- int));
+static HOST_WIDE_INT frame_base_offset;
+
+static void sparc_init_modes (void);
+static int save_regs (FILE *, int, int, const char *, int, int, HOST_WIDE_INT);
+static int restore_regs (FILE *, int, int, const char *, int, int);
+static void build_big_number (FILE *, HOST_WIDE_INT, const char *);
+static void scan_record_type (tree, int *, int *, int *);
+static int function_arg_slotno (const CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int, int, int *, int *);
+
+static int supersparc_adjust_cost (rtx, rtx, rtx, int);
+static int hypersparc_adjust_cost (rtx, rtx, rtx, int);
+
+static void sparc_output_addr_vec (rtx);
+static void sparc_output_addr_diff_vec (rtx);
+static void sparc_output_deferred_case_vectors (void);
+static int check_return_regs (rtx);
+static int epilogue_renumber (rtx *, int);
+static bool sparc_assemble_integer (rtx, unsigned int, int);
+static int set_extends (rtx);
+static void output_restore_regs (FILE *, int);
+static void sparc_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void sparc_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void sparc_flat_function_epilogue (FILE *, HOST_WIDE_INT);
+static void sparc_flat_function_prologue (FILE *, HOST_WIDE_INT);
+static void sparc_flat_save_restore (FILE *, const char *, int,
+ unsigned long, unsigned long,
+ const char *, const char *,
+ HOST_WIDE_INT);
+static void sparc_nonflat_function_epilogue (FILE *, HOST_WIDE_INT, int);
+static void sparc_nonflat_function_prologue (FILE *, HOST_WIDE_INT, int);
#ifdef OBJECT_FORMAT_ELF
-static void sparc_elf_asm_named_section PARAMS ((const char *, unsigned int));
+static void sparc_elf_asm_named_section (const char *, unsigned int);
#endif
-static void sparc_aout_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT))
+static void sparc_aout_select_section (tree, int, unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static void sparc_aout_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT))
+static void sparc_aout_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static int sparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int sparc_issue_rate PARAMS ((void));
-static void sparc_sched_init PARAMS ((FILE *, int, int));
-static int sparc_use_dfa_pipeline_interface PARAMS ((void));
-static int sparc_use_sched_lookahead PARAMS ((void));
-
-static void emit_soft_tfmode_libcall PARAMS ((const char *, int, rtx *));
-static void emit_soft_tfmode_binop PARAMS ((enum rtx_code, rtx *));
-static void emit_soft_tfmode_unop PARAMS ((enum rtx_code, rtx *));
-static void emit_soft_tfmode_cvt PARAMS ((enum rtx_code, rtx *));
-static void emit_hard_tfmode_operation PARAMS ((enum rtx_code, rtx *));
-
-static void sparc_encode_section_info PARAMS ((tree, int));
-static void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
+static int sparc_adjust_cost (rtx, rtx, rtx, int);
+static int sparc_issue_rate (void);
+static void sparc_sched_init (FILE *, int, int);
+static int sparc_use_dfa_pipeline_interface (void);
+static int sparc_use_sched_lookahead (void);
+
+static void emit_soft_tfmode_libcall (const char *, int, rtx *);
+static void emit_soft_tfmode_binop (enum rtx_code, rtx *);
+static void emit_soft_tfmode_unop (enum rtx_code, rtx *);
+static void emit_soft_tfmode_cvt (enum rtx_code, rtx *);
+static void emit_hard_tfmode_operation (enum rtx_code, rtx *);
+
+static bool sparc_function_ok_for_sibcall (tree, tree);
+static void sparc_init_libfuncs (void);
+static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+static struct machine_function * sparc_init_machine_status (void);
+static bool sparc_cannot_force_const_mem (rtx);
+static rtx sparc_tls_get_addr (void);
+static rtx sparc_tls_got (void);
+static const char *get_some_local_dynamic_name (void);
+static int get_some_local_dynamic_name_1 (rtx *, void *);
+static bool sparc_rtx_costs (rtx, int, int, int *);
/* Option handling. */
@@ -238,21 +254,36 @@ enum processor_type sparc_cpu;
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD sparc_use_sched_lookahead
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO sparc_encode_section_info
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL sparc_function_ok_for_sibcall
+
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS sparc_init_libfuncs
+
+#ifdef HAVE_AS_TLS
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS true
+#endif
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM sparc_cannot_force_const_mem
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS sparc_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Validate and override various options, and do some machine dependent
initialization. */
void
-sparc_override_options ()
+sparc_override_options (void)
{
static struct code_model {
const char *const name;
@@ -444,6 +475,9 @@ sparc_override_options ()
/* Do various machine dependent initializations. */
sparc_init_modes ();
+
+ /* Set up function hooks. */
+ init_machine_status = sparc_init_machine_status;
}
/* Miscellaneous utilities. */
@@ -452,8 +486,7 @@ sparc_override_options ()
or branch on register contents instructions. */
int
-v9_regcmp_p (code)
- enum rtx_code code;
+v9_regcmp_p (enum rtx_code code)
{
return (code == EQ || code == NE || code == GE || code == LT
|| code == LE || code == GT);
@@ -466,9 +499,7 @@ v9_regcmp_p (code)
or const0_rtx. */
int
-reg_or_0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_0_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
@@ -486,9 +517,7 @@ reg_or_0_operand (op, mode)
/* Return nonzero only if OP is const1_rtx. */
int
-const1_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return op == const1_rtx;
}
@@ -496,9 +525,7 @@ const1_operand (op, mode)
/* Nonzero if OP is a floating point value with value 0.0. */
int
-fp_zero_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fp_zero_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE_CLASS (GET_MODE (op)) != MODE_FLOAT)
return 0;
@@ -508,9 +535,7 @@ fp_zero_operand (op, mode)
/* Nonzero if OP is a register operand in floating point register. */
int
-fp_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fp_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -524,8 +549,7 @@ fp_register_operand (op, mode)
sethi instruction. */
int
-fp_sethi_p (op)
- rtx op;
+fp_sethi_p (rtx op)
{
if (GET_CODE (op) == CONST_DOUBLE)
{
@@ -549,8 +573,7 @@ fp_sethi_p (op)
mov instruction. */
int
-fp_mov_p (op)
- rtx op;
+fp_mov_p (rtx op)
{
if (GET_CODE (op) == CONST_DOUBLE)
{
@@ -574,8 +597,7 @@ fp_mov_p (op)
instruction sequence. */
int
-fp_high_losum_p (op)
- rtx op;
+fp_high_losum_p (rtx op)
{
/* The constraints calling this should only be in
SFmode move insns, so any constant which cannot
@@ -601,9 +623,7 @@ fp_high_losum_p (op)
/* Nonzero if OP is an integer register. */
int
-intreg_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+intreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (register_operand (op, SImode)
|| (TARGET_ARCH64 && register_operand (op, DImode)));
@@ -612,9 +632,7 @@ intreg_operand (op, mode)
/* Nonzero if OP is a floating point condition code register. */
int
-fcc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcc_reg_operand (rtx op, enum machine_mode mode)
{
/* This can happen when recog is called from combine. Op may be a MEM.
Fail instead of calling abort in this case. */
@@ -639,9 +657,7 @@ fcc_reg_operand (op, mode)
/* Nonzero if OP is a floating point condition code fcc0 register. */
int
-fcc0_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcc0_reg_operand (rtx op, enum machine_mode mode)
{
/* This can happen when recog is called from combine. Op may be a MEM.
Fail instead of calling abort in this case. */
@@ -660,9 +676,7 @@ fcc0_reg_operand (op, mode)
/* Nonzero if OP is an integer or floating point condition code register. */
int
-icc_or_fcc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+icc_or_fcc_reg_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == REG && REGNO (op) == SPARC_ICC_REG)
{
@@ -679,9 +693,7 @@ icc_or_fcc_reg_operand (op, mode)
/* Nonzero if OP can appear as the dest of a RESTORE insn. */
int
-restore_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+restore_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == REG && GET_MODE (op) == mode
&& (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32)));
@@ -691,9 +703,7 @@ restore_operand (op, mode)
memory address. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
abort ();
@@ -702,20 +712,51 @@ call_operand (op, mode)
}
int
-call_operand_address (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand_address (rtx op, enum machine_mode mode)
{
return (symbolic_operand (op, mode) || memory_address_p (Pmode, op));
}
+/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
+ otherwise return 0. */
+
+int
+tls_symbolic_operand (rtx op)
+{
+ if (GET_CODE (op) != SYMBOL_REF)
+ return 0;
+ return SYMBOL_REF_TLS_MODEL (op);
+}
+
+int
+tgd_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_GLOBAL_DYNAMIC;
+}
+
+int
+tld_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_LOCAL_DYNAMIC;
+}
+
+int
+tie_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_INITIAL_EXEC;
+}
+
+int
+tle_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_LOCAL_EXEC;
+}
+
/* Returns 1 if OP is either a symbol reference or a sum of a symbol
reference and a constant. */
int
-symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+symbolic_operand (register rtx op, enum machine_mode mode)
{
enum machine_mode omode = GET_MODE (op);
@@ -725,12 +766,15 @@ symbolic_operand (op, mode)
switch (GET_CODE (op))
{
case SYMBOL_REF:
+ return !SYMBOL_REF_TLS_MODEL (op);
+
case LABEL_REF:
return 1;
case CONST:
op = XEXP (op, 0);
- return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
@@ -743,25 +787,22 @@ symbolic_operand (op, mode)
operand of mode MODE. */
int
-symbolic_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
if (GET_CODE (op) != MEM)
return 0;
op = XEXP (op, 0);
- return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
- || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
+ return ((GET_CODE (op) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (op))
+ || GET_CODE (op) == CONST || GET_CODE (op) == HIGH
+ || GET_CODE (op) == LABEL_REF);
}
/* Return truth value of statement that OP is a LABEL_REF of mode MODE. */
int
-label_ref_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+label_ref_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != LABEL_REF)
return 0;
@@ -774,9 +815,7 @@ label_ref_operand (op, mode)
in either the medium/low or medium/anywhere code models of sparc64. */
int
-sp64_medium_pic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+sp64_medium_pic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
/* Check for (const (minus (symbol_ref:GOT)
(const (minus (label) (pc))))). */
@@ -801,14 +840,12 @@ sp64_medium_pic_operand (op, mode)
are accessed with EMBMEDANY_BASE_REG. */
int
-data_segment_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+data_segment_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
case SYMBOL_REF :
- return ! SYMBOL_REF_FLAG (op);
+ return ! SYMBOL_REF_FUNCTION_P (op);
case PLUS :
/* Assume canonical format of symbol + constant.
Fall through. */
@@ -823,16 +860,14 @@ data_segment_operand (op, mode)
This is needed in the medium/anywhere code model on v9. */
int
-text_segment_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+text_segment_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
case LABEL_REF :
return 1;
case SYMBOL_REF :
- return SYMBOL_REF_FLAG (op);
+ return SYMBOL_REF_FUNCTION_P (op);
case PLUS :
/* Assume canonical format of symbol + constant.
Fall through. */
@@ -847,9 +882,7 @@ text_segment_operand (op, mode)
not symbolic. */
int
-reg_or_nonsymb_mem_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_or_nonsymb_mem_operand (register rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
@@ -861,9 +894,8 @@ reg_or_nonsymb_mem_operand (op, mode)
}
int
-splittable_symbolic_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+splittable_symbolic_memory_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != MEM)
return 0;
@@ -873,9 +905,8 @@ splittable_symbolic_memory_operand (op, mode)
}
int
-splittable_immediate_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+splittable_immediate_memory_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != MEM)
return 0;
@@ -887,9 +918,7 @@ splittable_immediate_memory_operand (op, mode)
/* Return truth value of whether OP is EQ or NE. */
int
-eq_or_neq (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+eq_or_neq (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
}
@@ -898,9 +927,7 @@ eq_or_neq (op, mode)
or LTU for non-floating-point. We handle those specially. */
int
-normal_comp_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+normal_comp_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -918,9 +945,7 @@ normal_comp_operator (op, mode)
MATCH_OPERATOR to recognize all the branch insns. */
int
-noov_compare_op (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+noov_compare_op (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -938,9 +963,7 @@ noov_compare_op (op, mode)
MATCH_OPERATOR to recognize all the branch insns. */
int
-noov_compare64_op (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+noov_compare64_op (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -960,9 +983,7 @@ noov_compare64_op (op, mode)
conditional move or branch on register contents instructions. */
int
-v9_regcmp_op (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+v9_regcmp_op (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -975,9 +996,7 @@ v9_regcmp_op (op, mode)
/* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */
int
-extend_op (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+extend_op (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;
}
@@ -987,9 +1006,7 @@ extend_op (op, mode)
because these require CC_NOOVmode, which we handle explicitly. */
int
-cc_arithop (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+cc_arithop (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == AND
|| GET_CODE (op) == IOR
@@ -1003,9 +1020,7 @@ cc_arithop (op, mode)
complement its second operand and set the condition codes explicitly. */
int
-cc_arithopn (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+cc_arithopn (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
/* XOR is not here because combine canonicalizes (xor (not ...) ...)
and (xor ... (not ...)) to (not (xor ...)). */
@@ -1018,9 +1033,7 @@ cc_arithopn (op, mode)
most 3 address instructions. */
int
-arith_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
@@ -1032,9 +1045,7 @@ arith_operand (op, mode)
/* Return true if OP is a constant 4096 */
int
-arith_4096_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+arith_4096_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return 0;
@@ -1045,9 +1056,7 @@ arith_4096_operand (op, mode)
/* Return true if OP is suitable as second operand for add/sub */
int
-arith_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_add_operand (rtx op, enum machine_mode mode)
{
return arith_operand (op, mode) || arith_4096_operand (op, mode);
}
@@ -1056,9 +1065,7 @@ arith_add_operand (op, mode)
immediate field of OR and XOR instructions. Used for 64-bit
constant formation patterns. */
int
-const64_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const64_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT
&& SPARC_SIMM13_P (INTVAL (op)))
@@ -1074,9 +1081,7 @@ const64_operand (op, mode)
/* The same, but only for sethi instructions. */
int
-const64_high_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+const64_high_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT
&& (INTVAL (op) & ~(HOST_WIDE_INT)0x3ff) != 0
@@ -1093,9 +1098,7 @@ const64_high_operand (op, mode)
the movcc instructions. */
int
-arith11_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith11_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM11_P (INTVAL (op))));
@@ -1106,9 +1109,7 @@ arith11_operand (op, mode)
the movrcc instructions. */
int
-arith10_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith10_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM10_P (INTVAL (op))));
@@ -1122,9 +1123,7 @@ arith10_operand (op, mode)
for most 3 address instructions. */
int
-arith_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_double_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && SMALL_INT (op))
@@ -1144,9 +1143,7 @@ arith_double_operand (op, mode)
/* Return true if OP is a constant 4096 for DImode on ARCH64 */
int
-arith_double_4096_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+arith_double_4096_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (TARGET_ARCH64 &&
((GET_CODE (op) == CONST_INT && INTVAL (op) == 4096) ||
@@ -1158,9 +1155,7 @@ arith_double_4096_operand (op, mode)
/* Return true if OP is suitable as second operand for add/sub in DImode */
int
-arith_double_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_double_add_operand (rtx op, enum machine_mode mode)
{
return arith_double_operand (op, mode) || arith_double_4096_operand (op, mode);
}
@@ -1171,9 +1166,7 @@ arith_double_add_operand (op, mode)
/* ??? Replace with arith11_operand? */
int
-arith11_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith11_double_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_DOUBLE
@@ -1194,9 +1187,7 @@ arith11_double_operand (op, mode)
/* ??? Replace with arith10_operand? */
int
-arith10_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith10_double_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_DOUBLE
@@ -1216,17 +1207,13 @@ arith10_double_operand (op, mode)
which have a 13 bit immediate field. */
int
-small_int (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
}
int
-small_int_or_double (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_int_or_double (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT && SMALL_INT (op))
|| (GET_CODE (op) == CONST_DOUBLE
@@ -1239,9 +1226,7 @@ small_int_or_double (op, mode)
interprets the extended result as an unsigned number. */
int
-uns_small_int (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+uns_small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
#if HOST_BITS_PER_WIDE_INT > 32
/* All allowed constants will fit a CONST_INT. */
@@ -1258,18 +1243,14 @@ uns_small_int (op, mode)
}
int
-uns_arith_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+uns_arith_operand (rtx op, enum machine_mode mode)
{
return register_operand (op, mode) || uns_small_int (op, mode);
}
/* Return truth value of statement that OP is a call-clobbered register. */
int
-clobbered_register (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+clobbered_register (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]);
}
@@ -1277,16 +1258,14 @@ clobbered_register (op, mode)
/* Return 1 if OP is a valid operand for the source of a move insn. */
int
-input_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+input_operand (rtx op, enum machine_mode mode)
{
/* If both modes are non-void they must be the same. */
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
- /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
- if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == CONSTANT_P_RTX)
+ /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and result in 0/1. */
+ if (GET_CODE (op) == CONSTANT_P_RTX)
return 1;
/* Allow any one instruction integer constant, and all CONST_INT
@@ -1357,13 +1336,37 @@ input_operand (op, mode)
return 0;
}
+/* Return 1 if OP is valid for the lhs of a compare insn. */
+
+int
+compare_operand (rtx op, enum machine_mode mode)
+{
+ if (GET_CODE (op) == ZERO_EXTRACT)
+ return (register_operand (XEXP (op, 0), mode)
+ && small_int_or_double (XEXP (op, 1), mode)
+ && small_int_or_double (XEXP (op, 2), mode)
+ /* This matches cmp_zero_extract. */
+ && ((mode == SImode
+ && ((GET_CODE (XEXP (op, 2)) == CONST_INT
+ && INTVAL (XEXP (op, 2)) > 19)
+ || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE
+ && CONST_DOUBLE_LOW (XEXP (op, 2)) > 19)))
+ /* This matches cmp_zero_extract_sp64. */
+ || (mode == DImode
+ && TARGET_ARCH64
+ && ((GET_CODE (XEXP (op, 2)) == CONST_INT
+ && INTVAL (XEXP (op, 2)) > 51)
+ || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE
+ && CONST_DOUBLE_LOW (XEXP (op, 2)) > 51)))));
+ else
+ return register_operand (op, mode);
+}
+
/* We know it can't be done in one insn when we get here,
- the movsi expander guarentees this. */
+ the movsi expander guarantees this. */
void
-sparc_emit_set_const32 (op0, op1)
- rtx op0;
- rtx op1;
+sparc_emit_set_const32 (rtx op0, rtx op1)
{
enum machine_mode mode = GET_MODE (op0);
rtx temp;
@@ -1417,21 +1420,25 @@ sparc_emit_set_const32 (op0, op1)
}
-/* SPARC-v9 code-model support. */
+/* Load OP1, a symbolic 64-bit constant, into OP0, a DImode register.
+ If TEMP is non-zero, we are forbidden to use any other scratch
+ registers. Otherwise, we are allowed to generate them as needed.
+
+ Note that TEMP may have TImode if the code model is TARGET_CM_MEDANY
+ or TARGET_CM_EMBMEDANY (see the reload_indi and reload_outdi patterns). */
void
-sparc_emit_set_symbolic_const64 (op0, op1, temp1)
- rtx op0;
- rtx op1;
- rtx temp1;
+sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp)
{
- rtx ti_temp1 = 0;
+ rtx temp1, temp2, temp3, temp4, temp5;
+ rtx ti_temp = 0;
- if (temp1 && GET_MODE (temp1) == TImode)
+ if (temp && GET_MODE (temp) == TImode)
{
- ti_temp1 = temp1;
- temp1 = gen_rtx_REG (DImode, REGNO (temp1));
+ ti_temp = temp;
+ temp = gen_rtx_REG (DImode, REGNO (temp));
}
+ /* SPARC-V9 code-model support. */
switch (sparc_cmodel)
{
case CM_MEDLOW:
@@ -1443,8 +1450,13 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
The executable must be in the low 4TB of the virtual address
space.
- sethi %hi(symbol), %temp
- or %temp, %lo(symbol), %reg */
+ sethi %hi(symbol), %temp1
+ or %temp1, %lo(symbol), %reg */
+ if (temp)
+ temp1 = temp; /* op0 is allowed. */
+ else
+ temp1 = gen_reg_rtx (DImode);
+
emit_insn (gen_rtx_SET (VOIDmode, temp1, gen_rtx_HIGH (DImode, op1)));
emit_insn (gen_rtx_SET (VOIDmode, op0, gen_rtx_LO_SUM (DImode, temp1, op1)));
break;
@@ -1462,11 +1474,24 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
or %temp1, %m44(symbol), %temp2
sllx %temp2, 12, %temp3
or %temp3, %l44(symbol), %reg */
- emit_insn (gen_seth44 (op0, op1));
- emit_insn (gen_setm44 (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, temp1,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (12))));
- emit_insn (gen_setl44 (op0, temp1, op1));
+ if (temp)
+ {
+ temp1 = op0;
+ temp2 = op0;
+ temp3 = temp; /* op0 is allowed. */
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ }
+
+ emit_insn (gen_seth44 (temp1, op1));
+ emit_insn (gen_setm44 (temp2, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp3,
+ gen_rtx_ASHIFT (DImode, temp2, GEN_INT (12))));
+ emit_insn (gen_setl44 (op0, temp3, op1));
break;
case CM_MEDANY:
@@ -1481,29 +1506,44 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
sethi %hh(symbol), %temp1
sethi %lm(symbol), %temp2
or %temp1, %hm(symbol), %temp3
- or %temp2, %lo(symbol), %temp4
- sllx %temp3, 32, %temp5
- or %temp4, %temp5, %reg */
-
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (rtx_equal_p (temp1, op0))
+ sllx %temp3, 32, %temp4
+ or %temp4, %temp2, %temp5
+ or %temp5, %lo(symbol), %reg */
+ if (temp)
{
- if (ti_temp1)
- temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1);
- else
- abort();
+ /* It is possible that one of the registers we got for operands[2]
+ might coincide with that of operands[0] (which is why we made
+ it TImode). Pick the other one to use as our scratch. */
+ if (rtx_equal_p (temp, op0))
+ {
+ if (ti_temp)
+ temp = gen_rtx_REG (DImode, REGNO (temp) + 1);
+ else
+ abort();
+ }
+ temp1 = op0;
+ temp2 = temp; /* op0 is _not_ allowed, see above. */
+ temp3 = op0;
+ temp4 = op0;
+ temp5 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ temp4 = gen_reg_rtx (DImode);
+ temp5 = gen_reg_rtx (DImode);
}
- emit_insn (gen_sethh (op0, op1));
- emit_insn (gen_setlm (temp1, op1));
- emit_insn (gen_sethm (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (32))));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_PLUS (DImode, op0, temp1)));
- emit_insn (gen_setlo (op0, op0, op1));
+ emit_insn (gen_sethh (temp1, op1));
+ emit_insn (gen_setlm (temp2, op1));
+ emit_insn (gen_sethm (temp3, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp4,
+ gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
+ emit_insn (gen_rtx_SET (VOIDmode, temp5,
+ gen_rtx_PLUS (DImode, temp4, temp2)));
+ emit_insn (gen_setlo (op0, temp5, op1));
break;
case CM_EMBMEDANY:
@@ -1515,42 +1555,69 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
look different.
Data segment: sethi %hi(symbol), %temp1
- or %temp1, %lo(symbol), %temp2
- add %temp2, EMBMEDANY_BASE_REG, %reg
-
- Text segment: sethi %uhi(symbol), %temp1
- sethi %hi(symbol), %temp2
- or %temp1, %ulo(symbol), %temp3
- or %temp2, %lo(symbol), %temp4
- sllx %temp3, 32, %temp5
- or %temp4, %temp5, %reg */
+ add %temp1, EMBMEDANY_BASE_REG, %temp2
+ or %temp2, %lo(symbol), %reg */
if (data_segment_operand (op1, GET_MODE (op1)))
{
+ if (temp)
+ {
+ temp1 = temp; /* op0 is allowed. */
+ temp2 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ }
+
emit_insn (gen_embmedany_sethi (temp1, op1));
- emit_insn (gen_embmedany_brsum (op0, temp1));
- emit_insn (gen_embmedany_losum (op0, op0, op1));
+ emit_insn (gen_embmedany_brsum (temp2, temp1));
+ emit_insn (gen_embmedany_losum (op0, temp2, op1));
}
+
+ /* Text segment: sethi %uhi(symbol), %temp1
+ sethi %hi(symbol), %temp2
+ or %temp1, %ulo(symbol), %temp3
+ sllx %temp3, 32, %temp4
+ or %temp4, %temp2, %temp5
+ or %temp5, %lo(symbol), %reg */
else
{
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (rtx_equal_p (temp1, op0))
+ if (temp)
{
- if (ti_temp1)
- temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1);
- else
- abort();
+ /* It is possible that one of the registers we got for operands[2]
+ might coincide with that of operands[0] (which is why we made
+ it TImode). Pick the other one to use as our scratch. */
+ if (rtx_equal_p (temp, op0))
+ {
+ if (ti_temp)
+ temp = gen_rtx_REG (DImode, REGNO (temp) + 1);
+ else
+ abort();
+ }
+ temp1 = op0;
+ temp2 = temp; /* op0 is _not_ allowed, see above. */
+ temp3 = op0;
+ temp4 = op0;
+ temp5 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ temp4 = gen_reg_rtx (DImode);
+ temp5 = gen_reg_rtx (DImode);
}
- emit_insn (gen_embmedany_textuhi (op0, op1));
- emit_insn (gen_embmedany_texthi (temp1, op1));
- emit_insn (gen_embmedany_textulo (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (32))));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_PLUS (DImode, op0, temp1)));
- emit_insn (gen_embmedany_textlo (op0, op0, op1));
+ emit_insn (gen_embmedany_textuhi (temp1, op1));
+ emit_insn (gen_embmedany_texthi (temp2, op1));
+ emit_insn (gen_embmedany_textulo (temp3, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp4,
+ gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
+ emit_insn (gen_rtx_SET (VOIDmode, temp5,
+ gen_rtx_PLUS (DImode, temp4, temp2)));
+ emit_insn (gen_embmedany_textlo (op0, temp5, op1));
}
break;
@@ -1562,10 +1629,10 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
/* These avoid problems when cross compiling. If we do not
go through all this hair then the optimizer will see
invalid REG_EQUAL notes or in some cases none at all. */
-static void sparc_emit_set_safe_HIGH64 PARAMS ((rtx, HOST_WIDE_INT));
-static rtx gen_safe_SET64 PARAMS ((rtx, HOST_WIDE_INT));
-static rtx gen_safe_OR64 PARAMS ((rtx, HOST_WIDE_INT));
-static rtx gen_safe_XOR64 PARAMS ((rtx, HOST_WIDE_INT));
+static void sparc_emit_set_safe_HIGH64 (rtx, HOST_WIDE_INT);
+static rtx gen_safe_SET64 (rtx, HOST_WIDE_INT);
+static rtx gen_safe_OR64 (rtx, HOST_WIDE_INT);
+static rtx gen_safe_XOR64 (rtx, HOST_WIDE_INT);
#if HOST_BITS_PER_WIDE_INT == 64
#define GEN_HIGHINT64(__x) GEN_INT ((__x) & ~(HOST_WIDE_INT)0x3ff)
@@ -1584,33 +1651,25 @@ static rtx gen_safe_XOR64 PARAMS ((rtx, HOST_WIDE_INT));
during CSE. We mask out the non-HIGH bits, and matches
a plain movdi, to alleviate this problem. */
static void
-sparc_emit_set_safe_HIGH64 (dest, val)
- rtx dest;
- HOST_WIDE_INT val;
+sparc_emit_set_safe_HIGH64 (rtx dest, HOST_WIDE_INT val)
{
emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_HIGHINT64 (val)));
}
static rtx
-gen_safe_SET64 (dest, val)
- rtx dest;
- HOST_WIDE_INT val;
+gen_safe_SET64 (rtx dest, HOST_WIDE_INT val)
{
return gen_rtx_SET (VOIDmode, dest, GEN_INT64 (val));
}
static rtx
-gen_safe_OR64 (src, val)
- rtx src;
- HOST_WIDE_INT val;
+gen_safe_OR64 (rtx src, HOST_WIDE_INT val)
{
return gen_rtx_IOR (DImode, src, GEN_INT64 (val));
}
static rtx
-gen_safe_XOR64 (src, val)
- rtx src;
- HOST_WIDE_INT val;
+gen_safe_XOR64 (rtx src, HOST_WIDE_INT val)
{
return gen_rtx_XOR (DImode, src, GEN_INT64 (val));
}
@@ -1623,15 +1682,12 @@ gen_safe_XOR64 (src, val)
Without doing this, the optimizer cannot see such
opportunities. */
-static void sparc_emit_set_const64_quick1
- PARAMS ((rtx, rtx, unsigned HOST_WIDE_INT, int));
+static void sparc_emit_set_const64_quick1 (rtx, rtx,
+ unsigned HOST_WIDE_INT, int);
static void
-sparc_emit_set_const64_quick1 (op0, temp, low_bits, is_neg)
- rtx op0;
- rtx temp;
- unsigned HOST_WIDE_INT low_bits;
- int is_neg;
+sparc_emit_set_const64_quick1 (rtx op0, rtx temp,
+ unsigned HOST_WIDE_INT low_bits, int is_neg)
{
unsigned HOST_WIDE_INT high_bits;
@@ -1666,17 +1722,14 @@ sparc_emit_set_const64_quick1 (op0, temp, low_bits, is_neg)
}
}
-static void sparc_emit_set_const64_quick2
- PARAMS ((rtx, rtx, unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, int));
+static void sparc_emit_set_const64_quick2 (rtx, rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, int);
static void
-sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count)
- rtx op0;
- rtx temp;
- unsigned HOST_WIDE_INT high_bits;
- unsigned HOST_WIDE_INT low_immediate;
- int shift_count;
+sparc_emit_set_const64_quick2 (rtx op0, rtx temp,
+ unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_immediate,
+ int shift_count)
{
rtx temp2 = op0;
@@ -1707,17 +1760,15 @@ sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count)
gen_safe_OR64 (op0, low_immediate)));
}
-static void sparc_emit_set_const64_longway
- PARAMS ((rtx, rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT));
+static void sparc_emit_set_const64_longway (rtx, rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT);
/* Full 64-bit constant decomposition. Even though this is the
'worst' case, we still optimize a few things away. */
static void
-sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits)
- rtx op0;
- rtx temp;
- unsigned HOST_WIDE_INT high_bits;
- unsigned HOST_WIDE_INT low_bits;
+sparc_emit_set_const64_longway (rtx op0, rtx temp,
+ unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits)
{
rtx sub_temp;
@@ -1815,15 +1866,14 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits)
}
/* Analyze a 64-bit constant for certain properties. */
-static void analyze_64bit_constant
- PARAMS ((unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT,
- int *, int *, int *));
+static void analyze_64bit_constant (unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ int *, int *, int *);
static void
-analyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp)
- unsigned HOST_WIDE_INT high_bits, low_bits;
- int *hbsp, *lbsp, *abbasp;
+analyze_64bit_constant (unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits,
+ int *hbsp, int *lbsp, int *abbasp)
{
int lowest_bit_set, highest_bit_set, all_bits_between_are_set;
int i;
@@ -1884,12 +1934,11 @@ analyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp)
*abbasp = all_bits_between_are_set;
}
-static int const64_is_2insns
- PARAMS ((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT));
+static int const64_is_2insns (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
static int
-const64_is_2insns (high_bits, low_bits)
- unsigned HOST_WIDE_INT high_bits, low_bits;
+const64_is_2insns (unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits)
{
int highest_bit_set, lowest_bit_set, all_bits_between_are_set;
@@ -1912,14 +1961,14 @@ const64_is_2insns (high_bits, low_bits)
return 0;
}
-static unsigned HOST_WIDE_INT create_simple_focus_bits
- PARAMS ((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
- int, int));
+static unsigned HOST_WIDE_INT create_simple_focus_bits (unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ int, int);
static unsigned HOST_WIDE_INT
-create_simple_focus_bits (high_bits, low_bits, lowest_bit_set, shift)
- unsigned HOST_WIDE_INT high_bits, low_bits;
- int lowest_bit_set, shift;
+create_simple_focus_bits (unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits,
+ int lowest_bit_set, int shift)
{
HOST_WIDE_INT hi, lo;
@@ -1943,14 +1992,12 @@ create_simple_focus_bits (high_bits, low_bits, lowest_bit_set, shift)
insn sequence possible. Detection of all the 1-insn cases
has been done already. */
void
-sparc_emit_set_const64 (op0, op1)
- rtx op0;
- rtx op1;
+sparc_emit_set_const64 (rtx op0, rtx op1)
{
unsigned HOST_WIDE_INT high_bits, low_bits;
int lowest_bit_set, highest_bit_set;
int all_bits_between_are_set;
- rtx temp;
+ rtx temp = 0;
/* Sanity check that we know what we are working with. */
if (! TARGET_ARCH64)
@@ -1966,8 +2013,6 @@ sparc_emit_set_const64 (op0, op1)
if (reload_in_progress || reload_completed)
temp = op0;
- else
- temp = gen_reg_rtx (DImode);
if (GET_CODE (op1) != CONST_DOUBLE
&& GET_CODE (op1) != CONST_INT)
@@ -1976,6 +2021,9 @@ sparc_emit_set_const64 (op0, op1)
return;
}
+ if (! temp)
+ temp = gen_reg_rtx (DImode);
+
if (GET_CODE (op1) == CONST_DOUBLE)
{
#if HOST_BITS_PER_WIDE_INT == 64
@@ -2223,10 +2271,7 @@ sparc_emit_set_const64 (op0, op1)
processing is needed. */
enum machine_mode
-select_cc_mode (op, x, y)
- enum rtx_code op;
- rtx x;
- rtx y ATTRIBUTE_UNUSED;
+select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
{
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
{
@@ -2275,9 +2320,7 @@ select_cc_mode (op, x, y)
return the rtx for the cc reg in the proper mode. */
rtx
-gen_compare_reg (code, x, y)
- enum rtx_code code;
- rtx x, y;
+gen_compare_reg (enum rtx_code code, rtx x, rtx y)
{
enum machine_mode mode = SELECT_CC_MODE (code, x, y);
rtx cc_reg;
@@ -2358,9 +2401,7 @@ gen_compare_reg (code, x, y)
sparc_compare_op1. */
int
-gen_v9_scc (compare_code, operands)
- enum rtx_code compare_code;
- register rtx *operands;
+gen_v9_scc (enum rtx_code compare_code, register rtx *operands)
{
rtx temp, op0, op1;
@@ -2448,9 +2489,7 @@ gen_v9_scc (compare_code, operands)
This function exists to take advantage of the v9 brxx insns. */
void
-emit_v9_brxx_insn (code, op0, label)
- enum rtx_code code;
- rtx op0, label;
+emit_v9_brxx_insn (enum rtx_code code, rtx op0, rtx label)
{
emit_jump_insn (gen_rtx_SET (VOIDmode,
pc_rtx,
@@ -2466,9 +2505,7 @@ emit_v9_brxx_insn (code, op0, label)
low 64bit of the register and 0 otherwise.
*/
rtx
-gen_df_reg (reg, low)
- rtx reg;
- int low;
+gen_df_reg (rtx reg, int low)
{
int regno = REGNO (reg);
@@ -2482,10 +2519,7 @@ gen_df_reg (reg, low)
assumed that no more than 3 operands are required. */
static void
-emit_soft_tfmode_libcall (func_name, nargs, operands)
- const char *func_name;
- int nargs;
- rtx *operands;
+emit_soft_tfmode_libcall (const char *func_name, int nargs, rtx *operands)
{
rtx ret_slot = NULL, arg[3], func_sym;
int i;
@@ -2570,9 +2604,7 @@ emit_soft_tfmode_libcall (func_name, nargs, operands)
/* Expand soft-float TFmode calls to sparc abi routines. */
static void
-emit_soft_tfmode_binop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_soft_tfmode_binop (enum rtx_code code, rtx *operands)
{
const char *func;
@@ -2598,9 +2630,7 @@ emit_soft_tfmode_binop (code, operands)
}
static void
-emit_soft_tfmode_unop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_soft_tfmode_unop (enum rtx_code code, rtx *operands)
{
const char *func;
@@ -2617,9 +2647,7 @@ emit_soft_tfmode_unop (code, operands)
}
static void
-emit_soft_tfmode_cvt (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_soft_tfmode_cvt (enum rtx_code code, rtx *operands)
{
const char *func;
@@ -2720,9 +2748,7 @@ emit_soft_tfmode_cvt (code, operands)
registers. */
static void
-emit_hard_tfmode_operation (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_hard_tfmode_operation (enum rtx_code code, rtx *operands)
{
rtx op, dest;
@@ -2751,9 +2777,7 @@ emit_hard_tfmode_operation (code, operands)
}
void
-emit_tfmode_binop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_tfmode_binop (enum rtx_code code, rtx *operands)
{
if (TARGET_HARD_QUAD)
emit_hard_tfmode_operation (code, operands);
@@ -2762,9 +2786,7 @@ emit_tfmode_binop (code, operands)
}
void
-emit_tfmode_unop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_tfmode_unop (enum rtx_code code, rtx *operands)
{
if (TARGET_HARD_QUAD)
emit_hard_tfmode_operation (code, operands);
@@ -2773,9 +2795,7 @@ emit_tfmode_unop (code, operands)
}
void
-emit_tfmode_cvt (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_tfmode_cvt (enum rtx_code code, rtx *operands)
{
if (TARGET_HARD_QUAD)
emit_hard_tfmode_operation (code, operands);
@@ -2786,7 +2806,7 @@ emit_tfmode_cvt (code, operands)
/* Return nonzero if a return peephole merging return with
setting of output register is ok. */
int
-leaf_return_peephole_ok ()
+leaf_return_peephole_ok (void)
{
return (actual_fsize == 0);
}
@@ -2795,8 +2815,7 @@ leaf_return_peephole_ok ()
nop into its delay slot. */
int
-empty_delay_slot (insn)
- rtx insn;
+empty_delay_slot (rtx insn)
{
rtx seq;
@@ -2815,9 +2834,7 @@ empty_delay_slot (insn)
delay slot. SLOT is the slot we are trying to fill. */
int
-eligible_for_epilogue_delay (trial, slot)
- rtx trial;
- int slot;
+eligible_for_epilogue_delay (rtx trial, int slot)
{
rtx pat, src;
@@ -2939,12 +2956,37 @@ eligible_for_epilogue_delay (trial, slot)
return 0;
}
+/* Return nonzero if TRIAL can go into the call delay slot. */
+int
+tls_call_delay (rtx trial)
+{
+ rtx pat, unspec;
+
+ /* Binutils allows
+ call __tls_get_addr, %tgd_call (foo)
+ add %l7, %o0, %o0, %tgd_add (foo)
+ while Sun as/ld does not. */
+ if (TARGET_GNU_TLS || !TARGET_TLS)
+ return 1;
+
+ pat = PATTERN (trial);
+ if (GET_CODE (pat) != SET || GET_CODE (SET_DEST (pat)) != PLUS)
+ return 1;
+
+ unspec = XEXP (SET_DEST (pat), 1);
+ if (GET_CODE (unspec) != UNSPEC
+ || (XINT (unspec, 1) != UNSPEC_TLSGD
+ && XINT (unspec, 1) != UNSPEC_TLSLDM))
+ return 1;
+
+ return 0;
+}
+
/* Return nonzero if TRIAL can go into the sibling call
delay slot. */
int
-eligible_for_sibcall_delay (trial)
- rtx trial;
+eligible_for_sibcall_delay (rtx trial)
{
rtx pat, src;
@@ -3034,8 +3076,7 @@ eligible_for_sibcall_delay (trial)
}
static int
-check_return_regs (x)
- rtx x;
+check_return_regs (rtx x)
{
switch (GET_CODE (x))
{
@@ -3069,8 +3110,7 @@ check_return_regs (x)
}
int
-short_branch (uid1, uid2)
- int uid1, uid2;
+short_branch (int uid1, int uid2)
{
int delta = INSN_ADDRESSES (uid1) - INSN_ADDRESSES (uid2);
@@ -3085,9 +3125,7 @@ short_branch (uid1, uid2)
We assume REG is a reload reg, and therefore does
not live past labels or calls or jumps. */
int
-reg_unused_after (reg, insn)
- rtx reg;
- rtx insn;
+reg_unused_after (rtx reg, rtx insn)
{
enum rtx_code code, prev_code = UNKNOWN;
@@ -3116,18 +3154,56 @@ reg_unused_after (reg, insn)
return 1;
}
+/* Determine if it's legal to put X into the constant pool. This
+ is not possible if X contains the address of a symbol that is
+ not constant (TLS) or not known at final link time (PIC). */
+
+static bool
+sparc_cannot_force_const_mem (rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ /* Accept all non-symbolic constants. */
+ return false;
+
+ case LABEL_REF:
+ /* Labels are OK iff we are non-PIC. */
+ return flag_pic != 0;
+
+ case SYMBOL_REF:
+ /* 'Naked' TLS symbol references are never OK,
+ non-TLS symbols are OK iff we are non-PIC. */
+ if (SYMBOL_REF_TLS_MODEL (x))
+ return true;
+ else
+ return flag_pic != 0;
+
+ case CONST:
+ return sparc_cannot_force_const_mem (XEXP (x, 0));
+ case PLUS:
+ case MINUS:
+ return sparc_cannot_force_const_mem (XEXP (x, 0))
+ || sparc_cannot_force_const_mem (XEXP (x, 1));
+ case UNSPEC:
+ return true;
+ default:
+ abort ();
+ }
+}
+
/* The table we use to reference PIC data. */
static GTY(()) rtx global_offset_table;
/* The function we use to get at it. */
static GTY(()) rtx get_pc_symbol;
-static char get_pc_symbol_name[256];
+static GTY(()) char get_pc_symbol_name[256];
/* Ensure that we are not using patterns that are not OK with PIC. */
int
-check_pic (i)
- int i;
+check_pic (int i)
{
switch (flag_pic)
{
@@ -3150,8 +3226,7 @@ check_pic (i)
reloaded while generating PIC code. */
int
-pic_address_needs_scratch (x)
- rtx x;
+pic_address_needs_scratch (rtx x)
{
/* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
@@ -3163,16 +3238,399 @@ pic_address_needs_scratch (x)
return 0;
}
+/* Determine if a given RTX is a valid constant. We already know this
+ satisfies CONSTANT_P. */
+
+bool
+legitimate_constant_p (rtx x)
+{
+ rtx inner;
+
+ switch (GET_CODE (x))
+ {
+ case SYMBOL_REF:
+ /* TLS symbols are not constant. */
+ if (SYMBOL_REF_TLS_MODEL (x))
+ return false;
+ break;
+
+ case CONST:
+ inner = XEXP (x, 0);
+
+ /* Offsets of TLS symbols are never valid.
+ Discourage CSE from creating them. */
+ if (GET_CODE (inner) == PLUS
+ && tls_symbolic_operand (XEXP (inner, 0)))
+ return false;
+ break;
+
+ case CONST_DOUBLE:
+ if (GET_MODE (x) == VOIDmode)
+ return true;
+
+ /* Floating point constants are generally not ok.
+ The only exception is 0.0 in VIS. */
+ if (TARGET_VIS
+ && (GET_MODE (x) == SFmode
+ || GET_MODE (x) == DFmode
+ || GET_MODE (x) == TFmode)
+ && fp_zero_operand (x, GET_MODE (x)))
+ return true;
+
+ return false;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/* Determine if a given RTX is a valid constant address. */
+
+bool
+constant_address_p (rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case LABEL_REF:
+ case CONST_INT:
+ case HIGH:
+ return true;
+
+ case CONST:
+ if (flag_pic && pic_address_needs_scratch (x))
+ return false;
+ return legitimate_constant_p (x);
+
+ case SYMBOL_REF:
+ return !flag_pic && legitimate_constant_p (x);
+
+ default:
+ return false;
+ }
+}
+
+/* Nonzero if the constant value X is a legitimate general operand
+ when generating PIC code. It is given that flag_pic is on and
+ that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
+
+bool
+legitimate_pic_operand_p (rtx x)
+{
+ if (pic_address_needs_scratch (x))
+ return false;
+ if (tls_symbolic_operand (x)
+ || (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && tls_symbolic_operand (XEXP (XEXP (x, 0), 0))))
+ return false;
+ return true;
+}
+
+/* Return nonzero if ADDR is a valid memory address.
+ STRICT specifies whether strict register checking applies. */
+
+int
+legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
+{
+ rtx rs1 = NULL, rs2 = NULL, imm1 = NULL, imm2;
+
+ if (REG_P (addr) || GET_CODE (addr) == SUBREG)
+ rs1 = addr;
+ else if (GET_CODE (addr) == PLUS)
+ {
+ rs1 = XEXP (addr, 0);
+ rs2 = XEXP (addr, 1);
+
+ /* Canonicalize. REG comes first, if there are no regs,
+ LO_SUM comes first. */
+ if (!REG_P (rs1)
+ && GET_CODE (rs1) != SUBREG
+ && (REG_P (rs2)
+ || GET_CODE (rs2) == SUBREG
+ || (GET_CODE (rs2) == LO_SUM && GET_CODE (rs1) != LO_SUM)))
+ {
+ rs1 = XEXP (addr, 1);
+ rs2 = XEXP (addr, 0);
+ }
+
+ if ((flag_pic == 1
+ && rs1 == pic_offset_table_rtx
+ && !REG_P (rs2)
+ && GET_CODE (rs2) != SUBREG
+ && GET_CODE (rs2) != LO_SUM
+ && GET_CODE (rs2) != MEM
+ && !tls_symbolic_operand (rs2)
+ && (! symbolic_operand (rs2, VOIDmode) || mode == Pmode)
+ && (GET_CODE (rs2) != CONST_INT || SMALL_INT (rs2)))
+ || ((REG_P (rs1)
+ || GET_CODE (rs1) == SUBREG)
+ && RTX_OK_FOR_OFFSET_P (rs2)))
+ {
+ imm1 = rs2;
+ rs2 = NULL;
+ }
+ else if ((REG_P (rs1) || GET_CODE (rs1) == SUBREG)
+ && (REG_P (rs2) || GET_CODE (rs2) == SUBREG))
+ {
+ /* We prohibit REG + REG for TFmode when there are no instructions
+ which accept REG+REG instructions. We do this because REG+REG
+ is not an offsetable address. If we get the situation in reload
+ where source and destination of a movtf pattern are both MEMs with
+ REG+REG address, then only one of them gets converted to an
+ offsetable address. */
+ if (mode == TFmode
+ && !(TARGET_FPU && TARGET_ARCH64 && TARGET_V9
+ && TARGET_HARD_QUAD))
+ return 0;
+
+ /* We prohibit REG + REG on ARCH32 if not optimizing for
+ DFmode/DImode because then mem_min_alignment is likely to be zero
+ after reload and the forced split would lack a matching splitter
+ pattern. */
+ if (TARGET_ARCH32 && !optimize
+ && (mode == DFmode || mode == DImode))
+ return 0;
+ }
+ else if (USE_AS_OFFSETABLE_LO10
+ && GET_CODE (rs1) == LO_SUM
+ && TARGET_ARCH64
+ && ! TARGET_CM_MEDMID
+ && RTX_OK_FOR_OLO10_P (rs2))
+ {
+ imm2 = rs2;
+ rs2 = NULL;
+ imm1 = XEXP (rs1, 1);
+ rs1 = XEXP (rs1, 0);
+ if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
+ return 0;
+ }
+ }
+ else if (GET_CODE (addr) == LO_SUM)
+ {
+ rs1 = XEXP (addr, 0);
+ imm1 = XEXP (addr, 1);
+
+ if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
+ return 0;
+
+ /* We can't allow TFmode, because an offset greater than or equal to the
+ alignment (8) may cause the LO_SUM to overflow if !v9. */
+ if (mode == TFmode && !TARGET_V9)
+ return 0;
+ }
+ else if (GET_CODE (addr) == CONST_INT && SMALL_INT (addr))
+ return 1;
+ else
+ return 0;
+
+ if (GET_CODE (rs1) == SUBREG)
+ rs1 = SUBREG_REG (rs1);
+ if (!REG_P (rs1))
+ return 0;
+
+ if (rs2)
+ {
+ if (GET_CODE (rs2) == SUBREG)
+ rs2 = SUBREG_REG (rs2);
+ if (!REG_P (rs2))
+ return 0;
+ }
+
+ if (strict)
+ {
+ if (!REGNO_OK_FOR_BASE_P (REGNO (rs1))
+ || (rs2 && !REGNO_OK_FOR_BASE_P (REGNO (rs2))))
+ return 0;
+ }
+ else
+ {
+ if ((REGNO (rs1) >= 32
+ && REGNO (rs1) != FRAME_POINTER_REGNUM
+ && REGNO (rs1) < FIRST_PSEUDO_REGISTER)
+ || (rs2
+ && (REGNO (rs2) >= 32
+ && REGNO (rs2) != FRAME_POINTER_REGNUM
+ && REGNO (rs2) < FIRST_PSEUDO_REGISTER)))
+ return 0;
+ }
+ return 1;
+}
+
+/* Construct the SYMBOL_REF for the tls_get_offset function. */
+
+static GTY(()) rtx sparc_tls_symbol;
+static rtx
+sparc_tls_get_addr (void)
+{
+ if (!sparc_tls_symbol)
+ sparc_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
+
+ return sparc_tls_symbol;
+}
+
+static rtx
+sparc_tls_got (void)
+{
+ rtx temp;
+ if (flag_pic)
+ {
+ current_function_uses_pic_offset_table = 1;
+ return pic_offset_table_rtx;
+ }
+
+ if (!global_offset_table)
+ global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ temp = gen_reg_rtx (Pmode);
+ emit_move_insn (temp, global_offset_table);
+ return temp;
+}
+
+
+/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
+ this (thread-local) address. */
+
+rtx
+legitimize_tls_address (rtx addr)
+{
+ rtx temp1, temp2, temp3, ret, o0, got, insn;
+
+ if (no_new_pseudos)
+ abort ();
+
+ if (GET_CODE (addr) == SYMBOL_REF)
+ switch (SYMBOL_REF_TLS_MODEL (addr))
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ start_sequence ();
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ ret = gen_reg_rtx (Pmode);
+ o0 = gen_rtx_REG (Pmode, 8);
+ got = sparc_tls_got ();
+ emit_insn (gen_tgd_hi22 (temp1, addr));
+ emit_insn (gen_tgd_lo10 (temp2, temp1, addr));
+ if (TARGET_ARCH32)
+ {
+ emit_insn (gen_tgd_add32 (o0, got, temp2, addr));
+ insn = emit_call_insn (gen_tgd_call32 (o0, sparc_tls_get_addr (),
+ addr, const1_rtx));
+ }
+ else
+ {
+ emit_insn (gen_tgd_add64 (o0, got, temp2, addr));
+ insn = emit_call_insn (gen_tgd_call64 (o0, sparc_tls_get_addr (),
+ addr, const1_rtx));
+ }
+ CALL_INSN_FUNCTION_USAGE (insn)
+ = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, o0),
+ CALL_INSN_FUNCTION_USAGE (insn));
+ insn = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insn, ret, o0, addr);
+ break;
+
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ start_sequence ();
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ temp3 = gen_reg_rtx (Pmode);
+ ret = gen_reg_rtx (Pmode);
+ o0 = gen_rtx_REG (Pmode, 8);
+ got = sparc_tls_got ();
+ emit_insn (gen_tldm_hi22 (temp1));
+ emit_insn (gen_tldm_lo10 (temp2, temp1));
+ if (TARGET_ARCH32)
+ {
+ emit_insn (gen_tldm_add32 (o0, got, temp2));
+ insn = emit_call_insn (gen_tldm_call32 (o0, sparc_tls_get_addr (),
+ const1_rtx));
+ }
+ else
+ {
+ emit_insn (gen_tldm_add64 (o0, got, temp2));
+ insn = emit_call_insn (gen_tldm_call64 (o0, sparc_tls_get_addr (),
+ const1_rtx));
+ }
+ CALL_INSN_FUNCTION_USAGE (insn)
+ = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, o0),
+ CALL_INSN_FUNCTION_USAGE (insn));
+ insn = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insn, temp3, o0,
+ gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_TLSLD_BASE));
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ emit_insn (gen_tldo_hix22 (temp1, addr));
+ emit_insn (gen_tldo_lox10 (temp2, temp1, addr));
+ if (TARGET_ARCH32)
+ emit_insn (gen_tldo_add32 (ret, temp3, temp2, addr));
+ else
+ emit_insn (gen_tldo_add64 (ret, temp3, temp2, addr));
+ break;
+
+ case TLS_MODEL_INITIAL_EXEC:
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ temp3 = gen_reg_rtx (Pmode);
+ got = sparc_tls_got ();
+ emit_insn (gen_tie_hi22 (temp1, addr));
+ emit_insn (gen_tie_lo10 (temp2, temp1, addr));
+ if (TARGET_ARCH32)
+ emit_insn (gen_tie_ld32 (temp3, got, temp2, addr));
+ else
+ emit_insn (gen_tie_ld64 (temp3, got, temp2, addr));
+ if (TARGET_SUN_TLS)
+ {
+ ret = gen_reg_rtx (Pmode);
+ if (TARGET_ARCH32)
+ emit_insn (gen_tie_add32 (ret, gen_rtx_REG (Pmode, 7),
+ temp3, addr));
+ else
+ emit_insn (gen_tie_add64 (ret, gen_rtx_REG (Pmode, 7),
+ temp3, addr));
+ }
+ else
+ ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, 7), temp3);
+ break;
+
+ case TLS_MODEL_LOCAL_EXEC:
+ temp1 = gen_reg_rtx (Pmode);
+ temp2 = gen_reg_rtx (Pmode);
+ if (TARGET_ARCH32)
+ {
+ emit_insn (gen_tle_hix22_sp32 (temp1, addr));
+ emit_insn (gen_tle_lox10_sp32 (temp2, temp1, addr));
+ }
+ else
+ {
+ emit_insn (gen_tle_hix22_sp64 (temp1, addr));
+ emit_insn (gen_tle_lox10_sp64 (temp2, temp1, addr));
+ }
+ ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, 7), temp2);
+ break;
+
+ default:
+ abort ();
+ }
+
+ else
+ abort (); /* for now ... */
+
+ return ret;
+}
+
+
/* Legitimize PIC addresses. If the address is already position-independent,
we return ORIG. Newly generated position-independent addresses go into a
reg. This is REG if nonzero, otherwise we allocate register(s) as
necessary. */
rtx
-legitimize_pic_address (orig, mode, reg)
- rtx orig;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx reg;
+legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx reg)
{
if (GET_CODE (orig) == SYMBOL_REF)
{
@@ -3272,10 +3730,56 @@ legitimize_pic_address (orig, mode, reg)
return orig;
}
+/* Try machine-dependent ways of modifying an illegitimate address X
+ to be legitimate. If we find one, return the new, valid address.
+
+ OLDX is the address as it was before break_out_memory_refs was called.
+ In some cases it is useful to look at this to decide what needs to be done.
+
+ MODE is the mode of the operand pointed to by X. */
+
+rtx
+legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
+{
+ rtx orig_x = x;
+
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT)
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 1),
+ force_operand (XEXP (x, 0), NULL_RTX));
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == MULT)
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ force_operand (XEXP (x, 1), NULL_RTX));
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS)
+ x = gen_rtx_PLUS (Pmode, force_operand (XEXP (x, 0), NULL_RTX),
+ XEXP (x, 1));
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == PLUS)
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ force_operand (XEXP (x, 1), NULL_RTX));
+
+ if (x != orig_x && legitimate_address_p (mode, x, FALSE))
+ return x;
+
+ if (tls_symbolic_operand (x))
+ x = legitimize_tls_address (x);
+ else if (flag_pic)
+ x = legitimize_pic_address (x, mode, 0);
+ else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1)))
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ copy_to_mode_reg (Pmode, XEXP (x, 1)));
+ else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 0)))
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 1),
+ copy_to_mode_reg (Pmode, XEXP (x, 0)));
+ else if (GET_CODE (x) == SYMBOL_REF
+ || GET_CODE (x) == CONST
+ || GET_CODE (x) == LABEL_REF)
+ x = copy_to_suggested_reg (x, NULL_RTX, Pmode);
+ return x;
+}
+
/* Emit special PIC prologues. */
void
-load_pic_register ()
+load_pic_register (void)
{
/* Labels to get the PC in the prologue of this function. */
int orig_flag_pic = flag_pic;
@@ -3294,7 +3798,7 @@ load_pic_register ()
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
if (align > 0)
ASM_OUTPUT_ALIGN (asm_out_file, align);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LGETPC", 0);
+ (*targetm.asm_out.internal_label) (asm_out_file, "LGETPC", 0);
fputs ("\tretl\n\tadd\t%o7, %l7, %l7\n", asm_out_file);
}
@@ -3320,9 +3824,7 @@ load_pic_register ()
least a DESIRED byte boundary. */
int
-mem_min_alignment (mem, desired)
- rtx mem;
- int desired;
+mem_min_alignment (rtx mem, int desired)
{
rtx addr, base, offset;
@@ -3515,7 +4017,7 @@ int sparc_mode_class [NUM_MACHINE_MODES];
enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
static void
-sparc_init_modes ()
+sparc_init_modes (void)
{
int i;
@@ -3551,16 +4053,13 @@ sparc_init_modes ()
sparc_mode_class[i] = 0;
break;
case MODE_CC:
- default:
- /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
- we must explicitly check for them here. */
if (i == (int) CCFPmode || i == (int) CCFPEmode)
sparc_mode_class[i] = 1 << (int) CCFP_MODE;
- else if (i == (int) CCmode || i == (int) CC_NOOVmode
- || i == (int) CCXmode || i == (int) CCX_NOOVmode)
- sparc_mode_class[i] = 1 << (int) CC_MODE;
else
- sparc_mode_class[i] = 0;
+ sparc_mode_class[i] = 1 << (int) CC_MODE;
+ break;
+ default:
+ sparc_mode_class[i] = 0;
break;
}
}
@@ -3593,13 +4092,8 @@ sparc_init_modes ()
v9 int regs as it simplifies the code. */
static int
-save_regs (file, low, high, base, offset, n_regs, real_offset)
- FILE *file;
- int low, high;
- const char *base;
- int offset;
- int n_regs;
- int real_offset;
+save_regs (FILE *file, int low, int high, const char *base,
+ int offset, int n_regs, HOST_WIDE_INT real_offset)
{
int i;
@@ -3666,12 +4160,8 @@ save_regs (file, low, high, base, offset, n_regs, real_offset)
v9 int regs as it simplifies the code. */
static int
-restore_regs (file, low, high, base, offset, n_regs)
- FILE *file;
- int low, high;
- const char *base;
- int offset;
- int n_regs;
+restore_regs (FILE *file, int low, int high, const char *base,
+ int offset, int n_regs)
{
int i;
@@ -3710,10 +4200,8 @@ restore_regs (file, low, high, base, offset, n_regs)
/* Compute the frame size required by the function. This function is called
during the reload pass and also by output_function_prologue(). */
-int
-compute_frame_size (size, leaf_function)
- int size;
- int leaf_function;
+HOST_WIDE_INT
+compute_frame_size (HOST_WIDE_INT size, int leaf_function)
{
int n_regs = 0, i;
int outgoing_args_size = (current_function_outgoing_args_size
@@ -3767,41 +4255,102 @@ compute_frame_size (size, leaf_function)
return SPARC_STACK_ALIGN (actual_fsize);
}
-/* Build a (32 bit) big number in a register. */
-/* ??? We may be able to use the set macro here too. */
+/* Build big number NUM in register REG and output the result to FILE.
+ REG is guaranteed to be the only clobbered register. The function
+ will very likely emit several instructions, so it must not be called
+ from within a delay slot. */
static void
-build_big_number (file, num, reg)
- FILE *file;
- int num;
- const char *reg;
+build_big_number (FILE *file, HOST_WIDE_INT num, const char *reg)
{
- if (num >= 0 || ! TARGET_ARCH64)
+#if HOST_BITS_PER_WIDE_INT == 64
+ HOST_WIDE_INT high_bits = (num >> 32) & 0xffffffff;
+
+ if (high_bits == 0
+#else
+ if (num >= 0
+#endif
+ || ! TARGET_ARCH64)
{
- fprintf (file, "\tsethi\t%%hi(%d), %s\n", num, reg);
+ /* We don't use the 'set' macro because it appears to be broken
+ in the Solaris 7 assembler. */
+ fprintf (file, "\tsethi\t%%hi("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ num, reg);
if ((num & 0x3ff) != 0)
- fprintf (file, "\tor\t%s, %%lo(%d), %s\n", reg, num, reg);
+ fprintf (file, "\tor\t%s, %%lo("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ reg, num, reg);
}
+#if HOST_BITS_PER_WIDE_INT == 64
+ else if (high_bits == 0xffffffff) /* && TARGET_ARCH64 */
+#else
else /* num < 0 && TARGET_ARCH64 */
+#endif
{
/* Sethi does not sign extend, so we must use a little trickery
to use it for negative numbers. Invert the constant before
loading it in, then use xor immediate to invert the loaded bits
(along with the upper 32 bits) to the desired constant. This
works because the sethi and immediate fields overlap. */
- int asize = num;
- int inv = ~asize;
- int low = -0x400 + (asize & 0x3FF);
+ HOST_WIDE_INT inv = ~num;
+ HOST_WIDE_INT low = -0x400 + (num & 0x3ff);
- fprintf (file, "\tsethi\t%%hi(%d), %s\n\txor\t%s, %d, %s\n",
- inv, reg, reg, low, reg);
+ fprintf (file, "\tsethi\t%%hi("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ inv, reg);
+ fprintf (file, "\txor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low, reg);
}
+#if HOST_BITS_PER_WIDE_INT == 64
+ else /* TARGET_ARCH64 */
+ {
+ /* We don't use the 'setx' macro because if requires a scratch register.
+ This is the translation of sparc_emit_set_const64_longway into asm.
+ Hopefully we will soon have prologue/epilogue emitted as RTL. */
+ HOST_WIDE_INT low1 = (num >> (32 - 12)) & 0xfff;
+ HOST_WIDE_INT low2 = (num >> (32 - 12 - 12)) & 0xfff;
+ HOST_WIDE_INT low3 = (num >> (32 - 12 - 12 - 8)) & 0x0ff;
+ int to_shift = 12;
+
+ /* We don't use the 'set' macro because it appears to be broken
+ in the Solaris 7 assembler. */
+ fprintf (file, "\tsethi\t%%hi("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ high_bits, reg);
+ if ((high_bits & 0x3ff) != 0)
+ fprintf (file, "\tor\t%s, %%lo("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ reg, high_bits, reg);
+
+ if (low1 != 0)
+ {
+ fprintf (file, "\tsllx\t%s, %d, %s\n", reg, to_shift, reg);
+ fprintf (file, "\tor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low1, reg);
+ to_shift = 12;
+ }
+ else
+ {
+ to_shift += 12;
+ }
+ if (low2 != 0)
+ {
+ fprintf (file, "\tsllx\t%s, %d, %s\n", reg, to_shift, reg);
+ fprintf (file, "\tor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low2, reg);
+ to_shift = 8;
+ }
+ else
+ {
+ to_shift += 8;
+ }
+ fprintf (file, "\tsllx\t%s, %d, %s\n", reg, to_shift, reg);
+ if (low3 != 0)
+ fprintf (file, "\tor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low3, reg);
+ }
+#endif
}
/* Output any necessary .register pseudo-ops. */
void
-sparc_output_scratch_registers (file)
- FILE *file ATTRIBUTE_UNUSED;
+sparc_output_scratch_registers (FILE *file ATTRIBUTE_UNUSED)
{
#ifdef HAVE_AS_REGISTER_PSEUDO_OP
int i;
@@ -3841,9 +4390,7 @@ sparc_output_scratch_registers (file)
to do this is made in regclass.c. */
static void
-sparc_output_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_output_function_prologue (FILE *file, HOST_WIDE_INT size)
{
if (TARGET_FLAT)
sparc_flat_function_prologue (file, size);
@@ -3855,10 +4402,8 @@ sparc_output_function_prologue (file, size)
/* Output code for the function prologue. */
static void
-sparc_nonflat_function_prologue (file, size, leaf_function)
- FILE *file;
- HOST_WIDE_INT size;
- int leaf_function;
+sparc_nonflat_function_prologue (FILE *file, HOST_WIDE_INT size,
+ int leaf_function)
{
sparc_output_scratch_registers (file);
@@ -3885,11 +4430,13 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
else if (! leaf_function)
{
if (actual_fsize <= 4096)
- fprintf (file, "\tsave\t%%sp, -%d, %%sp\n", actual_fsize);
+ fprintf (file, "\tsave\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize);
else if (actual_fsize <= 8192)
{
fprintf (file, "\tsave\t%%sp, -4096, %%sp\n");
- fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize - 4096);
+ fprintf (file, "\tadd\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize - 4096);
}
else
{
@@ -3900,11 +4447,13 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
else /* leaf function */
{
if (actual_fsize <= 4096)
- fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize);
+ fprintf (file, "\tadd\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize);
else if (actual_fsize <= 8192)
{
fprintf (file, "\tadd\t%%sp, -4096, %%sp\n");
- fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize - 4096);
+ fprintf (file, "\tadd\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize - 4096);
}
else
{
@@ -3941,7 +4490,8 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
/* Call saved registers are saved just above the outgoing argument area. */
if (num_gfregs)
{
- int offset, real_offset, n_regs;
+ HOST_WIDE_INT offset, real_offset;
+ int n_regs;
const char *base;
real_offset = -apparent_fsize;
@@ -3973,11 +4523,10 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
/* Output code to restore any call saved registers. */
static void
-output_restore_regs (file, leaf_function)
- FILE *file;
- int leaf_function ATTRIBUTE_UNUSED;
+output_restore_regs (FILE *file, int leaf_function ATTRIBUTE_UNUSED)
{
- int offset, n_regs;
+ HOST_WIDE_INT offset;
+ int n_regs;
const char *base;
offset = -apparent_fsize + frame_base_offset;
@@ -4006,9 +4555,7 @@ output_restore_regs (file, leaf_function)
before returning. */
static void
-sparc_output_function_epilogue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
{
if (TARGET_FLAT)
sparc_flat_function_epilogue (file, size);
@@ -4020,10 +4567,9 @@ sparc_output_function_epilogue (file, size)
/* Output code for the function epilogue. */
static void
-sparc_nonflat_function_epilogue (file, size, leaf_function)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
- int leaf_function;
+sparc_nonflat_function_epilogue (FILE *file,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ int leaf_function)
{
const char *ret;
@@ -4088,7 +4634,7 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
? "\treturn\t%i7+12\n"
: "\treturn\t%i7+8\n", file);
final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
- file, 1, 0, 0);
+ file, 1, 0, 0, NULL);
}
else
{
@@ -4113,7 +4659,7 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
insn = emit_jump_insn (insn);
sparc_emitting_epilogue = true;
- final_scan_insn (insn, file, 1, 0, 1);
+ final_scan_insn (insn, file, 1, 0, 1, NULL);
sparc_emitting_epilogue = false;
}
}
@@ -4135,23 +4681,23 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
abort ();
fprintf (file, "\t%s\n", ret);
final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
- file, 1, 0, 1);
+ file, 1, 0, 1, NULL);
}
/* Output 'nop' instead of 'sub %sp,-0,%sp' when no frame, so as to
avoid generating confusing assembly language output. */
else if (actual_fsize == 0)
fprintf (file, "\t%s\n\tnop\n", ret);
else if (actual_fsize <= 4096)
- fprintf (file, "\t%s\n\tsub\t%%sp, -%d, %%sp\n", ret, actual_fsize);
+ fprintf (file, "\t%s\n\tsub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ ret, actual_fsize);
else if (actual_fsize <= 8192)
- fprintf (file, "\tsub\t%%sp, -4096, %%sp\n\t%s\n\tsub\t%%sp, -%d, %%sp\n",
+ fprintf (file, "\tsub\t%%sp, -4096, %%sp\n\t%s\n\tsub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
ret, actual_fsize - 4096);
- else if ((actual_fsize & 0x3ff) == 0)
- fprintf (file, "\tsethi\t%%hi(%d), %%g1\n\t%s\n\tadd\t%%sp, %%g1, %%sp\n",
- actual_fsize, ret);
- else
- fprintf (file, "\tsethi\t%%hi(%d), %%g1\n\tor\t%%g1, %%lo(%d), %%g1\n\t%s\n\tadd\t%%sp, %%g1, %%sp\n",
- actual_fsize, actual_fsize, ret);
+ else
+ {
+ build_big_number (file, actual_fsize, "%g1");
+ fprintf (file, "\t%s\n\tadd\t%%sp, %%g1, %%sp\n", ret);
+ }
output_vectors:
sparc_output_deferred_case_vectors ();
@@ -4160,8 +4706,7 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
/* Output a sibling call. */
const char *
-output_sibcall (insn, call_operand)
- rtx insn, call_operand;
+output_sibcall (rtx insn, rtx call_operand)
{
int leaf_regs = current_function_uses_only_leaf_regs;
rtx operands[3];
@@ -4179,7 +4724,7 @@ output_sibcall (insn, call_operand)
if (! delay)
abort ();
- final_scan_insn (delay, asm_out_file, 1, 0, 1);
+ final_scan_insn (delay, asm_out_file, 1, 0, 1, NULL);
PATTERN (delay) = gen_blockage ();
INSN_CODE (delay) = -1;
delay_slot = 0;
@@ -4200,7 +4745,7 @@ output_sibcall (insn, call_operand)
#else
int spare_slot = ((TARGET_ARCH32 || TARGET_CM_MEDLOW) && ! flag_pic);
#endif
- int size = 0;
+ HOST_WIDE_INT size = 0;
if ((actual_fsize || ! spare_slot) && delay_slot)
{
@@ -4209,7 +4754,7 @@ output_sibcall (insn, call_operand)
if (! delay)
abort ();
- final_scan_insn (delay, asm_out_file, 1, 0, 1);
+ final_scan_insn (delay, asm_out_file, 1, 0, 1, NULL);
PATTERN (delay) = gen_blockage ();
INSN_CODE (delay) = -1;
delay_slot = 0;
@@ -4223,15 +4768,9 @@ output_sibcall (insn, call_operand)
fputs ("\tsub\t%sp, -4096, %sp\n", asm_out_file);
size = actual_fsize - 4096;
}
- else if ((actual_fsize & 0x3ff) == 0)
- fprintf (asm_out_file,
- "\tsethi\t%%hi(%d), %%g1\n\tadd\t%%sp, %%g1, %%sp\n",
- actual_fsize);
else
{
- fprintf (asm_out_file,
- "\tsethi\t%%hi(%d), %%g1\n\tor\t%%g1, %%lo(%d), %%g1\n",
- actual_fsize, actual_fsize);
+ build_big_number (asm_out_file, actual_fsize, "%g1");
fputs ("\tadd\t%%sp, %%g1, %%sp\n", asm_out_file);
}
}
@@ -4240,14 +4779,14 @@ output_sibcall (insn, call_operand)
output_asm_insn ("sethi\t%%hi(%a0), %%g1", operands);
output_asm_insn ("jmpl\t%%g1 + %%lo(%a0), %%g0", operands);
if (size)
- fprintf (asm_out_file, "\t sub\t%%sp, -%d, %%sp\n", size);
+ fprintf (asm_out_file, "\t sub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n", size);
else if (! delay_slot)
fputs ("\t nop\n", asm_out_file);
}
else
{
if (size)
- fprintf (asm_out_file, "\tsub\t%%sp, -%d, %%sp\n", size);
+ fprintf (asm_out_file, "\tsub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n", size);
/* Use or with rs2 %%g0 instead of mov, so that as/ld can optimize
it into branch if possible. */
output_asm_insn ("or\t%%o7, %%g0, %%g1", operands);
@@ -4363,19 +4902,48 @@ output_sibcall (insn, call_operand)
For a library call, FNTYPE is 0. */
void
-init_cumulative_args (cum, fntype, libname, indirect)
- CUMULATIVE_ARGS *cum;
- tree fntype;
- rtx libname ATTRIBUTE_UNUSED;
- int indirect ATTRIBUTE_UNUSED;
+init_cumulative_args (struct sparc_args *cum, tree fntype,
+ rtx libname ATTRIBUTE_UNUSED,
+ tree fndecl ATTRIBUTE_UNUSED)
{
cum->words = 0;
cum->prototype_p = fntype && TYPE_ARG_TYPES (fntype);
cum->libcall_p = fntype == 0;
}
+/* Scan the record type TYPE and return the following predicates:
+ - INTREGS_P: the record contains at least one field or sub-field
+ that is eligible for promotion in integer registers.
+ - FP_REGS_P: the record contains at least one field or sub-field
+ that is eligible for promotion in floating-point registers.
+ - PACKED_P: the record contains at least one field that is packed.
+
+ Sub-fields are not taken into account for the PACKED_P predicate. */
+
+static void
+scan_record_type (tree type, int *intregs_p, int *fpregs_p, int *packed_p)
+{
+ tree field;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
+ scan_record_type (TREE_TYPE (field), intregs_p, fpregs_p, 0);
+ else if (FLOAT_TYPE_P (TREE_TYPE (field)) && TARGET_FPU)
+ *fpregs_p = 1;
+ else
+ *intregs_p = 1;
+
+ if (packed_p && DECL_PACKED (field))
+ *packed_p = 1;
+ }
+ }
+}
+
/* Compute the slot number to pass an argument in.
- Returns the slot number or -1 if passing on the stack.
+ Return the slot number or -1 if passing on the stack.
CUM is a variable of type CUMULATIVE_ARGS which gives info about
the preceding args and about the function being called.
@@ -4390,14 +4958,9 @@ init_cumulative_args (cum, fntype, libname, indirect)
*PPADDING records the amount of padding needed in words. */
static int
-function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
- const CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
- int incoming_p;
- int *pregno;
- int *ppadding;
+function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode,
+ tree type, int named, int incoming_p,
+ int *pregno, int *ppadding)
{
int regbase = (incoming_p
? SPARC_INCOMING_INT_ARG_FIRST
@@ -4421,19 +4984,27 @@ function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
See emit_call_1. */
return -1;
+ case TImode : case CTImode :
+ if (TARGET_ARCH64 && (slotno & 1) != 0)
+ slotno++, *ppadding = 1;
+ /* fallthrough */
+
case QImode : case CQImode :
case HImode : case CHImode :
case SImode : case CSImode :
case DImode : case CDImode :
- case TImode : case CTImode :
if (slotno >= SPARC_INT_ARG_MAX)
return -1;
regno = regbase + slotno;
break;
+ case TFmode : case TCmode :
+ if (TARGET_ARCH64 && (slotno & 1) != 0)
+ slotno++, *ppadding = 1;
+ /* fallthrough */
+
case SFmode : case SCmode :
case DFmode : case DCmode :
- case TFmode : case TCmode :
if (TARGET_ARCH32)
{
if (slotno >= SPARC_INT_ARG_MAX)
@@ -4442,9 +5013,6 @@ function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
}
else
{
- if ((mode == TFmode || mode == TCmode)
- && (slotno & 1) != 0)
- slotno++, *ppadding = 1;
if (TARGET_FPU && named)
{
if (slotno >= SPARC_FP_ARG_MAX)
@@ -4479,27 +5047,14 @@ function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
}
else
{
- tree field;
- int intregs_p = 0, fpregs_p = 0;
- /* The ABI obviously doesn't specify how packed
- structures are passed. These are defined to be passed
- in int regs if possible, otherwise memory. */
- int packed_p = 0;
+ int intregs_p = 0, fpregs_p = 0, packed_p = 0;
- /* First see what kinds of registers we need. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL)
- {
- if (TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
- && TARGET_FPU)
- fpregs_p = 1;
- else
- intregs_p = 1;
- if (DECL_PACKED (field))
- packed_p = 1;
- }
- }
+ /* First see what kinds of registers we would need. */
+ scan_record_type (type, &intregs_p, &fpregs_p, &packed_p);
+
+ /* The ABI obviously doesn't specify how packed structures
+ are passed. These are defined to be passed in int regs
+ if possible, otherwise memory. */
if (packed_p || !named)
fpregs_p = 0, intregs_p = 1;
@@ -4535,49 +5090,45 @@ struct function_arg_record_value_parms
int named; /* whether the argument is named. */
int regbase; /* regno of the base register. */
int stack; /* 1 if part of the argument is on the stack. */
- int intoffset; /* offset of the pending integer field. */
+ int intoffset; /* offset of the first pending integer field. */
unsigned int nregs; /* number of words passed in registers. */
};
static void function_arg_record_value_3
- PARAMS ((HOST_WIDE_INT, struct function_arg_record_value_parms *));
+ (HOST_WIDE_INT, struct function_arg_record_value_parms *);
static void function_arg_record_value_2
- PARAMS ((tree, HOST_WIDE_INT,
- struct function_arg_record_value_parms *));
+ (tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool);
static void function_arg_record_value_1
- PARAMS ((tree, HOST_WIDE_INT,
- struct function_arg_record_value_parms *));
-static rtx function_arg_record_value
- PARAMS ((tree, enum machine_mode, int, int, int));
+ (tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool);
+static rtx function_arg_record_value (tree, enum machine_mode, int, int, int);
+static rtx function_arg_union_value (int, enum machine_mode, int);
/* A subroutine of function_arg_record_value. Traverse the structure
- recusively and determine how many registers will be required. */
+ recursively and determine how many registers will be required. */
static void
-function_arg_record_value_1 (type, startbitpos, parms)
- tree type;
- HOST_WIDE_INT startbitpos;
- struct function_arg_record_value_parms *parms;
+function_arg_record_value_1 (tree type, HOST_WIDE_INT startbitpos,
+ struct function_arg_record_value_parms *parms,
+ bool packed_p)
{
tree field;
- /* The ABI obviously doesn't specify how packed structures are
- passed. These are defined to be passed in int regs if possible,
- otherwise memory. */
- int packed_p = 0;
-
/* We need to compute how many registers are needed so we can
allocate the PARALLEL but before we can do that we need to know
- whether there are any packed fields. If there are, int regs are
- used regardless of whether there are fp values present. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
- {
- packed_p = 1;
- break;
- }
- }
+ whether there are any packed fields. The ABI obviously doesn't
+ specify how structures are passed in this case, so they are
+ defined to be passed in int regs if possible, otherwise memory,
+ regardless of whether there are fp values present. */
+
+ if (! packed_p)
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
+ {
+ packed_p = true;
+ break;
+ }
+ }
/* Compute how many registers we need. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
@@ -4593,21 +5144,24 @@ function_arg_record_value_1 (type, startbitpos, parms)
/* ??? FIXME: else assume zero offset. */
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
- function_arg_record_value_1 (TREE_TYPE (field), bitpos, parms);
- else if ((TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
- || (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
- == REAL_TYPE)))
- && TARGET_FPU
- && ! packed_p
- && parms->named)
+ function_arg_record_value_1 (TREE_TYPE (field),
+ bitpos,
+ parms,
+ packed_p);
+ else if (FLOAT_TYPE_P (TREE_TYPE (field))
+ && TARGET_FPU
+ && parms->named
+ && ! packed_p)
{
if (parms->intoffset != -1)
{
+ unsigned int startbit, endbit;
int intslots, this_slotno;
- intslots = (bitpos - parms->intoffset + BITS_PER_WORD - 1)
- / BITS_PER_WORD;
+ startbit = parms->intoffset & -BITS_PER_WORD;
+ endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
+
+ intslots = (endbit - startbit) / BITS_PER_WORD;
this_slotno = parms->slotno + parms->intoffset
/ BITS_PER_WORD;
@@ -4641,9 +5195,8 @@ function_arg_record_value_1 (type, startbitpos, parms)
structure between parms->intoffset and bitpos to integer registers. */
static void
-function_arg_record_value_3 (bitpos, parms)
- HOST_WIDE_INT bitpos;
- struct function_arg_record_value_parms *parms;
+function_arg_record_value_3 (HOST_WIDE_INT bitpos,
+ struct function_arg_record_value_parms *parms)
{
enum machine_mode mode;
unsigned int regno;
@@ -4687,6 +5240,7 @@ function_arg_record_value_3 (bitpos, parms)
this_slotno += 1;
intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
+ mode = word_mode;
parms->nregs += 1;
intslots -= 1;
}
@@ -4699,22 +5253,21 @@ function_arg_record_value_3 (bitpos, parms)
to make that happen. */
static void
-function_arg_record_value_2 (type, startbitpos, parms)
- tree type;
- HOST_WIDE_INT startbitpos;
- struct function_arg_record_value_parms *parms;
+function_arg_record_value_2 (tree type, HOST_WIDE_INT startbitpos,
+ struct function_arg_record_value_parms *parms,
+ bool packed_p)
{
tree field;
- int packed_p = 0;
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
- {
- packed_p = 1;
- break;
- }
- }
+ if (! packed_p)
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
+ {
+ packed_p = true;
+ break;
+ }
+ }
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
@@ -4729,14 +5282,14 @@ function_arg_record_value_2 (type, startbitpos, parms)
/* ??? FIXME: else assume zero offset. */
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
- function_arg_record_value_2 (TREE_TYPE (field), bitpos, parms);
- else if ((TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
- || (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
- == REAL_TYPE)))
- && TARGET_FPU
- && ! packed_p
- && parms->named)
+ function_arg_record_value_2 (TREE_TYPE (field),
+ bitpos,
+ parms,
+ packed_p);
+ else if (FLOAT_TYPE_P (TREE_TYPE (field))
+ && TARGET_FPU
+ && parms->named
+ && ! packed_p)
{
int this_slotno = parms->slotno + bitpos / BITS_PER_WORD;
int regno;
@@ -4794,10 +5347,8 @@ function_arg_record_value_2 (type, startbitpos, parms)
REGBASE is the regno of the base register for the parameter array. */
static rtx
-function_arg_record_value (type, mode, slotno, named, regbase)
- tree type;
- enum machine_mode mode;
- int slotno, named, regbase;
+function_arg_record_value (tree type, enum machine_mode mode,
+ int slotno, int named, int regbase)
{
HOST_WIDE_INT typesize = int_size_in_bytes (type);
struct function_arg_record_value_parms parms;
@@ -4812,8 +5363,9 @@ function_arg_record_value (type, mode, slotno, named, regbase)
/* Compute how many registers we need. */
parms.nregs = 0;
parms.intoffset = 0;
- function_arg_record_value_1 (type, 0, &parms);
+ function_arg_record_value_1 (type, 0, &parms, false);
+ /* Take into account pending integer fields. */
if (parms.intoffset != -1)
{
unsigned int startbit, endbit;
@@ -4874,7 +5426,7 @@ function_arg_record_value (type, mode, slotno, named, regbase)
/* Fill in the entries. */
parms.nregs = 0;
parms.intoffset = 0;
- function_arg_record_value_2 (type, 0, &parms);
+ function_arg_record_value_2 (type, 0, &parms, false);
function_arg_record_value_3 (typesize * BITS_PER_UNIT, &parms);
if (parms.nregs != nregs)
@@ -4883,6 +5435,33 @@ function_arg_record_value (type, mode, slotno, named, regbase)
return parms.ret;
}
+/* Used by function_arg and function_value to implement the conventions
+ of the 64-bit ABI for passing and returning unions.
+ Return an expression valid as a return value for the two macros
+ FUNCTION_ARG and FUNCTION_VALUE.
+
+ SIZE is the size in bytes of the union.
+ MODE is the argument's machine mode.
+ REGNO is the hard register the union will be passed in. */
+
+static rtx
+function_arg_union_value (int size, enum machine_mode mode, int regno)
+{
+ int nwords = ROUND_ADVANCE (size), i;
+ rtx regs;
+
+ /* Unions are passed left-justified. */
+ regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
+
+ for (i = 0; i < nwords; i++)
+ XVECEXP (regs, 0, i)
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (word_mode, regno + i),
+ GEN_INT (UNITS_PER_WORD * i));
+
+ return regs;
+}
+
/* Handle the FUNCTION_ARG macro.
Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
@@ -4899,12 +5478,8 @@ function_arg_record_value (type, mode, slotno, named, regbase)
INCOMING_P is zero for FUNCTION_ARG, nonzero for FUNCTION_INCOMING_ARG. */
rtx
-function_arg (cum, mode, type, named, incoming_p)
- const CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
- int incoming_p;
+function_arg (const struct sparc_args *cum, enum machine_mode mode,
+ tree type, int named, int incoming_p)
{
int regbase = (incoming_p
? SPARC_INCOMING_INT_ARG_FIRST
@@ -4923,13 +5498,32 @@ function_arg (cum, mode, type, named, incoming_p)
reg = gen_rtx_REG (mode, regno);
return reg;
}
+
+ if (type && TREE_CODE (type) == RECORD_TYPE)
+ {
+ /* Structures up to 16 bytes in size are passed in arg slots on the
+ stack and are promoted to registers where possible. */
+ if (int_size_in_bytes (type) > 16)
+ abort (); /* shouldn't get here */
+
+ return function_arg_record_value (type, mode, slotno, named, regbase);
+ }
+ else if (type && TREE_CODE (type) == UNION_TYPE)
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+
+ if (size > 16)
+ abort (); /* shouldn't get here */
+
+ return function_arg_union_value (size, mode, regno);
+ }
/* v9 fp args in reg slots beyond the int reg slots get passed in regs
but also have the slot allocated for them.
If no prototype is in scope fp values in register slots get passed
in two places, either fp regs and int regs or fp regs and memory. */
- if ((GET_MODE_CLASS (mode) == MODE_FLOAT
- || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
+ else if ((GET_MODE_CLASS (mode) == MODE_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
&& SPARC_FP_REG_P (regno))
{
reg = gen_rtx_REG (mode, regno);
@@ -4958,7 +5552,7 @@ function_arg (cum, mode, type, named, incoming_p)
This is due to locate_and_pad_parm being called in
expand_call whenever reg_parm_stack_space > 0, which
- while benefical to our example here, would seem to be
+ while beneficial to our example here, would seem to be
in error from what had been intended. Ho hum... -- r~ */
#endif
return reg;
@@ -4993,27 +5587,6 @@ function_arg (cum, mode, type, named, incoming_p)
}
}
}
- else if (type && TREE_CODE (type) == RECORD_TYPE)
- {
- /* Structures up to 16 bytes in size are passed in arg slots on the
- stack and are promoted to registers where possible. */
-
- if (int_size_in_bytes (type) > 16)
- abort (); /* shouldn't get here */
-
- return function_arg_record_value (type, mode, slotno, named, regbase);
- }
- else if (type && TREE_CODE (type) == UNION_TYPE)
- {
- enum machine_mode mode;
- int bytes = int_size_in_bytes (type);
-
- if (bytes > 16)
- abort ();
-
- mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
- reg = gen_rtx_REG (mode, regno);
- }
else
{
/* Scalar or complex int. */
@@ -5035,11 +5608,8 @@ function_arg (cum, mode, type, named, incoming_p)
mode] will be split between that reg and memory. */
int
-function_arg_partial_nregs (cum, mode, type, named)
- const CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg_partial_nregs (const struct sparc_args *cum,
+ enum machine_mode mode, tree type, int named)
{
int slotno, regno, padding;
@@ -5073,11 +5643,17 @@ function_arg_partial_nregs (cum, mode, type, named)
}
else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
|| (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- && ! TARGET_FPU))
+ && ! (TARGET_FPU && named)))
{
+ /* The complex types are passed as packed types. */
+ if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
+ return 0;
+
if (GET_MODE_ALIGNMENT (mode) == 128)
{
slotno += slotno & 1;
+
+ /* ??? The mode needs 3 slots? */
if (slotno == SPARC_INT_ARG_MAX - 2)
return 1;
}
@@ -5106,21 +5682,21 @@ function_arg_partial_nregs (cum, mode, type, named)
For Pascal, also pass arrays by reference. */
int
-function_arg_pass_by_reference (cum, mode, type, named)
- const CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg_pass_by_reference (const struct sparc_args *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode, tree type,
+ int named ATTRIBUTE_UNUSED)
{
if (TARGET_ARCH32)
{
return ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode || mode == TCmode);
+ || mode == SCmode
+ || GET_MODE_SIZE (mode) > 8);
}
else
{
return ((type && TREE_CODE (type) == ARRAY_TYPE)
- /* Consider complex values as aggregates, so care for TCmode. */
+ /* Consider complex values as aggregates, so care
+ for CTImode and TCmode. */
|| GET_MODE_SIZE (mode) > 16
|| (type
&& AGGREGATE_TYPE_P (type)
@@ -5134,11 +5710,8 @@ function_arg_pass_by_reference (cum, mode, type, named)
TYPE is null for libcalls where that information may not be available. */
void
-function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg_advance (struct sparc_args *cum, enum machine_mode mode,
+ tree type, int named)
{
int slotno, regno, padding;
@@ -5168,14 +5741,6 @@ function_arg_advance (cum, mode, type, named)
else /* passed by reference */
++cum->words;
}
- else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
- {
- cum->words += 2;
- }
- else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
- {
- cum->words += GET_MODE_SIZE (mode) / UNITS_PER_WORD;
- }
else
{
cum->words += (mode != BLKmode
@@ -5190,21 +5755,13 @@ function_arg_advance (cum, mode, type, named)
argument slot. */
enum direction
-function_arg_padding (mode, type)
- enum machine_mode mode;
- tree type;
+function_arg_padding (enum machine_mode mode, tree type)
{
if (TARGET_ARCH64 && type != 0 && AGGREGATE_TYPE_P (type))
return upward;
- /* This is the default definition. */
- return (! BYTES_BIG_ENDIAN
- ? upward
- : ((mode == BLKmode
- ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
- : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
- ? downward : upward));
+ /* Fall back to the default. */
+ return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
}
/* Handle FUNCTION_VALUE, FUNCTION_OUTGOING_VALUE, and LIBCALL_VALUE macros.
@@ -5212,18 +5769,16 @@ function_arg_padding (mode, type)
except that up to 32-bytes may be returned in registers. */
rtx
-function_value (type, mode, incoming_p)
- tree type;
- enum machine_mode mode;
- int incoming_p;
+function_value (tree type, enum machine_mode mode, int incoming_p)
{
int regno;
- int regbase = (incoming_p
- ? SPARC_OUTGOING_INT_ARG_FIRST
- : SPARC_INCOMING_INT_ARG_FIRST);
if (TARGET_ARCH64 && type)
{
+ int regbase = (incoming_p
+ ? SPARC_OUTGOING_INT_ARG_FIRST
+ : SPARC_INCOMING_INT_ARG_FIRST);
+
if (TREE_CODE (type) == RECORD_TYPE)
{
/* Structures up to 32 bytes in size are passed in registers,
@@ -5234,6 +5789,15 @@ function_value (type, mode, incoming_p)
return function_arg_record_value (type, mode, 0, 1, regbase);
}
+ else if (TREE_CODE (type) == UNION_TYPE)
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+
+ if (size > 32)
+ abort (); /* shouldn't get here */
+
+ return function_arg_union_value (size, mode, regbase);
+ }
else if (AGGREGATE_TYPE_P (type))
{
/* All other aggregate types are passed in an integer register
@@ -5244,14 +5808,23 @@ function_value (type, mode, incoming_p)
abort ();
mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
+
+ /* ??? We probably should have made the same ABI change in
+ 3.4.0 as the one we made for unions. The latter was
+ required by the SCD though, while the former is not
+ specified, so we favored compatibility and efficiency.
+
+ Now we're stuck for aggregates larger than 16 bytes,
+ because OImode vanished in the meantime. Let's not
+ try to be unduly clever, and simply follow the ABI
+ for unions in that case. */
+ if (mode == BLKmode)
+ return function_arg_union_value (bytes, mode, regbase);
}
+ else if (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+ mode = word_mode;
}
-
- if (TARGET_ARCH64
- && GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) < UNITS_PER_WORD
- && type && ! AGGREGATE_TYPE_P (type))
- mode = DImode;
if (incoming_p)
regno = BASE_RETURN_VALUE_REG (mode);
@@ -5266,7 +5839,7 @@ function_value (type, mode, incoming_p)
the first unnamed parameter. */
rtx
-sparc_builtin_saveregs ()
+sparc_builtin_saveregs (void)
{
int first_reg = current_function_args_info.words;
rtx address;
@@ -5293,9 +5866,7 @@ sparc_builtin_saveregs ()
/* Implement `va_start' for varargs and stdarg. */
void
-sparc_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+sparc_va_start (tree valist, rtx nextarg)
{
nextarg = expand_builtin_saveregs ();
std_expand_builtin_va_start (valist, nextarg);
@@ -5304,8 +5875,7 @@ sparc_va_start (valist, nextarg)
/* Implement `va_arg'. */
rtx
-sparc_va_arg (valist, type)
- tree valist, type;
+sparc_va_arg (tree valist, tree type)
{
HOST_WIDE_INT size, rsize, align;
tree addr, incr;
@@ -5322,16 +5892,19 @@ sparc_va_arg (valist, type)
if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD)
align = 2 * UNITS_PER_WORD;
- if (AGGREGATE_TYPE_P (type))
+ /* Consider complex values as aggregates, so care
+ for CTImode and TCmode. */
+ if ((unsigned HOST_WIDE_INT) size > 16)
{
- if ((unsigned HOST_WIDE_INT) size > 16)
- {
- indirect = 1;
- size = rsize = UNITS_PER_WORD;
- }
- /* SPARC v9 ABI states that structures up to 8 bytes in size are
- given one 8 byte slot. */
- else if (size == 0)
+ indirect = 1;
+ size = rsize = UNITS_PER_WORD;
+ align = 0;
+ }
+ else if (AGGREGATE_TYPE_P (type))
+ {
+ /* SPARC-V9 ABI states that structures up to 16 bytes in size
+ are given whole slots as needed. */
+ if (size == 0)
size = rsize = UNITS_PER_WORD;
else
size = rsize;
@@ -5340,8 +5913,8 @@ sparc_va_arg (valist, type)
else
{
if (AGGREGATE_TYPE_P (type)
- || TYPE_MODE (type) == TFmode
- || TYPE_MODE (type) == TCmode)
+ || TYPE_MODE (type) == SCmode
+ || GET_MODE_SIZE (TYPE_MODE (type)) > 8)
{
indirect = 1;
size = rsize = UNITS_PER_WORD;
@@ -5414,25 +5987,81 @@ sparc_va_arg (valist, type)
return addr_rtx;
}
+/* Return the string to output an unconditional branch to LABEL, which is
+ the operand number of the label.
+
+ DEST is the destination insn (i.e. the label), INSN is the source. */
+
+const char *
+output_ubranch (rtx dest, int label, rtx insn)
+{
+ static char string[64];
+ bool noop = false;
+ char *p;
+
+ /* TurboSPARC is reported to have problems with
+ with
+ foo: b,a foo
+ i.e. an empty loop with the annul bit set. The workaround is to use
+ foo: b foo; nop
+ instead. */
+
+ if (! TARGET_V9 && flag_delayed_branch
+ && (INSN_ADDRESSES (INSN_UID (dest))
+ == INSN_ADDRESSES (INSN_UID (insn))))
+ {
+ strcpy (string, "b\t");
+ noop = true;
+ }
+ else
+ {
+ bool v9_form = false;
+
+ if (TARGET_V9 && INSN_ADDRESSES_SET_P ())
+ {
+ int delta = (INSN_ADDRESSES (INSN_UID (dest))
+ - INSN_ADDRESSES (INSN_UID (insn)));
+ /* Leave some instructions for "slop". */
+ if (delta >= -260000 && delta < 260000)
+ v9_form = true;
+ }
+
+ if (v9_form)
+ strcpy (string, "ba%*,pt\t%%xcc, ");
+ else
+ strcpy (string, "b%*\t");
+ }
+
+ p = strchr (string, '\0');
+ *p++ = '%';
+ *p++ = 'l';
+ *p++ = '0' + label;
+ *p++ = '%';
+ if (noop)
+ *p++ = '#';
+ else
+ *p++ = '(';
+ *p = '\0';
+
+ return string;
+}
+
/* Return the string to output a conditional branch to LABEL, which is
the operand number of the label. OP is the conditional expression.
XEXP (OP, 0) is assumed to be a condition code register (integer or
floating point) and its mode specifies what kind of comparison we made.
+ DEST is the destination insn (i.e. the label), INSN is the source.
+
REVERSED is nonzero if we should reverse the sense of the comparison.
ANNUL is nonzero if we should generate an annulling branch.
- NOOP is nonzero if we have to follow this branch by a noop.
-
- INSN, if set, is the insn. */
+ NOOP is nonzero if we have to follow this branch by a noop. */
char *
-output_cbranch (op, dest, label, reversed, annul, noop, insn)
- rtx op, dest;
- int label;
- int reversed, annul, noop;
- rtx insn;
+output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
+ int noop, rtx insn)
{
static char string[50];
enum rtx_code code = GET_CODE (op);
@@ -5463,7 +6092,7 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
nop
ba .LC29 */
- far = get_attr_length (insn) >= 3;
+ far = TARGET_V9 && (get_attr_length (insn) >= 3);
if (reversed ^ far)
{
/* Reversal of FP compares takes care -- an ordered compare
@@ -5593,9 +6222,7 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
spaces -= 2;
}
- if (! TARGET_V9)
- labelno = "";
- else
+ if (TARGET_V9)
{
rtx note;
int v8 = 0;
@@ -5645,6 +6272,9 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
spaces -= 3;
}
}
+ else
+ labelno = "";
+
if (spaces > 0)
*p++ = '\t';
else
@@ -5676,9 +6306,7 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
values as arguments instead of the TFmode registers themselves,
that's why we cannot call emit_float_lib_cmp. */
void
-sparc_emit_float_lib_cmp (x, y, comparison)
- rtx x, y;
- enum rtx_code comparison;
+sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
{
const char *qpfunc;
rtx slot0, slot1, result, tem, tem2;
@@ -5815,8 +6443,7 @@ sparc_emit_float_lib_cmp (x, y, comparison)
optabs would emit if we didn't have TFmode patterns. */
void
-sparc_emit_floatunsdi (operands)
- rtx operands[2];
+sparc_emit_floatunsdi (rtx *operands)
{
rtx neglab, donelab, i0, i1, f0, in, out;
enum machine_mode mode;
@@ -5852,6 +6479,8 @@ sparc_emit_floatunsdi (operands)
operand number of the reg. OP is the conditional expression. The mode
of REG says what kind of comparison we made.
+ DEST is the destination insn (i.e. the label), INSN is the source.
+
REVERSED is nonzero if we should reverse the sense of the comparison.
ANNUL is nonzero if we should generate an annulling branch.
@@ -5859,11 +6488,8 @@ sparc_emit_floatunsdi (operands)
NOOP is nonzero if we have to follow this branch by a noop. */
char *
-output_v9branch (op, dest, reg, label, reversed, annul, noop, insn)
- rtx op, dest;
- int reg, label;
- int reversed, annul, noop;
- rtx insn;
+output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
+ int annul, int noop, rtx insn)
{
static char string[50];
enum rtx_code code = GET_CODE (op);
@@ -6003,9 +6629,7 @@ output_v9branch (op, dest, reg, label, reversed, annul, noop, insn)
*/
static int
-epilogue_renumber (where, test)
- register rtx *where;
- int test;
+epilogue_renumber (register rtx *where, int test)
{
register const char *fmt;
register int i;
@@ -6089,7 +6713,7 @@ static const int *const reg_alloc_orders[] = {
reg_nonleaf_alloc_order};
void
-order_regs_for_local_alloc ()
+order_regs_for_local_alloc (void)
{
static int last_order_nonleaf = 1;
@@ -6106,9 +6730,7 @@ order_regs_for_local_alloc ()
mem<-->reg splits to be run. */
int
-sparc_splitdi_legitimate (reg, mem)
- rtx reg;
- rtx mem;
+sparc_splitdi_legitimate (rtx reg, rtx mem)
{
/* Punt if we are here by mistake. */
if (! reload_completed)
@@ -6129,12 +6751,11 @@ sparc_splitdi_legitimate (reg, mem)
}
/* Return 1 if x and y are some kind of REG and they refer to
- different hard registers. This test is guarenteed to be
+ different hard registers. This test is guaranteed to be
run after reload. */
int
-sparc_absnegfloat_split_legitimate (x, y)
- rtx x, y;
+sparc_absnegfloat_split_legitimate (rtx x, rtx y)
{
if (GET_CODE (x) != REG)
return 0;
@@ -6151,8 +6772,7 @@ sparc_absnegfloat_split_legitimate (x, y)
Note reg1 and reg2 *must* be hard registers. */
int
-registers_ok_for_ldd_peep (reg1, reg2)
- rtx reg1, reg2;
+registers_ok_for_ldd_peep (rtx reg1, rtx reg2)
{
/* We might have been passed a SUBREG. */
if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
@@ -6200,12 +6820,11 @@ registers_ok_for_ldd_peep (reg1, reg2)
NULL_RTX. */
int
-mems_ok_for_ldd_peep (mem1, mem2, dependent_reg_rtx)
- rtx mem1, mem2, dependent_reg_rtx;
+mems_ok_for_ldd_peep (rtx mem1, rtx mem2, rtx dependent_reg_rtx)
{
rtx addr1, addr2;
unsigned int reg1;
- int offset1;
+ HOST_WIDE_INT offset1;
/* The mems cannot be volatile. */
if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
@@ -6275,8 +6894,7 @@ mems_ok_for_ldd_peep (mem1, mem2, dependent_reg_rtx)
ldd and std insns. */
int
-register_ok_for_ldd (reg)
- rtx reg;
+register_ok_for_ldd (rtx reg)
{
/* We might have been passed a SUBREG. */
if (GET_CODE (reg) != REG)
@@ -6293,10 +6911,7 @@ register_ok_for_ldd (reg)
For `%' followed by punctuation, CODE is the punctuation and X is null. */
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
switch (code)
{
@@ -6331,7 +6946,11 @@ print_operand (file, x, code)
/* Print out what we are using as the frame pointer. This might
be %fp, or might be %sp+offset. */
/* ??? What if offset is too big? Perhaps the caller knows it isn't? */
- fprintf (file, "%s+%d", frame_base_name, frame_base_offset);
+ fprintf (file, "%s+"HOST_WIDE_INT_PRINT_DEC, frame_base_name, frame_base_offset);
+ return;
+ case '&':
+ /* Print some local dynamic TLS name. */
+ assemble_name (file, get_some_local_dynamic_name ());
return;
case 'Y':
/* Adjust the operand to take into account a RESTORE operation. */
@@ -6581,10 +7200,7 @@ print_operand (file, x, code)
special handling for aligned DI-mode objects. */
static bool
-sparc_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+sparc_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
/* ??? We only output .xword's for symbols and only then in environments
where the assembler can handle them. */
@@ -6639,8 +7255,7 @@ sparc_assemble_integer (x, size, aligned_p)
#endif
unsigned long
-sparc_type_code (type)
- register tree type;
+sparc_type_code (register tree type)
{
register unsigned long qualifiers = 0;
register unsigned shift;
@@ -6764,10 +7379,9 @@ sparc_type_code (type)
Emit enough FLUSH insns to synchronize the data and instruction caches. */
void
-sparc_initialize_trampoline (tramp, fnaddr, cxt)
- rtx tramp, fnaddr, cxt;
+sparc_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
{
- /* SPARC 32 bit trampoline:
+ /* SPARC 32-bit trampoline:
sethi %hi(fn), %g1
sethi %hi(static), %g2
@@ -6777,10 +7391,6 @@ sparc_initialize_trampoline (tramp, fnaddr, cxt)
SETHI i,r = 00rr rrr1 00ii iiii iiii iiii iiii iiii
JMPL r+i,d = 10dd ddd1 1100 0rrr rr1i iiii iiii iiii
*/
-#ifdef TRANSFER_FROM_TRAMPOLINE
- emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
- LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
-#endif
emit_move_insn
(gen_rtx_MEM (SImode, plus_constant (tramp, 0)),
@@ -6819,22 +7429,25 @@ sparc_initialize_trampoline (tramp, fnaddr, cxt)
&& sparc_cpu != PROCESSOR_ULTRASPARC3)
emit_insn (gen_flush (validize_mem (gen_rtx_MEM (SImode,
plus_constant (tramp, 8)))));
+
+ /* Call __enable_execute_stack after writing onto the stack to make sure
+ the stack address is accessible. */
+#ifdef ENABLE_EXECUTE_STACK
+ emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
+ LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
+#endif
+
}
-/* The 64 bit version is simpler because it makes more sense to load the
+/* The 64-bit version is simpler because it makes more sense to load the
values as "immediate" data out of the trampoline. It's also easier since
we can read the PC without clobbering a register. */
void
-sparc64_initialize_trampoline (tramp, fnaddr, cxt)
- rtx tramp, fnaddr, cxt;
+sparc64_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
{
-#ifdef TRANSFER_FROM_TRAMPOLINE
- emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
- LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
-#endif
+ /* SPARC 64-bit trampoline:
- /*
rd %pc, %g1
ldx [%g1+24], %g5
jmp %g5
@@ -6857,6 +7470,13 @@ sparc64_initialize_trampoline (tramp, fnaddr, cxt)
if (sparc_cpu != PROCESSOR_ULTRASPARC
&& sparc_cpu != PROCESSOR_ULTRASPARC3)
emit_insn (gen_flushdi (validize_mem (gen_rtx_MEM (DImode, plus_constant (tramp, 8)))));
+
+ /* Call __enable_execute_stack after writing onto the stack to make sure
+ the stack address is accessible. */
+#ifdef ENABLE_EXECUTE_STACK
+ emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
+ LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
+#endif
}
/* Subroutines to support a flat (single) register window calling
@@ -6925,16 +7545,16 @@ sparc64_initialize_trampoline (tramp, fnaddr, cxt)
struct sparc_frame_info
{
- unsigned long total_size; /* # bytes that the entire frame takes up. */
- unsigned long var_size; /* # bytes that variables take up. */
- unsigned long args_size; /* # bytes that outgoing arguments take up. */
- unsigned long extra_size; /* # bytes of extra gunk. */
- unsigned int gp_reg_size; /* # bytes needed to store gp regs. */
- unsigned int fp_reg_size; /* # bytes needed to store fp regs. */
+ HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
+ HOST_WIDE_INT var_size; /* # bytes that variables take up. */
+ int args_size; /* # bytes that outgoing arguments take up. */
+ int extra_size; /* # bytes of extra gunk. */
+ int gp_reg_size; /* # bytes needed to store gp regs. */
+ int fp_reg_size; /* # bytes needed to store fp regs. */
unsigned long gmask; /* Mask of saved gp registers. */
unsigned long fmask; /* Mask of saved fp registers. */
- unsigned long reg_offset; /* Offset from new sp to store regs. */
- int initialized; /* Nonzero if frame size already calculated. */
+ int reg_offset; /* Offset from new sp to store regs. */
+ int initialized; /* Nonzero if frame size already calculated. */
};
/* Current frame information calculated by sparc_flat_compute_frame_size. */
@@ -6943,34 +7563,56 @@ struct sparc_frame_info current_frame_info;
/* Zero structure to initialize current_frame_info. */
struct sparc_frame_info zero_frame_info;
-/* Tell prologue and epilogue if register REGNO should be saved / restored. */
-
#define RETURN_ADDR_REGNUM 15
#define HARD_FRAME_POINTER_MASK (1 << (HARD_FRAME_POINTER_REGNUM))
#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
+
+/* Tell prologue and epilogue if register REGNO should be saved / restored. */
+
+static bool
+sparc_flat_must_save_register_p (int regno)
+{
+ /* General case: call-saved registers live at some point. */
+ if (!call_used_regs[regno] && regs_ever_live[regno])
+ return true;
+
+ /* Frame pointer register (%i7) if needed. */
+ if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
+ return true;
-#define MUST_SAVE_REGISTER(regno) \
- ((regs_ever_live[regno] && !call_used_regs[regno]) \
- || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \
- || (regno == RETURN_ADDR_REGNUM && regs_ever_live[RETURN_ADDR_REGNUM]))
+ /* PIC register (%l7) if needed. */
+ if (regno == (int) PIC_OFFSET_TABLE_REGNUM
+ && flag_pic && current_function_uses_pic_offset_table)
+ return true;
+ /* Return address register (%o7) if needed. */
+ if (regno == RETURN_ADDR_REGNUM
+ && (regs_ever_live[RETURN_ADDR_REGNUM]
+ /* When the PIC offset table is used, the PIC register
+ is set by using a bare call that clobbers %o7. */
+ || (flag_pic && current_function_uses_pic_offset_table)))
+ return true;
+
+ return false;
+}
+
/* Return the bytes needed to compute the frame pointer from the current
stack pointer. */
-unsigned long
-sparc_flat_compute_frame_size (size)
- int size; /* # of var. bytes allocated. */
+HOST_WIDE_INT
+sparc_flat_compute_frame_size (HOST_WIDE_INT size)
+ /* # of var. bytes allocated. */
{
int regno;
- unsigned long total_size; /* # bytes that the entire frame takes up. */
- unsigned long var_size; /* # bytes that variables take up. */
- unsigned long args_size; /* # bytes that outgoing arguments take up. */
- unsigned long extra_size; /* # extra bytes. */
- unsigned int gp_reg_size; /* # bytes needed to store gp regs. */
- unsigned int fp_reg_size; /* # bytes needed to store fp regs. */
+ HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
+ HOST_WIDE_INT var_size; /* # bytes that variables take up. */
+ int args_size; /* # bytes that outgoing arguments take up. */
+ int extra_size; /* # extra bytes. */
+ int gp_reg_size; /* # bytes needed to store gp regs. */
+ int fp_reg_size; /* # bytes needed to store fp regs. */
unsigned long gmask; /* Mask of saved gp registers. */
unsigned long fmask; /* Mask of saved fp registers. */
- unsigned long reg_offset; /* Offset to register save area. */
+ int reg_offset; /* Offset to register save area. */
int need_aligned_p; /* 1 if need the save area 8 byte aligned. */
/* This is the size of the 16 word reg save area, 1 word struct addr
@@ -6995,11 +7637,11 @@ sparc_flat_compute_frame_size (size)
/* Calculate space needed for gp registers. */
for (regno = 1; regno <= 31; regno++)
{
- if (MUST_SAVE_REGISTER (regno))
+ if (sparc_flat_must_save_register_p (regno))
{
/* If we need to save two regs in a row, ensure there's room to bump
up the address to align it to a doubleword boundary. */
- if ((regno & 0x1) == 0 && MUST_SAVE_REGISTER (regno+1))
+ if ((regno & 0x1) == 0 && sparc_flat_must_save_register_p (regno+1))
{
if (gp_reg_size % 8 != 0)
gp_reg_size += 4;
@@ -7076,17 +7718,11 @@ sparc_flat_compute_frame_size (size)
WORD_OP is either "st" for save, "ld" for restore.
DOUBLEWORD_OP is either "std" for save, "ldd" for restore. */
-void
-sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op,
- doubleword_op, base_offset)
- FILE *file;
- const char *base_reg;
- unsigned int offset;
- unsigned long gmask;
- unsigned long fmask;
- const char *word_op;
- const char *doubleword_op;
- unsigned long base_offset;
+static void
+sparc_flat_save_restore (FILE *file, const char *base_reg, int offset,
+ unsigned long gmask, unsigned long fmask,
+ const char *word_op, const char *doubleword_op,
+ HOST_WIDE_INT base_offset)
{
int regno;
@@ -7181,9 +7817,7 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op,
/* Set up the stack and frame (if desired) for the function. */
static void
-sparc_flat_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_flat_function_prologue (FILE *file, HOST_WIDE_INT size)
{
const char *sp_str = reg_names[STACK_POINTER_REGNUM];
unsigned long gmask = current_frame_info.gmask;
@@ -7192,7 +7826,8 @@ sparc_flat_function_prologue (file, size)
/* This is only for the human reader. */
fprintf (file, "\t%s#PROLOGUE# 0\n", ASM_COMMENT_START);
- fprintf (file, "\t%s# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n",
+ fprintf (file, "\t%s# vars= "HOST_WIDE_INT_PRINT_DEC", "
+ "regs= %d/%d, args= %d, extra= %d\n",
ASM_COMMENT_START,
current_frame_info.var_size,
current_frame_info.gp_reg_size / 4,
@@ -7223,7 +7858,7 @@ sparc_flat_function_prologue (file, size)
after %i7 so gdb won't have to look too far to find it. */
if (size > 0)
{
- unsigned int reg_offset = current_frame_info.reg_offset;
+ int reg_offset = current_frame_info.reg_offset;
const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
static const char *const t1_str = "%g1";
@@ -7239,27 +7874,26 @@ sparc_flat_function_prologue (file, size)
the gdb folk first. */
/* Is the entire register save area offsettable from %sp? */
- if (reg_offset < 4096 - 64 * (unsigned) UNITS_PER_WORD)
+ if (reg_offset < 4096 - 64 * UNITS_PER_WORD)
{
if (size <= 4096)
{
- fprintf (file, "\tadd\t%s, %d, %s\n",
- sp_str, (int) -size, sp_str);
+ fprintf (file, "\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
fp_str, sp_str, reg_offset);
- fprintf (file, "\tsub\t%s, %d, %s\t%s# set up frame pointer\n",
- sp_str, (int) -size, fp_str, ASM_COMMENT_START);
+ fprintf (file, "\tsub\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s"
+ "\t%s# set up frame pointer\n",
+ sp_str, size, fp_str, ASM_COMMENT_START);
reg_offset += 4;
}
}
else
{
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
- fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ build_big_number (file, size, t1_str);
+ fprintf (file, "\tsub\t%s, %s, %s\n", sp_str, t1_str, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
@@ -7297,34 +7931,40 @@ sparc_flat_function_prologue (file, size)
else
{
/* Subtract %sp in two steps, but make sure there is always a
- 64 byte register save area, and %sp is properly aligned. */
+ 64-byte register save area, and %sp is properly aligned. */
+
/* Amount to decrement %sp by, the first time. */
- unsigned HOST_WIDE_INT size1 = ((size - reg_offset + 64) + 15) & -16;
- /* Offset to register save area from %sp. */
- unsigned HOST_WIDE_INT offset = size1 - (size - reg_offset);
+ HOST_WIDE_INT size1 = ((size - reg_offset + 64) + 15) & -16;
+
+ /* Amount to decrement %sp by, the second time. */
+ HOST_WIDE_INT size2 = size - size1;
+
+ /* Offset to register save area from %sp after first decrement. */
+ int offset = (int)(size1 - (size - reg_offset));
if (size1 <= 4096)
{
- fprintf (file, "\tadd\t%s, %d, %s\n",
- sp_str, (int) -size1, sp_str);
+ fprintf (file, "\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size1, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
- fprintf (file, "\tst\t%s, [%s+%d]\n\tsub\t%s, %d, %s\t%s# set up frame pointer\n",
- fp_str, sp_str, (int) offset, sp_str, (int) -size1,
+ fprintf (file, "\tst\t%s, [%s+%d]\n"
+ "\tsub\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s"
+ "\t%s# set up frame pointer\n",
+ fp_str, sp_str, offset, sp_str, size1,
fp_str, ASM_COMMENT_START);
offset += 4;
}
}
else
{
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size1);
- fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ build_big_number (file, size1, t1_str);
+ fprintf (file, "\tsub\t%s, %s, %s\n", sp_str, t1_str, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
- fprintf (file, "\tst\t%s, [%s+%d]\n\tadd\t%s, %s, %s\t%s# set up frame pointer\n",
- fp_str, sp_str, (int) offset, sp_str, t1_str,
+ fprintf (file, "\tst\t%s, [%s+%d]\n"
+ "\tadd\t%s, %s, %s\t%s# set up frame pointer\n",
+ fp_str, sp_str, offset, sp_str, t1_str,
fp_str, ASM_COMMENT_START);
offset += 4;
}
@@ -7344,7 +7984,7 @@ sparc_flat_function_prologue (file, size)
if (gmask & RETURN_ADDR_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
- reg_names[RETURN_ADDR_REGNUM], sp_str, (int) offset);
+ reg_names[RETURN_ADDR_REGNUM], sp_str, offset);
if (dwarf2out_do_frame ())
/* offset - size1 == reg_offset - size
if reg_offset were updated above like offset. */
@@ -7355,10 +7995,14 @@ sparc_flat_function_prologue (file, size)
gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"st", "std", -size1);
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size - size1);
- fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ if (size2 <= 4096)
+ fprintf (file, "\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size2, sp_str);
+ else
+ {
+ build_big_number (file, size2, t1_str);
+ fprintf (file, "\tsub\t%s, %s, %s\n", sp_str, t1_str, sp_str);
+ }
if (dwarf2out_do_frame ())
if (! (gmask & HARD_FRAME_POINTER_MASK))
dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, size);
@@ -7372,9 +8016,7 @@ sparc_flat_function_prologue (file, size)
and regs. */
static void
-sparc_flat_function_epilogue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_flat_function_epilogue (FILE *file, HOST_WIDE_INT size)
{
rtx epilogue_delay = current_function_epilogue_delay_list;
int noepilogue = FALSE;
@@ -7406,8 +8048,8 @@ sparc_flat_function_epilogue (file, size)
if (!noepilogue)
{
- unsigned HOST_WIDE_INT reg_offset = current_frame_info.reg_offset;
- unsigned HOST_WIDE_INT size1;
+ int reg_offset = current_frame_info.reg_offset;
+ int reg_offset1;
const char *const sp_str = reg_names[STACK_POINTER_REGNUM];
const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
static const char *const t1_str = "%g1";
@@ -7416,41 +8058,43 @@ sparc_flat_function_epilogue (file, size)
slots for most of the loads, also see if we can fill the final
delay slot if not otherwise filled by the reload sequence. */
- if (size > 4095)
- {
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
- fprintf (file, ", %s\n", t1_str);
- }
+ if (size > 4096)
+ build_big_number (file, size, t1_str);
if (frame_pointer_needed)
{
- if (size > 4095)
+ if (size > 4096)
fprintf (file,"\tsub\t%s, %s, %s\t\t%s# sp not trusted here\n",
fp_str, t1_str, sp_str, ASM_COMMENT_START);
else
- fprintf (file,"\tsub\t%s, %d, %s\t\t%s# sp not trusted here\n",
- fp_str, (int) size, sp_str, ASM_COMMENT_START);
+ fprintf (file,"\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s"
+ "\t\t%s# sp not trusted here\n",
+ fp_str, size, sp_str, ASM_COMMENT_START);
}
/* Is the entire register save area offsettable from %sp? */
- if (reg_offset < 4096 - 64 * (unsigned) UNITS_PER_WORD)
+ if (reg_offset < 4096 - 64 * UNITS_PER_WORD)
{
- size1 = 0;
+ reg_offset1 = 0;
}
else
{
/* Restore %sp in two steps, but make sure there is always a
- 64 byte register save area, and %sp is properly aligned. */
+ 64-byte register save area, and %sp is properly aligned. */
+
/* Amount to increment %sp by, the first time. */
- size1 = ((reg_offset - 64 - 16) + 15) & -16;
+ reg_offset1 = ((reg_offset - 64 - 16) + 15) & -16;
+
/* Offset to register save area from %sp. */
- reg_offset = size1 - reg_offset;
+ reg_offset = reg_offset1 - reg_offset;
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size1);
- fprintf (file, ", %s\n\tadd\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ if (reg_offset1 > 4096)
+ {
+ build_big_number (file, reg_offset1, t1_str);
+ fprintf (file, "\tadd\t%s, %s, %s\n", sp_str, t1_str, sp_str);
+ }
+ else
+ fprintf (file, "\tsub\t%s, -%d, %s\n", sp_str, reg_offset1, sp_str);
}
/* We must restore the frame pointer and return address reg first
@@ -7458,13 +8102,13 @@ sparc_flat_function_epilogue (file, size)
if (current_frame_info.gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tld\t[%s+%d], %s\n",
- sp_str, (int) reg_offset, fp_str);
+ sp_str, reg_offset, fp_str);
reg_offset += 4;
}
if (current_frame_info.gmask & RETURN_ADDR_MASK)
{
fprintf (file, "\tld\t[%s+%d], %s\n",
- sp_str, (int) reg_offset, reg_names[RETURN_ADDR_REGNUM]);
+ sp_str, reg_offset, reg_names[RETURN_ADDR_REGNUM]);
reg_offset += 4;
}
@@ -7476,15 +8120,11 @@ sparc_flat_function_epilogue (file, size)
/* If we had to increment %sp in two steps, record it so the second
restoration in the epilogue finishes up. */
- if (size1 > 0)
+ if (reg_offset1 > 0)
{
- size -= size1;
- if (size > 4095)
- {
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
- fprintf (file, ", %s\n", t1_str);
- }
+ size -= reg_offset1;
+ if (size > 4096)
+ build_big_number (file, size, t1_str);
}
if (current_function_returns_struct)
@@ -7501,14 +8141,15 @@ sparc_flat_function_epilogue (file, size)
{
if (size)
abort ();
- final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
+ final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1, NULL);
}
- else if (size > 4095)
+ else if (size > 4096)
fprintf (file, "\tadd\t%s, %s, %s\n", sp_str, t1_str, sp_str);
else if (size > 0)
- fprintf (file, "\tadd\t%s, %d, %s\n", sp_str, (int) size, sp_str);
+ fprintf (file, "\tsub\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size, sp_str);
else
fprintf (file, "\tnop\n");
@@ -7526,7 +8167,7 @@ sparc_flat_function_epilogue (file, size)
or the only register saved is the return register. */
int
-sparc_flat_epilogue_delay_slots ()
+sparc_flat_epilogue_delay_slots (void)
{
if (!current_frame_info.initialized)
(void) sparc_flat_compute_frame_size (get_frame_size ());
@@ -7542,9 +8183,7 @@ sparc_flat_epilogue_delay_slots ()
pointer is OK. */
int
-sparc_flat_eligible_for_epilogue_delay (trial, slot)
- rtx trial;
- int slot ATTRIBUTE_UNUSED;
+sparc_flat_eligible_for_epilogue_delay (rtx trial, int slot ATTRIBUTE_UNUSED)
{
rtx pat = PATTERN (trial);
@@ -7562,11 +8201,7 @@ sparc_flat_eligible_for_epilogue_delay (trial, slot)
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
static int
-supersparc_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
+supersparc_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
enum attr_type insn_type;
@@ -7627,11 +8262,7 @@ supersparc_adjust_cost (insn, link, dep_insn, cost)
}
static int
-hypersparc_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
+hypersparc_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
enum attr_type insn_type, dep_type;
rtx pat = PATTERN(insn);
@@ -7708,11 +8339,7 @@ hypersparc_adjust_cost (insn, link, dep_insn, cost)
}
static int
-sparc_adjust_cost(insn, link, dep, cost)
- rtx insn;
- rtx link;
- rtx dep;
- int cost;
+sparc_adjust_cost(rtx insn, rtx link, rtx dep, int cost)
{
switch (sparc_cpu)
{
@@ -7730,15 +8357,14 @@ sparc_adjust_cost(insn, link, dep, cost)
}
static void
-sparc_sched_init (dump, sched_verbose, max_ready)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- int max_ready ATTRIBUTE_UNUSED;
+sparc_sched_init (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ int max_ready ATTRIBUTE_UNUSED)
{
}
static int
-sparc_use_dfa_pipeline_interface ()
+sparc_use_dfa_pipeline_interface (void)
{
if ((1 << sparc_cpu) &
((1 << PROCESSOR_ULTRASPARC) | (1 << PROCESSOR_CYPRESS) |
@@ -7750,7 +8376,7 @@ sparc_use_dfa_pipeline_interface ()
}
static int
-sparc_use_sched_lookahead ()
+sparc_use_sched_lookahead (void)
{
if (sparc_cpu == PROCESSOR_ULTRASPARC
|| sparc_cpu == PROCESSOR_ULTRASPARC3)
@@ -7763,7 +8389,7 @@ sparc_use_sched_lookahead ()
}
static int
-sparc_issue_rate ()
+sparc_issue_rate (void)
{
switch (sparc_cpu)
{
@@ -7784,8 +8410,7 @@ sparc_issue_rate ()
}
static int
-set_extends (insn)
- rtx insn;
+set_extends (rtx insn)
{
register rtx pat = PATTERN (insn);
@@ -7852,9 +8477,7 @@ static GTY(()) rtx sparc_addr_diff_list;
static GTY(()) rtx sparc_addr_list;
void
-sparc_defer_case_vector (lab, vec, diff)
- rtx lab, vec;
- int diff;
+sparc_defer_case_vector (rtx lab, rtx vec, int diff)
{
vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
if (diff)
@@ -7865,8 +8488,7 @@ sparc_defer_case_vector (lab, vec, diff)
}
static void
-sparc_output_addr_vec (vec)
- rtx vec;
+sparc_output_addr_vec (rtx vec)
{
rtx lab = XEXP (vec, 0), body = XEXP (vec, 1);
int idx, vlen = XVECLEN (body, 0);
@@ -7879,7 +8501,7 @@ sparc_output_addr_vec (vec)
ASM_OUTPUT_CASE_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab),
NEXT_INSN (lab));
#else
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+ (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
#endif
for (idx = 0; idx < vlen; idx++)
@@ -7894,8 +8516,7 @@ sparc_output_addr_vec (vec)
}
static void
-sparc_output_addr_diff_vec (vec)
- rtx vec;
+sparc_output_addr_diff_vec (rtx vec)
{
rtx lab = XEXP (vec, 0), body = XEXP (vec, 1);
rtx base = XEXP (XEXP (body, 0), 0);
@@ -7909,7 +8530,7 @@ sparc_output_addr_diff_vec (vec)
ASM_OUTPUT_CASE_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab),
NEXT_INSN (lab));
#else
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+ (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
#endif
for (idx = 0; idx < vlen; idx++)
@@ -7927,7 +8548,7 @@ sparc_output_addr_diff_vec (vec)
}
static void
-sparc_output_deferred_case_vectors ()
+sparc_output_deferred_case_vectors (void)
{
rtx t;
int align;
@@ -7955,8 +8576,7 @@ sparc_output_deferred_case_vectors ()
unknown. Return 1 if the high bits are zero, -1 if the register is
sign extended. */
int
-sparc_check_64 (x, insn)
- rtx x, insn;
+sparc_check_64 (rtx x, rtx insn)
{
/* If a register is set only once it is safe to ignore insns this
code does not know how to handle. The loop will either recognize
@@ -8016,10 +8636,7 @@ sparc_check_64 (x, insn)
/* Returns assembly code to perform a DImode shift using
a 64-bit global or out register on SPARC-V8+. */
char *
-sparc_v8plus_shift (operands, insn, opcode)
- rtx *operands;
- rtx insn;
- const char *opcode;
+sparc_v8plus_shift (rtx *operands, rtx insn, const char *opcode)
{
static char asm_code[60];
@@ -8056,8 +8673,7 @@ sparc_v8plus_shift (operands, insn, opcode)
for profiling a function entry. */
void
-sparc_profile_hook (labelno)
- int labelno;
+sparc_profile_hook (int labelno)
{
char buf[32];
rtx lab, fun;
@@ -8071,9 +8687,7 @@ sparc_profile_hook (labelno)
#ifdef OBJECT_FORMAT_ELF
static void
-sparc_elf_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+sparc_elf_asm_named_section (const char *name, unsigned int flags)
{
if (flags & SECTION_MERGE)
{
@@ -8089,6 +8703,8 @@ sparc_elf_asm_named_section (name, flags)
fputs (",#alloc", asm_out_file);
if (flags & SECTION_WRITE)
fputs (",#write", asm_out_file);
+ if (flags & SECTION_TLS)
+ fputs (",#tls", asm_out_file);
if (flags & SECTION_CODE)
fputs (",#execinstr", asm_out_file);
@@ -8098,15 +8714,133 @@ sparc_elf_asm_named_section (name, flags)
}
#endif /* OBJECT_FORMAT_ELF */
+/* We do not allow sibling calls if -mflat, nor
+ we do not allow indirect calls to be optimized into sibling calls.
+
+ Also, on sparc 32-bit we cannot emit a sibling call when the
+ current function returns a structure. This is because the "unimp
+ after call" convention would cause the callee to return to the
+ wrong place. The generic code already disallows cases where the
+ function being called returns a structure.
+
+ It may seem strange how this last case could occur. Usually there
+ is code after the call which jumps to epilogue code which dumps the
+ return value into the struct return area. That ought to invalidate
+ the sibling call right? Well, in the c++ case we can end up passing
+ the pointer to the struct return area to a constructor (which returns
+ void) and then nothing else happens. Such a sibling call would look
+ valid without the added check here. */
+static bool
+sparc_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+{
+ return (decl
+ && ! TARGET_FLAT
+ && (TARGET_ARCH64 || ! current_function_returns_struct));
+}
+
+/* libfunc renaming. */
+#include "config/gofast.h"
+
+static void
+sparc_init_libfuncs (void)
+{
+ if (TARGET_ARCH32)
+ {
+ /* Use the subroutines that Sun's library provides for integer
+ multiply and divide. The `*' prevents an underscore from
+ being prepended by the compiler. .umul is a little faster
+ than .mul. */
+ set_optab_libfunc (smul_optab, SImode, "*.umul");
+ set_optab_libfunc (sdiv_optab, SImode, "*.div");
+ set_optab_libfunc (udiv_optab, SImode, "*.udiv");
+ set_optab_libfunc (smod_optab, SImode, "*.rem");
+ set_optab_libfunc (umod_optab, SImode, "*.urem");
+
+ /* TFmode arithmetic. These names are part of the SPARC 32bit ABI. */
+ set_optab_libfunc (add_optab, TFmode, "_Q_add");
+ set_optab_libfunc (sub_optab, TFmode, "_Q_sub");
+ set_optab_libfunc (neg_optab, TFmode, "_Q_neg");
+ set_optab_libfunc (smul_optab, TFmode, "_Q_mul");
+ set_optab_libfunc (sdiv_optab, TFmode, "_Q_div");
+
+ /* We can define the TFmode sqrt optab only if TARGET_FPU. This
+ is because with soft-float, the SFmode and DFmode sqrt
+ instructions will be absent, and the compiler will notice and
+ try to use the TFmode sqrt instruction for calls to the
+ builtin function sqrt, but this fails. */
+ if (TARGET_FPU)
+ set_optab_libfunc (sqrt_optab, TFmode, "_Q_sqrt");
+
+ set_optab_libfunc (eq_optab, TFmode, "_Q_feq");
+ set_optab_libfunc (ne_optab, TFmode, "_Q_fne");
+ set_optab_libfunc (gt_optab, TFmode, "_Q_fgt");
+ set_optab_libfunc (ge_optab, TFmode, "_Q_fge");
+ set_optab_libfunc (lt_optab, TFmode, "_Q_flt");
+ set_optab_libfunc (le_optab, TFmode, "_Q_fle");
+
+ set_conv_libfunc (sext_optab, TFmode, SFmode, "_Q_stoq");
+ set_conv_libfunc (sext_optab, TFmode, DFmode, "_Q_dtoq");
+ set_conv_libfunc (trunc_optab, SFmode, TFmode, "_Q_qtos");
+ set_conv_libfunc (trunc_optab, DFmode, TFmode, "_Q_qtod");
+
+ set_conv_libfunc (sfix_optab, SImode, TFmode, "_Q_qtoi");
+ set_conv_libfunc (ufix_optab, SImode, TFmode, "_Q_qtou");
+ set_conv_libfunc (sfloat_optab, TFmode, SImode, "_Q_itoq");
+
+ if (DITF_CONVERSION_LIBFUNCS)
+ {
+ set_conv_libfunc (sfix_optab, DImode, TFmode, "_Q_qtoll");
+ set_conv_libfunc (ufix_optab, DImode, TFmode, "_Q_qtoull");
+ set_conv_libfunc (sfloat_optab, TFmode, DImode, "_Q_lltoq");
+ }
+
+ if (SUN_CONVERSION_LIBFUNCS)
+ {
+ set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftoll");
+ set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoull");
+ set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtoll");
+ set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoull");
+ }
+ }
+ if (TARGET_ARCH64)
+ {
+ /* In the SPARC 64bit ABI, SImode multiply and divide functions
+ do not exist in the library. Make sure the compiler does not
+ emit calls to them by accident. (It should always use the
+ hardware instructions.) */
+ set_optab_libfunc (smul_optab, SImode, 0);
+ 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);
+
+ if (SUN_INTEGER_MULTIPLY_64)
+ {
+ set_optab_libfunc (smul_optab, DImode, "__mul64");
+ set_optab_libfunc (sdiv_optab, DImode, "__div64");
+ set_optab_libfunc (udiv_optab, DImode, "__udiv64");
+ set_optab_libfunc (smod_optab, DImode, "__rem64");
+ set_optab_libfunc (umod_optab, DImode, "__urem64");
+ }
+
+ if (SUN_CONVERSION_LIBFUNCS)
+ {
+ set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftol");
+ set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoul");
+ set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtol");
+ set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoul");
+ }
+ }
+
+ gofast_maybe_init_libfuncs ();
+}
+
/* ??? Similar to the standard section selection, but force reloc-y-ness
if SUNOS4_SHARED_LIBRARIES. Unclear why this helps (as opposed to
pretending PIC always on), but that's what the old code did. */
static void
-sparc_aout_select_section (t, reloc, align)
- tree t;
- int reloc;
- unsigned HOST_WIDE_INT align;
+sparc_aout_select_section (tree t, int reloc, unsigned HOST_WIDE_INT align)
{
default_select_section (t, reloc | SUNOS4_SHARED_LIBRARIES, align);
}
@@ -8115,10 +8849,8 @@ sparc_aout_select_section (t, reloc, align)
that offers. */
static void
-sparc_aout_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+sparc_aout_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
if (align <= MAX_TEXT_ALIGN
&& ! (flag_pic && (symbolic_operand (x, mode)
@@ -8129,10 +8861,7 @@ sparc_aout_select_rtx_section (mode, x, align)
}
int
-sparc_extra_constraint_check (op, c, strict)
- rtx op;
- int c;
- int strict;
+sparc_extra_constraint_check (rtx op, int c, int strict)
{
int reload_ok_mem;
@@ -8194,10 +8923,8 @@ sparc_extra_constraint_check (op, c, strict)
??? scheduler description. Some day, teach genautomata to output
??? the latencies and then CSE will just use that. */
-int
-sparc_rtx_costs (x, code, outer_code)
- rtx x;
- enum rtx_code code, outer_code;
+static bool
+sparc_rtx_costs (rtx x, int code, int outer_code, int *total)
{
switch (code)
{
@@ -8211,50 +8938,61 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
}
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case SQRT:
switch (sparc_cpu)
{
case PROCESSOR_ULTRASPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (13);
+ *total = COSTS_N_INSNS (13);
else
- return COSTS_N_INSNS (23);
+ *total = COSTS_N_INSNS (23);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (20);
+ *total = COSTS_N_INSNS (20);
else
- return COSTS_N_INSNS (29);
+ *total = COSTS_N_INSNS (29);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (12);
+ *total = COSTS_N_INSNS (12);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (63);
+ *total = COSTS_N_INSNS (63);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
- return COSTS_N_INSNS (17);
+ *total = COSTS_N_INSNS (17);
+ return true;
default:
- return COSTS_N_INSNS (30);
+ *total = COSTS_N_INSNS (30);
+ return true;
}
case COMPARE:
@@ -8264,18 +9002,22 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
}
@@ -8283,7 +9025,8 @@ sparc_rtx_costs (x, code, outer_code)
??? all UltraSPARC processors because the result
??? can be bypassed to a branch in the same group. */
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case MULT:
if (FLOAT_MODE_P (GET_MODE (x)))
@@ -8292,20 +9035,25 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (7);
+ *total = COSTS_N_INSNS (7);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
default:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
}
}
@@ -8342,20 +9090,28 @@ sparc_rtx_costs (x, code, outer_code)
Since we do not play any such tricks currently the
safest thing to do is report the worst case latency. */
if (sparc_cpu == PROCESSOR_ULTRASPARC)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (34) : COSTS_N_INSNS (19));
+ {
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (34) : COSTS_N_INSNS (19));
+ return true;
+ }
/* Multiply latency on Ultra-III, fortunately, is constant. */
if (sparc_cpu == PROCESSOR_ULTRASPARC3)
- return COSTS_N_INSNS (6);
+ {
+ *total = COSTS_N_INSNS (6);
+ return true;
+ }
if (sparc_cpu == PROCESSOR_HYPERSPARC
|| sparc_cpu == PROCESSOR_SPARCLITE86X)
- return COSTS_N_INSNS (17);
+ {
+ *total = COSTS_N_INSNS (17);
+ return true;
+ }
- return (TARGET_HARD_MUL
- ? COSTS_N_INSNS (5)
- : COSTS_N_INSNS (25));
+ *total = (TARGET_HARD_MUL ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25));
+ return true;
case DIV:
case UDIV:
@@ -8367,57 +9123,67 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (13);
+ *total = COSTS_N_INSNS (13);
else
- return COSTS_N_INSNS (23);
+ *total = COSTS_N_INSNS (23);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (17);
+ *total = COSTS_N_INSNS (17);
else
- return COSTS_N_INSNS (20);
+ *total = COSTS_N_INSNS (20);
+ return true;
case PROCESSOR_SUPERSPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (6);
+ *total = COSTS_N_INSNS (6);
else
- return COSTS_N_INSNS (9);
+ *total = COSTS_N_INSNS (9);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (8);
+ *total = COSTS_N_INSNS (8);
else
- return COSTS_N_INSNS (12);
+ *total = COSTS_N_INSNS (12);
+ return true;
default:
- return COSTS_N_INSNS (7);
+ *total = COSTS_N_INSNS (7);
+ return true;
}
}
if (sparc_cpu == PROCESSOR_ULTRASPARC)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (68) : COSTS_N_INSNS (37));
- if (sparc_cpu == PROCESSOR_ULTRASPARC3)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (71) : COSTS_N_INSNS (40));
- return COSTS_N_INSNS (25);
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (68) : COSTS_N_INSNS (37));
+ else if (sparc_cpu == PROCESSOR_ULTRASPARC3)
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (71) : COSTS_N_INSNS (40));
+ else
+ *total = COSTS_N_INSNS (25);
+ return true;
case IF_THEN_ELSE:
/* Conditional moves. */
switch (sparc_cpu)
{
case PROCESSOR_ULTRASPARC:
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (FLOAT_MODE_P (GET_MODE (x)))
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
case MEM:
@@ -8428,9 +9194,10 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
if (outer_code == ZERO_EXTEND)
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (outer_code == ZERO_EXTEND)
@@ -8438,112 +9205,110 @@ sparc_rtx_costs (x, code, outer_code)
if (GET_MODE (x) == QImode
|| GET_MODE (x) == HImode
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
}
else
{
/* This handles sign extension (3 cycles)
and everything else (2 cycles). */
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
}
+ return true;
case PROCESSOR_SUPERSPARC:
if (FLOAT_MODE_P (GET_MODE (x))
|| outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (0);
+ *total = COSTS_N_INSNS (0);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case PROCESSOR_TSC701:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
else
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (0);
+ *total = COSTS_N_INSNS (0);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
case CONST_INT:
if (INTVAL (x) < 0x1000 && INTVAL (x) >= -0x1000)
- return 0;
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
- /* fallthru */
case HIGH:
- return 2;
+ *total = 2;
+ return true;
case CONST:
case LABEL_REF:
case SYMBOL_REF:
- return 4;
+ *total = 4;
+ return true;
case CONST_DOUBLE:
- if (GET_MODE (x) == DImode)
- if ((XINT (x, 3) == 0
- && (unsigned) XINT (x, 2) < 0x1000)
- || (XINT (x, 3) == -1
- && XINT (x, 2) < 0
- && XINT (x, 2) >= -0x1000))
- return 0;
- return 8;
+ if (GET_MODE (x) == DImode
+ && ((XINT (x, 3) == 0
+ && (unsigned HOST_WIDE_INT) XINT (x, 2) < 0x1000)
+ || (XINT (x, 3) == -1
+ && XINT (x, 2) < 0
+ && XINT (x, 2) >= -0x1000)))
+ *total = 0;
+ else
+ *total = 8;
+ return true;
default:
- abort();
- };
-}
-
-/* If we are referencing a function make the SYMBOL_REF special. In
- the Embedded Medium/Anywhere code model, %g4 points to the data
- segment so we must not add it to function addresses. */
-
-static void
-sparc_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
-{
- if (TARGET_CM_EMBMEDANY && TREE_CODE (decl) == FUNCTION_DECL)
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+ return false;
+ }
}
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
static void
-sparc_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
- FILE *file;
- tree thunk_fndecl ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
+sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ tree function)
{
rtx this, insn, funexp, delta_rtx, tmp;
reload_completed = 1;
+ epilogue_completed = 1;
no_new_pseudos = 1;
current_function_uses_only_leaf_regs = 1;
- emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+ emit_note (NOTE_INSN_PROLOGUE_END);
/* Find the "this" pointer. Normally in %o0, but in ARCH64 if the function
returns a structure, the structure return pointer is there instead. */
- if (TARGET_ARCH64 && aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+ if (TARGET_ARCH64 && aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST + 1);
else
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST);
@@ -8554,10 +9319,17 @@ sparc_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
if (!SPARC_SIMM13_P (delta))
{
rtx scratch = gen_rtx_REG (Pmode, 1);
- if (TARGET_ARCH64)
- sparc_emit_set_const64 (scratch, delta_rtx);
+
+ if (input_operand (delta_rtx, GET_MODE (scratch)))
+ emit_insn (gen_rtx_SET (VOIDmode, scratch, delta_rtx));
else
- sparc_emit_set_const32 (scratch, delta_rtx);
+ {
+ if (TARGET_ARCH64)
+ sparc_emit_set_const64 (scratch, delta_rtx);
+ else
+ sparc_emit_set_const32 (scratch, delta_rtx);
+ }
+
delta_rtx = scratch;
}
@@ -8581,13 +9353,79 @@ sparc_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
insn = get_insns ();
+ insn_locators_initialize ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
final_end_function ();
reload_completed = 0;
+ epilogue_completed = 0;
no_new_pseudos = 0;
}
+/* How to allocate a 'struct machine_function'. */
+
+static struct machine_function *
+sparc_init_machine_status (void)
+{
+ return ggc_alloc_cleared (sizeof (struct machine_function));
+}
+
+/* Locate some local-dynamic symbol still in use by this function
+ so that we can print its name in local-dynamic base patterns. */
+
+static const char *
+get_some_local_dynamic_name (void)
+{
+ rtx insn;
+
+ if (cfun->machine->some_ld_name)
+ return cfun->machine->some_ld_name;
+
+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
+ return cfun->machine->some_ld_name;
+
+ abort ();
+}
+
+static int
+get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
+{
+ rtx x = *px;
+
+ if (x
+ && GET_CODE (x) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ cfun->machine->some_ld_name = XSTR (x, 0);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+sparc_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ switch (size)
+ {
+ case 4:
+ fputs ("\t.word\t%r_tls_dtpoff32(", file);
+ break;
+ case 8:
+ fputs ("\t.xword\t%r_tls_dtpoff64(", file);
+ break;
+ default:
+ abort ();
+ }
+ output_addr_const (file, x);
+ fputs (")", file);
+}
+
#include "gt-sparc.h"
diff --git a/contrib/gcc/config/sparc/sparc.h b/contrib/gcc/config/sparc/sparc.h
index 7c6a7fd..3202359 100644
--- a/contrib/gcc/config/sparc/sparc.h
+++ b/contrib/gcc/config/sparc/sparc.h
@@ -1,30 +1,50 @@
/* Definitions of target machine for GNU compiler, for Sun SPARC.
Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
- 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+ 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Note that some other tm.h files include this one and then override
whatever definitions are necessary. */
+/* Target CPU builtins. FIXME: Defining sparc is for the benefit of
+ Solaris only; otherwise just define __sparc__. Sadly the headers
+ are such a mess there is no Solaris-specific header. */
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ if (TARGET_64BIT) \
+ { \
+ builtin_assert ("cpu=sparc64"); \
+ builtin_assert ("machine=sparc64"); \
+ } \
+ else \
+ { \
+ builtin_assert ("cpu=sparc"); \
+ builtin_assert ("machine=sparc"); \
+ } \
+ } \
+ while (0)
+
/* Specify this in a cover file to provide bi-architecture (32/64) support. */
/* #define SPARC_BI_ARCH */
@@ -49,35 +69,41 @@ Boston, MA 02111-1307, USA. */
#endif /* IN_LIBGCC2 */
#define TARGET_ARCH64 (! TARGET_ARCH32)
-/* Code model selection.
- -mcmodel is used to select the v9 code model.
- Different code models aren't supported for v7/8 code.
-
- TARGET_CM_32: 32 bit address space, top 32 bits = 0,
- pointers are 32 bits. Note that this isn't intended
- to imply a v7/8 abi.
-
- TARGET_CM_MEDLOW: 32 bit address space, top 32 bits = 0,
- avoid generating %uhi and %ulo terms,
- pointers are 64 bits.
-
- TARGET_CM_MEDMID: 64 bit address space.
- The executable must be in the low 16 TB of memory.
- This corresponds to the low 44 bits, and the %[hml]44
- relocs are used. The text segment has a maximum size
- of 31 bits.
-
- TARGET_CM_MEDANY: 64 bit address space.
- The text and data segments have a maximum size of 31
- bits and may be located anywhere. The maximum offset
- from any instruction to the label _GLOBAL_OFFSET_TABLE_
- is 31 bits.
-
- TARGET_CM_EMBMEDANY: 64 bit address space.
- The text and data segments have a maximum size of 31 bits
- and may be located anywhere. Register %g4 contains
- the start address of the data segment.
-*/
+/* Code model selection in 64-bit environment.
+
+ The machine mode used for addresses is 32-bit wide:
+
+ TARGET_CM_32: 32-bit address space.
+ It is the code model used when generating 32-bit code.
+
+ The machine mode used for addresses is 64-bit wide:
+
+ TARGET_CM_MEDLOW: 32-bit address space.
+ The executable must be in the low 32 bits of memory.
+ This avoids generating %uhi and %ulo terms. Programs
+ can be statically or dynamically linked.
+
+ TARGET_CM_MEDMID: 44-bit address space.
+ The executable must be in the low 44 bits of memory,
+ and the %[hml]44 terms are used. The text and data
+ segments have a maximum size of 2GB (31-bit span).
+ The maximum offset from any instruction to the label
+ _GLOBAL_OFFSET_TABLE_ is 2GB (31-bit span).
+
+ TARGET_CM_MEDANY: 64-bit address space.
+ The text and data segments have a maximum size of 2GB
+ (31-bit span) and may be located anywhere in memory.
+ The maximum offset from any instruction to the label
+ _GLOBAL_OFFSET_TABLE_ is 2GB (31-bit span).
+
+ TARGET_CM_EMBMEDANY: 64-bit address space.
+ The text and data segments have a maximum size of 2GB
+ (31-bit span) and may be located anywhere in memory.
+ The global register %g4 contains the start address of
+ the data segment. Programs are statically linked and
+ PIC is not supported.
+
+ Different code models are not supported in 32-bit environment. */
enum cmodel {
CM_32,
@@ -239,15 +265,8 @@ extern enum cmodel sparc_cmodel;
%{mcpu=ultrasparc3:-D__sparc_v9__} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
"
-
-/* ??? The GCC_NEW_VARARGS macro is now obsolete, because gcc always uses
- the right varags.h file when bootstrapping. */
-/* ??? It's not clear what value we want to use for -Acpu/machine for
- sparc64 in 32 bit environments, so for now we only use `sparc64' in
- 64 bit environments. */
-
-#define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
-#define CPP_ARCH64_SPEC "-D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
+#define CPP_ARCH32_SPEC ""
+#define CPP_ARCH64_SPEC "-D__arch64__"
#define CPP_ARCH_DEFAULT_SPEC \
(DEFAULT_ARCH32_P ? CPP_ARCH32_SPEC : CPP_ARCH64_SPEC)
@@ -323,15 +342,17 @@ extern enum cmodel sparc_cmodel;
/* Special flags to the Sun-4 assembler when using pipe for input. */
#define ASM_SPEC "\
-%| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L} \
+%{R} %{!pg:%{!p:%{fpic|fPIC|fpie|fPIE:-k}}} %{keep-local-as-symbols:-L} \
%(asm_cpu) %(asm_relax)"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -630,17 +651,27 @@ extern enum processor_type sparc_cpu;
#define TARGET_OPTIONS \
{ \
{ "cpu=", &sparc_select[1].string, \
- N_("Use features of and schedule code for given CPU") }, \
+ N_("Use features of and schedule code for given CPU"), 0}, \
{ "tune=", &sparc_select[2].string, \
- N_("Schedule code for given CPU") }, \
+ N_("Schedule code for given CPU"), 0}, \
{ "cmodel=", &sparc_cmodel_string, \
- N_("Use given SPARC code model") }, \
+ N_("Use given SPARC code model"), 0}, \
SUBTARGET_OPTIONS \
}
/* This is meant to be redefined in target specific files. */
#define SUBTARGET_OPTIONS
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float, -msoft-float, -mfpu, or -mno-fpu
+ are specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+
/* sparc_select[0] is reserved for the default cpu. */
struct sparc_cpu_select
{
@@ -755,7 +786,13 @@ if (TARGET_ARCH64 \
#define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
+/* FIXME, this is wrong when TARGET_ARCH64 and TARGET_STACK_BIAS, because
+ then sp+2047 is 128-bit aligned so sp is really only byte-aligned. */
#define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64)
+/* Temporary hack until the FIXME above is fixed. This macro is used
+ only in pad_to_arg_alignment in function.c; see the comment there
+ for details about what it does. */
+#define SPARC_STACK_BOUNDARY_HACK (TARGET_ARCH64 && TARGET_STACK_BIAS)
/* ALIGN FRAMES on double word boundaries */
@@ -1018,7 +1055,7 @@ while (0)
: (GET_MODE_SIZE (MODE) + 3) / 4) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-/* Due to the ARCH64 descrepancy above we must override this next
+/* Due to the ARCH64 discrepancy above we must override this next
macro too. */
#define REGMODE_NATURAL_SIZE(MODE) \
((TARGET_ARCH64 && FLOAT_MODE_P (MODE)) ? 4 : UNITS_PER_WORD)
@@ -1126,8 +1163,7 @@ extern int sparc_mode_class[];
#define RETURN_IN_MEMORY(TYPE) \
(TARGET_ARCH32 \
? (TYPE_MODE (TYPE) == BLKmode \
- || TYPE_MODE (TYPE) == TFmode \
- || TYPE_MODE (TYPE) == TCmode) \
+ || TYPE_MODE (TYPE) == TFmode) \
: (TYPE_MODE (TYPE) == BLKmode \
&& (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 32))
@@ -1233,6 +1269,20 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
{-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \
{-1, -1, -1, 0x3f}} /* ALL_REGS */
+/* Defines invalid mode changes. Borrowed from pa64-regs.h.
+
+ SImode loads to floating-point registers are not zero-extended.
+ The definition for LOAD_EXTEND_OP specifies that integer loads
+ narrower than BITS_PER_WORD will be zero-extended. As a result,
+ we inhibit changes from SImode unless they are to a mode that is
+ identical in size. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (TARGET_ARCH64 \
+ && (FROM) == SImode \
+ && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
+
/* The same information, inverted:
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
@@ -1253,7 +1303,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
We know in this case that we will not end up with a leaf function.
- The register allocater is given the global and out registers first
+ The register allocator is given the global and out registers first
because these registers are call clobbered and thus less useful to
global register allocation.
@@ -1626,13 +1676,13 @@ extern char leaf_reg_remap[];
#define BASE_RETURN_VALUE_REG(MODE) \
(TARGET_ARCH64 \
? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \
- : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8))
+ : (TARGET_FPU && FLOAT_MODE_P (MODE) && (MODE) != TFmode ? 32 : 8))
#define BASE_OUTGOING_VALUE_REG(MODE) \
(TARGET_ARCH64 \
? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \
: TARGET_FLAT ? 8 : 24) \
- : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 \
+ : (TARGET_FPU && FLOAT_MODE_P (MODE) && (MODE) != TFmode ? 32\
: (TARGET_FLAT ? 8 : 24)))
#define BASE_PASSING_ARG_REG(MODE) \
@@ -1735,8 +1785,8 @@ struct sparc_args {
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
-init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (INDIRECT));
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
+init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
@@ -1935,27 +1985,6 @@ do { \
#define STRICT_ARGUMENT_NAMING TARGET_V9
-/* We do not allow sibling calls if -mflat, nor
- we do not allow indirect calls to be optimized into sibling calls.
-
- Also, on sparc 32-bit we cannot emit a sibling call when the
- current function returns a structure. This is because the "unimp
- after call" convention would cause the callee to return to the
- wrong place. The generic code already disallows cases where the
- function being called returns a structure.
-
- It may seem strange how this last case could occur. Usually there
- is code after the call which jumps to epilogue code which dumps the
- return value into the struct return area. That ought to invalidate
- the sibling call right? Well, in the c++ case we can end up passing
- the pointer to the struct return area to a constructor (which returns
- void) and then nothing else happens. Such a sibling call would look
- valid without the added check here. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) \
- (DECL \
- && ! TARGET_FLAT \
- && (TARGET_ARCH64 || ! current_function_returns_struct))
-
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */
#define SETUP_FRAME_ADDRESSES() \
@@ -2050,12 +2079,6 @@ do { \
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
-/* #define HAVE_PRE_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT 0 */
-
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@@ -2101,27 +2124,18 @@ do { \
When PIC, we do not accept an address that would require a scratch reg
to load into a register. */
-#define CONSTANT_ADDRESS_P(X) \
- (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
- || (GET_CODE (X) == CONST \
- && ! (flag_pic && pic_address_needs_scratch (X))))
+#define CONSTANT_ADDRESS_P(X) constant_address_p (X)
/* Define this, so that when PIC, reload won't try to reload invalid
addresses which require two reload registers. */
-#define LEGITIMATE_PIC_OPERAND_P(X) (! pic_address_needs_scratch (X))
+#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
/* Nonzero if the constant value X is a legitimate general operand.
Anything can be made to work except floating point constants.
If TARGET_VIS, 0.0 can be made to work as well. */
-#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode || \
- (TARGET_VIS && \
- (GET_MODE (X) == SFmode || GET_MODE (X) == DFmode || \
- GET_MODE (X) == TFmode) && \
- fp_zero_operand (X, GET_MODE (X))))
+#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@@ -2228,110 +2242,19 @@ do { \
#define RTX_OK_FOR_OLO10_P(X) \
(GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
+#ifdef REG_OK_STRICT
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ if (RTX_OK_FOR_BASE_P (X)) \
+{ \
+ if (legitimate_address_p (MODE, X, 1)) \
goto ADDR; \
- else if (GET_CODE (X) == PLUS) \
- { \
- register rtx op0 = XEXP (X, 0); \
- register rtx op1 = XEXP (X, 1); \
- if (flag_pic && op0 == pic_offset_table_rtx) \
- { \
- if (RTX_OK_FOR_BASE_P (op1)) \
- goto ADDR; \
- else if (flag_pic == 1 \
- && GET_CODE (op1) != REG \
- && GET_CODE (op1) != LO_SUM \
- && GET_CODE (op1) != MEM \
- && (! SYMBOLIC_CONST (op1) \
- || MODE == Pmode) \
- && (GET_CODE (op1) != CONST_INT \
- || SMALL_INT (op1))) \
- goto ADDR; \
- } \
- else if (RTX_OK_FOR_BASE_P (op0)) \
- { \
- if ((RTX_OK_FOR_INDEX_P (op1) \
- /* We prohibit REG + REG for TFmode when \
- there are no instructions which accept \
- REG+REG instructions. We do this \
- because REG+REG is not an offsetable \
- address. If we get the situation \
- in reload where source and destination \
- of a movtf pattern are both MEMs with \
- REG+REG address, then only one of them \
- gets converted to an offsetable \
- address. */ \
- && (MODE != TFmode \
- || (TARGET_FPU && TARGET_ARCH64 \
- && TARGET_V9 \
- && TARGET_HARD_QUAD)) \
- /* We prohibit REG + REG on ARCH32 if \
- not optimizing for DFmode/DImode \
- because then mem_min_alignment is \
- likely to be zero after reload and the \
- forced split would lack a matching \
- splitter pattern. */ \
- && (TARGET_ARCH64 || optimize \
- || (MODE != DFmode \
- && MODE != DImode))) \
- || RTX_OK_FOR_OFFSET_P (op1)) \
- goto ADDR; \
- } \
- else if (RTX_OK_FOR_BASE_P (op1)) \
- { \
- if ((RTX_OK_FOR_INDEX_P (op0) \
- /* See the previous comment. */ \
- && (MODE != TFmode \
- || (TARGET_FPU && TARGET_ARCH64 \
- && TARGET_V9 \
- && TARGET_HARD_QUAD)) \
- && (TARGET_ARCH64 || optimize \
- || (MODE != DFmode \
- && MODE != DImode))) \
- || RTX_OK_FOR_OFFSET_P (op0)) \
- goto ADDR; \
- } \
- else if (USE_AS_OFFSETABLE_LO10 \
- && GET_CODE (op0) == LO_SUM \
- && TARGET_ARCH64 \
- && ! TARGET_CM_MEDMID \
- && RTX_OK_FOR_OLO10_P (op1)) \
- { \
- register rtx op00 = XEXP (op0, 0); \
- register rtx op01 = XEXP (op0, 1); \
- if (RTX_OK_FOR_BASE_P (op00) \
- && CONSTANT_P (op01)) \
- goto ADDR; \
- } \
- else if (USE_AS_OFFSETABLE_LO10 \
- && GET_CODE (op1) == LO_SUM \
- && TARGET_ARCH64 \
- && ! TARGET_CM_MEDMID \
- && RTX_OK_FOR_OLO10_P (op0)) \
- { \
- register rtx op10 = XEXP (op1, 0); \
- register rtx op11 = XEXP (op1, 1); \
- if (RTX_OK_FOR_BASE_P (op10) \
- && CONSTANT_P (op11)) \
- goto ADDR; \
- } \
- } \
- else if (GET_CODE (X) == LO_SUM) \
- { \
- register rtx op0 = XEXP (X, 0); \
- register rtx op1 = XEXP (X, 1); \
- if (RTX_OK_FOR_BASE_P (op0) \
- && CONSTANT_P (op1) \
- /* We can't allow TFmode, because an offset \
- greater than or equal to the alignment (8) \
- may cause the LO_SUM to overflow if !v9. */\
- && (MODE != TFmode || TARGET_V9)) \
- goto ADDR; \
- } \
- else if (GET_CODE (X) == CONST_INT && SMALL_INT (X)) \
+}
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if (legitimate_address_p (MODE, X, 0)) \
goto ADDR; \
}
+#endif
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
@@ -2376,33 +2299,11 @@ do { \
/* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ rtx sparc_x = (X); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \
- force_operand (XEXP (X, 0), NULL_RTX)); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- force_operand (XEXP (X, 1), NULL_RTX)); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS) \
- (X) = gen_rtx_PLUS (Pmode, force_operand (XEXP (X, 0), NULL_RTX),\
- XEXP (X, 1)); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- force_operand (XEXP (X, 1), NULL_RTX)); \
- if (sparc_x != (X) && memory_address_p (MODE, X)) \
- goto WIN; \
- if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0); \
- else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- copy_to_mode_reg (Pmode, XEXP (X, 1))); \
- else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \
- copy_to_mode_reg (Pmode, XEXP (X, 0))); \
- else if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \
- || GET_CODE (X) == LABEL_REF) \
- (X) = copy_to_suggested_reg (X, NULL_RTX, Pmode); \
- if (memory_address_p (MODE, X)) \
- goto WIN; }
+{ \
+ (X) = legitimize_address (X, OLDX, MODE); \
+ if (memory_address_p (MODE, X)) \
+ goto WIN; \
+}
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
@@ -2491,11 +2392,6 @@ do { \
and maybe make use of that. */
#define SLOW_BYTE_ACCESS 1
-/* We assume that the store-condition-codes instructions store 0 for false
- and some other value for true. This is the value stored for true. */
-
-#define STORE_FLAG_VALUE 1
-
/* When a prototype says `char' or `short', really pass an `int'. */
#define PROMOTE_PROTOTYPES (TARGET_ARCH32)
@@ -2507,9 +2403,7 @@ do { \
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-/* Specify the machine mode that pointers have.
- After generation of rtl, the compiler makes no further distinction
- between pointers and any other objects of this machine mode. */
+/* Specify the machine mode used for addresses. */
#define Pmode (TARGET_ARCH64 ? DImode : SImode)
/* Generate calls to memcpy, memcmp and memset. */
@@ -2540,100 +2434,20 @@ do { \
/* alloca should avoid clobbering the old register save area. */
#define SETJMP_VIA_SAVE_AREA
-/* Define subroutines to call to handle multiply and divide.
- Use the subroutines that Sun's library provides.
- The `*' prevents an underscore from being prepended by the compiler. */
-
-#define DIVSI3_LIBCALL "*.div"
-#define UDIVSI3_LIBCALL "*.udiv"
-#define MODSI3_LIBCALL "*.rem"
-#define UMODSI3_LIBCALL "*.urem"
-/* .umul is a little faster than .mul. */
-#define MULSI3_LIBCALL "*.umul"
-
-/* Define library calls for quad FP operations. These are all part of the
- SPARC 32bit ABI. */
-#define ADDTF3_LIBCALL "_Q_add"
-#define SUBTF3_LIBCALL "_Q_sub"
-#define NEGTF2_LIBCALL "_Q_neg"
-#define MULTF3_LIBCALL "_Q_mul"
-#define DIVTF3_LIBCALL "_Q_div"
-#define FLOATSITF2_LIBCALL "_Q_itoq"
-#define FIX_TRUNCTFSI2_LIBCALL "_Q_qtoi"
-#define FIXUNS_TRUNCTFSI2_LIBCALL "_Q_qtou"
-#define EXTENDSFTF2_LIBCALL "_Q_stoq"
-#define TRUNCTFSF2_LIBCALL "_Q_qtos"
-#define EXTENDDFTF2_LIBCALL "_Q_dtoq"
-#define TRUNCTFDF2_LIBCALL "_Q_qtod"
-#define EQTF2_LIBCALL "_Q_feq"
-#define NETF2_LIBCALL "_Q_fne"
-#define GTTF2_LIBCALL "_Q_fgt"
-#define GETF2_LIBCALL "_Q_fge"
-#define LTTF2_LIBCALL "_Q_flt"
-#define LETF2_LIBCALL "_Q_fle"
+/* The _Q_* comparison libcalls return booleans. */
+#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
/* Assume by default that the _Qp_* 64-bit libcalls are implemented such
that the inputs are fully consumed before the output memory is clobbered. */
#define TARGET_BUGGY_QP_LIB 0
-/* We can define the TFmode sqrt optab only if TARGET_FPU. This is because
- with soft-float, the SFmode and DFmode sqrt instructions will be absent,
- and the compiler will notice and try to use the TFmode sqrt instruction
- for calls to the builtin function sqrt, but this fails. */
-#define INIT_TARGET_OPTABS \
- do { \
- if (TARGET_ARCH32) \
- { \
- add_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (ADDTF3_LIBCALL); \
- sub_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SUBTF3_LIBCALL); \
- neg_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (NEGTF2_LIBCALL); \
- smul_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (MULTF3_LIBCALL); \
- sdiv_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (DIVTF3_LIBCALL); \
- eqtf2_libfunc = init_one_libfunc (EQTF2_LIBCALL); \
- netf2_libfunc = init_one_libfunc (NETF2_LIBCALL); \
- gttf2_libfunc = init_one_libfunc (GTTF2_LIBCALL); \
- getf2_libfunc = init_one_libfunc (GETF2_LIBCALL); \
- lttf2_libfunc = init_one_libfunc (LTTF2_LIBCALL); \
- letf2_libfunc = init_one_libfunc (LETF2_LIBCALL); \
- trunctfsf2_libfunc = init_one_libfunc (TRUNCTFSF2_LIBCALL); \
- trunctfdf2_libfunc = init_one_libfunc (TRUNCTFDF2_LIBCALL); \
- extendsftf2_libfunc = init_one_libfunc (EXTENDSFTF2_LIBCALL); \
- extenddftf2_libfunc = init_one_libfunc (EXTENDDFTF2_LIBCALL); \
- floatsitf_libfunc = init_one_libfunc (FLOATSITF2_LIBCALL); \
- fixtfsi_libfunc = init_one_libfunc (FIX_TRUNCTFSI2_LIBCALL); \
- fixunstfsi_libfunc \
- = init_one_libfunc (FIXUNS_TRUNCTFSI2_LIBCALL); \
- if (TARGET_FPU) \
- sqrt_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc ("_Q_sqrt"); \
- } \
- if (TARGET_ARCH64) \
- { \
- /* In the SPARC 64bit ABI, these libfuncs do not exist in the \
- library. Make sure the compiler does not emit calls to them \
- by accident. */ \
- sdiv_optab->handlers[(int) SImode].libfunc = NULL; \
- udiv_optab->handlers[(int) SImode].libfunc = NULL; \
- smod_optab->handlers[(int) SImode].libfunc = NULL; \
- umod_optab->handlers[(int) SImode].libfunc = NULL; \
- smul_optab->handlers[(int) SImode].libfunc = NULL; \
- } \
- INIT_SUBTARGET_OPTABS; \
- } while (0)
-
-/* This is meant to be redefined in the host dependent files */
-#define INIT_SUBTARGET_OPTABS
+/* Assume by default that we do not have the Solaris-specific conversion
+ routines nor 64-bit integer multiply and divide routines. */
-/* Nonzero if a floating point comparison library call for
- mode MODE that will return a boolean value. Zero if one
- of the libgcc2 functions is used. */
-#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
+#define SUN_CONVERSION_LIBFUNCS 0
+#define DITF_CONVERSION_LIBFUNCS 0
+#define SUN_INTEGER_MULTIPLY_64 0
/* Compute extra cost of moving data between one register class
and another. */
@@ -2662,29 +2476,6 @@ do { \
: (sparc_cpu == PROCESSOR_ULTRASPARC3 \
? 9 : 3))
-/* The cases that RTX_COSTS handles. */
-
-#define RTX_COSTS_CASES \
-case PLUS: case MINUS: case ABS: case NEG: \
-case FLOAT: case UNSIGNED_FLOAT: \
-case FIX: case UNSIGNED_FIX: \
-case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
-case SQRT: \
-case COMPARE: case IF_THEN_ELSE: \
-case MEM: \
-case MULT: case DIV: case UDIV: case MOD: case UMOD: \
-case CONST_INT: case HIGH: case CONST: \
-case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- RTX_COSTS_CASES \
- return sparc_rtx_costs(X,CODE,OUTER_CODE);
-
-#define ADDRESS_COST(RTX) 1
-
#define PREFETCH_BLOCK \
((sparc_cpu == PROCESSOR_ULTRASPARC \
|| sparc_cpu == PROCESSOR_ULTRASPARC3) \
@@ -2698,10 +2489,6 @@ case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
/* Control the assembler format that we output. */
-/* Output at beginning of assembler file. */
-
-#define ASM_FILE_START(file)
-
/* A C string constant describing how to begin a comment in the target
assembler language. The compiler assumes that the comment will end at
the end of the line. */
@@ -2765,12 +2552,6 @@ case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
#define USER_LABEL_PREFIX "_"
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%d:\n", PREFIX, NUM)
-
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
@@ -2849,7 +2630,7 @@ do { \
fprintf (FILE, "\t.align %d,0x1000000\n", (1<<(LOG)))
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.skip %u\n", (SIZE))
+ fprintf (FILE, "\t.skip "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* This says how to output an assembler line
to define a global common symbol. */
@@ -2857,7 +2638,7 @@ do { \
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs ("\t.common ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u,\"bss\"\n", (SIZE)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",\"bss\"\n", (SIZE)))
/* This says how to output an assembler line to define a local common
symbol. */
@@ -2865,7 +2646,7 @@ do { \
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED) \
( fputs ("\t.reserve ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u,\"bss\",%u\n", \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",\"bss\",%u\n", \
(SIZE), ((ALIGNED) / BITS_PER_UNIT)))
/* A C statement (sans semicolon) to output to the stdio stream
@@ -2875,20 +2656,9 @@ do { \
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
- fputs (".globl ", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs ("\n", (FILE)); \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
#define IDENT_ASM_OP "\t.ident\t"
/* Output #ident as a .ident. */
@@ -2896,8 +2666,16 @@ do { \
#define ASM_OUTPUT_IDENT(FILE, NAME) \
fprintf (FILE, "%s\"%s\"\n", IDENT_ASM_OP, NAME);
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ sparc_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
- ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
+ ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' \
+ || (CHAR) == '(' || (CHAR) == '_' || (CHAR) == '&')
/* Print operand X (an rtx) in assembler syntax to file FILE.
CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
@@ -2984,6 +2762,14 @@ do { \
} \
}
+#ifdef HAVE_AS_TLS
+#define TARGET_TLS 1
+#else
+#define TARGET_TLS 0
+#endif
+#define TARGET_SUN_TLS TARGET_TLS
+#define TARGET_GNU_TLS 0
+
/* Define the codes that are matched by predicates in sparc.c. */
#define PREDICATE_CODES \
@@ -3030,8 +2816,13 @@ do { \
{"uns_arith_operand", {SUBREG, REG, CONST_INT}}, \
{"clobbered_register", {REG}}, \
{"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}}, \
+{"compare_operand", {SUBREG, REG, ZERO_EXTRACT}}, \
{"const64_operand", {CONST_INT, CONST_DOUBLE}}, \
-{"const64_high_operand", {CONST_INT, CONST_DOUBLE}},
+{"const64_high_operand", {CONST_INT, CONST_DOUBLE}}, \
+{"tgd_symbolic_operand", {SYMBOL_REF}}, \
+{"tld_symbolic_operand", {SYMBOL_REF}}, \
+{"tie_symbolic_operand", {SYMBOL_REF}}, \
+{"tle_symbolic_operand", {SYMBOL_REF}},
/* The number of Pmode words for the setjmp buffer. */
#define JMP_BUF_SIZE 12
diff --git a/contrib/gcc/config/sparc/sparc.md b/contrib/gcc/config/sparc/sparc.md
index b53013e..c7da780 100644
--- a/contrib/gcc/config/sparc/sparc.md
+++ b/contrib/gcc/config/sparc/sparc.md
@@ -1,24 +1,24 @@
-;; Machine description for SPARC chip for GNU C compiler
+;; Machine description for SPARC chip for GCC
;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Contributed by Michael Tiemann (tiemann@cygnus.com)
-;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
;; at Cygnus Support.
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -38,6 +38,13 @@
(UNSPEC_EMB_TEXTHI 14)
(UNSPEC_EMB_TEXTULO 15)
(UNSPEC_EMB_SETHM 18)
+
+ (UNSPEC_TLSGD 30)
+ (UNSPEC_TLSLDM 31)
+ (UNSPEC_TLSLDO 32)
+ (UNSPEC_TLSIE 33)
+ (UNSPEC_TLSLE 34)
+ (UNSPEC_TLSLD_BASE 35)
])
(define_constants
@@ -99,6 +106,7 @@
fpcmp,
fpmul,fpdivs,fpdivd,
fpsqrts,fpsqrtd,
+ fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
cmove,
ialuX,
multi,flushw,iflush,trap"
@@ -120,6 +128,8 @@
(symbol_ref "TARGET_FLAT != 0"))
;; Length (in # of insns).
+;; Beware that setting a length greater or equal to 3 for conditional branches
+;; has a side-effect (see output_cbranch and output_v9branch).
(define_attr "length" ""
(cond [(eq_attr "type" "uncond_branch,call,sibcall")
(if_then_else (eq_attr "empty_delay_slot" "true")
@@ -199,6 +209,9 @@
;; Attributes for instruction and branch scheduling
+(define_attr "tls_call_delay" "false,true"
+ (symbol_ref "tls_call_delay (insn)"))
+
(define_attr "in_call_delay" "false,true"
(cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
(const_string "false")
@@ -206,7 +219,8 @@
(if_then_else (eq_attr "length" "1")
(const_string "true")
(const_string "false"))]
- (if_then_else (eq_attr "length" "1")
+ (if_then_else (and (eq_attr "length" "1")
+ (eq_attr "tls_call_delay" "true"))
(const_string "true")
(const_string "false"))))
@@ -290,10 +304,13 @@
(define_expand "cmpsi"
[(set (reg:CC 100)
- (compare:CC (match_operand:SI 0 "register_operand" "")
+ (compare:CC (match_operand:SI 0 "compare_operand" "")
(match_operand:SI 1 "arith_operand" "")))]
""
{
+ if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
+ operands[0] = force_reg (SImode, operands[0]);
+
sparc_compare_op0 = operands[0];
sparc_compare_op1 = operands[1];
DONE;
@@ -301,10 +318,13 @@
(define_expand "cmpdi"
[(set (reg:CCX 100)
- (compare:CCX (match_operand:DI 0 "register_operand" "")
+ (compare:CCX (match_operand:DI 0 "compare_operand" "")
(match_operand:DI 1 "arith_double_operand" "")))]
"TARGET_ARCH64"
{
+ if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
+ operands[0] = force_reg (DImode, operands[0]);
+
sparc_compare_op0 = operands[0];
sparc_compare_op1 = operands[1];
DONE;
@@ -1685,6 +1705,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
/* Fixup PIC cases. */
if (flag_pic)
{
@@ -1744,6 +1768,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
/* Fixup PIC cases. */
if (flag_pic)
{
@@ -1798,8 +1826,8 @@
;; We always work with constants here.
(define_insn "*movhi_lo_sum"
[(set (match_operand:HI 0 "register_operand" "=r")
- (ior:HI (match_operand:HI 1 "arith_operand" "%r")
- (match_operand:HI 2 "arith_operand" "I")))]
+ (ior:HI (match_operand:HI 1 "register_operand" "%r")
+ (match_operand:HI 2 "small_int" "I")))]
""
"or\t%1, %2, %0")
@@ -1826,6 +1854,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
/* Fixup PIC cases. */
if (flag_pic)
{
@@ -1897,7 +1929,7 @@
st\t%r1, %0
st\t%1, %0
fzeros\t%0"
- [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
+ [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
(define_insn "*movsi_lo_sum"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -2002,6 +2034,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
if (flag_pic)
{
if (CONSTANT_P (operands[1])
@@ -2165,7 +2201,7 @@
ldd\t%1, %0
std\t%1, %0
fzero\t%0"
- [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
+ [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
(set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
(define_expand "movdi_pic_label_ref"
@@ -2613,7 +2649,7 @@
abort();
}
}
- [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
+ [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
;; Exactly the same as above, except that all `f' cases are deleted.
;; This is necessary to prevent reload from ever trying to use a `f' reg
@@ -2930,7 +2966,7 @@
#
#
#"
- [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
+ [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
(set_attr "length" "*,*,*,*,*,*,*,2,2,2")
(set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
@@ -2977,7 +3013,7 @@
ldx\t%1, %0
stx\t%r1, %0
#"
- [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
+ [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
(set_attr "length" "*,*,*,*,*,*,*,2")
(set_attr "fptype" "double,double,*,*,*,*,*,*")])
@@ -3205,7 +3241,7 @@
operands[1]));
}
- /* Handle MEM cases first, note that only v9 guarentees
+ /* Handle MEM cases first, note that only v9 guarantees
full 16-byte alignment for quads. */
if (GET_CODE (operands[0]) == MEM)
{
@@ -4949,7 +4985,7 @@
add\t%1, %2, %0
sub\t%1, -%2, %0
fpadd32s\t%1, %2, %0"
- [(set_attr "type" "*,*,fp")])
+ [(set_attr "type" "*,*,fga")])
(define_insn "*cmp_cc_plus"
[(set (reg:CC_NOOV 100)
@@ -5105,7 +5141,7 @@
sub\t%1, %2, %0
add\t%1, -%2, %0
fpsub32s\t%1, %2, %0"
- [(set_attr "type" "*,*,fp")])
+ [(set_attr "type" "*,*,fga")])
(define_insn "*cmp_minus_cc"
[(set (reg:CC_NOOV 100)
@@ -5829,7 +5865,7 @@
"@
#
fand\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -5841,7 +5877,7 @@
"@
and\t%1, %2, %0
fand\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "andsi3"
@@ -5852,7 +5888,7 @@
"@
and\t%1, %2, %0
fands\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
@@ -5924,7 +5960,7 @@
operands[6] = gen_lowpart (SImode, operands[0]);
operands[7] = gen_lowpart (SImode, operands[1]);
operands[8] = gen_lowpart (SImode, operands[2]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -5936,7 +5972,7 @@
"@
andn\t%2, %1, %0
fandnot1\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*and_not_si"
@@ -5947,7 +5983,7 @@
"@
andn\t%2, %1, %0
fandnot1s\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_expand "iordi3"
[(set (match_operand:DI 0 "register_operand" "")
@@ -5964,7 +6000,7 @@
"@
#
for\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -5976,7 +6012,7 @@
"@
or\t%1, %2, %0
for\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "iorsi3"
@@ -5987,7 +6023,7 @@
"@
or\t%1, %2, %0
fors\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
@@ -6025,7 +6061,7 @@
operands[6] = gen_lowpart (SImode, operands[0]);
operands[7] = gen_lowpart (SImode, operands[1]);
operands[8] = gen_lowpart (SImode, operands[2]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6037,7 +6073,7 @@
"@
orn\t%2, %1, %0
fornot1\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*or_not_si"
@@ -6048,7 +6084,7 @@
"@
orn\t%2, %1, %0
fornot1s\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_expand "xordi3"
[(set (match_operand:DI 0 "register_operand" "")
@@ -6065,7 +6101,7 @@
"@
#
fxor\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6077,7 +6113,7 @@
"@
xor\t%r1, %2, %0
fxor\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*xordi3_sp64_dbl"
@@ -6096,7 +6132,7 @@
"@
xor\t%r1, %2, %0
fxors\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
@@ -6150,7 +6186,7 @@
operands[6] = gen_lowpart (SImode, operands[0]);
operands[7] = gen_lowpart (SImode, operands[1]);
operands[8] = gen_lowpart (SImode, operands[2]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6162,7 +6198,7 @@
"@
xnor\t%r1, %2, %0
fxnor\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*xor_not_si"
@@ -6173,7 +6209,7 @@
"@
xnor\t%r1, %2, %0
fxnors\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
;; These correspond to the above in the case where we also (or only)
;; want to set the condition code.
@@ -6436,7 +6472,7 @@
operands[3] = gen_highpart (SImode, operands[1]);
operands[4] = gen_lowpart (SImode, operands[0]);
operands[5] = gen_lowpart (SImode, operands[1]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6447,7 +6483,7 @@
"@
xnor\t%%g0, %1, %0
fnot1\t%1, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "one_cmplsi2"
@@ -6457,7 +6493,7 @@
"@
xnor\t%%g0, %1, %0
fnot1s\t%1, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_insn "*cmp_cc_not"
[(set (reg:CC 100)
@@ -7212,27 +7248,10 @@
[(set_attr "type" "shift")])
;; Unconditional and other jump instructions
-;; On the SPARC, by setting the annul bit on an unconditional branch, the
-;; following insn is never executed. This saves us a nop. Dbx does not
-;; handle such branches though, so we only use them when optimizing.
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
-{
- /* TurboSPARC is reported to have problems with
- with
- foo: b,a foo
- i.e. an empty loop with the annul bit set. The workaround is to use
- foo: b foo; nop
- instead. */
-
- if (! TARGET_V9 && flag_delayed_branch
- && (INSN_ADDRESSES (INSN_UID (operands[0]))
- == INSN_ADDRESSES (INSN_UID (insn))))
- return "b\t%l0%#";
- else
- return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
-}
+ "* return output_ubranch (operands[0], 0, insn);"
[(set_attr "type" "uncond_branch")])
(define_expand "tablejump"
@@ -7658,7 +7677,7 @@
emit_insn (gen_rtx_USE (VOIDmode, valreg2));
/* Construct the return. */
- expand_null_return ();
+ expand_naked_return ();
DONE;
})
@@ -7796,7 +7815,7 @@
;; For __builtin_setjmp we need to flush register windows iff the function
;; calls alloca as well, because otherwise the register window might be
-;; saved after %sp adjustement and thus setjmp would crash
+;; saved after %sp adjustment and thus setjmp would crash
(define_expand "builtin_setjmp_setup"
[(match_operand 0 "register_operand" "r")]
""
@@ -8239,31 +8258,6 @@
[(set_attr "type" "multi")
(set_attr "length" "2")])
-;; Now peepholes to do a call followed by a jump.
-
-(define_peephole
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
- (match_operand 2 "" "")))
- (clobber (reg:SI 15))])
- (set (pc) (label_ref (match_operand 3 "" "")))]
- "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
- && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
- && sparc_cpu != PROCESSOR_ULTRASPARC
- && sparc_cpu != PROCESSOR_ULTRASPARC3"
- "call\t%a1, %2\n\tadd\t%%o7, (%l3-.-4), %%o7")
-
-(define_peephole
- [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
- (match_operand 1 "" ""))
- (clobber (reg:SI 15))])
- (set (pc) (label_ref (match_operand 2 "" "")))]
- "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
- && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
- && sparc_cpu != PROCESSOR_ULTRASPARC
- && sparc_cpu != PROCESSOR_ULTRASPARC3"
- "call\t%a0, %1\n\tadd\t%%o7, (%l2-.-4), %%o7")
-
;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
;; ??? operations. With DFA we might be able to model this, but it requires a lot of
@@ -8391,3 +8385,566 @@
"TARGET_V9"
"t%C0\t%%xcc, %1"
[(set_attr "type" "trap")])
+
+;; TLS support
+(define_insn "tgd_hi22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS"
+ "sethi\\t%%tgd_hi22(%a1), %0")
+
+(define_insn "tgd_lo10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS"
+ "add\\t%1, %%tgd_lo10(%a2), %0")
+
+(define_insn "tgd_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tgd_add(%a3)")
+
+(define_insn "tgd_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tgd_add(%a3)")
+
+(define_insn "tgd_call32"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
+ (match_operand 2 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD))
+ (match_operand 3 "" "")))
+ (clobber (reg:SI 15))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "call\t%a1, %%tgd_call(%a2)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tgd_call64"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
+ (match_operand 2 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD))
+ (match_operand 3 "" "")))
+ (clobber (reg:DI 15))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "call\t%a1, %%tgd_call(%a2)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tldm_hi22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
+ "TARGET_TLS"
+ "sethi\\t%%tldm_hi22(%&), %0")
+
+(define_insn "tldm_lo10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
+ "TARGET_TLS"
+ "add\\t%1, %%tldm_lo10(%&), %0")
+
+(define_insn "tldm_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
+ UNSPEC_TLSLDM)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tldm_add(%&)")
+
+(define_insn "tldm_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
+ UNSPEC_TLSLDM)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tldm_add(%&)")
+
+(define_insn "tldm_call32"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
+ UNSPEC_TLSLDM))
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 15))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "call\t%a1, %%tldm_call(%&)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tldm_call64"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
+ UNSPEC_TLSLDM))
+ (match_operand 2 "" "")))
+ (clobber (reg:DI 15))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "call\t%a1, %%tldm_call(%&)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tldo_hix22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS"
+ "sethi\\t%%tldo_hix22(%a1), %0")
+
+(define_insn "tldo_lox10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS"
+ "xor\\t%1, %%tldo_lox10(%a2), %0")
+
+(define_insn "tldo_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tldo_add(%a3)")
+
+(define_insn "tldo_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tldo_add(%a3)")
+
+(define_insn "tie_hi22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_TLS"
+ "sethi\\t%%tie_hi22(%a1), %0")
+
+(define_insn "tie_lo10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_TLS"
+ "add\\t%1, %%tie_lo10(%a2), %0")
+
+(define_insn "tie_ld32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
+ [(set_attr "type" "load")])
+
+(define_insn "tie_ld64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
+ [(set_attr "type" "load")])
+
+(define_insn "tie_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_SUN_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tie_add(%a3)")
+
+(define_insn "tie_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:DI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_SUN_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tie_add(%a3)")
+
+(define_insn "tle_hix22_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "sethi\\t%%tle_hix22(%a1), %0")
+
+(define_insn "tle_lox10_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "xor\\t%1, %%tle_lox10(%a2), %0")
+
+(define_insn "tle_hix22_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "sethi\\t%%tle_hix22(%a1), %0")
+
+(define_insn "tle_lox10_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "xor\\t%1, %%tle_lox10(%a2), %0")
+
+;; Now patterns combining tldo_add{32,64} with some integer loads or stores
+(define_insn "*tldo_ldub_sp32"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub1_sp32"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub2_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb1_sp32"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb2_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub_sp64"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub1_sp64"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub2_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub3_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb1_sp64"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb2_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb3_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh_sp32"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh1_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsh1_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh_sp64"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh1_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh2_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsh1_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsh2_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduw_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ld\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_lduw_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_lduw1_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_ldsw1_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldx_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_stb_sp32"
+ [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))
+ (match_operand:QI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "stb\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stb_sp64"
+ [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:QI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "stb\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_sth_sp32"
+ [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))
+ (match_operand:HI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "sth\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_sth_sp64"
+ [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:HI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "sth\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stw_sp32"
+ [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))
+ (match_operand:SI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "st\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stw_sp64"
+ [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:SI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "stw\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stx_sp64"
+ [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:DI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "stx\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
diff --git a/contrib/gcc/config/sparc/sparclet.md b/contrib/gcc/config/sparc/sparclet.md
index 080090c..15020ba 100644
--- a/contrib/gcc/config/sparc/sparclet.md
+++ b/contrib/gcc/config/sparc/sparclet.md
@@ -1,20 +1,20 @@
;; Scheduling description for SPARClet.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/supersparc.md b/contrib/gcc/config/sparc/supersparc.md
index ea32886..93e4cf7 100644
--- a/contrib/gcc/config/sparc/supersparc.md
+++ b/contrib/gcc/config/sparc/supersparc.md
@@ -1,20 +1,20 @@
;; Scheduling description for SuperSPARC.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/sysv4-only.h b/contrib/gcc/config/sparc/sysv4-only.h
new file mode 100644
index 0000000..da265a0
--- /dev/null
+++ b/contrib/gcc/config/sparc/sysv4-only.h
@@ -0,0 +1,35 @@
+/* Target macros for GCC for SPARC running System V.4
+ Copyright (C) 2003
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Provide a set of pre-definitions and pre-assertions appropriate for
+ the SPARC running svr4. __svr4__ is our extension. */
+
+/* Target OS builtins. */ \
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ builtin_define_std ("unix"); \
+ builtin_define ("__svr4__"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=svr4"); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/sparc/sysv4.h b/contrib/gcc/config/sparc/sysv4.h
index f304d6b..776debc 100644
--- a/contrib/gcc/config/sparc/sysv4.h
+++ b/contrib/gcc/config/sparc/sysv4.h
@@ -3,20 +3,20 @@
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -48,13 +48,6 @@ Boston, MA 02111-1307, USA. */
#undef SKIP_ASM_OP
#undef SET_ASM_OP /* Has no equivalent. See ASM_OUTPUT_DEF below. */
-/* Provide a set of pre-definitions and pre-assertions appropriate for
- the SPARC running svr4. __svr4__ is our extension. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES \
-"-Dsparc -Dunix -D__svr4__ -Asystem=unix -Asystem=svr4"
-
/* The native assembler can't compute differences between symbols in different
sections when generating pic code, so we must put jump tables in the
text section. */
@@ -66,7 +59,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC \
"%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
- %{fpic:-K PIC} %{fPIC:-K PIC} %(asm_cpu)"
+ %{fpic|fPIC|fpie|fPIE:-K PIC} %(asm_cpu)"
/* Define the names of various pseudo-op used by the SPARC/svr4 assembler.
Note that many of these are different from the typical pseudo-ops used
@@ -93,7 +86,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \
- ASM_OUTPUT_INTERNAL_LABEL ((FILE), PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) ((FILE), PREFIX, NUM); \
} while (0)
/* This is how to equate one symbol to another symbol. The syntax used is
@@ -161,11 +154,6 @@ do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION sparc_elf_asm_named_section
-/* A C statement (sans semicolon) to output to the stdio stream
- FILE the assembler definition of uninitialized global DECL named
- NAME whose size is SIZE bytes and alignment is ALIGN bytes.
- Try to use asm_output_aligned_bss to implement this macro. */
-
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
diff --git a/contrib/gcc/config/sparc/t-sol2 b/contrib/gcc/config/sparc/t-sol2
index 4a5a13b..f32765f 100644
--- a/contrib/gcc/config/sparc/t-sol2
+++ b/contrib/gcc/config/sparc/t-sol2
@@ -1,5 +1,6 @@
# gmon build rule:
-$(T)gmon.o: $(srcdir)/config/sparc/gmon-sol2.c $(GCC_PASSES) $(CONFIG_H) stmp-int-hdrs
+$(T)gmon.o: $(srcdir)/config/sparc/gmon-sol2.c $(GCC_PASSES) \
+ $(TCONFIG_H) tsystem.h coretypes.h $(TM_H) stmp-int-hdrs
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \
-c $(srcdir)/config/sparc/gmon-sol2.c -o $(T)gmon.o
diff --git a/contrib/gcc/config/sparc/ultra1_2.md b/contrib/gcc/config/sparc/ultra1_2.md
index 2194be7..e58c624 100644
--- a/contrib/gcc/config/sparc/ultra1_2.md
+++ b/contrib/gcc/config/sparc/ultra1_2.md
@@ -1,20 +1,20 @@
;; Scheduling description for UltraSPARC-I/II.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -250,3 +250,53 @@
;; An integer branch may execute in the same cycle as the compare
;; creating the condition codes.
(define_bypass 0 "us1_simple_ieu1" "us1_branch")
+
+;; VIS scheduling
+(define_insn_reservation "us1_fga_single"
+ 2
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fga"))
+ (eq_attr "fptype" "single"))
+ "us1_fpa + us1_fp_single + us1_slotany, nothing")
+
+(define_bypass 1 "us1_fga_single" "us1_fga_single")
+
+(define_insn_reservation "us1_fga_double"
+ 2
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fga"))
+ (eq_attr "fptype" "double"))
+ "us1_fpa + us1_fp_double + us1_slotany, nothing")
+
+(define_bypass 1 "us1_fga_double" "us1_fga_double")
+
+(define_insn_reservation "us1_fgm_single"
+ 4
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fgm_pack,fgm_mul,fgm_cmp"))
+ (eq_attr "fptype" "single"))
+ "us1_fpm + us1_fp_single + us1_slotany, nothing*3")
+
+(define_bypass 3 "us1_fgm_single" "us1_fga_single")
+
+(define_insn_reservation "us1_fgm_double"
+ 4
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fgm_pack,fgm_mul,fgm_cmp"))
+ (eq_attr "fptype" "double"))
+ "us1_fpm + us1_fp_double + us1_slotany, nothing*3")
+
+(define_bypass 3 "us1_fgm_double" "us1_fga_double")
+
+(define_insn_reservation "us1_pdist"
+ 4
+ (and (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fgm_pdist"))
+ "us1_fpm + us1_fp_double + us1_slotany, nothing*3")
+
+(define_bypass 3 "us1_pdist" "us1_fga_double,us1_fga_single")
+(define_bypass 1 "us1_pdist" "us1_pdist")
diff --git a/contrib/gcc/config/sparc/ultra3.md b/contrib/gcc/config/sparc/ultra3.md
index cebc9f2..238beab 100644
--- a/contrib/gcc/config/sparc/ultra3.md
+++ b/contrib/gcc/config/sparc/ultra3.md
@@ -1,20 +1,20 @@
;; Scheduling description for UltraSPARC-III.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -167,3 +167,24 @@
;; If FMOVfcc is user of FPCMP, latency is only 1 cycle.
(define_bypass 1 "us3_fpcmp" "us3_fcmov")
+
+;; VIS scheduling
+(define_insn_reservation "us3_fga"
+ 3
+ (and (eq_attr "cpu" "ultrasparc3")
+ (eq_attr "type" "fga"))
+ "us3_fpa + us3_slotany, nothing*2")
+
+(define_insn_reservation "us3_fgm"
+ 4
+ (and (eq_attr "cpu" "ultrasparc3")
+ (eq_attr "type" "fgm_pack,fgm_mul,fgm_cmp"))
+ "us3_fpm + us3_slotany, nothing*3")
+
+(define_insn_reservation "us3_pdist"
+ 4
+ (and (eq_attr "cpu" "ultrasparc3")
+ (eq_attr "type" "fgm_pdist"))
+ "us3_fpm + us3_slotany, nothing*3")
+
+(define_bypass 1 "us3_pdist" "us3_pdist")
diff --git a/contrib/gcc/config/svr3.h b/contrib/gcc/config/svr3.h
index e559c5c..21595ea 100644
--- a/contrib/gcc/config/svr3.h
+++ b/contrib/gcc/config/svr3.h
@@ -3,41 +3,22 @@
Copyright (C) 1991, 1996, 2000, 2002 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
-
- To use this file, make up a file with a name like:
-
- ?????svr3.h
-
- where ????? is replaced by the name of the basic hardware that you
- are targeting for. Then, in the file ?????svr3.h, put something
- like:
-
- #include "?????.h"
- #include "svr3.h"
-
- followed by any really system-specific defines (or overrides of
- defines) which you find that you need. For example, CPP_PREDEFINES
- is defined here with only the defined -Dunix and -DSVR3. You should
- probably override that in your target-specific ?????svr3.h file
- with a set of defines that includes these, but also contains an
- appropriate define for the type of hardware that you are targeting.
-*/
+Boston, MA 02111-1307, USA. */
/* Define a symbol indicating that we are using svr3.h. */
#define USING_SVR3_H
@@ -46,27 +27,10 @@ Boston, MA 02111-1307, USA.
environment and assembler syntax we are targeting for. */
#define SVR3_target
-/* Cpp, assembler, linker, library, and startfile spec's. */
-
-/* You should redefine CPP_PREDEFINES in any file which includes this one.
- The definition should be appropriate for the type of target system
- involved, and it should include any -A (assertion) options which are
- appropriate for the given target system. */
+/* Assembler, linker, library, and startfile spec's. */
-#undef CPP_PREDEFINES
-
-/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { output_file_directive ((FILE), main_input_filename); \
- if (optimize) { ASM_FILE_START_1 (FILE); } \
- } while (0)
-
-/* By default, do nothing: a few machines support .optim, but not most. */
-#undef ASM_FILE_START_1
-#define ASM_FILE_START_1(FILE)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* This says how to output an assembler line
to define a global common symbol. */
@@ -78,7 +42,7 @@ Boston, MA 02111-1307, USA.
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (SIZE)))
+ fprintf ((FILE), ",%lu\n", (unsigned long)(SIZE)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -93,26 +57,9 @@ Boston, MA 02111-1307, USA.
data_section (); \
ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(ROUNDED)); \
} while (0)
-#if 0 /* For now, let's leave these machine-specific. */
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#define STARTFILE_SPEC \
- "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
-
-#ifdef CROSS_COMPILE
-#define LIB_SPEC "-lc crtn.o%s"
-#else
-#define LIB_SPEC "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} -lc crtn.o%s"
-#endif
-
-/* Special flags for the linker. I don't know what they do. */
-
-#define LINK_SPEC "%{T*} %{z:-lm}"
-#endif
-
/* Output #ident as a .ident. */
#undef ASM_OUTPUT_IDENT
@@ -158,16 +105,6 @@ Boston, MA 02111-1307, USA.
#undef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX "_"
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class.
-
- For most svr3 systems, the convention is that any symbol which begins
- with a period is not put into the linker symbol table by the assembler. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- asm_fprintf (FILE, "%0L%s%d:\n", PREFIX, NUM)
-
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
diff --git a/contrib/gcc/config/svr4.h b/contrib/gcc/config/svr4.h
index bc6a3b8..ca65cd8 100644
--- a/contrib/gcc/config/svr4.h
+++ b/contrib/gcc/config/svr4.h
@@ -4,20 +4,20 @@
2000, 2001 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
@@ -28,11 +28,7 @@ Boston, MA 02111-1307, USA.
where MACHINE is replaced by the name of the basic hardware that you
are targeting for. Then, in the file MACHINE/svr4.h, put any really
system-specific defines (or overrides of defines) which you find that
- you need. For example, CPP_PREDEFINES is defined here with only the
- defined -Dunix and -DSVR4. You should probably override that in your
- target-specific MACHINE/svr4.h file with a set of defines that
- includes these, but also contains an appropriate define for the type
- of hardware that you are targeting.
+ you need.
*/
/* Define a symbol indicating that we are using svr4.h. */
@@ -45,6 +41,7 @@ Boston, MA 02111-1307, USA.
-z* options (for the linker). Note however that there is no such
thing as a -T option for svr4. */
+#undef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) \
(DEFAULT_SWITCH_TAKES_ARG (CHAR) \
|| (CHAR) == 'h' \
@@ -59,12 +56,6 @@ Boston, MA 02111-1307, USA.
&& strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \
&& strcmp (STR, "Tbss"))
-/* You should redefine CPP_PREDEFINES in any file which includes this one.
- The definition should be appropriate for the type of target system
- involved, and it should include any -A (assertion) options which are
- appropriate for the given target system. */
-#undef CPP_PREDEFINES
-
/* Provide an ASM_SPEC appropriate for svr4. Here we try to support as
many of the specialized svr4 assembler options as seems reasonable,
given that there are certain options which we can't (or shouldn't)
@@ -79,22 +70,16 @@ Boston, MA 02111-1307, USA.
Note that gcc doesn't allow a space to follow -Y in a -Ym,* or -Yd,*
option.
+
+ The svr4 assembler wants '-' on the command line if it's expected to
+ read its stdin.
*/
#undef ASM_SPEC
#define ASM_SPEC \
"%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
-/* svr4 assemblers need the `-' (indicating input from stdin) to come after
- the -o option (and its argument) for some reason. If we try to put it
- before the -o option, the assembler will try to read the file named as
- the output file in the -o option as an input file (after it has already
- written some stuff to it) and the binary stuff contained therein will
- cause totally confuse the assembler, resulting in many spurious error
- messages. */
-
-#undef ASM_FINAL_SPEC
-#define ASM_FINAL_SPEC "%|"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
/* Under svr4, the normal location of the `ld' and `as' programs is the
/usr/ccs/bin directory. */
@@ -218,8 +203,4 @@ Boston, MA 02111-1307, USA.
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
-/* This causes trouble, because it requires the host machine
- to support ANSI C. */
-/* #define MULTIBYTE_CHARS */
-
#define TARGET_HAS_F_SETLKW
diff --git a/contrib/gcc/config/t-darwin b/contrib/gcc/config/t-darwin
index c823fa5..a7076ab 100644
--- a/contrib/gcc/config/t-darwin
+++ b/contrib/gcc/config/t-darwin
@@ -1,12 +1,12 @@
-darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) $(RTL_BASE_H) \
- $(REGS_H) hard-reg-set.h insn-config.h conditions.h output.h \
- insn-attr.h flags.h $(TREE_H) $(EXPR_H) reload.h \
- function.h $(GGC_H) $(TM_P_H) gt-darwin.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(REAL_H) insn-config.h \
+ conditions.h insn-flags.h output.h insn-attr.h flags.h $(TREE_H) expr.h \
+ reload.h function.h $(GGC_H) langhooks.h $(TM_P_H) gt-darwin.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/darwin.c
-darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(C_TREE_H) c-pragma.h toplev.h cpplib.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(CPPLIB_H) tree.h c-pragma.h $(C_TREE_H) toplev.h $(TM_P_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/darwin-c.c
gt-darwin.h : s-gtype ; @true
@@ -20,3 +20,5 @@ $(T)crt2$(objext): $(srcdir)/config/darwin-crt2.c $(GCC_PASSES) \
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-darwin.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
+
+TARGET_LIBGCC2_CFLAGS = -fPIC
diff --git a/contrib/gcc/config/t-freebsd b/contrib/gcc/config/t-freebsd
index da9c642..211dbdf 100644
--- a/contrib/gcc/config/t-freebsd
+++ b/contrib/gcc/config/t-freebsd
@@ -1,6 +1,3 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# Compile crtbeginS.o and crtendS.o with pic.
CRTSTUFF_T_CFLAGS_S = -fPIC
diff --git a/contrib/gcc/config/t-gnu b/contrib/gcc/config/t-gnu
index 59481ee..7be5d00 100644
--- a/contrib/gcc/config/t-gnu
+++ b/contrib/gcc/config/t-gnu
@@ -1,2 +1,2 @@
# In GNU, "/usr" is a four-letter word.
-SYSTEM_HEADER_DIR = /include
+NATIVE_SYSTEM_HEADER_DIR = /include
diff --git a/contrib/gcc/config/t-kfreebsd-gnu b/contrib/gcc/config/t-kfreebsd-gnu
new file mode 100644
index 0000000..a40dc7a
--- /dev/null
+++ b/contrib/gcc/config/t-kfreebsd-gnu
@@ -0,0 +1,16 @@
+# glibc provides a limits.h, which must be combined with gcc's limits.h.
+LIMITS_H_TEST = true
+
+# Compile crtbeginS.o and crtendS.o with pic.
+CRTSTUFF_T_CFLAGS_S = -fPIC
+# Compile libgcc2.a with pic.
+TARGET_LIBGCC2_CFLAGS = -fPIC
+
+# Override t-slibgcc-elf-ver to export some libgcc symbols with
+# the symbol versions that glibc used.
+SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver
+
+# Use unwind-dw2-fde-glibc
+LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
+ $(srcdir)/unwind-sjlj.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
diff --git a/contrib/gcc/config/t-libunwind b/contrib/gcc/config/t-libunwind
index be50bc4..2204ae3 100644
--- a/contrib/gcc/config/t-libunwind
+++ b/contrib/gcc/config/t-libunwind
@@ -1 +1,5 @@
-LIB2ADDEH = $(srcdir)/unwind-libunwind.c $(srcdir)/unwind-sjlj.c
+# Override the default value from t-slibgcc-elf-ver and mention -lunwind
+# so that the resulting libgcc_s.so has the necessary DT_NEEDED entry for
+# libunwind.
+SHLIB_LC = -lunwind -lc
+LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
diff --git a/contrib/gcc/config/t-linux b/contrib/gcc/config/t-linux
index 61bce29..f25ab64 100644
--- a/contrib/gcc/config/t-linux
+++ b/contrib/gcc/config/t-linux
@@ -1,6 +1,3 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# Compile crtbeginS.o and crtendS.o with pic.
CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
# Compile libgcc2.a with pic.
@@ -12,5 +9,5 @@ SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver
# Use unwind-dw2-fde-glibc
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
- $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
-LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
+ $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c gthr-gnat.c
diff --git a/contrib/gcc/config/t-netbsd b/contrib/gcc/config/t-netbsd
index fa2a488..843e410 100644
--- a/contrib/gcc/config/t-netbsd
+++ b/contrib/gcc/config/t-netbsd
@@ -1,5 +1,2 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# Always build crtstuff with PIC.
CRTSTUFF_T_CFLAGS = -fPIC
diff --git a/contrib/gcc/config/t-openbsd b/contrib/gcc/config/t-openbsd
index 0578cbd..2289f15 100644
--- a/contrib/gcc/config/t-openbsd
+++ b/contrib/gcc/config/t-openbsd
@@ -1,5 +1,2 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# We don't need GCC's own include files.
USER_H =
diff --git a/contrib/gcc/config/t-rtems b/contrib/gcc/config/t-rtems
index c403ff8..dfbd3af 100644
--- a/contrib/gcc/config/t-rtems
+++ b/contrib/gcc/config/t-rtems
@@ -1,6 +1,3 @@
-# RTEMS uses newlib which does not require prototype fixing
-STMP_FIXPROTO =
-
# RTEMS always has limits.h.
LIMITS_H_TEST = true
diff --git a/contrib/gcc/config/t-slibgcc-darwin b/contrib/gcc/config/t-slibgcc-darwin
new file mode 100644
index 0000000..f27fae4
--- /dev/null
+++ b/contrib/gcc/config/t-slibgcc-darwin
@@ -0,0 +1,30 @@
+# Build a shared libgcc library with the darwin linker.
+SHLIB_MINOR = 1
+SHLIB_REVISION = 0
+SHLIB_VERSTRING = -compatibility_version $(SHLIB_MINOR) -current_version $(SHLIB_MINOR).$(SHLIB_REVISION)
+SHLIB_EXT = .dylib
+SHLIB_SOLINK = @shlib_base_name@.dylib
+SHLIB_SONAME = @shlib_so_name@.$(SHLIB_MINOR).$(SHLIB_REVISION).dylib
+SHLIB_NAME = @shlib_dir@@shlib_so_name@.$(SHLIB_MINOR).$(SHLIB_REVISION).dylib
+SHLIB_MAP = @shlib_map_file@
+SHLIB_OBJS = @shlib_objs@
+SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
+
+SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -dynamiclib -nodefaultlibs \
+ -Wl,-install_name,$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME) \
+ -Wl,-flat_namespace -o $(SHLIB_NAME) \
+ $(SHLIB_VERSTRING) \
+ @multilib_flags@ $(SHLIB_OBJS) -lc && \
+ rm -f $(SHLIB_SOLINK) && \
+ $(LN_S) $(SHLIB_NAME) $(SHLIB_SOLINK)
+# $(slibdir) double quoted to protect it from expansion while building
+# libgcc.mk. We want this delayed until actual install time.
+SHLIB_INSTALL = \
+ $$(SHELL) $$(srcdir)/mkinstalldirs $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL); \
+ $(INSTALL_DATA) $(SHLIB_NAME) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME); \
+ rm -f $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \
+ $(LN_S) $(SHLIB_SONAME) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
+SHLIB_MKMAP = $(srcdir)/mkmap-symver.awk
+SHLIB_MAPFILES = $(srcdir)/libgcc-darwin.ver
diff --git a/contrib/gcc/config/t-slibgcc-elf-ver b/contrib/gcc/config/t-slibgcc-elf-ver
index a176b10..a4f8ef0 100644
--- a/contrib/gcc/config/t-slibgcc-elf-ver
+++ b/contrib/gcc/config/t-slibgcc-elf-ver
@@ -3,8 +3,9 @@
SHLIB_EXT = .so
SHLIB_SOLINK = @shlib_base_name@.so
-SHLIB_SONAME = @shlib_so_name@.so.1
-SHLIB_NAME = @shlib_dir@@shlib_so_name@.so.1
+SHLIB_SOVERSION = 1
+SHLIB_SONAME = @shlib_so_name@.so.$(SHLIB_SOVERSION)
+SHLIB_NAME = @shlib_dir@@shlib_so_name@.so.$(SHLIB_SOVERSION)
SHLIB_MAP = @shlib_map_file@
SHLIB_OBJS = @shlib_objs@
SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
diff --git a/contrib/gcc/config/t-vxworks b/contrib/gcc/config/t-vxworks
new file mode 100644
index 0000000..ebf47e1
--- /dev/null
+++ b/contrib/gcc/config/t-vxworks
@@ -0,0 +1,22 @@
+# Since we have a functional assert.h, use it.
+INSTALL_ASSERT_H =
+
+# Build libgcc using the multilib mechanism
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+# No special flags needed for libgcc.a
+TARGET_LIBGCC2_CFLAGS =
+
+# Don't build libgcc.a with debug info
+LIBGCC2_DEBUG_CFLAGS =
+
+# Extra libgcc2 module used by gthr-vxworks.h functions
+LIB2FUNCS_EXTRA = $(srcdir)/config/vxlib.c
+
+# This ensures that the correct target headers are used; some
+# VxWorks system headers have names that collide with GCC's
+# internal (host) headers, e.g. regs.h.
+# FIXME: May not be necessary anymore.
+LIBGCC2_INCLUDES="-I$(SYSTEM_HEADER_DIR)"
diff --git a/contrib/gcc/config/usegas.h b/contrib/gcc/config/usegas.h
index cf20c55..54fa9bd 100644
--- a/contrib/gcc/config/usegas.h
+++ b/contrib/gcc/config/usegas.h
@@ -1,19 +1,19 @@
/* Copyright (C) 2001 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/vxlib.c b/contrib/gcc/config/vxlib.c
new file mode 100644
index 0000000..20a257e
--- /dev/null
+++ b/contrib/gcc/config/vxlib.c
@@ -0,0 +1,325 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Zack Weinberg <zack@codesourcery.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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Threads compatibility routines for libgcc2 for VxWorks.
+ These are out-of-line routines called from gthr-vxworks.h. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "gthr.h"
+
+#include <vxWorks.h>
+#include <vxLib.h>
+#include <taskLib.h>
+#include <taskHookLib.h>
+
+/* Init-once operation.
+
+ This would be a clone of the implementation from gthr-solaris.h,
+ except that we have a bootstrap problem - the whole point of this
+ exercise is to prevent double initialization, but if two threads
+ are racing with each other, once->mutex is liable to be initialized
+ by both. Then each thread will lock its own mutex, and proceed to
+ call the initialization routine.
+
+ So instead we use a bare atomic primitive (vxTas()) to handle
+ mutual exclusion. Threads losing the race then busy-wait, calling
+ taskDelay() to yield the processor, until the initialization is
+ completed. Inefficient, but reliable. */
+
+int
+__gthread_once (__gthread_once_t *guard, void (*func)(void))
+{
+ if (guard->done)
+ return 0;
+
+ while (!vxTas ((void *)&guard->busy))
+ taskDelay (1);
+
+ /* Only one thread at a time gets here. Check ->done again, then
+ go ahead and call func() if no one has done it yet. */
+ if (!guard->done)
+ {
+ func ();
+ guard->done = 1;
+ }
+
+ guard->busy = 0;
+ return 0;
+}
+
+/* Thread-specific data.
+
+ We reserve a field in the TCB to point to a dynamically allocated
+ array which is used to store TSD values. A TSD key is simply an
+ offset in this array. The exact location of the TCB field is not
+ known to this code nor to vxlib.c -- all access to it indirects
+ through the routines __gthread_get_tsd_data and
+ __gthread_set_tsd_data, which are provided by the VxWorks kernel.
+
+ There is also a global array which records which keys are valid and
+ which have destructors.
+
+ A task delete hook is installed to execute key destructors. The
+ routines __gthread_enter_tsd_dtor_context and
+ __gthread_leave_tsd_dtor_context, which are also provided by the
+ kernel, ensure that it is safe to call free() on memory allocated
+ by the task being deleted. (This is a no-op on VxWorks 5, but
+ a major undertaking on AE.)
+
+ Since this interface is used to allocate only a small number of
+ keys, the table size is small and static, which simplifies the
+ code quite a bit. Revisit this if and when it becomes necessary. */
+
+#define MAX_KEYS 4
+
+/* This is the structure pointed to by the pointer returned
+ by __gthread_get_tsd_data. */
+struct tsd_data
+{
+ void *values[MAX_KEYS];
+ unsigned int generation[MAX_KEYS];
+};
+
+
+/* kernel provided routines */
+extern void *__gthread_get_tsd_data (WIND_TCB *tcb);
+extern void __gthread_set_tsd_data (WIND_TCB *tcb, void *data);
+
+extern void __gthread_enter_tsd_dtor_context (WIND_TCB *tcb);
+extern void __gthread_leave_tsd_dtor_context (WIND_TCB *tcb);
+
+typedef void (*fet_callback_t) (WIND_TCB *, unsigned int);
+extern void __gthread_for_all_tasks (fet_callback_t fun, unsigned int number);
+
+/* This is a global structure which records all of the active keys.
+
+ A key is potentially valid (i.e. has been handed out by
+ __gthread_key_create) iff its generation count in this structure is
+ even. In that case, the matching entry in the dtors array is a
+ routine to be called when a thread terminates with a valid,
+ non-NULL specific value for that key.
+
+ A key is actually valid in a thread T iff the generation count
+ stored in this structure is equal to the generation count stored in
+ T's specific-value structure. */
+
+typedef void (*tsd_dtor) (void *);
+
+struct tsd_keys
+{
+ tsd_dtor dtor[MAX_KEYS];
+ unsigned int generation[MAX_KEYS];
+};
+
+#define KEY_VALID_P(key) !(tsd_keys.generation[key] & 1)
+
+/* Note: if MAX_KEYS is increased, this initializer must be updated
+ to match. All the generation counts begin at 1, which means no
+ key is valid. */
+static struct tsd_keys tsd_keys =
+{
+ { 0, 0, 0, 0 },
+ { 1, 1, 1, 1 }
+};
+
+/* This lock protects the tsd_keys structure. */
+static __gthread_mutex_t tsd_lock;
+
+static __gthread_once_t tsd_init_guard = __GTHREAD_ONCE_INIT;
+
+/* Internal routines. */
+
+/* The task TCB has just been deleted. Call the destructor
+ function for each TSD key that has both a destructor and
+ a non-NULL specific value in this thread.
+
+ This routine does not need to take tsd_lock; the generation
+ count protects us from calling a stale destructor. It does
+ need to read tsd_keys.dtor[key] atomically. */
+
+static void
+tsd_delete_hook (WIND_TCB *tcb)
+{
+ struct tsd_data *data = __gthread_get_tsd_data (tcb);
+ __gthread_key_t key;
+
+ if (data)
+ {
+ __gthread_enter_tsd_dtor_context (tcb);
+ for (key = 0; key < MAX_KEYS; key++)
+ {
+ if (data->generation[key] == tsd_keys.generation[key])
+ {
+ tsd_dtor dtor = tsd_keys.dtor[key];
+
+ if (dtor)
+ dtor (data->values[key]);
+ }
+ }
+ free (data);
+ __gthread_set_tsd_data (tcb, 0);
+ __gthread_leave_tsd_dtor_context (tcb);
+ }
+}
+
+/* Initialize global data used by the TSD system. */
+static void
+tsd_init (void)
+{
+ taskDeleteHookAdd ((FUNCPTR)tsd_delete_hook);
+ __GTHREAD_MUTEX_INIT_FUNCTION (&tsd_lock);
+}
+
+/* External interface */
+
+/* Store in KEYP a value which can be passed to __gthread_setspecific/
+ __gthread_getspecific to store and retrieve a value which is
+ specific to each calling thread. If DTOR is not NULL, it will be
+ called when a thread terminates with a non-NULL specific value for
+ this key, with the value as its sole argument. */
+
+int
+__gthread_key_create (__gthread_key_t *keyp, tsd_dtor dtor)
+{
+ __gthread_key_t key;
+
+ __gthread_once (&tsd_init_guard, tsd_init);
+
+ if (__gthread_mutex_lock (&tsd_lock) == ERROR)
+ return errno;
+
+ for (key = 0; key < MAX_KEYS; key++)
+ if (!KEY_VALID_P (key))
+ goto found_slot;
+
+ /* no room */
+ __gthread_mutex_unlock (&tsd_lock);
+ return EAGAIN;
+
+ found_slot:
+ tsd_keys.generation[key]++; /* making it even */
+ tsd_keys.dtor[key] = dtor;
+ *keyp = key;
+ __gthread_mutex_unlock (&tsd_lock);
+ return 0;
+}
+
+/* Invalidate KEY; it can no longer be used as an argument to
+ setspecific/getspecific. Note that this does NOT call destructor
+ functions for any live values for this key. */
+int
+__gthread_key_delete (__gthread_key_t key)
+{
+ if (key >= MAX_KEYS)
+ return EINVAL;
+
+ __gthread_once (&tsd_init_guard, tsd_init);
+
+ if (__gthread_mutex_lock (&tsd_lock) == ERROR)
+ return errno;
+
+ if (!KEY_VALID_P (key))
+ {
+ __gthread_mutex_unlock (&tsd_lock);
+ return EINVAL;
+ }
+
+ tsd_keys.generation[key]++; /* making it odd */
+ tsd_keys.dtor[key] = 0;
+
+ __gthread_mutex_unlock (&tsd_lock);
+ return 0;
+}
+
+/* Retrieve the thread-specific value for KEY. If it has never been
+ set in this thread, or KEY is invalid, returns NULL.
+
+ It does not matter if this function races with key_create or
+ key_delete; the worst that can happen is you get a value other than
+ the one that a serialized implementation would have provided. */
+
+void *
+__gthread_getspecific (__gthread_key_t key)
+{
+ struct tsd_data *data;
+
+ if (key >= MAX_KEYS)
+ return 0;
+
+ data = __gthread_get_tsd_data (taskTcb (taskIdSelf ()));
+
+ if (!data)
+ return 0;
+
+ if (data->generation[key] != tsd_keys.generation[key])
+ return 0;
+
+ return data->values[key];
+}
+
+/* Set the thread-specific value for KEY. If KEY is invalid, or
+ memory allocation fails, returns -1, otherwise 0.
+
+ The generation count protects this function against races with
+ key_create/key_delete; the worst thing that can happen is that a
+ value is successfully stored into a dead generation (and then
+ immediately becomes invalid). However, we do have to make sure
+ to read tsd_keys.generation[key] atomically. */
+
+int
+__gthread_setspecific (__gthread_key_t key, void *value)
+{
+ struct tsd_data *data;
+ WIND_TCB *tcb;
+ unsigned int generation;
+
+ if (key >= MAX_KEYS)
+ return EINVAL;
+
+ tcb = taskTcb (taskIdSelf ());
+ data = __gthread_get_tsd_data (tcb);
+ if (!data)
+ {
+ data = malloc (sizeof (struct tsd_data));
+ if (!data)
+ return ENOMEM;
+
+ memset (data, 0, sizeof (struct tsd_data));
+ __gthread_set_tsd_data (tcb, data);
+ }
+
+ generation = tsd_keys.generation[key];
+
+ if (generation & 1)
+ return EINVAL;
+
+ data->generation[key] = generation;
+ data->values[key] = value;
+
+ return 0;
+}
diff --git a/contrib/gcc/config/vxworks.h b/contrib/gcc/config/vxworks.h
new file mode 100644
index 0000000..085eb8c
--- /dev/null
+++ b/contrib/gcc/config/vxworks.h
@@ -0,0 +1,64 @@
+/* Common VxWorks target definitions for GCC.
+ Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Wind River Systems.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Specify what to link with. */
+/* VxWorks does all the library stuff itself. */
+#undef LIB_SPEC
+#define LIB_SPEC ""
+
+#undef LINK_SPEC
+#define LINK_SPEC "-r"
+
+/* VxWorks provides the functionality of crt0.o and friends itself. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC ""
+
+/* VxWorks cannot have dots in constructor labels, because it uses a
+ mutant variation of collect2 that generates C code instead of
+ assembly. Thus each constructor label must be a legitimate C
+ symbol. FIXME: Have VxWorks use real collect2 instead. */
+
+#undef NO_DOLLAR_IN_LABEL
+#define NO_DOT_IN_LABEL
+
+/* enable #pragma pack(n) */
+#define HANDLE_SYSV_PRAGMA
+
+/* No underscore is prepended to any C symbol name. */
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+
+/* VxWorks uses wchar_t == unsigned short (UCS2) on all architectures. */
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "short unsigned int"
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 16
+
+/* Dwarf2 unwind info is not supported. */
+#define DWARF2_UNWIND_INFO 0
+/* Weak symbols and link-once sections are not enabled by default. */
+#define DEFAULT_USE_WEAK 0
+
+/* Only supported debug format is Dwarf2. */
+#undef DBX_DEBUGGING_INFO
diff --git a/contrib/gcc/config/windiss.h b/contrib/gcc/config/windiss.h
new file mode 100644
index 0000000..7aef9b6
--- /dev/null
+++ b/contrib/gcc/config/windiss.h
@@ -0,0 +1,38 @@
+/* Support for GCC using WindISS simulator.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by CodeSourcery, LLC.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* windiss uses wchar_t == unsigned short (UCS2) on all architectures. */
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "short unsigned int"
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 16
+
+/* windiss has wint_t == int */
+#undef WINT_TYPE
+#define WINT_TYPE "int"
+
+/* No profiling. */
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(FILE, LABELNO) \
+{ \
+ sorry ("profiler support for WindISS"); \
+}
OpenPOWER on IntegriCloud