summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/rs6000
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
commit5e00ec74d8ce58f99801200d4d3d0412c7cc1b28 (patch)
tree052f4bb635f2bea2c5e350bd60c902be100a0d1e /contrib/gcc/config/rs6000
parent87b8398a7d9f9bf0e28bbcd54a4fc27db2125f38 (diff)
downloadFreeBSD-src-5e00ec74d8ce58f99801200d4d3d0412c7cc1b28.zip
FreeBSD-src-5e00ec74d8ce58f99801200d4d3d0412c7cc1b28.tar.gz
Gcc 3.4.2 20040728.
Diffstat (limited to 'contrib/gcc/config/rs6000')
-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
76 files changed, 12878 insertions, 7177 deletions
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)
OpenPOWER on IntegriCloud