diff options
Diffstat (limited to 'gcc-4.8.1/gcc/config/rs6000')
127 files changed, 0 insertions, 83177 deletions
diff --git a/gcc-4.8.1/gcc/config/rs6000/40x.md b/gcc-4.8.1/gcc/config/rs6000/40x.md deleted file mode 100644 index ab0cf0631..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/40x.md +++ /dev/null @@ -1,120 +0,0 @@ -;; Scheduling description for IBM PowerPC 403 and PowerPC 405 processors. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_automaton "ppc40x,ppc40xiu") -(define_cpu_unit "bpu_40x,fpu_405" "ppc40x") -(define_cpu_unit "iu_40x" "ppc40xiu") - -;; 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,\ - load_l,store_c,sync") - (eq_attr "cpu" "ppc403,ppc405")) - "iu_40x") - -(define_insn_reservation "ppc403-store" 2 - (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,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc403,ppc405")) - "iu_40x") - -(define_insn_reservation "ppc403-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc403,ppc405")) - "iu_40x,iu_40x") - -(define_insn_reservation "ppc403-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc403,ppc405")) - "iu_40x,iu_40x,iu_40x") - -(define_insn_reservation "ppc403-compare" 3 - (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare,\ - var_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,isync") - (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/gcc-4.8.1/gcc/config/rs6000/440.md b/gcc-4.8.1/gcc/config/rs6000/440.md deleted file mode 100644 index fe70be0fb..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/440.md +++ /dev/null @@ -1,133 +0,0 @@ -;; Scheduling description for IBM PowerPC 440 processor. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; GCC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; 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,\ - load_l,store_c,sync") - (eq_attr "cpu" "ppc440")) - "ppc440_issue,ppc440_l_pipe") - -(define_insn_reservation "ppc440-store" 3 - (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,insert_dword,shift,\ - trap,var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc440")) - "ppc440_issue,ppc440_i_pipe|ppc440_j_pipe") - -(define_insn_reservation "ppc440-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc440")) - "ppc440_issue_0+ppc440_issue_1,\ - ppc440_i_pipe|ppc440_j_pipe,ppc440_i_pipe|ppc440_j_pipe") - -(define_insn_reservation "ppc440-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc440")) - "ppc440_issue_0+ppc440_issue_1,ppc440_i_pipe|ppc440_j_pipe,\ - ppc440_i_pipe|ppc440_j_pipe,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,isync") - (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/gcc-4.8.1/gcc/config/rs6000/476.h b/gcc-4.8.1/gcc/config/rs6000/476.h deleted file mode 100644 index f0a928ff6..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/476.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Enable IBM PowerPC 476 support. - Copyright (C) 2011-2013 Free Software Foundation, Inc. - Contributed by Peter Bergner (bergner@vnet.ibm.com) - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_LINK_STACK -#define TARGET_LINK_STACK (rs6000_link_stack) - -#undef SET_TARGET_LINK_STACK -#define SET_TARGET_LINK_STACK(X) do { TARGET_LINK_STACK = (X); } while (0) - -#undef TARGET_ASM_CODE_END -#define TARGET_ASM_CODE_END rs6000_code_end diff --git a/gcc-4.8.1/gcc/config/rs6000/476.md b/gcc-4.8.1/gcc/config/rs6000/476.md deleted file mode 100644 index 4254659d7..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/476.md +++ /dev/null @@ -1,141 +0,0 @@ -;; Scheduling description for IBM PowerPC 476 processor. -;; Copyright (C) 2009-2013 Free Software Foundation, Inc. -;; Contributed by Peter Bergner (bergner@vnet.ibm.com). -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; GCC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; PPC476 Embedded PowerPC controller -;; 3 issue (476) / 4 issue (476fp) -;; -;; i_pipe - complex integer / compare -;; lj_pipe - load-store / simple integer arithmetic -;; b_pipe - branch pipe -;; f_pipe - floating point arithmetic - -(define_automaton "ppc476_core,ppc476_apu") - -(define_cpu_unit "ppc476_i_pipe,ppc476_lj_pipe,ppc476_b_pipe" "ppc476_core") -(define_cpu_unit "ppc476_issue_fp,ppc476_f_pipe" "ppc476_apu") -(define_cpu_unit "ppc476_issue_0,ppc476_issue_1,ppc476_issue_2" "ppc476_core") - -(define_reservation "ppc476_issue" "ppc476_issue_0|ppc476_issue_1|ppc476_issue_2") -(define_reservation "ppc476_issue2" "ppc476_issue_0+ppc476_issue_1\ - |ppc476_issue_0+ppc476_issue_2\ - |ppc476_issue_1+ppc476_issue_2") -(define_reservation "ppc476_issue3" "ppc476_issue_0+ppc476_issue_1+ppc476_issue_2") - -(define_insn_reservation "ppc476-load" 4 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ - load_l,store_c,sync") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_lj_pipe") - -(define_insn_reservation "ppc476-store" 4 - (and (eq_attr "type" "store,store_ux,store_u") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_lj_pipe") - -(define_insn_reservation "ppc476-fpload" 4 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_lj_pipe") - -(define_insn_reservation "ppc476-fpstore" 4 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_lj_pipe") - -(define_insn_reservation "ppc476-simple-integer" 1 - (and (eq_attr "type" "integer,insert_word,var_shift_rotate,exts,shift") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_i_pipe|ppc476_lj_pipe") - -(define_insn_reservation "ppc476-complex-integer" 1 - (and (eq_attr "type" "cmp,cr_logical,delayed_cr,cntlz,isel,isync,sync,trap,popcnt") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_i_pipe") - -(define_insn_reservation "ppc476-compare" 4 - (and (eq_attr "type" "compare,delayed_compare,fast_compare,mfcr,mfcrf,\ - mtcr,mfjmpr,mtjmpr,var_delayed_compare") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_i_pipe") - -(define_insn_reservation "ppc476-imul" 4 - (and (eq_attr "type" "imul,imul_compare,imul2,imul3") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_i_pipe") - -(define_insn_reservation "ppc476-idiv" 11 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_i_pipe*11") - -(define_insn_reservation "ppc476-branch" 1 - (and (eq_attr "type" "branch,jmpreg") - (eq_attr "cpu" "ppc476")) - "ppc476_issue,\ - ppc476_b_pipe") - -(define_insn_reservation "ppc476-two" 2 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc476")) - "ppc476_issue2,\ - ppc476_i_pipe|ppc476_lj_pipe,\ - ppc476_i_pipe|ppc476_lj_pipe") - -(define_insn_reservation "ppc476-three" 3 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc476")) - "ppc476_issue3,\ - ppc476_i_pipe|ppc476_lj_pipe,\ - ppc476_i_pipe|ppc476_lj_pipe,\ - ppc476_i_pipe|ppc476_lj_pipe") - -(define_insn_reservation "ppc476-fpcompare" 6 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "ppc476")) - "ppc476_issue+ppc476_issue_fp,\ - ppc476_f_pipe+ppc476_i_pipe") - -(define_insn_reservation "ppc476-fp" 6 - (and (eq_attr "type" "fp,dmul") - (eq_attr "cpu" "ppc476")) - "ppc476_issue_fp,\ - ppc476_f_pipe") - -(define_insn_reservation "ppc476-sdiv" 19 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppc476")) - "ppc476_issue_fp, - ppc476_f_pipe*19") - -(define_insn_reservation "ppc476-ddiv" 33 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppc476")) - "ppc476_issue_fp,\ - ppc476_f_pipe*33") - diff --git a/gcc-4.8.1/gcc/config/rs6000/476.opt b/gcc-4.8.1/gcc/config/rs6000/476.opt deleted file mode 100644 index 7d01b3f19..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/476.opt +++ /dev/null @@ -1,24 +0,0 @@ -; IBM PowerPC 476 options. -; -; Copyright (C) 2011-2013 Free Software Foundation, Inc. -; Contributed by Peter Bergner (bergner@vnet.ibm.com) -; -; This file is part of GCC. -; -; GCC is free software; you can redistribute it and/or modify it under -; the terms of the GNU General Public License as published by the Free -; Software Foundation; either version 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -; WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -mpreserve-link-stack -Target Var(rs6000_link_stack) Init(-1) Save -Preserve the PowerPC 476's link stack by matching up a blr with the bcl/bl insns used for GOT accesses diff --git a/gcc-4.8.1/gcc/config/rs6000/601.md b/gcc-4.8.1/gcc/config/rs6000/601.md deleted file mode 100644 index d9170dc8e..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/601.md +++ /dev/null @@ -1,136 +0,0 @@ -;; Scheduling description for PowerPC 601 processor. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_automaton "ppc601,ppc601fp") -(define_cpu_unit "iu_ppc601" "ppc601") -(define_cpu_unit "fpu_ppc601" "ppc601fp") -(define_cpu_unit "bpu_ppc601" "ppc601") - -;; PPC601 32-bit IU, FPU, BPU - -(define_insn_reservation "ppc601-load" 2 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ - load_l,store_c,sync") - (eq_attr "cpu" "ppc601")) - "iu_ppc601") - -(define_insn_reservation "ppc601-store" 2 - (and (eq_attr "type" "store,store_ux,store_u") - (eq_attr "cpu" "ppc601")) - "iu_ppc601") - -(define_insn_reservation "ppc601-fpload" 3 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "ppc601")) - "iu_ppc601") - -(define_insn_reservation "ppc601-fpstore" 3 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppc601")) - "iu_ppc601+fpu_ppc601") - -(define_insn_reservation "ppc601-integer" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,shift,\ - trap,var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc601")) - "iu_ppc601") - -(define_insn_reservation "ppc601-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc601")) - "iu_ppc601,iu_ppc601") - -(define_insn_reservation "ppc601-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc601")) - "iu_ppc601,iu_ppc601,iu_ppc601") - -(define_insn_reservation "ppc601-imul" 5 - (and (eq_attr "type" "imul,imul2,imul3,imul_compare") - (eq_attr "cpu" "ppc601")) - "iu_ppc601*5") - -(define_insn_reservation "ppc601-idiv" 36 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppc601")) - "iu_ppc601*36") - -; compare executes on integer unit, but feeds insns which -; execute on the branch unit. -(define_insn_reservation "ppc601-compare" 3 - (and (eq_attr "type" "cmp,compare,delayed_compare,\ - var_delayed_compare") - (eq_attr "cpu" "ppc601")) - "iu_ppc601,nothing,bpu_ppc601") - -(define_insn_reservation "ppc601-fpcompare" 5 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "ppc601")) - "(fpu_ppc601+iu_ppc601*2),nothing*2,bpu_ppc601") - -(define_insn_reservation "ppc601-fp" 4 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "ppc601")) - "fpu_ppc601") - -(define_insn_reservation "ppc601-dmul" 5 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "ppc601")) - "fpu_ppc601*2") - -(define_insn_reservation "ppc601-sdiv" 17 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppc601")) - "fpu_ppc601*17") - -(define_insn_reservation "ppc601-ddiv" 31 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppc601")) - "fpu_ppc601*31") - -(define_insn_reservation "ppc601-mfcr" 2 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "ppc601")) - "iu_ppc601,bpu_ppc601") - -(define_insn_reservation "ppc601-mtcr" 4 - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "ppc601")) - "iu_ppc601,bpu_ppc601") - -(define_insn_reservation "ppc601-crlogical" 4 - (and (eq_attr "type" "cr_logical,delayed_cr") - (eq_attr "cpu" "ppc601")) - "bpu_ppc601") - -(define_insn_reservation "ppc601-mtjmpr" 4 - (and (eq_attr "type" "mtjmpr") - (eq_attr "cpu" "ppc601")) - "iu_ppc601,bpu_ppc601") - -(define_insn_reservation "ppc601-mfjmpr" 2 - (and (eq_attr "type" "mfjmpr") - (eq_attr "cpu" "ppc601")) - "iu_ppc601,bpu_ppc601") - -(define_insn_reservation "ppc601-branch" 1 - (and (eq_attr "type" "jmpreg,branch,isync") - (eq_attr "cpu" "ppc601")) - "bpu_ppc601") - diff --git a/gcc-4.8.1/gcc/config/rs6000/603.md b/gcc-4.8.1/gcc/config/rs6000/603.md deleted file mode 100644 index 00627f9e1..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/603.md +++ /dev/null @@ -1,143 +0,0 @@ -;; Scheduling description for PowerPC 603 processor. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(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,load_l") - (eq_attr "cpu" "ppc603")) - "lsu_603") - -(define_insn_reservation "ppc603-store" 2 - (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppc603")) - "lsu_603*2") - -(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-storec" 8 - (and (eq_attr "type" "store_c") - (eq_attr "cpu" "ppc603")) - "lsu_603") - -(define_insn_reservation "ppc603-integer" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc603")) - "iu_603") - -(define_insn_reservation "ppc603-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc603")) - "iu_603,iu_603") - -(define_insn_reservation "ppc603-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc603")) - "iu_603,iu_603,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,\ - var_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,isync,sync") - (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/gcc-4.8.1/gcc/config/rs6000/6xx.md b/gcc-4.8.1/gcc/config/rs6000/6xx.md deleted file mode 100644 index 361989d43..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/6xx.md +++ /dev/null @@ -1,275 +0,0 @@ -;; Scheduling description for PowerPC 604, PowerPC 604e, PowerPC 620, -;; and PowerPC 630 processors. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(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" 3 - (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-llsc" 3 - (and (eq_attr "type" "load_l,store_c") - (eq_attr "cpu" "ppc604,ppc604e")) - "lsu_6xx") - -(define_insn_reservation "ppc630-llsc" 4 - (and (eq_attr "type" "load_l,store_c") - (eq_attr "cpu" "ppc620,ppc630")) - "lsu_6xx") - -(define_insn_reservation "ppc604-integer" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) - "iu1_6xx|iu2_6xx") - -(define_insn_reservation "ppc604-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) - "iu1_6xx|iu2_6xx,iu1_6xx|iu2_6xx") - -(define_insn_reservation "ppc604-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) - "iu1_6xx|iu2_6xx,iu1_6xx|iu2_6xx,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,\ - var_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") - -(define_insn_reservation "ppc604-isync" 0 - (and (eq_attr "type" "isync") - (eq_attr "cpu" "ppc604,ppc604e")) - "bpu_6xx") - -(define_insn_reservation "ppc630-isync" 6 - (and (eq_attr "type" "isync") - (eq_attr "cpu" "ppc620,ppc630")) - "bpu_6xx") - -(define_insn_reservation "ppc604-sync" 35 - (and (eq_attr "type" "sync") - (eq_attr "cpu" "ppc604,ppc604e")) - "lsu_6xx") - -(define_insn_reservation "ppc630-sync" 26 - (and (eq_attr "type" "sync") - (eq_attr "cpu" "ppc620,ppc630")) - "lsu_6xx") - diff --git a/gcc-4.8.1/gcc/config/rs6000/7450.md b/gcc-4.8.1/gcc/config/rs6000/7450.md deleted file mode 100644 index 59fe15fda..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/7450.md +++ /dev/null @@ -1,185 +0,0 @@ -;; Scheduling description for Motorola PowerPC 7450 processor. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_automaton "ppc7450,ppc7450mciu,ppc7450fp,ppc7450vec") -(define_cpu_unit "iu1_7450,iu2_7450,iu3_7450" "ppc7450") -(define_cpu_unit "mciu_7450" "ppc7450mciu") -(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-llsc" 3 - (and (eq_attr "type" "load_l,store_c") - (eq_attr "cpu" "ppc7450")) - "ppc7450_du,lsu_7450") - -(define_insn_reservation "ppc7450-sync" 35 - (and (eq_attr "type" "sync") - (eq_attr "cpu" "ppc7450")) - "ppc7450_du,lsu_7450") - -(define_insn_reservation "ppc7450-integer" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,shift,\ - trap,var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc7450")) - "ppc7450_du,iu1_7450|iu2_7450|iu3_7450") - -(define_insn_reservation "ppc7450-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc7450")) - "ppc7450_du,iu1_7450|iu2_7450|iu3_7450,iu1_7450|iu2_7450|iu3_7450") - -(define_insn_reservation "ppc7450-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc7450")) - "ppc7450_du,iu1_7450|iu2_7450|iu3_7450,\ - iu1_7450|iu2_7450|iu3_7450,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,\ - var_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,isync") - (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/gcc-4.8.1/gcc/config/rs6000/750cl.h b/gcc-4.8.1/gcc/config/rs6000/750cl.h deleted file mode 100644 index dfb5459b8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/750cl.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Enable 750cl paired single support. - Copyright (C) 2007-2013 Free Software Foundation, Inc. - Contributed by Revital Eres (eres@il.ibm.com) - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_PAIRED_FLOAT -#define TARGET_PAIRED_FLOAT rs6000_paired_float - -#undef ASM_CPU_SPEC -#define ASM_CPU_SPEC "-m750cl" - diff --git a/gcc-4.8.1/gcc/config/rs6000/7xx.md b/gcc-4.8.1/gcc/config/rs6000/7xx.md deleted file mode 100644 index 32dc20b45..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/7xx.md +++ /dev/null @@ -1,184 +0,0 @@ -;; Scheduling description for Motorola PowerPC 750 and PowerPC 7400 processors. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(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,load_l") - (eq_attr "cpu" "ppc750,ppc7400")) - "ppc750_du,lsu_7xx") - -(define_insn_reservation "ppc750-store" 2 - (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-storec" 8 - (and (eq_attr "type" "store_c") - (eq_attr "cpu" "ppc750,ppc7400")) - "ppc750_du,lsu_7xx") - -(define_insn_reservation "ppc750-integer" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,shift,\ - trap,var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc750,ppc7400")) - "ppc750_du,iu1_7xx|iu2_7xx") - -(define_insn_reservation "ppc750-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc750,ppc7400")) - "ppc750_du,iu1_7xx|iu2_7xx,iu1_7xx|iu2_7xx") - -(define_insn_reservation "ppc750-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc750,ppc7400")) - "ppc750_du,iu1_7xx|iu2_7xx,iu1_7xx|iu2_7xx,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,\ - var_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")) - "nothing,sru_7xx*2") - -(define_insn_reservation "ppc750-mtjmpr" 2 - (and (eq_attr "type" "mtjmpr,isync,sync") - (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,isync") - (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/gcc-4.8.1/gcc/config/rs6000/8540.md b/gcc-4.8.1/gcc/config/rs6000/8540.md deleted file mode 100644 index 26d7ce45b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/8540.md +++ /dev/null @@ -1,250 +0,0 @@ -;; Pipeline description for Motorola PowerPC 8540 processor. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(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 cannot 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 cannot 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,insert_dword,cmp,compare,\ - delayed_compare,var_delayed_compare,fast_compare,\ - shift,trap,var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppc8540,ppc8548")) - "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") - -(define_insn_reservation "ppc8540_two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppc8540,ppc8548")) - "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\ - ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") - -(define_insn_reservation "ppc8540_three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppc8540,ppc8548")) - "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\ - ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\ - 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,isync") - (eq_attr "cpu" "ppc8540,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "ppc8540_decode,ppc8540_bu,ppc8540_retire") - -;; Mfcr -(define_insn_reservation "ppc8540_mfcr" 1 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "ppc8540,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,\ - load_l,sync") - (eq_attr "cpu" "ppc8540,ppc8548")) - "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,store_c") - (eq_attr "cpu" "ppc8540,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "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,ppc8548")) - "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire") diff --git a/gcc-4.8.1/gcc/config/rs6000/a2.md b/gcc-4.8.1/gcc/config/rs6000/a2.md deleted file mode 100644 index 571e2565f..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/a2.md +++ /dev/null @@ -1,134 +0,0 @@ -;; Scheduling description for PowerPC A2 processors. -;; Copyright (C) 2009-2013 Free Software Foundation, Inc. -;; Contributed by Ben Elliston (bje@au.ibm.com) - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_automaton "ppca2") - -;; CPU units - -;; The multiplier pipeline. -(define_cpu_unit "mult" "ppca2") - -;; The auxiliary processor unit (FP/vector unit). -(define_cpu_unit "axu" "ppca2") - -;; D.4.6 -;; Some peculiarities for certain SPRs - -(define_insn_reservation "ppca2-mfcr" 1 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "ppca2")) - "nothing") - -(define_insn_reservation "ppca2-mfjmpr" 5 - (and (eq_attr "type" "mfjmpr") - (eq_attr "cpu" "ppca2")) - "nothing") - -(define_insn_reservation "ppca2-mtjmpr" 5 - (and (eq_attr "type" "mtjmpr") - (eq_attr "cpu" "ppca2")) - "nothing") - -;; D.4.8 -(define_insn_reservation "ppca2-imul" 1 - (and (eq_attr "type" "imul,imul2,imul3,imul_compare") - (eq_attr "cpu" "ppca2")) - "nothing") - -;; FIXME: latency and multiplier reservation for 64-bit multiply? -(define_insn_reservation "ppca2-lmul" 6 - (and (eq_attr "type" "lmul,lmul_compare") - (eq_attr "cpu" "ppca2")) - "mult*3") - -;; D.4.9 -(define_insn_reservation "ppca2-idiv" 32 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppca2")) - "mult*32") - -(define_insn_reservation "ppca2-ldiv" 65 - (and (eq_attr "type" "ldiv") - (eq_attr "cpu" "ppca2")) - "mult*65") - -;; D.4.13 -(define_insn_reservation "ppca2-load" 5 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u") - (eq_attr "cpu" "ppca2")) - "nothing") - -;; D.8.1 -(define_insn_reservation "ppca2-fp" 6 - (and (eq_attr "type" "fp") ;; Ignore fpsimple insn types (SPE only). - (eq_attr "cpu" "ppca2")) - "axu") - -;; D.8.4 -(define_insn_reservation "ppca2-fp-load" 6 - (and (eq_attr "type" "fpload,fpload_u,fpload_ux") - (eq_attr "cpu" "ppca2")) - "axu") - -;; D.8.5 -(define_insn_reservation "ppca2-fp-store" 2 - (and (eq_attr "type" "fpstore,fpstore_u,fpstore_ux") - (eq_attr "cpu" "ppca2")) - "axu") - -;; D.8.6 -(define_insn_reservation "ppca2-fpcompare" 5 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "ppca2")) - "axu") - -;; D.8.7 -;; -;; Instructions from the same thread succeeding the floating-point -;; divide cannot be executed until the floating-point divide has -;; completed. Since there is nothing else we can do, this thread will -;; just have to stall. - -(define_insn_reservation "ppca2-ddiv" 72 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppca2")) - "axu") - -(define_insn_reservation "ppca2-sdiv" 59 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppca2")) - "axu") - -;; D.8.8 -;; -;; Instructions from the same thread succeeding the floating-point -;; divide cannot be executed until the floating-point divide has -;; completed. Since there is nothing else we can do, this thread will -;; just have to stall. - -(define_insn_reservation "ppca2-dsqrt" 69 - (and (eq_attr "type" "dsqrt") - (eq_attr "cpu" "ppca2")) - "axu") - -(define_insn_reservation "ppca2-ssqrt" 65 - (and (eq_attr "type" "ssqrt") - (eq_attr "cpu" "ppca2")) - "axu") diff --git a/gcc-4.8.1/gcc/config/rs6000/aix-stdint.h b/gcc-4.8.1/gcc/config/rs6000/aix-stdint.h deleted file mode 100644 index b62ae45b7..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix-stdint.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Definitions for <stdint.h> types on systems using AIX. - Copyright (C) 2009-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#define SIG_ATOMIC_TYPE "int" - -#define INT8_TYPE "signed char" -#define INT16_TYPE "short int" -#define INT32_TYPE "int" -#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") -#define UINT8_TYPE "unsigned char" -#define UINT16_TYPE "short unsigned int" -#define UINT32_TYPE "unsigned int" -#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") - -#define INT_LEAST8_TYPE "signed char" -#define INT_LEAST16_TYPE "short int" -#define INT_LEAST32_TYPE "int" -#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") -#define UINT_LEAST8_TYPE "unsigned char" -#define UINT_LEAST16_TYPE "short unsigned int" -#define UINT_LEAST32_TYPE "unsigned int" -#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") - -#define INT_FAST8_TYPE "signed char" -#define INT_FAST16_TYPE "short int" -#define INT_FAST32_TYPE "int" -#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") -#define UINT_FAST8_TYPE "unsigned char" -#define UINT_FAST16_TYPE "short unsigned int" -#define UINT_FAST32_TYPE "unsigned int" -#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") - -#define INTPTR_TYPE "long int" -#define UINTPTR_TYPE "long unsigned int" - diff --git a/gcc-4.8.1/gcc/config/rs6000/aix.h b/gcc-4.8.1/gcc/config/rs6000/aix.h deleted file mode 100644 index f81666a3b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix.h +++ /dev/null @@ -1,220 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX. - Copyright (C) 2000-2013 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Yes! We are AIX! */ -#define DEFAULT_ABI ABI_AIX -#undef TARGET_AIX -#define TARGET_AIX 1 - -/* Linux64.h wants to redefine TARGET_AIX based on -m64, but it can't be used - in the #if conditional in options-default.h, so provide another macro. */ -#undef TARGET_AIX_OS -#define TARGET_AIX_OS 1 - -/* AIX always has a TOC. */ -#define TARGET_NO_TOC 0 -#define TARGET_TOC 1 -#define FIXED_R2 1 - -/* AIX allows r13 to be used in 32-bit mode. */ -#define FIXED_R13 0 - -/* 32-bit and 64-bit AIX stack boundary is 128. */ -#undef STACK_BOUNDARY -#define STACK_BOUNDARY 128 - -#undef TARGET_IEEEQUAD -#define TARGET_IEEEQUAD 0 - -/* The AIX linker will discard static constructors in object files before - collect has a chance to see them, so scan the object files directly. */ -#define COLLECT_EXPORT_LIST - -#if HAVE_AS_REF -/* Issue assembly directives that create a reference to the given DWARF table - identifier label from the current function section. This is defined to - ensure we drag frame frame tables associated with needed function bodies in - a link with garbage collection activated. */ -#define ASM_OUTPUT_DWARF_TABLE_REF rs6000_aix_asm_output_dwarf_table_ref -#endif - -/* This is the only version of nm that collect2 can work with. */ -#define REAL_NM_FILE_NAME "/usr/ucb/nm" - -#define USER_LABEL_PREFIX "" - -/* Don't turn -B into -L if the argument specifies a relative file name. */ -#define RELATIVE_PREFIX_NOT_LINKDIR - -/* Because of the above, we must have gcc search itself to find libgcc.a. */ -#define LINK_LIBGCC_SPECIAL_1 - -#define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \ - -brename:malloc,__wrap_malloc -brename:__real_malloc,malloc \ - -brename:free,__wrap_free -brename:__real_free,free \ - -brename:calloc,__wrap_calloc -brename:__real_calloc,calloc \ - -brename:realloc,__wrap_realloc -brename:__real_realloc,realloc \ - -brename:mmap,__wrap_mmap -brename:__real_mmap,mmap \ - -brename:munmap,__wrap_munmap -brename:__real_munmap,munmap \ - -brename:alloca,__wrap_alloca -brename:__real_alloca,alloca \ -} %{fmudflapth: \ - -brename:pthread_create,__wrap_pthread_create \ - -brename:__real_pthread_create,pthread_create \ - -brename:pthread_join,__wrap_pthread_join \ - -brename:__real_pthread_join,pthread_join \ - -brename:pthread_exit,__wrap_pthread_exit \ - -brename:__real_pthread_exit,pthread_exit \ -}} %{fmudflap|fmudflapth: \ - -brename:main,__wrap_main -brename:__real_main,main \ -}" - -#define MFLIB_SPEC " %{fmudflap: -lmudflap \ - %{static:%(link_gcc_c_sequence) -lmudflap}} \ - %{fmudflapth: -lmudflapth -lpthread \ - %{static:%(link_gcc_c_sequence) -lmudflapth}} " - -/* Names to predefine in the preprocessor for this target machine. */ -#define TARGET_OS_AIX_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("_IBMR2"); \ - builtin_define ("_POWER"); \ - builtin_define ("__powerpc__"); \ - builtin_define ("__PPC__"); \ - builtin_define ("__unix__"); \ - builtin_define ("_AIX"); \ - builtin_define ("_AIX32"); \ - builtin_define ("_AIX41"); \ - builtin_define ("_LONG_LONG"); \ - if (TARGET_LONG_DOUBLE_128) \ - builtin_define ("__LONGDOUBLE128"); \ - builtin_assert ("system=unix"); \ - builtin_assert ("system=aix"); \ - } \ - while (0) - -/* Define appropriate architecture macros for preprocessor depending on - target switches. */ - -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\ - %{ansi: -D_ANSI_C_SOURCE}" - -#define CC1_SPEC "%(cc1_cpu)" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "" - -/* Tell the assembler to assume that all undefined names are external. - - 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 - rs6000_xcoff_file_start will no longer be needed. */ - -/* #define ASM_SPEC "-u %(asm_cpu)" */ - -/* Default location of syscalls.exp under AIX */ -#define LINK_SYSCALLS_SPEC "-bI:%R/lib/syscalls.exp" - -/* Default location of libg.exp under AIX */ -#define LINK_LIBG_SPEC "-bexport:%R/usr/lib/libg.exp" - -/* Define the options for the binder: Start text at 512, align all segments - to 512 bytes, and warn if there is text relocation. - - The -bhalt:4 option supposedly changes the level at which ld will abort, - but it also suppresses warnings about multiply defined symbols and is - used by the AIX cc command. So we use it here. - - -bnodelcsect undoes a poor choice of default relating to multiply-defined - csects. See AIX documentation for more information about this. - - -bM:SRE tells the linker that the output file is Shared REusable. Note - that to actually build a shared library you will also need to specify an - export list with the -Wl,-bE option. */ - -#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ -%{static:-bnso %(link_syscalls) } \ -%{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}" - -/* Profiled library versions are used by linking with special directories. */ -#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ -%{p:-L%R/lib/profiled -L%R/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc" - -/* Static linking with shared libstdc++ requires libsupc++ as well. */ -#define LIBSTDCXX_STATIC "supc++" - -/* 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 == 0 \ - && TYPE_MODE (strip_array_types (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. */ -#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 - -/* 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 - -/* Define any extra SPECS that the compiler needs to generate. */ -#undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ - { "link_syscalls", LINK_SYSCALLS_SPEC }, \ - { "link_libg", LINK_LIBG_SPEC } - -#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL) - -/* 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 - -/* WINT_TYPE */ -#define WINT_TYPE "int" - -/* Static stack checking is supported by means of probes. */ -#define STACK_CHECK_STATIC_BUILTIN 1 diff --git a/gcc-4.8.1/gcc/config/rs6000/aix43.h b/gcc-4.8.1/gcc/config/rs6000/aix43.h deleted file mode 100644 index 70db7f748..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix43.h +++ /dev/null @@ -1,161 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX version 4.3. - Copyright (C) 1998-2013 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@gnu.org). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control in TARGET_OPTION_OVERRIDE. */ - -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (TARGET_64BIT && ! TARGET_POWERPC64) \ - { \ - rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ - warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ - } \ - if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ - { \ - rs6000_long_double_type_size = 64; \ - if (global_options_set.x_rs6000_long_double_type_size) \ - warning (0, "soft-float and long-double-128 are incompatible"); \ - } \ - if (TARGET_POWERPC64 && ! TARGET_64BIT) \ - { \ - error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ - } \ -} while (0); - -#undef ASM_SPEC -#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" - -/* 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: %(asm_default)} \ - %{mpowerpc64: -mppc64}}} \ -%{mcpu=power3: -m620} \ -%{mcpu=power4: -m620} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rs64a: -mppc} \ -%{mcpu=601: -m601} \ -%{mcpu=602: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=604e: -m604} \ -%{mcpu=620: -m620} \ -%{mcpu=630: -m620}" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc" - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("_AIX43"); \ - TARGET_OS_AIX_CPP_BUILTINS (); \ - } \ - while (0) - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\ - %{ansi: -D_ANSI_C_SOURCE}\ - %{maix64: -D__64BIT__}\ - %{mpe: -I%R/usr/lpp/ppe.poe/include}\ - %{pthread: -D_THREAD_SAFE}" - -/* The GNU C++ standard library requires that these macros be - defined. */ -#undef CPLUSPLUS_CPP_SPEC -#define CPLUSPLUS_CPP_SPEC \ - "-D_ALL_SOURCE \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0 - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC604e - -/* AIX does not support Altivec. */ -#undef TARGET_ALTIVEC -#define TARGET_ALTIVEC 0 -#undef TARGET_ALTIVEC_ABI -#define TARGET_ALTIVEC_ABI 0 - -/* 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 { "mcpu=common" } - -#undef LIB_SPEC -#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{!maix64:%{!shared:%{g*:-lg}}}\ - %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ - %{pthread:-L%R/usr/lib/threads -lpthreads -lc_r %R/usr/lib/libc.a}\ - %{!pthread:-lc}" - -#undef LINK_SPEC -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ - %{mpe:-binitfini:poe_remote_main}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{!shared:\ - %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ - %{!maix64:\ - %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" - -/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */ - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" - -/* AIX 4.2 and above provides initialization and finalization function - support from linker command line. */ -#undef HAS_INIT_SECTION -#define HAS_INIT_SECTION - -#undef LD_INIT_SWITCH -#define LD_INIT_SWITCH "-binitfini" - -/* The IBM AIX 4.x assembler doesn't support forward references in - .set directives. We handle this by deferring the output of .set - directives to the end of the compilation unit. */ -#define TARGET_DEFERRED_OUTPUT_DEFS(DECL,TARGET) true - -/* This target uses the aix64.opt file. */ -#define TARGET_USES_AIX64_OPT 1 - -#define TARGET_AIX_VERSION 43 diff --git a/gcc-4.8.1/gcc/config/rs6000/aix51.h b/gcc-4.8.1/gcc/config/rs6000/aix51.h deleted file mode 100644 index 669dbbe03..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix51.h +++ /dev/null @@ -1,165 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX V5. - Copyright (C) 2001-2013 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@gnu.org). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control in TARGET_OPTION_OVERRIDE. */ - -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (TARGET_64BIT && ! TARGET_POWERPC64) \ - { \ - rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ - warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ - } \ - if (TARGET_POWERPC64 && ! TARGET_64BIT) \ - { \ - error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ - } \ -} while (0); - -#undef ASM_SPEC -#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" - -/* 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: %(asm_default)} \ - %{mpowerpc64: -mppc64}}} \ -%{mcpu=power3: -m620} \ -%{mcpu=power4: -m620} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rs64a: -mppc} \ -%{mcpu=601: -m601} \ -%{mcpu=602: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=604e: -m604} \ -%{mcpu=620: -m620} \ -%{mcpu=630: -m620} \ -%{mcpu=970: -m620} \ -%{mcpu=G5: -m620}" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc" - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("_AIX43"); \ - builtin_define ("_AIX51"); \ - TARGET_OS_AIX_CPP_BUILTINS (); \ - } \ - while (0) - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ - %{ansi: -D_ANSI_C_SOURCE} \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -/* The GNU C++ standard library requires that these macros be - defined. */ -#undef CPLUSPLUS_CPP_SPEC -#define CPLUSPLUS_CPP_SPEC \ - "-D_ALL_SOURCE \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0 - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC604e - -/* AIX does not support Altivec. */ -#undef TARGET_ALTIVEC -#define TARGET_ALTIVEC 0 -#undef TARGET_ALTIVEC_ABI -#define TARGET_ALTIVEC_ABI 0 - -/* 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 { "mcpu=common" } - -#undef LIB_SPEC -#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{!maix64:%{!shared:%{g*:-lg}}}\ - %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ - %{pthread:-lpthreads} -lc" - -#undef LINK_SPEC -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ - %{mpe:-binitfini:poe_remote_main}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{!shared:\ - %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ - %{!maix64:\ - %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" - -/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" - -/* Type used for wchar_t, as a string used in a declaration. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") - -/* Width of wchar_t in bits. */ -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) - -/* AIX 4.2 and above provides initialization and finalization function - support from linker command line. */ -#undef HAS_INIT_SECTION -#define HAS_INIT_SECTION - -#undef LD_INIT_SWITCH -#define LD_INIT_SWITCH "-binitfini" - -/* This target uses the aix64.opt file. */ -#define TARGET_USES_AIX64_OPT 1 - -/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, - but does not have crtbegin/end. */ - -#define TARGET_USE_JCR_SECTION 0 - -#define TARGET_AIX_VERSION 51 diff --git a/gcc-4.8.1/gcc/config/rs6000/aix52.h b/gcc-4.8.1/gcc/config/rs6000/aix52.h deleted file mode 100644 index c57271a5a..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix52.h +++ /dev/null @@ -1,185 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX V5.2. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@gnu.org). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control in TARGET_OPTION_OVERRIDE. */ - -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (TARGET_64BIT && ! TARGET_POWERPC64) \ - { \ - rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ - warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ - } \ - if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ - { \ - rs6000_long_double_type_size = 64; \ - if (global_options_set.x_rs6000_long_double_type_size) \ - warning (0, "soft-float and long-double-128 are incompatible"); \ - } \ - if (TARGET_POWERPC64 && ! TARGET_64BIT) \ - { \ - error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ - } \ -} while (0); - -#undef ASM_SPEC -#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" - -/* 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} \ - %{!mpowerpc64: %(asm_default)}}} \ -%{mcpu=power3: -m620} \ -%{mcpu=power4: -m620} \ -%{mcpu=power5: -m620} \ -%{mcpu=power5+: -m620} \ -%{mcpu=power6: -m620} \ -%{mcpu=power6x: -m620} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rs64a: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=604e: -m604} \ -%{mcpu=620: -m620} \ -%{mcpu=630: -m620} \ -%{mcpu=970: -m620} \ -%{mcpu=G5: -m620}" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc" - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("_AIX43"); \ - builtin_define ("_AIX51"); \ - builtin_define ("_AIX52"); \ - TARGET_OS_AIX_CPP_BUILTINS (); \ - } \ - while (0) - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ - %{ansi: -D_ANSI_C_SOURCE} \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -/* The GNU C++ standard library requires that these macros be - defined. Synchronize with libstdc++ os_defines.h. */ -#undef CPLUSPLUS_CPP_SPEC -#define CPLUSPLUS_CPP_SPEC \ - "-D_ALL_SOURCE \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0 - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWER4 -#undef PROCESSOR_DEFAULT64 -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4 - -/* AIX does not support Altivec. */ -#undef TARGET_ALTIVEC -#define TARGET_ALTIVEC 0 -#undef TARGET_ALTIVEC_ABI -#define TARGET_ALTIVEC_ABI 0 -#undef TARGET_EXTRA_BUILTINS -#define TARGET_EXTRA_BUILTINS 0 - -/* 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 - -#undef LIB_SPEC -#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{!maix64:%{!shared:%{g*:-lg}}}\ - %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ - %{pthread:-lpthreads} -lc" - -#undef LINK_SPEC -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ - %{mpe:-binitfini:poe_remote_main}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{!shared:\ - %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ - %{!maix64:\ - %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" - -/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" - -/* Type used for wchar_t, as a string used in a declaration. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") - -/* Width of wchar_t in bits. */ -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) - -/* AIX 4.2 and above provides initialization and finalization function - support from linker command line. */ -#undef HAS_INIT_SECTION -#define HAS_INIT_SECTION - -#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 - -#ifndef _AIX52 -extern long long int atoll(const char *); -#endif - -/* This target uses the aix64.opt file. */ -#define TARGET_USES_AIX64_OPT 1 - -/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, - but does not have crtbegin/end. */ - -#define TARGET_USE_JCR_SECTION 0 - -#define TARGET_AIX_VERSION 52 diff --git a/gcc-4.8.1/gcc/config/rs6000/aix53.h b/gcc-4.8.1/gcc/config/rs6000/aix53.h deleted file mode 100644 index b1b0759e7..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix53.h +++ /dev/null @@ -1,185 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX V5.3. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@gnu.org). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control in TARGET_OPTION_OVERRIDE. */ - -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (TARGET_64BIT && ! TARGET_POWERPC64) \ - { \ - rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ - warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ - } \ - if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ - { \ - rs6000_long_double_type_size = 64; \ - if (global_options_set.x_rs6000_long_double_type_size) \ - warning (0, "soft-float and long-double-128 are incompatible"); \ - } \ - if (TARGET_POWERPC64 && ! TARGET_64BIT) \ - { \ - error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ - } \ -} while (0); - -#undef ASM_SPEC -#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" - -/* Common ASM definitions used by ASM_SPEC amongst the various targets for - handling -mcpu=xxx switches. There is a parallel list in driver-rs6000.c to - provide the default assembler options if the user uses -mcpu=native, so if - you make changes here, make them there also. */ -#undef ASM_CPU_SPEC -#define ASM_CPU_SPEC \ -"%{!mcpu*: %{!maix64: \ - %{mpowerpc64: -mppc64} \ - %{maltivec: -m970} \ - %{!maltivec: %{!mpowerpc64: %(asm_default)}}}} \ -%{mcpu=native: %(asm_cpu_native)} \ -%{mcpu=power3: -m620} \ -%{mcpu=power4: -mpwr4} \ -%{mcpu=power5: -mpwr5} \ -%{mcpu=power5+: -mpwr5x} \ -%{mcpu=power6: -mpwr6} \ -%{mcpu=power6x: -mpwr6} \ -%{mcpu=power7: -mpwr7} \ -%{mcpu=power8: -mpwr8} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rs64a: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=604e: -m604} \ -%{mcpu=620: -m620} \ -%{mcpu=630: -m620} \ -%{mcpu=970: -m970} \ -%{mcpu=G5: -m970}" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc" - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("_AIX43"); \ - builtin_define ("_AIX51"); \ - builtin_define ("_AIX52"); \ - builtin_define ("_AIX53"); \ - TARGET_OS_AIX_CPP_BUILTINS (); \ - } \ - while (0) - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ - %{ansi: -D_ANSI_C_SOURCE} \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -/* The GNU C++ standard library requires that these macros be - defined. Synchronize with libstdc++ os_defines.h. */ -#undef CPLUSPLUS_CPP_SPEC -#define CPLUSPLUS_CPP_SPEC \ - "-D_ALL_SOURCE \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0 - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWER5 -#undef PROCESSOR_DEFAULT64 -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER5 - -/* 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 - -#undef LIB_SPEC -#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{!maix64:%{!shared:%{g*:-lg}}}\ - %{fprofile-arcs|fprofile-generate*|coverage:-lpthreads}\ - %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ - %{pthread:-lpthreads} -lc" - -#undef LINK_SPEC -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ - %{mpe:-binitfini:poe_remote_main}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{!shared:\ - %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ - %{!maix64:\ - %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" - -/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" - -/* Type used for wchar_t, as a string used in a declaration. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") - -/* Width of wchar_t in bits. */ -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) - -/* AIX 4.2 and above provides initialization and finalization function - support from linker command line. */ -#undef HAS_INIT_SECTION -#define HAS_INIT_SECTION - -#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 - -#ifndef _AIX52 -extern long long int atoll(const char *); -#endif - -/* This target uses the aix64.opt file. */ -#define TARGET_USES_AIX64_OPT 1 - -/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, - but does not have crtbegin/end. */ - -#define TARGET_USE_JCR_SECTION 0 - -#define TARGET_AIX_VERSION 53 diff --git a/gcc-4.8.1/gcc/config/rs6000/aix61.h b/gcc-4.8.1/gcc/config/rs6000/aix61.h deleted file mode 100644 index cd341b97e..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix61.h +++ /dev/null @@ -1,218 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for IBM RS/6000 POWER running AIX V6.1. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by David Edelsohn (edelsohn@gnu.org). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control in TARGET_OPTION_OVERRIDE. */ - -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (TARGET_64BIT && ! TARGET_POWERPC64) \ - { \ - rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ - warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ - } \ - if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ - { \ - rs6000_long_double_type_size = 64; \ - if (global_options_set.x_rs6000_long_double_type_size) \ - warning (0, "soft-float and long-double-128 are incompatible"); \ - } \ - if (TARGET_POWERPC64 && ! TARGET_64BIT) \ - { \ - error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ - } \ - if ((rs6000_isa_flags_explicit \ - & OPTION_MASK_MINIMAL_TOC) != 0) \ - { \ - if (global_options_set.x_rs6000_current_cmodel \ - && rs6000_current_cmodel != CMODEL_SMALL) \ - error ("-mcmodel incompatible with other toc options"); \ - SET_CMODEL (CMODEL_SMALL); \ - } \ - if (rs6000_current_cmodel != CMODEL_SMALL) \ - { \ - TARGET_NO_FP_IN_TOC = 0; \ - TARGET_NO_SUM_IN_TOC = 0; \ - } \ - if (rs6000_current_cmodel == CMODEL_MEDIUM) \ - { \ - rs6000_current_cmodel = CMODEL_LARGE; \ - } \ -} while (0); - -#undef ASM_SPEC -#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" - -/* Common ASM definitions used by ASM_SPEC amongst the various targets for - handling -mcpu=xxx switches. There is a parallel list in driver-rs6000.c to - provide the default assembler options if the user uses -mcpu=native, so if - you make changes here, make them there also. */ -#undef ASM_CPU_SPEC -#define ASM_CPU_SPEC \ -"%{!mcpu*: %{!maix64: \ - %{mpowerpc64: -mppc64} \ - %{maltivec: -m970} \ - %{!maltivec: %{!mpowerpc64: %(asm_default)}}}} \ -%{mcpu=native: %(asm_cpu_native)} \ -%{mcpu=power3: -m620} \ -%{mcpu=power4: -mpwr4} \ -%{mcpu=power5: -mpwr5} \ -%{mcpu=power5+: -mpwr5x} \ -%{mcpu=power6: -mpwr6} \ -%{mcpu=power6x: -mpwr6} \ -%{mcpu=power7: -mpwr7} \ -%{mcpu=power8: -mpwr8} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rs64a: -mppc} \ -%{mcpu=603: -m603} \ -%{mcpu=603e: -m603} \ -%{mcpu=604: -m604} \ -%{mcpu=604e: -m604} \ -%{mcpu=620: -m620} \ -%{mcpu=630: -m620} \ -%{mcpu=970: -m970} \ -%{mcpu=G5: -m970} \ -%{mvsx: %{!mcpu*: -mpwr6}} \ --many" - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mpwr4" - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("_AIX43"); \ - builtin_define ("_AIX51"); \ - builtin_define ("_AIX52"); \ - builtin_define ("_AIX53"); \ - builtin_define ("_AIX61"); \ - TARGET_OS_AIX_CPP_BUILTINS (); \ - } \ - while (0) - -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ - %{ansi: -D_ANSI_C_SOURCE} \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -/* The GNU C++ standard library requires that these macros be - defined. Synchronize with libstdc++ os_defines.h. */ -#undef CPLUSPLUS_CPP_SPEC -#define CPLUSPLUS_CPP_SPEC \ - "-D_ALL_SOURCE -D__COMPATMATH__ \ - %{maix64: -D__64BIT__} \ - %{mpe: -I%R/usr/lpp/ppe.poe/include} \ - %{pthread: -D_THREAD_SAFE}" - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_MFCRF) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWER7 -#undef PROCESSOR_DEFAULT64 -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER7 - -/* AIX 6.1 kernel and assembler have necessary support for Altivec and VSX. */ -#undef OS_MISSING_ALTIVEC - -/* 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 - -#undef LIB_SPEC -#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ - %{!maix64:%{!shared:%{g*:-lg}}}\ - %{fprofile-arcs|fprofile-generate*|coverage:-lpthreads}\ - %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ - %{pthread:-lpthreads} -lc" - -#undef LINK_SPEC -#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ - %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ - %{mpe:-binitfini:poe_remote_main}" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "%{!shared:\ - %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ - %{!maix64:\ - %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ - %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}\ - %{shared:crtcxa_s%O%s;:crtcxa%O%s}" - -/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" - -/* Type used for wchar_t, as a string used in a declaration. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") - -/* Width of wchar_t in bits. */ -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) - -/* AIX 4.2 and above provides initialization and finalization function - support from linker command line. */ -#undef HAS_INIT_SECTION -#define HAS_INIT_SECTION - -#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 - -#ifndef _AIX52 -extern long long int atoll(const char *); -#endif - -/* This target uses the aix64.opt file. */ -#define TARGET_USES_AIX64_OPT 1 - -/* Large TOC Support */ -#ifdef HAVE_LD_LARGE_TOC -#undef TARGET_CMODEL -#define TARGET_CMODEL rs6000_current_cmodel -#define SET_CMODEL(opt) rs6000_current_cmodel = opt -#else -#define SET_CMODEL(opt) do {} while (0) -#endif - -/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, - but does not have crtbegin/end. */ - -#define TARGET_USE_JCR_SECTION 0 - -#define TARGET_AIX_VERSION 61 diff --git a/gcc-4.8.1/gcc/config/rs6000/aix64.opt b/gcc-4.8.1/gcc/config/rs6000/aix64.opt deleted file mode 100644 index e4607d2d0..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/aix64.opt +++ /dev/null @@ -1,55 +0,0 @@ -; Options for the 64-bit flavor of AIX. -; -; Copyright (C) 2005-2013 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 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -; License for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -maix64 -Target Report RejectNegative Negative(maix32) Mask(64BIT) Var(rs6000_isa_flags) -Compile for 64-bit pointers - -maix32 -Target Report RejectNegative Negative(maix64) InverseMask(64BIT) Var(rs6000_isa_flags) -Compile for 32-bit pointers - -mcmodel= -Target RejectNegative Joined Enum(rs6000_cmodel) Var(rs6000_current_cmodel) -Select code model - -Enum -Name(rs6000_cmodel) Type(enum rs6000_cmodel) -Known code models (for use with the -mcmodel= option): - -EnumValue -Enum(rs6000_cmodel) String(small) Value(CMODEL_SMALL) - -EnumValue -Enum(rs6000_cmodel) String(medium) Value(CMODEL_MEDIUM) - -EnumValue -Enum(rs6000_cmodel) String(large) Value(CMODEL_LARGE) - -mpe -Target Report RejectNegative Var(internal_nothing_1) Save -Support message passing with the Parallel Environment - -posix -Driver - -pthread -Driver diff --git a/gcc-4.8.1/gcc/config/rs6000/altivec.h b/gcc-4.8.1/gcc/config/rs6000/altivec.h deleted file mode 100644 index fd6d07f50..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/altivec.h +++ /dev/null @@ -1,492 +0,0 @@ -/* PowerPC AltiVec include file. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Aldy Hernandez (aldyh@redhat.com). - Rewritten by Paolo Bonzini (bonzini@gnu.org). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* Implemented to conform to the specification included in the AltiVec - Technology Programming Interface Manual (ALTIVECPIM/D 6/1999 Rev 0). */ - -#ifndef _ALTIVEC_H -#define _ALTIVEC_H 1 - -#if !defined(__VEC__) || !defined(__ALTIVEC__) -#error Use the "-maltivec" flag to enable PowerPC AltiVec support -#endif - -/* If __APPLE_ALTIVEC__ is defined, the compiler supports 'vector', - 'pixel' and 'bool' as context-sensitive AltiVec keywords (in - non-AltiVec contexts, they revert to their original meanings, - if any), so we do not need to define them as macros. */ - -#if !defined(__APPLE_ALTIVEC__) -/* You are allowed to undef these for C++ compatibility. */ -#define vector __vector -#define pixel __pixel -#define bool __bool -#endif - -/* Condition register codes for AltiVec predicates. */ - -#define __CR6_EQ 0 -#define __CR6_EQ_REV 1 -#define __CR6_LT 2 -#define __CR6_LT_REV 3 - -/* Synonyms. */ -#define vec_vaddcuw vec_addc -#define vec_vand vec_and -#define vec_vandc vec_andc -#define vec_vrfip vec_ceil -#define vec_vcmpbfp vec_cmpb -#define vec_vcmpgefp vec_cmpge -#define vec_vctsxs vec_cts -#define vec_vctuxs vec_ctu -#define vec_vexptefp vec_expte -#define vec_vrfim vec_floor -#define vec_lvx vec_ld -#define vec_lvxl vec_ldl -#define vec_vlogefp vec_loge -#define vec_vmaddfp vec_madd -#define vec_vmhaddshs vec_madds -#define vec_vmladduhm vec_mladd -#define vec_vmhraddshs vec_mradds -#define vec_vnmsubfp vec_nmsub -#define vec_vnor vec_nor -#define vec_vor vec_or -#define vec_vpkpx vec_packpx -#define vec_vperm vec_perm -#define vec_vrefp vec_re -#define vec_vrfin vec_round -#define vec_vrsqrtefp vec_rsqrte -#define vec_vsel vec_sel -#define vec_vsldoi vec_sld -#define vec_vsl vec_sll -#define vec_vslo vec_slo -#define vec_vspltisb vec_splat_s8 -#define vec_vspltish vec_splat_s16 -#define vec_vspltisw vec_splat_s32 -#define vec_vsr vec_srl -#define vec_vsro vec_sro -#define vec_stvx vec_st -#define vec_stvxl vec_stl -#define vec_vsubcuw vec_subc -#define vec_vsum2sws vec_sum2s -#define vec_vsumsws vec_sums -#define vec_vrfiz vec_trunc -#define vec_vxor vec_xor - -/* Functions that are resolved by the backend to one of the - typed builtins. */ -#define vec_vaddfp __builtin_vec_vaddfp -#define vec_addc __builtin_vec_addc -#define vec_vaddsws __builtin_vec_vaddsws -#define vec_vaddshs __builtin_vec_vaddshs -#define vec_vaddsbs __builtin_vec_vaddsbs -#define vec_vavgsw __builtin_vec_vavgsw -#define vec_vavguw __builtin_vec_vavguw -#define vec_vavgsh __builtin_vec_vavgsh -#define vec_vavguh __builtin_vec_vavguh -#define vec_vavgsb __builtin_vec_vavgsb -#define vec_vavgub __builtin_vec_vavgub -#define vec_ceil __builtin_vec_ceil -#define vec_cmpb __builtin_vec_cmpb -#define vec_vcmpeqfp __builtin_vec_vcmpeqfp -#define vec_cmpge __builtin_vec_cmpge -#define vec_vcmpgtfp __builtin_vec_vcmpgtfp -#define vec_vcmpgtsw __builtin_vec_vcmpgtsw -#define vec_vcmpgtuw __builtin_vec_vcmpgtuw -#define vec_vcmpgtsh __builtin_vec_vcmpgtsh -#define vec_vcmpgtuh __builtin_vec_vcmpgtuh -#define vec_vcmpgtsb __builtin_vec_vcmpgtsb -#define vec_vcmpgtub __builtin_vec_vcmpgtub -#define vec_vcfsx __builtin_vec_vcfsx -#define vec_vcfux __builtin_vec_vcfux -#define vec_cts __builtin_vec_cts -#define vec_ctu __builtin_vec_ctu -#define vec_expte __builtin_vec_expte -#define vec_floor __builtin_vec_floor -#define vec_loge __builtin_vec_loge -#define vec_madd __builtin_vec_madd -#define vec_madds __builtin_vec_madds -#define vec_mtvscr __builtin_vec_mtvscr -#define vec_vmaxfp __builtin_vec_vmaxfp -#define vec_vmaxsw __builtin_vec_vmaxsw -#define vec_vmaxsh __builtin_vec_vmaxsh -#define vec_vmaxsb __builtin_vec_vmaxsb -#define vec_vminfp __builtin_vec_vminfp -#define vec_vminsw __builtin_vec_vminsw -#define vec_vminsh __builtin_vec_vminsh -#define vec_vminsb __builtin_vec_vminsb -#define vec_mradds __builtin_vec_mradds -#define vec_vmsumshm __builtin_vec_vmsumshm -#define vec_vmsumuhm __builtin_vec_vmsumuhm -#define vec_vmsummbm __builtin_vec_vmsummbm -#define vec_vmsumubm __builtin_vec_vmsumubm -#define vec_vmsumshs __builtin_vec_vmsumshs -#define vec_vmsumuhs __builtin_vec_vmsumuhs -#define vec_vmulesb __builtin_vec_vmulesb -#define vec_vmulesh __builtin_vec_vmulesh -#define vec_vmuleuh __builtin_vec_vmuleuh -#define vec_vmuleub __builtin_vec_vmuleub -#define vec_vmulosh __builtin_vec_vmulosh -#define vec_vmulouh __builtin_vec_vmulouh -#define vec_vmulosb __builtin_vec_vmulosb -#define vec_vmuloub __builtin_vec_vmuloub -#define vec_nmsub __builtin_vec_nmsub -#define vec_packpx __builtin_vec_packpx -#define vec_vpkswss __builtin_vec_vpkswss -#define vec_vpkuwus __builtin_vec_vpkuwus -#define vec_vpkshss __builtin_vec_vpkshss -#define vec_vpkuhus __builtin_vec_vpkuhus -#define vec_vpkswus __builtin_vec_vpkswus -#define vec_vpkshus __builtin_vec_vpkshus -#define vec_re __builtin_vec_re -#define vec_round __builtin_vec_round -#define vec_recipdiv __builtin_vec_recipdiv -#define vec_rsqrt __builtin_vec_rsqrt -#define vec_rsqrte __builtin_vec_rsqrte -#define vec_vsubfp __builtin_vec_vsubfp -#define vec_subc __builtin_vec_subc -#define vec_vsubsws __builtin_vec_vsubsws -#define vec_vsubshs __builtin_vec_vsubshs -#define vec_vsubsbs __builtin_vec_vsubsbs -#define vec_sum4s __builtin_vec_sum4s -#define vec_vsum4shs __builtin_vec_vsum4shs -#define vec_vsum4sbs __builtin_vec_vsum4sbs -#define vec_vsum4ubs __builtin_vec_vsum4ubs -#define vec_sum2s __builtin_vec_sum2s -#define vec_sums __builtin_vec_sums -#define vec_trunc __builtin_vec_trunc -#define vec_vupkhpx __builtin_vec_vupkhpx -#define vec_vupkhsh __builtin_vec_vupkhsh -#define vec_vupkhsb __builtin_vec_vupkhsb -#define vec_vupklpx __builtin_vec_vupklpx -#define vec_vupklsh __builtin_vec_vupklsh -#define vec_vupklsb __builtin_vec_vupklsb -#define vec_abs __builtin_vec_abs -#define vec_abss __builtin_vec_abss -#define vec_add __builtin_vec_add -#define vec_adds __builtin_vec_adds -#define vec_and __builtin_vec_and -#define vec_andc __builtin_vec_andc -#define vec_avg __builtin_vec_avg -#define vec_cmpeq __builtin_vec_cmpeq -#define vec_cmpgt __builtin_vec_cmpgt -#define vec_ctf __builtin_vec_ctf -#define vec_dst __builtin_vec_dst -#define vec_dstst __builtin_vec_dstst -#define vec_dststt __builtin_vec_dststt -#define vec_dstt __builtin_vec_dstt -#define vec_ld __builtin_vec_ld -#define vec_lde __builtin_vec_lde -#define vec_ldl __builtin_vec_ldl -#define vec_lvebx __builtin_vec_lvebx -#define vec_lvehx __builtin_vec_lvehx -#define vec_lvewx __builtin_vec_lvewx -/* Cell only intrinsics. */ -#ifdef __PPU__ -#define vec_lvlx __builtin_vec_lvlx -#define vec_lvlxl __builtin_vec_lvlxl -#define vec_lvrx __builtin_vec_lvrx -#define vec_lvrxl __builtin_vec_lvrxl -#endif -#define vec_lvsl __builtin_vec_lvsl -#define vec_lvsr __builtin_vec_lvsr -#define vec_max __builtin_vec_max -#define vec_mergeh __builtin_vec_mergeh -#define vec_mergel __builtin_vec_mergel -#define vec_min __builtin_vec_min -#define vec_mladd __builtin_vec_mladd -#define vec_msum __builtin_vec_msum -#define vec_msums __builtin_vec_msums -#define vec_mule __builtin_vec_mule -#define vec_mulo __builtin_vec_mulo -#define vec_nor __builtin_vec_nor -#define vec_or __builtin_vec_or -#define vec_pack __builtin_vec_pack -#define vec_packs __builtin_vec_packs -#define vec_packsu __builtin_vec_packsu -#define vec_perm __builtin_vec_perm -#define vec_rl __builtin_vec_rl -#define vec_sel __builtin_vec_sel -#define vec_sl __builtin_vec_sl -#define vec_sld __builtin_vec_sld -#define vec_sll __builtin_vec_sll -#define vec_slo __builtin_vec_slo -#define vec_splat __builtin_vec_splat -#define vec_sr __builtin_vec_sr -#define vec_sra __builtin_vec_sra -#define vec_srl __builtin_vec_srl -#define vec_sro __builtin_vec_sro -#define vec_st __builtin_vec_st -#define vec_ste __builtin_vec_ste -#define vec_stl __builtin_vec_stl -#define vec_stvebx __builtin_vec_stvebx -#define vec_stvehx __builtin_vec_stvehx -#define vec_stvewx __builtin_vec_stvewx -/* Cell only intrinsics. */ -#ifdef __PPU__ -#define vec_stvlx __builtin_vec_stvlx -#define vec_stvlxl __builtin_vec_stvlxl -#define vec_stvrx __builtin_vec_stvrx -#define vec_stvrxl __builtin_vec_stvrxl -#endif -#define vec_sub __builtin_vec_sub -#define vec_subs __builtin_vec_subs -#define vec_sum __builtin_vec_sum -#define vec_unpackh __builtin_vec_unpackh -#define vec_unpackl __builtin_vec_unpackl -#define vec_vaddubm __builtin_vec_vaddubm -#define vec_vaddubs __builtin_vec_vaddubs -#define vec_vadduhm __builtin_vec_vadduhm -#define vec_vadduhs __builtin_vec_vadduhs -#define vec_vadduwm __builtin_vec_vadduwm -#define vec_vadduws __builtin_vec_vadduws -#define vec_vcmpequb __builtin_vec_vcmpequb -#define vec_vcmpequh __builtin_vec_vcmpequh -#define vec_vcmpequw __builtin_vec_vcmpequw -#define vec_vmaxub __builtin_vec_vmaxub -#define vec_vmaxuh __builtin_vec_vmaxuh -#define vec_vmaxuw __builtin_vec_vmaxuw -#define vec_vminub __builtin_vec_vminub -#define vec_vminuh __builtin_vec_vminuh -#define vec_vminuw __builtin_vec_vminuw -#define vec_vmrghb __builtin_vec_vmrghb -#define vec_vmrghh __builtin_vec_vmrghh -#define vec_vmrghw __builtin_vec_vmrghw -#define vec_vmrglb __builtin_vec_vmrglb -#define vec_vmrglh __builtin_vec_vmrglh -#define vec_vmrglw __builtin_vec_vmrglw -#define vec_vpkuhum __builtin_vec_vpkuhum -#define vec_vpkuwum __builtin_vec_vpkuwum -#define vec_vrlb __builtin_vec_vrlb -#define vec_vrlh __builtin_vec_vrlh -#define vec_vrlw __builtin_vec_vrlw -#define vec_vslb __builtin_vec_vslb -#define vec_vslh __builtin_vec_vslh -#define vec_vslw __builtin_vec_vslw -#define vec_vspltb __builtin_vec_vspltb -#define vec_vsplth __builtin_vec_vsplth -#define vec_vspltw __builtin_vec_vspltw -#define vec_vsrab __builtin_vec_vsrab -#define vec_vsrah __builtin_vec_vsrah -#define vec_vsraw __builtin_vec_vsraw -#define vec_vsrb __builtin_vec_vsrb -#define vec_vsrh __builtin_vec_vsrh -#define vec_vsrw __builtin_vec_vsrw -#define vec_vsububs __builtin_vec_vsububs -#define vec_vsububm __builtin_vec_vsububm -#define vec_vsubuhm __builtin_vec_vsubuhm -#define vec_vsubuhs __builtin_vec_vsubuhs -#define vec_vsubuwm __builtin_vec_vsubuwm -#define vec_vsubuws __builtin_vec_vsubuws -#define vec_xor __builtin_vec_xor - -#define vec_extract __builtin_vec_extract -#define vec_insert __builtin_vec_insert -#define vec_splats __builtin_vec_splats -#define vec_promote __builtin_vec_promote - -#ifdef __VSX__ -/* VSX additions */ -#define vec_div __builtin_vec_div -#define vec_mul __builtin_vec_mul -#define vec_msub __builtin_vec_msub -#define vec_nmadd __builtin_vec_nmadd -#define vec_nearbyint __builtin_vec_nearbyint -#define vec_rint __builtin_vec_rint -#define vec_sqrt __builtin_vec_sqrt -#define vec_vsx_ld __builtin_vec_vsx_ld -#define vec_vsx_st __builtin_vec_vsx_st -#endif - -/* Predicates. - For C++, we use templates in order to allow non-parenthesized arguments. - For C, instead, we use macros since non-parenthesized arguments were - not allowed even in older GCC implementation of AltiVec. - - In the future, we may add more magic to the back-end, so that no - one- or two-argument macros are used. */ - -#ifdef __cplusplus__ -#define __altivec_unary_pred(NAME, CALL) \ -template <class T> int NAME (T a1) { return CALL; } - -#define __altivec_scalar_pred(NAME, CALL) \ -template <class T, class U> int NAME (T a1, U a2) { return CALL; } - -/* Given the vec_step of a type, return the corresponding bool type. */ -template <int STEP> class __altivec_bool_ret { }; -template <> class __altivec_bool_ret <4> { - typedef __vector __bool int __ret; -}; -template <> class __altivec_bool_ret <8> { - typedef __vector __bool short __ret; -}; -template <> class __altivec_bool_ret <16> { - typedef __vector __bool char __ret; -}; - -/* Be very liberal in the pairs we accept. Mistakes such as passing - a `vector char' and `vector short' will be caught by the middle-end, - while any attempt to detect them here would produce hard to understand - error messages involving the implementation details of AltiVec. */ -#define __altivec_binary_pred(NAME, CALL) \ -template <class T, class U> \ -typename __altivec_bool_ret <vec_step (T)>::__ret \ -NAME (T a1, U a2) \ -{ \ - return CALL; \ -} - -__altivec_binary_pred(vec_cmplt, - __builtin_vec_cmpgt (a2, a1)) -__altivec_binary_pred(vec_cmple, - __builtin_vec_cmpge (a2, a1)) - -__altivec_scalar_pred(vec_all_in, - __builtin_altivec_vcmpbfp_p (__CR6_EQ, a1, a2)) -__altivec_scalar_pred(vec_any_out, - __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, a1, a2)) - -__altivec_unary_pred(vec_all_nan, - __builtin_altivec_vcmpeq_p (__CR6_EQ, a1, a1)) -__altivec_unary_pred(vec_any_nan, - __builtin_altivec_vcmpeq_p (__CR6_LT_REV, a1, a1)) - -__altivec_unary_pred(vec_all_numeric, - __builtin_altivec_vcmpeq_p (__CR6_LT, a1, a1)) -__altivec_unary_pred(vec_any_numeric, - __builtin_altivec_vcmpeq_p (__CR6_EQ_REV, a1, a1)) - -__altivec_scalar_pred(vec_all_eq, - __builtin_vec_vcmpeq_p (__CR6_LT, a1, a2)) -__altivec_scalar_pred(vec_all_ne, - __builtin_vec_vcmpeq_p (__CR6_EQ, a1, a2)) -__altivec_scalar_pred(vec_any_eq, - __builtin_vec_vcmpeq_p (__CR6_EQ_REV, a1, a2)) -__altivec_scalar_pred(vec_any_ne, - __builtin_vec_vcmpeq_p (__CR6_LT_REV, a1, a2)) - -__altivec_scalar_pred(vec_all_gt, - __builtin_vec_vcmpgt_p (__CR6_LT, a1, a2)) -__altivec_scalar_pred(vec_all_lt, - __builtin_vec_vcmpgt_p (__CR6_LT, a2, a1)) -__altivec_scalar_pred(vec_any_gt, - __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a1, a2)) -__altivec_scalar_pred(vec_any_lt, - __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a2, a1)) - -__altivec_scalar_pred(vec_all_ngt, - __builtin_altivec_vcmpgt_p (__CR6_EQ, a1, a2)) -__altivec_scalar_pred(vec_all_nlt, - __builtin_altivec_vcmpgt_p (__CR6_EQ, a2, a1)) -__altivec_scalar_pred(vec_any_ngt, - __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a1, a2)) -__altivec_scalar_pred(vec_any_nlt, - __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a2, a1)) - -/* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, - while for integer types it is converted to __builtin_vec_vcmpgt_p, - with inverted args and condition code. */ -__altivec_scalar_pred(vec_all_le, - __builtin_vec_vcmpge_p (__CR6_LT, a2, a1)) -__altivec_scalar_pred(vec_all_ge, - __builtin_vec_vcmpge_p (__CR6_LT, a1, a2)) -__altivec_scalar_pred(vec_any_le, - __builtin_vec_vcmpge_p (__CR6_EQ_REV, a2, a1)) -__altivec_scalar_pred(vec_any_ge, - __builtin_vec_vcmpge_p (__CR6_EQ_REV, a1, a2)) - -__altivec_scalar_pred(vec_all_nge, - __builtin_altivec_vcmpge_p (__CR6_EQ, a1, a2)) -__altivec_scalar_pred(vec_all_nle, - __builtin_altivec_vcmpge_p (__CR6_EQ, a2, a1)) -__altivec_scalar_pred(vec_any_nge, - __builtin_altivec_vcmpge_p (__CR6_LT_REV, a1, a2)) -__altivec_scalar_pred(vec_any_nle, - __builtin_altivec_vcmpge_p (__CR6_LT_REV, a2, a1)) - -#undef __altivec_scalar_pred -#undef __altivec_unary_pred -#undef __altivec_binary_pred -#else -#define vec_cmplt(a1, a2) __builtin_vec_cmpgt ((a2), (a1)) -#define vec_cmple(a1, a2) __builtin_vec_cmpge ((a2), (a1)) - -#define vec_all_in(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ, (a1), (a2)) -#define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2)) - -#define vec_all_nan(a1) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a1)) -#define vec_any_nan(a1) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a1)) - -#define vec_all_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a1)) -#define vec_any_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a1)) - -#define vec_all_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a2)) -#define vec_all_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a2)) -#define vec_any_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a2)) -#define vec_any_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a2)) - -#define vec_all_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT, (a1), (a2)) -#define vec_all_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT, (a2), (a1)) -#define vec_any_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a1), (a2)) -#define vec_any_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a2), (a1)) - -#define vec_all_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a1), (a2)) -#define vec_all_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a2), (a1)) -#define vec_any_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a1), (a2)) -#define vec_any_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a2), (a1)) - -/* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, - while for integer types it is converted to __builtin_vec_vcmpgt_p, - with inverted args and condition code. */ -#define vec_all_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT, (a2), (a1)) -#define vec_all_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT, (a1), (a2)) -#define vec_any_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a2), (a1)) -#define vec_any_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a1), (a2)) - -#define vec_all_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a1), (a2)) -#define vec_all_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a2), (a1)) -#define vec_any_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a1), (a2)) -#define vec_any_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a2), (a1)) -#endif - -/* These do not accept vectors, so they do not have a __builtin_vec_* - counterpart. */ -#define vec_dss(x) __builtin_altivec_dss((x)) -#define vec_dssall() __builtin_altivec_dssall () -#define vec_mfvscr() ((__vector unsigned short) __builtin_altivec_mfvscr ()) -#define vec_splat_s8(x) __builtin_altivec_vspltisb ((x)) -#define vec_splat_s16(x) __builtin_altivec_vspltish ((x)) -#define vec_splat_s32(x) __builtin_altivec_vspltisw ((x)) -#define vec_splat_u8(x) ((__vector unsigned char) vec_splat_s8 ((x))) -#define vec_splat_u16(x) ((__vector unsigned short) vec_splat_s16 ((x))) -#define vec_splat_u32(x) ((__vector unsigned int) vec_splat_s32 ((x))) - -/* This also accepts a type for its parameter, so it is not enough - to #define vec_step to __builtin_vec_step. */ -#define vec_step(x) __builtin_vec_step (* (__typeof__ (x) *) 0) - -#endif /* _ALTIVEC_H */ diff --git a/gcc-4.8.1/gcc/config/rs6000/altivec.md b/gcc-4.8.1/gcc/config/rs6000/altivec.md deleted file mode 100644 index 1b0b5c3fb..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/altivec.md +++ /dev/null @@ -1,2462 +0,0 @@ -;; AltiVec patterns. -;; Copyright (C) 2002-2013 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 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_c_enum "unspec" - [UNSPEC_VCMPBFP - UNSPEC_VMSUMU - UNSPEC_VMSUMM - UNSPEC_VMSUMSHM - UNSPEC_VMSUMUHS - UNSPEC_VMSUMSHS - UNSPEC_VMHADDSHS - UNSPEC_VMHRADDSHS - UNSPEC_VMLADDUHM - UNSPEC_VADDCUW - UNSPEC_VADDU - UNSPEC_VADDS - UNSPEC_VAVGU - UNSPEC_VAVGS - UNSPEC_VMULEUB - UNSPEC_VMULESB - UNSPEC_VMULEUH - UNSPEC_VMULESH - UNSPEC_VMULOUB - UNSPEC_VMULOSB - UNSPEC_VMULOUH - UNSPEC_VMULOSH - UNSPEC_VPKUHUM - UNSPEC_VPKUWUM - UNSPEC_VPKPX - UNSPEC_VPKSHSS - UNSPEC_VPKSWSS - UNSPEC_VPKUHUS - UNSPEC_VPKSHUS - UNSPEC_VPKUWUS - UNSPEC_VPKSWUS - UNSPEC_VSLV4SI - UNSPEC_VSLO - UNSPEC_VSR - UNSPEC_VSRO - UNSPEC_VSUBCUW - UNSPEC_VSUBU - UNSPEC_VSUBS - UNSPEC_VSUM4UBS - UNSPEC_VSUM4S - UNSPEC_VSUM2SWS - UNSPEC_VSUMSWS - UNSPEC_VPERM - UNSPEC_VPERM_UNS - UNSPEC_VRFIN - UNSPEC_VCFUX - UNSPEC_VCFSX - UNSPEC_VCTUXS - UNSPEC_VCTSXS - UNSPEC_VLOGEFP - UNSPEC_VEXPTEFP - UNSPEC_VLSDOI - UNSPEC_VUPKHSB - UNSPEC_VUPKHPX - UNSPEC_VUPKHSH - UNSPEC_VUPKLSB - UNSPEC_VUPKLPX - UNSPEC_VUPKLSH - UNSPEC_DST - UNSPEC_DSTT - UNSPEC_DSTST - UNSPEC_DSTSTT - UNSPEC_LVSL - UNSPEC_LVSR - UNSPEC_LVE - UNSPEC_STVX - UNSPEC_STVXL - UNSPEC_STVE - UNSPEC_SET_VSCR - UNSPEC_GET_VRSAVE - UNSPEC_LVX - UNSPEC_REDUC_PLUS - UNSPEC_VECSH - UNSPEC_EXTEVEN_V4SI - UNSPEC_EXTEVEN_V8HI - UNSPEC_EXTEVEN_V16QI - UNSPEC_EXTEVEN_V4SF - UNSPEC_EXTODD_V4SI - UNSPEC_EXTODD_V8HI - UNSPEC_EXTODD_V16QI - UNSPEC_EXTODD_V4SF - UNSPEC_INTERHI_V4SI - UNSPEC_INTERHI_V8HI - UNSPEC_INTERHI_V16QI - UNSPEC_INTERLO_V4SI - UNSPEC_INTERLO_V8HI - UNSPEC_INTERLO_V16QI - UNSPEC_LVLX - UNSPEC_LVLXL - UNSPEC_LVRX - UNSPEC_LVRXL - UNSPEC_STVLX - UNSPEC_STVLXL - UNSPEC_STVRX - UNSPEC_STVRXL - UNSPEC_VMULWHUB - UNSPEC_VMULWLUB - UNSPEC_VMULWHSB - UNSPEC_VMULWLSB - UNSPEC_VMULWHUH - UNSPEC_VMULWLUH - UNSPEC_VMULWHSH - UNSPEC_VMULWLSH - UNSPEC_VUPKHUB - UNSPEC_VUPKHUH - UNSPEC_VUPKLUB - UNSPEC_VUPKLUH - UNSPEC_VPERMSI - UNSPEC_VPERMHI - UNSPEC_INTERHI - UNSPEC_INTERLO - UNSPEC_VUPKHS_V4SF - UNSPEC_VUPKLS_V4SF - UNSPEC_VUPKHU_V4SF - UNSPEC_VUPKLU_V4SF -]) - -(define_c_enum "unspecv" - [UNSPECV_SET_VRSAVE - UNSPECV_MTVSCR - UNSPECV_MFVSCR - UNSPECV_DSSALL - UNSPECV_DSS - ]) - -;; Vec int modes -(define_mode_iterator VI [V4SI V8HI V16QI]) -;; Short vec in modes -(define_mode_iterator VIshort [V8HI V16QI]) -;; Vec float modes -(define_mode_iterator VF [V4SF]) -;; Vec modes, pity mode iterators are not composable -(define_mode_iterator V [V4SI V8HI V16QI V4SF]) -;; Vec modes for move/logical/permute ops, include vector types for move not -;; otherwise handled by altivec (v2df, v2di, ti) -(define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI TI]) - -;; Like VM, except don't do TImode -(define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI]) - -(define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")]) -(define_mode_attr VI_scalar [(V4SI "SI") (V8HI "HI") (V16QI "QI")]) - -;; Vector move instructions. -(define_insn "*altivec_mov<mode>" - [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*Y,*r,*r,v,v") - (match_operand:VM2 1 "input_operand" "v,Z,v,r,Y,r,j,W"))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode) - && (register_operand (operands[0], <MODE>mode) - || register_operand (operands[1], <MODE>mode))" -{ - 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 "vxor %0,%0,%0"; - case 7: return output_vec_const_move (operands); - default: gcc_unreachable (); - } -} - [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")]) - -;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode -;; is for unions. However for plain data movement, slightly favor the vector -;; loads -(define_insn "*altivec_movti" - [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v") - (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))] - "VECTOR_MEM_ALTIVEC_P (TImode) - && (register_operand (operands[0], TImode) - || register_operand (operands[1], TImode))" -{ - 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 "vxor %0,%0,%0"; - case 7: return output_vec_const_move (operands); - default: gcc_unreachable (); - } -} - [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")]) - -;; Load up a vector with the most significant bit set by loading up -1 and -;; doing a shift left -(define_split - [(set (match_operand:VM 0 "altivec_register_operand" "") - (match_operand:VM 1 "easy_vector_constant_msb" ""))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed" - [(const_int 0)] -{ - rtx dest = operands[0]; - enum machine_mode mode = GET_MODE (operands[0]); - rtvec v; - int i, num_elements; - - if (mode == V4SFmode) - { - mode = V4SImode; - dest = gen_lowpart (V4SImode, dest); - } - - num_elements = GET_MODE_NUNITS (mode); - v = rtvec_alloc (num_elements); - for (i = 0; i < num_elements; i++) - RTVEC_ELT (v, i) = constm1_rtx; - - emit_insn (gen_vec_initv4si (dest, gen_rtx_PARALLEL (mode, v))); - emit_insn (gen_rtx_SET (VOIDmode, dest, gen_rtx_ASHIFT (mode, dest, dest))); - DONE; -}) - -(define_split - [(set (match_operand:VM 0 "altivec_register_operand" "") - (match_operand:VM 1 "easy_vector_constant_add_self" ""))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed" - [(set (match_dup 0) (match_dup 3)) - (set (match_dup 0) (match_dup 4))] -{ - rtx dup = gen_easy_altivec_constant (operands[1]); - rtx const_vec; - enum machine_mode op_mode = <MODE>mode; - - /* Divide the operand of the resulting VEC_DUPLICATE, and use - simplify_rtx to make a CONST_VECTOR. */ - XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode, - XEXP (dup, 0), const1_rtx); - const_vec = simplify_rtx (dup); - - if (op_mode == V4SFmode) - { - op_mode = V4SImode; - operands[0] = gen_lowpart (op_mode, operands[0]); - } - if (GET_MODE (const_vec) == op_mode) - operands[3] = const_vec; - else - operands[3] = gen_lowpart (op_mode, const_vec); - operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]); -}) - -(define_insn "get_vrsave_internal" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(reg:SI 109)] UNSPEC_GET_VRSAVE))] - "TARGET_ALTIVEC" -{ - if (TARGET_MACHO) - return "mfspr %0,256"; - else - return "mfvrsave %0"; -} - [(set_attr "type" "*")]) - -(define_insn "*set_vrsave_internal" - [(match_parallel 0 "vrsave_operation" - [(set (reg:SI 109) - (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") - (reg:SI 109)] UNSPECV_SET_VRSAVE))])] - "TARGET_ALTIVEC" -{ - if (TARGET_MACHO) - return "mtspr 256,%1"; - else - return "mtvrsave %1"; -} - [(set_attr "type" "*")]) - -(define_insn "*save_world" - [(match_parallel 0 "save_world_operation" - [(clobber (reg:SI 65)) - (use (match_operand:SI 1 "call_operand" "s"))])] - "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" - "bl %z1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*restore_world" - [(match_parallel 0 "restore_world_operation" - [(return) - (use (reg:SI 65)) - (use (match_operand:SI 1 "call_operand" "s")) - (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])] - "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" - "b %z1") - -;; The save_vregs and restore_vregs patterns don't use memory_operand -;; because (plus (reg) (const_int)) is not a valid vector address. -;; This way is more compact than describing exactly what happens in -;; the out-of-line functions, ie. loading the constant into r11/r12 -;; then using indexed addressing, and requires less editing of rtl -;; to describe the operation to dwarf2out_frame_debug_expr. -(define_insn "*save_vregs_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (clobber (reg:P 11)) - (use (reg:P 0)) - (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") - (match_operand:P 3 "short_cint_operand" "I"))) - (match_operand:V4SI 4 "gpc_reg_operand" "v"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*save_vregs_<mode>_r12" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (clobber (reg:P 12)) - (use (reg:P 0)) - (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") - (match_operand:P 3 "short_cint_operand" "I"))) - (match_operand:V4SI 4 "gpc_reg_operand" "v"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*restore_vregs_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (clobber (reg:P 11)) - (use (reg:P 0)) - (set (match_operand:V4SI 2 "gpc_reg_operand" "=v") - (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") - (match_operand:P 4 "short_cint_operand" "I"))))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*restore_vregs_<mode>_r12" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (clobber (reg:P 12)) - (use (reg:P 0)) - (set (match_operand:V4SI 2 "gpc_reg_operand" "=v") - (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") - (match_operand:P 4 "short_cint_operand" "I"))))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -;; Simple binary operations. - -;; add -(define_insn "add<mode>3" - [(set (match_operand:VI 0 "register_operand" "=v") - (plus:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vaddu<VI_char>m %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_addv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (plus:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vaddfp %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vaddcuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VADDCUW))] - "TARGET_ALTIVEC" - "vaddcuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddu<VI_char>s" - [(set (match_operand:VI 0 "register_operand" "=v") - (unspec:VI [(match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")] - UNSPEC_VADDU)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vaddu<VI_char>s %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vadds<VI_char>s" - [(set (match_operand:VI 0 "register_operand" "=v") - (unspec:VI [(match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")] - UNSPEC_VADDS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vadds<VI_char>s %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -;; sub -(define_insn "sub<mode>3" - [(set (match_operand:VI 0 "register_operand" "=v") - (minus:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsubu<VI_char>m %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_subv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (minus:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vsubfp %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vsubcuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSUBCUW))] - "TARGET_ALTIVEC" - "vsubcuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubu<VI_char>s" - [(set (match_operand:VI 0 "register_operand" "=v") - (unspec:VI [(match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")] - UNSPEC_VSUBU)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vsubu<VI_char>s %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubs<VI_char>s" - [(set (match_operand:VI 0 "register_operand" "=v") - (unspec:VI [(match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")] - UNSPEC_VSUBS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vsubs<VI_char>s %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -;; -(define_insn "altivec_vavgu<VI_char>" - [(set (match_operand:VI 0 "register_operand" "=v") - (unspec:VI [(match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")] - UNSPEC_VAVGU))] - "TARGET_ALTIVEC" - "vavgu<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgs<VI_char>" - [(set (match_operand:VI 0 "register_operand" "=v") - (unspec:VI [(match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")] - UNSPEC_VAVGS))] - "TARGET_ALTIVEC" - "vavgs<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpbfp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] - UNSPEC_VCMPBFP))] - "TARGET_ALTIVEC" - "vcmpbfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_eq<mode>" - [(set (match_operand:VI 0 "altivec_register_operand" "=v") - (eq:VI (match_operand:VI 1 "altivec_register_operand" "v") - (match_operand:VI 2 "altivec_register_operand" "v")))] - "TARGET_ALTIVEC" - "vcmpequ<VI_char> %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_gt<mode>" - [(set (match_operand:VI 0 "altivec_register_operand" "=v") - (gt:VI (match_operand:VI 1 "altivec_register_operand" "v") - (match_operand:VI 2 "altivec_register_operand" "v")))] - "TARGET_ALTIVEC" - "vcmpgts<VI_char> %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_gtu<mode>" - [(set (match_operand:VI 0 "altivec_register_operand" "=v") - (gtu:VI (match_operand:VI 1 "altivec_register_operand" "v") - (match_operand:VI 2 "altivec_register_operand" "v")))] - "TARGET_ALTIVEC" - "vcmpgtu<VI_char> %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_eqv4sf" - [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") - (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") - (match_operand:V4SF 2 "altivec_register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vcmpeqfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_gtv4sf" - [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") - (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") - (match_operand:V4SF 2 "altivec_register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vcmpgtfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_gev4sf" - [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") - (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") - (match_operand:V4SF 2 "altivec_register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vcmpgefp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_vsel<mode>" - [(set (match_operand:VM 0 "altivec_register_operand" "=v") - (if_then_else:VM - (ne:CC (match_operand:VM 1 "altivec_register_operand" "v") - (match_operand:VM 4 "zero_constant" "")) - (match_operand:VM 2 "altivec_register_operand" "v") - (match_operand:VM 3 "altivec_register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vsel %0,%3,%2,%1" - [(set_attr "type" "vecperm")]) - -(define_insn "*altivec_vsel<mode>_uns" - [(set (match_operand:VM 0 "altivec_register_operand" "=v") - (if_then_else:VM - (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v") - (match_operand:VM 4 "zero_constant" "")) - (match_operand:VM 2 "altivec_register_operand" "v") - (match_operand:VM 3 "altivec_register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vsel %0,%3,%2,%1" - [(set_attr "type" "vecperm")]) - -;; Fused multiply add. - -(define_insn "*altivec_fmav4sf4" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand:V4SF 3 "register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vmaddfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - -;; We do multiply as a fused multiply-add with an add of a -0.0 vector. - -(define_expand "altivec_mulv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "") - (fma:V4SF (match_operand:V4SF 1 "register_operand" "") - (match_operand:V4SF 2 "register_operand" "") - (match_dup 3)))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" -{ - rtx neg0; - - /* Generate [-0.0, -0.0, -0.0, -0.0]. */ - neg0 = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); - emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); - - operands[3] = gen_lowpart (V4SFmode, neg0); -}) - -;; 32-bit integer multiplication -;; A_high = Operand_0 & 0xFFFF0000 >> 16 -;; A_low = Operand_0 & 0xFFFF -;; B_high = Operand_1 & 0xFFFF0000 >> 16 -;; B_low = Operand_1 & 0xFFFF -;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16 - -;; (define_insn "mulv4si3" -;; [(set (match_operand:V4SI 0 "register_operand" "=v") -;; (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") -;; (match_operand:V4SI 2 "register_operand" "v")))] -(define_expand "mulv4si3" - [(use (match_operand:V4SI 0 "register_operand" "")) - (use (match_operand:V4SI 1 "register_operand" "")) - (use (match_operand:V4SI 2 "register_operand" ""))] - "TARGET_ALTIVEC" - " - { - rtx zero; - rtx swap; - rtx small_swap; - rtx sixteen; - rtx one; - rtx two; - rtx low_product; - rtx high_product; - - zero = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); - - sixteen = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16))); - - swap = gen_reg_rtx (V4SImode); - emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen)); - - one = gen_reg_rtx (V8HImode); - convert_move (one, operands[1], 0); - - two = gen_reg_rtx (V8HImode); - convert_move (two, operands[2], 0); - - small_swap = gen_reg_rtx (V8HImode); - convert_move (small_swap, swap, 0); - - low_product = gen_reg_rtx (V4SImode); - emit_insn (gen_vec_widen_umult_odd_v8hi (low_product, one, two)); - - high_product = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero)); - - emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen)); - - emit_insn (gen_addv4si3 (operands[0], high_product, low_product)); - - DONE; - }") - -(define_expand "mulv8hi3" - [(use (match_operand:V8HI 0 "register_operand" "")) - (use (match_operand:V8HI 1 "register_operand" "")) - (use (match_operand:V8HI 2 "register_operand" ""))] - "TARGET_ALTIVEC" - " -{ - rtx odd = gen_reg_rtx (V4SImode); - rtx even = gen_reg_rtx (V4SImode); - rtx high = gen_reg_rtx (V4SImode); - rtx low = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_widen_smult_even_v8hi (even, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v8hi (odd, operands[1], operands[2])); - - emit_insn (gen_altivec_vmrghw (high, even, odd)); - emit_insn (gen_altivec_vmrglw (low, even, odd)); - - emit_insn (gen_altivec_vpkuwum (operands[0], high, low)); - - DONE; -}") - -;; Fused multiply subtract -(define_insn "*altivec_vnmsubfp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (neg:V4SF - (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (neg:V4SF - (match_operand:V4SF 3 "register_operand" "v")))))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vnmsubfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vmsumu<VI_char>m" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") - (match_operand:VIshort 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] - UNSPEC_VMSUMU))] - "TARGET_ALTIVEC" - "vmsumu<VI_char>m %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumm<VI_char>m" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") - (match_operand:VIshort 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] - UNSPEC_VMSUMM))] - "TARGET_ALTIVEC" - "vmsumm<VI_char>m %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumshm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] - UNSPEC_VMSUMSHM))] - "TARGET_ALTIVEC" - "vmsumshm %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumuhs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] - UNSPEC_VMSUMUHS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vmsumuhs %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumshs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] - UNSPEC_VMSUMSHS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vmsumshs %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -;; max - -(define_insn "umax<mode>3" - [(set (match_operand:VI 0 "register_operand" "=v") - (umax:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxu<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smax<mode>3" - [(set (match_operand:VI 0 "register_operand" "=v") - (smax:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxs<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_smaxv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (smax:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vmaxfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "umin<mode>3" - [(set (match_operand:VI 0 "register_operand" "=v") - (umin:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminu<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smin<mode>3" - [(set (match_operand:VI 0 "register_operand" "=v") - (smin:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmins<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_sminv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (smin:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vminfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vmhaddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] - UNSPEC_VMHADDSHS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vmhaddshs %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmhraddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] - UNSPEC_VMHRADDSHS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vmhraddshs %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmladduhm" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] - UNSPEC_VMLADDUHM))] - "TARGET_ALTIVEC" - "vmladduhm %0,%1,%2,%3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmrghb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (vec_select:V16QI - (vec_concat:V32QI - (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")) - (parallel [(const_int 0) (const_int 16) - (const_int 1) (const_int 17) - (const_int 2) (const_int 18) - (const_int 3) (const_int 19) - (const_int 4) (const_int 20) - (const_int 5) (const_int 21) - (const_int 6) (const_int 22) - (const_int 7) (const_int 23)])))] - "TARGET_ALTIVEC" - "vmrghb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrghh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (vec_select:V8HI - (vec_concat:V16HI - (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")) - (parallel [(const_int 0) (const_int 8) - (const_int 1) (const_int 9) - (const_int 2) (const_int 10) - (const_int 3) (const_int 11)])))] - "TARGET_ALTIVEC" - "vmrghh %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrghw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (vec_select:V4SI - (vec_concat:V8SI - (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")) - (parallel [(const_int 0) (const_int 4) - (const_int 1) (const_int 5)])))] - "VECTOR_MEM_ALTIVEC_P (V4SImode)" - "vmrghw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "*altivec_vmrghsf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (vec_select:V4SF - (vec_concat:V8SF - (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (parallel [(const_int 0) (const_int 4) - (const_int 1) (const_int 5)])))] - "VECTOR_MEM_ALTIVEC_P (V4SFmode)" - "vmrghw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (vec_select:V16QI - (vec_concat:V32QI - (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")) - (parallel [(const_int 8) (const_int 24) - (const_int 9) (const_int 25) - (const_int 10) (const_int 26) - (const_int 11) (const_int 27) - (const_int 12) (const_int 28) - (const_int 13) (const_int 29) - (const_int 14) (const_int 30) - (const_int 15) (const_int 31)])))] - "TARGET_ALTIVEC" - "vmrglb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (vec_select:V8HI - (vec_concat:V16HI - (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")) - (parallel [(const_int 4) (const_int 12) - (const_int 5) (const_int 13) - (const_int 6) (const_int 14) - (const_int 7) (const_int 15)])))] - "TARGET_ALTIVEC" - "vmrglh %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (vec_select:V4SI - (vec_concat:V8SI - (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")) - (parallel [(const_int 2) (const_int 6) - (const_int 3) (const_int 7)])))] - "VECTOR_MEM_ALTIVEC_P (V4SImode)" - "vmrglw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "*altivec_vmrglsf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (vec_select:V4SF - (vec_concat:V8SF - (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (parallel [(const_int 2) (const_int 6) - (const_int 3) (const_int 7)])))] - "VECTOR_MEM_ALTIVEC_P (V4SFmode)" - "vmrglw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "vec_widen_umult_even_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULEUB))] - "TARGET_ALTIVEC" - "vmuleub %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "vec_widen_smult_even_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULESB))] - "TARGET_ALTIVEC" - "vmulesb %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "vec_widen_umult_even_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULEUH))] - "TARGET_ALTIVEC" - "vmuleuh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "vec_widen_smult_even_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULESH))] - "TARGET_ALTIVEC" - "vmulesh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "vec_widen_umult_odd_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULOUB))] - "TARGET_ALTIVEC" - "vmuloub %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "vec_widen_smult_odd_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULOSB))] - "TARGET_ALTIVEC" - "vmulosb %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "vec_widen_umult_odd_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULOUH))] - "TARGET_ALTIVEC" - "vmulouh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "vec_widen_smult_odd_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULOSH))] - "TARGET_ALTIVEC" - "vmulosh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - - -;; logical ops. Have the logical ops follow the memory ops in -;; terms of whether to prefer VSX or Altivec - -(define_insn "*altivec_and<mode>3" - [(set (match_operand:VM 0 "register_operand" "=v") - (and:VM (match_operand:VM 1 "register_operand" "v") - (match_operand:VM 2 "register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vand %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_ior<mode>3" - [(set (match_operand:VM 0 "register_operand" "=v") - (ior:VM (match_operand:VM 1 "register_operand" "v") - (match_operand:VM 2 "register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_xor<mode>3" - [(set (match_operand:VM 0 "register_operand" "=v") - (xor:VM (match_operand:VM 1 "register_operand" "v") - (match_operand:VM 2 "register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vxor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_one_cmpl<mode>2" - [(set (match_operand:VM 0 "register_operand" "=v") - (not:VM (match_operand:VM 1 "register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vnor %0,%1,%1" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_nor<mode>3" - [(set (match_operand:VM 0 "register_operand" "=v") - (not:VM (ior:VM (match_operand:VM 1 "register_operand" "v") - (match_operand:VM 2 "register_operand" "v"))))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vnor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_andc<mode>3" - [(set (match_operand:VM 0 "register_operand" "=v") - (and:VM (not:VM (match_operand:VM 2 "register_operand" "v")) - (match_operand:VM 1 "register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" - "vandc %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vpkuhum" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VPKUHUM))] - "TARGET_ALTIVEC" - "vpkuhum %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwum" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VPKUWUM))] - "TARGET_ALTIVEC" - "vpkuwum %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkpx" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VPKPX))] - "TARGET_ALTIVEC" - "vpkpx %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkshss" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VPKSHSS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vpkshss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkswss" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VPKSWSS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vpkswss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuhus" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VPKUHUS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vpkuhus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkshus" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VPKSHUS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vpkshus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwus" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VPKUWUS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vpkuwus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkswus" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VPKSWUS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vpkswus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "*altivec_vrl<VI_char>" - [(set (match_operand:VI 0 "register_operand" "=v") - (rotate:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vrl<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsl" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSLV4SI))] - "TARGET_ALTIVEC" - "vsl %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vslo" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSLO))] - "TARGET_ALTIVEC" - "vslo %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "*altivec_vsl<VI_char>" - [(set (match_operand:VI 0 "register_operand" "=v") - (ashift:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsl<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_vsr<VI_char>" - [(set (match_operand:VI 0 "register_operand" "=v") - (lshiftrt:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsr<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*altivec_vsra<VI_char>" - [(set (match_operand:VI 0 "register_operand" "=v") - (ashiftrt:VI (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsra<VI_char> %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsr" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSR))] - "TARGET_ALTIVEC" - "vsr %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsro" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSRO))] - "TARGET_ALTIVEC" - "vsro %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsum4ubs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSUM4UBS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vsum4ubs %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum4s<VI_char>s" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSUM4S)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vsum4s<VI_char>s %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum2sws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSUM2SWS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vsum2sws %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsumsws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VSUMSWS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vsumsws %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vspltb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (vec_duplicate:V16QI - (vec_select:QI (match_operand:V16QI 1 "register_operand" "v") - (parallel - [(match_operand:QI 2 "u5bit_cint_operand" "")]))))] - "TARGET_ALTIVEC" - "vspltb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsplth" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (vec_duplicate:V8HI - (vec_select:HI (match_operand:V8HI 1 "register_operand" "v") - (parallel - [(match_operand:QI 2 "u5bit_cint_operand" "")]))))] - "TARGET_ALTIVEC" - "vsplth %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vspltw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (vec_duplicate:V4SI - (vec_select:SI (match_operand:V4SI 1 "register_operand" "v") - (parallel - [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))] - "TARGET_ALTIVEC" - "vspltw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vspltsf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (vec_duplicate:V4SF - (vec_select:SF (match_operand:V4SF 1 "register_operand" "v") - (parallel - [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vspltw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vspltis<VI_char>" - [(set (match_operand:VI 0 "register_operand" "=v") - (vec_duplicate:VI - (match_operand:QI 1 "s5bit_cint_operand" "i")))] - "TARGET_ALTIVEC" - "vspltis<VI_char> %0,%1" - [(set_attr "type" "vecperm")]) - -(define_insn "*altivec_vrfiz" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vrfiz %0,%1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vperm_<mode>" - [(set (match_operand:VM 0 "register_operand" "=v") - (unspec:VM [(match_operand:VM 1 "register_operand" "v") - (match_operand:VM 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] - UNSPEC_VPERM))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vperm_<mode>_uns" - [(set (match_operand:VM 0 "register_operand" "=v") - (unspec:VM [(match_operand:VM 1 "register_operand" "v") - (match_operand:VM 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] - UNSPEC_VPERM_UNS))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_expand "vec_permv16qi" - [(set (match_operand:V16QI 0 "register_operand" "") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "") - (match_operand:V16QI 2 "register_operand" "") - (match_operand:V16QI 3 "register_operand" "")] - UNSPEC_VPERM))] - "TARGET_ALTIVEC" - "") - -(define_expand "vec_perm_constv16qi" - [(match_operand:V16QI 0 "register_operand" "") - (match_operand:V16QI 1 "register_operand" "") - (match_operand:V16QI 2 "register_operand" "") - (match_operand:V16QI 3 "" "")] - "TARGET_ALTIVEC" -{ - if (altivec_expand_vec_perm_const (operands)) - DONE; - else - FAIL; -}) - -(define_insn "altivec_vrfip" ; ceil - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] - UNSPEC_FRIP))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VRFIN))] - "TARGET_ALTIVEC" - "vrfin %0,%1" - [(set_attr "type" "vecfloat")]) - -(define_insn "*altivec_vrfim" ; floor - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] - UNSPEC_FRIM))] - "TARGET_ALTIVEC" - "vrfim %0,%1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vcfux" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] - UNSPEC_VCFUX))] - "TARGET_ALTIVEC" - "vcfux %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vcfsx" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] - UNSPEC_VCFSX))] - "TARGET_ALTIVEC" - "vcfsx %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vctuxs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] - UNSPEC_VCTUXS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "vctuxs %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vctsxs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] - UNSPEC_VCTSXS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VLOGEFP))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VEXPTEFP))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_RSQRT))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "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")] - UNSPEC_FRES))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vrefp %0,%1" - [(set_attr "type" "vecfloat")]) - -(define_expand "altivec_copysign_v4sf3" - [(use (match_operand:V4SF 0 "register_operand" "")) - (use (match_operand:V4SF 1 "register_operand" "")) - (use (match_operand:V4SF 2 "register_operand" ""))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - " -{ - rtx mask = gen_reg_rtx (V4SImode); - rtvec v = rtvec_alloc (4); - unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31; - - RTVEC_ELT (v, 0) = GEN_INT (mask_val); - RTVEC_ELT (v, 1) = GEN_INT (mask_val); - RTVEC_ELT (v, 2) = GEN_INT (mask_val); - RTVEC_ELT (v, 3) = GEN_INT (mask_val); - - emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v))); - emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2], - gen_lowpart (V4SFmode, mask))); - DONE; -}") - -(define_insn "altivec_vsldoi_<mode>" - [(set (match_operand:VM 0 "register_operand" "=v") - (unspec:VM [(match_operand:VM 1 "register_operand" "v") - (match_operand:VM 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] - UNSPEC_VLSDOI))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VUPKHSB))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VUPKHPX))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VUPKHSH))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VUPKLSB))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VUPKLPX))] - "TARGET_ALTIVEC" - "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")] - UNSPEC_VUPKLSH))] - "TARGET_ALTIVEC" - "vupklsh %0,%1" - [(set_attr "type" "vecperm")]) - -;; Compare vectors producing a vector result and a predicate, setting CR6 to -;; indicate a combined status -(define_insn "*altivec_vcmpequ<VI_char>_p" - [(set (reg:CC 74) - (unspec:CC [(eq:CC (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v"))] - UNSPEC_PREDICATE)) - (set (match_operand:VI 0 "register_operand" "=v") - (eq:VI (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "vcmpequ<VI_char>. %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_vcmpgts<VI_char>_p" - [(set (reg:CC 74) - (unspec:CC [(gt:CC (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v"))] - UNSPEC_PREDICATE)) - (set (match_operand:VI 0 "register_operand" "=v") - (gt:VI (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "vcmpgts<VI_char>. %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_vcmpgtu<VI_char>_p" - [(set (reg:CC 74) - (unspec:CC [(gtu:CC (match_operand:VI 1 "register_operand" "v") - (match_operand:VI 2 "register_operand" "v"))] - UNSPEC_PREDICATE)) - (set (match_operand:VI 0 "register_operand" "=v") - (gtu:VI (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "vcmpgtu<VI_char>. %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_vcmpeqfp_p" - [(set (reg:CC 74) - (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v"))] - UNSPEC_PREDICATE)) - (set (match_operand:V4SF 0 "register_operand" "=v") - (eq:V4SF (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vcmpeqfp. %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_vcmpgtfp_p" - [(set (reg:CC 74) - (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v"))] - UNSPEC_PREDICATE)) - (set (match_operand:V4SF 0 "register_operand" "=v") - (gt:V4SF (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vcmpgtfp. %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "*altivec_vcmpgefp_p" - [(set (reg:CC 74) - (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v"))] - UNSPEC_PREDICATE)) - (set (match_operand:V4SF 0 "register_operand" "=v") - (ge:V4SF (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" - "vcmpgefp. %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vcmpbfp_p" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] - UNSPEC_VCMPBFP)) - (set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_dup 1) - (match_dup 2)] - UNSPEC_VCMPBFP))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" - "vcmpbfp. %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_mtvscr" - [(set (reg:SI 110) - (unspec_volatile:SI - [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))] - "TARGET_ALTIVEC" - "mtvscr %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_mfvscr" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))] - "TARGET_ALTIVEC" - "mfvscr %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dssall" - [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)] - "TARGET_ALTIVEC" - "dssall" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dss" - [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")] - UNSPECV_DSS)] - "TARGET_ALTIVEC" - "dss %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dst" - [(unspec [(match_operand 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)] - "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" - "dst %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dstt" - [(unspec [(match_operand 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)] - "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" - "dstt %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dstst" - [(unspec [(match_operand 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)] - "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" - "dstst %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dststt" - [(unspec [(match_operand 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)] - "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" - "dststt %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_lvsl" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] - UNSPEC_LVSL))] - "TARGET_ALTIVEC" - "lvsl %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvsr" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] - UNSPEC_LVSR))] - "TARGET_ALTIVEC" - "lvsr %0,%y1" - [(set_attr "type" "vecload")]) - -(define_expand "build_vector_mask_for_load" - [(set (match_operand:V16QI 0 "register_operand" "") - (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))] - "TARGET_ALTIVEC" - " -{ - rtx addr; - rtx temp; - - gcc_assert (GET_CODE (operands[1]) == MEM); - - addr = XEXP (operands[1], 0); - temp = gen_reg_rtx (GET_MODE (addr)); - emit_insn (gen_rtx_SET (VOIDmode, temp, - gen_rtx_NEG (GET_MODE (addr), addr))); - emit_insn (gen_altivec_lvsr (operands[0], - replace_equiv_address (operands[1], temp))); - DONE; -}") - -;; Parallel some of the LVE* and STV*'s with unspecs because some have -;; identical rtl but different instructions-- and gcc gets confused. - -(define_insn "altivec_lve<VI_char>x" - [(parallel - [(set (match_operand:VI 0 "register_operand" "=v") - (match_operand:VI 1 "memory_operand" "Z")) - (unspec [(const_int 0)] UNSPEC_LVE)])] - "TARGET_ALTIVEC" - "lve<VI_char>x %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "*altivec_lvesfx" - [(parallel - [(set (match_operand:V4SF 0 "register_operand" "=v") - (match_operand:V4SF 1 "memory_operand" "Z")) - (unspec [(const_int 0)] UNSPEC_LVE)])] - "TARGET_ALTIVEC" - "lvewx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvxl" - [(parallel - [(set (match_operand:V4SI 0 "register_operand" "=v") - (match_operand:V4SI 1 "memory_operand" "Z")) - (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] - "TARGET_ALTIVEC" - "lvxl %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_<mode>" - [(parallel - [(set (match_operand:VM2 0 "register_operand" "=v") - (match_operand:VM2 1 "memory_operand" "Z")) - (unspec [(const_int 0)] UNSPEC_LVX)])] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_stvx_<mode>" - [(parallel - [(set (match_operand:VM2 0 "memory_operand" "=Z") - (match_operand:VM2 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVX)])] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvxl" - [(parallel - [(set (match_operand:V4SI 0 "memory_operand" "=Z") - (match_operand:V4SI 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVXL)])] - "TARGET_ALTIVEC" - "stvxl %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stve<VI_char>x" - [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z") - (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] - "TARGET_ALTIVEC" - "stve<VI_char>x %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "*altivec_stvesfx" - [(set (match_operand:SF 0 "memory_operand" "=Z") - (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))] - "TARGET_ALTIVEC" - "stvewx %1,%y0" - [(set_attr "type" "vecstore")]) - -;; Generate -;; vspltis? SCRATCH0,0 -;; vsubu?m SCRATCH2,SCRATCH1,%1 -;; vmaxs? %0,%1,SCRATCH2" -(define_expand "abs<mode>2" - [(set (match_dup 2) (vec_duplicate:VI (const_int 0))) - (set (match_dup 3) - (minus:VI (match_dup 2) - (match_operand:VI 1 "register_operand" "v"))) - (set (match_operand:VI 0 "register_operand" "=v") - (smax:VI (match_dup 1) (match_dup 3)))] - "TARGET_ALTIVEC" -{ - operands[2] = gen_reg_rtx (GET_MODE (operands[0])); - operands[3] = gen_reg_rtx (GET_MODE (operands[0])); -}) - -;; Generate -;; vspltisw SCRATCH1,-1 -;; vslw SCRATCH2,SCRATCH1,SCRATCH1 -;; vandc %0,%1,SCRATCH2 -(define_expand "altivec_absv4sf2" - [(set (match_dup 2) - (vec_duplicate:V4SI (const_int -1))) - (set (match_dup 3) - (ashift:V4SI (match_dup 2) (match_dup 2))) - (set (match_operand:V4SF 0 "register_operand" "=v") - (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0)) - (match_operand:V4SF 1 "register_operand" "v")))] - "TARGET_ALTIVEC" -{ - operands[2] = gen_reg_rtx (V4SImode); - operands[3] = gen_reg_rtx (V4SImode); -}) - -;; Generate -;; vspltis? SCRATCH0,0 -;; vsubs?s SCRATCH2,SCRATCH1,%1 -;; vmaxs? %0,%1,SCRATCH2" -(define_expand "altivec_abss_<mode>" - [(set (match_dup 2) (vec_duplicate:VI (const_int 0))) - (parallel [(set (match_dup 3) - (unspec:VI [(match_dup 2) - (match_operand:VI 1 "register_operand" "v")] - UNSPEC_VSUBS)) - (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]) - (set (match_operand:VI 0 "register_operand" "=v") - (smax:VI (match_dup 1) (match_dup 3)))] - "TARGET_ALTIVEC" -{ - operands[2] = gen_reg_rtx (GET_MODE (operands[0])); - operands[3] = gen_reg_rtx (GET_MODE (operands[0])); -}) - -(define_expand "reduc_splus_<mode>" - [(set (match_operand:VIshort 0 "register_operand" "=v") - (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")] - UNSPEC_REDUC_PLUS))] - "TARGET_ALTIVEC" -{ - rtx vzero = gen_reg_rtx (V4SImode); - rtx vtmp1 = gen_reg_rtx (V4SImode); - rtx dest = gen_lowpart (V4SImode, operands[0]); - - emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); - emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero)); - emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero)); - DONE; -}) - -(define_expand "reduc_uplus_v16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_REDUC_PLUS))] - "TARGET_ALTIVEC" -{ - rtx vzero = gen_reg_rtx (V4SImode); - rtx vtmp1 = gen_reg_rtx (V4SImode); - rtx dest = gen_lowpart (V4SImode, operands[0]); - - emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); - emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero)); - emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero)); - DONE; -}) - -(define_expand "neg<mode>2" - [(use (match_operand:VI 0 "register_operand" "")) - (use (match_operand:VI 1 "register_operand" ""))] - "TARGET_ALTIVEC" - " -{ - rtx vzero; - - vzero = gen_reg_rtx (GET_MODE (operands[0])); - emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx)); - emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); - - DONE; -}") - -(define_expand "udot_prod<mode>" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") - (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") - (match_operand:VIshort 2 "register_operand" "v")] - UNSPEC_VMSUMU)))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3])); - DONE; -}") - -(define_expand "sdot_prodv8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMSUMSHM)))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3])); - DONE; -}") - -(define_expand "widen_usum<mode>3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") - (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")] - UNSPEC_VMSUMU)))] - "TARGET_ALTIVEC" - " -{ - rtx vones = gen_reg_rtx (GET_MODE (operands[1])); - - emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx)); - emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2])); - DONE; -}") - -(define_expand "widen_ssumv16qi3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_VMSUMM)))] - "TARGET_ALTIVEC" - " -{ - rtx vones = gen_reg_rtx (V16QImode); - - emit_insn (gen_altivec_vspltisb (vones, const1_rtx)); - emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2])); - DONE; -}") - -(define_expand "widen_ssumv8hi3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] - UNSPEC_VMSUMSHM)))] - "TARGET_ALTIVEC" - " -{ - rtx vones = gen_reg_rtx (V8HImode); - - emit_insn (gen_altivec_vspltish (vones, const1_rtx)); - emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2])); - DONE; -}") - -(define_expand "vec_unpacks_hi_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_VUPKHSB))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vupkhsb (operands[0], operands[1])); - DONE; -}") - -(define_expand "vec_unpacks_hi_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] - UNSPEC_VUPKHSH))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vupkhsh (operands[0], operands[1])); - DONE; -}") - -(define_expand "vec_unpacks_lo_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_VUPKLSB))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vupklsb (operands[0], operands[1])); - DONE; -}") - -(define_expand "vec_unpacks_lo_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] - UNSPEC_VUPKLSH))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vupklsh (operands[0], operands[1])); - DONE; -}") - -(define_insn "vperm_v8hiv4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] - UNSPEC_VPERMSI))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "vperm_v16qiv8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] - UNSPEC_VPERMHI))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - - -(define_expand "vec_unpacku_hi_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_VUPKHUB))] - "TARGET_ALTIVEC" - " -{ - rtx vzero = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - - emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 0); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 2); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 4); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 6); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7); - - emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); - DONE; -}") - -(define_expand "vec_unpacku_hi_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] - UNSPEC_VUPKHUH))] - "TARGET_ALTIVEC" - " -{ - rtx vzero = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - - emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 0); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 2); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 4); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 6); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7); - - emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); - DONE; -}") - -(define_expand "vec_unpacku_lo_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] - UNSPEC_VUPKLUB))] - "TARGET_ALTIVEC" - " -{ - rtx vzero = gen_reg_rtx (V8HImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - - emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 8); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 12); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 14); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15); - - emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); - DONE; -}") - -(define_expand "vec_unpacku_lo_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] - UNSPEC_VUPKLUH))] - "TARGET_ALTIVEC" - " -{ - rtx vzero = gen_reg_rtx (V4SImode); - rtx mask = gen_reg_rtx (V16QImode); - rtvec v = rtvec_alloc (16); - - emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); - - RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 8); - RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9); - RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10); - RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11); - RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 12); - RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13); - RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16); - RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17); - RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 14); - RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15); - - emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); - emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); - DONE; -}") - -(define_expand "vec_widen_umult_hi_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULWHUB))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V8HImode); - rtx vo = gen_reg_rtx (V8HImode); - - emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghh (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_widen_umult_lo_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULWLUB))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V8HImode); - rtx vo = gen_reg_rtx (V8HImode); - - emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglh (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_widen_smult_hi_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULWHSB))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V8HImode); - rtx vo = gen_reg_rtx (V8HImode); - - emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghh (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_widen_smult_lo_v16qi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMULWLSB))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V8HImode); - rtx vo = gen_reg_rtx (V8HImode); - - emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglh (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_widen_umult_hi_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULWHUH))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghw (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_widen_umult_lo_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULWLUH))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglw (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_widen_smult_hi_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULWHSH))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrghw (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_widen_smult_lo_v8hi" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VMULWLSH))] - "TARGET_ALTIVEC" - " -{ - rtx ve = gen_reg_rtx (V4SImode); - rtx vo = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2])); - emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2])); - emit_insn (gen_altivec_vmrglw (operands[0], ve, vo)); - DONE; -}") - -(define_expand "vec_pack_trunc_v8hi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] - UNSPEC_VPKUHUM))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vpkuhum (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_expand "vec_pack_trunc_v4si" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] - UNSPEC_VPKUWUM))] - "TARGET_ALTIVEC" - " -{ - emit_insn (gen_altivec_vpkuwum (operands[0], operands[1], operands[2])); - DONE; -}") - -(define_expand "altivec_negv4sf2" - [(use (match_operand:V4SF 0 "register_operand" "")) - (use (match_operand:V4SF 1 "register_operand" ""))] - "TARGET_ALTIVEC" - " -{ - rtx neg0; - - /* Generate [-0.0, -0.0, -0.0, -0.0]. */ - neg0 = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); - emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); - - /* XOR */ - emit_insn (gen_xorv4sf3 (operands[0], - gen_lowpart (V4SFmode, neg0), operands[1])); - - DONE; -}") - -;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL, -;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell. -(define_insn "altivec_lvlx" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] - UNSPEC_LVLX))] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "lvlx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvlxl" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] - UNSPEC_LVLXL))] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "lvlxl %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvrx" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] - UNSPEC_LVRX))] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "lvrx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvrxl" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] - UNSPEC_LVRXL))] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "lvrxl %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_stvlx" - [(parallel - [(set (match_operand:V16QI 0 "memory_operand" "=Z") - (match_operand:V16QI 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVLX)])] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "stvlx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvlxl" - [(parallel - [(set (match_operand:V16QI 0 "memory_operand" "=Z") - (match_operand:V16QI 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVLXL)])] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "stvlxl %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvrx" - [(parallel - [(set (match_operand:V16QI 0 "memory_operand" "=Z") - (match_operand:V16QI 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVRX)])] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "stvrx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvrxl" - [(parallel - [(set (match_operand:V16QI 0 "memory_operand" "=Z") - (match_operand:V16QI 1 "register_operand" "v")) - (unspec [(const_int 0)] UNSPEC_STVRXL)])] - "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" - "stvrxl %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_expand "vec_unpacks_float_hi_v8hi" - [(set (match_operand:V4SF 0 "register_operand" "") - (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] - UNSPEC_VUPKHS_V4SF))] - "TARGET_ALTIVEC" - " -{ - rtx tmp = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1])); - emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); - DONE; -}") - -(define_expand "vec_unpacks_float_lo_v8hi" - [(set (match_operand:V4SF 0 "register_operand" "") - (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] - UNSPEC_VUPKLS_V4SF))] - "TARGET_ALTIVEC" - " -{ - rtx tmp = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1])); - emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); - DONE; -}") - -(define_expand "vec_unpacku_float_hi_v8hi" - [(set (match_operand:V4SF 0 "register_operand" "") - (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] - UNSPEC_VUPKHU_V4SF))] - "TARGET_ALTIVEC" - " -{ - rtx tmp = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1])); - emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); - DONE; -}") - -(define_expand "vec_unpacku_float_lo_v8hi" - [(set (match_operand:V4SF 0 "register_operand" "") - (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] - UNSPEC_VUPKLU_V4SF))] - "TARGET_ALTIVEC" - " -{ - rtx tmp = gen_reg_rtx (V4SImode); - - emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1])); - emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); - DONE; -}") diff --git a/gcc-4.8.1/gcc/config/rs6000/biarch64.h b/gcc-4.8.1/gcc/config/rs6000/biarch64.h deleted file mode 100644 index 69bf4ba4a..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/biarch64.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Definitions of target machine for GNU compiler, for 32/64 bit powerpc. - Copyright (C) 2003-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -/* Specify this in a cover file to provide bi-architecture (32/64) support. */ -#define RS6000_BI_ARCH 1 diff --git a/gcc-4.8.1/gcc/config/rs6000/cell.md b/gcc-4.8.1/gcc/config/rs6000/cell.md deleted file mode 100644 index c3ee53da7..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/cell.md +++ /dev/null @@ -1,399 +0,0 @@ -;; Scheduling description for cell processor. -;; Copyright (C) 2001-2013 Free Software Foundation, Inc. -;; Contributed by Sony Computer Entertainment, Inc., - - -;; This file is free software; you can redistribute it and/or modify it under -;; the terms of the GNU General Public License as published by the Free -;; Software Foundation; either version 3 of the License, or (at your option) -;; any later version. - -;; This file is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -;; for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; Sources: BE BOOK4 (/sfs/enc/doc/PPU_BookIV_DD3.0_latest.pdf) - -;; BE Architecture *DD3.0 and DD3.1* -;; This file simulate PPU processor unit backend of pipeline, maualP24. -;; manual P27, stall and flush points -;; IU, XU, VSU, dispatcher decodes and dispatch 2 insns per cycle in program -;; order, the grouped address are aligned by 8 -;; This file only simulate one thread situation -;; XU executes all fixed point insns(3 units, a simple alu, a complex unit, -;; and load/store unit) -;; VSU executes all scalar floating points insn(a float unit), -;; VMX insns(VMX unit, 4 sub units, simple, permute, complex, floating point) - -;; Dual issue combination - -;; FXU LSU BR VMX VMX -;; (sx,cx,vsu_fp,fp_arith) (perm,vsu_ls,fp_ls) -;;FXU X -;;LSU X X X -;;BR X -;;VMX(sx,cx,vsu_fp,fp_arth) X -;;VMX(perm,vsu_ls, fp_ls) X -;; X are illegal combination. - -;; Dual issue exceptions: -;;(1) nop-pipelined FXU instr in slot 0 -;;(2) non-pipelined FPU inst in slot 0 -;; CSI instr(contex-synchronizing insn) -;; Microcode insn - -;; BRU unit: bru(none register stall), bru_cr(cr register stall) -;; VSU unit: vus(vmx simple), vup(vmx permute), vuc(vmx complex), -;; vuf(vmx float), fpu(floats). fpu_div is hypothetical, it is for -;; nonpipelined simulation -;; micr insns will stall at least 7 cycles to get the first instr from ROM, -;; micro instructions are not dual issued. - -;; slot0 is older than slot1 -;; non-pipelined insn need to be in slot1 to avoid 1cycle stall - -;; There different stall point -;; IB2, only stall one thread if stall here, so try to stall here as much as -;; we can -;; condition(1) insert nop, OR and ORI instruction form -;; condition(2) flush happens, in case of: RAW, WAW, D-ERAT miss, or -;; CR0-access while stdcx, or stwcx -;; IS2 stall ;; Page91 for details -;; VQ8 stall -;; IS2 stall can be activated by VQ8 stall and trying to issue a vsu instr to -;; the vsu issue queue - -;;(define_automaton "cellxu") - -;;(define_cpu_unit "fxu_cell,lsu_cell,bru_cell,vsu1_cell,vsu2_cell" "cellxu") - -;; ndfa -(define_automaton "cellxu,cellvsu,cellbru,cell_mis") - -(define_cpu_unit "fxu_cell,lsu_cell" "cellxu") -(define_cpu_unit "bru_cell" "cellbru") -(define_cpu_unit "vsu1_cell,vsu2_cell" "cellvsu") - -(define_cpu_unit "slot0,slot1" "cell_mis") - -(absence_set "slot0" "slot1") - -(define_reservation "nonpipeline" "fxu_cell+lsu_cell+vsu1_cell+vsu2_cell") -(define_reservation "slot01" "slot0|slot1") - - -;; Load/store -;; lmw, lswi, lswx are only generated for optimize for space, MC, -;; these instr are not simulated -(define_insn_reservation "cell-load" 2 - (and (eq_attr "type" "load") - (eq_attr "cpu" "cell")) - "slot01,lsu_cell") - -;; ldux, ldu, lbzux, lbzu, hardware breaks it down to two instrs, -;; if with 32bytes alignment, CMC -(define_insn_reservation "cell-load-ux" 2 - (and (eq_attr "type" "load_ux,load_u") - (eq_attr "cpu" "cell")) - "slot01,fxu_cell+lsu_cell") - -;; lha, lhax, lhau, lhaux, lwa, lwax, lwaux, MC, latency unknown -;; 11/7, 11/8, 11/12 -(define_insn_reservation "cell-load-ext" 2 - (and (eq_attr "type" "load_ext,load_ext_u,load_ext_ux") - (eq_attr "cpu" "cell")) - "slot01,fxu_cell+lsu_cell") - -;;lfs,lfsx,lfd,lfdx, 1 cycle -(define_insn_reservation "cell-fpload" 1 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "cell")) - "vsu2_cell+lsu_cell+slot01") - -;; lfsu,lfsux,lfdu,lfdux 1cycle(fpr) 2 cycle(gpr) -(define_insn_reservation "cell-fpload-update" 1 - (and (eq_attr "type" "fpload,fpload_u,fpload_ux") - (eq_attr "cpu" "cell")) - "fxu_cell+vsu2_cell+lsu_cell+slot01") - -(define_insn_reservation "cell-vecload" 2 - (and (eq_attr "type" "vecload") - (eq_attr "cpu" "cell")) - "slot01,vsu2_cell+lsu_cell") - -;;st? stw(MC) -(define_insn_reservation "cell-store" 1 - (and (eq_attr "type" "store") - (eq_attr "cpu" "cell")) - "lsu_cell+slot01") - -;;stdux, stdu, (hardware breaks into store and add) 2 for update reg -(define_insn_reservation "cell-store-update" 1 - (and (eq_attr "type" "store_ux,store_u") - (eq_attr "cpu" "cell")) - "fxu_cell+lsu_cell+slot01") - -(define_insn_reservation "cell-fpstore" 1 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "cell")) - "vsu2_cell+lsu_cell+slot01") - -(define_insn_reservation "cell-fpstore-update" 1 - (and (eq_attr "type" "fpstore_ux,fpstore_u") - (eq_attr "cpu" "cell")) - "vsu2_cell+fxu_cell+lsu_cell+slot01") - -(define_insn_reservation "cell-vecstore" 1 - (and (eq_attr "type" "vecstore") - (eq_attr "cpu" "cell")) - "vsu2_cell+lsu_cell+slot01") - -;; Integer latency is 2 cycles -(define_insn_reservation "cell-integer" 2 - (and (eq_attr "type" "integer,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "cell")) - "slot01,fxu_cell") - -;; Two integer latency is 4 cycles -(define_insn_reservation "cell-two" 4 - (and (eq_attr "type" "two") - (eq_attr "cpu" "cell")) - "slot01,fxu_cell,fxu_cell*2") - -;; Three integer latency is 6 cycles -(define_insn_reservation "cell-three" 6 - (and (eq_attr "type" "three") - (eq_attr "cpu" "cell")) - "slot01,fxu_cell,fxu_cell*4") - -;; rlwimi, alter cr0 -(define_insn_reservation "cell-insert" 2 - (and (eq_attr "type" "insert_word") - (eq_attr "cpu" "cell")) - "slot01,fxu_cell") - -;; cmpi, cmpli, cmpla, add, addo, sub, subo, alter cr0 -(define_insn_reservation "cell-cmp" 1 - (and (eq_attr "type" "cmp") - (eq_attr "cpu" "cell")) - "fxu_cell+slot01") - -;; add, addo, sub, subo, alter cr0, rldcli, rlwinm -(define_insn_reservation "cell-fast-cmp" 2 - (and (and (eq_attr "type" "fast_compare,delayed_compare,compare,\ - var_delayed_compare") - (eq_attr "cpu" "cell")) - (eq_attr "cell_micro" "not")) - "slot01,fxu_cell") - -(define_insn_reservation "cell-cmp-microcoded" 9 - (and (and (eq_attr "type" "fast_compare,delayed_compare,compare,\ - var_delayed_compare") - (eq_attr "cpu" "cell")) - (eq_attr "cell_micro" "always")) - "slot0+slot1,fxu_cell,fxu_cell*7") - -;; mulld -(define_insn_reservation "cell-lmul" 15 - (and (eq_attr "type" "lmul") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*13") - -;; mulld. is microcoded -(define_insn_reservation "cell-lmul-cmp" 22 - (and (eq_attr "type" "lmul_compare") - (eq_attr "cpu" "cell")) - "slot0+slot1,nonpipeline,nonpipeline*20") - -;; mulli, 6 cycles -(define_insn_reservation "cell-imul23" 6 - (and (eq_attr "type" "imul2,imul3") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*4") - -;; mullw, 9 -(define_insn_reservation "cell-imul" 9 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*7") - -;; divide -(define_insn_reservation "cell-idiv" 32 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*30") - -(define_insn_reservation "cell-ldiv" 64 - (and (eq_attr "type" "ldiv") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*62") - -;;mflr and mfctr are pipelined -(define_insn_reservation "cell-mfjmpr" 1 - (and (eq_attr "type" "mfjmpr") - (eq_attr "cpu" "cell")) - "slot01+bru_cell") - -;;mtlr and mtctr, -;;mtspr fully pipelined -(define_insn_reservation "cell-mtjmpr" 1 - (and (eq_attr "type" "mtjmpr") - (eq_attr "cpu" "cell")) - "bru_cell+slot01") - -;; Branches -;; b, ba, bl, bla, unconditional branch always predicts correctly n/a latency -;; bcctr, bcctrl, latency 2, actually adjust by be to 4 -(define_insn_reservation "cell-branch" 1 - (and (eq_attr "type" "branch") - (eq_attr "cpu" "cell")) - "bru_cell+slot1") - -(define_insn_reservation "cell-branchreg" 1 - (and (eq_attr "type" "jmpreg") - (eq_attr "cpu" "cell")) - "bru_cell+slot1") - -;; cr hazard -;; page 90, special cases for CR hazard, only one instr can access cr per cycle -;; if insn reads CR following a stwcx, pipeline stall till stwcx finish -(define_insn_reservation "cell-crlogical" 1 - (and (eq_attr "type" "cr_logical,delayed_cr") - (eq_attr "cpu" "cell")) - "bru_cell+slot01") - -;; mfcrf and mfcr is about 34 cycles and nonpipelined -(define_insn_reservation "cell-mfcr" 34 - (and (eq_attr "type" "mfcrf,mfcr") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*32") - -;; mtcrf (1 field) -(define_insn_reservation "cell-mtcrf" 1 - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "cell")) - "fxu_cell+slot01") - -; Basic FP latency is 10 cycles, thoughput is 1/cycle -(define_insn_reservation "cell-fp" 10 - (and (eq_attr "type" "fp,dmul") - (eq_attr "cpu" "cell")) - "slot01,vsu1_cell,vsu1_cell*8") - -(define_insn_reservation "cell-fpcompare" 1 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "cell")) - "vsu1_cell+slot01") - -;; sdiv thoughput 1/74, not pipelined but only in the FPU -(define_insn_reservation "cell-sdiv" 74 - (and (eq_attr "type" "sdiv,ddiv") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*72") - -;; fsqrt thoughput 1/84, not pipelined but only in the FPU -(define_insn_reservation "cell-sqrt" 84 - (and (eq_attr "type" "ssqrt,dsqrt") - (eq_attr "cpu" "cell")) - "slot1,nonpipeline,nonpipeline*82") - -; VMX -(define_insn_reservation "cell-vecsimple" 4 - (and (eq_attr "type" "vecsimple") - (eq_attr "cpu" "cell")) - "slot01,vsu1_cell,vsu1_cell*2") - -;; mult, div, madd -(define_insn_reservation "cell-veccomplex" 10 - (and (eq_attr "type" "veccomplex") - (eq_attr "cpu" "cell")) - "slot01,vsu1_cell,vsu1_cell*8") - -;; TODO: add support for recording instructions -(define_insn_reservation "cell-veccmp" 4 - (and (eq_attr "type" "veccmp") - (eq_attr "cpu" "cell")) - "slot01,vsu1_cell,vsu1_cell*2") - -(define_insn_reservation "cell-vecfloat" 12 - (and (eq_attr "type" "vecfloat") - (eq_attr "cpu" "cell")) - "slot01,vsu1_cell,vsu1_cell*10") - -(define_insn_reservation "cell-vecperm" 4 - (and (eq_attr "type" "vecperm") - (eq_attr "cpu" "cell")) - "slot01,vsu2_cell,vsu2_cell*2") - -;; New for 4.2, syncs - -(define_insn_reservation "cell-sync" 11 - (and (eq_attr "type" "sync") - (eq_attr "cpu" "cell")) - "slot01,lsu_cell,lsu_cell*9") - -(define_insn_reservation "cell-isync" 11 - (and (eq_attr "type" "isync") - (eq_attr "cpu" "cell")) - "slot01,lsu_cell,lsu_cell*9") - -(define_insn_reservation "cell-load_l" 11 - (and (eq_attr "type" "load_l") - (eq_attr "cpu" "cell")) - "slot01,lsu_cell,lsu_cell*9") - -(define_insn_reservation "cell-store_c" 11 - (and (eq_attr "type" "store_c") - (eq_attr "cpu" "cell")) - "slot01,lsu_cell,lsu_cell*9") - -;; RAW register dependency - -;; addi r3, r3, 1 -;; lw r4,offset(r3) -;; there are 5 cycle deplay for r3 bypassing -;; there are 5 cycle delay for a dependent load after a load -(define_bypass 5 "cell-integer" "cell-load") -(define_bypass 5 "cell-integer" "cell-load-ext") -(define_bypass 5 "cell-load,cell-load-ext" "cell-load,cell-load-ext") - -;; there is a 6 cycle delay after a fp compare until you can use the cr. -(define_bypass 6 "cell-fpcompare" "cell-branch,cell-branchreg,cell-mfcr,cell-crlogical") - -;; VXU float RAW -(define_bypass 11 "cell-vecfloat" "cell-vecfloat") - -;; VXU and FPU -(define_bypass 6 "cell-veccomplex" "cell-vecsimple") -;;(define_bypass 6 "cell-veccompare" "cell-branch,cell-branchreg") -(define_bypass 3 "cell-vecfloat" "cell-veccomplex") -; this is not correct, -;; this is a stall in general and not dependent on result -(define_bypass 13 "cell-vecstore" "cell-fpstore") -; this is not correct, this can never be true, not dependent on result -(define_bypass 7 "cell-fp" "cell-fpload") -;; vsu1 should avoid writing to the same target register as vsu2 insn -;; within 12 cycles. - -;; WAW hazard - -;; the target of VSU estimate should not be reused within 10 dispatch groups -;; the target of VSU float should not be reused within 8 dispatch groups -;; the target of VSU complex should not be reused within 5 dispatch groups -;; FP LOAD should not reuse an FPU Arithmetic target with 6 dispatch gropus - -;; mtctr-bcctr/bcctrl, branch target ctr register shadow update at -;; ex4 stage(10 cycles) -(define_bypass 10 "cell-mtjmpr" "cell-branchreg") - -;;Things are not simulated: -;; update instruction, update address gpr are not simulated -;; vrefp, vrsqrtefp have latency(14), currently simulated as 12 cycle float -;; insns - diff --git a/gcc-4.8.1/gcc/config/rs6000/constraints.md b/gcc-4.8.1/gcc/config/rs6000/constraints.md deleted file mode 100644 index ccb61edce..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/constraints.md +++ /dev/null @@ -1,199 +0,0 @@ -;; Constraint definitions for RS6000 -;; Copyright (C) 2006-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; GCC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; Available constraint letters: "e", "k", "q", "u", "A", "B", "C", "D" - -;; Register constraints - -(define_register_constraint "f" "rs6000_constraints[RS6000_CONSTRAINT_f]" - "@internal") - -(define_register_constraint "d" "rs6000_constraints[RS6000_CONSTRAINT_d]" - "@internal") - -(define_register_constraint "b" "BASE_REGS" - "@internal") - -(define_register_constraint "h" "SPECIAL_REGS" - "@internal") - -(define_register_constraint "c" "CTR_REGS" - "@internal") - -(define_register_constraint "l" "LINK_REGS" - "@internal") - -(define_register_constraint "v" "ALTIVEC_REGS" - "@internal") - -(define_register_constraint "x" "CR0_REGS" - "@internal") - -(define_register_constraint "y" "CR_REGS" - "@internal") - -(define_register_constraint "z" "CA_REGS" - "@internal") - -;; Use w as a prefix to add VSX modes -;; vector double (V2DF) -(define_register_constraint "wd" "rs6000_constraints[RS6000_CONSTRAINT_wd]" - "@internal") - -;; vector float (V4SF) -(define_register_constraint "wf" "rs6000_constraints[RS6000_CONSTRAINT_wf]" - "@internal") - -;; scalar double (DF) -(define_register_constraint "ws" "rs6000_constraints[RS6000_CONSTRAINT_ws]" - "@internal") - -;; any VSX register -(define_register_constraint "wa" "rs6000_constraints[RS6000_CONSTRAINT_wa]" - "@internal") - -;; Altivec style load/store that ignores the bottom bits of the address -(define_memory_constraint "wZ" - "Indexed or indirect memory operand, ignoring the bottom 4 bits" - (match_operand 0 "altivec_indexed_or_indirect_operand")) - -;; Integer constraints - -(define_constraint "I" - "A signed 16-bit constant" - (and (match_code "const_int") - (match_test "(unsigned HOST_WIDE_INT) (ival + 0x8000) < 0x10000"))) - -(define_constraint "J" - "high-order 16 bits nonzero" - (and (match_code "const_int") - (match_test "(ival & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0"))) - -(define_constraint "K" - "low-order 16 bits nonzero" - (and (match_code "const_int") - (match_test "(ival & (~ (HOST_WIDE_INT) 0xffff)) == 0"))) - -(define_constraint "L" - "signed 16-bit constant shifted left 16 bits" - (and (match_code "const_int") - (match_test "((ival & 0xffff) == 0 - && (ival >> 31 == -1 || ival >> 31 == 0))"))) - -(define_constraint "M" - "constant greater than 31" - (and (match_code "const_int") - (match_test "ival > 31"))) - -(define_constraint "N" - "positive constant that is an exact power of two" - (and (match_code "const_int") - (match_test "ival > 0 && exact_log2 (ival) >= 0"))) - -(define_constraint "O" - "constant zero" - (and (match_code "const_int") - (match_test "ival == 0"))) - -(define_constraint "P" - "constant whose negation is signed 16-bit constant" - (and (match_code "const_int") - (match_test "(unsigned HOST_WIDE_INT) ((- ival) + 0x8000) < 0x10000"))) - -;; Floating-point constraints - -(define_constraint "G" - "Constant that can be copied into GPR with two insns for DF/DI - and one for SF." - (and (match_code "const_double") - (match_test "num_insns_constant (op, mode) - == (mode == SFmode ? 1 : 2)"))) - -(define_constraint "H" - "DF/DI constant that takes three insns." - (and (match_code "const_double") - (match_test "num_insns_constant (op, mode) == 3"))) - -;; Memory constraints - -(define_memory_constraint "es" - "A ``stable'' memory operand; that is, one which does not include any -automodification of the base register. Unlike @samp{m}, this constraint -can be used in @code{asm} statements that might access the operand -several times, or that might not access it at all." - (and (match_code "mem") - (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC"))) - -(define_memory_constraint "Q" - "Memory operand that is an offset from a register (it is usually better -to use @samp{m} or @samp{es} in @code{asm} statements)" - (and (match_code "mem") - (match_test "GET_CODE (XEXP (op, 0)) == REG"))) - -(define_memory_constraint "Y" - "memory operand for 8 byte and 16 byte gpr load/store" - (and (match_code "mem") - (match_operand 0 "mem_operand_gpr"))) - -(define_memory_constraint "Z" - "Memory operand that is an indexed or indirect from a register (it is -usually better to use @samp{m} or @samp{es} in @code{asm} statements)" - (match_operand 0 "indexed_or_indirect_operand")) - -;; Address constraints - -(define_address_constraint "a" - "Indexed or indirect address operand" - (match_operand 0 "indexed_or_indirect_address")) - -(define_constraint "R" - "AIX TOC entry" - (match_test "legitimate_constant_pool_address_p (op, QImode, false)")) - -;; General constraints - -(define_constraint "S" - "Constant that can be placed into a 64-bit mask operand" - (match_operand 0 "mask64_operand")) - -(define_constraint "T" - "Constant that can be placed into a 32-bit mask operand" - (match_operand 0 "mask_operand")) - -(define_constraint "U" - "V.4 small data reference" - (and (match_test "DEFAULT_ABI == ABI_V4") - (match_operand 0 "small_data_operand"))) - -(define_constraint "t" - "AND masks that can be performed by two rldic{l,r} insns - (but excluding those that could match other constraints of anddi3)" - (and (and (and (match_operand 0 "mask64_2_operand") - (match_test "(fixed_regs[CR0_REGNO] - || !logical_operand (op, DImode))")) - (not (match_operand 0 "mask_operand"))) - (not (match_operand 0 "mask64_operand")))) - -(define_constraint "W" - "vector constant that does not require memory" - (match_operand 0 "easy_vector_constant")) - -(define_constraint "j" - "Zero vector constant" - (match_test "op == const0_rtx || op == CONST0_RTX (GET_MODE (op))")) diff --git a/gcc-4.8.1/gcc/config/rs6000/darwin.h b/gcc-4.8.1/gcc/config/rs6000/darwin.h deleted file mode 100644 index 9d92d2af4..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/darwin.h +++ /dev/null @@ -1,424 +0,0 @@ -/* Target definitions for PowerPC running Darwin (Mac OS X). - Copyright (C) 1997-2013 Free Software Foundation, Inc. - Contributed by Apple Computer Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#undef DARWIN_PPC -#define DARWIN_PPC 1 - -/* The "Darwin ABI" is mostly like AIX, but with some key differences. */ - -#define DEFAULT_ABI ABI_DARWIN - -#ifdef IN_LIBGCC2 -#undef TARGET_64BIT -#ifdef __powerpc64__ -#define TARGET_64BIT 1 -#else -#define TARGET_64BIT 0 -#endif -#endif - -/* The object file format is Mach-O. */ - -#define TARGET_OBJECT_FORMAT OBJECT_MACHO - -/* Size of the Obj-C jump buffer. */ -#define OBJC_JBLEN ((TARGET_64BIT) ? (26*2 + 18*2 + 129 + 1) : (26 + 18*2 + 129 + 1)) - -/* We're not ever going to do TOCs. */ - -#define TARGET_TOC 0 -#define TARGET_NO_TOC 1 - -/* Override the default rs6000 definition. */ -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int") - -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - if (!TARGET_64BIT) builtin_define ("__ppc__"); \ - if (TARGET_64BIT) builtin_define ("__ppc64__"); \ - builtin_define ("__POWERPC__"); \ - builtin_define ("__NATURAL_ALIGNMENT__"); \ - darwin_cpp_builtins (pfile); \ - } \ - while (0) - -/* Generate branch islands stubs if this is true. */ -extern int darwin_emit_branch_islands; - -#define SUBTARGET_OVERRIDE_OPTIONS darwin_rs6000_override_options () - -#define C_COMMON_OVERRIDE_OPTIONS do { \ - /* On powerpc, __cxa_get_exception_ptr is available starting in the \ - 10.4.6 libstdc++.dylib. */ \ - if (strverscmp (darwin_macosx_version_min, "10.4.6") < 0 \ - && flag_use_cxa_get_exception_ptr == 2) \ - flag_use_cxa_get_exception_ptr = 0; \ - if (flag_mkernel) \ - flag_no_builtin = 1; \ - SUBTARGET_C_COMMON_OVERRIDE_OPTIONS; \ -} while (0) - -/* Darwin has 128-bit long double support in libc in 10.4 and later. - Default to 128-bit long doubles even on earlier platforms for ABI - consistency; arithmetic will work even if libc and libm support is - not available. */ - -#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128 - - -/* We want -fPIC by default, unless we're using -static to compile for - the kernel or some such. The "-faltivec" option should have been - called "-maltivec" all along. */ - -#define CC1_SPEC "\ - %(cc1_cpu) \ - %{g: %{!fno-eliminate-unused-debug-symbols: -feliminate-unused-debug-symbols }} \ - %{static: %{Zdynamic: %e conflicting code gen style switches are used}}\ - %{!mmacosx-version-min=*:-mmacosx-version-min=%(darwin_minversion)} \ - %{!mkernel:%{!static:%{!mdynamic-no-pic:-fPIC}}} \ - %{faltivec:-maltivec -include altivec.h} %{fno-altivec:-mno-altivec} \ - %<faltivec %<fno-altivec " \ - DARWIN_CC1_SPEC - -#define DARWIN_ARCH_SPEC "%{m64:ppc64;:ppc}" - -#define DARWIN_SUBARCH_SPEC " \ - %{m64: ppc64} \ - %{!m64: \ - %{mcpu=601:ppc601; \ - mcpu=603:ppc603; \ - mcpu=603e:ppc603; \ - mcpu=604:ppc604; \ - mcpu=604e:ppc604e; \ - mcpu=740:ppc750; \ - mcpu=750:ppc750; \ - mcpu=G3:ppc750; \ - mcpu=7400:ppc7400; \ - mcpu=G4:ppc7400; \ - mcpu=7450:ppc7450; \ - mcpu=970:ppc970; \ - mcpu=power4:ppc970; \ - mcpu=G5:ppc970; \ - :ppc}}" - -/* crt2.o is at least partially required for 10.3.x and earlier. */ -#define DARWIN_CRT2_SPEC \ - "%{!m64:%:version-compare(!> 10.4 mmacosx-version-min= crt2.o%s)}" - -/* Determine a minimum version based on compiler options. */ -#define DARWIN_MINVERSION_SPEC \ - "%{m64:%{fgnu-runtime:10.4; \ - ,objective-c|,objc-cpp-output:10.5; \ - ,objective-c-header:10.5; \ - ,objective-c++|,objective-c++-cpp-output:10.5; \ - ,objective-c++-header|,objc++-cpp-output:10.5; \ - :10.4}; \ - shared-libgcc:10.3; \ - :10.1}" - -#undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ - DARWIN_EXTRA_SPECS \ - { "darwin_arch", DARWIN_ARCH_SPEC }, \ - { "darwin_crt2", DARWIN_CRT2_SPEC }, \ - { "darwin_subarch", DARWIN_SUBARCH_SPEC }, - -/* Output a .machine directive. */ -#undef TARGET_ASM_FILE_START -#define TARGET_ASM_FILE_START rs6000_darwin_file_start - -/* Make both r2 and r13 available for allocation. */ -#define FIXED_R2 0 -#define FIXED_R13 0 - -/* Base register for access to local variables of the function. */ - -#undef HARD_FRAME_POINTER_REGNUM -#define HARD_FRAME_POINTER_REGNUM 30 - -#undef RS6000_PIC_OFFSET_TABLE_REGNUM -#define RS6000_PIC_OFFSET_TABLE_REGNUM 31 - -/* Pad the outgoing args area to 16 bytes instead of the usual 8. */ - -#undef STARTING_FRAME_OFFSET -#define STARTING_FRAME_OFFSET \ - (FRAME_GROWS_DOWNWARD \ - ? 0 \ - : (RS6000_ALIGN (crtl->outgoing_args_size, 16) \ - + RS6000_SAVE_AREA)) - -#undef STACK_DYNAMIC_OFFSET -#define STACK_DYNAMIC_OFFSET(FUNDECL) \ - (RS6000_ALIGN (crtl->outgoing_args_size, 16) \ - + (STACK_POINTER_OFFSET)) - -/* Darwin uses a function call if everything needs to be saved/restored. */ - -#undef WORLD_SAVE_P -#define WORLD_SAVE_P(INFO) ((INFO)->world_save_p) - -/* We don't use these on Darwin, they are just place-holders. */ -#define SAVE_FP_PREFIX "" -#define SAVE_FP_SUFFIX "" -#define RESTORE_FP_PREFIX "" -#define RESTORE_FP_SUFFIX "" - -/* The assembler wants the alternate register names, but without - leading percent sign. */ -#undef 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", \ - "sfp" \ -} - -/* This outputs NAME to FILE. */ - -#undef RS6000_OUTPUT_BASENAME -#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ - assemble_name (FILE, NAME) - -/* Globalizing directive for a label. */ -#undef GLOBAL_ASM_OP -#define GLOBAL_ASM_OP "\t.globl " -#undef TARGET_ASM_GLOBALIZE_LABEL - -/* This is how to output an internal label prefix. rs6000.c uses this - when generating traceback tables. */ -/* Not really used for Darwin? */ - -#undef ASM_OUTPUT_INTERNAL_LABEL_PREFIX -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - fprintf (FILE, "%s", PREFIX) - -/* Override the standard rs6000 definition. */ - -#undef ASM_COMMENT_START -#define ASM_COMMENT_START ";" - -/* This is how to output an assembler line that says to advance - the location counter to a multiple of 2**LOG bytes using the - "nop" instruction as padding. */ - -#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \ - do \ - { \ - if ((LOG) < 3) \ - { \ - ASM_OUTPUT_ALIGN (FILE,LOG); \ - } \ - else /* nop == ori r0,r0,0 */ \ - fprintf (FILE, "\t.align32 %d,0x60000000\n", (LOG)); \ - } while (0) - -#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN -/* This is supported in cctools 465 and later. The macro test - above prevents using it in earlier build environments. */ -#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 - -/* Generate insns to call the profiler. */ - -#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL) - -/* Function name to call to do profiling. */ - -#define RS6000_MCOUNT "*mcount" - -/* Default processor: G4, and G5 for 64-bit. */ - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC7400 -#undef PROCESSOR_DEFAULT64 -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4 - -/* Default target flag settings. Despite the fact that STMW/LMW - serializes, it's still a big code size win to use them. Use FSEL by - default as well. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_MULTIPLE | MASK_PPC_GFXOPT) - -/* Darwin always uses IBM long double, never IEEE long double. */ -#undef TARGET_IEEEQUAD -#define TARGET_IEEEQUAD 0 - -/* Since Darwin doesn't do TOCs, stub this out. */ - -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) ((void)X, (void)MODE, 0) - -/* Unlike most other PowerPC targets, chars are signed, for - consistency with other Darwin architectures. */ - -#undef DEFAULT_SIGNED_CHAR -#define DEFAULT_SIGNED_CHAR (1) - -/* 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 - in some cases it is preferable to use a more restrictive class. - - On the RS/6000, we have to return NO_REGS when we want to reload a - floating-point CONST_DOUBLE to force it to be copied to memory. - - Don't allow R0 when loading the address of, or otherwise furtling with, - a SYMBOL_REF. */ - -#undef PREFERRED_RELOAD_CLASS -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - ((CONSTANT_P (X) \ - && reg_classes_intersect_p ((CLASS), FLOAT_REGS)) \ - ? 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)) - -/* Compute field alignment. This is similar to the version of the - macro in the Apple version of GCC, except that version supports - 'mac68k' alignment, and that version uses the computed alignment - always for the first field of a structure. The first-field - behavior is dealt with by - darwin_rs6000_special_round_type_align. */ -#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ - (TARGET_ALIGN_NATURAL ? (COMPUTED) \ - : (COMPUTED) == 128 ? 128 \ - : MIN ((COMPUTED), 32)) - -/* 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) \ - && TARGET_ALIGN_NATURAL == 0 \ - ? darwin_rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \ - : (TREE_CODE (STRUCT) == VECTOR_TYPE \ - && ALTIVEC_VECTOR_MODE (TYPE_MODE (STRUCT))) \ - ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \ - : MAX ((COMPUTED), (SPECIFIED))) - -/* 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)) - -#define DOUBLE_INT_ASM_OP "\t.quad\t" - -/* For binary compatibility with 2.95; Darwin C APIs use bool from - stdbool.h, which was an int-sized enum in 2.95. Users can explicitly - choose to have sizeof(bool)==1 with the -mone-byte-bool switch. */ -#define BOOL_TYPE_SIZE (darwin_one_byte_bool ? CHAR_TYPE_SIZE : INT_TYPE_SIZE) - -#undef REGISTER_TARGET_PRAGMAS -#define REGISTER_TARGET_PRAGMAS() \ - do \ - { \ - DARWIN_REGISTER_TARGET_PRAGMAS(); \ - targetm.resolve_overloaded_builtin = altivec_resolve_overloaded_builtin; \ - } \ - while (0) - -#ifdef IN_LIBGCC2 -#include <stdbool.h> -#endif - -/* True, iff we're generating fast turn around debugging code. When - true, we arrange for function prologues to start with 5 nops so - that gdb may insert code to redirect them, and for data to be - accessed indirectly. The runtime uses this indirection to forward - references for data to the original instance of that data. */ - -#define TARGET_FIX_AND_CONTINUE (darwin_fix_and_continue) - -/* This is the reserved direct dispatch address for Objective-C. */ -#define OFFS_MSGSEND_FAST 0xFFFEFF00 - -/* This is the reserved ivar address Objective-C. */ -#define OFFS_ASSIGNIVAR_FAST 0xFFFEFEC0 - -/* Old versions of Mac OS/Darwin don't have C99 functions available. */ -#undef TARGET_C99_FUNCTIONS -#define TARGET_C99_FUNCTIONS \ - (TARGET_64BIT \ - || strverscmp (darwin_macosx_version_min, "10.3") >= 0) - -/* When generating kernel code or kexts, we don't use Altivec by - default, as kernel code doesn't save/restore those registers. */ -#define OS_MISSING_ALTIVEC (flag_mkernel || flag_apple_kext) - -/* Darwin has support for section anchors on powerpc*. - It is disabled for any section containing a "zero-sized item" (because these - are re-written as size=1 to be compatible with the OSX ld64). - The re-writing would interfere with the computation of anchor offsets. - Therefore, we place zero-sized items in their own sections and make such - sections unavailable to section anchoring. */ - -#undef TARGET_ASM_OUTPUT_ANCHOR -#define TARGET_ASM_OUTPUT_ANCHOR darwin_asm_output_anchor - -#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P -#define TARGET_USE_ANCHORS_FOR_SYMBOL_P darwin_use_anchors_for_symbol_p - -#undef DARWIN_SECTION_ANCHORS -#define DARWIN_SECTION_ANCHORS 1 - -/* PPC Darwin has to rename some of the long double builtins. */ -#undef SUBTARGET_INIT_BUILTINS -#define SUBTARGET_INIT_BUILTINS \ -do { \ - darwin_patch_builtins (); \ - rs6000_builtin_decls[(unsigned) (RS6000_BUILTIN_CFSTRING)] \ - = darwin_init_cfstring_builtins ((unsigned) (RS6000_BUILTIN_CFSTRING)); \ -} while(0) - -/* So far, there is no rs6000_fold_builtin, if one is introduced, then - this will need to be modified similar to the x86 case. */ -#define TARGET_FOLD_BUILTIN SUBTARGET_FOLD_BUILTIN diff --git a/gcc-4.8.1/gcc/config/rs6000/darwin.md b/gcc-4.8.1/gcc/config/rs6000/darwin.md deleted file mode 100644 index 24e8cfaaf..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/darwin.md +++ /dev/null @@ -1,372 +0,0 @@ -/* Machine description patterns for PowerPC running Darwin (Mac OS X). - Copyright (C) 2004-2013 Free Software Foundation, Inc. - Contributed by Apple Computer Inc. - -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 3, 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 GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. */ - -(define_insn "adddi3_high" - [(set (match_operand:DI 0 "gpc_reg_operand" "=b") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") - (high:DI (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_64BIT" - "addis %0,%1,ha16(%2)" - [(set_attr "length" "4")]) - -(define_insn "movdf_low_si" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") - (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_64BIT" - "* -{ - switch (which_alternative) - { - case 0: - return \"lfd %0,lo16(%2)(%1)\"; - case 1: - { - if (TARGET_POWERPC64 && TARGET_32BIT) - /* Note, old assemblers didn't support relocation here. */ - return \"ld %0,lo16(%2)(%1)\"; - else - { - output_asm_insn (\"la %0,lo16(%2)(%1)\", operands); - output_asm_insn (\"lwz %L0,4(%0)\", operands); - return (\"lwz %0,0(%0)\"); - } - } - default: - gcc_unreachable (); - } -}" - [(set_attr "type" "load") - (set_attr "length" "4,12")]) - - -(define_insn "movdf_low_di" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") - (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" - "* -{ - switch (which_alternative) - { - case 0: - return \"lfd %0,lo16(%2)(%1)\"; - case 1: - return \"ld %0,lo16(%2)(%1)\"; - default: - gcc_unreachable (); - } -}" - [(set_attr "type" "load") - (set_attr "length" "4,4")]) - -(define_insn "movdf_low_st_si" - [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand 2 "" ""))) - (match_operand:DF 0 "gpc_reg_operand" "f"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" - "stfd %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "movdf_low_st_di" - [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") - (match_operand 2 "" ""))) - (match_operand:DF 0 "gpc_reg_operand" "f"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" - "stfd %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "movsf_low_si" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") - (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" - "@ - lfs %0,lo16(%2)(%1) - lwz %0,lo16(%2)(%1)" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "movsf_low_di" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") - (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" - "@ - lfs %0,lo16(%2)(%1) - lwz %0,lo16(%2)(%1)" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "movsf_low_st_si" - [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))) - (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" - "@ - stfs %0,lo16(%2)(%1) - stw %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "movsf_low_st_di" - [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))) - (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" - "@ - stfs %0,lo16(%2)(%1) - stw %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -;; 64-bit MachO load/store support -(define_insn "movdi_low" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,*!d") - (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_64BIT" - "@ - ld %0,lo16(%2)(%1) - lfd %0,lo16(%2)(%1)" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "movsi_low_st" - [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand 2 "" ""))) - (match_operand:SI 0 "gpc_reg_operand" "r"))] - "TARGET_MACHO && ! TARGET_64BIT" - "stw %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "movdi_low_st" - [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") - (match_operand 2 "" ""))) - (match_operand:DI 0 "gpc_reg_operand" "r,*!d"))] - "TARGET_MACHO && TARGET_64BIT" - "@ - std %0,lo16(%2)(%1) - stfd %0,lo16(%2)(%1)" - [(set_attr "type" "store") - (set_attr "length" "4")]) - -;; Mach-O PIC trickery. -(define_expand "macho_high" - [(set (match_operand 0 "" "") - (high (match_operand 1 "" "")))] - "TARGET_MACHO" -{ - if (TARGET_64BIT) - emit_insn (gen_macho_high_di (operands[0], operands[1])); - else - emit_insn (gen_macho_high_si (operands[0], operands[1])); - - DONE; -}) - -(define_insn "macho_high_si" - [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") - (high:SI (match_operand 1 "" "")))] - "TARGET_MACHO && ! TARGET_64BIT" - "lis %0,ha16(%1)") - - -(define_insn "macho_high_di" - [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") - (high:DI (match_operand 1 "" "")))] - "TARGET_MACHO && TARGET_64BIT" - "lis %0,ha16(%1)") - -(define_expand "macho_low" - [(set (match_operand 0 "" "") - (lo_sum (match_operand 1 "" "") - (match_operand 2 "" "")))] - "TARGET_MACHO" -{ - if (TARGET_64BIT) - emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2])); - else - emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2])); - - DONE; -}) - -(define_insn "macho_low_si" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") - (match_operand 2 "" "")))] - "TARGET_MACHO && ! TARGET_64BIT" - "@ - la %0,lo16(%2)(%1) - addic %0,%1,lo16(%2)") - -(define_insn "macho_low_di" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r") - (match_operand 2 "" "")))] - "TARGET_MACHO && TARGET_64BIT" - "@ - la %0,lo16(%2)(%1) - addic %0,%1,lo16(%2)") - -(define_split - [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "short_cint_operand" ""))) - (match_operand:V4SI 2 "register_operand" "")) - (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] - "TARGET_MACHO && TARGET_64BIT" - [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1))) - (set (mem:V4SI (match_dup 3)) - (match_dup 2))] - "") - -(define_expand "load_macho_picbase" - [(set (reg:SI 65) - (unspec [(match_operand 0 "" "")] - UNSPEC_LD_MPIC))] - "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" -{ - if (TARGET_32BIT) - emit_insn (gen_load_macho_picbase_si (operands[0])); - else - emit_insn (gen_load_macho_picbase_di (operands[0])); - - DONE; -}) - -(define_insn "load_macho_picbase_si" - [(set (reg:SI 65) - (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") - (pc)] UNSPEC_LD_MPIC))] - "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" - "bcl 20,31,%0\\n%0:" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "load_macho_picbase_di" - [(set (reg:DI 65) - (unspec:DI [(match_operand:DI 0 "immediate_operand" "s") - (pc)] UNSPEC_LD_MPIC))] - "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT" - "bcl 20,31,%0\\n%0:" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_expand "macho_correct_pic" - [(set (match_operand 0 "" "") - (plus (match_operand 1 "" "") - (unspec [(match_operand 2 "" "") - (match_operand 3 "" "")] - UNSPEC_MPIC_CORRECT)))] - "DEFAULT_ABI == ABI_DARWIN" -{ - if (TARGET_32BIT) - emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2], - operands[3])); - else - emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2], - operands[3])); - - DONE; -}) - -(define_insn "macho_correct_pic_si" - [(set (match_operand:SI 0 "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")] - UNSPEC_MPIC_CORRECT)))] - "DEFAULT_ABI == ABI_DARWIN" - "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" - [(set_attr "length" "8")]) - -(define_insn "macho_correct_pic_di" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (unspec:DI [(match_operand:DI 2 "immediate_operand" "s") - (match_operand:DI 3 "immediate_operand" "s")] - 16)))] - "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" - "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" - [(set_attr "length" "8")]) - -(define_insn "*call_indirect_nonlocal_darwin64" - [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l")) - (match_operand 1 "" "g,g,g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) - (clobber (reg:SI 65))] - "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" -{ - return "b%T0l"; -} - [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*call_nonlocal_darwin64" - [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s")) - (match_operand 1 "" "g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (clobber (reg:SI 65))] - "(DEFAULT_ABI == ABI_DARWIN) - && (INTVAL (operands[2]) & CALL_LONG) == 0" -{ -#if TARGET_MACHO - return output_call(insn, operands, 0, 2); -#else - gcc_unreachable (); -#endif -} - [(set_attr "type" "branch,branch") - (set_attr "length" "4,8")]) - -(define_insn "*call_value_indirect_nonlocal_darwin64" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l")) - (match_operand 2 "" "g,g,g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) - (clobber (reg:SI 65))] - "DEFAULT_ABI == ABI_DARWIN" -{ - return "b%T1l"; -} - [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") - (set_attr "length" "4,4,8,8")]) - -(define_insn "*call_value_nonlocal_darwin64" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (reg:SI 65))] - "(DEFAULT_ABI == ABI_DARWIN) - && (INTVAL (operands[3]) & CALL_LONG) == 0" -{ -#if TARGET_MACHO - return output_call(insn, operands, 1, 3); -#else - gcc_unreachable (); -#endif -} - [(set_attr "type" "branch,branch") - (set_attr "length" "4,8")]) diff --git a/gcc-4.8.1/gcc/config/rs6000/darwin.opt b/gcc-4.8.1/gcc/config/rs6000/darwin.opt deleted file mode 100644 index c9cdd104b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/darwin.opt +++ /dev/null @@ -1,42 +0,0 @@ -; Darwin options for PPC port. -; -; Copyright (C) 2005-2013 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 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -; License for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -Waltivec-long-deprecated -Driver Alias(mwarn-altivec-long) - -faltivec -Driver - -; -ffix-and-continue and -findirect-data are for compatibility for old -; compilers. -ffix-and-continue -Driver RejectNegative Alias(mfix-and-continue) - -findirect-data -Driver RejectNegative Alias(mfix-and-continue) - -m64 -Target RejectNegative Negative(m32) Mask(64BIT) Var(rs6000_isa_flags) -Generate 64-bit code - -m32 -Target RejectNegative Negative(m64) InverseMask(64BIT) Var(rs6000_isa_flags) -Generate 32-bit code diff --git a/gcc-4.8.1/gcc/config/rs6000/darwin64.h b/gcc-4.8.1/gcc/config/rs6000/darwin64.h deleted file mode 100644 index 9c10e1c9f..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/darwin64.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Target definitions for PowerPC running Darwin (Mac OS X). - Copyright (C) 2006-2013 Free Software Foundation, Inc. - Contributed by Apple Computer Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_POWERPC64 | MASK_64BIT \ - | MASK_MULTIPLE | MASK_PPC_GFXOPT) - -#undef DARWIN_ARCH_SPEC -#define DARWIN_ARCH_SPEC "%{m32:ppc;:ppc64}" - -#undef DARWIN_SUBARCH_SPEC -#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC - -#undef DARWIN_CRT2_SPEC -#define DARWIN_CRT2_SPEC "" diff --git a/gcc-4.8.1/gcc/config/rs6000/darwin7.h b/gcc-4.8.1/gcc/config/rs6000/darwin7.h deleted file mode 100644 index 8d1d2f802..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/darwin7.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Target definitions for Darwin 7.x (Mac OS X) systems. - Copyright (C) 2004-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -/* Machine dependent libraries. Include libmx when compiling for - Darwin 7.0 and above, but before libSystem, since the functions are - actually in libSystem but for 7.x compatibility we want them to be - looked for in libmx first. Include libmx by default because otherwise - libstdc++ isn't usable. */ - -#undef LIB_SPEC -#define LIB_SPEC "%{!static:\ - %:version-compare(!< 10.3 mmacosx-version-min= -lmx)\ - -lSystem}" - -#undef DEF_MIN_OSX_VERSION -#define DEF_MIN_OSX_VERSION "10.3.9" diff --git a/gcc-4.8.1/gcc/config/rs6000/darwin8.h b/gcc-4.8.1/gcc/config/rs6000/darwin8.h deleted file mode 100644 index 391584c93..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/darwin8.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Target definitions for Darwin 8.0 and above (Mac OS X) systems. - Copyright (C) 2004-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -/* Machine dependent libraries. Include libmx when compiling on - Darwin 7.0 and above, but before libSystem, since the functions are - actually in libSystem but for 7.x compatibility we want them to be - looked for in libmx first---but only do this if 7.x compatibility - is a concern, which it's not in 64-bit mode. Include - libSystemStubs when compiling on (not necessarily for) 8.0 and - above and not 64-bit long double. */ - -#undef LIB_SPEC -#define LIB_SPEC "%{!static:\ - %{!mlong-double-64:%{pg:-lSystemStubs_profile;:-lSystemStubs}} \ - %{!m64:%:version-compare(>< 10.3 10.4 mmacosx-version-min= -lmx)} -lSystem}" diff --git a/gcc-4.8.1/gcc/config/rs6000/default64.h b/gcc-4.8.1/gcc/config/rs6000/default64.h deleted file mode 100644 index 5a6192d18..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/default64.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for 64 bit powerpc linux defaulting to -m64. - Copyright (C) 2003-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT) diff --git a/gcc-4.8.1/gcc/config/rs6000/dfp.md b/gcc-4.8.1/gcc/config/rs6000/dfp.md deleted file mode 100644 index f73e115e3..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/dfp.md +++ /dev/null @@ -1,598 +0,0 @@ -;; Decimal Floating Point (DFP) patterns. -;; Copyright (C) 2007-2013 Free Software Foundation, Inc. -;; Contributed by Ben Elliston (bje@au.ibm.com) and Peter Bergner -;; (bergner@vnet.ibm.com). - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; -;; UNSPEC usage -;; - -(define_c_enum "unspec" - [UNSPEC_MOVSD_LOAD - UNSPEC_MOVSD_STORE - ]) - - -(define_expand "movsd" - [(set (match_operand:SD 0 "nonimmediate_operand" "") - (match_operand:SD 1 "any_operand" ""))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "{ rs6000_emit_move (operands[0], operands[1], SDmode); DONE; }") - -(define_split - [(set (match_operand:SD 0 "gpc_reg_operand" "") - (match_operand:SD 1 "const_double_operand" ""))] - "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 3))] - " -{ - long l; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l); - - if (! TARGET_POWERPC64) - operands[2] = operand_subword (operands[0], 0, 0, SDmode); - else - operands[2] = gen_lowpart (SImode, operands[0]); - - operands[3] = gen_int_mode (l, SImode); -}") - -(define_insn "movsd_hardfloat" - [(set (match_operand:SD 0 "nonimmediate_operand" "=r,r,m,f,*c*l,!r,*h,!r,!r") - (match_operand:SD 1 "input_operand" "r,m,r,f,r,h,0,G,Fn"))] - "(gpc_reg_operand (operands[0], SDmode) - || gpc_reg_operand (operands[1], SDmode)) - && (TARGET_HARD_FLOAT && TARGET_FPRS)" - "@ - mr %0,%1 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - fmr %0,%1 - mt%0 %1 - mf%1 %0 - nop - # - #" - [(set_attr "type" "*,load,store,fp,mtjmpr,mfjmpr,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,8")]) - -(define_insn "movsd_softfloat" - [(set (match_operand:SD 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,r,*h") - (match_operand:SD 1 "input_operand" "r,r,h,m,r,I,L,R,G,Fn,0"))] - "(gpc_reg_operand (operands[0], SDmode) - || gpc_reg_operand (operands[1], SDmode)) - && (TARGET_SOFT_FLOAT || !TARGET_FPRS)" - "@ - mr %0,%1 - mt%0 %1 - mf%1 %0 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - li %0,%1 - lis %0,%v1 - la %0,%a1 - # - # - nop" - [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,4")]) - -(define_insn "movsd_store" - [(set (match_operand:DD 0 "nonimmediate_operand" "=m") - (unspec:DD [(match_operand:SD 1 "input_operand" "d")] - UNSPEC_MOVSD_STORE))] - "(gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], SDmode)) - && TARGET_HARD_FLOAT && TARGET_FPRS" - "stfd%U0%X0 %1,%0" - [(set_attr "type" "fpstore") - (set_attr "length" "4")]) - -(define_insn "movsd_load" - [(set (match_operand:SD 0 "nonimmediate_operand" "=f") - (unspec:SD [(match_operand:DD 1 "input_operand" "m")] - UNSPEC_MOVSD_LOAD))] - "(gpc_reg_operand (operands[0], SDmode) - || gpc_reg_operand (operands[1], DDmode)) - && TARGET_HARD_FLOAT && TARGET_FPRS" - "lfd%U1%X1 %0,%1" - [(set_attr "type" "fpload") - (set_attr "length" "4")]) - -;; Hardware support for decimal floating point operations. - -(define_insn "extendsddd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))] - "TARGET_DFP" - "dctdp %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "extendsdtd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" -{ - rtx tmp = gen_reg_rtx (DDmode); - emit_insn (gen_extendsddd2 (tmp, operands[1])); - emit_insn (gen_extendddtd2 (operands[0], tmp)); - DONE; -}) - -(define_insn "truncddsd2" - [(set (match_operand:SD 0 "gpc_reg_operand" "=f") - (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "drsp %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "negdd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - -(define_insn "*negdd2_fpr" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "fneg %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "absdd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - -(define_insn "*absdd2_fpr" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "fabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "*nabsdd2_fpr" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "fnabs %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "movdd" - [(set (match_operand:DD 0 "nonimmediate_operand" "") - (match_operand:DD 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], DDmode); DONE; }") - -(define_split - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (match_operand:DD 1 "const_int_operand" ""))] - "! TARGET_POWERPC64 && 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 1))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - HOST_WIDE_INT value = INTVAL (operands[1]); - - operands[2] = operand_subword (operands[0], endian, 0, DDmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DDmode); -#if HOST_BITS_PER_WIDE_INT == 32 - operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; -#else - operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); -#endif -}") - -(define_split - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (match_operand:DD 1 "const_double_operand" ""))] - "! TARGET_POWERPC64 && 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))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - long l[2]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l); - - operands[2] = operand_subword (operands[0], endian, 0, DDmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DDmode); - operands[4] = gen_int_mode (l[endian], SImode); - operands[5] = gen_int_mode (l[1 - endian], SImode); -}") - -(define_split - [(set (match_operand:DD 0 "gpc_reg_operand" "") - (match_operand:DD 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && 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 3))] - " -{ - 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_DECIMAL64 (rv, l); - - operands[2] = gen_lowpart (DImode, operands[0]); - /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ -#if HOST_BITS_PER_WIDE_INT >= 64 - val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 - | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - - operands[3] = gen_int_mode (val, DImode); -#else - operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); -#endif -}") - -;; Don't have reload use general registers to load a constant. First, -;; it might not work if the output operand is the equivalent of -;; a non-offsettable memref, but also it is less efficient than loading -;; the constant into an FP register, since it will probably be used there. -;; The "??" is a kludge until we can figure out a more reasonable way -;; of handling these non-offsettable values. -(define_insn "*movdd_hardfloat32" - [(set (match_operand:DD 0 "nonimmediate_operand" "=!r,??r,m,d,d,m,!r,!r,!r") - (match_operand:DD 1 "input_operand" "r,m,r,d,m,d,G,H,F"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - case 1: - case 2: - return \"#\"; - case 3: - return \"fmr %0,%1\"; - case 4: - return \"lfd%U1%X1 %0,%1\"; - case 5: - return \"stfd%U0%X0 %1,%0\"; - case 6: - case 7: - case 8: - return \"#\"; - } -}" - [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*") - (set_attr "length" "8,16,16,4,4,4,8,12,16")]) - -(define_insn "*movdd_softfloat32" - [(set (match_operand:DD 0 "nonimmediate_operand" "=r,r,m,r,r,r") - (match_operand:DD 1 "input_operand" "r,m,r,G,H,F"))] - "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "#" - [(set_attr "type" "two,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 "*movdd_hardfloat64_mfpgpr" - [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r,r,d") - (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F,d,r"))] - "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "@ - 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 - mt%0 %1 - mf%1 %0 - nop - # - # - # - mftgpr %0,%1 - mffgpr %0,%1" - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")]) - -; ld/std require word-aligned displacements -> 'Y' constraint. -; List Y->r and r->Y before r->r for reload. -(define_insn "*movdd_hardfloat64" - [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,d,d,m,*c*l,!r,*h,!r,!r,!r") - (match_operand:DD 1 "input_operand" "r,Y,r,d,m,d,r,h,0,G,H,F"))] - "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "@ - 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 - mt%0 %1 - mf%1 %0 - nop - # - # - #" - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")]) - -(define_insn "*movdd_softfloat64" - [(set (match_operand:DD 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h") - (match_operand:DD 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))] - "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) - && (gpc_reg_operand (operands[0], DDmode) - || gpc_reg_operand (operands[1], DDmode))" - "@ - ld%U1%X1 %0,%1 - std%U0%X0 %1,%0 - mr %0,%1 - mt%0 %1 - mf%1 %0 - # - # - # - nop" - [(set_attr "type" "load,store,*,mtjmpr,mfjmpr,*,*,*,*") - (set_attr "length" "4,4,4,4,4,8,12,16,4")]) - -(define_expand "negtd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "") - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - -(define_insn "*negtd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "fneg %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "abstd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "") - (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "") - -(define_insn "*abstd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "fabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "*nabstd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "fnabs %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "movtd" - [(set (match_operand:TD 0 "general_operand" "") - (match_operand:TD 1 "any_operand" ""))] - "TARGET_HARD_FLOAT && TARGET_FPRS" - "{ rs6000_emit_move (operands[0], operands[1], TDmode); DONE; }") - -; It's important to list the Y->r and r->Y moves before r->r because -; otherwise reload, given m->r, will try to pick r->r and reload it, -; which doesn't make progress. -(define_insn_and_split "*movtd_internal" - [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") - (match_operand:TD 1 "input_operand" "d,m,d,r,YGHF,r"))] - "TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], TDmode) - || gpc_reg_operand (operands[1], TDmode))" - "#" - "&& reload_completed" - [(pc)] -{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } - [(set_attr "length" "8,8,8,20,20,16")]) - -;; Hardware support for decimal floating point operations. - -(define_insn "extendddtd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dctqpq %0,%1" - [(set_attr "type" "fp")]) - -;; The result of drdpq is an even/odd register pair with the converted -;; value in the even register and zero in the odd register. -;; FIXME: Avoid the register move by using a reload constraint to ensure -;; that the result is the first of the pair receiving the result of drdpq. - -(define_insn "trunctddd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d"))) - (clobber (match_scratch:TD 2 "=d"))] - "TARGET_DFP" - "drdpq %2,%1\;fmr %0,%2" - [(set_attr "type" "fp")]) - -(define_insn "adddd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d") - (match_operand:DD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dadd %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "addtd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d") - (match_operand:TD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "daddq %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "subdd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (minus:DD (match_operand:DD 1 "gpc_reg_operand" "d") - (match_operand:DD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dsub %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "subtd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (minus:TD (match_operand:TD 1 "gpc_reg_operand" "d") - (match_operand:TD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dsubq %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "muldd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d") - (match_operand:DD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dmul %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "multd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d") - (match_operand:TD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dmulq %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "divdd3" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (div:DD (match_operand:DD 1 "gpc_reg_operand" "d") - (match_operand:DD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "ddiv %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "divtd3" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (div:TD (match_operand:TD 1 "gpc_reg_operand" "d") - (match_operand:TD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "ddivq %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "*cmpdd_internal1" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d") - (match_operand:DD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dcmpu %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -(define_insn "*cmptd_internal1" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d") - (match_operand:TD 2 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dcmpuq %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -(define_insn "floatdidd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))] - "TARGET_DFP && TARGET_POPCNTD" - "dcffix %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "floatditd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dcffixq %0,%1" - [(set_attr "type" "fp")]) - -;; Convert a decimal64 to a decimal64 whose value is an integer. -;; This is the first stage of converting it to an integer type. - -(define_insn "ftruncdd2" - [(set (match_operand:DD 0 "gpc_reg_operand" "=d") - (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "drintn. 0,%0,%1,1" - [(set_attr "type" "fp")]) - -;; Convert a decimal64 whose value is an integer to an actual integer. -;; This is the second stage of converting decimal float to integer type. - -(define_insn "fixdddi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dctfix %0,%1" - [(set_attr "type" "fp")]) - -;; Convert a decimal128 to a decimal128 whose value is an integer. -;; This is the first stage of converting it to an integer type. - -(define_insn "ftrunctd2" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "drintnq. 0,%0,%1,1" - [(set_attr "type" "fp")]) - -;; Convert a decimal128 whose value is an integer to an actual integer. -;; This is the second stage of converting decimal float to integer type. - -(define_insn "fixtddi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))] - "TARGET_DFP" - "dctfixq %0,%1" - [(set_attr "type" "fp")]) diff --git a/gcc-4.8.1/gcc/config/rs6000/driver-rs6000.c b/gcc-4.8.1/gcc/config/rs6000/driver-rs6000.c deleted file mode 100644 index 2f4d1ead8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/driver-rs6000.c +++ /dev/null @@ -1,528 +0,0 @@ -/* Subroutines for the gcc driver. - Copyright (C) 2007-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include <stdlib.h> - -#ifdef _AIX -# include <sys/systemcfg.h> -#endif - -#ifdef __linux__ -# include <link.h> -#endif - -#if defined (__APPLE__) || (__FreeBSD__) -# include <sys/types.h> -# include <sys/sysctl.h> -#endif - -const char *host_detect_local_cpu (int argc, const char **argv); - -#if GCC_VERSION >= 0 - -/* Returns parameters that describe L1_ASSOC associative cache of size - L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB. */ - -static char * -describe_cache (unsigned l1_sizekb, unsigned l1_line, - unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb) -{ - char l1size[1000], line[1000], l2size[1000]; - - /* At the moment, gcc middle-end does not use the information about the - associativity of the cache. */ - - sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb); - sprintf (line, "--param l1-cache-line-size=%u", l1_line); - sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb); - - return concat (l1size, " ", line, " ", l2size, " ", NULL); -} - -#ifdef __APPLE__ - -/* Returns the description of caches on Darwin. */ - -static char * -detect_caches_darwin (void) -{ - unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; - size_t len = 4; - static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE }; - static int l1_line_name[2] = { CTL_HW, HW_CACHELINE }; - static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE }; - - sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0); - sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0); - sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0); - l1_assoc = 0; - - return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc, - l2_sizekb / 1024); -} - -static const char * -detect_processor_darwin (void) -{ - unsigned int proc; - size_t len = 4; - - sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0); - - if (len > 0) - switch (proc) - { - case 1: - return "601"; - case 2: - return "602"; - case 3: - return "603"; - case 4: - case 5: - return "603e"; - case 6: - return "604"; - case 7: - return "604e"; - case 8: - return "620"; - case 9: - return "750"; - case 10: - return "7400"; - case 11: - return "7450"; - case 100: - return "970"; - default: - return "powerpc"; - } - - return "powerpc"; -} - -#endif /* __APPLE__ */ - -#ifdef __FreeBSD__ - -/* Returns the description of caches on FreeBSD PPC. */ - -static char * -detect_caches_freebsd (void) -{ - unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; - size_t len = 4; - - /* Currently, as of FreeBSD-7.0, there is only the cacheline_size - available via sysctl. */ - sysctlbyname ("machdep.cacheline_size", &l1_line, &len, NULL, 0); - - l1_sizekb = 32; - l1_assoc = 0; - l2_sizekb = 512; - - return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb); -} - -/* Currently returns default powerpc. */ -static const char * -detect_processor_freebsd (void) -{ - return "powerpc"; -} - -#endif /* __FreeBSD__ */ - -#ifdef __linux__ - -/* Returns AT_PLATFORM if present, otherwise generic PowerPC. */ - -static const char * -elf_platform (void) -{ - int fd; - - fd = open ("/proc/self/auxv", O_RDONLY); - - if (fd != -1) - { - char buf[1024]; - ElfW(auxv_t) *av; - ssize_t n; - - n = read (fd, buf, sizeof (buf)); - close (fd); - - if (n > 0) - { - for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av) - switch (av->a_type) - { - case AT_PLATFORM: - return (const char *) av->a_un.a_val; - - default: - break; - } - } - } - return NULL; -} - -/* Returns AT_PLATFORM if present, otherwise generic 32. */ - -static int -elf_dcachebsize (void) -{ - int fd; - - fd = open ("/proc/self/auxv", O_RDONLY); - - if (fd != -1) - { - char buf[1024]; - ElfW(auxv_t) *av; - ssize_t n; - - n = read (fd, buf, sizeof (buf)); - close (fd); - - if (n > 0) - { - for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av) - switch (av->a_type) - { - case AT_DCACHEBSIZE: - return av->a_un.a_val; - - default: - break; - } - } - } - return 32; -} - -/* Returns the description of caches on Linux. */ - -static char * -detect_caches_linux (void) -{ - unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; - const char *platform; - - platform = elf_platform (); - - if (platform != NULL) - { - l1_line = 128; - - if (platform[5] == '6') - /* POWER6 and POWER6x */ - l1_sizekb = 64; - else - l1_sizekb = 32; - } - else - { - l1_line = elf_dcachebsize (); - l1_sizekb = 32; - } - - l1_assoc = 0; - l2_sizekb = 512; - - return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb); -} - -static const char * -detect_processor_linux (void) -{ - const char *platform; - - platform = elf_platform (); - - if (platform != NULL) - return platform; - else - return "powerpc"; -} - -#endif /* __linux__ */ - -#ifdef _AIX -/* Returns the description of caches on AIX. */ - -static char * -detect_caches_aix (void) -{ - unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; - - l1_sizekb = _system_configuration.dcache_size / 1024; - l1_line = _system_configuration.dcache_line; - l1_assoc = _system_configuration.dcache_asc; - l2_sizekb = _system_configuration.L2_cache_size / 1024; - - return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb); -} - - -/* Returns the processor implementation on AIX. */ - -static const char * -detect_processor_aix (void) -{ - switch (_system_configuration.implementation) - { - case 0x0008: - return "601"; - - case 0x0020: - return "603"; - - case 0x0010: - return "604"; - - case 0x0040: - return "620"; - - case 0x0080: - return "630"; - - case 0x0100: - case 0x0200: - case 0x0400: - return "rs64"; - - case 0x0800: - return "power4"; - - case 0x2000: - if (_system_configuration.version == 0x0F0000) - return "power5"; - else - return "power5+"; - - case 0x4000: - return "power6"; - - default: - return "powerpc"; - } -} -#endif /* _AIX */ - - -/* - * Array to map -mcpu=native names to the switches passed to the assembler. - * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here - * should be made there as well. - */ - -struct asm_name { - const char *cpu; - const char *asm_sw; -}; - -static const struct asm_name asm_names[] = { -#if defined (_AIX) - { "power3", "-m620" }, - { "power4", "-mpwr4" }, - { "power5", "-mpwr5" }, - { "power5+", "-mpwr5x" }, - { "power6", "-mpwr6" }, - { "power6x", "-mpwr6" }, - { "power7", "-mpwr7" }, - { "power8", "-mpwr8" }, - { "powerpc", "-mppc" }, - { "rs64a", "-mppc" }, - { "603", "-m603" }, - { "603e", "-m603" }, - { "604", "-m604" }, - { "604e", "-m604" }, - { "620", "-m620" }, - { "630", "-m620" }, - { "970", "-m970" }, - { "G5", "-m970" }, - { NULL, "\ -%{!maix64: \ -%{mpowerpc64: -mppc64} \ -%{maltivec: -m970} \ -%{!maltivec: %{!mpowerpc64: %(asm_default)}}}" }, - -#else - { "cell", "-mcell" }, - { "power3", "-mppc64" }, - { "power4", "-mpower4" }, - { "power5", "%(asm_cpu_power5)" }, - { "power5+", "%(asm_cpu_power5)" }, - { "power6", "%(asm_cpu_power6) -maltivec" }, - { "power6x", "%(asm_cpu_power6) -maltivec" }, - { "power7", "%(asm_cpu_power7)" }, - { "power8", "%(asm_cpu_power8)" }, - { "powerpc", "-mppc" }, - { "rs64a", "-mppc64" }, - { "401", "-mppc" }, - { "403", "-m403" }, - { "405", "-m405" }, - { "405fp", "-m405" }, - { "440", "-m440" }, - { "440fp", "-m440" }, - { "464", "-m440" }, - { "464fp", "-m440" }, - { "505", "-mppc" }, - { "601", "-m601" }, - { "602", "-mppc" }, - { "603", "-mppc" }, - { "603e", "-mppc" }, - { "ec603e", "-mppc" }, - { "604", "-mppc" }, - { "604e", "-mppc" }, - { "620", "-mppc64" }, - { "630", "-mppc64" }, - { "740", "-mppc" }, - { "750", "-mppc" }, - { "G3", "-mppc" }, - { "7400", "-mppc -maltivec" }, - { "7450", "-mppc -maltivec" }, - { "G4", "-mppc -maltivec" }, - { "801", "-mppc" }, - { "821", "-mppc" }, - { "823", "-mppc" }, - { "860", "-mppc" }, - { "970", "-mpower4 -maltivec" }, - { "G5", "-mpower4 -maltivec" }, - { "8540", "-me500" }, - { "8548", "-me500" }, - { "e300c2", "-me300" }, - { "e300c3", "-me300" }, - { "e500mc", "-me500mc" }, - { NULL, "\ -%{mpowerpc64*: -mppc64} \ -%{!mpowerpc64*: %(asm_default)}" }, -#endif -}; - -/* This will be called by the spec parser in gcc.c when it sees - a %:local_cpu_detect(args) construct. Currently it will be called - with either "arch" or "tune" as argument depending on if -march=native - or -mtune=native is to be substituted. - - Additionally it will be called with "asm" to select the appropriate flags - for the assembler. - - It returns a string containing new command line parameters to be - put at the place of the above two options, depending on what CPU - this is executed. - - ARGC and ARGV are set depending on the actual arguments given - in the spec. */ -const char * -host_detect_local_cpu (int argc, const char **argv) -{ - const char *cpu = NULL; - const char *cache = ""; - const char *options = ""; - bool arch; - bool assembler; - size_t i; - - if (argc < 1) - return NULL; - - arch = strcmp (argv[0], "cpu") == 0; - assembler = (!arch && strcmp (argv[0], "asm") == 0); - if (!arch && !assembler && strcmp (argv[0], "tune")) - return NULL; - - if (! assembler) - { -#if defined (_AIX) - cache = detect_caches_aix (); -#elif defined (__APPLE__) - cache = detect_caches_darwin (); -#elif defined (__FreeBSD__) - cache = detect_caches_freebsd (); - /* FreeBSD PPC does not provide any cache information yet. */ - cache = ""; -#elif defined (__linux__) - cache = detect_caches_linux (); - /* PPC Linux does not provide any cache information yet. */ - cache = ""; -#else - cache = ""; -#endif - } - -#if defined (_AIX) - cpu = detect_processor_aix (); -#elif defined (__APPLE__) - cpu = detect_processor_darwin (); -#elif defined (__FreeBSD__) - cpu = detect_processor_freebsd (); -#elif defined (__linux__) - cpu = detect_processor_linux (); -#else - cpu = "powerpc"; -#endif - - if (assembler) - { - for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++) - { - if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu)) - return asm_names[i].asm_sw; - } - - return NULL; - } - - return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL); -} - -#else /* GCC_VERSION */ - -/* If we aren't compiling with GCC we just provide a minimal - default value. */ -const char * -host_detect_local_cpu (int argc, const char **argv) -{ - const char *cpu; - bool arch; - - if (argc < 1) - return NULL; - - arch = strcmp (argv[0], "cpu") == 0; - if (!arch && strcmp (argv[0], "tune")) - return NULL; - - if (arch) - cpu = "powerpc"; - - return concat ("-m", argv[0], "=", cpu, NULL); -} - -#endif /* GCC_VERSION */ - diff --git a/gcc-4.8.1/gcc/config/rs6000/e300c2c3.md b/gcc-4.8.1/gcc/config/rs6000/e300c2c3.md deleted file mode 100644 index 8a9b7e1cd..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/e300c2c3.md +++ /dev/null @@ -1,189 +0,0 @@ -;; Pipeline description for Motorola PowerPC e300c3 core. -;; Copyright (C) 2008-2013 Free Software Foundation, Inc. -;; Contributed by Edmar Wienskoski (edmar@freescale.com) -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_automaton "ppce300c3_most,ppce300c3_long,ppce300c3_retire") -(define_cpu_unit "ppce300c3_decode_0,ppce300c3_decode_1" "ppce300c3_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 "ppce300c3_issue_0,ppce300c3_issue_1" "ppce300c3_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 "ppce300c3_retire_0,ppce300c3_retire_1" "ppce300c3_retire") - -;; Branch unit: -(define_cpu_unit "ppce300c3_bu" "ppce300c3_most") - -;; IU: -(define_cpu_unit "ppce300c3_iu0_stage0,ppce300c3_iu1_stage0" "ppce300c3_most") - -;; IU: This used to describe non-pipelined division. -(define_cpu_unit "ppce300c3_mu_div" "ppce300c3_long") - -;; SRU: -(define_cpu_unit "ppce300c3_sru_stage0" "ppce300c3_most") - -;; Here we simplified LSU unit description not describing the stages. -(define_cpu_unit "ppce300c3_lsu" "ppce300c3_most") - -;; FPU: -(define_cpu_unit "ppce300c3_fpu" "ppce300c3_most") - -;; The following units are used to make automata deterministic -(define_cpu_unit "present_ppce300c3_decode_0" "ppce300c3_most") -(define_cpu_unit "present_ppce300c3_issue_0" "ppce300c3_most") -(define_cpu_unit "present_ppce300c3_retire_0" "ppce300c3_retire") -(define_cpu_unit "present_ppce300c3_iu0_stage0" "ppce300c3_most") - -;; The following sets to make automata deterministic when option ndfa is used. -(presence_set "present_ppce300c3_decode_0" "ppce300c3_decode_0") -(presence_set "present_ppce300c3_issue_0" "ppce300c3_issue_0") -(presence_set "present_ppce300c3_retire_0" "ppce300c3_retire_0") -(presence_set "present_ppce300c3_iu0_stage0" "ppce300c3_iu0_stage0") - -;; Some useful abbreviations. -(define_reservation "ppce300c3_decode" - "ppce300c3_decode_0|ppce300c3_decode_1+present_ppce300c3_decode_0") -(define_reservation "ppce300c3_issue" - "ppce300c3_issue_0|ppce300c3_issue_1+present_ppce300c3_issue_0") -(define_reservation "ppce300c3_retire" - "ppce300c3_retire_0|ppce300c3_retire_1+present_ppce300c3_retire_0") -(define_reservation "ppce300c3_iu_stage0" - "ppce300c3_iu0_stage0|ppce300c3_iu1_stage0+present_ppce300c3_iu0_stage0") - -;; Compares can be executed either one of the IU or SRU -(define_insn_reservation "ppce300c3_cmp" 1 - (and (eq_attr "type" "cmp,compare,delayed_compare,fast_compare") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+(ppce300c3_iu_stage0|ppce300c3_sru_stage0) \ - +ppce300c3_retire") - -;; Other one cycle IU insns -(define_insn_reservation "ppce300c3_iu" 1 - (and (eq_attr "type" "integer,insert_word,isel") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_retire") - -;; Branch. Actually this latency time is not used by the scheduler. -(define_insn_reservation "ppce300c3_branch" 1 - (and (eq_attr "type" "jmpreg,branch") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_bu,ppce300c3_retire") - -;; Multiply is non-pipelined but can be executed in any IU -(define_insn_reservation "ppce300c3_multiply" 2 - (and (eq_attr "type" "imul,imul2,imul3,imul_compare") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0, \ - ppce300c3_iu_stage0+ppce300c3_retire") - -;; Divide. We use the average latency time here. We omit reserving a -;; retire unit because of the result automata will be huge. -(define_insn_reservation "ppce300c3_divide" 20 - (and (eq_attr "type" "idiv") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_mu_div,\ - ppce300c3_mu_div*19") - -;; CR logical -(define_insn_reservation "ppce300c3_cr_logical" 1 - (and (eq_attr "type" "cr_logical,delayed_cr") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") - -;; Mfcr -(define_insn_reservation "ppce300c3_mfcr" 1 - (and (eq_attr "type" "mfcr") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") - -;; Mtcrf -(define_insn_reservation "ppce300c3_mtcrf" 1 - (and (eq_attr "type" "mtcr") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") - -;; Mtjmpr -(define_insn_reservation "ppce300c3_mtjmpr" 1 - (and (eq_attr "type" "mtjmpr,mfjmpr") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") - -;; Float point instructions -(define_insn_reservation "ppce300c3_fpcompare" 3 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "ppce300c3")) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire") - -(define_insn_reservation "ppce300c3_fp" 3 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "ppce300c3")) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire") - -(define_insn_reservation "ppce300c3_dmul" 4 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "ppce300c3")) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu,nothing,ppce300c3_retire") - -; Divides are not pipelined -(define_insn_reservation "ppce300c3_sdiv" 18 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppce300c3")) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*17") - -(define_insn_reservation "ppce300c3_ddiv" 33 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppce300c3")) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*32") - -;; Loads -(define_insn_reservation "ppce300c3_load" 2 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") - -(define_insn_reservation "ppce300c3_fpload" 2 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "ppce300c3")) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") - -;; Stores. -(define_insn_reservation "ppce300c3_store" 2 - (and (eq_attr "type" "store,store_ux,store_u") - (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") - -(define_insn_reservation "ppce300c3_fpstore" 2 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppce300c3")) - "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") diff --git a/gcc-4.8.1/gcc/config/rs6000/e500.h b/gcc-4.8.1/gcc/config/rs6000/e500.h deleted file mode 100644 index e42bf8e0b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/e500.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Enable E500 support. - Copyright (C) 2003-2013 Free Software Foundation, Inc. - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_SPE_ABI -#undef TARGET_SPE -#undef TARGET_FPRS -#undef TARGET_E500_SINGLE -#undef TARGET_E500_DOUBLE -#undef CHECK_E500_OPTIONS - -#define TARGET_SPE_ABI rs6000_spe_abi -#define TARGET_SPE rs6000_spe -#define TARGET_FPRS (rs6000_float_gprs == 0) -#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1) -#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2) -#define CHECK_E500_OPTIONS \ - do { \ - if (TARGET_SPE || TARGET_SPE_ABI \ - || TARGET_E500_SINGLE || TARGET_E500_DOUBLE) \ - { \ - if (TARGET_ALTIVEC) \ - error ("AltiVec and SPE instructions cannot coexist"); \ - if (TARGET_VSX) \ - error ("VSX and SPE instructions cannot coexist"); \ - if (TARGET_64BIT) \ - error ("64-bit SPE not supported"); \ - if (TARGET_HARD_FLOAT && TARGET_FPRS) \ - error ("E500 and FPRs not supported"); \ - } \ - } while (0) - -/* Override rs6000.h definition. */ -#undef HARD_REGNO_CALLER_SAVE_MODE -/* When setting up caller-save slots (MODE == VOIDmode) ensure we - allocate space for DFmode. Save gprs in the correct mode too. */ -#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ - (TARGET_E500_DOUBLE && ((MODE) == VOIDmode || (MODE) == DFmode) \ - ? DFmode \ - : choose_hard_reg_mode ((REGNO), (NREGS), false)) diff --git a/gcc-4.8.1/gcc/config/rs6000/e500mc.md b/gcc-4.8.1/gcc/config/rs6000/e500mc.md deleted file mode 100644 index 8b2a826bc..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/e500mc.md +++ /dev/null @@ -1,200 +0,0 @@ -;; Pipeline description for Motorola PowerPC e500mc core. -;; Copyright (C) 2008-2013 Free Software Foundation, Inc. -;; Contributed by Edmar Wienskoski (edmar@freescale.com) -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. -;; -;; e500mc 32-bit SU(2), LSU, FPU, BPU -;; Max issue 3 insns/clock cycle (includes 1 branch) -;; FP is half clocked, timings of other instructions are as in the e500v2. - -(define_automaton "e500mc_most,e500mc_long,e500mc_retire") -(define_cpu_unit "e500mc_decode_0,e500mc_decode_1" "e500mc_most") -(define_cpu_unit "e500mc_issue_0,e500mc_issue_1" "e500mc_most") -(define_cpu_unit "e500mc_retire_0,e500mc_retire_1" "e500mc_retire") - -;; SU. -(define_cpu_unit "e500mc_su0_stage0,e500mc_su1_stage0" "e500mc_most") - -;; MU. -(define_cpu_unit "e500mc_mu_stage0,e500mc_mu_stage1" "e500mc_most") -(define_cpu_unit "e500mc_mu_stage2,e500mc_mu_stage3" "e500mc_most") - -;; Non-pipelined division. -(define_cpu_unit "e500mc_mu_div" "e500mc_long") - -;; LSU. -(define_cpu_unit "e500mc_lsu" "e500mc_most") - -;; FPU. -(define_cpu_unit "e500mc_fpu" "e500mc_most") - -;; Branch unit. -(define_cpu_unit "e500mc_bu" "e500mc_most") - -;; The following units are used to make the automata deterministic. -(define_cpu_unit "present_e500mc_decode_0" "e500mc_most") -(define_cpu_unit "present_e500mc_issue_0" "e500mc_most") -(define_cpu_unit "present_e500mc_retire_0" "e500mc_retire") -(define_cpu_unit "present_e500mc_su0_stage0" "e500mc_most") - -;; The following sets to make automata deterministic when option ndfa is used. -(presence_set "present_e500mc_decode_0" "e500mc_decode_0") -(presence_set "present_e500mc_issue_0" "e500mc_issue_0") -(presence_set "present_e500mc_retire_0" "e500mc_retire_0") -(presence_set "present_e500mc_su0_stage0" "e500mc_su0_stage0") - -;; Some useful abbreviations. -(define_reservation "e500mc_decode" - "e500mc_decode_0|e500mc_decode_1+present_e500mc_decode_0") -(define_reservation "e500mc_issue" - "e500mc_issue_0|e500mc_issue_1+present_e500mc_issue_0") -(define_reservation "e500mc_retire" - "e500mc_retire_0|e500mc_retire_1+present_e500mc_retire_0") -(define_reservation "e500mc_su_stage0" - "e500mc_su0_stage0|e500mc_su1_stage0+present_e500mc_su0_stage0") - -;; Simple SU insns. -(define_insn_reservation "e500mc_su" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,cmp,compare,\ - delayed_compare,var_delayed_compare,fast_compare,\ - shift,trap,var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") - -(define_insn_reservation "e500mc_two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ - e500mc_issue+e500mc_su_stage0+e500mc_retire") - -(define_insn_reservation "e500mc_three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ - e500mc_issue+e500mc_su_stage0+e500mc_retire,\ - e500mc_issue+e500mc_su_stage0+e500mc_retire") - -;; Multiply. -(define_insn_reservation "e500mc_multiply" 4 - (and (eq_attr "type" "imul,imul2,imul3,imul_compare") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_mu_stage0,e500mc_mu_stage1,\ - e500mc_mu_stage2,e500mc_mu_stage3+e500mc_retire") - -;; Divide. We use the average latency time here. -(define_insn_reservation "e500mc_divide" 14 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_mu_stage0+e500mc_mu_div,\ - e500mc_mu_div*13") - -;; Branch. -(define_insn_reservation "e500mc_branch" 1 - (and (eq_attr "type" "jmpreg,branch,isync") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_bu,e500mc_retire") - -;; CR logical. -(define_insn_reservation "e500mc_cr_logical" 1 - (and (eq_attr "type" "cr_logical,delayed_cr") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_bu,e500mc_retire") - -;; Mfcr. -(define_insn_reservation "e500mc_mfcr" 1 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") - -;; Mtcrf. -(define_insn_reservation "e500mc_mtcrf" 1 - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") - -;; Mtjmpr. -(define_insn_reservation "e500mc_mtjmpr" 1 - (and (eq_attr "type" "mtjmpr,mfjmpr") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") - -;; Brinc. -(define_insn_reservation "e500mc_brinc" 1 - (and (eq_attr "type" "brinc") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") - -;; Loads. -(define_insn_reservation "e500mc_load" 3 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ - load_l,sync") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") - -(define_insn_reservation "e500mc_fpload" 4 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_lsu,nothing*2,e500mc_retire") - -;; Stores. -(define_insn_reservation "e500mc_store" 3 - (and (eq_attr "type" "store,store_ux,store_u,store_c") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") - -(define_insn_reservation "e500mc_fpstore" 3 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") - -;; The following ignores the retire unit to avoid a large automata. - -;; Simple FP. -(define_insn_reservation "e500mc_simple_float" 8 - (and (eq_attr "type" "fpsimple") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_fpu") -; "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") - -;; FP. -(define_insn_reservation "e500mc_float" 8 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_fpu") -; "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") - -(define_insn_reservation "e500mc_fpcompare" 8 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_fpu") - -(define_insn_reservation "e500mc_dmul" 10 - (and (eq_attr "type" "dmul") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_fpu") - -;; FP divides are not pipelined. -(define_insn_reservation "e500mc_sdiv" 36 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*35") - -(define_insn_reservation "e500mc_ddiv" 66 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppce500mc")) - "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*65") diff --git a/gcc-4.8.1/gcc/config/rs6000/e500mc64.md b/gcc-4.8.1/gcc/config/rs6000/e500mc64.md deleted file mode 100644 index b238335ed..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/e500mc64.md +++ /dev/null @@ -1,191 +0,0 @@ -;; Pipeline description for Freescale PowerPC e500mc64 core. -;; Copyright (C) 2009-2013 Free Software Foundation, Inc. -;; Contributed by Edmar Wienskoski (edmar@freescale.com) -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. -;; -;; e500mc64 64-bit SU(2), LSU, FPU, BPU -;; Max issue 3 insns/clock cycle (includes 1 branch) - -(define_automaton "e500mc64_most,e500mc64_long,e500mc64_retire") -(define_cpu_unit "e500mc64_decode_0,e500mc64_decode_1" "e500mc64_most") -(define_cpu_unit "e500mc64_issue_0,e500mc64_issue_1" "e500mc64_most") -(define_cpu_unit "e500mc64_retire_0,e500mc64_retire_1" "e500mc64_retire") - -;; SU. -(define_cpu_unit "e500mc64_su0_stage0,e500mc64_su1_stage0" "e500mc64_most") - -;; MU. -(define_cpu_unit "e500mc64_mu_stage0,e500mc64_mu_stage1" "e500mc64_most") -(define_cpu_unit "e500mc64_mu_stage2,e500mc64_mu_stage3" "e500mc64_most") - -;; Non-pipelined division. -(define_cpu_unit "e500mc64_mu_div" "e500mc64_long") - -;; LSU. -(define_cpu_unit "e500mc64_lsu" "e500mc64_most") - -;; FPU. -(define_cpu_unit "e500mc64_fpu" "e500mc64_most") - -;; Branch unit. -(define_cpu_unit "e500mc64_bu" "e500mc64_most") - -;; The following units are used to make the automata deterministic. -(define_cpu_unit "present_e500mc64_decode_0" "e500mc64_most") -(define_cpu_unit "present_e500mc64_issue_0" "e500mc64_most") -(define_cpu_unit "present_e500mc64_retire_0" "e500mc64_retire") -(define_cpu_unit "present_e500mc64_su0_stage0" "e500mc64_most") - -;; The following sets to make automata deterministic when option ndfa is used. -(presence_set "present_e500mc64_decode_0" "e500mc64_decode_0") -(presence_set "present_e500mc64_issue_0" "e500mc64_issue_0") -(presence_set "present_e500mc64_retire_0" "e500mc64_retire_0") -(presence_set "present_e500mc64_su0_stage0" "e500mc64_su0_stage0") - -;; Some useful abbreviations. -(define_reservation "e500mc64_decode" - "e500mc64_decode_0|e500mc64_decode_1+present_e500mc64_decode_0") -(define_reservation "e500mc64_issue" - "e500mc64_issue_0|e500mc64_issue_1+present_e500mc64_issue_0") -(define_reservation "e500mc64_retire" - "e500mc64_retire_0|e500mc64_retire_1+present_e500mc64_retire_0") -(define_reservation "e500mc64_su_stage0" - "e500mc64_su0_stage0|e500mc64_su1_stage0+present_e500mc64_su0_stage0") - -;; Simple SU insns. -(define_insn_reservation "e500mc64_su" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,delayed_compare,\ - shift,cntlz,exts") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") - -(define_insn_reservation "e500mc64_su2" 2 - (and (eq_attr "type" "cmp,compare,delayed_compare,fast_compare,trap") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") - -(define_insn_reservation "e500mc64_delayed" 2 - (and (eq_attr "type" "var_shift_rotate,var_delayed_compare") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") - -(define_insn_reservation "e500mc64_two" 2 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ - e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") - -(define_insn_reservation "e500mc64_three" 3 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ - e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ - e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") - -;; Multiply. -(define_insn_reservation "e500mc64_multiply" 4 - (and (eq_attr "type" "imul,imul2,imul3,imul_compare") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0,e500mc64_mu_stage1,\ - e500mc64_mu_stage2,e500mc64_mu_stage3+e500mc64_retire") - -;; Divide. We use the average latency time here. -(define_insn_reservation "e500mc64_divide" 14 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0+e500mc64_mu_div,\ - e500mc64_mu_div*13") - -;; Branch. -(define_insn_reservation "e500mc64_branch" 1 - (and (eq_attr "type" "jmpreg,branch,isync") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_bu,e500mc64_retire") - -;; CR logical. -(define_insn_reservation "e500mc64_cr_logical" 1 - (and (eq_attr "type" "cr_logical,delayed_cr") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_bu,e500mc64_retire") - -;; Mfcr. -(define_insn_reservation "e500mc64_mfcr" 4 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0,e500mc64_su1_stage0*3+e500mc64_retire") - -;; Mtcrf. -(define_insn_reservation "e500mc64_mtcrf" 1 - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0+e500mc64_retire") - -;; Mtjmpr. -(define_insn_reservation "e500mc64_mtjmpr" 1 - (and (eq_attr "type" "mtjmpr,mfjmpr") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") - -;; Brinc. -(define_insn_reservation "e500mc64_brinc" 1 - (and (eq_attr "type" "brinc") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") - -;; Loads. -(define_insn_reservation "e500mc64_load" 3 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ - load_l,sync") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") - -(define_insn_reservation "e500mc64_fpload" 4 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing*2,e500mc64_retire") - -;; Stores. -(define_insn_reservation "e500mc64_store" 3 - (and (eq_attr "type" "store,store_ux,store_u,store_c") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") - -(define_insn_reservation "e500mc64_fpstore" 3 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") - -;; The following ignores the retire unit to avoid a large automata. - -;; FP. -(define_insn_reservation "e500mc64_float" 7 - (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_fpu") -; "e500mc64_decode,e500mc64_issue+e500mc64_fpu,nothing*5,e500mc64_retire") - -;; FP divides are not pipelined. -(define_insn_reservation "e500mc64_sdiv" 20 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*19") - -(define_insn_reservation "e500mc64_ddiv" 35 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppce500mc64")) - "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*34") diff --git a/gcc-4.8.1/gcc/config/rs6000/e5500.md b/gcc-4.8.1/gcc/config/rs6000/e5500.md deleted file mode 100644 index 68cc369dd..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/e5500.md +++ /dev/null @@ -1,176 +0,0 @@ -;; Pipeline description for Freescale PowerPC e5500 core. -;; Copyright (C) 2012-2013 Free Software Foundation, Inc. -;; Contributed by Edmar Wienskoski (edmar@freescale.com) -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. -;; -;; e5500 64-bit SFX(2), CFX, LSU, FPU, BU -;; Max issue 3 insns/clock cycle (includes 1 branch) - -(define_automaton "e5500_most,e5500_long") -(define_cpu_unit "e5500_decode_0,e5500_decode_1" "e5500_most") - -;; SFX. -(define_cpu_unit "e5500_sfx_0,e5500_sfx_1" "e5500_most") - -;; CFX. -(define_cpu_unit "e5500_cfx_stage0,e5500_cfx_stage1" "e5500_most") - -;; Non-pipelined division. -(define_cpu_unit "e5500_cfx_div" "e5500_long") - -;; LSU. -(define_cpu_unit "e5500_lsu" "e5500_most") - -;; FPU. -(define_cpu_unit "e5500_fpu" "e5500_long") - -;; BU. -(define_cpu_unit "e5500_bu" "e5500_most") - -;; The following units are used to make the automata deterministic. -(define_cpu_unit "present_e5500_decode_0" "e5500_most") -(define_cpu_unit "present_e5500_sfx_0" "e5500_most") -(presence_set "present_e5500_decode_0" "e5500_decode_0") -(presence_set "present_e5500_sfx_0" "e5500_sfx_0") - -;; Some useful abbreviations. -(define_reservation "e5500_decode" - "e5500_decode_0|e5500_decode_1+present_e5500_decode_0") -(define_reservation "e5500_sfx" - "e5500_sfx_0|e5500_sfx_1+present_e5500_sfx_0") - -;; SFX. -(define_insn_reservation "e5500_sfx" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,delayed_compare,\ - shift,cntlz,exts") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_sfx") - -(define_insn_reservation "e5500_sfx2" 2 - (and (eq_attr "type" "cmp,compare,fast_compare,trap") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_sfx") - -(define_insn_reservation "e5500_delayed" 2 - (and (eq_attr "type" "var_shift_rotate,var_delayed_compare") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_sfx*2") - -(define_insn_reservation "e5500_two" 2 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_decode+e5500_sfx,e5500_sfx") - -(define_insn_reservation "e5500_three" 3 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,(e5500_decode+e5500_sfx)*2,e5500_sfx") - -;; SFX - Mfcr. -(define_insn_reservation "e5500_mfcr" 4 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_sfx_0*4") - -;; SFX - Mtcrf. -(define_insn_reservation "e5500_mtcrf" 1 - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_sfx_0") - -;; SFX - Mtjmpr. -(define_insn_reservation "e5500_mtjmpr" 1 - (and (eq_attr "type" "mtjmpr,mfjmpr") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_sfx") - -;; CFX - Multiply. -(define_insn_reservation "e5500_multiply" 4 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_cfx_stage0,e5500_cfx_stage1") - -(define_insn_reservation "e5500_multiply_i" 5 - (and (eq_attr "type" "imul2,imul3,imul_compare") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_cfx_stage0,\ - e5500_cfx_stage0+e5500_cfx_stage1,e5500_cfx_stage1") - -;; CFX - Divide. -(define_insn_reservation "e5500_divide" 16 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_cfx_stage0+e5500_cfx_div,\ - e5500_cfx_div*15") - -(define_insn_reservation "e5500_divide_d" 26 - (and (eq_attr "type" "ldiv") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_cfx_stage0+e5500_cfx_div,\ - e5500_cfx_div*25") - -;; LSU - Loads. -(define_insn_reservation "e5500_load" 3 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ - load_l,sync") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_lsu") - -(define_insn_reservation "e5500_fpload" 4 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_lsu") - -;; LSU - Stores. -(define_insn_reservation "e5500_store" 3 - (and (eq_attr "type" "store,store_ux,store_u,store_c") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_lsu") - -(define_insn_reservation "e5500_fpstore" 3 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_lsu") - -;; FP. -(define_insn_reservation "e5500_float" 7 - (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_fpu") - -(define_insn_reservation "e5500_sdiv" 20 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_fpu*20") - -(define_insn_reservation "e5500_ddiv" 35 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_fpu*35") - -;; BU. -(define_insn_reservation "e5500_branch" 1 - (and (eq_attr "type" "jmpreg,branch,isync") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_bu") - -;; BU - CR logical. -(define_insn_reservation "e5500_cr_logical" 1 - (and (eq_attr "type" "cr_logical,delayed_cr") - (eq_attr "cpu" "ppce5500")) - "e5500_decode,e5500_bu") diff --git a/gcc-4.8.1/gcc/config/rs6000/e6500.md b/gcc-4.8.1/gcc/config/rs6000/e6500.md deleted file mode 100644 index cfd4fced8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/e6500.md +++ /dev/null @@ -1,213 +0,0 @@ -;; Pipeline description for Freescale PowerPC e6500 core. -;; Copyright (C) 2012-2013 Free Software Foundation, Inc. -;; Contributed by Edmar Wienskoski (edmar@freescale.com) -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. -;; -;; e6500 64-bit SFX(2), CFX, LSU, FPU, BU, VSFX, VCFX, VFPU, VPERM -;; Max issue 3 insns/clock cycle (includes 1 branch) - -(define_automaton "e6500_most,e6500_long,e6500_vec") -(define_cpu_unit "e6500_decode_0,e6500_decode_1" "e6500_most") - -;; SFX. -(define_cpu_unit "e6500_sfx_0,e6500_sfx_1" "e6500_most") - -;; CFX. -(define_cpu_unit "e6500_cfx_stage0,e6500_cfx_stage1" "e6500_most") - -;; Non-pipelined division. -(define_cpu_unit "e6500_cfx_div" "e6500_long") - -;; LSU. -(define_cpu_unit "e6500_lsu" "e6500_most") - -;; FPU. -(define_cpu_unit "e6500_fpu" "e6500_long") - -;; BU. -(define_cpu_unit "e6500_bu" "e6500_most") - -;; Altivec unit -(define_cpu_unit "e6500_vec,e6500_vecperm" "e6500_vec") - -;; The following units are used to make the automata deterministic. -(define_cpu_unit "present_e6500_decode_0" "e6500_most") -(define_cpu_unit "present_e6500_sfx_0" "e6500_most") -(presence_set "present_e6500_decode_0" "e6500_decode_0") -(presence_set "present_e6500_sfx_0" "e6500_sfx_0") - -;; Some useful abbreviations. -(define_reservation "e6500_decode" - "e6500_decode_0|e6500_decode_1+present_e6500_decode_0") -(define_reservation "e6500_sfx" - "e6500_sfx_0|e6500_sfx_1+present_e6500_sfx_0") - -;; SFX. -(define_insn_reservation "e6500_sfx" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,delayed_compare,\ - shift,cntlz,exts") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_sfx") - -(define_insn_reservation "e6500_sfx2" 2 - (and (eq_attr "type" "cmp,compare,fast_compare,trap") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_sfx") - -(define_insn_reservation "e6500_delayed" 2 - (and (eq_attr "type" "var_shift_rotate,var_delayed_compare") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_sfx*2") - -(define_insn_reservation "e6500_two" 2 - (and (eq_attr "type" "two") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_decode+e6500_sfx,e6500_sfx") - -(define_insn_reservation "e6500_three" 3 - (and (eq_attr "type" "three") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,(e6500_decode+e6500_sfx)*2,e6500_sfx") - -;; SFX - Mfcr. -(define_insn_reservation "e6500_mfcr" 4 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_sfx_0*4") - -;; SFX - Mtcrf. -(define_insn_reservation "e6500_mtcrf" 1 - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_sfx_0") - -;; SFX - Mtjmpr. -(define_insn_reservation "e6500_mtjmpr" 1 - (and (eq_attr "type" "mtjmpr,mfjmpr") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_sfx") - -;; CFX - Multiply. -(define_insn_reservation "e6500_multiply" 4 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_cfx_stage0,e6500_cfx_stage1") - -(define_insn_reservation "e6500_multiply_i" 5 - (and (eq_attr "type" "imul2,imul3,imul_compare") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_cfx_stage0,\ - e6500_cfx_stage0+e6500_cfx_stage1,e6500_cfx_stage1") - -;; CFX - Divide. -(define_insn_reservation "e6500_divide" 16 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_cfx_stage0+e6500_cfx_div,\ - e6500_cfx_div*15") - -(define_insn_reservation "e6500_divide_d" 26 - (and (eq_attr "type" "ldiv") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_cfx_stage0+e6500_cfx_div,\ - e6500_cfx_div*25") - -;; LSU - Loads. -(define_insn_reservation "e6500_load" 3 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ - load_l,sync") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_lsu") - -(define_insn_reservation "e6500_fpload" 4 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_lsu") - -(define_insn_reservation "e6500_vecload" 4 - (and (eq_attr "type" "vecload") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_lsu") - -;; LSU - Stores. -(define_insn_reservation "e6500_store" 3 - (and (eq_attr "type" "store,store_ux,store_u,store_c") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_lsu") - -(define_insn_reservation "e6500_fpstore" 3 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_lsu") - -(define_insn_reservation "e6500_vecstore" 4 - (and (eq_attr "type" "vecstore") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_lsu") - -;; FP. -(define_insn_reservation "e6500_float" 7 - (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_fpu") - -(define_insn_reservation "e6500_sdiv" 20 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_fpu*20") - -(define_insn_reservation "e6500_ddiv" 35 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_fpu*35") - -;; BU. -(define_insn_reservation "e6500_branch" 1 - (and (eq_attr "type" "jmpreg,branch,isync") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_bu") - -;; BU - CR logical. -(define_insn_reservation "e6500_cr_logical" 1 - (and (eq_attr "type" "cr_logical,delayed_cr") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_bu") - -;; VSFX. -(define_insn_reservation "e6500_vecsimple" 1 - (and (eq_attr "type" "vecsimple,veccmp") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_vec") - -;; VCFX. -(define_insn_reservation "e6500_veccomplex" 4 - (and (eq_attr "type" "veccomplex") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_vec") - -;; VFPU. -(define_insn_reservation "e6500_vecfloat" 6 - (and (eq_attr "type" "vecfloat") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_vec") - -;; VPERM. -(define_insn_reservation "e6500_vecperm" 2 - (and (eq_attr "type" "vecperm") - (eq_attr "cpu" "ppce6500")) - "e6500_decode,e6500_vecperm") diff --git a/gcc-4.8.1/gcc/config/rs6000/eabi.h b/gcc-4.8.1/gcc/config/rs6000/eabi.h deleted file mode 100644 index 6afc01768..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/eabi.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Core target definitions for GNU compiler - for IBM RS/6000 PowerPC targeted to embedded ELF systems. - Copyright (C) 1995-2013 Free Software Foundation, Inc. - Contributed by Cygnus Support. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Add -meabi to target flags. */ -#undef TARGET_DEFAULT -#define TARGET_DEFAULT MASK_EABI - -/* Invoke an initializer function to set up the GOT. */ -#define NAME__MAIN "__eabi" -#define INVOKE__main - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define_std ("PPC"); \ - builtin_define ("__embedded__"); \ - builtin_assert ("system=embedded"); \ - builtin_assert ("cpu=powerpc"); \ - builtin_assert ("machine=powerpc"); \ - TARGET_OS_SYSV_CPP_BUILTINS (); \ - } \ - while (0) diff --git a/gcc-4.8.1/gcc/config/rs6000/eabialtivec.h b/gcc-4.8.1/gcc/config/rs6000/eabialtivec.h deleted file mode 100644 index e9738aab0..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/eabialtivec.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Core target definitions for GNU compiler - for PowerPC targeted systems with AltiVec support. - Copyright (C) 2001-2013 Free Software Foundation, Inc. - Contributed by Aldy Hernandez (aldyh@redhat.com). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Add -meabi and -maltivec to target flags. */ -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_EABI | MASK_ALTIVEC) - -#undef SUBSUBTARGET_OVERRIDE_OPTIONS -#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1 diff --git a/gcc-4.8.1/gcc/config/rs6000/eabisim.h b/gcc-4.8.1/gcc/config/rs6000/eabisim.h deleted file mode 100644 index 12da21e4e..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/eabisim.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Support for GCC on simulated PowerPC systems targeted to embedded ELF - systems. - Copyright (C) 1995-2013 Free Software Foundation, Inc. - Contributed by Cygnus Support. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define_std ("PPC"); \ - builtin_define ("__embedded__"); \ - builtin_define ("__simulator__"); \ - builtin_assert ("system=embedded"); \ - builtin_assert ("system=simulator"); \ - builtin_assert ("cpu=powerpc"); \ - builtin_assert ("machine=powerpc"); \ - TARGET_OS_SYSV_CPP_BUILTINS (); \ - } \ - while (0) - -/* Make the simulator the default */ -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_sim)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_sim)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_sim)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_sim)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_sim)" diff --git a/gcc-4.8.1/gcc/config/rs6000/eabispe.h b/gcc-4.8.1/gcc/config/rs6000/eabispe.h deleted file mode 100644 index fa171c056..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/eabispe.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Core target definitions for GNU compiler - for PowerPC embedded targeted systems with SPE support. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Aldy Hernandez (aldyh@redhat.com). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_STRICT_ALIGN | MASK_EABI) - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc -mspe -me500" diff --git a/gcc-4.8.1/gcc/config/rs6000/freebsd.h b/gcc-4.8.1/gcc/config/rs6000/freebsd.h deleted file mode 100644 index d9313e8d0..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/freebsd.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Definitions for PowerPC running FreeBSD using the ELF format - Copyright (C) 2001-2013 Free Software Foundation, Inc. - Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Override the defaults, which exist to force the proper definition. */ - -#undef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_freebsd)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_freebsd)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_freebsd)" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_freebsd)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_freebsd)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)" - -/* XXX: This is wrong for many platforms in sysv4.h. - We should work on getting that definition fixed. */ -#undef LINK_SHLIB_SPEC -#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" - - -/************************[ Target stuff ]***********************************/ - -/* Define the actual types of some ANSI-mandated types. - Needs to agree with <machine/ansi.h>. GCC defaults come from c-decl.c, - c-common.c, and config/<arch>/<arch>.h. */ - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -/* rs6000.h gets this wrong for FreeBSD. We use the GCC defaults instead. */ -#undef WCHAR_TYPE - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - -/* Override rs6000.h definition. */ -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -/* Override rs6000.h definition. */ -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -/* We don't need to generate entries in .fixup, except when - -mrelocatable or -mrelocatable-lib is given. */ -#undef RELOCATABLE_NEEDS_FIXUP -#define RELOCATABLE_NEEDS_FIXUP \ - (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) - -#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) - -#define POWERPC_FREEBSD diff --git a/gcc-4.8.1/gcc/config/rs6000/freebsd64.h b/gcc-4.8.1/gcc/config/rs6000/freebsd64.h deleted file mode 100644 index b764f763d..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/freebsd64.h +++ /dev/null @@ -1,435 +0,0 @@ -/* Definitions for 64-bit PowerPC running FreeBSD using the ELF format - Copyright (C) 2012-2013 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Override the defaults, which exist to force the proper definition. */ - -#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 - -#ifdef HAVE_LD_NO_DOT_SYMS -/* New ABI uses a local sym for the function entry point. */ -extern int dot_symbols; -#undef DOT_SYMBOLS -#define DOT_SYMBOLS dot_symbols -#endif - -#define TARGET_USES_LINUX64_OPT 1 -#ifdef HAVE_LD_LARGE_TOC -#undef TARGET_CMODEL -#define TARGET_CMODEL rs6000_current_cmodel -#define SET_CMODEL(opt) rs6000_current_cmodel = opt -#else -#define SET_CMODEL(opt) do {} while (0) -#endif - -/* Until now the 970 is the only Processor where FreeBSD 64-bit runs on. */ -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWER4 -#undef PROCESSOR_DEFAULT64 -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4 - -/* We don't need to generate entries in .fixup, except when - -mrelocatable or -mrelocatable-lib is given. */ -#undef RELOCATABLE_NEEDS_FIXUP -#define RELOCATABLE_NEEDS_FIXUP \ - (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) - -#undef RS6000_ABI_NAME -#define RS6000_ABI_NAME "freebsd" - -#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 (!global_options_set.x_rs6000_alignment_flags) \ - rs6000_alignment_flags = MASK_ALIGN_NATURAL; \ - if (TARGET_64BIT) \ - { \ - if (DEFAULT_ABI != ABI_AIX) \ - { \ - rs6000_current_abi = ABI_AIX; \ - error (INVALID_64BIT, "call"); \ - } \ - dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \ - if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \ - error (INVALID_64BIT, "relocatable"); \ - } \ - if (rs6000_isa_flags & OPTION_MASK_EABI) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_EABI; \ - error (INVALID_64BIT, "eabi"); \ - } \ - if (TARGET_PROTOTYPE) \ - { \ - target_prototype = 0; \ - error (INVALID_64BIT, "prototype"); \ - } \ - if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0) \ - { \ - rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ - error ("-m64 requires a PowerPC64 cpu"); \ - } \ - if ((rs6000_isa_flags_explicit \ - & OPTION_MASK_MINIMAL_TOC) != 0) \ - { \ - if (global_options_set.x_rs6000_current_cmodel \ - && rs6000_current_cmodel != CMODEL_SMALL) \ - error ("-mcmodel incompatible with other toc options"); \ - SET_CMODEL (CMODEL_SMALL); \ - } \ - else \ - { \ - if (!global_options_set.x_rs6000_current_cmodel) \ - SET_CMODEL (CMODEL_MEDIUM); \ - if (rs6000_current_cmodel != CMODEL_SMALL) \ - { \ - TARGET_NO_FP_IN_TOC = 0; \ - TARGET_NO_SUM_IN_TOC = 0; \ - } \ - } \ - } \ - } \ - while (0) - -#undef ASM_DEFAULT_SPEC -#undef ASM_SPEC -#undef LINK_OS_FREEBSD_SPEC - -#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}" -#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)" -#define LINK_OS_FREEBSD_SPEC "%{m32:%(link_os_freebsd_spec32)}%{!m32:%(link_os_freebsd_spec64)}" - -#define ASM_SPEC32 "-a32 \ -%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \ -%{memb} %{!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) \ -%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ -%{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_freebsd_spec32", LINK_OS_FREEBSD_SPEC32 }, \ - { "link_os_freebsd_spec64", LINK_OS_FREEBSD_SPEC64 }, - -#define FREEBSD_DYNAMIC_LINKER32 "/libexec/ld-elf32.so.1" -#define FREEBSD_DYNAMIC_LINKER64 "/libexec/ld-elf.so.1" - -#define LINK_OS_FREEBSD_SPEC_DEF32 "\ - %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \ - %{v:-V} \ - %{assert*} %{R*} %{rpath*} %{defsym*} \ - %{shared:-Bshareable %{h*} %{soname*}} \ - %{!shared: \ - %{!static: \ - %{rdynamic: -export-dynamic} \ - %{!dynamic-linker:-dynamic-linker " FREEBSD_DYNAMIC_LINKER32 "}} \ - %{static:-Bstatic}} \ - %{symbolic:-Bsymbolic}" - -#define LINK_OS_FREEBSD_SPEC_DEF64 "\ - %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \ - %{v:-V} \ - %{assert*} %{R*} %{rpath*} %{defsym*} \ - %{shared:-Bshareable %{h*} %{soname*}} \ - %{!shared: \ - %{!static: \ - %{rdynamic: -export-dynamic} \ - %{!dynamic-linker:-dynamic-linker " FREEBSD_DYNAMIC_LINKER64 "}} \ - %{static:-Bstatic}} \ - %{symbolic:-Bsymbolic}" - -#define LINK_OS_FREEBSD_SPEC32 "-melf32ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF32 - -#define LINK_OS_FREEBSD_SPEC64 "-melf64ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF64 - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "m64" } - -/* PowerPC-64 FreeBSD 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_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))) - -/* Use the default for compiling target libs. */ -#ifdef IN_TARGET_LIBS -#undef TARGET_ALIGN_NATURAL -#define TARGET_ALIGN_NATURAL 1 -#endif - -/* Indicate that jump tables go in the text section. */ -#undef JUMP_TABLES_IN_TEXT_SECTION -#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. i.e. pad upward. - 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 - -/* 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)) - -/* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit - kernel. This is supported when running on a 64-bit kernel with - COMPAT_FREEBSD32, but tell GCC it isn't so that our 32-bit binaries - are compatible. */ -#define OS_MISSING_POWERPC64 !TARGET_64BIT - -#undef FBSD_TARGET_CPU_CPP_BUILTINS -#define FBSD_TARGET_CPU_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("__PPC__"); \ - builtin_define ("__ppc__"); \ - builtin_define ("__powerpc__"); \ - if (TARGET_64BIT) \ - { \ - builtin_define ("__arch64__"); \ - builtin_define ("__LP64__"); \ - builtin_define ("__PPC64__"); \ - builtin_define ("__powerpc64__"); \ - 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 -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_freebsd)" - -#undef CPP_OS_FREEBSD_SPEC -#define CPP_OS_FREEBSD_SPEC "" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_freebsd)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_freebsd)" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_freebsd)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_freebsd)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)" - -/* XXX: This is wrong for many platforms in sysv4.h. - We should work on getting that definition fixed. */ -#undef LINK_SHLIB_SPEC -#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" - - -/************************[ Target stuff ]***********************************/ - -/* Define the actual types of some ANSI-mandated types. - Needs to agree with <machine/ansi.h>. GCC defaults come from c-decl.c, - c-common.c, and config/<arch>/<arch>.h. */ - - -#undef SIZE_TYPE -#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int") - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int") - -/* rs6000.h gets this wrong for FreeBSD. We use the GCC defaults instead. */ -#undef WCHAR_TYPE -#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int") -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - - -/* Override rs6000.h definition. */ -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -/* Override rs6000.h definition. */ -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -/* Function profiling bits */ -#undef RS6000_MCOUNT -#define RS6000_MCOUNT "_mcount" - -#define PROFILE_HOOK(LABEL) \ - do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0) - -/* _init and _fini functions are built from bits spread across many - object files, each potentially with a different TOC pointer. For - that reason, place a nop after the call so that the linker can - restore the TOC pointer if a TOC adjusting call stub is needed. */ -#ifdef __powerpc64__ -#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ - asm (SECTION_OP "\n" \ -" bl " #FUNC "\n" \ -" nop\n" \ -" .previous"); -#endif - -/* FP save and restore routines. */ -#undef SAVE_FP_PREFIX -#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_") -#undef SAVE_FP_SUFFIX -#define SAVE_FP_SUFFIX "" -#undef RESTORE_FP_PREFIX -#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_") -#undef RESTORE_FP_SUFFIX -#define RESTORE_FP_SUFFIX "" - -/* 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) \ - ((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) - -/* Static stack checking is supported by means of probes. */ -#define STACK_CHECK_STATIC_BUILTIN 1 - -/* The default value isn't sufficient in 64-bit mode. */ -#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024) - -#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) - -/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */ -#undef ADJUST_FIELD_ALIGN -#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ - ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \ - ? 128 \ - : (TARGET_64BIT \ - && TARGET_ALIGN_NATURAL == 0 \ - && TYPE_MODE (strip_array_types (TREE_TYPE (FIELD))) == DFmode) \ - ? MIN ((COMPUTED), 32) \ - : (COMPUTED)) - -#undef TOC_SECTION_ASM_OP -#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 \ - (TARGET_64BIT \ - ? "\t.section\t\".toc1\",\"aw\"" \ - : ((TARGET_RELOCATABLE || flag_pic) \ - ? "\t.section\t\".got2\",\"aw\"" \ - : "\t.section\t\".got1\",\"aw\"")) - -/* This is how to declare the size of a function. */ -#undef ASM_DECLARE_FUNCTION_SIZE -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do \ - { \ - if (!flag_inhibit_size_directive) \ - { \ - fputs ("\t.size\t", (FILE)); \ - if (TARGET_64BIT && DOT_SYMBOLS) \ - putc ('.', (FILE)); \ - assemble_name ((FILE), (FNAME)); \ - fputs (",.-", (FILE)); \ - rs6000_output_function_entry (FILE, FNAME); \ - putc ('\n', (FILE)); \ - } \ - } \ - while (0) - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \ - (TARGET_TOC \ - && (GET_CODE (X) == SYMBOL_REF \ - || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ - || GET_CODE (X) == LABEL_REF \ - || (GET_CODE (X) == CONST_INT \ - && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \ - || (GET_CODE (X) == CONST_DOUBLE \ - && ((TARGET_64BIT \ - && (TARGET_MINIMAL_TOC \ - || (SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ - && ! TARGET_NO_FP_IN_TOC))) \ - || (!TARGET_64BIT \ - && !TARGET_NO_FP_IN_TOC \ - && !TARGET_RELOCATABLE \ - && SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ - && BITS_PER_WORD == HOST_BITS_PER_INT))))) - -/* Use --as-needed -lgcc_s for eh support. */ -#ifdef HAVE_LD_AS_NEEDED -#define USE_LD_AS_NEEDED 1 -#endif - -#define POWERPC_FREEBSD diff --git a/gcc-4.8.1/gcc/config/rs6000/genopt.sh b/gcc-4.8.1/gcc/config/rs6000/genopt.sh deleted file mode 100755 index 0c227c626..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/genopt.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/sh -# Generate rs6000-tables.opt from the list of CPUs in rs6000-cpus.def. -# Copyright (C) 2011-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -cat <<EOF -; -*- buffer-read-only: t -*- -; Generated automatically by genopt.sh from rs6000-cpus.def. - -; Copyright (C) 2011-2013 Free Software Foundation, Inc. -; -; This file is part of GCC. -; -; GCC is free software; you can redistribute it and/or modify it under -; the terms of the GNU General Public License as published by the Free -; Software Foundation; either version 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -; WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -Enum -Name(rs6000_cpu_opt_value) Type(int) -Known CPUs (for use with the -mcpu= and -mtune= options): - -EnumValue -Enum(rs6000_cpu_opt_value) String(native) Value(RS6000_CPU_OPTION_NATIVE) DriverOnly - -EOF - -awk -F'[(, ]+' ' -BEGIN { - value = 0 -} - -/^RS6000_CPU/ { - name = $2 - gsub("\"", "", name) - print "EnumValue" - print "Enum(rs6000_cpu_opt_value) String(" name ") Value(" value ")" - print "" - value++ -}' $1/rs6000-cpus.def diff --git a/gcc-4.8.1/gcc/config/rs6000/host-darwin.c b/gcc-4.8.1/gcc/config/rs6000/host-darwin.c deleted file mode 100644 index 281cb0e1f..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/host-darwin.c +++ /dev/null @@ -1,153 +0,0 @@ -/* Darwin/powerpc host-specific hook definitions. - Copyright (C) 2003-2013 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include <sys/ucontext.h> -#include "hosthooks.h" -#include "hosthooks-def.h" -#include "diagnostic.h" -#include "config/host-darwin.h" - -static void segv_crash_handler (int); -static void segv_handler (int, siginfo_t *, void *); -static void darwin_rs6000_extra_signals (void); - -#ifndef HAVE_DECL_SIGALTSTACK -/* 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 *); -#endif - -/* The fields of the mcontext_t type have acquired underscores in later - OS versions. */ -#ifdef HAS_MCONTEXT_T_UNDERSCORES -#define MC_FLD(x) __ ## x -#else -#define MC_FLD(x) x -#endif - -#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; - sigset_t sigset; - 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); - sigemptyset (&sigset); - sigaddset (&sigset, SIGSEGV); - sigprocmask (SIG_UNBLOCK, &sigset, NULL); - - faulting_insn = *(unsigned *)uc->uc_mcontext->MC_FLD(ss).MC_FLD(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 & 0xFC1F03FF) == 0x7C01016E /* stwux xxx, %r1, xxx */ - || (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) - fancy_abort (__FILE__, __LINE__, __FUNCTION__); - - exit (FATAL_EXIT_CODE); - } - - fprintf (stderr, "[address=%08lx pc=%08x]\n", - uc->uc_mcontext->MC_FLD(es).MC_FLD(dar), - uc->uc_mcontext->MC_FLD(ss).MC_FLD(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 = (char*)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"); -} - - -const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc-4.8.1/gcc/config/rs6000/host-ppc64-darwin.c b/gcc-4.8.1/gcc/config/rs6000/host-ppc64-darwin.c deleted file mode 100644 index 7e9894524..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/host-ppc64-darwin.c +++ /dev/null @@ -1,30 +0,0 @@ -/* ppc64-darwin host-specific hook definitions. - Copyright (C) 2006-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "hosthooks.h" -#include "hosthooks-def.h" -#include "config/host-darwin.h" - -/* Darwin doesn't do anything special for ppc64 hosts; this file exists just - to include config/host-darwin.h. */ - -const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc-4.8.1/gcc/config/rs6000/linux.h b/gcc-4.8.1/gcc/config/rs6000/linux.h deleted file mode 100644 index 8ec3548c2..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/linux.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for PowerPC machines running Linux. - Copyright (C) 1996-2013 Free Software Foundation, Inc. - Contributed by Michael Meissner (meissner@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 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit - process. */ -#define OS_MISSING_POWERPC64 1 - -/* We use glibc _mcount for profiling. */ -#define NO_PROFILE_COUNTERS 1 - -#ifdef SINGLE_LIBC -#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) -#else -#define OPTION_GLIBC (linux_libc == LIBC_GLIBC) -#endif - -/* glibc has float and long double forms of math functions. */ -#undef TARGET_C99_FUNCTIONS -#define TARGET_C99_FUNCTIONS (OPTION_GLIBC) - -/* Whether we have sincos that follows the GNU extension. */ -#undef TARGET_HAS_SINCOS -#define TARGET_HAS_SINCOS (OPTION_GLIBC) - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - 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 -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)" - -/* 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 -#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" - -#undef LINK_SHLIB_SPEC -#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_linux)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_linux)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" - -#define LINK_GCC_C_SEQUENCE_SPEC \ - "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" - -/* Use --as-needed -lgcc_s for eh support. */ -#ifdef HAVE_LD_AS_NEEDED -#define USE_LD_AS_NEEDED 1 -#endif - -/* Override rs6000.h definition. */ -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -/* Override rs6000.h definition. */ -#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 -#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, except when - -mrelocatable or -mrelocatable-lib is given. */ -#undef RELOCATABLE_NEEDS_FIXUP -#define RELOCATABLE_NEEDS_FIXUP \ - (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) - -#define TARGET_POSIX_IO - -#ifdef TARGET_LIBC_PROVIDES_SSP -/* ppc32 glibc provides __stack_chk_guard in -0x7008(2). */ -#define TARGET_THREAD_SSP_OFFSET -0x7008 -#endif - -#define POWERPC_LINUX - -/* ppc linux has 128-bit long double support in glibc 2.4 and later. */ -#ifdef TARGET_DEFAULT_LONG_DOUBLE_128 -#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128 -#endif - -/* Static stack checking is supported by means of probes. */ -#define STACK_CHECK_STATIC_BUILTIN 1 diff --git a/gcc-4.8.1/gcc/config/rs6000/linux64.h b/gcc-4.8.1/gcc/config/rs6000/linux64.h deleted file mode 100644 index dc6f67fcc..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/linux64.h +++ /dev/null @@ -1,548 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for 64 bit PowerPC linux. - Copyright (C) 2000-2013 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef RS6000_BI_ARCH - -#undef DEFAULT_ABI -#define DEFAULT_ABI ABI_AIX - -#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 - -#ifdef HAVE_LD_NO_DOT_SYMS -/* New ABI uses a local sym for the function entry point. */ -extern int dot_symbols; -#undef DOT_SYMBOLS -#define DOT_SYMBOLS dot_symbols -#endif - -#define TARGET_PROFILE_KERNEL profile_kernel - -#define TARGET_USES_LINUX64_OPT 1 -#ifdef HAVE_LD_LARGE_TOC -#undef TARGET_CMODEL -#define TARGET_CMODEL rs6000_current_cmodel -#define SET_CMODEL(opt) rs6000_current_cmodel = opt -#else -#define SET_CMODEL(opt) do {} while (0) -#endif - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_POWER7 -#undef PROCESSOR_DEFAULT64 -#define PROCESSOR_DEFAULT64 PROCESSOR_POWER7 - -/* We don't need to generate entries in .fixup, except when - -mrelocatable or -mrelocatable-lib is given. */ -#undef RELOCATABLE_NEEDS_FIXUP -#define RELOCATABLE_NEEDS_FIXUP \ - (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) - -#undef RS6000_ABI_NAME -#define RS6000_ABI_NAME "linux" - -#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 (!global_options_set.x_rs6000_alignment_flags) \ - rs6000_alignment_flags = MASK_ALIGN_NATURAL; \ - if (TARGET_64BIT) \ - { \ - if (DEFAULT_ABI != ABI_AIX) \ - { \ - rs6000_current_abi = ABI_AIX; \ - error (INVALID_64BIT, "call"); \ - } \ - dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \ - if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \ - error (INVALID_64BIT, "relocatable"); \ - } \ - if (rs6000_isa_flags & OPTION_MASK_EABI) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_EABI; \ - error (INVALID_64BIT, "eabi"); \ - } \ - if (TARGET_PROTOTYPE) \ - { \ - target_prototype = 0; \ - error (INVALID_64BIT, "prototype"); \ - } \ - if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0) \ - { \ - rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ - error ("-m64 requires a PowerPC64 cpu"); \ - } \ - if ((rs6000_isa_flags_explicit \ - & OPTION_MASK_MINIMAL_TOC) != 0) \ - { \ - if (global_options_set.x_rs6000_current_cmodel \ - && rs6000_current_cmodel != CMODEL_SMALL) \ - error ("-mcmodel incompatible with other toc options"); \ - SET_CMODEL (CMODEL_SMALL); \ - } \ - else \ - { \ - if (!global_options_set.x_rs6000_current_cmodel) \ - SET_CMODEL (CMODEL_MEDIUM); \ - if (rs6000_current_cmodel != CMODEL_SMALL) \ - { \ - TARGET_NO_FP_IN_TOC = 0; \ - TARGET_NO_SUM_IN_TOC = 0; \ - } \ - } \ - } \ - else \ - { \ - if (!RS6000_BI_ARCH_P) \ - error (INVALID_32BIT, "32"); \ - if (TARGET_PROFILE_KERNEL) \ - { \ - TARGET_PROFILE_KERNEL = 0; \ - error (INVALID_32BIT, "profile-kernel"); \ - } \ - if (global_options_set.x_rs6000_current_cmodel) \ - { \ - SET_CMODEL (CMODEL_SMALL); \ - error (INVALID_32BIT, "cmodel"); \ - } \ - } \ - } \ - while (0) - -#undef ASM_DEFAULT_SPEC -#undef ASM_SPEC -#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 \ -%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \ -%{memb} %{!memb: %{msdata=eabi: -memb}} \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-freebsd: -mbig} \ - %{mcall-i960-old: -mlittle} \ - %{mcall-linux: -mbig} \ - %{mcall-netbsd: -mbig} \ -}}}}" - -#define ASM_SPEC64 "-a64" - -#define ASM_SPEC_COMMON "%(asm_cpu) \ -%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ -%{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 OPTION_LITTLE_ENDIAN -#define OPTION_LITTLE_ENDIAN 0 - -/* 64-bit PowerPC Linux always has a TOC. */ -#undef TARGET_TOC -#define TARGET_TOC 1 - -/* Some things from sysv4.h we don't do when 64 bit. */ -#undef OPTION_RELOCATABLE -#define OPTION_RELOCATABLE 0 -#undef OPTION_EABI -#define OPTION_EABI 0 -#undef OPTION_PROTOTYPE -#define OPTION_PROTOTYPE 0 -#undef RELOCATABLE_NEEDS_FIXUP -#define RELOCATABLE_NEEDS_FIXUP 0 - -#endif - -/* We use glibc _mcount for profiling. */ -#define NO_PROFILE_COUNTERS 1 -#define PROFILE_HOOK(LABEL) \ - do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0) - -/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */ -#undef ADJUST_FIELD_ALIGN -#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ - ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \ - ? 128 \ - : (TARGET_64BIT \ - && TARGET_ALIGN_NATURAL == 0 \ - && TYPE_MODE (strip_array_types (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_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))) - -/* Use the default for compiling target libs. */ -#ifdef IN_TARGET_LIBS -#undef TARGET_ALIGN_NATURAL -#define TARGET_ALIGN_NATURAL 1 -#endif - -/* Indicate that jump tables go in the text section. */ -#undef JUMP_TABLES_IN_TEXT_SECTION -#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. i.e. pad upward. - 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 - -/* 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)) - -/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit - process. */ -#define OS_MISSING_POWERPC64 !TARGET_64BIT - -#ifdef SINGLE_LIBC -#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) -#else -#define OPTION_GLIBC (linux_libc == LIBC_GLIBC) -#endif - -/* glibc has float and long double forms of math functions. */ -#undef TARGET_C99_FUNCTIONS -#define TARGET_C99_FUNCTIONS (OPTION_GLIBC) - -/* Whether we have sincos that follows the GNU extension. */ -#undef TARGET_HAS_SINCOS -#define TARGET_HAS_SINCOS (OPTION_GLIBC) - -#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__"); \ - if (!DOT_SYMBOLS) \ - builtin_define ("_CALL_LINUX"); \ - 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 -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)" - -/* 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 -#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" - -#undef LINK_SHLIB_SPEC -#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "%(lib_linux)" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)" - -#undef ENDFILE_DEFAULT_SPEC -#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "%(link_start_linux)" - -#undef LINK_OS_DEFAULT_SPEC -#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" - -#define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1" -#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld64.so.1" -#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0" -#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0" -#if DEFAULT_LIBC == LIBC_UCLIBC -#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}" -#elif DEFAULT_LIBC == LIBC_GLIBC -#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}" -#else -#error "Unsupported DEFAULT_LIBC" -#endif -#define GNU_USER_DYNAMIC_LINKER32 \ - CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32) -#define GNU_USER_DYNAMIC_LINKER64 \ - CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64) - - -#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux %{!shared: %{!static: \ - %{rdynamic:-export-dynamic} \ - -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}}" - -#define LINK_OS_LINUX_SPEC64 "-m elf64ppc %{!shared: %{!static: \ - %{rdynamic:-export-dynamic} \ - -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}}" - -#undef TOC_SECTION_ASM_OP -#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 \ - (TARGET_64BIT \ - ? "\t.section\t\".toc1\",\"aw\"" \ - : ((TARGET_RELOCATABLE || flag_pic) \ - ? "\t.section\t\".got2\",\"aw\"" \ - : "\t.section\t\".got1\",\"aw\"")) - -/* Must be at least as big as our pointer type. */ -#undef SIZE_TYPE -#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int") - -#undef PTRDIFF_TYPE -#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int") - -#undef WCHAR_TYPE -#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int") -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - -/* Override rs6000.h definition. */ -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -/* Override rs6000.h definition. */ -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -#undef RS6000_MCOUNT -#define RS6000_MCOUNT "_mcount" - -#ifdef __powerpc64__ -/* _init and _fini functions are built from bits spread across many - object files, each potentially with a different TOC pointer. For - that reason, place a nop after the call so that the linker can - restore the TOC pointer if a TOC adjusting call stub is needed. */ -#if DOT_SYMBOLS -#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ - asm (SECTION_OP "\n" \ -" bl ." #FUNC "\n" \ -" nop\n" \ -" .previous"); -#else -#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ - asm (SECTION_OP "\n" \ -" bl " #FUNC "\n" \ -" nop\n" \ -" .previous"); -#endif -#endif - -/* FP save and restore routines. */ -#undef SAVE_FP_PREFIX -#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_") -#undef SAVE_FP_SUFFIX -#define SAVE_FP_SUFFIX "" -#undef RESTORE_FP_PREFIX -#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_") -#undef RESTORE_FP_SUFFIX -#define RESTORE_FP_SUFFIX "" - -/* Dwarf2 debugging. */ -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG - -/* This is how to declare the size of a function. */ -#undef ASM_DECLARE_FUNCTION_SIZE -#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ - do \ - { \ - if (!flag_inhibit_size_directive) \ - { \ - fputs ("\t.size\t", (FILE)); \ - if (TARGET_64BIT && DOT_SYMBOLS) \ - putc ('.', (FILE)); \ - assemble_name ((FILE), (FNAME)); \ - fputs (",.-", (FILE)); \ - rs6000_output_function_entry (FILE, FNAME); \ - putc ('\n', (FILE)); \ - } \ - } \ - while (0) - -/* Return nonzero if this entry is to be written into the constant - pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF - or a CONST containing one of them. If -mfp-in-toc (the default), - we also do this for floating-point constants. We actually can only - do this if the FP formats of the target and host machines are the - same, but we can't check that since not every file that uses - the macros includes real.h. We also do this when we can write the - entry into the TOC and the entry is not larger than a TOC entry. */ - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \ - (TARGET_TOC \ - && (GET_CODE (X) == SYMBOL_REF \ - || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ - || GET_CODE (X) == LABEL_REF \ - || (GET_CODE (X) == CONST_INT \ - && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \ - || (GET_CODE (X) == CONST_DOUBLE \ - && ((TARGET_64BIT \ - && (TARGET_MINIMAL_TOC \ - || (SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ - && ! TARGET_NO_FP_IN_TOC))) \ - || (!TARGET_64BIT \ - && !TARGET_NO_FP_IN_TOC \ - && !TARGET_RELOCATABLE \ - && SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ - && BITS_PER_WORD == HOST_BITS_PER_INT))))) - -/* 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) \ - ((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_POSIX_IO - -#define LINK_GCC_C_SEQUENCE_SPEC \ - "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" - -/* Use --as-needed -lgcc_s for eh support. */ -#ifdef HAVE_LD_AS_NEEDED -#define USE_LD_AS_NEEDED 1 -#endif - -#ifdef TARGET_LIBC_PROVIDES_SSP -/* ppc32 glibc provides __stack_chk_guard in -0x7008(2), - ppc64 glibc provides it at -0x7010(13). */ -#define TARGET_THREAD_SSP_OFFSET (TARGET_64BIT ? -0x7010 : -0x7008) -#endif - -#define POWERPC_LINUX - -/* ppc{32,64} linux has 128-bit long double support in glibc 2.4 and later. */ -#ifdef TARGET_DEFAULT_LONG_DOUBLE_128 -#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128 -#endif - -/* Static stack checking is supported by means of probes. */ -#define STACK_CHECK_STATIC_BUILTIN 1 - -/* The default value isn't sufficient in 64-bit mode. */ -#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024) diff --git a/gcc-4.8.1/gcc/config/rs6000/linux64.opt b/gcc-4.8.1/gcc/config/rs6000/linux64.opt deleted file mode 100644 index c3b5b3e4b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/linux64.opt +++ /dev/null @@ -1,42 +0,0 @@ -; Options for 64-bit PowerPC Linux. -; -; Copyright (C) 2005-2013 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 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -; License for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -mprofile-kernel -Target Report Var(profile_kernel) Save -Call mcount for profiling before a function prologue - -mcmodel= -Target RejectNegative Joined Enum(rs6000_cmodel) Var(rs6000_current_cmodel) -Select code model - -Enum -Name(rs6000_cmodel) Type(enum rs6000_cmodel) -Known code models (for use with the -mcmodel= option): - -EnumValue -Enum(rs6000_cmodel) String(small) Value(CMODEL_SMALL) - -EnumValue -Enum(rs6000_cmodel) String(medium) Value(CMODEL_MEDIUM) - -EnumValue -Enum(rs6000_cmodel) String(large) Value(CMODEL_LARGE) - diff --git a/gcc-4.8.1/gcc/config/rs6000/linuxaltivec.h b/gcc-4.8.1/gcc/config/rs6000/linuxaltivec.h deleted file mode 100644 index 632f58d5b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/linuxaltivec.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for AltiVec enhanced PowerPC machines running GNU/Linux. - Copyright (C) 2001-2013 Free Software Foundation, Inc. - Contributed by Aldy Hernandez (aldyh@redhat.com). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Override rs6000.h and sysv4.h definition. */ -#undef TARGET_DEFAULT -#define TARGET_DEFAULT MASK_ALTIVEC - -#undef SUBSUBTARGET_OVERRIDE_OPTIONS -#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1 diff --git a/gcc-4.8.1/gcc/config/rs6000/linuxspe.h b/gcc-4.8.1/gcc/config/rs6000/linuxspe.h deleted file mode 100644 index 99b8c7371..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/linuxspe.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for PowerPC e500 machines running GNU/Linux. - Copyright (C) 2003-2013 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 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Override rs6000.h and sysv4.h definition. */ -#undef TARGET_DEFAULT -#define TARGET_DEFAULT MASK_STRICT_ALIGN - -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc -mspe -me500" diff --git a/gcc-4.8.1/gcc/config/rs6000/lynx.h b/gcc-4.8.1/gcc/config/rs6000/lynx.h deleted file mode 100644 index 249a1426b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/lynx.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Definitions for Rs6000 running LynxOS. - Copyright (C) 1995-2013 Free Software Foundation, Inc. - Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com) - Rewritten by Adam Nemet, LynuxWorks Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Undefine the definition to enable the LynxOS default from the - top-level lynx.h. */ - -#undef SUBTARGET_EXTRA_SPECS - -/* Get rid off the spec definitions from rs6000/sysv4.h. */ - -#undef CPP_SPEC -#define CPP_SPEC \ -"%{msoft-float: -D_SOFT_FLOAT} \ - %(cpp_cpu) \ - %(cpp_os_lynx)" - -/* LynxOS only supports big-endian on PPC so we override the - definition from sysv4.h. Since the LynxOS 4.0 compiler was set to - return every structure in memory regardless of their size we have - to emulate the same behavior here with disabling the SVR4 structure - returning. */ - -#undef CC1_SPEC -#define CC1_SPEC \ -"%{G*} %{mno-sdata:-msdata=none} \ - %{maltivec:-mabi=altivec} \ - -maix-struct-return" - -#undef ASM_SPEC -#define ASM_SPEC \ -"%(asm_cpu) \ - %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" - -#undef STARTFILE_SPEC -#undef ENDFILE_SPEC -#undef LIB_SPEC -#undef LINK_SPEC -#define LINK_SPEC \ -"%{!msdata=none:%{G*}} %{msdata=none:-G0} \ - %(link_os_lynx)" - -/* Override the definition from sysv4.h. */ - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("__BIG_ENDIAN__"); \ - builtin_define ("__powerpc__"); \ - builtin_assert ("cpu=powerpc"); \ - builtin_assert ("machine=powerpc"); \ - builtin_define ("__PPC__"); \ - } \ - while (0) - -/* Override the rs6000.h definition. */ - -#undef ASM_APP_ON -#define ASM_APP_ON "#APP\n" - -/* Override the rs6000.h definition. */ - -#undef ASM_APP_OFF -#define ASM_APP_OFF "#NO_APP\n" - -/* LynxOS does not do anything with .fixup plus let's not create - writable section for linkonce.r and linkonce.t. */ - -#undef RELOCATABLE_NEEDS_FIXUP - -/* Override these from rs6000.h with the generic definition. */ - -#undef SIZE_TYPE -#undef ASM_OUTPUT_ALIGN -#undef PREFERRED_DEBUGGING_TYPE - -/* The file rs6000.c defines TARGET_HAVE_TLS unconditionally to the - value of HAVE_AS_TLS. HAVE_AS_TLS is true as gas support for TLS - is detected by configure. Override the definition to false. */ - -#undef HAVE_AS_TLS -#define HAVE_AS_TLS 0 - -#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) - -#ifdef CRT_BEGIN -/* This function is part of crtbegin*.o which is at the beginning of - the link and is called from .fini which is usually toward the end - of the executable. Make it longcall so that we don't limit the - text size of the executables to 32M. */ - -static void __do_global_dtors_aux (void) __attribute__ ((longcall)); -#endif /* CRT_BEGIN */ - -#ifdef CRT_END -/* Similarly here. This function resides in crtend*.o which is toward - to end of the link and is called from .init which is at the - beginning. */ - -static void __do_global_ctors_aux (void) __attribute__ ((longcall)); -#endif /* CRT_END */ diff --git a/gcc-4.8.1/gcc/config/rs6000/milli.exp b/gcc-4.8.1/gcc/config/rs6000/milli.exp deleted file mode 100644 index ea3a2b757..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/milli.exp +++ /dev/null @@ -1,7 +0,0 @@ -#! -__mulh 0x3100 -__mull 0x3180 -__divss 0x3200 -__divus 0x3280 -__quoss 0x3300 -__quous 0x3380 diff --git a/gcc-4.8.1/gcc/config/rs6000/mpc.md b/gcc-4.8.1/gcc/config/rs6000/mpc.md deleted file mode 100644 index 381db5b3e..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/mpc.md +++ /dev/null @@ -1,111 +0,0 @@ -;; Scheduling description for Motorola PowerPC processor cores. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(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,\ - load_l,store_c,sync") - (eq_attr "cpu" "mpccore")) - "lsu_mpc") - -(define_insn_reservation "mpccore-store" 2 - (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,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "mpccore")) - "iu_mpc") - -(define_insn_reservation "mpccore-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "mpccore")) - "iu_mpc,iu_mpc") - -(define_insn_reservation "mpccore-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "mpccore")) - "iu_mpc,iu_mpc,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,\ - var_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,isync") - (eq_attr "cpu" "mpccore")) - "bpu_mpc") - diff --git a/gcc-4.8.1/gcc/config/rs6000/netbsd.h b/gcc-4.8.1/gcc/config/rs6000/netbsd.h deleted file mode 100644 index d811d273c..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/netbsd.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for PowerPC NetBSD systems. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Wasabi Systems, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_OS_CPP_BUILTINS /* FIXME: sysv4.h should not define this! */ -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - NETBSD_OS_CPP_BUILTINS_ELF(); \ - builtin_define ("__powerpc__"); \ - builtin_assert ("cpu=powerpc"); \ - builtin_assert ("machine=powerpc"); \ - } \ - while (0) - -/* Override the default from rs6000.h to avoid conflicts with macros - defined in NetBSD header files. */ - -#undef RS6000_CPU_CPP_ENDIAN_BUILTINS -#define RS6000_CPU_CPP_ENDIAN_BUILTINS() \ - do \ - { \ - if (BYTES_BIG_ENDIAN) \ - { \ - builtin_define ("__BIG_ENDIAN__"); \ - builtin_assert ("machine=bigendian"); \ - } \ - else \ - { \ - builtin_define ("__LITTLE_ENDIAN__"); \ - builtin_assert ("machine=littleendian"); \ - } \ - } \ - while (0) - -/* Make GCC agree with <machine/ansi.h>. */ - -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -#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 -#define CPP_SPEC NETBSD_CPP_SPEC - -#undef LINK_SPEC -#define LINK_SPEC \ - "%{!msdata=none:%{G*}} %{msdata=none:-G0} \ - %(netbsd_link_spec)" - -#define NETBSD_ENTRY_POINT "_start" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC NETBSD_STARTFILE_SPEC - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "%(netbsd_endfile_spec)" - -#undef LIB_SPEC -#define LIB_SPEC NETBSD_LIB_SPEC - -#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 }, - - -#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) diff --git a/gcc-4.8.1/gcc/config/rs6000/option-defaults.h b/gcc-4.8.1/gcc/config/rs6000/option-defaults.h deleted file mode 100644 index 2d7e36a61..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/option-defaults.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Definitions of default options for config/rs6000 configurations. - Copyright (C) 1992-2013 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* This header needs to be included after any other headers affecting - TARGET_DEFAULT. */ - -#if TARGET_AIX_OS -#define OPT_64 "maix64" -#define OPT_32 "maix32" -#else -#define OPT_64 "m64" -#define OPT_32 "m32" -#endif - -#ifndef OPTION_MASK_64BIT -#define OPTION_MASK_64BIT 0 -#define MASK_64BIT 0 -#endif - -#if TARGET_DEFAULT & OPTION_MASK_64BIT -#define OPT_ARCH64 "!"OPT_32 -#define OPT_ARCH32 OPT_32 -#else -#define OPT_ARCH64 OPT_64 -#define OPT_ARCH32 "!"OPT_64 -#endif - -/* Support for a compile-time default CPU, et cetera. The rules are: - --with-cpu is ignored if -mcpu is specified; likewise --with-cpu-32 - and --with-cpu-64. - --with-tune is ignored if -mtune or -mcpu is specified; likewise - --with-tune-32 and --with-tune-64. - --with-float is ignored if -mhard-float or -msoft-float are - specified. */ -#define OPTION_DEFAULT_SPECS \ - {"tune", "%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}" }, \ - {"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \ - {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \ - {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \ - {"cpu_32", "%{" OPT_ARCH32 ":%{!mcpu=*:-mcpu=%(VALUE)}}" }, \ - {"cpu_64", "%{" OPT_ARCH64 ":%{!mcpu=*:-mcpu=%(VALUE)}}" }, \ - {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" } diff --git a/gcc-4.8.1/gcc/config/rs6000/paired.h b/gcc-4.8.1/gcc/config/rs6000/paired.h deleted file mode 100644 index 0b92da6bd..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/paired.h +++ /dev/null @@ -1,75 +0,0 @@ -/* PowerPC 750CL user include file. - Copyright (C) 2007-2013 Free Software Foundation, Inc. - Contributed by Revital Eres (eres@il.ibm.com). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _PAIRED_H -#define _PAIRED_H - -#define vector __attribute__((vector_size(8))) - -#define paired_msub __builtin_paired_msub -#define paired_madd __builtin_paired_madd -#define paired_nmsub __builtin_paired_nmsub -#define paired_nmadd __builtin_paired_nmadd -#define paired_sum0 __builtin_paired_sum0 -#define paired_sum1 __builtin_paired_sum1 -#define paired_div __builtin_paired_divv2sf3 -#define paired_add __builtin_paired_addv2sf3 -#define paired_sub __builtin_paired_subv2sf3 -#define paired_mul __builtin_paired_mulv2sf3 -#define paired_muls0 __builtin_paired_muls0 -#define paired_muls1 __builtin_paired_muls1 -#define paired_madds0 __builtin_paired_madds0 -#define paired_madds1 __builtin_paired_madds1 -#define paired_merge00 __builtin_paired_merge00 -#define paired_merge01 __builtin_paired_merge01 -#define paired_merge10 __builtin_paired_merge10 -#define paired_merge11 __builtin_paired_merge11 -#define paired_abs __builtin_paired_absv2sf2 -#define paired_nabs __builtin_paired_nabsv2sf2 -#define paired_neg __builtin_paired_negv2sf2 -#define paired_sqrt __builtin_paired_sqrtv2sf2 -#define paired_res __builtin_paired_resv2sf2 -#define paired_stx __builtin_paired_stx -#define paired_lx __builtin_paired_lx -#define paired_cmpu0 __builtin_paired_cmpu0 -#define paired_cmpu1 __builtin_paired_cmpu1 -#define paired_sel __builtin_paired_selv2sf4 - -/* Condition register codes for Paired predicates. */ -#define LT 0 -#define GT 1 -#define EQ 2 -#define UN 3 - -#define paired_cmpu0_un(a,b) __builtin_paired_cmpu0 (UN, (a), (b)) -#define paired_cmpu0_eq(a,b) __builtin_paired_cmpu0 (EQ, (a), (b)) -#define paired_cmpu0_lt(a,b) __builtin_paired_cmpu0 (LT, (a), (b)) -#define paired_cmpu0_gt(a,b) __builtin_paired_cmpu0 (GT, (a), (b)) -#define paired_cmpu1_un(a,b) __builtin_paired_cmpu1 (UN, (a), (b)) -#define paired_cmpu1_eq(a,b) __builtin_paired_cmpu1 (EQ, (a), (b)) -#define paired_cmpu1_lt(a,b) __builtin_paired_cmpu1 (LT, (a), (b)) -#define paired_cmpu1_gt(a,b) __builtin_paired_cmpu1 (GT, (a), (b)) - -#endif /* _PAIRED_H */ diff --git a/gcc-4.8.1/gcc/config/rs6000/paired.md b/gcc-4.8.1/gcc/config/rs6000/paired.md deleted file mode 100644 index 24397b239..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/paired.md +++ /dev/null @@ -1,488 +0,0 @@ -;; PowerPC paired single and double hummer description -;; Copyright (C) 2007-2013 Free Software Foundation, Inc. -;; Contributed by David Edelsohn <edelsohn@gnu.org> and Revital Eres -;; <eres@il.ibm.com> - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_c_enum "unspec" - [UNSPEC_INTERHI_V2SF - UNSPEC_INTERLO_V2SF - UNSPEC_EXTEVEN_V2SF - UNSPEC_EXTODD_V2SF - ]) - -(define_insn "paired_negv2sf2" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_neg %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "sqrtv2sf2" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (sqrt:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_rsqrte %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "paired_absv2sf2" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_abs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "nabsv2sf2" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (neg:V2SF (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f"))))] - "TARGET_PAIRED_FLOAT" - "ps_nabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "paired_addv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_add %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "paired_subv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_sub %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "paired_mulv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_mul %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "resv2sf2" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] - "TARGET_PAIRED_FLOAT && flag_finite_math_only" - "ps_res %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "paired_divv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_div %0,%1,%2" - [(set_attr "type" "sdiv")]) - -(define_insn "paired_madds0" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_concat:V2SF - (fma:SF - (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") - (parallel [(const_int 0)]))) - (fma:SF - (vec_select:SF (match_dup 1) - (parallel [(const_int 1)])) - (vec_select:SF (match_dup 2) - (parallel [(const_int 0)])) - (vec_select:SF (match_dup 3) - (parallel [(const_int 1)])))))] - "TARGET_PAIRED_FLOAT" - "ps_madds0 %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "paired_madds1" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_concat:V2SF - (fma:SF - (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") - (parallel [(const_int 1)])) - (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") - (parallel [(const_int 0)]))) - (fma:SF - (vec_select:SF (match_dup 1) - (parallel [(const_int 1)])) - (vec_select:SF (match_dup 2) - (parallel [(const_int 1)])) - (vec_select:SF (match_dup 3) - (parallel [(const_int 1)])))))] - "TARGET_PAIRED_FLOAT" - "ps_madds1 %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "*paired_madd" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (fma:V2SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (match_operand:V2SF 3 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_madd %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "*paired_msub" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (fma:V2SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f"))))] - "TARGET_PAIRED_FLOAT" - "ps_msub %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "*paired_nmadd" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (neg:V2SF - (fma:V2SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (match_operand:V2SF 3 "gpc_reg_operand" "f"))))] - "TARGET_PAIRED_FLOAT" - "ps_nmadd %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "*paired_nmsub" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (neg:V2SF - (fma:V2SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f")))))] - "TARGET_PAIRED_FLOAT" - "ps_nmsub %0,%1,%2,%3" - [(set_attr "type" "dmul")]) - -(define_insn "selv2sf4" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_concat:V2SF - (if_then_else:SF (ge (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (match_operand:SF 4 "zero_fp_constant" "F")) - (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") - (parallel [(const_int 0)]))) - (if_then_else:SF (ge (vec_select:SF (match_dup 1) - (parallel [(const_int 1)])) - (match_dup 4)) - (vec_select:SF (match_dup 2) - (parallel [(const_int 1)])) - (vec_select:SF (match_dup 3) - (parallel [(const_int 1)])))))] - - "TARGET_PAIRED_FLOAT" - "ps_sel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "*movv2sf_paired" - [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,Y,r,r,f") - (match_operand:V2SF 1 "input_operand" "f,Z,f,r,Y,r,W"))] - "TARGET_PAIRED_FLOAT - && (register_operand (operands[0], V2SFmode) - || register_operand (operands[1], V2SFmode))" -{ - switch (which_alternative) - { - case 0: return "psq_stx %1,%y0,0,0"; - case 1: return "psq_lx %0,%y1,0,0"; - case 2: return "ps_mr %0,%1"; - case 3: return "#"; - case 4: return "#"; - case 5: return "#"; - case 6: return "#"; - default: gcc_unreachable (); - } -} - [(set_attr "type" "fpstore,fpload,fp,*,*,*,*")]) - -(define_insn "paired_stx" - [(set (match_operand:V2SF 0 "memory_operand" "=Z") - (match_operand:V2SF 1 "gpc_reg_operand" "f"))] - "TARGET_PAIRED_FLOAT" - "psq_stx %1,%y0,0,0" - [(set_attr "type" "fpstore")]) - -(define_insn "paired_lx" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (match_operand:V2SF 1 "memory_operand" "Z"))] - "TARGET_PAIRED_FLOAT" - "psq_lx %0,%y1,0,0" - [(set_attr "type" "fpload")]) - - -(define_split - [(set (match_operand:V2SF 0 "nonimmediate_operand" "") - (match_operand:V2SF 1 "input_operand" ""))] - "TARGET_PAIRED_FLOAT && reload_completed - && gpr_or_gpr_p (operands[0], operands[1])" - [(pc)] - { - rs6000_split_multireg_move (operands[0], operands[1]); DONE; - }) - -(define_insn "paired_cmpu0" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (vec_select:SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (vec_select:SF - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (parallel [(const_int 0)]))))] - "TARGET_PAIRED_FLOAT" - "ps_cmpu0 %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -(define_insn "paired_cmpu1" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (vec_select:SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 1)])) - (vec_select:SF - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (parallel [(const_int 1)]))))] - "TARGET_PAIRED_FLOAT" - "ps_cmpu1 %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -(define_insn "paired_merge00" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_select:V2SF - (vec_concat:V4SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")) - (parallel [(const_int 0) (const_int 2)])))] - "TARGET_PAIRED_FLOAT" - "ps_merge00 %0, %1, %2" - [(set_attr "type" "fp")]) - -(define_insn "paired_merge01" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_select:V2SF - (vec_concat:V4SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")) - (parallel [(const_int 0) (const_int 3)])))] - "TARGET_PAIRED_FLOAT" - "ps_merge01 %0, %1, %2" - [(set_attr "type" "fp")]) - -(define_insn "paired_merge10" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_select:V2SF - (vec_concat:V4SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")) - (parallel [(const_int 1) (const_int 2)])))] - "TARGET_PAIRED_FLOAT" - "ps_merge10 %0, %1, %2" - [(set_attr "type" "fp")]) - -(define_insn "paired_merge11" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_select:V2SF - (vec_concat:V4SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")) - (parallel [(const_int 1) (const_int 3)])))] - "TARGET_PAIRED_FLOAT" - "ps_merge11 %0, %1, %2" - [(set_attr "type" "fp")]) - -(define_expand "vec_perm_constv2sf" - [(match_operand:V2SF 0 "gpc_reg_operand" "") - (match_operand:V2SF 1 "gpc_reg_operand" "") - (match_operand:V2SF 2 "gpc_reg_operand" "") - (match_operand:V2SI 3 "" "")] - "TARGET_PAIRED_FLOAT" -{ - if (rs6000_expand_vec_perm_const (operands)) - DONE; - else - FAIL; -}) - -(define_insn "paired_sum0" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_concat:V2SF (plus:SF (vec_select:SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (vec_select:SF - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (parallel [(const_int 1)]))) - (vec_select:SF - (match_operand:V2SF 3 "gpc_reg_operand" "f") - (parallel [(const_int 1)]))))] - "TARGET_PAIRED_FLOAT" - "ps_sum0 %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "paired_sum1" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_concat:V2SF (vec_select:SF - (match_operand:V2SF 2 "gpc_reg_operand" "f") - (parallel [(const_int 1)])) - (plus:SF (vec_select:SF - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 0)])) - (vec_select:SF - (match_operand:V2SF 3 "gpc_reg_operand" "f") - (parallel [(const_int 1)])))))] - "TARGET_PAIRED_FLOAT" - "ps_sum1 %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "paired_muls0" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") - (vec_duplicate:V2SF - (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 0)])))))] - "TARGET_PAIRED_FLOAT" - "ps_muls0 %0, %1, %2" - [(set_attr "type" "fp")]) - - -(define_insn "paired_muls1" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") - (vec_duplicate:V2SF - (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (parallel [(const_int 1)])))))] - "TARGET_PAIRED_FLOAT" - "ps_muls1 %0, %1, %2" - [(set_attr "type" "fp")]) - -(define_expand "vec_initv2sf" - [(match_operand:V2SF 0 "gpc_reg_operand" "=f") - (match_operand 1 "" "")] - "TARGET_PAIRED_FLOAT" -{ - paired_expand_vector_init (operands[0], operands[1]); - DONE; -}) - -(define_insn "*vconcatsf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (vec_concat:V2SF - (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" - "ps_merge00 %0, %1, %2" - [(set_attr "type" "fp")]) - -(define_expand "sminv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (smin:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" -{ - rtx tmp = gen_reg_rtx (V2SFmode); - - emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2])); - emit_insn (gen_selv2sf4 (operands[0], tmp, operands[2], operands[1], CONST0_RTX (SFmode))); - DONE; -}) - -(define_expand "smaxv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (smax:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT" -{ - rtx tmp = gen_reg_rtx (V2SFmode); - - emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2])); - emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], operands[2], CONST0_RTX (SFmode))); - DONE; -}) - -(define_expand "reduc_smax_v2sf" - [(match_operand:V2SF 0 "gpc_reg_operand" "=f") - (match_operand:V2SF 1 "gpc_reg_operand" "f")] - "TARGET_PAIRED_FLOAT" -{ - rtx tmp_swap = gen_reg_rtx (V2SFmode); - rtx tmp = gen_reg_rtx (V2SFmode); - - emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); - emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); - emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], tmp_swap, CONST0_RTX (SFmode))); - - DONE; -}) - -(define_expand "reduc_smin_v2sf" - [(match_operand:V2SF 0 "gpc_reg_operand" "=f") - (match_operand:V2SF 1 "gpc_reg_operand" "f")] - "TARGET_PAIRED_FLOAT" -{ - rtx tmp_swap = gen_reg_rtx (V2SFmode); - rtx tmp = gen_reg_rtx (V2SFmode); - - emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); - emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); - emit_insn (gen_selv2sf4 (operands[0], tmp, tmp_swap, operands[1], CONST0_RTX (SFmode))); - - DONE; -}) - -(define_expand "reduc_splus_v2sf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (match_operand:V2SF 1 "gpc_reg_operand" "f"))] - "TARGET_PAIRED_FLOAT" - " -{ - emit_insn (gen_paired_sum1 (operands[0], operands[1], operands[1], operands[1])); - DONE; -}") - -(define_expand "movmisalignv2sf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (match_operand:V2SF 1 "gpc_reg_operand" "f"))] - "TARGET_PAIRED_FLOAT" -{ - paired_expand_vector_move (operands); - DONE; -}) - -(define_expand "vcondv2sfv2sf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") - (if_then_else:V2SF - (match_operator 3 "gpc_reg_operand" - [(match_operand:V2SF 4 "gpc_reg_operand" "f") - (match_operand:V2SF 5 "gpc_reg_operand" "f")]) - (match_operand:V2SF 1 "gpc_reg_operand" "f") - (match_operand:V2SF 2 "gpc_reg_operand" "f")))] - "TARGET_PAIRED_FLOAT && flag_unsafe_math_optimizations" -{ - if (paired_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; -}) diff --git a/gcc-4.8.1/gcc/config/rs6000/power4.md b/gcc-4.8.1/gcc/config/rs6000/power4.md deleted file mode 100644 index 468cc60cd..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/power4.md +++ /dev/null @@ -1,408 +0,0 @@ -;; Scheduling description for IBM Power4 and PowerPC 970 processors. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; 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,lsu2_power4)\ - |(du4_power4,lsu1_power4)") - -(define_reservation "lsuq_power4" - "((du1_power4+du2_power4,lsu1_power4)\ - |(du2_power4+du3_power4,lsu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4))\ - +(nothing,iu2_power4|nothing,iu1_power4)") - -(define_reservation "iq_power4" - "(du1_power4|du2_power4|du3_power4|du4_power4),\ - (iu1_power4|iu2_power4)") - -(define_reservation "fpq_power4" - "(du1_power4|du2_power4|du3_power4|du4_power4),\ - (fpu1_power4|fpu2_power4)") - -(define_reservation "vq_power4" - "(du1_power4,vec_power4)\ - |(du2_power4,vec_power4)\ - |(du3_power4,vec_power4)\ - |(du4_power4,vec_power4)") - -(define_reservation "vpq_power4" - "(du1_power4,vecperm_power4)\ - |(du2_power4,vecperm_power4)\ - |(du3_power4,vecperm_power4)\ - |(du4_power4,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\ - |du2_power4+du3_power4,lsu2_power4\ - |du3_power4+du4_power4,lsu2_power4),\ - nothing,nothing,\ - (iu2_power4|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" 12 - (and (eq_attr "type" "store") - (eq_attr "cpu" "power4")) - "((du1_power4,lsu1_power4)\ - |(du2_power4,lsu2_power4)\ - |(du3_power4,lsu2_power4)\ - |(du4_power4,lsu1_power4)),\ - (iu1_power4|iu2_power4)") - -(define_insn_reservation "power4-store-update" 12 - (and (eq_attr "type" "store_u") - (eq_attr "cpu" "power4")) - "((du1_power4+du2_power4,lsu1_power4)\ - |(du2_power4+du3_power4,lsu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4))+\ - ((nothing,iu1_power4,iu2_power4)\ - |(nothing,iu2_power4,iu2_power4)\ - |(nothing,iu2_power4,iu1_power4))") - -(define_insn_reservation "power4-store-update-indexed" 12 - (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" 12 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "power4")) - "((du1_power4,lsu1_power4)\ - |(du2_power4,lsu2_power4)\ - |(du3_power4,lsu2_power4)\ - |(du4_power4,lsu1_power4)),\ - (fpu1_power4|fpu2_power4)") - -(define_insn_reservation "power4-fpstore-update" 12 - (and (eq_attr "type" "fpstore_u,fpstore_ux") - (eq_attr "cpu" "power4")) - "((du1_power4+du2_power4,lsu1_power4)\ - |(du2_power4+du3_power4,lsu2_power4)\ - |(du3_power4+du4_power4,lsu2_power4))\ - +(nothing,(iu1_power4|iu2_power4),(fpu1_power4|fpu2_power4))") - -(define_insn_reservation "power4-vecstore" 12 - (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,vec_power4)\ - |(du4_power4,lsu1_power4,vec_power4)") - -(define_insn_reservation "power4-llsc" 11 - (and (eq_attr "type" "load_l,store_c,sync") - (eq_attr "cpu" "power4")) - "du1_power4+du2_power4+du3_power4+du4_power4,lsu1_power4") - - -; Integer latency is 2 cycles -(define_insn_reservation "power4-integer" 2 - (and (eq_attr "type" "integer,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "power4")) - "iq_power4") - -(define_insn_reservation "power4-two" 2 - (and (eq_attr "type" "two") - (eq_attr "cpu" "power4")) - "((du1_power4+du2_power4)\ - |(du2_power4+du3_power4)\ - |(du3_power4+du4_power4)\ - |(du4_power4+du1_power4)),\ - ((iu1_power4,nothing,iu2_power4)\ - |(iu2_power4,nothing,iu2_power4)\ - |(iu2_power4,nothing,iu1_power4)\ - |(iu1_power4,nothing,iu1_power4))") - -(define_insn_reservation "power4-three" 2 - (and (eq_attr "type" "three") - (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4+du3_power4|du2_power4+du3_power4+du4_power4\ - |du3_power4+du4_power4+du1_power4|du4_power4+du1_power4+du2_power4),\ - ((iu1_power4,nothing,iu2_power4,nothing,iu2_power4)\ - |(iu2_power4,nothing,iu2_power4,nothing,iu1_power4)\ - |(iu2_power4,nothing,iu1_power4,nothing,iu1_power4)\ - |(iu1_power4,nothing,iu1_power4,nothing,iu2_power4))") - -(define_insn_reservation "power4-insert" 4 - (and (eq_attr "type" "insert_word") - (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ - ((iu1_power4,nothing,iu2_power4)\ - |(iu2_power4,nothing,iu2_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,var_delayed_compare") - (eq_attr "cpu" "power4")) - "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ - ((iu1_power4,iu2_power4)\ - |(iu2_power4,iu2_power4)\ - |(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|du2_power4+du3_power4|du3_power4+du4_power4),\ - ((iu1_power4*6,iu2_power4)\ - |(iu2_power4*6,iu2_power4)\ - |(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|du2_power4+du3_power4|du3_power4+du4_power4),\ - ((iu1_power4*4,iu2_power4)\ - |(iu2_power4*4,iu2_power4)\ - |(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|du2_power4|du3_power4|du4_power4),\ - (iu1_power4*6|iu2_power4*6)") - -(define_insn_reservation "power4-imul" 5 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "power4")) - "(du1_power4|du2_power4|du3_power4|du4_power4),\ - (iu1_power4*4|iu2_power4*4)") - -(define_insn_reservation "power4-imul3" 4 - (and (eq_attr "type" "imul2,imul3") - (eq_attr "cpu" "power4")) - "(du1_power4|du2_power4|du3_power4|du4_power4),\ - (iu1_power4*3|iu2_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|du2_power4|du3_power4|du4_power4),\ - (fpu1_power4*28|fpu2_power4*28)") - -(define_insn_reservation "power4-sqrt" 40 - (and (eq_attr "type" "ssqrt,dsqrt") - (eq_attr "cpu" "power4")) - "(du1_power4|du2_power4|du3_power4|du4_power4),\ - (fpu1_power4*35|fpu2_power4*35)") - -(define_insn_reservation "power4-isync" 2 - (and (eq_attr "type" "isync") - (eq_attr "cpu" "power4")) - "du1_power4+du2_power4+du3_power4+du4_power4,lsu1_power4") - - -; 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/gcc-4.8.1/gcc/config/rs6000/power5.md b/gcc-4.8.1/gcc/config/rs6000/power5.md deleted file mode 100644 index 0cd9d1a2f..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/power5.md +++ /dev/null @@ -1,308 +0,0 @@ -;; Scheduling description for IBM POWER5 processor. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; 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,lsu2_power5)\ - |(du4_power5,lsu1_power5)") - -(define_reservation "iq_power5" - "(du1_power5|du2_power5|du3_power5|du4_power5),\ - (iu1_power5|iu2_power5)") - -(define_reservation "fpq_power5" - "(du1_power5|du2_power5|du3_power5|du4_power5),\ - (fpu1_power5|fpu2_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" 12 - (and (eq_attr "type" "store") - (eq_attr "cpu" "power5")) - "((du1_power5,lsu1_power5)\ - |(du2_power5,lsu2_power5)\ - |(du3_power5,lsu2_power5)\ - |(du4_power5,lsu1_power5)),\ - (iu1_power5|iu2_power5)") - -(define_insn_reservation "power5-store-update" 12 - (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" 12 - (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" 12 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "power5")) - "((du1_power5,lsu1_power5)\ - |(du2_power5,lsu2_power5)\ - |(du3_power5,lsu2_power5)\ - |(du4_power5,lsu1_power5)),\ - (fpu1_power5|fpu2_power5)") - -(define_insn_reservation "power5-fpstore-update" 12 - (and (eq_attr "type" "fpstore_u,fpstore_ux") - (eq_attr "cpu" "power5")) - "du1_power5+du2_power5,lsu1_power5+iu2_power5,fpu1_power5") - -(define_insn_reservation "power5-llsc" 11 - (and (eq_attr "type" "load_l,store_c,sync") - (eq_attr "cpu" "power5")) - "du1_power5+du2_power5+du3_power5+du4_power5,\ - lsu1_power5") - - -; Integer latency is 2 cycles -(define_insn_reservation "power5-integer" 2 - (and (eq_attr "type" "integer,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel,popcnt") - (eq_attr "cpu" "power5")) - "iq_power5") - -(define_insn_reservation "power5-two" 2 - (and (eq_attr "type" "two") - (eq_attr "cpu" "power5")) - "((du1_power5+du2_power5)\ - |(du2_power5+du3_power5)\ - |(du3_power5+du4_power5)\ - |(du4_power5+du1_power5)),\ - ((iu1_power5,nothing,iu2_power5)\ - |(iu2_power5,nothing,iu2_power5)\ - |(iu2_power5,nothing,iu1_power5)\ - |(iu1_power5,nothing,iu1_power5))") - -(define_insn_reservation "power5-three" 2 - (and (eq_attr "type" "three") - (eq_attr "cpu" "power5")) - "(du1_power5+du2_power5+du3_power5|du2_power5+du3_power5+du4_power5\ - |du3_power5+du4_power5+du1_power5|du4_power5+du1_power5+du2_power5),\ - ((iu1_power5,nothing,iu2_power5,nothing,iu2_power5)\ - |(iu2_power5,nothing,iu2_power5,nothing,iu1_power5)\ - |(iu2_power5,nothing,iu1_power5,nothing,iu1_power5)\ - |(iu1_power5,nothing,iu2_power5,nothing,iu2_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,var_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|du2_power5|du3_power5|du4_power5),(iu1_power5*6|iu2_power5*6)") - -(define_insn_reservation "power5-imul" 5 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "power5")) - "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*4|iu2_power5*4)") - -(define_insn_reservation "power5-imul3" 4 - (and (eq_attr "type" "imul2,imul3") - (eq_attr "cpu" "power5")) - "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*3|iu2_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|du2_power5|du3_power5|du4_power5),\ - (fpu1_power5*28|fpu2_power5*28)") - -(define_insn_reservation "power5-sqrt" 40 - (and (eq_attr "type" "ssqrt,dsqrt") - (eq_attr "cpu" "power5")) - "(du1_power5|du2_power5|du3_power5|du4_power5),\ - (fpu1_power5*35|fpu2_power5*35)") - -(define_insn_reservation "power5-isync" 2 - (and (eq_attr "type" "isync") - (eq_attr "cpu" "power5")) - "du1_power5+du2_power5+du3_power5+du4_power5,\ - lsu1_power5") - diff --git a/gcc-4.8.1/gcc/config/rs6000/power6.md b/gcc-4.8.1/gcc/config/rs6000/power6.md deleted file mode 100644 index ed33374cf..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/power6.md +++ /dev/null @@ -1,578 +0,0 @@ -;; Scheduling description for IBM POWER6 processor. -;; Copyright (C) 2006-2013 Free Software Foundation, Inc. -;; Contributed by Peter Steinmetz (steinmtz@us.ibm.com) -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; Sources: - -;; The POWER6 has 2 iu, 2 fpu, 2 lsu, and 1 bu/cru unit per engine -;; (2 engines per chip). The chip can issue up to 5 internal ops -;; per cycle. - -(define_automaton "power6iu,power6lsu,power6fpu,power6bu") - -(define_cpu_unit "iu1_power6,iu2_power6" "power6iu") -(define_cpu_unit "lsu1_power6,lsu2_power6" "power6lsu") -(define_cpu_unit "bpu_power6" "power6bu") -(define_cpu_unit "fpu1_power6,fpu2_power6" "power6fpu") - -(define_reservation "LS2_power6" - "lsu1_power6+lsu2_power6") - -(define_reservation "FPU_power6" - "fpu1_power6|fpu2_power6") - -(define_reservation "BRU_power6" - "bpu_power6") - -(define_reservation "LSU_power6" - "lsu1_power6|lsu2_power6") - -(define_reservation "LSF_power6" - "(lsu1_power6+fpu1_power6)\ - |(lsu1_power6+fpu2_power6)\ - |(lsu2_power6+fpu1_power6)\ - |(lsu2_power6+fpu2_power6)") - -(define_reservation "LX2_power6" - "(iu1_power6+iu2_power6+lsu1_power6)\ - |(iu1_power6+iu2_power6+lsu2_power6)") - -(define_reservation "FX2_power6" - "iu1_power6+iu2_power6") - -(define_reservation "X2F_power6" - "(iu1_power6+iu2_power6+fpu1_power6)\ - |(iu1_power6+iu2_power6+fpu2_power6)") - -(define_reservation "BX2_power6" - "iu1_power6+iu2_power6+bpu_power6") - -(define_reservation "LSX_power6" - "(iu1_power6+lsu1_power6)\ - |(iu1_power6+lsu2_power6)\ - |(iu2_power6+lsu1_power6)\ - |(iu2_power6+lsu2_power6)") - -(define_reservation "FXU_power6" - "iu1_power6|iu2_power6") - -(define_reservation "XLF_power6" - "(iu1_power6+lsu1_power6+fpu1_power6)\ - |(iu1_power6+lsu1_power6+fpu2_power6)\ - |(iu1_power6+lsu2_power6+fpu1_power6)\ - |(iu1_power6+lsu2_power6+fpu2_power6)\ - |(iu2_power6+lsu1_power6+fpu1_power6)\ - |(iu2_power6+lsu1_power6+fpu2_power6)\ - |(iu2_power6+lsu2_power6+fpu1_power6)\ - |(iu2_power6+lsu2_power6+fpu2_power6)") - -(define_reservation "BRX_power6" - "(bpu_power6+iu1_power6)\ - |(bpu_power6+iu2_power6)") - -; Load/store - -; The default for a value written by a fixed point load -; that is read/written by a subsequent fixed point op. -(define_insn_reservation "power6-load" 2 ; fx - (and (eq_attr "type" "load") - (eq_attr "cpu" "power6")) - "LSU_power6") - -; define the bypass for the case where the value written -; by a fixed point load is used as the source value on -; a store. -(define_bypass 1 "power6-load,\ - power6-load-update,\ - power6-load-update-indexed" - "power6-store,\ - power6-store-update,\ - power6-store-update-indexed,\ - power6-fpstore,\ - power6-fpstore-update" - "store_data_bypass_p") - -(define_insn_reservation "power6-load-ext" 4 ; fx - (and (eq_attr "type" "load_ext") - (eq_attr "cpu" "power6")) - "LSU_power6") - -; define the bypass for the case where the value written -; by a fixed point load ext is used as the source value on -; a store. -(define_bypass 1 "power6-load-ext,\ - power6-load-ext-update,\ - power6-load-ext-update-indexed" - "power6-store,\ - power6-store-update,\ - power6-store-update-indexed,\ - power6-fpstore,\ - power6-fpstore-update" - "store_data_bypass_p") - -(define_insn_reservation "power6-load-update" 2 ; fx - (and (eq_attr "type" "load_u") - (eq_attr "cpu" "power6")) - "LSX_power6") - -(define_insn_reservation "power6-load-update-indexed" 2 ; fx - (and (eq_attr "type" "load_ux") - (eq_attr "cpu" "power6")) - "LSX_power6") - -(define_insn_reservation "power6-load-ext-update" 4 ; fx - (and (eq_attr "type" "load_ext_u") - (eq_attr "cpu" "power6")) - "LSX_power6") - -(define_insn_reservation "power6-load-ext-update-indexed" 4 ; fx - (and (eq_attr "type" "load_ext_ux") - (eq_attr "cpu" "power6")) - "LSX_power6") - -(define_insn_reservation "power6-fpload" 1 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "power6")) - "LSU_power6") - -(define_insn_reservation "power6-fpload-update" 1 - (and (eq_attr "type" "fpload_u,fpload_ux") - (eq_attr "cpu" "power6")) - "LSX_power6") - -(define_insn_reservation "power6-store" 14 - (and (eq_attr "type" "store") - (eq_attr "cpu" "power6")) - "LSU_power6") - -(define_insn_reservation "power6-store-update" 14 - (and (eq_attr "type" "store_u") - (eq_attr "cpu" "power6")) - "LSX_power6") - -(define_insn_reservation "power6-store-update-indexed" 14 - (and (eq_attr "type" "store_ux") - (eq_attr "cpu" "power6")) - "LX2_power6") - -(define_insn_reservation "power6-fpstore" 14 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "power6")) - "LSF_power6") - -(define_insn_reservation "power6-fpstore-update" 14 - (and (eq_attr "type" "fpstore_u,fpstore_ux") - (eq_attr "cpu" "power6")) - "XLF_power6") - -(define_insn_reservation "power6-larx" 3 - (and (eq_attr "type" "load_l") - (eq_attr "cpu" "power6")) - "LS2_power6") - -(define_insn_reservation "power6-stcx" 10 ; best case - (and (eq_attr "type" "store_c") - (eq_attr "cpu" "power6")) - "LSX_power6") - -(define_insn_reservation "power6-sync" 11 ; N/A - (and (eq_attr "type" "sync") - (eq_attr "cpu" "power6")) - "LSU_power6") - -(define_insn_reservation "power6-integer" 1 - (and (eq_attr "type" "integer") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-isel" 1 - (and (eq_attr "type" "isel") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-exts" 1 - (and (eq_attr "type" "exts") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-shift" 1 - (and (eq_attr "type" "shift") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-popcnt" 1 - (and (eq_attr "type" "popcnt") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-insert" 1 - (and (eq_attr "type" "insert_word") - (eq_attr "cpu" "power6")) - "FX2_power6") - -(define_insn_reservation "power6-insert-dword" 1 - (and (eq_attr "type" "insert_dword") - (eq_attr "cpu" "power6")) - "FX2_power6") - -; define the bypass for the case where the value written -; by a fixed point op is used as the source value on a -; store. -(define_bypass 1 "power6-integer,\ - power6-exts,\ - power6-shift,\ - power6-insert,\ - power6-insert-dword" - "power6-store,\ - power6-store-update,\ - power6-store-update-indexed,\ - power6-fpstore,\ - power6-fpstore-update" - "store_data_bypass_p") - -(define_insn_reservation "power6-cntlz" 2 - (and (eq_attr "type" "cntlz") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_bypass 1 "power6-cntlz" - "power6-store,\ - power6-store-update,\ - power6-store-update-indexed,\ - power6-fpstore,\ - power6-fpstore-update" - "store_data_bypass_p") - -(define_insn_reservation "power6-var-rotate" 4 - (and (eq_attr "type" "var_shift_rotate") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-trap" 1 ; N/A - (and (eq_attr "type" "trap") - (eq_attr "cpu" "power6")) - "BRX_power6") - -(define_insn_reservation "power6-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "power6")) - "(iu1_power6,iu1_power6)\ - |(iu1_power6+iu2_power6,nothing)\ - |(iu1_power6,iu2_power6)\ - |(iu2_power6,iu1_power6)\ - |(iu2_power6,iu2_power6)") - -(define_insn_reservation "power6-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "power6")) - "(iu1_power6,iu1_power6,iu1_power6)\ - |(iu1_power6,iu1_power6,iu2_power6)\ - |(iu1_power6,iu2_power6,iu1_power6)\ - |(iu1_power6,iu2_power6,iu2_power6)\ - |(iu2_power6,iu1_power6,iu1_power6)\ - |(iu2_power6,iu1_power6,iu2_power6)\ - |(iu2_power6,iu2_power6,iu1_power6)\ - |(iu2_power6,iu2_power6,iu2_power6)\ - |(iu1_power6+iu2_power6,iu1_power6)\ - |(iu1_power6+iu2_power6,iu2_power6)\ - |(iu1_power6,iu1_power6+iu2_power6)\ - |(iu2_power6,iu1_power6+iu2_power6)") - -(define_insn_reservation "power6-cmp" 1 - (and (eq_attr "type" "cmp") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-compare" 1 - (and (eq_attr "type" "compare") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-fast-compare" 1 - (and (eq_attr "type" "fast_compare") - (eq_attr "cpu" "power6")) - "FXU_power6") - -; define the bypass for the case where the value written -; by a fixed point rec form op is used as the source value -; on a store. -(define_bypass 1 "power6-compare,\ - power6-fast-compare" - "power6-store,\ - power6-store-update,\ - power6-store-update-indexed,\ - power6-fpstore,\ - power6-fpstore-update" - "store_data_bypass_p") - -(define_insn_reservation "power6-delayed-compare" 2 ; N/A - (and (eq_attr "type" "delayed_compare") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-var-delayed-compare" 4 - (and (eq_attr "type" "var_delayed_compare") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-lmul-cmp" 16 - (and (eq_attr "type" "lmul_compare") - (eq_attr "cpu" "power6")) - "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ - |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); - -(define_insn_reservation "power6-imul-cmp" 16 - (and (eq_attr "type" "imul_compare") - (eq_attr "cpu" "power6")) - "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ - |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); - -(define_insn_reservation "power6-lmul" 16 - (and (eq_attr "type" "lmul") - (eq_attr "cpu" "power6")) - "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ - |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); - -(define_insn_reservation "power6-imul" 16 - (and (eq_attr "type" "imul") - (eq_attr "cpu" "power6")) - "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ - |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); - -(define_insn_reservation "power6-imul3" 16 - (and (eq_attr "type" "imul2,imul3") - (eq_attr "cpu" "power6")) - "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ - |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); - -(define_bypass 9 "power6-imul,\ - power6-lmul,\ - power6-imul-cmp,\ - power6-lmul-cmp,\ - power6-imul3" - "power6-store,\ - power6-store-update,\ - power6-store-update-indexed,\ - power6-fpstore,\ - power6-fpstore-update" - "store_data_bypass_p") - -(define_insn_reservation "power6-idiv" 44 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "power6")) - "(iu1_power6*44+iu2_power6*44+fpu1_power6*44)\ - |(iu1_power6*44+iu2_power6*44+fpu2_power6*44)"); - -; The latency for this bypass is yet to be defined -;(define_bypass ? "power6-idiv" -; "power6-store,\ -; power6-store-update,\ -; power6-store-update-indexed,\ -; power6-fpstore,\ -; power6-fpstore-update" -; "store_data_bypass_p") - -(define_insn_reservation "power6-ldiv" 56 - (and (eq_attr "type" "ldiv") - (eq_attr "cpu" "power6")) - "(iu1_power6*56+iu2_power6*56+fpu1_power6*56)\ - |(iu1_power6*56+iu2_power6*56+fpu2_power6*56)"); - -; The latency for this bypass is yet to be defined -;(define_bypass ? "power6-ldiv" -; "power6-store,\ -; power6-store-update,\ -; power6-store-update-indexed,\ -; power6-fpstore,\ -; power6-fpstore-update" -; "store_data_bypass_p") - -(define_insn_reservation "power6-mtjmpr" 2 - (and (eq_attr "type" "mtjmpr,mfjmpr") - (eq_attr "cpu" "power6")) - "BX2_power6") - -(define_bypass 5 "power6-mtjmpr" "power6-branch") - -(define_insn_reservation "power6-branch" 2 - (and (eq_attr "type" "jmpreg,branch") - (eq_attr "cpu" "power6")) - "BRU_power6") - -(define_bypass 5 "power6-branch" "power6-mtjmpr") - -(define_insn_reservation "power6-crlogical" 3 - (and (eq_attr "type" "cr_logical") - (eq_attr "cpu" "power6")) - "BRU_power6") - -(define_bypass 3 "power6-crlogical" "power6-branch") - -(define_insn_reservation "power6-delayedcr" 3 - (and (eq_attr "type" "delayed_cr") - (eq_attr "cpu" "power6")) - "BRU_power6") - -(define_insn_reservation "power6-mfcr" 6 ; N/A - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "power6")) - "BX2_power6") - -; mfcrf (1 field) -(define_insn_reservation "power6-mfcrf" 3 ; N/A - (and (eq_attr "type" "mfcrf") - (eq_attr "cpu" "power6")) - "BX2_power6") ; - -; mtcrf (1 field) -(define_insn_reservation "power6-mtcr" 4 ; N/A - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "power6")) - "BX2_power6") - -(define_bypass 9 "power6-mtcr" "power6-branch") - -(define_insn_reservation "power6-fp" 6 - (and (eq_attr "type" "fp,dmul") - (eq_attr "cpu" "power6")) - "FPU_power6") - -; Any fp instruction that updates a CR has a latency -; of 6 to a dependent branch -(define_bypass 6 "power6-fp" "power6-branch") - -(define_bypass 1 "power6-fp" - "power6-fpstore,power6-fpstore-update" - "store_data_bypass_p") - -(define_insn_reservation "power6-fpcompare" 8 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_bypass 12 "power6-fpcompare" - "power6-branch,power6-crlogical") - -(define_insn_reservation "power6-sdiv" 26 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_insn_reservation "power6-ddiv" 32 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_insn_reservation "power6-sqrt" 30 - (and (eq_attr "type" "ssqrt") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_insn_reservation "power6-dsqrt" 42 - (and (eq_attr "type" "dsqrt") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_insn_reservation "power6-isync" 2 ; N/A - (and (eq_attr "type" "isync") - (eq_attr "cpu" "power6")) - "FXU_power6") - -(define_insn_reservation "power6-vecload" 1 - (and (eq_attr "type" "vecload") - (eq_attr "cpu" "power6")) - "LSU_power6") - -(define_insn_reservation "power6-vecstore" 1 - (and (eq_attr "type" "vecstore") - (eq_attr "cpu" "power6")) - "LSF_power6") - -(define_insn_reservation "power6-vecsimple" 3 - (and (eq_attr "type" "vecsimple") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_bypass 6 "power6-vecsimple" "power6-veccomplex,\ - power6-vecperm") - -(define_bypass 5 "power6-vecsimple" "power6-vecfloat") - -(define_bypass 4 "power6-vecsimple" "power6-vecstore" ) - -(define_insn_reservation "power6-veccmp" 1 - (and (eq_attr "type" "veccmp") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_bypass 10 "power6-veccmp" "power6-branch") - -(define_insn_reservation "power6-vecfloat" 7 - (and (eq_attr "type" "vecfloat") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_bypass 10 "power6-vecfloat" "power6-vecsimple") - -(define_bypass 11 "power6-vecfloat" "power6-veccomplex,\ - power6-vecperm") - -(define_bypass 9 "power6-vecfloat" "power6-vecstore" ) - -(define_insn_reservation "power6-veccomplex" 7 - (and (eq_attr "type" "vecsimple") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_bypass 10 "power6-veccomplex" "power6-vecsimple,\ - power6-vecfloat" ) - -(define_bypass 9 "power6-veccomplex" "power6-vecperm" ) - -(define_bypass 8 "power6-veccomplex" "power6-vecstore" ) - -(define_insn_reservation "power6-vecperm" 4 - (and (eq_attr "type" "vecperm") - (eq_attr "cpu" "power6")) - "FPU_power6") - -(define_bypass 7 "power6-vecperm" "power6-vecsimple,\ - power6-vecfloat" ) - -(define_bypass 6 "power6-vecperm" "power6-veccomplex" ) - -(define_bypass 5 "power6-vecperm" "power6-vecstore" ) - -(define_insn_reservation "power6-mftgpr" 8 - (and (eq_attr "type" "mftgpr") - (eq_attr "cpu" "power6")) - "X2F_power6") - -(define_insn_reservation "power6-mffgpr" 14 - (and (eq_attr "type" "mffgpr") - (eq_attr "cpu" "power6")) - "LX2_power6") - -(define_bypass 4 "power6-mftgpr" "power6-imul,\ - power6-lmul,\ - power6-imul-cmp,\ - power6-lmul-cmp,\ - power6-imul3,\ - power6-idiv,\ - power6-ldiv" ) diff --git a/gcc-4.8.1/gcc/config/rs6000/power7.md b/gcc-4.8.1/gcc/config/rs6000/power7.md deleted file mode 100644 index 52db123a4..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/power7.md +++ /dev/null @@ -1,333 +0,0 @@ -;; Scheduling description for IBM POWER7 processor. -;; Copyright (C) 2009-2013 Free Software Foundation, Inc. -;; -;; Contributed by Pat Haugen (pthaugen@us.ibm.com). - -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_automaton "power7iu,power7lsu,power7vsu,power7misc") - -(define_cpu_unit "iu1_power7,iu2_power7" "power7iu") -(define_cpu_unit "lsu1_power7,lsu2_power7" "power7lsu") -(define_cpu_unit "vsu1_power7,vsu2_power7" "power7vsu") -(define_cpu_unit "bpu_power7,cru_power7" "power7misc") -(define_cpu_unit "du1_power7,du2_power7,du3_power7,du4_power7,du5_power7" - "power7misc") - - -(define_reservation "DU_power7" - "du1_power7|du2_power7|du3_power7|du4_power7") - -(define_reservation "DU2F_power7" - "du1_power7+du2_power7") - -(define_reservation "DU4_power7" - "du1_power7+du2_power7+du3_power7+du4_power7") - -(define_reservation "FXU_power7" - "iu1_power7|iu2_power7") - -(define_reservation "VSU_power7" - "vsu1_power7|vsu2_power7") - -(define_reservation "LSU_power7" - "lsu1_power7|lsu2_power7") - - -; Dispatch slots are allocated in order conforming to program order. -(absence_set "du1_power7" "du2_power7,du3_power7,du4_power7,du5_power7") -(absence_set "du2_power7" "du3_power7,du4_power7,du5_power7") -(absence_set "du3_power7" "du4_power7,du5_power7") -(absence_set "du4_power7" "du5_power7") - - -; LS Unit -(define_insn_reservation "power7-load" 2 - (and (eq_attr "type" "load") - (eq_attr "cpu" "power7")) - "DU_power7,LSU_power7") - -(define_insn_reservation "power7-load-ext" 3 - (and (eq_attr "type" "load_ext") - (eq_attr "cpu" "power7")) - "DU2F_power7,LSU_power7,FXU_power7") - -(define_insn_reservation "power7-load-update" 2 - (and (eq_attr "type" "load_u") - (eq_attr "cpu" "power7")) - "DU2F_power7,LSU_power7+FXU_power7") - -(define_insn_reservation "power7-load-update-indexed" 3 - (and (eq_attr "type" "load_ux") - (eq_attr "cpu" "power7")) - "DU4_power7,FXU_power7,LSU_power7+FXU_power7") - -(define_insn_reservation "power7-load-ext-update" 4 - (and (eq_attr "type" "load_ext_u") - (eq_attr "cpu" "power7")) - "DU2F_power7,LSU_power7+FXU_power7,FXU_power7") - -(define_insn_reservation "power7-load-ext-update-indexed" 4 - (and (eq_attr "type" "load_ext_ux") - (eq_attr "cpu" "power7")) - "DU4_power7,FXU_power7,LSU_power7+FXU_power7,FXU_power7") - -(define_insn_reservation "power7-fpload" 3 - (and (eq_attr "type" "fpload") - (eq_attr "cpu" "power7")) - "DU_power7,LSU_power7") - -(define_insn_reservation "power7-fpload-update" 3 - (and (eq_attr "type" "fpload_u,fpload_ux") - (eq_attr "cpu" "power7")) - "DU2F_power7,LSU_power7+FXU_power7") - -(define_insn_reservation "power7-store" 6 ; store-forwarding latency - (and (eq_attr "type" "store") - (eq_attr "cpu" "power7")) - "DU_power7,LSU_power7+FXU_power7") - -(define_insn_reservation "power7-store-update" 6 - (and (eq_attr "type" "store_u") - (eq_attr "cpu" "power7")) - "DU2F_power7,LSU_power7+FXU_power7,FXU_power7") - -(define_insn_reservation "power7-store-update-indexed" 6 - (and (eq_attr "type" "store_ux") - (eq_attr "cpu" "power7")) - "DU4_power7,LSU_power7+FXU_power7,FXU_power7") - -(define_insn_reservation "power7-fpstore" 6 - (and (eq_attr "type" "fpstore") - (eq_attr "cpu" "power7")) - "DU_power7,LSU_power7+VSU_power7") - -(define_insn_reservation "power7-fpstore-update" 6 - (and (eq_attr "type" "fpstore_u,fpstore_ux") - (eq_attr "cpu" "power7")) - "DU_power7,LSU_power7+VSU_power7+FXU_power7") - -(define_insn_reservation "power7-larx" 3 - (and (eq_attr "type" "load_l") - (eq_attr "cpu" "power7")) - "DU4_power7,LSU_power7") - -(define_insn_reservation "power7-stcx" 10 - (and (eq_attr "type" "store_c") - (eq_attr "cpu" "power7")) - "DU4_power7,LSU_power7") - -(define_insn_reservation "power7-vecload" 3 - (and (eq_attr "type" "vecload") - (eq_attr "cpu" "power7")) - "DU_power7,LSU_power7") - -(define_insn_reservation "power7-vecstore" 6 - (and (eq_attr "type" "vecstore") - (eq_attr "cpu" "power7")) - "DU_power7,LSU_power7+vsu2_power7") - -(define_insn_reservation "power7-sync" 11 - (and (eq_attr "type" "sync") - (eq_attr "cpu" "power7")) - "DU4_power7,LSU_power7") - - -; FX Unit -(define_insn_reservation "power7-integer" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,shift,trap,\ - var_shift_rotate,exts,isel,popcnt") - (eq_attr "cpu" "power7")) - "DU_power7,FXU_power7") - -(define_insn_reservation "power7-cntlz" 2 - (and (eq_attr "type" "cntlz") - (eq_attr "cpu" "power7")) - "DU_power7,FXU_power7") - -(define_insn_reservation "power7-two" 2 - (and (eq_attr "type" "two") - (eq_attr "cpu" "power7")) - "DU_power7+DU_power7,FXU_power7,FXU_power7") - -(define_insn_reservation "power7-three" 3 - (and (eq_attr "type" "three") - (eq_attr "cpu" "power7")) - "DU_power7+DU_power7+DU_power7,FXU_power7,FXU_power7,FXU_power7") - -(define_insn_reservation "power7-cmp" 1 - (and (eq_attr "type" "cmp,fast_compare") - (eq_attr "cpu" "power7")) - "DU_power7,FXU_power7") - -(define_insn_reservation "power7-compare" 2 - (and (eq_attr "type" "compare,delayed_compare,var_delayed_compare") - (eq_attr "cpu" "power7")) - "DU2F_power7,FXU_power7,FXU_power7") - -(define_bypass 3 "power7-cmp,power7-compare" "power7-crlogical,power7-delayedcr") - -(define_insn_reservation "power7-mul" 4 - (and (eq_attr "type" "imul,imul2,imul3,lmul") - (eq_attr "cpu" "power7")) - "DU_power7,FXU_power7") - -(define_insn_reservation "power7-mul-compare" 5 - (and (eq_attr "type" "imul_compare,lmul_compare") - (eq_attr "cpu" "power7")) - "DU2F_power7,FXU_power7,nothing*3,FXU_power7") - -(define_insn_reservation "power7-idiv" 36 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "power7")) - "DU2F_power7,iu1_power7*36|iu2_power7*36") - -(define_insn_reservation "power7-ldiv" 68 - (and (eq_attr "type" "ldiv") - (eq_attr "cpu" "power7")) - "DU2F_power7,iu1_power7*68|iu2_power7*68") - -(define_insn_reservation "power7-isync" 1 ; - (and (eq_attr "type" "isync") - (eq_attr "cpu" "power7")) - "DU4_power7,FXU_power7") - - -; CR Unit -(define_insn_reservation "power7-mtjmpr" 4 - (and (eq_attr "type" "mtjmpr") - (eq_attr "cpu" "power7")) - "du1_power7,FXU_power7") - -(define_insn_reservation "power7-mfjmpr" 5 - (and (eq_attr "type" "mfjmpr") - (eq_attr "cpu" "power7")) - "du1_power7,cru_power7+FXU_power7") - -(define_insn_reservation "power7-crlogical" 3 - (and (eq_attr "type" "cr_logical") - (eq_attr "cpu" "power7")) - "du1_power7,cru_power7") - -(define_insn_reservation "power7-delayedcr" 3 - (and (eq_attr "type" "delayed_cr") - (eq_attr "cpu" "power7")) - "du1_power7,cru_power7") - -(define_insn_reservation "power7-mfcr" 6 - (and (eq_attr "type" "mfcr") - (eq_attr "cpu" "power7")) - "du1_power7,cru_power7") - -(define_insn_reservation "power7-mfcrf" 3 - (and (eq_attr "type" "mfcrf") - (eq_attr "cpu" "power7")) - "du1_power7,cru_power7") - -(define_insn_reservation "power7-mtcr" 3 - (and (eq_attr "type" "mtcr") - (eq_attr "cpu" "power7")) - "DU4_power7,cru_power7+FXU_power7") - - -; BR Unit -; Branches take dispatch Slot 4. The presence_sets prevent other insn from -; grabbing previous dispatch slots once this is assigned. -(define_insn_reservation "power7-branch" 3 - (and (eq_attr "type" "jmpreg,branch") - (eq_attr "cpu" "power7")) - "(du5_power7\ - |du4_power7+du5_power7\ - |du3_power7+du4_power7+du5_power7\ - |du2_power7+du3_power7+du4_power7+du5_power7\ - |du1_power7+du2_power7+du3_power7+du4_power7+du5_power7),bpu_power7") - - -; VS Unit (includes FP/VSX/VMX/DFP) -(define_insn_reservation "power7-fp" 6 - (and (eq_attr "type" "fp,dmul") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_bypass 8 "power7-fp" "power7-branch") - -(define_insn_reservation "power7-fpcompare" 8 - (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_insn_reservation "power7-sdiv" 27 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_insn_reservation "power7-ddiv" 33 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_insn_reservation "power7-sqrt" 32 - (and (eq_attr "type" "ssqrt") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_insn_reservation "power7-dsqrt" 44 - (and (eq_attr "type" "dsqrt") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_insn_reservation "power7-vecsimple" 2 - (and (eq_attr "type" "vecsimple,veccmp") - (eq_attr "cpu" "power7")) - "DU_power7,vsu1_power7") - -(define_insn_reservation "power7-vecfloat" 6 - (and (eq_attr "type" "vecfloat") - (eq_attr "cpu" "power7")) - "DU_power7,vsu1_power7") - -(define_bypass 7 "power7-vecfloat" "power7-vecsimple,power7-veccomplex,\ - power7-vecperm") - -(define_insn_reservation "power7-veccomplex" 7 - (and (eq_attr "type" "veccomplex") - (eq_attr "cpu" "power7")) - "DU_power7,vsu1_power7") - -(define_insn_reservation "power7-vecperm" 3 - (and (eq_attr "type" "vecperm") - (eq_attr "cpu" "power7")) - "DU_power7,vsu2_power7") - -(define_insn_reservation "power7-vecdouble" 6 - (and (eq_attr "type" "vecdouble") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_bypass 7 "power7-vecdouble" "power7-vecsimple,power7-veccomplex,\ - power7-vecperm") - -(define_insn_reservation "power7-vecfdiv" 26 - (and (eq_attr "type" "vecfdiv") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - -(define_insn_reservation "power7-vecdiv" 32 - (and (eq_attr "type" "vecdiv") - (eq_attr "cpu" "power7")) - "DU_power7,VSU_power7") - diff --git a/gcc-4.8.1/gcc/config/rs6000/ppc-asm.h b/gcc-4.8.1/gcc/config/rs6000/ppc-asm.h deleted file mode 100644 index db490b6c9..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/ppc-asm.h +++ /dev/null @@ -1,358 +0,0 @@ -/* PowerPC asm definitions for GNU C. - -Copyright (C) 2002-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -/* Under winnt, 1) gas supports the following as names and 2) in particular - defining "toc" breaks the FUNC_START macro as ".toc" becomes ".2" */ - -#define r0 0 -#define sp 1 -#define toc 2 -#define r3 3 -#define r4 4 -#define r5 5 -#define r6 6 -#define r7 7 -#define r8 8 -#define r9 9 -#define r10 10 -#define r11 11 -#define r12 12 -#define r13 13 -#define r14 14 -#define r15 15 -#define r16 16 -#define r17 17 -#define r18 18 -#define r19 19 -#define r20 20 -#define r21 21 -#define r22 22 -#define r23 23 -#define r24 24 -#define r25 25 -#define r26 26 -#define r27 27 -#define r28 28 -#define r29 29 -#define r30 30 -#define r31 31 - -#define cr0 0 -#define cr1 1 -#define cr2 2 -#define cr3 3 -#define cr4 4 -#define cr5 5 -#define cr6 6 -#define cr7 7 - -#define f0 0 -#define f1 1 -#define f2 2 -#define f3 3 -#define f4 4 -#define f5 5 -#define f6 6 -#define f7 7 -#define f8 8 -#define f9 9 -#define f10 10 -#define f11 11 -#define f12 12 -#define f13 13 -#define f14 14 -#define f15 15 -#define f16 16 -#define f17 17 -#define f18 18 -#define f19 19 -#define f20 20 -#define f21 21 -#define f22 22 -#define f23 23 -#define f24 24 -#define f25 25 -#define f26 26 -#define f27 27 -#define f28 28 -#define f29 29 -#define f30 30 -#define f31 31 - -#ifdef __VSX__ -#define f32 32 -#define f33 33 -#define f34 34 -#define f35 35 -#define f36 36 -#define f37 37 -#define f38 38 -#define f39 39 -#define f40 40 -#define f41 41 -#define f42 42 -#define f43 43 -#define f44 44 -#define f45 45 -#define f46 46 -#define f47 47 -#define f48 48 -#define f49 49 -#define f50 30 -#define f51 51 -#define f52 52 -#define f53 53 -#define f54 54 -#define f55 55 -#define f56 56 -#define f57 57 -#define f58 58 -#define f59 59 -#define f60 60 -#define f61 61 -#define f62 62 -#define f63 63 -#endif - -#ifdef __ALTIVEC__ -#define v0 0 -#define v1 1 -#define v2 2 -#define v3 3 -#define v4 4 -#define v5 5 -#define v6 6 -#define v7 7 -#define v8 8 -#define v9 9 -#define v10 10 -#define v11 11 -#define v12 12 -#define v13 13 -#define v14 14 -#define v15 15 -#define v16 16 -#define v17 17 -#define v18 18 -#define v19 19 -#define v20 20 -#define v21 21 -#define v22 22 -#define v23 23 -#define v24 24 -#define v25 25 -#define v26 26 -#define v27 27 -#define v28 28 -#define v29 29 -#define v30 30 -#define v31 31 -#endif - -#ifdef __VSX__ -#define vs0 0 -#define vs1 1 -#define vs2 2 -#define vs3 3 -#define vs4 4 -#define vs5 5 -#define vs6 6 -#define vs7 7 -#define vs8 8 -#define vs9 9 -#define vs10 10 -#define vs11 11 -#define vs12 12 -#define vs13 13 -#define vs14 14 -#define vs15 15 -#define vs16 16 -#define vs17 17 -#define vs18 18 -#define vs19 19 -#define vs20 20 -#define vs21 21 -#define vs22 22 -#define vs23 23 -#define vs24 24 -#define vs25 25 -#define vs26 26 -#define vs27 27 -#define vs28 28 -#define vs29 29 -#define vs30 30 -#define vs31 31 -#define vs32 32 -#define vs33 33 -#define vs34 34 -#define vs35 35 -#define vs36 36 -#define vs37 37 -#define vs38 38 -#define vs39 39 -#define vs40 40 -#define vs41 41 -#define vs42 42 -#define vs43 43 -#define vs44 44 -#define vs45 45 -#define vs46 46 -#define vs47 47 -#define vs48 48 -#define vs49 49 -#define vs50 30 -#define vs51 51 -#define vs52 52 -#define vs53 53 -#define vs54 54 -#define vs55 55 -#define vs56 56 -#define vs57 57 -#define vs58 58 -#define vs59 59 -#define vs60 60 -#define vs61 61 -#define vs62 62 -#define vs63 63 -#endif - -/* - * Macros to glue together two tokens. - */ - -#ifdef __STDC__ -#define XGLUE(a,b) a##b -#else -#define XGLUE(a,b) a/**/b -#endif - -#define GLUE(a,b) XGLUE(a,b) - -/* - * Macros to begin and end a function written in assembler. If -mcall-aixdesc - * or -mcall-nt, create a function descriptor with the given name, and create - * the real function with one or two leading periods respectively. - */ - -#if defined (__powerpc64__) -#define FUNC_NAME(name) GLUE(.,name) -#define JUMP_TARGET(name) FUNC_NAME(name) -#define FUNC_START(name) \ - .section ".opd","aw"; \ -name: \ - .quad GLUE(.,name); \ - .quad .TOC.@tocbase; \ - .quad 0; \ - .previous; \ - .type GLUE(.,name),@function; \ - .globl name; \ - .globl GLUE(.,name); \ -GLUE(.,name): - -#define HIDDEN_FUNC(name) \ - FUNC_START(name) \ - .hidden name; \ - .hidden GLUE(.,name); - -#define FUNC_END(name) \ -GLUE(.L,name): \ - .size GLUE(.,name),GLUE(.L,name)-GLUE(.,name) - -#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 DESC_SECTION,"aw"; \ -name: \ - .long GLUE(.,name); \ - .long _GLOBAL_OFFSET_TABLE_; \ - .long 0; \ - .previous; \ - .type GLUE(.,name),@function; \ - .globl name; \ - .globl GLUE(.,name); \ -GLUE(.,name): - -#define HIDDEN_FUNC(name) \ - FUNC_START(name) \ - .hidden name; \ - .hidden GLUE(.,name); - -#define FUNC_END(name) \ -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) -#else -#define JUMP_TARGET(name) FUNC_NAME(name) -#endif -#define FUNC_START(name) \ - .type FUNC_NAME(name),@function; \ - .globl FUNC_NAME(name); \ -FUNC_NAME(name): - -#define HIDDEN_FUNC(name) \ - FUNC_START(name) \ - .hidden FUNC_NAME(name); - -#define FUNC_END(name) \ -GLUE(.L,name): \ - .size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name) -#endif - -#ifdef IN_GCC -/* For HAVE_GAS_CFI_DIRECTIVE. */ -#include "auto-host.h" - -#ifdef HAVE_GAS_CFI_DIRECTIVE -# define CFI_STARTPROC .cfi_startproc -# define CFI_ENDPROC .cfi_endproc -# define CFI_OFFSET(reg, off) .cfi_offset reg, off -# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg -# define CFI_RESTORE(reg) .cfi_restore reg -#else -# define CFI_STARTPROC -# define CFI_ENDPROC -# define CFI_OFFSET(reg, off) -# define CFI_DEF_CFA_REGISTER(reg) -# define CFI_RESTORE(reg) -#endif -#endif - -#if defined __linux__ && !defined __powerpc64__ - .section .note.GNU-stack - .previous -#endif diff --git a/gcc-4.8.1/gcc/config/rs6000/ppu_intrinsics.h b/gcc-4.8.1/gcc/config/rs6000/ppu_intrinsics.h deleted file mode 100644 index ca502a944..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/ppu_intrinsics.h +++ /dev/null @@ -1,727 +0,0 @@ -/* PPU intrinsics as defined by the C/C++ Language extension for Cell BEA. - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* TODO: - misc ops (traps) - supervisor/hypervisor mode ops. */ - -#ifndef _PPU_INTRINSICS_H -#define _PPU_INTRINSICS_H - -#if !defined(__PPU__) && !defined(__ppc__) && !defined(__ppc64__) \ - && !defined(__GNUC__) - #error ppu_intrinsics.h included on wrong platform/compiler -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * unsigned int __cntlzw(unsigned int) - * unsigned int __cntlzd(unsigned long long) - * int __mulhw(int, int) - * unsigned int __mulhwu(unsigned int, unsigned int) - * long long __mulhd(long long, long long) - * unsigned long long __mulhdu(unsigned long long, unsigned long long) - * - * void __sync(void) - * void __isync(void) - * void __lwsync(void) - * void __eieio(void) - * - * void __nop(void) - * void __cctpl(void) - * void __cctpm(void) - * void __cctph(void) - * void __db8cyc(void) - * void __db10cyc(void) - * void __db12cyc(void) - * void __db16cyc(void) - * - * void __mtspr(unsigned int spr, unsigned long long value) - * unsigned long long __mfspr(unsigned int spr) - * unsigned long long __mftb(void) - * - * void __icbi(void *base) - * void __dcbi(void *base) - * - * void __dcbf(void *base) - * void __dcbz(void *base) - * void __dcbst(void *base) - * void __dcbtst(void *base) - * void __dcbt(void *base) - * void __dcbt_TH1000(void *EATRUNC, bool D, bool UG, int ID) - * void __dcbt_TH1010(bool GO, int S, int UNITCNT, bool T, bool U, int ID) - * - * unsigned __lwarx(void *base) - * unsigned long long __ldarx(void *base) - * bool __stwcx(void *base, unsigned value) - * bool __stdcx(void *base, unsigned long long value) - * - * unsigned short __lhbrx(void *base) - * unsigned int __lwbrx(void *base) - * unsigned long long __ldbrx(void *base) - * void __sthbrx(void *base, unsigned short value) - * void __stwbrx(void *base, unsigned int value) - * void __stdbrx(void *base, unsigned long long value) - * - * double __fabs(double x) - * float __fabsf(float x) - * double __fnabs(double x) - * float __fnabsf(float x) - * double __fmadd(double x, double y, double z) - * double __fmsub(double x, double y, double z) - * double __fnmadd(double x, double y, double z) - * double __fnmsub(double x, double y, double z) - * float __fmadds(float x, float y, float z) - * float __fmsubs(float x, float y, float z) - * float __fnmadds(float x, float y, float z) - * float __fnmsubs(float x, float y, float z) - * double __fsel(double x, double y, double z) - * float __fsels(float x, float y, float z) - * double __frsqrte(double x) - * float __fres(float x) - * double __fsqrt(double x) - * float __fsqrts(float x) - * long long __fctid(double x) - * long long __fctiw(double x) - * double __fcfid(long long x) - * double __mffs(void) - * void __mtfsf(int mask, double value) - * void __mtfsfi(int bits, int field) - * void __mtfsb0(int) - * void __mtfsb1(int) - * double __setflm(double) - * - * dcbt intrinsics - * void __protected_unlimited_stream_set (unsigned int direction, const void *add, unsigned int ID) - * void __protected_stream_set (unsigned int direction, const void *add, unsigned int ID) - * void __protected_stream_stop_all (void) - * void __protected_stream_stop (unsigned int ID) - * void __protected_stream_count (unsigned int unit_cnt, unsigned int ID) - * void __protected_stream_go (void) - */ - -typedef int __V4SI __attribute__((vector_size(16))); - -#define __cntlzw(v) __builtin_clz(v) -#define __cntlzd(v) __builtin_clzll(v) - -#define __mulhw(a,b) __extension__ \ - ({int result; \ - __asm__ ("mulhw %0,%1,%2" \ - : "=r" (result) \ - : "r" ((int) (a)), \ - "r" ((int) (b))); \ - result; }) - -#define __mulhwu(a,b) __extension__ \ - ({unsigned int result; \ - __asm__ ("mulhwu %0,%1,%2" \ - : "=r" (result) \ - : "r" ((unsigned int) (a)), \ - "r" ((unsigned int) (b))); \ - result; }) - -#ifdef __powerpc64__ -#define __mulhd(a,b) __extension__ \ - ({ long long result; \ - __asm__ ("mulhd %0,%1,%2" \ - : "=r" (result) \ - : "r" ((long long) (a)), \ - "r" ((long long) (b))); \ - result; }) - -#define __mulhdu(a,b) __extension__ \ - ({unsigned long long result; \ - __asm__ ("mulhdu %0,%1,%2" \ - : "=r" (result) \ - : "r" ((unsigned long long) (a)), \ - "r" ((unsigned long long) (b))); \ - result; }) -#endif /* __powerpc64__ */ - -#define __sync() __asm__ volatile ("sync" : : : "memory") -#define __isync() __asm__ volatile ("isync" : : : "memory") -#define __lwsync() __asm__ volatile ("lwsync" : : : "memory") -#define __eieio() __asm__ volatile ("eieio" : : : "memory") - -#define __nop() __asm__ volatile ("ori 0,0,0" : : : "memory") -#define __cctpl() __asm__ volatile ("or 1,1,1" : : : "memory") -#define __cctpm() __asm__ volatile ("or 2,2,2" : : : "memory") -#define __cctph() __asm__ volatile ("or 3,3,3" : : : "memory") -#define __db8cyc() __asm__ volatile ("or 28,28,28" : : : "memory") -#define __db10cyc() __asm__ volatile ("or 29,29,29" : : : "memory") -#define __db12cyc() __asm__ volatile ("or 30,30,30" : : : "memory") -#define __db16cyc() __asm__ volatile ("or 31,31,31" : : : "memory") - -#ifdef __powerpc64__ -#define __mtspr(spr, value) \ - __asm__ volatile ("mtspr %0,%1" : : "n" (spr), "r" (value)) - -#define __mfspr(spr) __extension__ \ - ({ unsigned long long result; \ - __asm__ volatile ("mfspr %0,%1" : "=r" (result) : "n" (spr)); \ - result; }) -#endif /* __powerpc64__ */ - -#ifdef __powerpc64__ -/* Work around the hardware bug in the current Cell implementation. */ -#define __mftb() __extension__ \ - ({ unsigned long long result; \ - __asm__ volatile ("1: mftb %[current_tb]\n" \ - "\tcmpwi 7, %[current_tb], 0\n" \ - "\tbeq- 7, 1b" \ - : [current_tb] "=r" (result): \ - :"cr7"); \ - result; }) -#else -#define __mftb() __extension__ \ - ({ unsigned long long result; \ - unsigned long t; \ - __asm__ volatile ("1:\n" \ - "\tmftbu %0\n" \ - "\tmftb %L0\n" \ - "\tmftbu %1\n" \ - "\tcmpw %0,%1\n" \ - "\tbne 1b" \ - : "=r" (result), "=r" (t)); \ - result; }) -#endif /* __powerpc64__ */ - -#define __dcbf(base) \ - __asm__ volatile ("dcbf %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") - -#define __dcbz(base) \ - __asm__ volatile ("dcbz %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") - -#define __dcbst(base) \ - __asm__ volatile ("dcbst %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") - -#define __dcbtst(base) \ - __asm__ volatile ("dcbtst %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") - -#define __dcbt(base) \ - __asm__ volatile ("dcbt %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") - -#define __icbi(base) \ - __asm__ volatile ("icbi %y0" : "=Z" (*(__V4SI*) (base)) : : "memory") - -#define __dcbt_TH1000(EATRUNC, D, UG, ID) \ - __asm__ volatile ("dcbt %y0,8" \ - : "=Z" (*(__V4SI*) (__SIZE_TYPE__)((((__SIZE_TYPE__) (EATRUNC)) & ~0x7F) \ - | ((((D) & 1) << 6) \ - | (((UG) & 1) << 5) \ - | ((ID) & 0xF)))) : : "memory") - -#define __dcbt_TH1010(GO, S, UNITCNT, T, U, ID) \ - __asm__ volatile ("dcbt %y0,10" \ - : "=Z" (*(__V4SI*) (__SIZE_TYPE__)((((__SIZE_TYPE__) (GO) & 1) << 31) \ - | (((S) & 0x3) << 29) \ - | (((UNITCNT) & 0x3FF) << 7) \ - | (((T) & 1) << 6) \ - | (((U) & 1) << 5) \ - | ((ID) & 0xF))) : : "memory") - -#define __protected_unlimited_stream_set(DIRECTION, ADDR, ID) \ - __dcbt_TH1000 ((ADDR), (DIRECTION)>>1, 1, (ID)) - -#define __protected_stream_set(DIRECTION, ADDR, ID) \ - __dcbt_TH1000 ((ADDR), (DIRECTION)>>1, 0, (ID)) - -#define __protected_stream_stop_all() \ - __dcbt_TH1010 (0, 3, 0, 0, 0, 0) - -#define __protected_stream_stop(ID) \ - __dcbt_TH1010 (0, 2, 0, 0, 0, (ID)) - -#define __protected_stream_count(COUNT, ID) \ - __dcbt_TH1010 (0, 0, (COUNT), 0, 0, (ID)) - -#define __protected_stream_go() \ - __dcbt_TH1010 (1, 0, 0, 0, 0, 0) - -#define __lhbrx(base) __extension__ \ - ({unsigned short result; \ - typedef struct {char a[2];} halfwordsize; \ - halfwordsize *ptrp = (halfwordsize*)(void*)(base); \ - __asm__ ("lhbrx %0,%y1" \ - : "=r" (result) \ - : "Z" (*ptrp)); \ - result; }) - -#define __lwbrx(base) __extension__ \ - ({unsigned int result; \ - typedef struct {char a[4];} wordsize; \ - wordsize *ptrp = (wordsize*)(void*)(base); \ - __asm__ ("lwbrx %0,%y1" \ - : "=r" (result) \ - : "Z" (*ptrp)); \ - result; }) - - -#ifdef __powerpc64__ -#define __ldbrx(base) __extension__ \ - ({unsigned long long result; \ - typedef struct {char a[8];} doublewordsize; \ - doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ - __asm__ ("ldbrx %0,%y1" \ - : "=r" (result) \ - : "Z" (*ptrp)); \ - result; }) -#else -#define __ldbrx(base) __extension__ \ - ({unsigned long long result; \ - typedef struct {char a[8];} doublewordsize; \ - doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ - __asm__ ("lwbrx %L0,%y1\n" \ - "\tlwbrx %0,%y2" \ - : "=&r" (result) \ - : "Z" (*ptrp), "Z" (*((char *) ptrp + 4))); \ - result; }) -#endif /* __powerpc64__ */ - - -#define __sthbrx(base, value) do { \ - typedef struct {char a[2];} halfwordsize; \ - halfwordsize *ptrp = (halfwordsize*)(void*)(base); \ - __asm__ ("sthbrx %1,%y0" \ - : "=Z" (*ptrp) \ - : "r" (value)); \ - } while (0) - -#define __stwbrx(base, value) do { \ - typedef struct {char a[4];} wordsize; \ - wordsize *ptrp = (wordsize*)(void*)(base); \ - __asm__ ("stwbrx %1,%y0" \ - : "=Z" (*ptrp) \ - : "r" (value)); \ - } while (0) - -#ifdef __powerpc64__ -#define __stdbrx(base, value) do { \ - typedef struct {char a[8];} doublewordsize; \ - doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ - __asm__ ("stdbrx %1,%y0" \ - : "=Z" (*ptrp) \ - : "r" (value)); \ - } while (0) -#else -#define __stdbrx(base, value) do { \ - typedef struct {char a[8];} doublewordsize; \ - doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ - __asm__ ("stwbrx %L2,%y0\n" \ - "\tstwbrx %2,%y1" \ - : "=Z" (*ptrp), "=Z" (*((char *) ptrp + 4)) \ - : "r" (value)); \ - } while (0) -#endif /* __powerpc64__ */ - - -#define __lwarx(base) __extension__ \ - ({unsigned int result; \ - typedef struct {char a[4];} wordsize; \ - wordsize *ptrp = (wordsize*)(void*)(base); \ - __asm__ volatile ("lwarx %0,%y1" \ - : "=r" (result) \ - : "Z" (*ptrp)); \ - result; }) - -#ifdef __powerpc64__ -#define __ldarx(base) __extension__ \ - ({unsigned long long result; \ - typedef struct {char a[8];} doublewordsize; \ - doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ - __asm__ volatile ("ldarx %0,%y1" \ - : "=r" (result) \ - : "Z" (*ptrp)); \ - result; }) -#endif /* __powerpc64__ */ - -#define __stwcx(base, value) __extension__ \ - ({unsigned int result; \ - typedef struct {char a[4];} wordsize; \ - wordsize *ptrp = (wordsize*)(void*)(base); \ - __asm__ volatile ("stwcx. %2,%y1\n" \ - "\tmfocrf %0,0x80" \ - : "=r" (result), \ - "=Z" (*ptrp) \ - : "r" (value) : "cr0"); \ - ((result & 0x20000000) >> 29); }) - - -#ifdef __powerpc64__ -#define __stdcx(base, value) __extension__ \ - ({unsigned long long result; \ - typedef struct {char a[8];} doublewordsize; \ - doublewordsize *ptrp = (doublewordsize*)(void*)(base); \ - __asm__ volatile ("stdcx. %2,%y1\n" \ - "\tmfocrf %0,0x80" \ - : "=r" (result), \ - "=Z" (*ptrp) \ - : "r" (value) : "cr0"); \ - ((result & 0x20000000) >> 29); }) -#endif /* __powerpc64__ */ - -#define __mffs() __extension__ \ - ({double result; \ - __asm__ volatile ("mffs %0" : "=d" (result)); \ - result; }) - -#define __mtfsf(mask,value) \ - __asm__ volatile ("mtfsf %0,%1" : : "n" (mask), "d" ((double) (value))) - -#define __mtfsfi(bits,field) \ - __asm__ volatile ("mtfsfi %0,%1" : : "n" (bits), "n" (field)) - -#define __mtfsb0(bit) __asm__ volatile ("mtfsb0 %0" : : "n" (bit)) -#define __mtfsb1(bit) __asm__ volatile ("mtfsb1 %0" : : "n" (bit)) - -#define __setflm(v) __extension__ \ - ({double result; \ - __asm__ volatile ("mffs %0\n\tmtfsf 255,%1" \ - : "=&d" (result) \ - : "d" ((double) (v))); \ - result; }) - -/* __builtin_fabs may perform unnecessary rounding. */ - -/* Rename __fabs and __fabsf to work around internal prototypes defined - in bits/mathcalls.h with some glibc versions. */ -#define __fabs __ppu_fabs -#define __fabsf __ppu_fabsf - -static __inline__ double __fabs(double x) __attribute__((always_inline)); -static __inline__ double -__fabs(double x) -{ - double r; - __asm__("fabs %0,%1" : "=d"(r) : "d"(x)); - return r; -} - -static __inline__ float __fabsf(float x) __attribute__((always_inline)); -static __inline__ float -__fabsf(float x) -{ - float r; - __asm__("fabs %0,%1" : "=f"(r) : "f"(x)); - return r; -} - -static __inline__ double __fnabs(double x) __attribute__((always_inline)); -static __inline__ double -__fnabs(double x) -{ - double r; - __asm__("fnabs %0,%1" : "=d"(r) : "d"(x)); - return r; -} - -static __inline__ float __fnabsf(float x) __attribute__((always_inline)); -static __inline__ float -__fnabsf(float x) -{ - float r; - __asm__("fnabs %0,%1" : "=f"(r) : "f"(x)); - return r; -} - -static __inline__ double __fmadd(double x, double y, double z) - __attribute__((always_inline)); -static __inline__ double -__fmadd(double x, double y, double z) -{ - double r; - __asm__("fmadd %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); - return r; -} - -static __inline__ double __fmsub(double x, double y, double z) - __attribute__((always_inline)); -static __inline__ double -__fmsub(double x, double y, double z) -{ - double r; - __asm__("fmsub %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); - return r; -} - -static __inline__ double __fnmadd(double x, double y, double z) - __attribute__((always_inline)); -static __inline__ double -__fnmadd(double x, double y, double z) -{ - double r; - __asm__("fnmadd %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); - return r; -} - -static __inline__ double __fnmsub(double x, double y, double z) - __attribute__((always_inline)); -static __inline__ double -__fnmsub(double x, double y, double z) -{ - double r; - __asm__("fnmsub %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); - return r; -} - -static __inline__ float __fmadds(float x, float y, float z) - __attribute__((always_inline)); -static __inline__ float -__fmadds(float x, float y, float z) -{ - float r; - __asm__("fmadds %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); - return r; -} - -static __inline__ float __fmsubs(float x, float y, float z) - __attribute__((always_inline)); -static __inline__ float -__fmsubs(float x, float y, float z) -{ - float r; - __asm__("fmsubs %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); - return r; -} - -static __inline__ float __fnmadds(float x, float y, float z) - __attribute__((always_inline)); -static __inline__ float -__fnmadds(float x, float y, float z) -{ - float r; - __asm__("fnmadds %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); - return r; -} - -static __inline__ float __fnmsubs(float x, float y, float z) - __attribute__((always_inline)); -static __inline__ float -__fnmsubs(float x, float y, float z) -{ - float r; - __asm__("fnmsubs %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); - return r; -} - -static __inline__ double __fsel(double x, double y, double z) - __attribute__((always_inline)); -static __inline__ double -__fsel(double x, double y, double z) -{ - double r; - __asm__("fsel %0,%1,%2,%3" : "=d"(r) : "d"(x),"d"(y),"d"(z)); - return r; -} - -static __inline__ float __fsels(float x, float y, float z) - __attribute__((always_inline)); -static __inline__ float -__fsels(float x, float y, float z) -{ - float r; - __asm__("fsel %0,%1,%2,%3" : "=f"(r) : "f"(x),"f"(y),"f"(z)); - return r; -} - -static __inline__ double __frsqrte(double x) __attribute__((always_inline)); -static __inline__ double -__frsqrte(double x) -{ - double r; - __asm__("frsqrte %0,%1" : "=d" (r) : "d" (x)); - return r; -} - -static __inline__ float __fres(float x) __attribute__((always_inline)); -static __inline__ float -__fres(float x) -{ - float r; - __asm__("fres %0,%1" : "=f"(r) : "f"(x)); - return r; -} - -static __inline__ double __fsqrt(double x) __attribute__((always_inline)); -static __inline__ double -__fsqrt(double x) -{ - double r; - __asm__("fsqrt %0,%1" : "=d"(r) : "d"(x)); - return r; -} - -static __inline__ float __fsqrts(float x) __attribute__((always_inline)); -static __inline__ float -__fsqrts(float x) -{ - float r; - __asm__("fsqrts %0,%1" : "=f"(r) : "f"(x)); - return r; -} - -static __inline__ double __fmul (double a, double b) __attribute__ ((always_inline)); -static __inline__ double -__fmul(double a, double b) -{ - double d; - __asm__ ("fmul %0,%1,%2" : "=d" (d) : "d" (a), "d" (b)); - return d; -} - -static __inline__ float __fmuls (float a, float b) __attribute__ ((always_inline)); -static __inline__ float -__fmuls (float a, float b) -{ - float d; - __asm__ ("fmuls %0,%1,%2" : "=d" (d) : "f" (a), "f" (b)); - return d; -} - -static __inline__ float __frsp (float a) __attribute__ ((always_inline)); -static __inline__ float -__frsp (float a) -{ - float d; - __asm__ ("frsp %0,%1" : "=d" (d) : "f" (a)); - return d; -} - -static __inline__ double __fcfid (long long a) __attribute__((always_inline)); -static __inline__ double -__fcfid (long long a) -{ - double d; - __asm__ ("fcfid %0,%1" : "=d" (d) : "d" (a)); - return d; -} - -static __inline__ long long __fctid (double a) __attribute__ ((always_inline)); -static __inline__ long long -__fctid (double a) -{ - long long d; - __asm__ ("fctid %0,%1" : "=d" (d) : "d" (a)); - return d; -} - -static __inline__ long long __fctidz (double a) __attribute__ ((always_inline)); -static __inline__ long long -__fctidz (double a) -{ - long long d; - __asm__ ("fctidz %0,%1" : "=d" (d) : "d" (a)); - return d; -} - -static __inline__ int __fctiw (double a) __attribute__ ((always_inline)); -static __inline__ int -__fctiw (double a) -{ - unsigned long long d; - __asm__ ("fctiw %0,%1" : "=d" (d) : "d" (a)); - return (int) d; -} - -static __inline__ int __fctiwz (double a) __attribute__ ((always_inline)); -static __inline__ int -__fctiwz (double a) -{ - long long d; - __asm__ ("fctiwz %0,%1" : "=d" (d) : "d" (a)); - return (int) d; -} - -#ifdef __powerpc64__ -#define __rldcl(a,b,mb) __extension__ \ - ({ \ - unsigned long long d; \ - __asm__ ("rldcl %0,%1,%2,%3" : "=r" (d) : "r" (a), "r" (b), "i" (mb)); \ - d; \ - }) - -#define __rldcr(a,b,me) __extension__ \ - ({ \ - unsigned long long d; \ - __asm__ ("rldcr %0,%1,%2,%3" : "=r" (d) : "r" (a), "r" (b), "i" (me)); \ - d; \ - }) - -#define __rldic(a,sh,mb) __extension__ \ - ({ \ - unsigned long long d; \ - __asm__ ("rldic %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (mb)); \ - d; \ - }) - -#define __rldicl(a,sh,mb) __extension__ \ - ({ \ - unsigned long long d; \ - __asm__ ("rldicl %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (mb)); \ - d; \ - }) - -#define __rldicr(a,sh,me) __extension__ \ - ({ \ - unsigned long long d; \ - __asm__ ("rldicr %0,%1,%2,%3" : "=r" (d) : "r" (a), "i" (sh), "i" (me)); \ - d; \ - }) - -#define __rldimi(a,b,sh,mb) __extension__ \ - ({ \ - unsigned long long d; \ - __asm__ ("rldimi %0,%1,%2,%3" : "=r" (d) : "r" (b), "i" (sh), "i" (mb), "0" (a)); \ - d; \ - }) -#endif /* __powerpc64__ */ - -#define __rlwimi(a,b,sh,mb,me) __extension__ \ - ({ \ - unsigned int d; \ - __asm__ ("rlwimi %0,%1,%2,%3,%4" : "=r" (d) : "r" (b), "i" (sh), "i" (mb), "i" (me), "0" (a)); \ - d; \ - }) - -#define __rlwinm(a,sh,mb,me) __extension__ \ - ({ \ - unsigned int d; \ - __asm__ ("rlwinm %0,%1,%2,%3,%4" : "=r" (d) : "r" (a), "i" (sh), "i" (mb), "i" (me)); \ - d; \ - }) - -#define __rlwnm(a,b,mb,me) __extension__ \ - ({ \ - unsigned int d; \ - __asm__ ("rlwnm %0,%1,%2,%3,%4" : "=r" (d) : "r" (a), "r" (b), "i" (mb), "i" (me)); \ - d; \ - }) - -#ifdef __cplusplus -} -#endif - -#endif /* _PPU_INTRINSICS_H */ diff --git a/gcc-4.8.1/gcc/config/rs6000/predicates.md b/gcc-4.8.1/gcc/config/rs6000/predicates.md deleted file mode 100644 index 868ba5679..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/predicates.md +++ /dev/null @@ -1,1528 +0,0 @@ -;; Predicate definitions for POWER and PowerPC. -;; Copyright (C) 2005-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; GCC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; Return 1 for anything except PARALLEL. -(define_predicate "any_operand" - (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,mem")) - -;; Return 1 for any PARALLEL. -(define_predicate "any_parallel_operand" - (match_code "parallel")) - -;; Return 1 if op is COUNT register. -(define_predicate "count_register_operand" - (and (match_code "reg") - (match_test "REGNO (op) == CTR_REGNO - || REGNO (op) > LAST_VIRTUAL_REGISTER"))) - -;; Return 1 if op is an Altivec register. -(define_predicate "altivec_register_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - return ALTIVEC_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is a VSX register. -(define_predicate "vsx_register_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - return VSX_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is a vector register that operates on floating point vectors -;; (either altivec or VSX). -(define_predicate "vfloat_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - return VFLOAT_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is a vector register that operates on integer vectors -;; (only altivec, VSX doesn't support integer vectors) -(define_predicate "vint_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - return VINT_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is a vector register to do logical operations on (and, or, -;; xor, etc.) -(define_predicate "vlogical_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - return VLOGICAL_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is the carry register. -(define_predicate "ca_operand" - (and (match_code "reg") - (match_test "CA_REGNO_P (REGNO (op))"))) - -;; Return 1 if op is a signed 5-bit constant integer. -(define_predicate "s5bit_cint_operand" - (and (match_code "const_int") - (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15"))) - -;; Return 1 if op is a unsigned 5-bit constant integer. -(define_predicate "u5bit_cint_operand" - (and (match_code "const_int") - (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 31"))) - -;; Return 1 if op is a signed 8-bit constant integer. -;; Integer multiplication complete more quickly -(define_predicate "s8bit_cint_operand" - (and (match_code "const_int") - (match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127"))) - -;; Return 1 if op is a constant integer that can fit in a D field. -(define_predicate "short_cint_operand" - (and (match_code "const_int") - (match_test "satisfies_constraint_I (op)"))) - -;; Return 1 if op is a constant integer that can fit in an unsigned D field. -(define_predicate "u_short_cint_operand" - (and (match_code "const_int") - (match_test "satisfies_constraint_K (op)"))) - -;; Return 1 if op is a constant integer that cannot fit in a signed D field. -(define_predicate "non_short_cint_operand" - (and (match_code "const_int") - (match_test "(unsigned HOST_WIDE_INT) - (INTVAL (op) + 0x8000) >= 0x10000"))) - -;; Return 1 if op is a positive constant integer that is an exact power of 2. -(define_predicate "exact_log2_cint_operand" - (and (match_code "const_int") - (match_test "INTVAL (op) > 0 && exact_log2 (INTVAL (op)) >= 0"))) - -;; Match op = 0 or op = 1. -(define_predicate "const_0_to_1_operand" - (and (match_code "const_int") - (match_test "IN_RANGE (INTVAL (op), 0, 1)"))) - -;; Match op = 2 or op = 3. -(define_predicate "const_2_to_3_operand" - (and (match_code "const_int") - (match_test "IN_RANGE (INTVAL (op), 2, 3)"))) - -;; Return 1 if op is a register that is not special. -(define_predicate "gpc_reg_operand" - (match_operand 0 "register_operand") -{ - if ((TARGET_E500_DOUBLE || TARGET_SPE) && invalid_e500_subreg (op, mode)) - return 0; - - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) >= ARG_POINTER_REGNUM && !CA_REGNO_P (REGNO (op))) - return 1; - - return INT_REGNO_P (REGNO (op)) || FP_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is a register that is a condition register field. -(define_predicate "cc_reg_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - return CR_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is a register that is a condition register field not cr0. -(define_predicate "cc_reg_not_cr0_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - return CR_REGNO_NOT_CR0_P (REGNO (op)); -}) - -;; Return 1 if op is a register that is a condition register field and if generating microcode, not cr0. -(define_predicate "cc_reg_not_micro_cr0_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - if (!REG_P (op)) - return 0; - - if (REGNO (op) > LAST_VIRTUAL_REGISTER) - return 1; - - if (rs6000_gen_cell_microcode) - return CR_REGNO_NOT_CR0_P (REGNO (op)); - else - return CR_REGNO_P (REGNO (op)); -}) - -;; Return 1 if op is a constant integer valid for D field -;; or non-special register register. -(define_predicate "reg_or_short_operand" - (if_then_else (match_code "const_int") - (match_operand 0 "short_cint_operand") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if op is a constant integer valid whose negation is valid for -;; D field or non-special register register. -;; Do not allow a constant zero because all patterns that call this -;; predicate use "addic r1,r2,-const" to set carry when r2 is greater than -;; or equal to const, which does not work for zero. -(define_predicate "reg_or_neg_short_operand" - (if_then_else (match_code "const_int") - (match_test "satisfies_constraint_P (op) - && INTVAL (op) != 0") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if op is a constant integer valid for DS field -;; or non-special register. -(define_predicate "reg_or_aligned_short_operand" - (if_then_else (match_code "const_int") - (and (match_operand 0 "short_cint_operand") - (match_test "!(INTVAL (op) & 3)")) - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if op is a constant integer whose high-order 16 bits are zero -;; or non-special register. -(define_predicate "reg_or_u_short_operand" - (if_then_else (match_code "const_int") - (match_operand 0 "u_short_cint_operand") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if op is any constant integer -;; or non-special register. -(define_predicate "reg_or_cint_operand" - (ior (match_code "const_int") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if op is a constant integer valid for addition -;; or non-special register. -(define_predicate "reg_or_add_cint_operand" - (if_then_else (match_code "const_int") - (match_test "(HOST_BITS_PER_WIDE_INT == 32 - && (mode == SImode || INTVAL (op) < 0x7fff8000)) - || ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000) - < (unsigned HOST_WIDE_INT) 0x100000000ll)") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if op is a constant integer valid for subtraction -;; or non-special register. -(define_predicate "reg_or_sub_cint_operand" - (if_then_else (match_code "const_int") - (match_test "(HOST_BITS_PER_WIDE_INT == 32 - && (mode == SImode || - INTVAL (op) < 0x7fff8000)) - || ((unsigned HOST_WIDE_INT) (- INTVAL (op) - + (mode == SImode - ? 0x80000000 : 0x80008000)) - < (unsigned HOST_WIDE_INT) 0x100000000ll)") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if op is any 32-bit unsigned constant integer -;; or non-special register. -(define_predicate "reg_or_logical_cint_operand" - (if_then_else (match_code "const_int") - (match_test "(GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT - && INTVAL (op) >= 0) - || ((INTVAL (op) & GET_MODE_MASK (mode) - & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0)") - (if_then_else (match_code "const_double") - (match_test "GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT - && mode == DImode - && CONST_DOUBLE_HIGH (op) == 0") - (match_operand 0 "gpc_reg_operand")))) - -;; Return 1 if operand is a CONST_DOUBLE that can be set in a register -;; with no more than one instruction per word. -(define_predicate "easy_fp_constant" - (match_code "const_double") -{ - long k[4]; - REAL_VALUE_TYPE rv; - - if (GET_MODE (op) != mode - || (!SCALAR_FLOAT_MODE_P (mode) && mode != DImode)) - return 0; - - /* Consider all constants with -msoft-float to be easy. */ - if ((TARGET_SOFT_FLOAT || TARGET_E500_SINGLE - || (TARGET_HARD_FLOAT && (TARGET_SINGLE_FLOAT && ! TARGET_DOUBLE_FLOAT))) - && mode != DImode) - return 1; - - if (DECIMAL_FLOAT_MODE_P (mode)) - return 0; - - /* If we are using V.4 style PIC, consider all constants to be hard. */ - if (flag_pic && DEFAULT_ABI == ABI_V4) - return 0; - -#ifdef TARGET_RELOCATABLE - /* Similarly if we are using -mrelocatable, consider all constants - to be hard. */ - if (TARGET_RELOCATABLE) - return 0; -#endif - - switch (mode) - { - case TFmode: - if (TARGET_E500_DOUBLE) - return 0; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); - - return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1); - - case DFmode: - /* The constant 0.f is easy under VSX. */ - if (op == CONST0_RTX (DFmode) && VECTOR_UNIT_VSX_P (DFmode)) - return 1; - - /* Force constants to memory before reload to utilize - compress_float_constant. - Avoid this when flag_unsafe_math_optimizations is enabled - because RDIV division to reciprocal optimization is not able - to regenerate the division. */ - if (TARGET_E500_DOUBLE - || (!reload_in_progress && !reload_completed - && !flag_unsafe_math_optimizations)) - return 0; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_DOUBLE (rv, k); - - return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1 - && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1); - - case SFmode: - /* The constant 0.f is easy. */ - if (op == CONST0_RTX (SFmode)) - return 1; - - /* Force constants to memory before reload to utilize - compress_float_constant. - Avoid this when flag_unsafe_math_optimizations is enabled - because RDIV division to reciprocal optimization is not able - to regenerate the division. */ - if (!reload_in_progress && !reload_completed - && !flag_unsafe_math_optimizations) - return 0; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - REAL_VALUE_TO_TARGET_SINGLE (rv, k[0]); - - return num_insns_constant_wide (k[0]) == 1; - - case DImode: - return ((TARGET_POWERPC64 - && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0) - || (num_insns_constant (op, DImode) <= 2)); - - case SImode: - return 1; - - default: - gcc_unreachable (); - } -}) - -;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a -;; vector register without using memory. -(define_predicate "easy_vector_constant" - (match_code "const_vector") -{ - /* As the paired vectors are actually FPRs it seems that there is - no easy way to load a CONST_VECTOR without using memory. */ - if (TARGET_PAIRED_FLOAT) - return false; - - if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) - { - if (zero_constant (op, mode)) - return true; - - return easy_altivec_constant (op, mode); - } - - if (SPE_VECTOR_MODE (mode)) - { - int cst, cst2; - if (zero_constant (op, mode)) - return true; - if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) - return false; - - /* 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 (mode == V2SImode) - { - cst = INTVAL (CONST_VECTOR_ELT (op, 0)); - cst2 = INTVAL (CONST_VECTOR_ELT (op, 1)); - return cst >= -0x7fff && cst <= 0x7fff - && cst2 >= -0x7fff && cst2 <= 0x7fff; - } - } - - return false; -}) - -;; Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF. -(define_predicate "easy_vector_constant_add_self" - (and (match_code "const_vector") - (and (match_test "TARGET_ALTIVEC") - (match_test "easy_altivec_constant (op, mode)"))) -{ - HOST_WIDE_INT val; - if (mode == V2DImode || mode == V2DFmode) - return 0; - val = const_vector_elt_as_int (op, GET_MODE_NUNITS (mode) - 1); - val = ((val & 0xff) ^ 0x80) - 0x80; - return EASY_VECTOR_15_ADD_SELF (val); -}) - -;; Same as easy_vector_constant but only for EASY_VECTOR_MSB. -(define_predicate "easy_vector_constant_msb" - (and (match_code "const_vector") - (and (match_test "TARGET_ALTIVEC") - (match_test "easy_altivec_constant (op, mode)"))) -{ - HOST_WIDE_INT val; - if (mode == V2DImode || mode == V2DFmode) - return 0; - val = const_vector_elt_as_int (op, GET_MODE_NUNITS (mode) - 1); - return EASY_VECTOR_MSB (val, GET_MODE_INNER (mode)); -}) - -;; Return 1 if operand is constant zero (scalars and vectors). -(define_predicate "zero_constant" - (and (match_code "const_int,const_double,const_vector") - (match_test "op == CONST0_RTX (mode)"))) - -;; Return 1 if operand is 0.0. -(define_predicate "zero_fp_constant" - (and (match_code "const_double") - (match_test "SCALAR_FLOAT_MODE_P (mode) - && op == CONST0_RTX (mode)"))) - -;; Return 1 if the operand is in volatile memory. Note that during the -;; RTL generation phase, memory_operand does not return TRUE for volatile -;; memory references. So this function allows us to recognize volatile -;; references where it's safe. -(define_predicate "volatile_mem_operand" - (and (and (match_code "mem") - (match_test "MEM_VOLATILE_P (op)")) - (if_then_else (match_test "reload_completed") - (match_operand 0 "memory_operand") - (if_then_else (match_test "reload_in_progress") - (match_test "strict_memory_address_p (mode, XEXP (op, 0))") - (match_test "memory_address_p (mode, XEXP (op, 0))"))))) - -;; Return 1 if the operand is an offsettable memory operand. -(define_predicate "offsettable_mem_operand" - (and (match_operand 0 "memory_operand") - (match_test "offsettable_nonstrict_memref_p (op)"))) - -;; Return 1 if the operand is an indexed or indirect memory operand. -(define_predicate "indexed_or_indirect_operand" - (match_code "mem") -{ - op = XEXP (op, 0); - if (VECTOR_MEM_ALTIVEC_P (mode) - && GET_CODE (op) == AND - && GET_CODE (XEXP (op, 1)) == CONST_INT - && INTVAL (XEXP (op, 1)) == -16) - op = XEXP (op, 0); - - return indexed_or_indirect_address (op, mode); -}) - -;; Return 1 if the operand is an indexed or indirect memory operand with an -;; AND -16 in it, used to recognize when we need to switch to Altivec loads -;; to realign loops instead of VSX (altivec silently ignores the bottom bits, -;; while VSX uses the full address and traps) -(define_predicate "altivec_indexed_or_indirect_operand" - (match_code "mem") -{ - op = XEXP (op, 0); - if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) - && GET_CODE (op) == AND - && GET_CODE (XEXP (op, 1)) == CONST_INT - && INTVAL (XEXP (op, 1)) == -16) - return indexed_or_indirect_address (XEXP (op, 0), mode); - - return 0; -}) - -;; Return 1 if the operand is an indexed or indirect address. -(define_special_predicate "indexed_or_indirect_address" - (and (match_test "REG_P (op) - || (GET_CODE (op) == PLUS - /* Omit testing REG_P (XEXP (op, 0)). */ - && REG_P (XEXP (op, 1)))") - (match_operand 0 "address_operand"))) - -;; Used for the destination of the fix_truncdfsi2 expander. -;; If stfiwx will be used, the result goes to memory; otherwise, -;; we're going to emit a store and a load of a subreg, so the dest is a -;; register. -(define_predicate "fix_trunc_dest_operand" - (if_then_else (match_test "! TARGET_E500_DOUBLE && TARGET_PPC_GFXOPT") - (match_operand 0 "memory_operand") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if the operand is either a non-special register or can be used -;; as the operand of a `mode' add insn. -(define_predicate "add_operand" - (if_then_else (match_code "const_int") - (match_test "satisfies_constraint_I (op) - || satisfies_constraint_L (op)") - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if OP is a constant but not a valid add_operand. -(define_predicate "non_add_cint_operand" - (and (match_code "const_int") - (match_test "!satisfies_constraint_I (op) - && !satisfies_constraint_L (op)"))) - -;; Return 1 if the operand is a constant that can be used as the operand -;; of an OR or XOR. -(define_predicate "logical_const_operand" - (match_code "const_int,const_double") -{ - HOST_WIDE_INT opl, oph; - - if (GET_CODE (op) == CONST_INT) - { - opl = INTVAL (op) & GET_MODE_MASK (mode); - - if (HOST_BITS_PER_WIDE_INT <= 32 - && GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0) - return 0; - } - else if (GET_CODE (op) == CONST_DOUBLE) - { - gcc_assert (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT); - - opl = CONST_DOUBLE_LOW (op); - oph = CONST_DOUBLE_HIGH (op); - if (oph != 0) - return 0; - } - else - return 0; - - return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0 - || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0); -}) - -;; Return 1 if the operand is a non-special register or a constant that -;; can be used as the operand of an OR or XOR. -(define_predicate "logical_operand" - (ior (match_operand 0 "gpc_reg_operand") - (match_operand 0 "logical_const_operand"))) - -;; Return 1 if op is a constant that is not a logical operand, but could -;; be split into one. -(define_predicate "non_logical_cint_operand" - (and (match_code "const_int,const_double") - (and (not (match_operand 0 "logical_operand")) - (match_operand 0 "reg_or_logical_cint_operand")))) - -;; Return 1 if op is a constant that can be encoded in a 32-bit mask, -;; suitable for use with rlwinm (no more than two 1->0 or 0->1 -;; transitions). Reject all ones and all zeros, since these should have -;; been optimized away and confuse the making of MB and ME. -(define_predicate "mask_operand" - (match_code "const_int") -{ - HOST_WIDE_INT c, lsb; - - c = INTVAL (op); - - if (TARGET_POWERPC64) - { - /* Fail if the mask is not 32-bit. */ - if (mode == DImode && (c & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0) - return 0; - - /* Fail if the mask wraps around because the upper 32-bits of the - mask will all be 1s, contrary to GCC's internal view. */ - if ((c & 0x80000001) == 0x80000001) - return 0; - } - - /* We don't change the number of transitions by inverting, - so make sure we start with the LS bit zero. */ - if (c & 1) - c = ~c; - - /* Reject all zeros or all ones. */ - if (c == 0) - return 0; - - /* Find the first transition. */ - lsb = c & -c; - - /* Invert to look for a second transition. */ - c = ~c; - - /* Erase first transition. */ - c &= -lsb; - - /* Find the second transition (if any). */ - lsb = c & -c; - - /* Match if all the bits above are 1's (or c is zero). */ - return c == -lsb; -}) - -;; Return 1 for the PowerPC64 rlwinm corner case. -(define_predicate "mask_operand_wrap" - (match_code "const_int") -{ - HOST_WIDE_INT c, lsb; - - c = INTVAL (op); - - if ((c & 0x80000001) != 0x80000001) - return 0; - - c = ~c; - if (c == 0) - return 0; - - lsb = c & -c; - c = ~c; - c &= -lsb; - lsb = c & -c; - return c == -lsb; -}) - -;; Return 1 if the operand is a constant that is a PowerPC64 mask -;; suitable for use with rldicl or rldicr (no more than one 1->0 or 0->1 -;; transition). Reject all zeros, since zero should have been -;; optimized away and confuses the making of MB and ME. -(define_predicate "mask64_operand" - (match_code "const_int") -{ - HOST_WIDE_INT c, lsb; - - c = INTVAL (op); - - /* Reject all zeros. */ - if (c == 0) - return 0; - - /* We don't change the number of transitions by inverting, - so make sure we start with the LS bit zero. */ - if (c & 1) - c = ~c; - - /* Find the first transition. */ - lsb = c & -c; - - /* Match if all the bits above are 1's (or c is zero). */ - return c == -lsb; -}) - -;; Like mask64_operand, but allow up to three transitions. This -;; predicate is used by insn patterns that generate two rldicl or -;; rldicr machine insns. -(define_predicate "mask64_2_operand" - (match_code "const_int") -{ - HOST_WIDE_INT c, lsb; - - c = INTVAL (op); - - /* Disallow all zeros. */ - if (c == 0) - return 0; - - /* We don't change the number of transitions by inverting, - so make sure we start with the LS bit zero. */ - if (c & 1) - c = ~c; - - /* Find the first transition. */ - lsb = c & -c; - - /* Invert to look for a second transition. */ - c = ~c; - - /* Erase first transition. */ - c &= -lsb; - - /* Find the second transition. */ - lsb = c & -c; - - /* Invert to look for a third transition. */ - c = ~c; - - /* Erase second transition. */ - c &= -lsb; - - /* Find the third transition (if any). */ - lsb = c & -c; - - /* Match if all the bits above are 1's (or c is zero). */ - return c == -lsb; -}) - -;; Like and_operand, but also match constants that can be implemented -;; with two rldicl or rldicr insns. -(define_predicate "and64_2_operand" - (ior (match_operand 0 "mask64_2_operand") - (if_then_else (match_test "fixed_regs[CR0_REGNO]") - (match_operand 0 "gpc_reg_operand") - (match_operand 0 "logical_operand")))) - -;; Return 1 if the operand is either a non-special register or a -;; constant that can be used as the operand of a logical AND. -(define_predicate "and_operand" - (ior (match_operand 0 "mask_operand") - (ior (and (match_test "TARGET_POWERPC64 && mode == DImode") - (match_operand 0 "mask64_operand")) - (if_then_else (match_test "fixed_regs[CR0_REGNO]") - (match_operand 0 "gpc_reg_operand") - (match_operand 0 "logical_operand"))))) - -;; Return 1 if the operand is either a logical operand or a short cint operand. -(define_predicate "scc_eq_operand" - (ior (match_operand 0 "logical_operand") - (match_operand 0 "short_cint_operand"))) - -;; Return 1 if the operand is a general non-special register or memory operand. -(define_predicate "reg_or_mem_operand" - (ior (match_operand 0 "memory_operand") - (ior (and (match_code "mem") - (match_test "macho_lo_sum_memory_operand (op, mode)")) - (ior (match_operand 0 "volatile_mem_operand") - (match_operand 0 "gpc_reg_operand"))))) - -;; Return 1 if the operand is either an easy FP constant or memory or reg. -(define_predicate "reg_or_none500mem_operand" - (if_then_else (match_code "mem") - (and (match_test "!TARGET_E500_DOUBLE") - (ior (match_operand 0 "memory_operand") - (ior (match_test "macho_lo_sum_memory_operand (op, mode)") - (match_operand 0 "volatile_mem_operand")))) - (match_operand 0 "gpc_reg_operand"))) - -;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand. -(define_predicate "zero_reg_mem_operand" - (ior (match_operand 0 "zero_fp_constant") - (match_operand 0 "reg_or_mem_operand"))) - -;; Return 1 if the operand is a general register or memory operand without -;; pre_inc or pre_dec or pre_modify, which produces invalid form of PowerPC -;; lwa instruction. -(define_predicate "lwa_operand" - (match_code "reg,subreg,mem") -{ - rtx inner, addr, offset; - - inner = op; - if (reload_completed && GET_CODE (inner) == SUBREG) - inner = SUBREG_REG (inner); - - if (gpc_reg_operand (inner, mode)) - return true; - if (!memory_operand (inner, mode)) - return false; - addr = XEXP (inner, 0); - if (GET_CODE (addr) == PRE_INC - || GET_CODE (addr) == PRE_DEC - || (GET_CODE (addr) == PRE_MODIFY - && !legitimate_indexed_address_p (XEXP (addr, 1), 0))) - return false; - if (GET_CODE (addr) == LO_SUM - && GET_CODE (XEXP (addr, 0)) == REG - && GET_CODE (XEXP (addr, 1)) == CONST) - addr = XEXP (XEXP (addr, 1), 0); - if (GET_CODE (addr) != PLUS) - return true; - offset = XEXP (addr, 1); - if (GET_CODE (offset) != CONST_INT) - return true; - return INTVAL (offset) % 4 == 0; -}) - -;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. -(define_predicate "symbol_ref_operand" - (and (match_code "symbol_ref") - (match_test "(mode == VOIDmode || GET_MODE (op) == mode) - && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))"))) - -;; Return 1 if op is an operand that can be loaded via the GOT. -;; or non-special register register field no cr0 -(define_predicate "got_operand" - (match_code "symbol_ref,const,label_ref")) - -;; Return 1 if op is a simple reference that can be loaded via the GOT, -;; excluding labels involving addition. -(define_predicate "got_no_const_operand" - (match_code "symbol_ref,label_ref")) - -;; Return 1 if op is a SYMBOL_REF for a TLS symbol. -(define_predicate "rs6000_tls_symbol_ref" - (and (match_code "symbol_ref") - (match_test "RS6000_SYMBOL_REF_TLS_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. -(define_predicate "call_operand" - (if_then_else (match_code "reg") - (match_test "REGNO (op) == LR_REGNO - || REGNO (op) == CTR_REGNO - || REGNO (op) >= FIRST_PSEUDO_REGISTER") - (match_code "symbol_ref"))) - -;; Return 1 if the operand is a SYMBOL_REF for a function known to be in -;; this file. -(define_predicate "current_file_function_operand" - (and (match_code "symbol_ref") - (match_test "(DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)) - && ((SYMBOL_REF_LOCAL_P (op) - && (DEFAULT_ABI != ABI_AIX - || !SYMBOL_REF_EXTERNAL_P (op))) - || (op == XEXP (DECL_RTL (current_function_decl), - 0)))"))) - -;; Return 1 if this operand is a valid input for a move insn. -(define_predicate "input_operand" - (match_code "symbol_ref,const,reg,subreg,mem, - const_double,const_vector,const_int") -{ - /* Memory is always valid. */ - if (memory_operand (op, mode)) - return 1; - - /* For floating-point, easy constants are valid. */ - if (SCALAR_FLOAT_MODE_P (mode) - && easy_fp_constant (op, mode)) - return 1; - - /* Allow any integer constant. */ - if (GET_MODE_CLASS (mode) == MODE_INT - && (GET_CODE (op) == CONST_INT - || GET_CODE (op) == CONST_DOUBLE)) - return 1; - - /* Allow easy vector constants. */ - if (GET_CODE (op) == CONST_VECTOR - && easy_vector_constant (op, mode)) - return 1; - - /* Do not allow invalid E500 subregs. */ - if ((TARGET_E500_DOUBLE || TARGET_SPE) - && GET_CODE (op) == SUBREG - && invalid_e500_subreg (op, mode)) - return 0; - - /* For floating-point or multi-word mode, the only remaining valid type - is a register. */ - if (SCALAR_FLOAT_MODE_P (mode) - || GET_MODE_SIZE (mode) > UNITS_PER_WORD) - return register_operand (op, mode); - - /* The only cases left are integral modes one word or smaller (we - do not get called for MODE_CC values). These can be in any - register. */ - if (register_operand (op, mode)) - return 1; - - /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region - to be valid. */ - if (DEFAULT_ABI == ABI_V4 - && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST) - && small_data_operand (op, Pmode)) - return 1; - - return 0; -}) - -;; Return 1 if this operand is a valid input for a vsx_splat insn. -(define_predicate "splat_input_operand" - (match_code "symbol_ref,const,reg,subreg,mem, - const_double,const_vector,const_int") -{ - if (MEM_P (op)) - { - if (! volatile_ok && MEM_VOLATILE_P (op)) - return 0; - if (mode == DFmode) - mode = V2DFmode; - else if (mode == DImode) - mode = V2DImode; - else - gcc_unreachable (); - return memory_address_addr_space_p (mode, XEXP (op, 0), - MEM_ADDR_SPACE (op)); - } - return input_operand (op, mode); -}) - -;; Return true if OP is a non-immediate operand and not an invalid -;; SUBREG operation on the e500. -(define_predicate "rs6000_nonimmediate_operand" - (match_code "reg,subreg,mem") -{ - if ((TARGET_E500_DOUBLE || TARGET_SPE) - && GET_CODE (op) == SUBREG - && invalid_e500_subreg (op, mode)) - return 0; - - return nonimmediate_operand (op, mode); -}) - -;; Return true if operand is boolean operator. -(define_predicate "boolean_operator" - (match_code "and,ior,xor")) - -;; Return true if operand is OR-form of boolean operator. -(define_predicate "boolean_or_operator" - (match_code "ior,xor")) - -;; Return true if operand is an equality operator. -(define_special_predicate "equality_operator" - (match_code "eq,ne")) - -;; Return true if operand is MIN or MAX operator. -(define_predicate "min_max_operator" - (match_code "smin,smax,umin,umax")) - -;; Return 1 if OP is a comparison operation that is valid for a branch -;; instruction. We check the opcode against the mode of the CC value. -;; validate_condition_mode is an assertion. -(define_predicate "branch_comparison_operator" - (and (match_operand 0 "comparison_operator") - (and (match_test "GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_CC") - (match_test "validate_condition_mode (GET_CODE (op), - GET_MODE (XEXP (op, 0))), - 1")))) - -(define_predicate "rs6000_cbranch_operator" - (if_then_else (match_test "TARGET_HARD_FLOAT && !TARGET_FPRS") - (match_operand 0 "ordered_comparison_operator") - (match_operand 0 "comparison_operator"))) - -;; Return 1 if OP is a comparison operation that is valid for an SCC insn -- -;; it must be a positive comparison. -(define_predicate "scc_comparison_operator" - (and (match_operand 0 "branch_comparison_operator") - (match_code "eq,lt,gt,ltu,gtu,unordered"))) - -;; Return 1 if OP is a comparison operation whose inverse would be valid for -;; an SCC insn. -(define_predicate "scc_rev_comparison_operator" - (and (match_operand 0 "branch_comparison_operator") - (match_code "ne,le,ge,leu,geu,ordered"))) - -;; Return 1 if OP is a comparison operation that is valid for a branch -;; insn, which is true if the corresponding bit in the CC register is set. -(define_predicate "branch_positive_comparison_operator" - (and (match_operand 0 "branch_comparison_operator") - (match_code "eq,lt,gt,ltu,gtu,unordered"))) - -;; Return 1 if OP is a load multiple operation, known to be a PARALLEL. -(define_predicate "load_multiple_operation" - (match_code "parallel") -{ - int count = XVECLEN (op, 0); - unsigned int dest_regno; - rtx src_addr; - 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_DEST (XVECEXP (op, 0, 0))) != REG - || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) - return 0; - - dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); - src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); - - for (i = 1; i < count; i++) - { - rtx elt = XVECEXP (op, 0, i); - - if (GET_CODE (elt) != SET - || GET_CODE (SET_DEST (elt)) != REG - || GET_MODE (SET_DEST (elt)) != SImode - || REGNO (SET_DEST (elt)) != dest_regno + i - || GET_CODE (SET_SRC (elt)) != MEM - || GET_MODE (SET_SRC (elt)) != SImode - || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS - || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) - || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT - || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4) - return 0; - } - - return 1; -}) - -;; Return 1 if OP is a store multiple operation, known to be a PARALLEL. -;; The second vector element is a CLOBBER. -(define_predicate "store_multiple_operation" - (match_code "parallel") -{ - int count = XVECLEN (op, 0) - 1; - unsigned int src_regno; - rtx dest_addr; - 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_DEST (XVECEXP (op, 0, 0))) != MEM - || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) - return 0; - - src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); - dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); - - for (i = 1; i < count; i++) - { - rtx elt = XVECEXP (op, 0, i + 1); - - if (GET_CODE (elt) != SET - || GET_CODE (SET_SRC (elt)) != REG - || GET_MODE (SET_SRC (elt)) != SImode - || REGNO (SET_SRC (elt)) != src_regno + i - || GET_CODE (SET_DEST (elt)) != MEM - || GET_MODE (SET_DEST (elt)) != SImode - || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS - || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) - || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT - || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4) - return 0; - } - - return 1; -}) - -;; Return 1 if OP is valid for a save_world call in prologue, known to be -;; a PARLLEL. -(define_predicate "save_world_operation" - (match_code "parallel") -{ - int index; - int i; - rtx elt; - int count = XVECLEN (op, 0); - - if (count != 54) - return 0; - - index = 0; - if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER - || GET_CODE (XVECEXP (op, 0, index++)) != USE) - return 0; - - for (i=1; i <= 18; i++) - { - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_DEST (elt)) != MEM - || ! memory_operand (SET_DEST (elt), DFmode) - || GET_CODE (SET_SRC (elt)) != REG - || GET_MODE (SET_SRC (elt)) != DFmode) - return 0; - } - - for (i=1; i <= 12; i++) - { - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_DEST (elt)) != MEM - || GET_CODE (SET_SRC (elt)) != REG - || GET_MODE (SET_SRC (elt)) != V4SImode) - return 0; - } - - for (i=1; i <= 19; i++) - { - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_DEST (elt)) != MEM - || ! memory_operand (SET_DEST (elt), Pmode) - || GET_CODE (SET_SRC (elt)) != REG - || GET_MODE (SET_SRC (elt)) != Pmode) - return 0; - } - - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_DEST (elt)) != MEM - || ! memory_operand (SET_DEST (elt), Pmode) - || GET_CODE (SET_SRC (elt)) != REG - || REGNO (SET_SRC (elt)) != CR2_REGNO - || GET_MODE (SET_SRC (elt)) != Pmode) - return 0; - - if (GET_CODE (XVECEXP (op, 0, index++)) != SET - || GET_CODE (XVECEXP (op, 0, index++)) != SET) - return 0; - return 1; -}) - -;; Return 1 if OP is valid for a restore_world call in epilogue, known to be -;; a PARLLEL. -(define_predicate "restore_world_operation" - (match_code "parallel") -{ - int index; - int i; - rtx elt; - int count = XVECLEN (op, 0); - - if (count != 59) - return 0; - - index = 0; - if (GET_CODE (XVECEXP (op, 0, index++)) != RETURN - || GET_CODE (XVECEXP (op, 0, index++)) != USE - || GET_CODE (XVECEXP (op, 0, index++)) != USE - || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER) - return 0; - - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_SRC (elt)) != MEM - || ! memory_operand (SET_SRC (elt), Pmode) - || GET_CODE (SET_DEST (elt)) != REG - || REGNO (SET_DEST (elt)) != CR2_REGNO - || GET_MODE (SET_DEST (elt)) != Pmode) - return 0; - - for (i=1; i <= 19; i++) - { - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_SRC (elt)) != MEM - || ! memory_operand (SET_SRC (elt), Pmode) - || GET_CODE (SET_DEST (elt)) != REG - || GET_MODE (SET_DEST (elt)) != Pmode) - return 0; - } - - for (i=1; i <= 12; i++) - { - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_SRC (elt)) != MEM - || GET_CODE (SET_DEST (elt)) != REG - || GET_MODE (SET_DEST (elt)) != V4SImode) - return 0; - } - - for (i=1; i <= 18; i++) - { - elt = XVECEXP (op, 0, index++); - if (GET_CODE (elt) != SET - || GET_CODE (SET_SRC (elt)) != MEM - || ! memory_operand (SET_SRC (elt), DFmode) - || GET_CODE (SET_DEST (elt)) != REG - || GET_MODE (SET_DEST (elt)) != DFmode) - return 0; - } - - if (GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER - || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER - || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER - || GET_CODE (XVECEXP (op, 0, index++)) != CLOBBER - || GET_CODE (XVECEXP (op, 0, index++)) != USE) - return 0; - return 1; -}) - -;; Return 1 if OP is valid for a vrsave call, known to be a PARALLEL. -(define_predicate "vrsave_operation" - (match_code "parallel") -{ - int count = XVECLEN (op, 0); - unsigned int dest_regno, src_regno; - int i; - - if (count <= 1 - || GET_CODE (XVECEXP (op, 0, 0)) != SET - || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG - || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE - || XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPECV_SET_VRSAVE) - return 0; - - dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); - src_regno = REGNO (XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 1)); - - if (dest_regno != VRSAVE_REGNO || src_regno != VRSAVE_REGNO) - return 0; - - for (i = 1; i < count; i++) - { - rtx elt = XVECEXP (op, 0, i); - - if (GET_CODE (elt) != CLOBBER - && GET_CODE (elt) != SET) - return 0; - } - - return 1; -}) - -;; Return 1 if OP is valid for mfcr insn, known to be a PARALLEL. -(define_predicate "mfcr_operation" - (match_code "parallel") -{ - 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 if OP is valid for mtcrf insn, known to be a PARALLEL. -(define_predicate "mtcrf_operation" - (match_code "parallel") -{ - int count = XVECLEN (op, 0); - int i; - rtx src_reg; - - /* 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; - src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0); - - if (GET_CODE (src_reg) != REG - || GET_MODE (src_reg) != SImode - || ! INT_REGNO_P (REGNO (src_reg))) - return 0; - - for (i = 0; i < count; i++) - { - rtx exp = XVECEXP (op, 0, i); - rtx unspec; - int maskval; - - if (GET_CODE (exp) != SET - || GET_CODE (SET_DEST (exp)) != REG - || GET_MODE (SET_DEST (exp)) != CCmode - || ! CR_REGNO_P (REGNO (SET_DEST (exp)))) - return 0; - unspec = SET_SRC (exp); - maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp))); - - if (GET_CODE (unspec) != UNSPEC - || 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 - || INTVAL (XVECEXP (unspec, 0, 1)) != maskval) - return 0; - } - return 1; -}) - -;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL. -(define_predicate "lmw_operation" - (match_code "parallel") -{ - int count = XVECLEN (op, 0); - unsigned int dest_regno; - rtx src_addr; - unsigned int base_regno; - HOST_WIDE_INT offset; - 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_DEST (XVECEXP (op, 0, 0))) != REG - || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) - return 0; - - dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); - src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); - - if (dest_regno > 31 - || count != 32 - (int) dest_regno) - return 0; - - if (legitimate_indirect_address_p (src_addr, 0)) - { - offset = 0; - base_regno = REGNO (src_addr); - if (base_regno == 0) - return 0; - } - else if (rs6000_legitimate_offset_address_p (SImode, src_addr, false, false)) - { - offset = INTVAL (XEXP (src_addr, 1)); - base_regno = REGNO (XEXP (src_addr, 0)); - } - else - return 0; - - for (i = 0; i < count; i++) - { - rtx elt = XVECEXP (op, 0, i); - rtx newaddr; - rtx addr_reg; - HOST_WIDE_INT newoffset; - - if (GET_CODE (elt) != SET - || GET_CODE (SET_DEST (elt)) != REG - || GET_MODE (SET_DEST (elt)) != SImode - || REGNO (SET_DEST (elt)) != dest_regno + i - || GET_CODE (SET_SRC (elt)) != MEM - || GET_MODE (SET_SRC (elt)) != SImode) - return 0; - newaddr = XEXP (SET_SRC (elt), 0); - if (legitimate_indirect_address_p (newaddr, 0)) - { - newoffset = 0; - addr_reg = newaddr; - } - else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false)) - { - addr_reg = XEXP (newaddr, 0); - newoffset = INTVAL (XEXP (newaddr, 1)); - } - else - return 0; - if (REGNO (addr_reg) != base_regno - || newoffset != offset + 4 * i) - return 0; - } - - return 1; -}) - -;; Return 1 if OP is valid for stmw insn, known to be a PARALLEL. -(define_predicate "stmw_operation" - (match_code "parallel") -{ - int count = XVECLEN (op, 0); - unsigned int src_regno; - rtx dest_addr; - unsigned int base_regno; - HOST_WIDE_INT offset; - 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_DEST (XVECEXP (op, 0, 0))) != MEM - || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) - return 0; - - src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); - dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); - - if (src_regno > 31 - || count != 32 - (int) src_regno) - return 0; - - if (legitimate_indirect_address_p (dest_addr, 0)) - { - offset = 0; - base_regno = REGNO (dest_addr); - if (base_regno == 0) - return 0; - } - else if (rs6000_legitimate_offset_address_p (SImode, dest_addr, false, false)) - { - offset = INTVAL (XEXP (dest_addr, 1)); - base_regno = REGNO (XEXP (dest_addr, 0)); - } - else - return 0; - - for (i = 0; i < count; i++) - { - rtx elt = XVECEXP (op, 0, i); - rtx newaddr; - rtx addr_reg; - HOST_WIDE_INT newoffset; - - if (GET_CODE (elt) != SET - || GET_CODE (SET_SRC (elt)) != REG - || GET_MODE (SET_SRC (elt)) != SImode - || REGNO (SET_SRC (elt)) != src_regno + i - || GET_CODE (SET_DEST (elt)) != MEM - || GET_MODE (SET_DEST (elt)) != SImode) - return 0; - newaddr = XEXP (SET_DEST (elt), 0); - if (legitimate_indirect_address_p (newaddr, 0)) - { - newoffset = 0; - addr_reg = newaddr; - } - else if (rs6000_legitimate_offset_address_p (SImode, newaddr, false, false)) - { - addr_reg = XEXP (newaddr, 0); - newoffset = INTVAL (XEXP (newaddr, 1)); - } - else - return 0; - if (REGNO (addr_reg) != base_regno - || newoffset != offset + 4 * i) - return 0; - } - - return 1; -}) - -;; Return 1 if OP is a stack tie operand. -(define_predicate "tie_operand" - (match_code "parallel") -{ - return (GET_CODE (XVECEXP (op, 0, 0)) == SET - && GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) == MEM - && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode - && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx); -}) - -;; Match a small code model toc reference (or medium and large -;; model toc references before reload). -(define_predicate "small_toc_ref" - (match_code "unspec,plus") -{ - if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1))) - op = XEXP (op, 0); - - return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL; -}) diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000-builtin.def b/gcc-4.8.1/gcc/config/rs6000/rs6000-builtin.def deleted file mode 100644 index a545fe3e4..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000-builtin.def +++ /dev/null @@ -1,1440 +0,0 @@ -/* Builtin functions for rs6000/powerpc. - Copyright (C) 2009-2013 Free Software Foundation, Inc. - Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* Before including this file, some macros must be defined: - RS6000_BUILTIN_1 -- 1 arg builtins - RS6000_BUILTIN_2 -- 2 arg builtins - RS6000_BUILTIN_3 -- 3 arg builtins - RS6000_BUILTIN_A -- ABS builtins - RS6000_BUILTIN_D -- DST builtins - RS6000_BUILTIN_E -- SPE EVSEL builtins. - RS6000_BUILTIN_P -- Altivec and VSX predicate builtins - RS6000_BUILTIN_Q -- Paired floating point VSX predicate builtins - RS6000_BUILTIN_S -- SPE predicate builtins - RS6000_BUILTIN_X -- special builtins - - Each of the above macros takes 4 arguments: - ENUM Enumeration name - NAME String literal for the name - MASK Mask of bits that indicate which options enables the builtin - ATTR builtin attribute information. - ICODE Insn code of the function that implents the builtin. */ - -#ifndef RS6000_BUILTIN_1 - #error "RS6000_BUILTIN_1 is not defined." -#endif - -#ifndef RS6000_BUILTIN_2 - #error "RS6000_BUILTIN_2 is not defined." -#endif - -#ifndef RS6000_BUILTIN_3 - #error "RS6000_BUILTIN_3 is not defined." -#endif - -#ifndef RS6000_BUILTIN_A - #error "RS6000_BUILTIN_A is not defined." -#endif - -#ifndef RS6000_BUILTIN_D - #error "RS6000_BUILTIN_D is not defined." -#endif - -#ifndef RS6000_BUILTIN_E - #error "RS6000_BUILTIN_E is not defined." -#endif - -#ifndef RS6000_BUILTIN_P - #error "RS6000_BUILTIN_P is not defined." -#endif - -#ifndef RS6000_BUILTIN_Q - #error "RS6000_BUILTIN_Q is not defined." -#endif - -#ifndef RS6000_BUILTIN_S - #error "RS6000_BUILTIN_S is not defined." -#endif - -#ifndef RS6000_BUILTIN_X - #error "RS6000_BUILTIN_X is not defined." -#endif - -#ifndef BU_AV_1 -/* Define convenience macros using token pasting to allow fitting everything in - one line. */ - -/* Altivec convenience macros. */ -#define BU_ALTIVEC_1(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_1 (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_UNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_ALTIVEC_2(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_2 (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_BINARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_ALTIVEC_3(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_3 (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_TERNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_ALTIVEC_A(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_A (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_ABS), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_ALTIVEC_D(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_D (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_DST), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_ALTIVEC_P(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_P (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_PREDICATE), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_ALTIVEC_X(ENUM, NAME, ATTR) \ - RS6000_BUILTIN_X (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_SPECIAL), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_ALTIVEC_C(ENUM, NAME, ATTR) \ - RS6000_BUILTIN_X (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_altivec_" NAME, /* NAME */ \ - (RS6000_BTM_ALTIVEC /* MASK */ \ - | RS6000_BTM_CELL), \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_SPECIAL), \ - CODE_FOR_nothing) /* ICODE */ - -/* Altivec overloaded builtin function macros. */ -#define BU_ALTIVEC_OVERLOAD_1(ENUM, NAME) \ - RS6000_BUILTIN_1 (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_UNARY), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_ALTIVEC_OVERLOAD_2(ENUM, NAME) \ - RS6000_BUILTIN_2 (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_BINARY), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_ALTIVEC_OVERLOAD_3(ENUM, NAME) \ - RS6000_BUILTIN_3 (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_TERNARY), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_ALTIVEC_OVERLOAD_A(ENUM, NAME) \ - RS6000_BUILTIN_A (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_ABS), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_ALTIVEC_OVERLOAD_D(ENUM, NAME) \ - RS6000_BUILTIN_D (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_DST), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_ALTIVEC_OVERLOAD_P(ENUM, NAME) \ - RS6000_BUILTIN_P (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_PREDICATE), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_ALTIVEC_OVERLOAD_X(ENUM, NAME) \ - RS6000_BUILTIN_X (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_ALTIVEC, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_SPECIAL), \ - CODE_FOR_nothing) /* ICODE */ - -/* VSX convenience macros. */ -#define BU_VSX_1(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_1 (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_vsx_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_UNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_VSX_2(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_2 (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_vsx_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_BINARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_VSX_3(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_3 (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_vsx_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_TERNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_VSX_A(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_A (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_vsx_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_ABS), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_VSX_P(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_P (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_vsx_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_PREDICATE), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_VSX_X(ENUM, NAME, ATTR) \ - RS6000_BUILTIN_X (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_vsx_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_SPECIAL), \ - CODE_FOR_nothing) /* ICODE */ - -/* VSX overloaded builtin function macros. */ -#define BU_VSX_OVERLOAD_1(ENUM, NAME) \ - RS6000_BUILTIN_1 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_UNARY), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_VSX_OVERLOAD_2(ENUM, NAME) \ - RS6000_BUILTIN_2 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_BINARY), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_VSX_OVERLOAD_3(ENUM, NAME) \ - RS6000_BUILTIN_3 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_TERNARY), \ - CODE_FOR_nothing) /* ICODE */ - -/* xxpermdi and xxsldwi are overloaded functions, but had __builtin_vsx names - instead of __builtin_vec. */ -#define BU_VSX_OVERLOAD_3V(ENUM, NAME) \ - RS6000_BUILTIN_3 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vsx_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_TERNARY), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_VSX_OVERLOAD_X(ENUM, NAME) \ - RS6000_BUILTIN_X (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ - "__builtin_vec_" NAME, /* NAME */ \ - RS6000_BTM_VSX, /* MASK */ \ - (RS6000_BTC_OVERLOADED /* ATTR */ \ - | RS6000_BTC_SPECIAL), \ - CODE_FOR_nothing) /* ICODE */ - -/* SPE convenience macros. */ -#define BU_SPE_1(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_1 (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_spe_" NAME, /* NAME */ \ - RS6000_BTM_SPE, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_UNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_SPE_2(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_2 (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_spe_" NAME, /* NAME */ \ - RS6000_BTM_SPE, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_BINARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_SPE_3(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_3 (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_spe_" NAME, /* NAME */ \ - RS6000_BTM_SPE, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_TERNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_SPE_E(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_E (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_spe_" NAME, /* NAME */ \ - RS6000_BTM_SPE, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_EVSEL), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_SPE_P(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_S (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_spe_" NAME, /* NAME */ \ - RS6000_BTM_SPE, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_PREDICATE), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_SPE_X(ENUM, NAME, ATTR) \ - RS6000_BUILTIN_X (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_spe_" NAME, /* NAME */ \ - RS6000_BTM_SPE, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_SPECIAL), \ - CODE_FOR_nothing) /* ICODE */ - -/* Paired floating point convenience macros. */ -#define BU_PAIRED_1(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_1 (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_paired_" NAME, /* NAME */ \ - RS6000_BTM_PAIRED, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_UNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_PAIRED_2(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_2 (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_paired_" NAME, /* NAME */ \ - RS6000_BTM_PAIRED, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_BINARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_PAIRED_3(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_3 (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_paired_" NAME, /* NAME */ \ - RS6000_BTM_PAIRED, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_TERNARY), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_PAIRED_P(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_Q (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_paired_" NAME, /* NAME */ \ - RS6000_BTM_PAIRED, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_PREDICATE), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_PAIRED_X(ENUM, NAME, ATTR) \ - RS6000_BUILTIN_X (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_paired_" NAME, /* NAME */ \ - RS6000_BTM_PAIRED, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_SPECIAL), \ - CODE_FOR_nothing) /* ICODE */ - -#define BU_SPECIAL_X(ENUM, NAME, MASK, ATTR) \ - RS6000_BUILTIN_X (ENUM, /* ENUM */ \ - NAME, /* NAME */ \ - MASK, /* MASK */ \ - (ATTR | RS6000_BTC_SPECIAL), /* ATTR */ \ - CODE_FOR_nothing) /* ICODE */ -#endif - -/* Insure 0 is not a legitimate index. */ -BU_SPECIAL_X (RS6000_BUILTIN_NONE, NULL, 0, RS6000_BTC_MISC) - -/* 3 argument Altivec builtins. */ -BU_ALTIVEC_3 (VMADDFP, "vmaddfp", FP, fmav4sf4) -BU_ALTIVEC_3 (VMHADDSHS, "vmhaddshs", SAT, altivec_vmhaddshs) -BU_ALTIVEC_3 (VMHRADDSHS, "vmhraddshs", SAT, altivec_vmhraddshs) -BU_ALTIVEC_3 (VMLADDUHM, "vmladduhm", CONST, altivec_vmladduhm) -BU_ALTIVEC_3 (VMSUMUBM, "vmsumubm", CONST, altivec_vmsumubm) -BU_ALTIVEC_3 (VMSUMMBM, "vmsummbm", CONST, altivec_vmsummbm) -BU_ALTIVEC_3 (VMSUMUHM, "vmsumuhm", CONST, altivec_vmsumuhm) -BU_ALTIVEC_3 (VMSUMSHM, "vmsumshm", CONST, altivec_vmsumshm) -BU_ALTIVEC_3 (VMSUMUHS, "vmsumuhs", SAT, altivec_vmsumuhs) -BU_ALTIVEC_3 (VMSUMSHS, "vmsumshs", SAT, altivec_vmsumshs) -BU_ALTIVEC_3 (VNMSUBFP, "vnmsubfp", FP, nfmsv4sf4) -BU_ALTIVEC_3 (VPERM_2DF, "vperm_2df", CONST, altivec_vperm_v2df) -BU_ALTIVEC_3 (VPERM_2DI, "vperm_2di", CONST, altivec_vperm_v2di) -BU_ALTIVEC_3 (VPERM_4SF, "vperm_4sf", CONST, altivec_vperm_v4sf) -BU_ALTIVEC_3 (VPERM_4SI, "vperm_4si", CONST, altivec_vperm_v4si) -BU_ALTIVEC_3 (VPERM_8HI, "vperm_8hi", CONST, altivec_vperm_v8hi) -BU_ALTIVEC_3 (VPERM_16QI, "vperm_16qi", CONST, altivec_vperm_v16qi_uns) -BU_ALTIVEC_3 (VPERM_2DI_UNS, "vperm_2di_uns", CONST, altivec_vperm_v2di_uns) -BU_ALTIVEC_3 (VPERM_4SI_UNS, "vperm_4si_uns", CONST, altivec_vperm_v4si_uns) -BU_ALTIVEC_3 (VPERM_8HI_UNS, "vperm_8hi_uns", CONST, altivec_vperm_v8hi_uns) -BU_ALTIVEC_3 (VPERM_16QI_UNS, "vperm_16qi_uns", CONST, altivec_vperm_v16qi_uns) -BU_ALTIVEC_3 (VSEL_4SF, "vsel_4sf", CONST, vector_select_v4sf) -BU_ALTIVEC_3 (VSEL_4SI, "vsel_4si", CONST, vector_select_v4si) -BU_ALTIVEC_3 (VSEL_8HI, "vsel_8hi", CONST, vector_select_v8hi) -BU_ALTIVEC_3 (VSEL_16QI, "vsel_16qi", CONST, vector_select_v16qi) -BU_ALTIVEC_3 (VSEL_2DF, "vsel_2df", CONST, vector_select_v2df) -BU_ALTIVEC_3 (VSEL_2DI, "vsel_2di", CONST, vector_select_v2di) -BU_ALTIVEC_3 (VSEL_4SI_UNS, "vsel_4si_uns", CONST, vector_select_v4si_uns) -BU_ALTIVEC_3 (VSEL_8HI_UNS, "vsel_8hi_uns", CONST, vector_select_v8hi_uns) -BU_ALTIVEC_3 (VSEL_16QI_UNS, "vsel_16qi_uns", CONST, vector_select_v16qi_uns) -BU_ALTIVEC_3 (VSEL_2DI_UNS, "vsel_2di_uns", CONST, vector_select_v2di_uns) -BU_ALTIVEC_3 (VSLDOI_16QI, "vsldoi_16qi", CONST, altivec_vsldoi_v16qi) -BU_ALTIVEC_3 (VSLDOI_8HI, "vsldoi_8hi", CONST, altivec_vsldoi_v8hi) -BU_ALTIVEC_3 (VSLDOI_4SI, "vsldoi_4si", CONST, altivec_vsldoi_v4si) -BU_ALTIVEC_3 (VSLDOI_4SF, "vsldoi_4sf", CONST, altivec_vsldoi_v4sf) - -/* Altivec DST builtins. */ -BU_ALTIVEC_D (DST, "dst", MISC, altivec_dst) -BU_ALTIVEC_D (DSTT, "dstt", MISC, altivec_dstt) -BU_ALTIVEC_D (DSTST, "dstst", MISC, altivec_dstst) -BU_ALTIVEC_D (DSTSTT, "dststt", MISC, altivec_dststt) - -/* Altivec 2 argument builtin functions. */ -BU_ALTIVEC_2 (VADDUBM, "vaddubm", CONST, addv16qi3) -BU_ALTIVEC_2 (VADDUHM, "vadduhm", CONST, addv8hi3) -BU_ALTIVEC_2 (VADDUWM, "vadduwm", CONST, addv4si3) -BU_ALTIVEC_2 (VADDFP, "vaddfp", CONST, addv4sf3) -BU_ALTIVEC_2 (VADDCUW, "vaddcuw", CONST, altivec_vaddcuw) -BU_ALTIVEC_2 (VADDUBS, "vaddubs", CONST, altivec_vaddubs) -BU_ALTIVEC_2 (VADDSBS, "vaddsbs", CONST, altivec_vaddsbs) -BU_ALTIVEC_2 (VADDUHS, "vadduhs", CONST, altivec_vadduhs) -BU_ALTIVEC_2 (VADDSHS, "vaddshs", CONST, altivec_vaddshs) -BU_ALTIVEC_2 (VADDUWS, "vadduws", CONST, altivec_vadduws) -BU_ALTIVEC_2 (VADDSWS, "vaddsws", CONST, altivec_vaddsws) -BU_ALTIVEC_2 (VAND, "vand", CONST, andv4si3) -BU_ALTIVEC_2 (VANDC, "vandc", CONST, andcv4si3) -BU_ALTIVEC_2 (VAVGUB, "vavgub", CONST, altivec_vavgub) -BU_ALTIVEC_2 (VAVGSB, "vavgsb", CONST, altivec_vavgsb) -BU_ALTIVEC_2 (VAVGUH, "vavguh", CONST, altivec_vavguh) -BU_ALTIVEC_2 (VAVGSH, "vavgsh", CONST, altivec_vavgsh) -BU_ALTIVEC_2 (VAVGUW, "vavguw", CONST, altivec_vavguw) -BU_ALTIVEC_2 (VAVGSW, "vavgsw", CONST, altivec_vavgsw) -BU_ALTIVEC_2 (VCFUX, "vcfux", CONST, altivec_vcfux) -BU_ALTIVEC_2 (VCFSX, "vcfsx", CONST, altivec_vcfsx) -BU_ALTIVEC_2 (VCMPBFP, "vcmpbfp", CONST, altivec_vcmpbfp) -BU_ALTIVEC_2 (VCMPEQUB, "vcmpequb", CONST, vector_eqv16qi) -BU_ALTIVEC_2 (VCMPEQUH, "vcmpequh", CONST, vector_eqv8hi) -BU_ALTIVEC_2 (VCMPEQUW, "vcmpequw", CONST, vector_eqv4si) -BU_ALTIVEC_2 (VCMPEQFP, "vcmpeqfp", CONST, vector_eqv4sf) -BU_ALTIVEC_2 (VCMPGEFP, "vcmpgefp", CONST, vector_gev4sf) -BU_ALTIVEC_2 (VCMPGTUB, "vcmpgtub", CONST, vector_gtuv16qi) -BU_ALTIVEC_2 (VCMPGTSB, "vcmpgtsb", CONST, vector_gtv16qi) -BU_ALTIVEC_2 (VCMPGTUH, "vcmpgtuh", CONST, vector_gtuv8hi) -BU_ALTIVEC_2 (VCMPGTSH, "vcmpgtsh", CONST, vector_gtv8hi) -BU_ALTIVEC_2 (VCMPGTUW, "vcmpgtuw", CONST, vector_gtuv4si) -BU_ALTIVEC_2 (VCMPGTSW, "vcmpgtsw", CONST, vector_gtv4si) -BU_ALTIVEC_2 (VCMPGTFP, "vcmpgtfp", CONST, vector_gtv4sf) -BU_ALTIVEC_2 (VCTSXS, "vctsxs", CONST, altivec_vctsxs) -BU_ALTIVEC_2 (VCTUXS, "vctuxs", CONST, altivec_vctuxs) -BU_ALTIVEC_2 (VMAXUB, "vmaxub", CONST, umaxv16qi3) -BU_ALTIVEC_2 (VMAXSB, "vmaxsb", CONST, smaxv16qi3) -BU_ALTIVEC_2 (VMAXUH, "vmaxuh", CONST, umaxv8hi3) -BU_ALTIVEC_2 (VMAXSH, "vmaxsh", CONST, smaxv8hi3) -BU_ALTIVEC_2 (VMAXUW, "vmaxuw", CONST, umaxv4si3) -BU_ALTIVEC_2 (VMAXSW, "vmaxsw", CONST, smaxv4si3) -BU_ALTIVEC_2 (VMAXFP, "vmaxfp", CONST, smaxv4sf3) -BU_ALTIVEC_2 (VMRGHB, "vmrghb", CONST, altivec_vmrghb) -BU_ALTIVEC_2 (VMRGHH, "vmrghh", CONST, altivec_vmrghh) -BU_ALTIVEC_2 (VMRGHW, "vmrghw", CONST, altivec_vmrghw) -BU_ALTIVEC_2 (VMRGLB, "vmrglb", CONST, altivec_vmrglb) -BU_ALTIVEC_2 (VMRGLH, "vmrglh", CONST, altivec_vmrglh) -BU_ALTIVEC_2 (VMRGLW, "vmrglw", CONST, altivec_vmrglw) -BU_ALTIVEC_2 (VMINUB, "vminub", CONST, uminv16qi3) -BU_ALTIVEC_2 (VMINSB, "vminsb", CONST, sminv16qi3) -BU_ALTIVEC_2 (VMINUH, "vminuh", CONST, uminv8hi3) -BU_ALTIVEC_2 (VMINSH, "vminsh", CONST, sminv8hi3) -BU_ALTIVEC_2 (VMINUW, "vminuw", CONST, uminv4si3) -BU_ALTIVEC_2 (VMINSW, "vminsw", CONST, sminv4si3) -BU_ALTIVEC_2 (VMINFP, "vminfp", CONST, sminv4sf3) -BU_ALTIVEC_2 (VMULEUB, "vmuleub", CONST, vec_widen_umult_even_v16qi) -BU_ALTIVEC_2 (VMULEUB_UNS, "vmuleub_uns", CONST, vec_widen_umult_even_v16qi) -BU_ALTIVEC_2 (VMULESB, "vmulesb", CONST, vec_widen_smult_even_v16qi) -BU_ALTIVEC_2 (VMULEUH, "vmuleuh", CONST, vec_widen_umult_even_v8hi) -BU_ALTIVEC_2 (VMULEUH_UNS, "vmuleuh_uns", CONST, vec_widen_umult_even_v8hi) -BU_ALTIVEC_2 (VMULESH, "vmulesh", CONST, vec_widen_smult_even_v8hi) -BU_ALTIVEC_2 (VMULOUB, "vmuloub", CONST, vec_widen_umult_odd_v16qi) -BU_ALTIVEC_2 (VMULOUB_UNS, "vmuloub_uns", CONST, vec_widen_umult_odd_v16qi) -BU_ALTIVEC_2 (VMULOSB, "vmulosb", CONST, vec_widen_smult_odd_v16qi) -BU_ALTIVEC_2 (VMULOUH, "vmulouh", CONST, vec_widen_umult_odd_v8hi) -BU_ALTIVEC_2 (VMULOUH_UNS, "vmulouh_uns", CONST, vec_widen_umult_odd_v8hi) -BU_ALTIVEC_2 (VMULOSH, "vmulosh", CONST, vec_widen_smult_odd_v8hi) -BU_ALTIVEC_2 (VNOR, "vnor", CONST, norv4si3) -BU_ALTIVEC_2 (VOR, "vor", CONST, iorv4si3) -BU_ALTIVEC_2 (VPKUHUM, "vpkuhum", CONST, altivec_vpkuhum) -BU_ALTIVEC_2 (VPKUWUM, "vpkuwum", CONST, altivec_vpkuwum) -BU_ALTIVEC_2 (VPKPX, "vpkpx", CONST, altivec_vpkpx) -BU_ALTIVEC_2 (VPKSHSS, "vpkshss", CONST, altivec_vpkshss) -BU_ALTIVEC_2 (VPKSWSS, "vpkswss", CONST, altivec_vpkswss) -BU_ALTIVEC_2 (VPKUHUS, "vpkuhus", CONST, altivec_vpkuhus) -BU_ALTIVEC_2 (VPKSHUS, "vpkshus", CONST, altivec_vpkshus) -BU_ALTIVEC_2 (VPKUWUS, "vpkuwus", CONST, altivec_vpkuwus) -BU_ALTIVEC_2 (VPKSWUS, "vpkswus", CONST, altivec_vpkswus) -BU_ALTIVEC_2 (VRECIPFP, "vrecipdivfp", CONST, recipv4sf3) -BU_ALTIVEC_2 (VRLB, "vrlb", CONST, vrotlv16qi3) -BU_ALTIVEC_2 (VRLH, "vrlh", CONST, vrotlv8hi3) -BU_ALTIVEC_2 (VRLW, "vrlw", CONST, vrotlv4si3) -BU_ALTIVEC_2 (VSLB, "vslb", CONST, vashlv16qi3) -BU_ALTIVEC_2 (VSLH, "vslh", CONST, vashlv8hi3) -BU_ALTIVEC_2 (VSLW, "vslw", CONST, vashlv4si3) -BU_ALTIVEC_2 (VSL, "vsl", CONST, altivec_vsl) -BU_ALTIVEC_2 (VSLO, "vslo", CONST, altivec_vslo) -BU_ALTIVEC_2 (VSPLTB, "vspltb", CONST, altivec_vspltb) -BU_ALTIVEC_2 (VSPLTH, "vsplth", CONST, altivec_vsplth) -BU_ALTIVEC_2 (VSPLTW, "vspltw", CONST, altivec_vspltw) -BU_ALTIVEC_2 (VSRB, "vsrb", CONST, vlshrv16qi3) -BU_ALTIVEC_2 (VSRH, "vsrh", CONST, vlshrv8hi3) -BU_ALTIVEC_2 (VSRW, "vsrw", CONST, vlshrv4si3) -BU_ALTIVEC_2 (VSRAB, "vsrab", CONST, vashrv16qi3) -BU_ALTIVEC_2 (VSRAH, "vsrah", CONST, vashrv8hi3) -BU_ALTIVEC_2 (VSRAW, "vsraw", CONST, vashrv4si3) -BU_ALTIVEC_2 (VSR, "vsr", CONST, altivec_vsr) -BU_ALTIVEC_2 (VSRO, "vsro", CONST, altivec_vsro) -BU_ALTIVEC_2 (VSUBUBM, "vsububm", CONST, subv16qi3) -BU_ALTIVEC_2 (VSUBUHM, "vsubuhm", CONST, subv8hi3) -BU_ALTIVEC_2 (VSUBUWM, "vsubuwm", CONST, subv4si3) -BU_ALTIVEC_2 (VSUBFP, "vsubfp", CONST, subv4sf3) -BU_ALTIVEC_2 (VSUBCUW, "vsubcuw", CONST, altivec_vsubcuw) -BU_ALTIVEC_2 (VSUBUBS, "vsububs", CONST, altivec_vsububs) -BU_ALTIVEC_2 (VSUBSBS, "vsubsbs", CONST, altivec_vsubsbs) -BU_ALTIVEC_2 (VSUBUHS, "vsubuhs", CONST, altivec_vsubuhs) -BU_ALTIVEC_2 (VSUBSHS, "vsubshs", CONST, altivec_vsubshs) -BU_ALTIVEC_2 (VSUBUWS, "vsubuws", CONST, altivec_vsubuws) -BU_ALTIVEC_2 (VSUBSWS, "vsubsws", CONST, altivec_vsubsws) -BU_ALTIVEC_2 (VSUM4UBS, "vsum4ubs", CONST, altivec_vsum4ubs) -BU_ALTIVEC_2 (VSUM4SBS, "vsum4sbs", CONST, altivec_vsum4sbs) -BU_ALTIVEC_2 (VSUM4SHS, "vsum4shs", CONST, altivec_vsum4shs) -BU_ALTIVEC_2 (VSUM2SWS, "vsum2sws", CONST, altivec_vsum2sws) -BU_ALTIVEC_2 (VSUMSWS, "vsumsws", CONST, altivec_vsumsws) -BU_ALTIVEC_2 (VXOR, "vxor", CONST, xorv4si3) -BU_ALTIVEC_2 (COPYSIGN_V4SF, "copysignfp", CONST, vector_copysignv4sf3) - -/* Altivec ABS functions. */ -BU_ALTIVEC_A (ABS_V4SI, "abs_v4si", CONST, absv4si2) -BU_ALTIVEC_A (ABS_V8HI, "abs_v8hi", CONST, absv8hi2) -BU_ALTIVEC_A (ABS_V4SF, "abs_v4sf", CONST, absv4sf2) -BU_ALTIVEC_A (ABS_V16QI, "abs_v16qi", CONST, absv16qi2) -BU_ALTIVEC_A (ABSS_V4SI, "abss_v4si", SAT, altivec_abss_v4si) -BU_ALTIVEC_A (ABSS_V8HI, "abss_v8hi", SAT, altivec_abss_v8hi) -BU_ALTIVEC_A (ABSS_V16QI, "abss_v16qi", SAT, altivec_abss_v16qi) - -/* 1 argument Altivec builtin functions. */ -BU_ALTIVEC_1 (VEXPTEFP, "vexptefp", FP, altivec_vexptefp) -BU_ALTIVEC_1 (VLOGEFP, "vlogefp", FP, altivec_vlogefp) -BU_ALTIVEC_1 (VREFP, "vrefp", FP, rev4sf2) -BU_ALTIVEC_1 (VRFIM, "vrfim", FP, vector_floorv4sf2) -BU_ALTIVEC_1 (VRFIN, "vrfin", FP, altivec_vrfin) -BU_ALTIVEC_1 (VRFIP, "vrfip", FP, vector_ceilv4sf2) -BU_ALTIVEC_1 (VRFIZ, "vrfiz", FP, vector_btruncv4sf2) -BU_ALTIVEC_1 (VRSQRTFP, "vrsqrtfp", FP, rsqrtv4sf2) -BU_ALTIVEC_1 (VRSQRTEFP, "vrsqrtefp", FP, rsqrtev4sf2) -BU_ALTIVEC_1 (VSPLTISB, "vspltisb", CONST, altivec_vspltisb) -BU_ALTIVEC_1 (VSPLTISH, "vspltish", CONST, altivec_vspltish) -BU_ALTIVEC_1 (VSPLTISW, "vspltisw", CONST, altivec_vspltisw) -BU_ALTIVEC_1 (VUPKHSB, "vupkhsb", CONST, altivec_vupkhsb) -BU_ALTIVEC_1 (VUPKHPX, "vupkhpx", CONST, altivec_vupkhpx) -BU_ALTIVEC_1 (VUPKHSH, "vupkhsh", CONST, altivec_vupkhsh) -BU_ALTIVEC_1 (VUPKLSB, "vupklsb", CONST, altivec_vupklsb) -BU_ALTIVEC_1 (VUPKLPX, "vupklpx", CONST, altivec_vupklpx) -BU_ALTIVEC_1 (VUPKLSH, "vupklsh", CONST, altivec_vupklsh) - -BU_ALTIVEC_1 (FLOAT_V4SI_V4SF, "float_sisf", FP, floatv4siv4sf2) -BU_ALTIVEC_1 (UNSFLOAT_V4SI_V4SF, "uns_float_sisf", FP, floatunsv4siv4sf2) -BU_ALTIVEC_1 (FIX_V4SF_V4SI, "fix_sfsi", FP, fix_truncv4sfv4si2) -BU_ALTIVEC_1 (FIXUNS_V4SF_V4SI, "fixuns_sfsi", FP, fixuns_truncv4sfv4si2) - -/* Altivec predicate functions. */ -BU_ALTIVEC_P (VCMPBFP_P, "vcmpbfp_p", CONST, altivec_vcmpbfp_p) -BU_ALTIVEC_P (VCMPEQFP_P, "vcmpeqfp_p", CONST, vector_eq_v4sf_p) -BU_ALTIVEC_P (VCMPGEFP_P, "vcmpgefp_p", CONST, vector_ge_v4sf_p) -BU_ALTIVEC_P (VCMPGTFP_P, "vcmpgtfp_p", CONST, vector_gt_v4sf_p) -BU_ALTIVEC_P (VCMPEQUW_P, "vcmpequw_p", CONST, vector_eq_v4si_p) -BU_ALTIVEC_P (VCMPGTSW_P, "vcmpgtsw_p", CONST, vector_gt_v4si_p) -BU_ALTIVEC_P (VCMPGTUW_P, "vcmpgtuw_p", CONST, vector_gtu_v4si_p) -BU_ALTIVEC_P (VCMPEQUH_P, "vcmpequh_p", CONST, vector_eq_v8hi_p) -BU_ALTIVEC_P (VCMPGTSH_P, "vcmpgtsh_p", CONST, vector_gt_v8hi_p) -BU_ALTIVEC_P (VCMPGTUH_P, "vcmpgtuh_p", CONST, vector_gtu_v8hi_p) -BU_ALTIVEC_P (VCMPEQUB_P, "vcmpequb_p", CONST, vector_eq_v16qi_p) -BU_ALTIVEC_P (VCMPGTSB_P, "vcmpgtsb_p", CONST, vector_gt_v16qi_p) -BU_ALTIVEC_P (VCMPGTUB_P, "vcmpgtub_p", CONST, vector_gtu_v16qi_p) - -/* AltiVec builtins that are handled as special cases. */ -BU_ALTIVEC_X (ST_INTERNAL_4si, "st_internal_4si", MEM) -BU_ALTIVEC_X (LD_INTERNAL_4si, "ld_internal_4si", MEM) -BU_ALTIVEC_X (ST_INTERNAL_8hi, "st_internal_8hi", MEM) -BU_ALTIVEC_X (LD_INTERNAL_8hi, "ld_internal_8hi", MEM) -BU_ALTIVEC_X (ST_INTERNAL_16qi, "st_internal_16qi", MEM) -BU_ALTIVEC_X (LD_INTERNAL_16qi, "ld_internal_16qi", MEM) -BU_ALTIVEC_X (ST_INTERNAL_4sf, "st_internal_16qi", MEM) -BU_ALTIVEC_X (LD_INTERNAL_4sf, "ld_internal_4sf", MEM) -BU_ALTIVEC_X (ST_INTERNAL_2df, "st_internal_4sf", MEM) -BU_ALTIVEC_X (LD_INTERNAL_2df, "ld_internal_2df", MEM) -BU_ALTIVEC_X (ST_INTERNAL_2di, "st_internal_2di", MEM) -BU_ALTIVEC_X (LD_INTERNAL_2di, "ld_internal_2di", MEM) -BU_ALTIVEC_X (MTVSCR, "mtvscr", MISC) -BU_ALTIVEC_X (MFVSCR, "mfvscr", MISC) -BU_ALTIVEC_X (DSSALL, "dssall", MISC) -BU_ALTIVEC_X (DSS, "dss", MISC) -BU_ALTIVEC_X (LVSL, "lvsl", MEM) -BU_ALTIVEC_X (LVSR, "lvsr", MEM) -BU_ALTIVEC_X (LVEBX, "lvebx", MEM) -BU_ALTIVEC_X (LVEHX, "lvehx", MEM) -BU_ALTIVEC_X (LVEWX, "lvewx", MEM) -BU_ALTIVEC_X (LVXL, "lvxl", MEM) -BU_ALTIVEC_X (LVX, "lvx", MEM) -BU_ALTIVEC_X (STVX, "stvx", MEM) -BU_ALTIVEC_C (LVLX, "lvlx", MEM) -BU_ALTIVEC_C (LVLXL, "lvlxl", MEM) -BU_ALTIVEC_C (LVRX, "lvrx", MEM) -BU_ALTIVEC_C (LVRXL, "lvrxl", MEM) -BU_ALTIVEC_X (STVEBX, "stvebx", MEM) -BU_ALTIVEC_X (STVEHX, "stvehx", MEM) -BU_ALTIVEC_X (STVEWX, "stvewx", MEM) -BU_ALTIVEC_X (STVXL, "stvxl", MEM) -BU_ALTIVEC_C (STVLX, "stvlx", MEM) -BU_ALTIVEC_C (STVLXL, "stvlxl", MEM) -BU_ALTIVEC_C (STVRX, "stvrx", MEM) -BU_ALTIVEC_C (STVRXL, "stvrxl", MEM) -BU_ALTIVEC_X (MASK_FOR_LOAD, "mask_for_load", MISC) -BU_ALTIVEC_X (MASK_FOR_STORE, "mask_for_store", MISC) -BU_ALTIVEC_X (VEC_INIT_V4SI, "vec_init_v4si", CONST) -BU_ALTIVEC_X (VEC_INIT_V8HI, "vec_init_v8hi", CONST) -BU_ALTIVEC_X (VEC_INIT_V16QI, "vec_init_v16qi", CONST) -BU_ALTIVEC_X (VEC_INIT_V4SF, "vec_init_v4sf", CONST) -BU_ALTIVEC_X (VEC_SET_V4SI, "vec_set_v4si", CONST) -BU_ALTIVEC_X (VEC_SET_V8HI, "vec_set_v8hi", CONST) -BU_ALTIVEC_X (VEC_SET_V16QI, "vec_set_v16qi", CONST) -BU_ALTIVEC_X (VEC_SET_V4SF, "vec_set_v4sf", CONST) -BU_ALTIVEC_X (VEC_EXT_V4SI, "vec_ext_v4si", CONST) -BU_ALTIVEC_X (VEC_EXT_V8HI, "vec_ext_v8hi", CONST) -BU_ALTIVEC_X (VEC_EXT_V16QI, "vec_ext_v16qi", CONST) -BU_ALTIVEC_X (VEC_EXT_V4SF, "vec_ext_v4sf", CONST) - -/* Altivec overloaded builtins. */ -/* For now, don't set the classification for overloaded functions. - The function should be converted to the type specific instruction - before we get to the point about classifying the builtin type. */ - -/* 3 argument Altivec overloaded builtins. */ -BU_ALTIVEC_OVERLOAD_3 (MADD, "madd") -BU_ALTIVEC_OVERLOAD_3 (MADDS, "madds") -BU_ALTIVEC_OVERLOAD_3 (MLADD, "mladd") -BU_ALTIVEC_OVERLOAD_3 (MRADDS, "mradds") -BU_ALTIVEC_OVERLOAD_3 (MSUM, "msum") -BU_ALTIVEC_OVERLOAD_3 (MSUMS, "msums") -BU_ALTIVEC_OVERLOAD_3 (NMSUB, "nmsub") -BU_ALTIVEC_OVERLOAD_3 (PERM, "perm") -BU_ALTIVEC_OVERLOAD_3 (SEL, "sel") -BU_ALTIVEC_OVERLOAD_3 (VMSUMMBM, "vmsummbm") -BU_ALTIVEC_OVERLOAD_3 (VMSUMSHM, "vmsumshm") -BU_ALTIVEC_OVERLOAD_3 (VMSUMSHS, "vmsumshs") -BU_ALTIVEC_OVERLOAD_3 (VMSUMUBM, "vmsumubm") -BU_ALTIVEC_OVERLOAD_3 (VMSUMUHM, "vmsumuhm") -BU_ALTIVEC_OVERLOAD_3 (VMSUMUHS, "vmsumuhs") - -/* Altivec DST overloaded builtins. */ -BU_ALTIVEC_OVERLOAD_D (DST, "dst") -BU_ALTIVEC_OVERLOAD_D (DSTT, "dstt") -BU_ALTIVEC_OVERLOAD_D (DSTST, "dstst") -BU_ALTIVEC_OVERLOAD_D (DSTSTT, "dststt") - -/* 2 argument Altivec overloaded builtins. */ -BU_ALTIVEC_OVERLOAD_2 (ADD, "add") -BU_ALTIVEC_OVERLOAD_2 (ADDC, "addc") -BU_ALTIVEC_OVERLOAD_2 (ADDS, "adds") -BU_ALTIVEC_OVERLOAD_2 (AND, "and") -BU_ALTIVEC_OVERLOAD_2 (ANDC, "andc") -BU_ALTIVEC_OVERLOAD_2 (AVG, "avg") -BU_ALTIVEC_OVERLOAD_2 (CMPB, "cmpb") -BU_ALTIVEC_OVERLOAD_2 (CMPEQ, "cmpeq") -BU_ALTIVEC_OVERLOAD_2 (CMPGE, "cmpge") -BU_ALTIVEC_OVERLOAD_2 (CMPGT, "cmpgt") -BU_ALTIVEC_OVERLOAD_2 (CMPLE, "cmple") -BU_ALTIVEC_OVERLOAD_2 (CMPLT, "cmplt") -BU_ALTIVEC_OVERLOAD_2 (COPYSIGN, "copysign") -BU_ALTIVEC_OVERLOAD_2 (MAX, "max") -BU_ALTIVEC_OVERLOAD_2 (MERGEH, "mergeh") -BU_ALTIVEC_OVERLOAD_2 (MERGEL, "mergel") -BU_ALTIVEC_OVERLOAD_2 (MIN, "min") -BU_ALTIVEC_OVERLOAD_2 (MULE, "mule") -BU_ALTIVEC_OVERLOAD_2 (MULO, "mulo") -BU_ALTIVEC_OVERLOAD_2 (NOR, "nor") -BU_ALTIVEC_OVERLOAD_2 (OR, "or") -BU_ALTIVEC_OVERLOAD_2 (PACK, "pack") -BU_ALTIVEC_OVERLOAD_2 (PACKPX, "packpx") -BU_ALTIVEC_OVERLOAD_2 (PACKS, "packs") -BU_ALTIVEC_OVERLOAD_2 (PACKSU, "packsu") -BU_ALTIVEC_OVERLOAD_2 (RECIP, "recipdiv") -BU_ALTIVEC_OVERLOAD_2 (RL, "rl") -BU_ALTIVEC_OVERLOAD_2 (SL, "sl") -BU_ALTIVEC_OVERLOAD_2 (SLL, "sll") -BU_ALTIVEC_OVERLOAD_2 (SLO, "slo") -BU_ALTIVEC_OVERLOAD_2 (SR, "sr") -BU_ALTIVEC_OVERLOAD_2 (SRA, "sra") -BU_ALTIVEC_OVERLOAD_2 (SRL, "srl") -BU_ALTIVEC_OVERLOAD_2 (SRO, "sro") -BU_ALTIVEC_OVERLOAD_2 (SUB, "sub") -BU_ALTIVEC_OVERLOAD_2 (SUBC, "subc") -BU_ALTIVEC_OVERLOAD_2 (SUBS, "subs") -BU_ALTIVEC_OVERLOAD_2 (SUM2S, "sum2s") -BU_ALTIVEC_OVERLOAD_2 (SUM4S, "sum4s") -BU_ALTIVEC_OVERLOAD_2 (SUMS, "sums") -BU_ALTIVEC_OVERLOAD_2 (VADDFP, "vaddfp") -BU_ALTIVEC_OVERLOAD_2 (VADDSBS, "vaddsbs") -BU_ALTIVEC_OVERLOAD_2 (VADDSHS, "vaddshs") -BU_ALTIVEC_OVERLOAD_2 (VADDSWS, "vaddsws") -BU_ALTIVEC_OVERLOAD_2 (VADDUBM, "vaddubm") -BU_ALTIVEC_OVERLOAD_2 (VADDUBS, "vaddubs") -BU_ALTIVEC_OVERLOAD_2 (VADDUHM, "vadduhm") -BU_ALTIVEC_OVERLOAD_2 (VADDUHS, "vadduhs") -BU_ALTIVEC_OVERLOAD_2 (VADDUWM, "vadduwm") -BU_ALTIVEC_OVERLOAD_2 (VADDUWS, "vadduws") -BU_ALTIVEC_OVERLOAD_2 (VAVGSB, "vavgsb") -BU_ALTIVEC_OVERLOAD_2 (VAVGSH, "vavgsh") -BU_ALTIVEC_OVERLOAD_2 (VAVGSW, "vavgsw") -BU_ALTIVEC_OVERLOAD_2 (VAVGUB, "vavgub") -BU_ALTIVEC_OVERLOAD_2 (VAVGUH, "vavguh") -BU_ALTIVEC_OVERLOAD_2 (VAVGUW, "vavguw") -BU_ALTIVEC_OVERLOAD_2 (VCMPEQFP, "vcmpeqfp") -BU_ALTIVEC_OVERLOAD_2 (VCMPEQUB, "vcmpequb") -BU_ALTIVEC_OVERLOAD_2 (VCMPEQUH, "vcmpequh") -BU_ALTIVEC_OVERLOAD_2 (VCMPEQUW, "vcmpequw") -BU_ALTIVEC_OVERLOAD_2 (VCMPGTFP, "vcmpgtfp") -BU_ALTIVEC_OVERLOAD_2 (VCMPGTSB, "vcmpgtsb") -BU_ALTIVEC_OVERLOAD_2 (VCMPGTSH, "vcmpgtsh") -BU_ALTIVEC_OVERLOAD_2 (VCMPGTSW, "vcmpgtsw") -BU_ALTIVEC_OVERLOAD_2 (VCMPGTUB, "vcmpgtub") -BU_ALTIVEC_OVERLOAD_2 (VCMPGTUH, "vcmpgtuh") -BU_ALTIVEC_OVERLOAD_2 (VCMPGTUW, "vcmpgtuw") -BU_ALTIVEC_OVERLOAD_2 (VMAXFP, "vmaxfp") -BU_ALTIVEC_OVERLOAD_2 (VMAXSB, "vmaxsb") -BU_ALTIVEC_OVERLOAD_2 (VMAXSH, "vmaxsh") -BU_ALTIVEC_OVERLOAD_2 (VMAXSW, "vmaxsw") -BU_ALTIVEC_OVERLOAD_2 (VMAXUB, "vmaxub") -BU_ALTIVEC_OVERLOAD_2 (VMAXUH, "vmaxuh") -BU_ALTIVEC_OVERLOAD_2 (VMAXUW, "vmaxuw") -BU_ALTIVEC_OVERLOAD_2 (VMINFP, "vminfp") -BU_ALTIVEC_OVERLOAD_2 (VMINSB, "vminsb") -BU_ALTIVEC_OVERLOAD_2 (VMINSH, "vminsh") -BU_ALTIVEC_OVERLOAD_2 (VMINSW, "vminsw") -BU_ALTIVEC_OVERLOAD_2 (VMINUB, "vminub") -BU_ALTIVEC_OVERLOAD_2 (VMINUH, "vminuh") -BU_ALTIVEC_OVERLOAD_2 (VMINUW, "vminuw") -BU_ALTIVEC_OVERLOAD_2 (VMRGHB, "vmrghb") -BU_ALTIVEC_OVERLOAD_2 (VMRGHH, "vmrghh") -BU_ALTIVEC_OVERLOAD_2 (VMRGHW, "vmrghw") -BU_ALTIVEC_OVERLOAD_2 (VMRGLB, "vmrglb") -BU_ALTIVEC_OVERLOAD_2 (VMRGLH, "vmrglh") -BU_ALTIVEC_OVERLOAD_2 (VMRGLW, "vmrglw") -BU_ALTIVEC_OVERLOAD_2 (VMULESB, "vmulesb") -BU_ALTIVEC_OVERLOAD_2 (VMULESH, "vmulesh") -BU_ALTIVEC_OVERLOAD_2 (VMULEUB, "vmuleub") -BU_ALTIVEC_OVERLOAD_2 (VMULEUH, "vmuleuh") -BU_ALTIVEC_OVERLOAD_2 (VMULOSB, "vmulosb") -BU_ALTIVEC_OVERLOAD_2 (VMULOSH, "vmulosh") -BU_ALTIVEC_OVERLOAD_2 (VMULOUB, "vmuloub") -BU_ALTIVEC_OVERLOAD_2 (VMULOUH, "vmulouh") -BU_ALTIVEC_OVERLOAD_2 (VPKSHSS, "vpkshss") -BU_ALTIVEC_OVERLOAD_2 (VPKSHUS, "vpkshus") -BU_ALTIVEC_OVERLOAD_2 (VPKSWSS, "vpkswss") -BU_ALTIVEC_OVERLOAD_2 (VPKSWUS, "vpkswus") -BU_ALTIVEC_OVERLOAD_2 (VPKUHUM, "vpkuhum") -BU_ALTIVEC_OVERLOAD_2 (VPKUHUS, "vpkuhus") -BU_ALTIVEC_OVERLOAD_2 (VPKUWUM, "vpkuwum") -BU_ALTIVEC_OVERLOAD_2 (VPKUWUS, "vpkuwus") -BU_ALTIVEC_OVERLOAD_2 (VRLB, "vrlb") -BU_ALTIVEC_OVERLOAD_2 (VRLH, "vrlh") -BU_ALTIVEC_OVERLOAD_2 (VRLW, "vrlw") -BU_ALTIVEC_OVERLOAD_2 (VSLB, "vslb") -BU_ALTIVEC_OVERLOAD_2 (VSLH, "vslh") -BU_ALTIVEC_OVERLOAD_2 (VSLW, "vslw") -BU_ALTIVEC_OVERLOAD_2 (VSRAB, "vsrab") -BU_ALTIVEC_OVERLOAD_2 (VSRAH, "vsrah") -BU_ALTIVEC_OVERLOAD_2 (VSRAW, "vsraw") -BU_ALTIVEC_OVERLOAD_2 (VSRB, "vsrb") -BU_ALTIVEC_OVERLOAD_2 (VSRH, "vsrh") -BU_ALTIVEC_OVERLOAD_2 (VSRW, "vsrw") -BU_ALTIVEC_OVERLOAD_2 (VSUBFP, "vsubfp") -BU_ALTIVEC_OVERLOAD_2 (VSUBSBS, "vsubsbs") -BU_ALTIVEC_OVERLOAD_2 (VSUBSHS, "vsubshs") -BU_ALTIVEC_OVERLOAD_2 (VSUBSWS, "vsubsws") -BU_ALTIVEC_OVERLOAD_2 (VSUBUBM, "vsububm") -BU_ALTIVEC_OVERLOAD_2 (VSUBUBS, "vsububs") -BU_ALTIVEC_OVERLOAD_2 (VSUBUHM, "vsubuhm") -BU_ALTIVEC_OVERLOAD_2 (VSUBUHS, "vsubuhs") -BU_ALTIVEC_OVERLOAD_2 (VSUBUWM, "vsubuwm") -BU_ALTIVEC_OVERLOAD_2 (VSUBUWS, "vsubuws") -BU_ALTIVEC_OVERLOAD_2 (VSUM4SBS, "vsum4sbs") -BU_ALTIVEC_OVERLOAD_2 (VSUM4SHS, "vsum4shs") -BU_ALTIVEC_OVERLOAD_2 (VSUM4UBS, "vsum4ubs") -BU_ALTIVEC_OVERLOAD_2 (XOR, "xor") - -/* 1 argument Altivec overloaded functions. */ -BU_ALTIVEC_OVERLOAD_1 (ABS, "abs") -BU_ALTIVEC_OVERLOAD_1 (ABSS, "abss") -BU_ALTIVEC_OVERLOAD_1 (CEIL, "ceil") -BU_ALTIVEC_OVERLOAD_1 (EXPTE, "expte") -BU_ALTIVEC_OVERLOAD_1 (FLOOR, "floor") -BU_ALTIVEC_OVERLOAD_1 (LOGE, "loge") -BU_ALTIVEC_OVERLOAD_1 (MTVSCR, "mtvscr") -BU_ALTIVEC_OVERLOAD_1 (NEARBYINT, "nearbyint") -BU_ALTIVEC_OVERLOAD_1 (RE, "re") -BU_ALTIVEC_OVERLOAD_1 (RINT, "rint") -BU_ALTIVEC_OVERLOAD_1 (ROUND, "round") -BU_ALTIVEC_OVERLOAD_1 (RSQRT, "rsqrt") -BU_ALTIVEC_OVERLOAD_1 (RSQRTE, "rsqrte") -BU_ALTIVEC_OVERLOAD_1 (SQRT, "sqrt") -BU_ALTIVEC_OVERLOAD_1 (TRUNC, "trunc") -BU_ALTIVEC_OVERLOAD_1 (UNPACKH, "unpackh") -BU_ALTIVEC_OVERLOAD_1 (UNPACKL, "unpackl") -BU_ALTIVEC_OVERLOAD_1 (VUPKHPX, "vupkhpx") -BU_ALTIVEC_OVERLOAD_1 (VUPKHSB, "vupkhsb") -BU_ALTIVEC_OVERLOAD_1 (VUPKHSH, "vupkhsh") -BU_ALTIVEC_OVERLOAD_1 (VUPKLPX, "vupklpx") -BU_ALTIVEC_OVERLOAD_1 (VUPKLSB, "vupklsb") -BU_ALTIVEC_OVERLOAD_1 (VUPKLSH, "vupklsh") - -/* Overloaded altivec predicates. */ -BU_ALTIVEC_OVERLOAD_P (VCMPEQ_P, "vcmpeq_p") -BU_ALTIVEC_OVERLOAD_P (VCMPGT_P, "vcmpgt_p") -BU_ALTIVEC_OVERLOAD_P (VCMPGE_P, "vcmpge_p") - -/* Overloaded Altivec builtins that are handled as special cases. */ -BU_ALTIVEC_OVERLOAD_X (CTF, "ctf") -BU_ALTIVEC_OVERLOAD_X (CTS, "cts") -BU_ALTIVEC_OVERLOAD_X (CTU, "ctu") -BU_ALTIVEC_OVERLOAD_X (EXTRACT, "extract") -BU_ALTIVEC_OVERLOAD_X (INSERT, "insert") -BU_ALTIVEC_OVERLOAD_X (LD, "ld") -BU_ALTIVEC_OVERLOAD_X (LDE, "lde") -BU_ALTIVEC_OVERLOAD_X (LDL, "ldl") -BU_ALTIVEC_OVERLOAD_X (LVEBX, "lvebx") -BU_ALTIVEC_OVERLOAD_X (LVEHX, "lvehx") -BU_ALTIVEC_OVERLOAD_X (LVEWX, "lvewx") -BU_ALTIVEC_OVERLOAD_X (LVLX, "lvlx") -BU_ALTIVEC_OVERLOAD_X (LVLXL, "lvlxl") -BU_ALTIVEC_OVERLOAD_X (LVRX, "lvrx") -BU_ALTIVEC_OVERLOAD_X (LVRXL, "lvrxl") -BU_ALTIVEC_OVERLOAD_X (LVSL, "lvsl") -BU_ALTIVEC_OVERLOAD_X (LVSR, "lvsr") -BU_ALTIVEC_OVERLOAD_X (PROMOTE, "promote") -BU_ALTIVEC_OVERLOAD_X (SLD, "sld") -BU_ALTIVEC_OVERLOAD_X (SPLAT, "splat") -BU_ALTIVEC_OVERLOAD_X (SPLATS, "splats") -BU_ALTIVEC_OVERLOAD_X (ST, "st") -BU_ALTIVEC_OVERLOAD_X (STE, "ste") -BU_ALTIVEC_OVERLOAD_X (STEP, "step") -BU_ALTIVEC_OVERLOAD_X (STL, "stl") -BU_ALTIVEC_OVERLOAD_X (STVEBX, "stvebx") -BU_ALTIVEC_OVERLOAD_X (STVEHX, "stvehx") -BU_ALTIVEC_OVERLOAD_X (STVEWX, "stvewx") -BU_ALTIVEC_OVERLOAD_X (STVLX, "stvlx") -BU_ALTIVEC_OVERLOAD_X (STVLXL, "stvlxl") -BU_ALTIVEC_OVERLOAD_X (STVRX, "stvrx") -BU_ALTIVEC_OVERLOAD_X (STVRXL, "stvrxl") -BU_ALTIVEC_OVERLOAD_X (VCFSX, "vcfsx") -BU_ALTIVEC_OVERLOAD_X (VCFUX, "vcfux") -BU_ALTIVEC_OVERLOAD_X (VSPLTB, "vspltb") -BU_ALTIVEC_OVERLOAD_X (VSPLTH, "vsplth") -BU_ALTIVEC_OVERLOAD_X (VSPLTW, "vspltw") - -/* 3 argument VSX builtins. */ -BU_VSX_3 (XVMADDSP, "xvmaddsp", CONST, fmav4sf4) -BU_VSX_3 (XVMSUBSP, "xvmsubsp", CONST, fmsv4sf4) -BU_VSX_3 (XVNMADDSP, "xvnmaddsp", CONST, nfmav4sf4) -BU_VSX_3 (XVNMSUBSP, "xvnmsubsp", CONST, nfmsv4sf4) - -BU_VSX_3 (XVMADDDP, "xvmadddp", CONST, fmav2df4) -BU_VSX_3 (XVMSUBDP, "xvmsubdp", CONST, fmsv2df4) -BU_VSX_3 (XVNMADDDP, "xvnmadddp", CONST, nfmav2df4) -BU_VSX_3 (XVNMSUBDP, "xvnmsubdp", CONST, nfmsv2df4) - -BU_VSX_3 (XXSEL_2DI, "xxsel_2di", CONST, vector_select_v2di) -BU_VSX_3 (XXSEL_2DF, "xxsel_2df", CONST, vector_select_v2df) -BU_VSX_3 (XXSEL_4SF, "xxsel_4sf", CONST, vector_select_v4sf) -BU_VSX_3 (XXSEL_4SI, "xxsel_4si", CONST, vector_select_v4si) -BU_VSX_3 (XXSEL_8HI, "xxsel_8hi", CONST, vector_select_v8hi) -BU_VSX_3 (XXSEL_16QI, "xxsel_16qi", CONST, vector_select_v16qi) -BU_VSX_3 (XXSEL_2DI_UNS, "xxsel_2di_uns", CONST, vector_select_v2di_uns) -BU_VSX_3 (XXSEL_4SI_UNS, "xxsel_4si_uns", CONST, vector_select_v4si_uns) -BU_VSX_3 (XXSEL_8HI_UNS, "xxsel_8hi_uns", CONST, vector_select_v8hi_uns) -BU_VSX_3 (XXSEL_16QI_UNS, "xxsel_16qi_uns", CONST, vector_select_v16qi_uns) - -BU_VSX_3 (VPERM_2DI, "vperm_2di", CONST, altivec_vperm_v2di) -BU_VSX_3 (VPERM_2DF, "vperm_2df", CONST, altivec_vperm_v2df) -BU_VSX_3 (VPERM_4SF, "vperm_4sf", CONST, altivec_vperm_v4sf) -BU_VSX_3 (VPERM_4SI, "vperm_4si", CONST, altivec_vperm_v4si) -BU_VSX_3 (VPERM_8HI, "vperm_8hi", CONST, altivec_vperm_v8hi) -BU_VSX_3 (VPERM_16QI, "vperm_16qi", CONST, altivec_vperm_v16qi) -BU_VSX_3 (VPERM_2DI_UNS, "vperm_2di_uns", CONST, altivec_vperm_v2di_uns) -BU_VSX_3 (VPERM_4SI_UNS, "vperm_4si_uns", CONST, altivec_vperm_v4si_uns) -BU_VSX_3 (VPERM_8HI_UNS, "vperm_8hi_uns", CONST, altivec_vperm_v8hi_uns) -BU_VSX_3 (VPERM_16QI_UNS, "vperm_16qi_uns", CONST, altivec_vperm_v16qi_uns) - -BU_VSX_3 (XXPERMDI_2DF, "xxpermdi_2df", CONST, vsx_xxpermdi_v2df) -BU_VSX_3 (XXPERMDI_2DI, "xxpermdi_2di", CONST, vsx_xxpermdi_v2di) -BU_VSX_3 (XXPERMDI_4SF, "xxpermdi_4sf", CONST, vsx_xxpermdi_v4sf) -BU_VSX_3 (XXPERMDI_4SI, "xxpermdi_4si", CONST, vsx_xxpermdi_v4si) -BU_VSX_3 (XXPERMDI_8HI, "xxpermdi_8hi", CONST, vsx_xxpermdi_v8hi) -BU_VSX_3 (XXPERMDI_16QI, "xxpermdi_16qi", CONST, vsx_xxpermdi_v16qi) -BU_VSX_3 (SET_2DF, "set_2df", CONST, vsx_set_v2df) -BU_VSX_3 (SET_2DI, "set_2di", CONST, vsx_set_v2di) -BU_VSX_3 (XXSLDWI_2DI, "xxsldwi_2di", CONST, vsx_xxsldwi_v2di) -BU_VSX_3 (XXSLDWI_2DF, "xxsldwi_2df", CONST, vsx_xxsldwi_v2df) -BU_VSX_3 (XXSLDWI_4SF, "xxsldwi_4sf", CONST, vsx_xxsldwi_v4sf) -BU_VSX_3 (XXSLDWI_4SI, "xxsldwi_4si", CONST, vsx_xxsldwi_v4si) -BU_VSX_3 (XXSLDWI_8HI, "xxsldwi_8hi", CONST, vsx_xxsldwi_v8hi) -BU_VSX_3 (XXSLDWI_16QI, "xxsldwi_16qi", CONST, vsx_xxsldwi_v16qi) - -/* 2 argument VSX builtins. */ -BU_VSX_2 (XVADDDP, "xvadddp", FP, addv2df3) -BU_VSX_2 (XVSUBDP, "xvsubdp", FP, subv2df3) -BU_VSX_2 (XVMULDP, "xvmuldp", FP, mulv2df3) -BU_VSX_2 (XVDIVDP, "xvdivdp", FP, divv2df3) -BU_VSX_2 (RECIP_V2DF, "xvrecipdivdp", FP, recipv2df3) -BU_VSX_2 (XVMINDP, "xvmindp", CONST, sminv2df3) -BU_VSX_2 (XVMAXDP, "xvmaxdp", CONST, smaxv2df3) -BU_VSX_2 (XVTDIVDP_FE, "xvtdivdp_fe", CONST, vsx_tdivv2df3_fe) -BU_VSX_2 (XVTDIVDP_FG, "xvtdivdp_fg", CONST, vsx_tdivv2df3_fg) -BU_VSX_2 (XVCMPEQDP, "xvcmpeqdp", CONST, vector_eqv2df) -BU_VSX_2 (XVCMPGTDP, "xvcmpgtdp", CONST, vector_gtv2df) -BU_VSX_2 (XVCMPGEDP, "xvcmpgedp", CONST, vector_gev2df) - -BU_VSX_2 (XVADDSP, "xvaddsp", FP, addv4sf3) -BU_VSX_2 (XVSUBSP, "xvsubsp", FP, subv4sf3) -BU_VSX_2 (XVMULSP, "xvmulsp", FP, mulv4sf3) -BU_VSX_2 (XVDIVSP, "xvdivsp", FP, divv4sf3) -BU_VSX_2 (RECIP_V4SF, "xvrecipdivsp", FP, recipv4sf3) -BU_VSX_2 (XVMINSP, "xvminsp", CONST, sminv4sf3) -BU_VSX_2 (XVMAXSP, "xvmaxsp", CONST, smaxv4sf3) -BU_VSX_2 (XVTDIVSP_FE, "xvtdivsp_fe", CONST, vsx_tdivv4sf3_fe) -BU_VSX_2 (XVTDIVSP_FG, "xvtdivsp_fg", CONST, vsx_tdivv4sf3_fg) -BU_VSX_2 (XVCMPEQSP, "xvcmpeqsp", CONST, vector_eqv4sf) -BU_VSX_2 (XVCMPGTSP, "xvcmpgtsp", CONST, vector_gtv4sf) -BU_VSX_2 (XVCMPGESP, "xvcmpgesp", CONST, vector_gev4sf) - -BU_VSX_2 (XSMINDP, "xsmindp", CONST, smindf3) -BU_VSX_2 (XSMAXDP, "xsmaxdp", CONST, smaxdf3) -BU_VSX_2 (XSTDIVDP_FE, "xstdivdp_fe", CONST, vsx_tdivdf3_fe) -BU_VSX_2 (XSTDIVDP_FG, "xstdivdp_fg", CONST, vsx_tdivdf3_fg) -BU_VSX_2 (CPSGNDP, "cpsgndp", CONST, vector_copysignv2df3) -BU_VSX_2 (CPSGNSP, "cpsgnsp", CONST, vector_copysignv4sf3) - -BU_VSX_2 (CONCAT_2DF, "concat_2df", CONST, vsx_concat_v2df) -BU_VSX_2 (CONCAT_2DI, "concat_2di", CONST, vsx_concat_v2di) -BU_VSX_2 (SPLAT_2DF, "splat_2df", CONST, vsx_splat_v2df) -BU_VSX_2 (SPLAT_2DI, "splat_2di", CONST, vsx_splat_v2di) -BU_VSX_2 (XXMRGHW_4SF, "xxmrghw", CONST, vsx_xxmrghw_v4sf) -BU_VSX_2 (XXMRGHW_4SI, "xxmrghw_4si", CONST, vsx_xxmrghw_v4si) -BU_VSX_2 (XXMRGLW_4SF, "xxmrglw", CONST, vsx_xxmrglw_v4sf) -BU_VSX_2 (XXMRGLW_4SI, "xxmrglw_4si", CONST, vsx_xxmrglw_v4si) -BU_VSX_2 (VEC_MERGEL_V2DF, "mergel_2df", CONST, vsx_mergel_v2df) -BU_VSX_2 (VEC_MERGEL_V2DI, "mergel_2di", CONST, vsx_mergel_v2di) -BU_VSX_2 (VEC_MERGEH_V2DF, "mergeh_2df", CONST, vsx_mergeh_v2df) -BU_VSX_2 (VEC_MERGEH_V2DI, "mergeh_2di", CONST, vsx_mergeh_v2di) - -/* VSX abs builtin functions. */ -BU_VSX_A (XVABSDP, "xvabsdp", CONST, absv2df2) -BU_VSX_A (XVNABSDP, "xvnabsdp", CONST, vsx_nabsv2df2) -BU_VSX_A (XVABSSP, "xvabssp", CONST, absv4sf2) -BU_VSX_A (XVNABSSP, "xvnabssp", CONST, vsx_nabsv4sf2) - -/* 1 argument VSX builtin functions. */ -BU_VSX_1 (XVNEGDP, "xvnegdp", CONST, negv2df2) -BU_VSX_1 (XVSQRTDP, "xvsqrtdp", CONST, sqrtv2df2) -BU_VSX_1 (RSQRT_2DF, "xvrsqrtdp", CONST, rsqrtv2df2) -BU_VSX_1 (XVRSQRTEDP, "xvrsqrtedp", CONST, rsqrtev2df2) -BU_VSX_1 (XVTSQRTDP_FE, "xvtsqrtdp_fe", CONST, vsx_tsqrtv2df2_fe) -BU_VSX_1 (XVTSQRTDP_FG, "xvtsqrtdp_fg", CONST, vsx_tsqrtv2df2_fg) -BU_VSX_1 (XVREDP, "xvredp", CONST, vsx_frev2df2) - -BU_VSX_1 (XVNEGSP, "xvnegsp", CONST, negv4sf2) -BU_VSX_1 (XVSQRTSP, "xvsqrtsp", CONST, sqrtv4sf2) -BU_VSX_1 (RSQRT_4SF, "xvrsqrtsp", CONST, rsqrtv4sf2) -BU_VSX_1 (XVRSQRTESP, "xvrsqrtesp", CONST, rsqrtev4sf2) -BU_VSX_1 (XVTSQRTSP_FE, "xvtsqrtsp_fe", CONST, vsx_tsqrtv4sf2_fe) -BU_VSX_1 (XVTSQRTSP_FG, "xvtsqrtsp_fg", CONST, vsx_tsqrtv4sf2_fg) -BU_VSX_1 (XVRESP, "xvresp", CONST, vsx_frev4sf2) - -BU_VSX_1 (XSCVDPSP, "xscvdpsp", CONST, vsx_xscvdpsp) -BU_VSX_1 (XSCVSPDP, "xscvspdp", CONST, vsx_xscvdpsp) -BU_VSX_1 (XVCVDPSP, "xvcvdpsp", CONST, vsx_xvcvdpsp) -BU_VSX_1 (XVCVSPDP, "xvcvspdp", CONST, vsx_xvcvspdp) -BU_VSX_1 (XSTSQRTDP_FE, "xstsqrtdp_fe", CONST, vsx_tsqrtdf2_fe) -BU_VSX_1 (XSTSQRTDP_FG, "xstsqrtdp_fg", CONST, vsx_tsqrtdf2_fg) - -BU_VSX_1 (XVCVDPSXDS, "xvcvdpsxds", CONST, vsx_fix_truncv2dfv2di2) -BU_VSX_1 (XVCVDPUXDS, "xvcvdpuxds", CONST, vsx_fixuns_truncv2dfv2di2) -BU_VSX_1 (XVCVDPUXDS_UNS, "xvcvdpuxds_uns", CONST, vsx_fixuns_truncv2dfv2di2) -BU_VSX_1 (XVCVSXDDP, "xvcvsxddp", CONST, vsx_floatv2div2df2) -BU_VSX_1 (XVCVUXDDP, "xvcvuxddp", CONST, vsx_floatunsv2div2df2) -BU_VSX_1 (XVCVUXDDP_UNS, "xvcvuxddp_uns", CONST, vsx_floatunsv2div2df2) - -BU_VSX_1 (XVCVSPSXWS, "xvcvspsxws", CONST, vsx_fix_truncv4sfv4si2) -BU_VSX_1 (XVCVSPUXWS, "xvcvspuxws", CONST, vsx_fixuns_truncv4sfv4si2) -BU_VSX_1 (XVCVSXWSP, "xvcvsxwsp", CONST, vsx_floatv4siv4sf2) -BU_VSX_1 (XVCVUXWSP, "xvcvuxwsp", CONST, vsx_floatunsv4siv4sf2) - -BU_VSX_1 (XVCVDPSXWS, "xvcvdpsxws", CONST, vsx_xvcvdpsxws) -BU_VSX_1 (XVCVDPUXWS, "xvcvdpuxws", CONST, vsx_xvcvdpuxws) -BU_VSX_1 (XVCVSXWDP, "xvcvsxwdp", CONST, vsx_xvcvsxwdp) -BU_VSX_1 (XVCVUXWDP, "xvcvuxwdp", CONST, vsx_xvcvuxwdp) -BU_VSX_1 (XVRDPI, "xvrdpi", CONST, vsx_xvrdpi) -BU_VSX_1 (XVRDPIC, "xvrdpic", CONST, vsx_xvrdpic) -BU_VSX_1 (XVRDPIM, "xvrdpim", CONST, vsx_floorv2df2) -BU_VSX_1 (XVRDPIP, "xvrdpip", CONST, vsx_ceilv2df2) -BU_VSX_1 (XVRDPIZ, "xvrdpiz", CONST, vsx_btruncv2df2) - -BU_VSX_1 (XVCVSPSXDS, "xvcvspsxds", CONST, vsx_xvcvspsxds) -BU_VSX_1 (XVCVSPUXDS, "xvcvspuxds", CONST, vsx_xvcvspuxds) -BU_VSX_1 (XVCVSXDSP, "xvcvsxdsp", CONST, vsx_xvcvsxdsp) -BU_VSX_1 (XVCVUXDSP, "xvcvuxdsp", CONST, vsx_xvcvuxdsp) -BU_VSX_1 (XVRSPI, "xvrspi", CONST, vsx_xvrspi) -BU_VSX_1 (XVRSPIC, "xvrspic", CONST, vsx_xvrspic) -BU_VSX_1 (XVRSPIM, "xvrspim", CONST, vsx_floorv4sf2) -BU_VSX_1 (XVRSPIP, "xvrspip", CONST, vsx_ceilv4sf2) -BU_VSX_1 (XVRSPIZ, "xvrspiz", CONST, vsx_btruncv4sf2) - -BU_VSX_1 (XSRDPI, "xsrdpi", CONST, vsx_xsrdpi) -BU_VSX_1 (XSRDPIC, "xsrdpic", CONST, vsx_xsrdpic) -BU_VSX_1 (XSRDPIM, "xsrdpim", CONST, vsx_floordf2) -BU_VSX_1 (XSRDPIP, "xsrdpip", CONST, vsx_ceildf2) -BU_VSX_1 (XSRDPIZ, "xsrdpiz", CONST, vsx_btruncdf2) - -/* VSX predicate functions. */ -BU_VSX_P (XVCMPEQSP_P, "xvcmpeqsp_p", CONST, vector_eq_v4sf_p) -BU_VSX_P (XVCMPGESP_P, "xvcmpgesp_p", CONST, vector_ge_v4sf_p) -BU_VSX_P (XVCMPGTSP_P, "xvcmpgtsp_p", CONST, vector_gt_v4sf_p) -BU_VSX_P (XVCMPEQDP_P, "xvcmpeqdp_p", CONST, vector_eq_v2df_p) -BU_VSX_P (XVCMPGEDP_P, "xvcmpgedp_p", CONST, vector_ge_v2df_p) -BU_VSX_P (XVCMPGTDP_P, "xvcmpgtdp_p", CONST, vector_gt_v2df_p) - -/* VSX builtins that are handled as special cases. */ -BU_VSX_X (LXSDX, "lxsdx", MEM) -BU_VSX_X (LXVD2X_V2DF, "lxvd2x_v2df", MEM) -BU_VSX_X (LXVD2X_V2DI, "lxvd2x_v2di", MEM) -BU_VSX_X (LXVDSX, "lxvdsx", MEM) -BU_VSX_X (LXVW4X_V4SF, "lxvw4x_v4sf", MEM) -BU_VSX_X (LXVW4X_V4SI, "lxvw4x_v4si", MEM) -BU_VSX_X (LXVW4X_V8HI, "lxvw4x_v8hi", MEM) -BU_VSX_X (LXVW4X_V16QI, "lxvw4x_v16qi", MEM) -BU_VSX_X (STXSDX, "stxsdx", MEM) -BU_VSX_X (STXVD2X_V2DF, "stxsdx_v2df", MEM) -BU_VSX_X (STXVD2X_V2DI, "stxsdx_v2di", MEM) -BU_VSX_X (STXVW4X_V4SF, "stxsdx_v4sf", MEM) -BU_VSX_X (STXVW4X_V4SI, "stxsdx_v4si", MEM) -BU_VSX_X (STXVW4X_V8HI, "stxsdx_v8hi", MEM) -BU_VSX_X (STXVW4X_V16QI, "stxsdx_v16qi", MEM) -BU_VSX_X (XSABSDP, "xsabsdp", CONST) -BU_VSX_X (XSADDDP, "xsadddp", FP) -BU_VSX_X (XSCMPODP, "xscmpodp", FP) -BU_VSX_X (XSCMPUDP, "xscmpudp", FP) -BU_VSX_X (XSCVDPSXDS, "xscvdpsxds", FP) -BU_VSX_X (XSCVDPSXWS, "xscvdpsxws", FP) -BU_VSX_X (XSCVDPUXDS, "xscvdpuxds", FP) -BU_VSX_X (XSCVDPUXWS, "xscvdpuxws", FP) -BU_VSX_X (XSCVSXDDP, "xscvsxddp", FP) -BU_VSX_X (XSCVUXDDP, "xscvuxddp", FP) -BU_VSX_X (XSDIVDP, "xsdivdp", FP) -BU_VSX_X (XSMADDADP, "xsmaddadp", FP) -BU_VSX_X (XSMADDMDP, "xsmaddmdp", FP) -BU_VSX_X (XSMOVDP, "xsmovdp", FP) -BU_VSX_X (XSMSUBADP, "xsmsubadp", FP) -BU_VSX_X (XSMSUBMDP, "xsmsubmdp", FP) -BU_VSX_X (XSMULDP, "xsmuldp", FP) -BU_VSX_X (XSNABSDP, "xsnabsdp", FP) -BU_VSX_X (XSNEGDP, "xsnegdp", FP) -BU_VSX_X (XSNMADDADP, "xsnmaddadp", FP) -BU_VSX_X (XSNMADDMDP, "xsnmaddmdp", FP) -BU_VSX_X (XSNMSUBADP, "xsnmsubadp", FP) -BU_VSX_X (XSNMSUBMDP, "xsnmsubmdp", FP) -BU_VSX_X (XSSUBDP, "xssubdp", FP) -BU_VSX_X (VEC_INIT_V2DF, "vec_init_v2df", CONST) -BU_VSX_X (VEC_INIT_V2DI, "vec_init_v2di", CONST) -BU_VSX_X (VEC_SET_V2DF, "vec_set_v2df", CONST) -BU_VSX_X (VEC_SET_V2DI, "vec_set_v2di", CONST) -BU_VSX_X (VEC_EXT_V2DF, "vec_ext_v2df", CONST) -BU_VSX_X (VEC_EXT_V2DI, "vec_ext_v2di", CONST) - -/* VSX overloaded builtins, add the overloaded functions not present in - Altivec. */ - -/* 3 argument VSX overloaded builtins. */ -BU_VSX_OVERLOAD_3 (MSUB, "msub") -BU_VSX_OVERLOAD_3 (NMADD, "nmadd") -BU_VSX_OVERLOAD_3V (XXPERMDI, "xxpermdi") -BU_VSX_OVERLOAD_3V (XXSLDWI, "xxsldwi") - -/* 2 argument VSX overloaded builtin functions. */ -BU_VSX_OVERLOAD_2 (MUL, "mul") -BU_VSX_OVERLOAD_2 (DIV, "div") -BU_VSX_OVERLOAD_2 (XXMRGHW, "xxmrghw") -BU_VSX_OVERLOAD_2 (XXMRGLW, "xxmrglw") -BU_VSX_OVERLOAD_2 (XXSPLTD, "xxspltd") -BU_VSX_OVERLOAD_2 (XXSPLTW, "xxspltw") - -/* VSX builtins that are handled as special cases. */ -BU_VSX_OVERLOAD_X (LD, "ld") -BU_VSX_OVERLOAD_X (ST, "st") - -/* 3 argument paired floating point builtins. */ -BU_PAIRED_3 (MSUB, "msub", FP, fmsv2sf4) -BU_PAIRED_3 (MADD, "madd", FP, fmav2sf4) -BU_PAIRED_3 (MADDS0, "madds0", FP, paired_madds0) -BU_PAIRED_3 (MADDS1, "madds1", FP, paired_madds1) -BU_PAIRED_3 (NMSUB, "nmsub", FP, nfmsv2sf4) -BU_PAIRED_3 (NMADD, "nmadd", FP, nfmav2sf4) -BU_PAIRED_3 (SUM0, "sum0", FP, paired_sum0) -BU_PAIRED_3 (SUM1, "sum1", FP, paired_sum1) -BU_PAIRED_3 (SELV2SF4, "selv2sf4", CONST, selv2sf4) - -/* 2 argument paired floating point builtins. */ -BU_PAIRED_2 (DIVV2SF3, "divv2sf3", FP, paired_divv2sf3) -BU_PAIRED_2 (ADDV2SF3, "addv2sf3", FP, paired_addv2sf3) -BU_PAIRED_2 (SUBV2SF3, "subv2sf3", FP, paired_subv2sf3) -BU_PAIRED_2 (MULV2SF3, "mulv2sf3", FP, paired_mulv2sf3) -BU_PAIRED_2 (MULS0, "muls0", FP, paired_muls0) -BU_PAIRED_2 (MULS1, "muls1", FP, paired_muls1) -BU_PAIRED_2 (MERGE00, "merge00", CONST, paired_merge00) -BU_PAIRED_2 (MERGE01, "merge01", CONST, paired_merge01) -BU_PAIRED_2 (MERGE10, "merge10", CONST, paired_merge10) -BU_PAIRED_2 (MERGE11, "merge11", CONST, paired_merge11) - -/* 1 argument paired floating point builtin functions. */ -BU_PAIRED_1 (ABSV2SF2, "absv2sf2", CONST, paired_absv2sf2) -BU_PAIRED_1 (NABSV2SF2, "nabsv2sf2", CONST, nabsv2sf2) -BU_PAIRED_1 (NEGV2SF2, "negv2sf2", CONST, paired_negv2sf2) -BU_PAIRED_1 (SQRTV2SF2, "sqrtv2sf2", FP, sqrtv2sf2) -BU_PAIRED_1 (RESV2SF, "resv2sf2", FP, resv2sf2) - -/* PAIRED builtins that are handled as special cases. */ -BU_PAIRED_X (STX, "stx", MISC) -BU_PAIRED_X (LX, "lx", MISC) - -/* Paired predicates. */ -BU_PAIRED_P (CMPU0, "cmpu0", CONST, paired_cmpu0) -BU_PAIRED_P (CMPU1, "cmpu1", CONST, paired_cmpu1) - -/* PowerPC E500 builtins (SPE). */ - -BU_SPE_2 (EVADDW, "evaddw", MISC, addv2si3) -BU_SPE_2 (EVAND, "evand", MISC, andv2si3) -BU_SPE_2 (EVANDC, "evandc", MISC, spe_evandc) -BU_SPE_2 (EVDIVWS, "evdivws", MISC, divv2si3) -BU_SPE_2 (EVDIVWU, "evdivwu", MISC, spe_evdivwu) -BU_SPE_2 (EVEQV, "eveqv", MISC, spe_eveqv) -BU_SPE_2 (EVFSADD, "evfsadd", MISC, spe_evfsadd) -BU_SPE_2 (EVFSDIV, "evfsdiv", MISC, spe_evfsdiv) -BU_SPE_2 (EVFSMUL, "evfsmul", MISC, spe_evfsmul) -BU_SPE_2 (EVFSSUB, "evfssub", MISC, spe_evfssub) -BU_SPE_2 (EVMERGEHI, "evmergehi", MISC, spe_evmergehi) -BU_SPE_2 (EVMERGEHILO, "evmergehilo", MISC, spe_evmergehilo) -BU_SPE_2 (EVMERGELO, "evmergelo", MISC, spe_evmergelo) -BU_SPE_2 (EVMERGELOHI, "evmergelohi", MISC, spe_evmergelohi) -BU_SPE_2 (EVMHEGSMFAA, "evmhegsmfaa", MISC, spe_evmhegsmfaa) -BU_SPE_2 (EVMHEGSMFAN, "evmhegsmfan", MISC, spe_evmhegsmfan) -BU_SPE_2 (EVMHEGSMIAA, "evmhegsmiaa", MISC, spe_evmhegsmiaa) -BU_SPE_2 (EVMHEGSMIAN, "evmhegsmian", MISC, spe_evmhegsmian) -BU_SPE_2 (EVMHEGUMIAA, "evmhegumiaa", MISC, spe_evmhegumiaa) -BU_SPE_2 (EVMHEGUMIAN, "evmhegumian", MISC, spe_evmhegumian) -BU_SPE_2 (EVMHESMF, "evmhesmf", MISC, spe_evmhesmf) -BU_SPE_2 (EVMHESMFA, "evmhesmfa", MISC, spe_evmhesmfa) -BU_SPE_2 (EVMHESMFAAW, "evmhesmfaaw", MISC, spe_evmhesmfaaw) -BU_SPE_2 (EVMHESMFANW, "evmhesmfanw", MISC, spe_evmhesmfanw) -BU_SPE_2 (EVMHESMI, "evmhesmi", MISC, spe_evmhesmi) -BU_SPE_2 (EVMHESMIA, "evmhesmia", MISC, spe_evmhesmia) -BU_SPE_2 (EVMHESMIAAW, "evmhesmiaaw", MISC, spe_evmhesmiaaw) -BU_SPE_2 (EVMHESMIANW, "evmhesmianw", MISC, spe_evmhesmianw) -BU_SPE_2 (EVMHESSF, "evmhessf", MISC, spe_evmhessf) -BU_SPE_2 (EVMHESSFA, "evmhessfa", MISC, spe_evmhessfa) -BU_SPE_2 (EVMHESSFAAW, "evmhessfaaw", MISC, spe_evmhessfaaw) -BU_SPE_2 (EVMHESSFANW, "evmhessfanw", MISC, spe_evmhessfanw) -BU_SPE_2 (EVMHESSIAAW, "evmhessiaaw", MISC, spe_evmhessiaaw) -BU_SPE_2 (EVMHESSIANW, "evmhessianw", MISC, spe_evmhessianw) -BU_SPE_2 (EVMHEUMI, "evmheumi", MISC, spe_evmheumi) -BU_SPE_2 (EVMHEUMIA, "evmheumia", MISC, spe_evmheumia) -BU_SPE_2 (EVMHEUMIAAW, "evmheumiaaw", MISC, spe_evmheumiaaw) -BU_SPE_2 (EVMHEUMIANW, "evmheumianw", MISC, spe_evmheumianw) -BU_SPE_2 (EVMHEUSIAAW, "evmheusiaaw", MISC, spe_evmheusiaaw) -BU_SPE_2 (EVMHEUSIANW, "evmheusianw", MISC, spe_evmheusianw) -BU_SPE_2 (EVMHOGSMFAA, "evmhogsmfaa", MISC, spe_evmhogsmfaa) -BU_SPE_2 (EVMHOGSMFAN, "evmhogsmfan", MISC, spe_evmhogsmfan) -BU_SPE_2 (EVMHOGSMIAA, "evmhogsmiaa", MISC, spe_evmhogsmiaa) -BU_SPE_2 (EVMHOGSMIAN, "evmhogsmian", MISC, spe_evmhogsmian) -BU_SPE_2 (EVMHOGUMIAA, "evmhogumiaa", MISC, spe_evmhogumiaa) -BU_SPE_2 (EVMHOGUMIAN, "evmhogumian", MISC, spe_evmhogumian) -BU_SPE_2 (EVMHOSMF, "evmhosmf", MISC, spe_evmhosmf) -BU_SPE_2 (EVMHOSMFA, "evmhosmfa", MISC, spe_evmhosmfa) -BU_SPE_2 (EVMHOSMFAAW, "evmhosmfaaw", MISC, spe_evmhosmfaaw) -BU_SPE_2 (EVMHOSMFANW, "evmhosmfanw", MISC, spe_evmhosmfanw) -BU_SPE_2 (EVMHOSMI, "evmhosmi", MISC, spe_evmhosmi) -BU_SPE_2 (EVMHOSMIA, "evmhosmia", MISC, spe_evmhosmia) -BU_SPE_2 (EVMHOSMIAAW, "evmhosmiaaw", MISC, spe_evmhosmiaaw) -BU_SPE_2 (EVMHOSMIANW, "evmhosmianw", MISC, spe_evmhosmianw) -BU_SPE_2 (EVMHOSSF, "evmhossf", MISC, spe_evmhossf) -BU_SPE_2 (EVMHOSSFA, "evmhossfa", MISC, spe_evmhossfa) -BU_SPE_2 (EVMHOSSFAAW, "evmhossfaaw", MISC, spe_evmhossfaaw) -BU_SPE_2 (EVMHOSSFANW, "evmhossfanw", MISC, spe_evmhossfanw) -BU_SPE_2 (EVMHOSSIAAW, "evmhossiaaw", MISC, spe_evmhossiaaw) -BU_SPE_2 (EVMHOSSIANW, "evmhossianw", MISC, spe_evmhossianw) -BU_SPE_2 (EVMHOUMI, "evmhoumi", MISC, spe_evmhoumi) -BU_SPE_2 (EVMHOUMIA, "evmhoumia", MISC, spe_evmhoumia) -BU_SPE_2 (EVMHOUMIAAW, "evmhoumiaaw", MISC, spe_evmhoumiaaw) -BU_SPE_2 (EVMHOUMIANW, "evmhoumianw", MISC, spe_evmhoumianw) -BU_SPE_2 (EVMHOUSIAAW, "evmhousiaaw", MISC, spe_evmhousiaaw) -BU_SPE_2 (EVMHOUSIANW, "evmhousianw", MISC, spe_evmhousianw) -BU_SPE_2 (EVMWHSMF, "evmwhsmf", MISC, spe_evmwhsmf) -BU_SPE_2 (EVMWHSMFA, "evmwhsmfa", MISC, spe_evmwhsmfa) -BU_SPE_2 (EVMWHSMI, "evmwhsmi", MISC, spe_evmwhsmi) -BU_SPE_2 (EVMWHSMIA, "evmwhsmia", MISC, spe_evmwhsmia) -BU_SPE_2 (EVMWHSSF, "evmwhssf", MISC, spe_evmwhssf) -BU_SPE_2 (EVMWHSSFA, "evmwhssfa", MISC, spe_evmwhssfa) -BU_SPE_2 (EVMWHUMI, "evmwhumi", MISC, spe_evmwhumi) -BU_SPE_2 (EVMWHUMIA, "evmwhumia", MISC, spe_evmwhumia) -BU_SPE_2 (EVMWLSMIAAW, "evmwlsmiaaw", MISC, spe_evmwlsmiaaw) -BU_SPE_2 (EVMWLSMIANW, "evmwlsmianw", MISC, spe_evmwlsmianw) -BU_SPE_2 (EVMWLSSIAAW, "evmwlssiaaw", MISC, spe_evmwlssiaaw) -BU_SPE_2 (EVMWLSSIANW, "evmwlssianw", MISC, spe_evmwlssianw) -BU_SPE_2 (EVMWLUMI, "evmwlumi", MISC, spe_evmwlumi) -BU_SPE_2 (EVMWLUMIA, "evmwlumia", MISC, spe_evmwlumia) -BU_SPE_2 (EVMWLUMIAAW, "evmwlumiaaw", MISC, spe_evmwlumiaaw) -BU_SPE_2 (EVMWLUMIANW, "evmwlumianw", MISC, spe_evmwlumianw) -BU_SPE_2 (EVMWLUSIAAW, "evmwlusiaaw", MISC, spe_evmwlusiaaw) -BU_SPE_2 (EVMWLUSIANW, "evmwlusianw", MISC, spe_evmwlusianw) -BU_SPE_2 (EVMWSMF, "evmwsmf", MISC, spe_evmwsmf) -BU_SPE_2 (EVMWSMFA, "evmwsmfa", MISC, spe_evmwsmfa) -BU_SPE_2 (EVMWSMFAA, "evmwsmfaa", MISC, spe_evmwsmfaa) -BU_SPE_2 (EVMWSMFAN, "evmwsmfan", MISC, spe_evmwsmfan) -BU_SPE_2 (EVMWSMI, "evmwsmi", MISC, spe_evmwsmi) -BU_SPE_2 (EVMWSMIA, "evmwsmia", MISC, spe_evmwsmia) -BU_SPE_2 (EVMWSMIAA, "evmwsmiaa", MISC, spe_evmwsmiaa) -BU_SPE_2 (EVMWSMIAN, "evmwsmian", MISC, spe_evmwsmian) -BU_SPE_2 (EVMWSSF, "evmwssf", MISC, spe_evmwssf) -BU_SPE_2 (EVMWSSFA, "evmwssfa", MISC, spe_evmwssfa) -BU_SPE_2 (EVMWSSFAA, "evmwssfaa", MISC, spe_evmwssfaa) -BU_SPE_2 (EVMWSSFAN, "evmwssfan", MISC, spe_evmwssfan) -BU_SPE_2 (EVMWUMI, "evmwumi", MISC, spe_evmwumi) -BU_SPE_2 (EVMWUMIA, "evmwumia", MISC, spe_evmwumia) -BU_SPE_2 (EVMWUMIAA, "evmwumiaa", MISC, spe_evmwumiaa) -BU_SPE_2 (EVMWUMIAN, "evmwumian", MISC, spe_evmwumian) -BU_SPE_2 (EVNAND, "evnand", MISC, spe_evnand) -BU_SPE_2 (EVNOR, "evnor", MISC, spe_evnor) -BU_SPE_2 (EVOR, "evor", MISC, spe_evor) -BU_SPE_2 (EVORC, "evorc", MISC, spe_evorc) -BU_SPE_2 (EVRLW, "evrlw", MISC, spe_evrlw) -BU_SPE_2 (EVSLW, "evslw", MISC, spe_evslw) -BU_SPE_2 (EVSRWS, "evsrws", MISC, spe_evsrws) -BU_SPE_2 (EVSRWU, "evsrwu", MISC, spe_evsrwu) -BU_SPE_2 (EVSUBFW, "evsubfw", MISC, subv2si3) - -/* SPE binary operations expecting a 5-bit unsigned literal. */ -BU_SPE_2 (EVADDIW, "evaddiw", MISC, spe_evaddiw) - -BU_SPE_2 (EVRLWI, "evrlwi", MISC, spe_evrlwi) -BU_SPE_2 (EVSLWI, "evslwi", MISC, spe_evslwi) -BU_SPE_2 (EVSRWIS, "evsrwis", MISC, spe_evsrwis) -BU_SPE_2 (EVSRWIU, "evsrwiu", MISC, spe_evsrwiu) -BU_SPE_2 (EVSUBIFW, "evsubifw", MISC, spe_evsubifw) -BU_SPE_2 (EVMWHSSFAA, "evmwhssfaa", MISC, spe_evmwhssfaa) -BU_SPE_2 (EVMWHSSMAA, "evmwhssmaa", MISC, spe_evmwhssmaa) -BU_SPE_2 (EVMWHSMFAA, "evmwhsmfaa", MISC, spe_evmwhsmfaa) -BU_SPE_2 (EVMWHSMIAA, "evmwhsmiaa", MISC, spe_evmwhsmiaa) -BU_SPE_2 (EVMWHUSIAA, "evmwhusiaa", MISC, spe_evmwhusiaa) -BU_SPE_2 (EVMWHUMIAA, "evmwhumiaa", MISC, spe_evmwhumiaa) -BU_SPE_2 (EVMWHSSFAN, "evmwhssfan", MISC, spe_evmwhssfan) -BU_SPE_2 (EVMWHSSIAN, "evmwhssian", MISC, spe_evmwhssian) -BU_SPE_2 (EVMWHSMFAN, "evmwhsmfan", MISC, spe_evmwhsmfan) -BU_SPE_2 (EVMWHSMIAN, "evmwhsmian", MISC, spe_evmwhsmian) -BU_SPE_2 (EVMWHUSIAN, "evmwhusian", MISC, spe_evmwhusian) -BU_SPE_2 (EVMWHUMIAN, "evmwhumian", MISC, spe_evmwhumian) -BU_SPE_2 (EVMWHGSSFAA, "evmwhgssfaa", MISC, spe_evmwhgssfaa) -BU_SPE_2 (EVMWHGSMFAA, "evmwhgsmfaa", MISC, spe_evmwhgsmfaa) -BU_SPE_2 (EVMWHGSMIAA, "evmwhgsmiaa", MISC, spe_evmwhgsmiaa) -BU_SPE_2 (EVMWHGUMIAA, "evmwhgumiaa", MISC, spe_evmwhgumiaa) -BU_SPE_2 (EVMWHGSSFAN, "evmwhgssfan", MISC, spe_evmwhgssfan) -BU_SPE_2 (EVMWHGSMFAN, "evmwhgsmfan", MISC, spe_evmwhgsmfan) -BU_SPE_2 (EVMWHGSMIAN, "evmwhgsmian", MISC, spe_evmwhgsmian) -BU_SPE_2 (EVMWHGUMIAN, "evmwhgumian", MISC, spe_evmwhgumian) -BU_SPE_2 (BRINC, "brinc", MISC, spe_brinc) -BU_SPE_2 (EVXOR, "evxor", MISC, xorv2si3) - -/* SPE predicate builtins. */ -BU_SPE_P (EVCMPEQ, "evcmpeq", MISC, spe_evcmpeq) -BU_SPE_P (EVCMPGTS, "evcmpgts", MISC, spe_evcmpgts) -BU_SPE_P (EVCMPGTU, "evcmpgtu", MISC, spe_evcmpgtu) -BU_SPE_P (EVCMPLTS, "evcmplts", MISC, spe_evcmplts) -BU_SPE_P (EVCMPLTU, "evcmpltu", MISC, spe_evcmpltu) -BU_SPE_P (EVFSCMPEQ, "evfscmpeq", MISC, spe_evfscmpeq) -BU_SPE_P (EVFSCMPGT, "evfscmpgt", MISC, spe_evfscmpgt) -BU_SPE_P (EVFSCMPLT, "evfscmplt", MISC, spe_evfscmplt) -BU_SPE_P (EVFSTSTEQ, "evfststeq", MISC, spe_evfststeq) -BU_SPE_P (EVFSTSTGT, "evfststgt", MISC, spe_evfststgt) -BU_SPE_P (EVFSTSTLT, "evfststlt", MISC, spe_evfststlt) - -/* SPE evsel builtins. */ -BU_SPE_E (EVSEL_CMPGTS, "evsel_gts", MISC, spe_evcmpgts) -BU_SPE_E (EVSEL_CMPGTU, "evsel_gtu", MISC, spe_evcmpgtu) -BU_SPE_E (EVSEL_CMPLTS, "evsel_lts", MISC, spe_evcmplts) -BU_SPE_E (EVSEL_CMPLTU, "evsel_ltu", MISC, spe_evcmpltu) -BU_SPE_E (EVSEL_CMPEQ, "evsel_eq", MISC, spe_evcmpeq) -BU_SPE_E (EVSEL_FSCMPGT, "evsel_fsgt", MISC, spe_evfscmpgt) -BU_SPE_E (EVSEL_FSCMPLT, "evsel_fslt", MISC, spe_evfscmplt) -BU_SPE_E (EVSEL_FSCMPEQ, "evsel_fseq", MISC, spe_evfscmpeq) -BU_SPE_E (EVSEL_FSTSTGT, "evsel_fststgt", MISC, spe_evfststgt) -BU_SPE_E (EVSEL_FSTSTLT, "evsel_fststlt", MISC, spe_evfststlt) -BU_SPE_E (EVSEL_FSTSTEQ, "evsel_fststeq", MISC, spe_evfststeq) - -BU_SPE_1 (EVABS, "evabs", CONST, absv2si2) -BU_SPE_1 (EVADDSMIAAW, "evaddsmiaaw", CONST, spe_evaddsmiaaw) -BU_SPE_1 (EVADDSSIAAW, "evaddssiaaw", CONST, spe_evaddssiaaw) -BU_SPE_1 (EVADDUMIAAW, "evaddumiaaw", CONST, spe_evaddumiaaw) -BU_SPE_1 (EVADDUSIAAW, "evaddusiaaw", CONST, spe_evaddusiaaw) -BU_SPE_1 (EVCNTLSW, "evcntlsw", CONST, spe_evcntlsw) -BU_SPE_1 (EVCNTLZW, "evcntlzw", CONST, spe_evcntlzw) -BU_SPE_1 (EVEXTSB, "evextsb", CONST, spe_evextsb) -BU_SPE_1 (EVEXTSH, "evextsh", CONST, spe_evextsh) -BU_SPE_1 (EVFSABS, "evfsabs", CONST, spe_evfsabs) -BU_SPE_1 (EVFSCFSF, "evfscfsf", CONST, spe_evfscfsf) -BU_SPE_1 (EVFSCFSI, "evfscfsi", CONST, spe_evfscfsi) -BU_SPE_1 (EVFSCFUF, "evfscfuf", CONST, spe_evfscfuf) -BU_SPE_1 (EVFSCFUI, "evfscfui", CONST, spe_evfscfui) -BU_SPE_1 (EVFSCTSF, "evfsctsf", CONST, spe_evfsctsf) -BU_SPE_1 (EVFSCTSI, "evfsctsi", CONST, spe_evfsctsi) -BU_SPE_1 (EVFSCTSIZ, "evfsctsiz", CONST, spe_evfsctsiz) -BU_SPE_1 (EVFSCTUF, "evfsctuf", CONST, spe_evfsctuf) -BU_SPE_1 (EVFSCTUI, "evfsctui", CONST, spe_evfsctui) -BU_SPE_1 (EVFSCTUIZ, "evfsctuiz", CONST, spe_evfsctuiz) -BU_SPE_1 (EVFSNABS, "evfsnabs", CONST, spe_evfsnabs) -BU_SPE_1 (EVFSNEG, "evfsneg", CONST, spe_evfsneg) -BU_SPE_1 (EVMRA, "evmra", CONST, spe_evmra) -BU_SPE_1 (EVNEG, "evneg", CONST, negv2si2) -BU_SPE_1 (EVRNDW, "evrndw", CONST, spe_evrndw) -BU_SPE_1 (EVSUBFSMIAAW, "evsubfsmiaaw", CONST, spe_evsubfsmiaaw) -BU_SPE_1 (EVSUBFSSIAAW, "evsubfssiaaw", CONST, spe_evsubfssiaaw) -BU_SPE_1 (EVSUBFUMIAAW, "evsubfumiaaw", CONST, spe_evsubfumiaaw) -BU_SPE_1 (EVSUBFUSIAAW, "evsubfusiaaw", CONST, spe_evsubfusiaaw) - -/* SPE builtins that are handled as special cases. */ -BU_SPE_X (EVLDD, "evldd", MISC) -BU_SPE_X (EVLDDX, "evlddx", MISC) -BU_SPE_X (EVLDH, "evldh", MISC) -BU_SPE_X (EVLDHX, "evldhx", MISC) -BU_SPE_X (EVLDW, "evldw", MISC) -BU_SPE_X (EVLDWX, "evldwx", MISC) -BU_SPE_X (EVLHHESPLAT, "evlhhesplat", MISC) -BU_SPE_X (EVLHHESPLATX, "evlhhesplatx", MISC) -BU_SPE_X (EVLHHOSSPLAT, "evlhhossplat", MISC) -BU_SPE_X (EVLHHOSSPLATX, "evlhhossplatx", MISC) -BU_SPE_X (EVLHHOUSPLAT, "evlhhousplat", MISC) -BU_SPE_X (EVLHHOUSPLATX, "evlhhousplatx", MISC) -BU_SPE_X (EVLWHE, "evlwhe", MISC) -BU_SPE_X (EVLWHEX, "evlwhex", MISC) -BU_SPE_X (EVLWHOS, "evlwhos", MISC) -BU_SPE_X (EVLWHOSX, "evlwhosx", MISC) -BU_SPE_X (EVLWHOU, "evlwhou", MISC) -BU_SPE_X (EVLWHOUX, "evlwhoux", MISC) -BU_SPE_X (EVLWHSPLAT, "evlwhsplat", MISC) -BU_SPE_X (EVLWHSPLATX, "evlwhsplatx", MISC) -BU_SPE_X (EVLWWSPLAT, "evlwwsplat", MISC) -BU_SPE_X (EVLWWSPLATX, "evlwwsplatx", MISC) -BU_SPE_X (EVSPLATFI, "evsplatfi", MISC) -BU_SPE_X (EVSPLATI, "evsplati", MISC) -BU_SPE_X (EVSTDD, "evstdd", MISC) -BU_SPE_X (EVSTDDX, "evstddx", MISC) -BU_SPE_X (EVSTDH, "evstdh", MISC) -BU_SPE_X (EVSTDHX, "evstdhx", MISC) -BU_SPE_X (EVSTDW, "evstdw", MISC) -BU_SPE_X (EVSTDWX, "evstdwx", MISC) -BU_SPE_X (EVSTWHE, "evstwhe", MISC) -BU_SPE_X (EVSTWHEX, "evstwhex", MISC) -BU_SPE_X (EVSTWHO, "evstwho", MISC) -BU_SPE_X (EVSTWHOX, "evstwhox", MISC) -BU_SPE_X (EVSTWWE, "evstwwe", MISC) -BU_SPE_X (EVSTWWEX, "evstwwex", MISC) -BU_SPE_X (EVSTWWO, "evstwwo", MISC) -BU_SPE_X (EVSTWWOX, "evstwwox", MISC) -BU_SPE_X (MFSPEFSCR, "mfspefscr", MISC) -BU_SPE_X (MTSPEFSCR, "mtspefscr", MISC) - - -/* Power7 builtins, that aren't VSX instructions. */ -BU_SPECIAL_X (POWER7_BUILTIN_BPERMD, "__builtin_bpermd", RS6000_BTM_POPCNTD, - RS6000_BTC_CONST) - -/* Miscellaneous builtins. */ -BU_SPECIAL_X (RS6000_BUILTIN_RECIP, "__builtin_recipdiv", RS6000_BTM_FRE, - RS6000_BTC_FP) - -BU_SPECIAL_X (RS6000_BUILTIN_RECIPF, "__builtin_recipdivf", RS6000_BTM_FRES, - RS6000_BTC_FP) - -BU_SPECIAL_X (RS6000_BUILTIN_RSQRT, "__builtin_rsqrt", RS6000_BTM_FRSQRTE, - RS6000_BTC_FP) - -BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf", RS6000_BTM_FRSQRTES, - RS6000_BTC_FP) - -BU_SPECIAL_X (RS6000_BUILTIN_GET_TB, "__builtin_ppc_get_timebase", - RS6000_BTM_ALWAYS, RS6000_BTC_MISC) - -BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb", - RS6000_BTM_ALWAYS, RS6000_BTC_MISC) - -/* Darwin CfString builtin. */ -BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS, - RS6000_BTC_MISC) diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000-c.c b/gcc-4.8.1/gcc/config/rs6000/rs6000-c.c deleted file mode 100644 index a4f66ba8f..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000-c.c +++ /dev/null @@ -1,3833 +0,0 @@ -/* Subroutines for the C front end on the PowerPC architecture. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - - Contributed by Zack Weinberg <zack@codesourcery.com> - and Paolo Bonzini <bonzini@gnu.org> - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "cpplib.h" -#include "tree.h" -#include "c-family/c-common.h" -#include "c-family/c-pragma.h" -#include "diagnostic-core.h" -#include "tm_p.h" -#include "target.h" -#include "langhooks.h" - - - -/* Handle the machine specific pragma longcall. Its syntax is - - # pragma longcall ( TOGGLE ) - - where TOGGLE is either 0 or 1. - - rs6000_default_long_calls is set to the value of TOGGLE, changing - whether or not new function declarations receive a longcall - attribute by default. */ - -#define SYNTAX_ERROR(gmsgid) do { \ - warning (OPT_Wpragmas, gmsgid); \ - warning (OPT_Wpragmas, "ignoring malformed #pragma longcall"); \ - return; \ -} while (0) - -void -rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED) -{ - tree x, n; - - /* If we get here, generic code has already scanned the directive - leader and the word "longcall". */ - - if (pragma_lex (&x) != CPP_OPEN_PAREN) - SYNTAX_ERROR ("missing open paren"); - if (pragma_lex (&n) != CPP_NUMBER) - SYNTAX_ERROR ("missing number"); - if (pragma_lex (&x) != CPP_CLOSE_PAREN) - SYNTAX_ERROR ("missing close paren"); - - if (n != integer_zero_node && n != integer_one_node) - SYNTAX_ERROR ("number must be 0 or 1"); - - if (pragma_lex (&x) != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of #pragma longcall"); - - rs6000_default_long_calls = (n == integer_one_node); -} - -/* Handle defining many CPP flags based on TARGET_xxx. As a general - policy, rather than trying to guess what flags a user might want a - #define for, it's better to define a flag for everything. */ - -#define builtin_define(TXT) cpp_define (pfile, TXT) -#define builtin_assert(TXT) cpp_assert (pfile, TXT) - -/* Keep the AltiVec keywords handy for fast comparisons. */ -static GTY(()) tree __vector_keyword; -static GTY(()) tree vector_keyword; -static GTY(()) tree __pixel_keyword; -static GTY(()) tree pixel_keyword; -static GTY(()) tree __bool_keyword; -static GTY(()) tree bool_keyword; -static GTY(()) tree _Bool_keyword; - -/* Preserved across calls. */ -static tree expand_bool_pixel; - -static cpp_hashnode * -altivec_categorize_keyword (const cpp_token *tok) -{ - if (tok->type == CPP_NAME) - { - cpp_hashnode *ident = tok->val.node.node; - - if (ident == C_CPP_HASHNODE (vector_keyword)) - return C_CPP_HASHNODE (__vector_keyword); - - if (ident == C_CPP_HASHNODE (pixel_keyword)) - return C_CPP_HASHNODE (__pixel_keyword); - - if (ident == C_CPP_HASHNODE (bool_keyword)) - return C_CPP_HASHNODE (__bool_keyword); - - if (ident == C_CPP_HASHNODE (_Bool_keyword)) - return C_CPP_HASHNODE (__bool_keyword); - - return ident; - } - - return 0; -} - -static void -init_vector_keywords (void) -{ - /* Keywords without two leading underscores are context-sensitive, - and hence implemented as conditional macros, controlled by the - rs6000_macro_to_expand() function below. */ - - __vector_keyword = get_identifier ("__vector"); - C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL; - - __pixel_keyword = get_identifier ("__pixel"); - C_CPP_HASHNODE (__pixel_keyword)->flags |= NODE_CONDITIONAL; - - __bool_keyword = get_identifier ("__bool"); - C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL; - - vector_keyword = get_identifier ("vector"); - C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL; - - pixel_keyword = get_identifier ("pixel"); - C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL; - - bool_keyword = get_identifier ("bool"); - C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL; - - _Bool_keyword = get_identifier ("_Bool"); - C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL; -} - -/* Called to decide whether a conditional macro should be expanded. - Since we have exactly one such macro (i.e, 'vector'), we do not - need to examine the 'tok' parameter. */ - -static cpp_hashnode * -rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) -{ - cpp_hashnode *expand_this = tok->val.node.node; - cpp_hashnode *ident; - - /* If the current machine does not have altivec, don't look for the - keywords. */ - if (!TARGET_ALTIVEC) - return NULL; - - ident = altivec_categorize_keyword (tok); - - if (ident != expand_this) - expand_this = NULL; - - if (ident == C_CPP_HASHNODE (__vector_keyword)) - { - int idx = 0; - do - tok = cpp_peek_token (pfile, idx++); - while (tok->type == CPP_PADDING); - ident = altivec_categorize_keyword (tok); - - if (ident == C_CPP_HASHNODE (__pixel_keyword)) - { - expand_this = C_CPP_HASHNODE (__vector_keyword); - expand_bool_pixel = __pixel_keyword; - } - else if (ident == C_CPP_HASHNODE (__bool_keyword)) - { - expand_this = C_CPP_HASHNODE (__vector_keyword); - expand_bool_pixel = __bool_keyword; - } - /* The boost libraries have code with Iterator::vector vector in it. If - we allow the normal handling, this module will be called recursively, - and the vector will be skipped.; */ - else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword))) - { - enum rid rid_code = (enum rid)(ident->rid_code); - if (ident->type == NT_MACRO) - { - do - (void) cpp_get_token (pfile); - while (--idx > 0); - do - tok = cpp_peek_token (pfile, idx++); - while (tok->type == CPP_PADDING); - ident = altivec_categorize_keyword (tok); - if (ident == C_CPP_HASHNODE (__pixel_keyword)) - { - expand_this = C_CPP_HASHNODE (__vector_keyword); - expand_bool_pixel = __pixel_keyword; - rid_code = RID_MAX; - } - else if (ident == C_CPP_HASHNODE (__bool_keyword)) - { - expand_this = C_CPP_HASHNODE (__vector_keyword); - expand_bool_pixel = __bool_keyword; - rid_code = RID_MAX; - } - else if (ident) - rid_code = (enum rid)(ident->rid_code); - } - - if (rid_code == RID_UNSIGNED || rid_code == RID_LONG - || rid_code == RID_SHORT || rid_code == RID_SIGNED - || rid_code == RID_INT || rid_code == RID_CHAR - || rid_code == RID_FLOAT - || (rid_code == RID_DOUBLE && TARGET_VSX)) - { - expand_this = C_CPP_HASHNODE (__vector_keyword); - /* If the next keyword is bool or pixel, it - will need to be expanded as well. */ - do - tok = cpp_peek_token (pfile, idx++); - while (tok->type == CPP_PADDING); - ident = altivec_categorize_keyword (tok); - - if (ident == C_CPP_HASHNODE (__pixel_keyword)) - expand_bool_pixel = __pixel_keyword; - else if (ident == C_CPP_HASHNODE (__bool_keyword)) - expand_bool_pixel = __bool_keyword; - else - { - /* Try two tokens down, too. */ - do - tok = cpp_peek_token (pfile, idx++); - while (tok->type == CPP_PADDING); - ident = altivec_categorize_keyword (tok); - if (ident == C_CPP_HASHNODE (__pixel_keyword)) - expand_bool_pixel = __pixel_keyword; - else if (ident == C_CPP_HASHNODE (__bool_keyword)) - expand_bool_pixel = __bool_keyword; - } - } - } - } - else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__pixel_keyword)) - { - expand_this = C_CPP_HASHNODE (__pixel_keyword); - expand_bool_pixel = 0; - } - else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__bool_keyword)) - { - expand_this = C_CPP_HASHNODE (__bool_keyword); - expand_bool_pixel = 0; - } - - return expand_this; -} - - -/* Define or undefine a single macro. */ - -static void -rs6000_define_or_undefine_macro (bool define_p, const char *name) -{ - if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) - fprintf (stderr, "#%s %s\n", (define_p) ? "define" : "undef", name); - - if (define_p) - cpp_define (parse_in, name); - else - cpp_undef (parse_in, name); -} - -/* Define or undefine macros based on the current target. If the user does - #pragma GCC target, we need to adjust the macros dynamically. Note, some of - the options needed for builtins have been moved to separate variables, so - have both the target flags and the builtin flags as arguments. */ - -void -rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags, - HOST_WIDE_INT bu_mask) -{ - if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) - fprintf (stderr, - "rs6000_target_modify_macros (%s, " HOST_WIDE_INT_PRINT_HEX - ", " HOST_WIDE_INT_PRINT_HEX ")\n", - (define_p) ? "define" : "undef", - flags, bu_mask); - - /* rs6000_isa_flags based options. */ - rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC"); - if ((flags & OPTION_MASK_PPC_GPOPT) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCSQ"); - if ((flags & OPTION_MASK_PPC_GFXOPT) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCGR"); - if ((flags & OPTION_MASK_POWERPC64) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC64"); - if ((flags & OPTION_MASK_MFCRF) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR4"); - if ((flags & OPTION_MASK_POPCNTB) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5"); - if ((flags & OPTION_MASK_FPRND) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5X"); - if ((flags & OPTION_MASK_CMPB) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6"); - if ((flags & OPTION_MASK_MFPGPR) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6X"); - if ((flags & OPTION_MASK_POPCNTD) != 0) - rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR7"); - if ((flags & OPTION_MASK_SOFT_FLOAT) != 0) - rs6000_define_or_undefine_macro (define_p, "_SOFT_FLOAT"); - if ((flags & OPTION_MASK_RECIP_PRECISION) != 0) - rs6000_define_or_undefine_macro (define_p, "__RECIP_PRECISION__"); - if ((flags & OPTION_MASK_ALTIVEC) != 0) - { - const char *vec_str = (define_p) ? "__VEC__=10206" : "__VEC__"; - rs6000_define_or_undefine_macro (define_p, "__ALTIVEC__"); - rs6000_define_or_undefine_macro (define_p, vec_str); - - /* Define this when supporting context-sensitive keywords. */ - if (!flag_iso) - rs6000_define_or_undefine_macro (define_p, "__APPLE_ALTIVEC__"); - } - if ((flags & OPTION_MASK_VSX) != 0) - rs6000_define_or_undefine_macro (define_p, "__VSX__"); - - /* options from the builtin masks. */ - if ((bu_mask & RS6000_BTM_SPE) != 0) - rs6000_define_or_undefine_macro (define_p, "__SPE__"); - if ((bu_mask & RS6000_BTM_PAIRED) != 0) - rs6000_define_or_undefine_macro (define_p, "__PAIRED__"); - if ((bu_mask & RS6000_BTM_CELL) != 0) - rs6000_define_or_undefine_macro (define_p, "__PPU__"); -} - -void -rs6000_cpu_cpp_builtins (cpp_reader *pfile) -{ - /* Define all of the common macros. */ - rs6000_target_modify_macros (true, rs6000_isa_flags, - rs6000_builtin_mask_calculate ()); - - if (TARGET_FRE) - builtin_define ("__RECIP__"); - if (TARGET_FRES) - builtin_define ("__RECIPF__"); - if (TARGET_FRSQRTE) - builtin_define ("__RSQRTE__"); - if (TARGET_FRSQRTES) - builtin_define ("__RSQRTEF__"); - - if (TARGET_EXTRA_BUILTINS) - { - /* Define the AltiVec syntactic elements. */ - builtin_define ("__vector=__attribute__((altivec(vector__)))"); - builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short"); - builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned"); - - if (!flag_iso) - { - builtin_define ("vector=vector"); - builtin_define ("pixel=pixel"); - builtin_define ("bool=bool"); - builtin_define ("_Bool=_Bool"); - init_vector_keywords (); - - /* Enable context-sensitive macros. */ - cpp_get_callbacks (pfile)->macro_to_expand = rs6000_macro_to_expand; - } - } - if ((!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE))) - ||(TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_DOUBLE_FLOAT)) - builtin_define ("_SOFT_DOUBLE"); - /* Used by lwarx/stwcx. errata work-around. */ - if (rs6000_cpu == PROCESSOR_PPC405) - builtin_define ("__PPC405__"); - /* Used by libstdc++. */ - if (TARGET_NO_LWSYNC) - builtin_define ("__NO_LWSYNC__"); - - if (TARGET_EXTRA_BUILTINS) - { - /* For the VSX builtin functions identical to Altivec functions, just map - the altivec builtin into the vsx version (the altivec functions - generate VSX code if -mvsx). */ - builtin_define ("__builtin_vsx_xxland=__builtin_vec_and"); - builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc"); - builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor"); - builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or"); - builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor"); - builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel"); - builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm"); - - /* Also map the a and m versions of the multiply/add instructions to the - builtin for people blindly going off the instruction manual. */ - builtin_define ("__builtin_vsx_xvmaddadp=__builtin_vsx_xvmadddp"); - builtin_define ("__builtin_vsx_xvmaddmdp=__builtin_vsx_xvmadddp"); - builtin_define ("__builtin_vsx_xvmaddasp=__builtin_vsx_xvmaddsp"); - builtin_define ("__builtin_vsx_xvmaddmsp=__builtin_vsx_xvmaddsp"); - builtin_define ("__builtin_vsx_xvmsubadp=__builtin_vsx_xvmsubdp"); - builtin_define ("__builtin_vsx_xvmsubmdp=__builtin_vsx_xvmsubdp"); - builtin_define ("__builtin_vsx_xvmsubasp=__builtin_vsx_xvmsubsp"); - builtin_define ("__builtin_vsx_xvmsubmsp=__builtin_vsx_xvmsubsp"); - builtin_define ("__builtin_vsx_xvnmaddadp=__builtin_vsx_xvnmadddp"); - builtin_define ("__builtin_vsx_xvnmaddmdp=__builtin_vsx_xvnmadddp"); - builtin_define ("__builtin_vsx_xvnmaddasp=__builtin_vsx_xvnmaddsp"); - builtin_define ("__builtin_vsx_xvnmaddmsp=__builtin_vsx_xvnmaddsp"); - builtin_define ("__builtin_vsx_xvnmsubadp=__builtin_vsx_xvnmsubdp"); - builtin_define ("__builtin_vsx_xvnmsubmdp=__builtin_vsx_xvnmsubdp"); - builtin_define ("__builtin_vsx_xvnmsubasp=__builtin_vsx_xvnmsubsp"); - builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp"); - } - - /* Tell users they can use __builtin_bswap{16,64}. */ - builtin_define ("__HAVE_BSWAP__"); - - /* May be overridden by target configuration. */ - RS6000_CPU_CPP_ENDIAN_BUILTINS(); - - if (TARGET_LONG_DOUBLE_128) - { - builtin_define ("__LONG_DOUBLE_128__"); - builtin_define ("__LONGDOUBLE128"); - } - - switch (TARGET_CMODEL) - { - /* Deliberately omit __CMODEL_SMALL__ since that was the default - before --mcmodel support was added. */ - case CMODEL_MEDIUM: - builtin_define ("__CMODEL_MEDIUM__"); - break; - case CMODEL_LARGE: - builtin_define ("__CMODEL_LARGE__"); - break; - default: - break; - } - - switch (rs6000_current_abi) - { - case ABI_V4: - builtin_define ("_CALL_SYSV"); - break; - case ABI_AIX: - builtin_define ("_CALL_AIXDESC"); - builtin_define ("_CALL_AIX"); - break; - case ABI_DARWIN: - builtin_define ("_CALL_DARWIN"); - break; - default: - break; - } - - /* Let the compiled code know if 'f' class registers will not be available. */ - if (TARGET_SOFT_FLOAT || !TARGET_FPRS) - builtin_define ("__NO_FPRS__"); - - /* Generate defines for Xilinx FPU. */ - if (rs6000_xilinx_fpu) - { - builtin_define ("_XFPU"); - if (rs6000_single_float && ! rs6000_double_float) - { - if (rs6000_simple_fpu) - builtin_define ("_XFPU_SP_LITE"); - else - builtin_define ("_XFPU_SP_FULL"); - } - if (rs6000_double_float) - { - if (rs6000_simple_fpu) - builtin_define ("_XFPU_DP_LITE"); - else - builtin_define ("_XFPU_DP_FULL"); - } - } -} - - -struct altivec_builtin_types -{ - enum rs6000_builtins code; - enum rs6000_builtins overloaded_code; - signed char ret_type; - signed char op1; - signed char op2; - signed char op3; -}; - -const struct altivec_builtin_types altivec_overloaded_builtins[] = { - /* Unary AltiVec/VSX builtins. */ - { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ABS, VSX_BUILTIN_XVABSDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_CEIL, ALTIVEC_BUILTIN_VRFIP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_CEIL, VSX_BUILTIN_XVRDPIP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_EXPTE, ALTIVEC_BUILTIN_VEXPTEFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_FLOOR, VSX_BUILTIN_XVRDPIM, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_FLOOR, ALTIVEC_BUILTIN_VRFIM, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_LOGE, ALTIVEC_BUILTIN_VLOGEFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_V4SI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RE, ALTIVEC_BUILTIN_VREFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RE, VSX_BUILTIN_XVREDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_ROUND, ALTIVEC_BUILTIN_VRFIN, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RECIP, ALTIVEC_BUILTIN_VRECIPFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_RECIP, VSX_BUILTIN_RECIP_V2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_RSQRT, ALTIVEC_BUILTIN_VRSQRTFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RSQRT, VSX_BUILTIN_RSQRT_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RSQRTE, ALTIVEC_BUILTIN_VRSQRTEFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RSQRTE, VSX_BUILTIN_XVRSQRTEDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_TRUNC, ALTIVEC_BUILTIN_VRFIZ, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_TRUNC, VSX_BUILTIN_XVRDPIZ, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSH, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHPX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKHSH, ALTIVEC_BUILTIN_VUPKHSH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKHSH, ALTIVEC_BUILTIN_VUPKHSH, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKHPX, ALTIVEC_BUILTIN_VUPKHPX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKHPX, ALTIVEC_BUILTIN_VUPKHPX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKHSB, ALTIVEC_BUILTIN_VUPKHSB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKHSB, ALTIVEC_BUILTIN_VUPKHSB, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSB, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLPX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSH, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKLPX, ALTIVEC_BUILTIN_VUPKLPX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKLPX, ALTIVEC_BUILTIN_VUPKLPX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKLSH, ALTIVEC_BUILTIN_VUPKLSH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKLSH, ALTIVEC_BUILTIN_VUPKLSH, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, - - /* Binary AltiVec/VSX builtins. */ - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_ADD, VSX_BUILTIN_XVADDDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDFP, ALTIVEC_BUILTIN_VADDFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDC, ALTIVEC_BUILTIN_VADDCUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSBS, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSWS, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSWS, ALTIVEC_BUILTIN_VADDSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSWS, ALTIVEC_BUILTIN_VADDSWS, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSWS, ALTIVEC_BUILTIN_VADDSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSHS, ALTIVEC_BUILTIN_VADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSHS, ALTIVEC_BUILTIN_VADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSHS, ALTIVEC_BUILTIN_VADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSBS, ALTIVEC_BUILTIN_VADDSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSBS, ALTIVEC_BUILTIN_VADDSBS, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDSBS, ALTIVEC_BUILTIN_VADDSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VAVGSW, ALTIVEC_BUILTIN_VAVGSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VAVGUW, ALTIVEC_BUILTIN_VAVGUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VAVGSH, ALTIVEC_BUILTIN_VAVGSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VAVGUH, ALTIVEC_BUILTIN_VAVGUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VAVGSB, ALTIVEC_BUILTIN_VAVGSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VAVGUB, ALTIVEC_BUILTIN_VAVGUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPB, ALTIVEC_BUILTIN_VCMPBFP, - RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQFP, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPEQ, VSX_BUILTIN_XVCMPEQDP, - RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPEQFP, ALTIVEC_BUILTIN_VCMPEQFP, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - - { ALTIVEC_BUILTIN_VEC_VCMPEQUW, ALTIVEC_BUILTIN_VCMPEQUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPEQUW, ALTIVEC_BUILTIN_VCMPEQUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - - { ALTIVEC_BUILTIN_VEC_VCMPEQUH, ALTIVEC_BUILTIN_VCMPEQUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPEQUH, ALTIVEC_BUILTIN_VCMPEQUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - - { ALTIVEC_BUILTIN_VEC_VCMPEQUB, ALTIVEC_BUILTIN_VCMPEQUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPEQUB, ALTIVEC_BUILTIN_VCMPEQUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - - { ALTIVEC_BUILTIN_VEC_CMPGE, ALTIVEC_BUILTIN_VCMPGEFP, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_XVCMPGEDP, - RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSB, - RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSH, - RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSW, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTFP, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPGT, VSX_BUILTIN_XVCMPGTDP, - RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTFP, ALTIVEC_BUILTIN_VCMPGTFP, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTSW, ALTIVEC_BUILTIN_VCMPGTSW, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTSW, ALTIVEC_BUILTIN_VCMPGTSW, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTUW, ALTIVEC_BUILTIN_VCMPGTUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTUW, ALTIVEC_BUILTIN_VCMPGTUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTSH, ALTIVEC_BUILTIN_VCMPGTSH, - RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTSH, ALTIVEC_BUILTIN_VCMPGTSH, - RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTUH, ALTIVEC_BUILTIN_VCMPGTUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTUH, ALTIVEC_BUILTIN_VCMPGTUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTSB, ALTIVEC_BUILTIN_VCMPGTSB, - RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTSB, ALTIVEC_BUILTIN_VCMPGTSB, - RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTUB, ALTIVEC_BUILTIN_VCMPGTUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCMPGTUB, ALTIVEC_BUILTIN_VCMPGTUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLE, ALTIVEC_BUILTIN_VCMPGEFP, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_XVCMPGEDP, - RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUB, - RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSB, - RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUH, - RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSH, - RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUW, - RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSW, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTFP, - RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_CMPLT, VSX_BUILTIN_XVCMPGTDP, - RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_COPYSIGN, VSX_BUILTIN_CPSGNDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_COPYSIGN, ALTIVEC_BUILTIN_COPYSIGN_V4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFUX, - RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFSX, - RS6000_BTI_V4SF, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCFSX, ALTIVEC_BUILTIN_VCFSX, - RS6000_BTI_V4SF, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VCFUX, ALTIVEC_BUILTIN_VCFUX, - RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_CTS, ALTIVEC_BUILTIN_VCTSXS, - RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_CTU, ALTIVEC_BUILTIN_VCTUXS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, - { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVSP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEBX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEBX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEHX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEHX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEHX, ALTIVEC_BUILTIN_LVEHX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEHX, ALTIVEC_BUILTIN_LVEHX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEBX, ALTIVEC_BUILTIN_LVEBX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVEBX, ALTIVEC_BUILTIN_LVEBX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL, - RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_double, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTDI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTDI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_long_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_double, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTDI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTDI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_long_long, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSB, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSH, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSW, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_MAX, VSX_BUILTIN_XVMAXDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXFP, ALTIVEC_BUILTIN_VMAXFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSH, ALTIVEC_BUILTIN_VMAXSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSH, ALTIVEC_BUILTIN_VMAXSH, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSH, ALTIVEC_BUILTIN_VMAXSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSB, ALTIVEC_BUILTIN_VMAXSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSB, ALTIVEC_BUILTIN_VMAXSB, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXSB, ALTIVEC_BUILTIN_VMAXSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHB, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHB, ALTIVEC_BUILTIN_VMRGHB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHB, ALTIVEC_BUILTIN_VMRGHB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGHB, ALTIVEC_BUILTIN_VMRGHB, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLB, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLB, ALTIVEC_BUILTIN_VMRGLB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLB, ALTIVEC_BUILTIN_VMRGLB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMRGLB, ALTIVEC_BUILTIN_VMRGLB, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSB, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSH, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSW, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_MIN, VSX_BUILTIN_XVMINDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINFP, ALTIVEC_BUILTIN_VMINFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSH, ALTIVEC_BUILTIN_VMINSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSH, ALTIVEC_BUILTIN_VMINSH, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSH, ALTIVEC_BUILTIN_VMINSH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSB, ALTIVEC_BUILTIN_VMINSB, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSB, ALTIVEC_BUILTIN_VMINSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINSB, ALTIVEC_BUILTIN_VMINSB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { VSX_BUILTIN_VEC_MUL, VSX_BUILTIN_XVMULSP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { VSX_BUILTIN_VEC_MUL, VSX_BUILTIN_XVMULDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUB, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUH, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULEUB, ALTIVEC_BUILTIN_VMULEUB, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULESB, ALTIVEC_BUILTIN_VMULESB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULEUH, ALTIVEC_BUILTIN_VMULEUH, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULESH, ALTIVEC_BUILTIN_VMULESH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOUB, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOSB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOUH, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOSH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULOSH, ALTIVEC_BUILTIN_VMULOSH, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULOUH, ALTIVEC_BUILTIN_VMULOUH, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULOSB, ALTIVEC_BUILTIN_VMULOSB, - RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VMULOUB, ALTIVEC_BUILTIN_VMULOUB, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRDPI, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRSPI, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUHUM, - RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUHUM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUHUM, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUWUM, - RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUWUM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUWUM, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM, - RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUHUM, ALTIVEC_BUILTIN_VPKUHUM, - RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUHUM, ALTIVEC_BUILTIN_VPKUHUM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUHUM, ALTIVEC_BUILTIN_VPKUHUM, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKPX, ALTIVEC_BUILTIN_VPKPX, - RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKUHUS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKSHSS, - RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKUWUS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKSWSS, - RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKSWSS, ALTIVEC_BUILTIN_VPKSWSS, - RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUWUS, ALTIVEC_BUILTIN_VPKUWUS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKSHSS, ALTIVEC_BUILTIN_VPKSHSS, - RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKUHUS, ALTIVEC_BUILTIN_VPKUHUS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKUHUS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKSHUS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKUWUS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKSWUS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKSWUS, ALTIVEC_BUILTIN_VPKSWUS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VPKSHUS, ALTIVEC_BUILTIN_VPKSHUS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRDPIC, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRSPIC, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VRLW, ALTIVEC_BUILTIN_VRLW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VRLW, ALTIVEC_BUILTIN_VRLW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VRLH, ALTIVEC_BUILTIN_VRLH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VRLH, ALTIVEC_BUILTIN_VRLH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VRLB, ALTIVEC_BUILTIN_VRLB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VRLB, ALTIVEC_BUILTIN_VRLB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTSP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, - { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSLH, ALTIVEC_BUILTIN_VSLH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSLH, ALTIVEC_BUILTIN_VSLH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSLB, ALTIVEC_BUILTIN_VSLB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSLB, ALTIVEC_BUILTIN_VSLB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTB, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTB, ALTIVEC_BUILTIN_VSPLTB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTB, ALTIVEC_BUILTIN_VSPLTB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSPLTB, ALTIVEC_BUILTIN_VSPLTB, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, 0 }, - { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRW, ALTIVEC_BUILTIN_VSRW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRW, ALTIVEC_BUILTIN_VSRW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRH, ALTIVEC_BUILTIN_VSRH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRH, ALTIVEC_BUILTIN_VSRH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRB, ALTIVEC_BUILTIN_VSRB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRB, ALTIVEC_BUILTIN_VSRB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRAW, ALTIVEC_BUILTIN_VSRAW, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRAW, ALTIVEC_BUILTIN_VSRAW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRAH, ALTIVEC_BUILTIN_VSRAH, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRAH, ALTIVEC_BUILTIN_VSRAH, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRAB, ALTIVEC_BUILTIN_VSRAB, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSRAB, ALTIVEC_BUILTIN_VSRAB, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_SUB, VSX_BUILTIN_XVSUBDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBFP, ALTIVEC_BUILTIN_VSUBFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBC, ALTIVEC_BUILTIN_VSUBCUW, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSBS, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSHS, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSWS, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSWS, ALTIVEC_BUILTIN_VSUBSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSWS, ALTIVEC_BUILTIN_VSUBSWS, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSWS, ALTIVEC_BUILTIN_VSUBSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSHS, ALTIVEC_BUILTIN_VSUBSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSHS, ALTIVEC_BUILTIN_VSUBSHS, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSHS, ALTIVEC_BUILTIN_VSUBSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSBS, ALTIVEC_BUILTIN_VSUBSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSBS, ALTIVEC_BUILTIN_VSUBSBS, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBSBS, ALTIVEC_BUILTIN_VSUBSBS, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUM4S, ALTIVEC_BUILTIN_VSUM4UBS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUM4S, ALTIVEC_BUILTIN_VSUM4SBS, - RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUM4S, ALTIVEC_BUILTIN_VSUM4SHS, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUM4SHS, ALTIVEC_BUILTIN_VSUM4SHS, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUM4SBS, ALTIVEC_BUILTIN_VSUM4SBS, - RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_VSUM4UBS, ALTIVEC_BUILTIN_VSUM4UBS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUM2S, ALTIVEC_BUILTIN_VSUM2SWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_SUMS, ALTIVEC_BUILTIN_VSUMSWS, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, - { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, - - /* Ternary AltiVec/VSX builtins. */ - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, - RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, - RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, - RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, - RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMADDFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_MADD, VSX_BUILTIN_XVMADDDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - { ALTIVEC_BUILTIN_VEC_MADDS, ALTIVEC_BUILTIN_VMHADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, - RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_MRADDS, ALTIVEC_BUILTIN_VMHRADDSHS, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, - { VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBSP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUBM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMMBM, - RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUHM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMSHM, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VMSUMSHM, ALTIVEC_BUILTIN_VMSUMSHM, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VMSUMUHM, ALTIVEC_BUILTIN_VMSUMUHM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_VMSUMMBM, ALTIVEC_BUILTIN_VMSUMMBM, - RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VMSUMUBM, ALTIVEC_BUILTIN_VMSUMUBM, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_MSUMS, ALTIVEC_BUILTIN_VMSUMUHS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_MSUMS, ALTIVEC_BUILTIN_VMSUMSHS, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VMSUMSHS, ALTIVEC_BUILTIN_VMSUMSHS, - RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VMSUMUHS, ALTIVEC_BUILTIN_VMSUMUHS, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, - { VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDSP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - { ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_NMSUB, VSX_BUILTIN_XVNMSUBDP, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SI, - RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, - RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, - RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_16QI, - RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_NOT_OPAQUE }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V2DI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_bool_V2DI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_void }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, - { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, - { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, - { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, - { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, - { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_double }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V2DI }, - { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL, - RS6000_BTI_void, RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_bool_V2DI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, - RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, - RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, - RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI, - RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, - RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DF, - RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI, - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI, - RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, - RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SF, - RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI, - RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, - RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI, - RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, - RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI, - RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, - { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, - RS6000_BTI_NOT_OPAQUE }, - - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DF, - RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DI, - RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DI, - RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V2DI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DI, - RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V2DI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SF, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SF, - RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, - RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, - RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V4SI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, - RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_long, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, - RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, - RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, - RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V8HI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, - RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, - RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, - RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V16QI, 0 }, - { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, - RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, - - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DF, - RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DI, - RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DI, - RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V2DI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DI, - RS6000_BTI_void, RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, - ~RS6000_BTI_bool_V2DI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SF, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SF, - RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, - RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V4SI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, - RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, - ~RS6000_BTI_UINTSI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, - ~RS6000_BTI_bool_V4SI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, - ~RS6000_BTI_UINTSI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, - RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, - ~RS6000_BTI_INTSI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, - RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V8HI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, - RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, - ~RS6000_BTI_UINTHI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, - ~RS6000_BTI_bool_V8HI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, - ~RS6000_BTI_UINTHI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, - RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, - ~RS6000_BTI_INTHI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_unsigned_V16QI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_UINTQI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_bool_V16QI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_UINTQI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, - ~RS6000_BTI_INTQI }, - { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, - RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, - ~RS6000_BTI_pixel_V8HI }, - - /* Predicates. */ - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTFP_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_VCMPGT_P, VSX_BUILTIN_XVCMPGTDP_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - - - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQFP_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, VSX_BUILTIN_XVCMPEQDP_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - - - /* cmpge is the same as cmpgt for all cases except floating point. - There is further code to deal with this special case in - altivec_build_resolved_builtin. */ - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSB_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSH_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSW_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGEFP_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, - { ALTIVEC_BUILTIN_VEC_VCMPGE_P, VSX_BUILTIN_XVCMPGEDP_P, - RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, - - { (enum rs6000_builtins) 0, (enum rs6000_builtins) 0, 0, 0, 0, 0 } -}; - - -/* Convert a type stored into a struct altivec_builtin_types as ID, - into a tree. The types are in rs6000_builtin_types: negative values - create a pointer type for the type associated to ~ID. Note it is - a logical NOT, rather than a negation, otherwise you cannot represent - a pointer type for ID 0. */ - -static inline tree -rs6000_builtin_type (int id) -{ - tree t; - t = rs6000_builtin_types[id < 0 ? ~id : id]; - return id < 0 ? build_pointer_type (t) : t; -} - -/* Check whether the type of an argument, T, is compatible with a - type ID stored into a struct altivec_builtin_types. Integer - types are considered compatible; otherwise, the language hook - lang_hooks.types_compatible_p makes the decision. */ - -static inline bool -rs6000_builtin_type_compatible (tree t, int id) -{ - tree builtin_type; - builtin_type = rs6000_builtin_type (id); - if (t == error_mark_node) - return false; - if (INTEGRAL_TYPE_P (t) && INTEGRAL_TYPE_P (builtin_type)) - return true; - else - return lang_hooks.types_compatible_p (t, builtin_type); -} - - -/* In addition to calling fold_convert for EXPR of type TYPE, also - call c_fully_fold to remove any C_MAYBE_CONST_EXPRs that could be - hiding there (PR47197). */ - -static tree -fully_fold_convert (tree type, tree expr) -{ - tree result = fold_convert (type, expr); - bool maybe_const = true; - - if (!c_dialect_cxx ()) - result = c_fully_fold (result, false, &maybe_const); - - return result; -} - -/* Build a tree for a function call to an Altivec non-overloaded builtin. - The overloaded builtin that matched the types and args is described - by DESC. The N arguments are given in ARGS, respectively. - - Actually the only thing it does is calling fold_convert on ARGS, with - a small exception for vec_{all,any}_{ge,le} predicates. */ - -static tree -altivec_build_resolved_builtin (tree *args, int n, - const struct altivec_builtin_types *desc) -{ - tree impl_fndecl = rs6000_builtin_decls[desc->overloaded_code]; - tree ret_type = rs6000_builtin_type (desc->ret_type); - tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (impl_fndecl)); - tree arg_type[3]; - tree call; - - int i; - for (i = 0; i < n; i++) - arg_type[i] = TREE_VALUE (argtypes), argtypes = TREE_CHAIN (argtypes); - - /* The AltiVec overloading implementation is overall gross, but this - is particularly disgusting. The vec_{all,any}_{ge,le} builtins - are completely different for floating-point vs. integer vector - types, because the former has vcmpgefp, but the latter should use - vcmpgtXX. - - In practice, the second and third arguments are swapped, and the - condition (LT vs. EQ, which is recognizable by bit 1 of the first - argument) is reversed. Patch the arguments here before building - the resolved CALL_EXPR. */ - if (desc->code == ALTIVEC_BUILTIN_VEC_VCMPGE_P - && desc->overloaded_code != ALTIVEC_BUILTIN_VCMPGEFP_P) - { - tree t; - t = args[2], args[2] = args[1], args[1] = t; - t = arg_type[2], arg_type[2] = arg_type[1], arg_type[1] = t; - - args[0] = fold_build2 (BIT_XOR_EXPR, TREE_TYPE (args[0]), args[0], - build_int_cst (NULL_TREE, 2)); - } - - switch (n) - { - case 0: - call = build_call_expr (impl_fndecl, 0); - break; - case 1: - call = build_call_expr (impl_fndecl, 1, - fully_fold_convert (arg_type[0], args[0])); - break; - case 2: - call = build_call_expr (impl_fndecl, 2, - fully_fold_convert (arg_type[0], args[0]), - fully_fold_convert (arg_type[1], args[1])); - break; - case 3: - call = build_call_expr (impl_fndecl, 3, - fully_fold_convert (arg_type[0], args[0]), - fully_fold_convert (arg_type[1], args[1]), - fully_fold_convert (arg_type[2], args[2])); - break; - default: - gcc_unreachable (); - } - return fold_convert (ret_type, call); -} - -/* Implementation of the resolve_overloaded_builtin target hook, to - support Altivec's overloaded builtins. */ - -tree -altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, - void *passed_arglist) -{ - vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist); - unsigned int nargs = vec_safe_length (arglist); - enum rs6000_builtins fcode - = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl); - tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); - tree types[3], args[3]; - const struct altivec_builtin_types *desc; - unsigned int n; - - if (!rs6000_overloaded_builtin_p (fcode)) - return NULL_TREE; - - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "altivec_resolve_overloaded_builtin, code = %4d, %s\n", - (int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl))); - - /* For now treat vec_splats and vec_promote as the same. */ - if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS - || fcode == ALTIVEC_BUILTIN_VEC_PROMOTE) - { - tree type, arg; - int size; - int i; - bool unsigned_p; - vec<constructor_elt, va_gc> *vec; - const char *name = fcode == ALTIVEC_BUILTIN_VEC_SPLATS ? "vec_splats": "vec_promote"; - - if (nargs == 0) - { - error ("%s only accepts %d arguments", name, (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE)+1 ); - return error_mark_node; - } - if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS && nargs != 1) - { - error ("%s only accepts 1 argument", name); - return error_mark_node; - } - if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE && nargs != 2) - { - error ("%s only accepts 2 arguments", name); - return error_mark_node; - } - /* Ignore promote's element argument. */ - if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE - && !INTEGRAL_TYPE_P (TREE_TYPE ((*arglist)[1]))) - goto bad; - - arg = (*arglist)[0]; - type = TREE_TYPE (arg); - if (!SCALAR_FLOAT_TYPE_P (type) - && !INTEGRAL_TYPE_P (type)) - goto bad; - unsigned_p = TYPE_UNSIGNED (type); - switch (TYPE_MODE (type)) - { - case DImode: - type = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); - size = 2; - break; - case SImode: - type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); - size = 4; - break; - case HImode: - type = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node); - size = 8; - break; - case QImode: - type = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); - size = 16; - break; - case SFmode: type = V4SF_type_node; size = 4; break; - case DFmode: type = V2DF_type_node; size = 2; break; - default: - goto bad; - } - arg = save_expr (fold_convert (TREE_TYPE (type), arg)); - vec_alloc (vec, size); - for(i = 0; i < size; i++) - { - constructor_elt elt = {NULL_TREE, arg}; - vec->quick_push (elt); - } - return build_constructor (type, vec); - } - - /* For now use pointer tricks to do the extaction, unless we are on VSX - extracting a double from a constant offset. */ - if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT) - { - tree arg1; - tree arg1_type; - tree arg2; - tree arg1_inner_type; - tree decl, stmt; - tree innerptrtype; - enum machine_mode mode; - - /* No second argument. */ - if (nargs != 2) - { - error ("vec_extract only accepts 2 arguments"); - return error_mark_node; - } - - arg2 = (*arglist)[1]; - arg1 = (*arglist)[0]; - arg1_type = TREE_TYPE (arg1); - - if (TREE_CODE (arg1_type) != VECTOR_TYPE) - goto bad; - if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) - goto bad; - - /* If we can use the VSX xxpermdi instruction, use that for extract. */ - mode = TYPE_MODE (arg1_type); - if ((mode == V2DFmode || mode == V2DImode) && VECTOR_MEM_VSX_P (mode) - && TREE_CODE (arg2) == INTEGER_CST - && TREE_INT_CST_HIGH (arg2) == 0 - && (TREE_INT_CST_LOW (arg2) == 0 || TREE_INT_CST_LOW (arg2) == 1)) - { - tree call = NULL_TREE; - - if (mode == V2DFmode) - call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF]; - else if (mode == V2DImode) - call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI]; - - if (call) - return build_call_expr (call, 2, arg1, arg2); - } - - /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */ - arg1_inner_type = TREE_TYPE (arg1_type); - arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, - build_int_cst (TREE_TYPE (arg2), - TYPE_VECTOR_SUBPARTS (arg1_type) - - 1), 0); - decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type); - DECL_EXTERNAL (decl) = 0; - TREE_PUBLIC (decl) = 0; - DECL_CONTEXT (decl) = current_function_decl; - TREE_USED (decl) = 1; - TREE_TYPE (decl) = arg1_type; - TREE_READONLY (decl) = TYPE_READONLY (arg1_type); - DECL_INITIAL (decl) = arg1; - stmt = build1 (DECL_EXPR, arg1_type, decl); - TREE_ADDRESSABLE (decl) = 1; - SET_EXPR_LOCATION (stmt, loc); - stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt); - - innerptrtype = build_pointer_type (arg1_inner_type); - - stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0); - stmt = convert (innerptrtype, stmt); - stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1); - stmt = build_indirect_ref (loc, stmt, RO_NULL); - - return stmt; - } - - /* For now use pointer tricks to do the insertation, unless we are on VSX - inserting a double to a constant offset.. */ - if (fcode == ALTIVEC_BUILTIN_VEC_INSERT) - { - tree arg0; - tree arg1; - tree arg2; - tree arg1_type; - tree arg1_inner_type; - tree decl, stmt; - tree innerptrtype; - enum machine_mode mode; - - /* No second or third arguments. */ - if (nargs != 3) - { - error ("vec_insert only accepts 3 arguments"); - return error_mark_node; - } - - arg0 = (*arglist)[0]; - arg1 = (*arglist)[1]; - arg1_type = TREE_TYPE (arg1); - arg2 = (*arglist)[2]; - - if (TREE_CODE (arg1_type) != VECTOR_TYPE) - goto bad; - if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) - goto bad; - - /* If we can use the VSX xxpermdi instruction, use that for insert. */ - mode = TYPE_MODE (arg1_type); - if ((mode == V2DFmode || mode == V2DImode) && VECTOR_UNIT_VSX_P (mode) - && TREE_CODE (arg2) == INTEGER_CST - && TREE_INT_CST_HIGH (arg2) == 0 - && (TREE_INT_CST_LOW (arg2) == 0 || TREE_INT_CST_LOW (arg2) == 1)) - { - tree call = NULL_TREE; - - if (mode == V2DFmode) - call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DF]; - else if (mode == V2DImode) - call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DI]; - - /* Note, __builtin_vec_insert_<xxx> has vector and scalar types - reversed. */ - if (call) - return build_call_expr (call, 3, arg1, arg0, arg2); - } - - /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */ - arg1_inner_type = TREE_TYPE (arg1_type); - arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, - build_int_cst (TREE_TYPE (arg2), - TYPE_VECTOR_SUBPARTS (arg1_type) - - 1), 0); - decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type); - DECL_EXTERNAL (decl) = 0; - TREE_PUBLIC (decl) = 0; - DECL_CONTEXT (decl) = current_function_decl; - TREE_USED (decl) = 1; - TREE_TYPE (decl) = arg1_type; - TREE_READONLY (decl) = TYPE_READONLY (arg1_type); - DECL_INITIAL (decl) = arg1; - stmt = build1 (DECL_EXPR, arg1_type, decl); - TREE_ADDRESSABLE (decl) = 1; - SET_EXPR_LOCATION (stmt, loc); - stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt); - - innerptrtype = build_pointer_type (arg1_inner_type); - - stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0); - stmt = convert (innerptrtype, stmt); - stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1); - stmt = build_indirect_ref (loc, stmt, RO_NULL); - stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt, - convert (TREE_TYPE (stmt), arg0)); - stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl); - return stmt; - } - - for (n = 0; - !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs; - fnargs = TREE_CHAIN (fnargs), n++) - { - tree decl_type = TREE_VALUE (fnargs); - tree arg = (*arglist)[n]; - tree type; - - if (arg == error_mark_node) - return error_mark_node; - - if (n >= 3) - abort (); - - arg = default_conversion (arg); - - /* The C++ front-end converts float * to const void * using - NOP_EXPR<const void *> (NOP_EXPR<void *> (x)). */ - type = TREE_TYPE (arg); - if (POINTER_TYPE_P (type) - && TREE_CODE (arg) == NOP_EXPR - && lang_hooks.types_compatible_p (TREE_TYPE (arg), - const_ptr_type_node) - && lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (arg, 0)), - ptr_type_node)) - { - arg = TREE_OPERAND (arg, 0); - type = TREE_TYPE (arg); - } - - /* Remove the const from the pointers to simplify the overload - matching further down. */ - if (POINTER_TYPE_P (decl_type) - && POINTER_TYPE_P (type) - && TYPE_QUALS (TREE_TYPE (type)) != 0) - { - if (TYPE_READONLY (TREE_TYPE (type)) - && !TYPE_READONLY (TREE_TYPE (decl_type))) - warning (0, "passing arg %d of %qE discards qualifiers from" - "pointer target type", n + 1, fndecl); - type = build_pointer_type (build_qualified_type (TREE_TYPE (type), - 0)); - arg = fold_convert (type, arg); - } - - args[n] = arg; - types[n] = type; - } - - /* If the number of arguments did not match the prototype, return NULL - and the generic code will issue the appropriate error message. */ - if (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs) - return NULL; - - if (n == 0) - abort (); - - if (fcode == ALTIVEC_BUILTIN_VEC_STEP) - { - if (TREE_CODE (types[0]) != VECTOR_TYPE) - goto bad; - - return build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (types[0])); - } - - for (desc = altivec_overloaded_builtins; - desc->code && desc->code != fcode; desc++) - continue; - - /* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in - the opX fields. */ - for (; desc->code == fcode; desc++) - if ((desc->op1 == RS6000_BTI_NOT_OPAQUE - || rs6000_builtin_type_compatible (types[0], desc->op1)) - && (desc->op2 == RS6000_BTI_NOT_OPAQUE - || rs6000_builtin_type_compatible (types[1], desc->op2)) - && (desc->op3 == RS6000_BTI_NOT_OPAQUE - || rs6000_builtin_type_compatible (types[2], desc->op3))) - return altivec_build_resolved_builtin (args, n, desc); - - bad: - error ("invalid parameter combination for AltiVec intrinsic"); - return error_mark_node; -} diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000-cpus.def b/gcc-4.8.1/gcc/config/rs6000/rs6000-cpus.def deleted file mode 100644 index 3f17c6f23..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000-cpus.def +++ /dev/null @@ -1,175 +0,0 @@ -/* IBM RS/6000 CPU names.. - Copyright (C) 1991-2013 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* ISA masks. */ -#ifndef ISA_2_1_MASKS -#define ISA_2_1_MASKS OPTION_MASK_MFCRF -#define ISA_2_2_MASKS (ISA_2_1_MASKS | OPTION_MASK_POPCNTB) -#define ISA_2_4_MASKS (ISA_2_2_MASKS | OPTION_MASK_FPRND) - - /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add - ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel, - fre, fsqrt, etc. were no longer documented as optional. Group masks by - server and embedded. */ -#define ISA_2_5_MASKS_EMBEDDED (ISA_2_2_MASKS \ - | OPTION_MASK_CMPB \ - | OPTION_MASK_RECIP_PRECISION \ - | OPTION_MASK_PPC_GFXOPT \ - | OPTION_MASK_PPC_GPOPT) - -#define ISA_2_5_MASKS_SERVER (ISA_2_5_MASKS_EMBEDDED | OPTION_MASK_DFP) - - /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but - altivec is a win so enable it. */ -#define ISA_2_6_MASKS_EMBEDDED (ISA_2_5_MASKS_EMBEDDED | OPTION_MASK_POPCNTD) -#define ISA_2_6_MASKS_SERVER (ISA_2_5_MASKS_SERVER \ - | OPTION_MASK_POPCNTD \ - | OPTION_MASK_ALTIVEC \ - | OPTION_MASK_VSX) - -#define POWERPC_7400_MASK (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC) - -/* Deal with ports that do not have -mstrict-align. */ -#ifdef OPTION_MASK_STRICT_ALIGN -#define OPTION_MASK_STRICT_ALIGN_OPTIONAL OPTION_MASK_STRICT_ALIGN -#else -#define OPTION_MASK_STRICT_ALIGN 0 -#define OPTION_MASK_STRICT_ALIGN_OPTIONAL 0 -#ifndef MASK_STRICT_ALIGN -#define MASK_STRICT_ALIGN 0 -#endif -#endif - -/* Mask of all options to set the default isa flags based on -mcpu=<xxx>. */ -#define POWERPC_MASKS (OPTION_MASK_ALTIVEC \ - | OPTION_MASK_CMPB \ - | OPTION_MASK_DFP \ - | OPTION_MASK_DLMZB \ - | OPTION_MASK_FPRND \ - | OPTION_MASK_ISEL \ - | OPTION_MASK_MFCRF \ - | OPTION_MASK_MFPGPR \ - | OPTION_MASK_MULHW \ - | OPTION_MASK_NO_UPDATE \ - | OPTION_MASK_POPCNTB \ - | OPTION_MASK_POPCNTD \ - | OPTION_MASK_POWERPC64 \ - | OPTION_MASK_PPC_GFXOPT \ - | OPTION_MASK_PPC_GPOPT \ - | OPTION_MASK_RECIP_PRECISION \ - | OPTION_MASK_SOFT_FLOAT \ - | OPTION_MASK_STRICT_ALIGN_OPTIONAL \ - | OPTION_MASK_VSX) - -#endif - -/* 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. - - Before including this file, define a macro: - - RS6000_CPU (NAME, CPU, FLAGS) - - where the arguments are the fields of struct rs6000_ptt. */ - -RS6000_CPU ("401", PROCESSOR_PPC403, MASK_SOFT_FLOAT) -RS6000_CPU ("403", PROCESSOR_PPC403, MASK_SOFT_FLOAT | MASK_STRICT_ALIGN) -RS6000_CPU ("405", PROCESSOR_PPC405, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("405fp", PROCESSOR_PPC405, MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("440", PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("440fp", PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("464", PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("464fp", PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("476", PROCESSOR_PPC476, - MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB - | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("476fp", PROCESSOR_PPC476, - MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND - | MASK_CMPB | MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("505", PROCESSOR_MPCCORE, 0) -RS6000_CPU ("601", PROCESSOR_PPC601, MASK_MULTIPLE | MASK_STRING) -RS6000_CPU ("602", PROCESSOR_PPC603, MASK_PPC_GFXOPT) -RS6000_CPU ("603", PROCESSOR_PPC603, MASK_PPC_GFXOPT) -RS6000_CPU ("603e", PROCESSOR_PPC603, MASK_PPC_GFXOPT) -RS6000_CPU ("604", PROCESSOR_PPC604, MASK_PPC_GFXOPT) -RS6000_CPU ("604e", PROCESSOR_PPC604e, MASK_PPC_GFXOPT) -RS6000_CPU ("620", PROCESSOR_PPC620, MASK_PPC_GFXOPT | MASK_POWERPC64) -RS6000_CPU ("630", PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64) -RS6000_CPU ("740", PROCESSOR_PPC750, MASK_PPC_GFXOPT) -RS6000_CPU ("7400", PROCESSOR_PPC7400, POWERPC_7400_MASK) -RS6000_CPU ("7450", PROCESSOR_PPC7450, POWERPC_7400_MASK) -RS6000_CPU ("750", PROCESSOR_PPC750, MASK_PPC_GFXOPT) -RS6000_CPU ("801", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) -RS6000_CPU ("821", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) -RS6000_CPU ("823", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) -RS6000_CPU ("8540", PROCESSOR_PPC8540, MASK_STRICT_ALIGN | MASK_ISEL) -RS6000_CPU ("8548", PROCESSOR_PPC8548, MASK_STRICT_ALIGN | MASK_ISEL) -RS6000_CPU ("a2", PROCESSOR_PPCA2, - MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB | MASK_CMPB - | MASK_NO_UPDATE) -RS6000_CPU ("e300c2", PROCESSOR_PPCE300C2, MASK_SOFT_FLOAT) -RS6000_CPU ("e300c3", PROCESSOR_PPCE300C3, 0) -RS6000_CPU ("e500mc", PROCESSOR_PPCE500MC, MASK_PPC_GFXOPT | MASK_ISEL) -RS6000_CPU ("e500mc64", PROCESSOR_PPCE500MC64, - MASK_POWERPC64 | MASK_PPC_GFXOPT | MASK_ISEL) -RS6000_CPU ("e5500", PROCESSOR_PPCE5500, - MASK_POWERPC64 | MASK_PPC_GFXOPT | MASK_ISEL) -RS6000_CPU ("e6500", PROCESSOR_PPCE6500, POWERPC_7400_MASK | MASK_POWERPC64 - | MASK_MFCRF | MASK_ISEL) -RS6000_CPU ("860", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) -RS6000_CPU ("970", PROCESSOR_POWER4, - POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64) -RS6000_CPU ("cell", PROCESSOR_CELL, - POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64) -RS6000_CPU ("ec603e", PROCESSOR_PPC603, MASK_SOFT_FLOAT) -RS6000_CPU ("G3", PROCESSOR_PPC750, MASK_PPC_GFXOPT) -RS6000_CPU ("G4", PROCESSOR_PPC7450, POWERPC_7400_MASK) -RS6000_CPU ("G5", PROCESSOR_POWER4, - POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64) -RS6000_CPU ("titan", PROCESSOR_TITAN, MASK_MULHW | MASK_DLMZB) -RS6000_CPU ("power3", PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64) -RS6000_CPU ("power4", PROCESSOR_POWER4, MASK_POWERPC64 | MASK_PPC_GPOPT - | MASK_PPC_GFXOPT | MASK_MFCRF) -RS6000_CPU ("power5", PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT - | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB) -RS6000_CPU ("power5+", PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT - | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND) -RS6000_CPU ("power6", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT - | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND - | MASK_CMPB | MASK_DFP | MASK_RECIP_PRECISION) -RS6000_CPU ("power6x", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT - | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND - | MASK_CMPB | MASK_DFP | MASK_MFPGPR | MASK_RECIP_PRECISION) -RS6000_CPU ("power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */ - POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF - | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD - | MASK_VSX | MASK_RECIP_PRECISION) -RS6000_CPU ("power8", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */ - POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF - | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD - | MASK_VSX | MASK_RECIP_PRECISION) -RS6000_CPU ("powerpc", PROCESSOR_POWERPC, 0) -RS6000_CPU ("powerpc64", PROCESSOR_POWERPC64, MASK_PPC_GFXOPT | MASK_POWERPC64) -RS6000_CPU ("rs64", PROCESSOR_RS64A, MASK_PPC_GFXOPT | MASK_POWERPC64) diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000-modes.def b/gcc-4.8.1/gcc/config/rs6000/rs6000-modes.def deleted file mode 100644 index bc18f8a16..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000-modes.def +++ /dev/null @@ -1,43 +0,0 @@ -/* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* 128-bit floating point. ABI_V4 uses IEEE quad, AIX/Darwin - adjust this in rs6000_option_override_internal. */ -FLOAT_MODE (TF, 16, ieee_quad_format); - -/* Add any extra modes needed to represent the condition code. - - For the RS/6000, we need separate modes when unsigned (logical) comparisons - are being done and we need a separate mode for floating-point. We also - 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_MODE (CCUNS); -CC_MODE (CCFP); -CC_MODE (CCEQ); - -/* Vector modes. */ -VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */ -VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ -VECTOR_MODES (INT, 32); /* V32QI V16HI V8SI V4DI */ -VECTOR_MODE (INT, DI, 1); -VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ -VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ -VECTOR_MODES (FLOAT, 32); /* V16HF V8SF V4DF */ diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000-opts.h b/gcc-4.8.1/gcc/config/rs6000/rs6000-opts.h deleted file mode 100644 index fc843fd19..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000-opts.h +++ /dev/null @@ -1,149 +0,0 @@ -/* Definitions of target machine needed for option handling for GNU compiler, - for IBM RS/6000. - Copyright (C) 2010-2013 Free Software Foundation, Inc. - Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef RS6000_OPTS_H -#define RS6000_OPTS_H - -/* Processor type. Order must match cpu attribute in MD file. */ -enum processor_type - { - PROCESSOR_RS64A, - PROCESSOR_MPCCORE, - PROCESSOR_PPC403, - PROCESSOR_PPC405, - PROCESSOR_PPC440, - PROCESSOR_PPC476, - PROCESSOR_PPC601, - PROCESSOR_PPC603, - PROCESSOR_PPC604, - PROCESSOR_PPC604e, - PROCESSOR_PPC620, - PROCESSOR_PPC630, - PROCESSOR_PPC750, - PROCESSOR_PPC7400, - PROCESSOR_PPC7450, - PROCESSOR_PPC8540, - PROCESSOR_PPC8548, - PROCESSOR_PPCE300C2, - PROCESSOR_PPCE300C3, - PROCESSOR_PPCE500MC, - PROCESSOR_PPCE500MC64, - PROCESSOR_PPCE5500, - PROCESSOR_PPCE6500, - PROCESSOR_POWER4, - PROCESSOR_POWER5, - PROCESSOR_POWER6, - PROCESSOR_POWER7, - PROCESSOR_CELL, - PROCESSOR_PPCA2, - PROCESSOR_TITAN -}; - -/* FP processor type. */ -enum fpu_type_t -{ - FPU_NONE, /* No FPU */ - FPU_SF_LITE, /* Limited Single Precision FPU */ - FPU_DF_LITE, /* Limited Double Precision FPU */ - FPU_SF_FULL, /* Full Single Precision FPU */ - FPU_DF_FULL /* Full Double Single Precision FPU */ -}; - -/* 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 -}; - -/* Enumeration to give which calling sequence to use. */ -enum rs6000_abi { - ABI_NONE, - ABI_AIX, /* IBM's AIX */ - ABI_V4, /* System V.4/eabi */ - ABI_DARWIN /* Apple's Darwin (OS X kernel) */ -}; - -/* Small data support types. */ -enum rs6000_sdata_type { - SDATA_NONE, /* No small data support. */ - SDATA_DATA, /* Just put data in .sbss/.sdata, don't use relocs. */ - SDATA_SYSV, /* Use r13 to point to .sdata/.sbss. */ - SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2. */ -}; - -/* Type of traceback to use. */ -enum rs6000_traceback_type { - traceback_default = 0, - traceback_none, - traceback_part, - traceback_full -}; - -/* Code model for 64-bit linux. - small: 16-bit toc offsets. - medium: 32-bit toc offsets, static data and code within 2G of TOC pointer. - large: 32-bit toc offsets, no limit on static data and code. */ -enum rs6000_cmodel { - CMODEL_SMALL, - CMODEL_MEDIUM, - CMODEL_LARGE -}; - -/* Describe which vector unit to use for a given machine mode. */ -enum rs6000_vector { - VECTOR_NONE, /* Type is not a vector or not supported */ - VECTOR_ALTIVEC, /* Use altivec for vector processing */ - VECTOR_VSX, /* Use VSX for vector processing */ - VECTOR_PAIRED, /* Use paired floating point for vectors */ - VECTOR_SPE, /* Use SPE for vector processing */ - VECTOR_OTHER /* Some other vector unit */ -}; - -/* No enumeration is defined to index the -mcpu= values (entries in - processor_target_table), with the type int being used instead, but - we need to distinguish the special "native" value. */ -#define RS6000_CPU_OPTION_NATIVE -1 - -#endif diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000-protos.h b/gcc-4.8.1/gcc/config/rs6000/rs6000-protos.h deleted file mode 100644 index d9bcf1a41..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000-protos.h +++ /dev/null @@ -1,203 +0,0 @@ -/* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 2000-2013 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#ifndef GCC_RS6000_PROTOS_H -#define GCC_RS6000_PROTOS_H - -/* Declare functions in rs6000.c */ - -#ifdef RTX_CODE - -#ifdef TREE_CODE -extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int, - tree, enum machine_mode); -#endif /* TREE_CODE */ - -extern bool easy_altivec_constant (rtx, enum machine_mode); -extern HOST_WIDE_INT const_vector_elt_as_int (rtx, unsigned int); -extern bool macho_lo_sum_memory_operand (rtx, enum machine_mode); -extern int num_insns_constant (rtx, enum machine_mode); -extern int num_insns_constant_wide (HOST_WIDE_INT); -extern int small_data_operand (rtx, enum machine_mode); -extern bool mem_operand_gpr (rtx, enum machine_mode); -extern bool toc_relative_expr_p (const_rtx, bool); -extern bool invalid_e500_subreg (rtx, enum machine_mode); -extern void validate_condition_mode (enum rtx_code, enum machine_mode); -extern bool legitimate_constant_pool_address_p (const_rtx, enum machine_mode, - bool); -extern bool legitimate_indirect_address_p (rtx, int); -extern bool legitimate_indexed_address_p (rtx, int); -extern bool avoiding_indexed_address_p (enum machine_mode); - -extern rtx rs6000_got_register (rtx); -extern rtx find_addr_reg (rtx); -extern rtx gen_easy_altivec_constant (rtx); -extern const char *output_vec_const_move (rtx *); -extern void rs6000_expand_vector_init (rtx, rtx); -extern void paired_expand_vector_init (rtx, rtx); -extern void rs6000_expand_vector_set (rtx, rtx, int); -extern void rs6000_expand_vector_extract (rtx, rtx, int); -extern bool altivec_expand_vec_perm_const (rtx op[4]); -extern bool rs6000_expand_vec_perm_const (rtx op[4]); -extern void rs6000_expand_extract_even (rtx, rtx, rtx); -extern void rs6000_expand_interleave (rtx, rtx, rtx, bool); -extern void build_mask64_2_operands (rtx, rtx *); -extern int expand_block_clear (rtx[]); -extern int expand_block_move (rtx[]); -extern const char * rs6000_output_load_multiple (rtx[]); -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 insvdi_rshift_rlwimi_p (rtx, rtx, rtx); -extern int registers_ok_for_quad_peep (rtx, rtx); -extern int mems_ok_for_quad_peep (rtx, rtx); -extern bool gpr_or_gpr_p (rtx, rtx); -extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, - enum reg_class); -extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, - enum machine_mode, - rtx); -extern bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, - enum reg_class, - enum machine_mode); -extern bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode, - enum machine_mode, - enum reg_class); -extern void rs6000_secondary_reload_inner (rtx, rtx, rtx, bool); -extern void rs6000_secondary_reload_gpr (rtx, rtx, rtx, bool); -extern int paired_emit_vector_cond_expr (rtx, rtx, rtx, - rtx, rtx, rtx); -extern void paired_expand_vector_move (rtx operands[]); - - -extern int ccr_bit (rtx, int); -extern int extract_MB (rtx); -extern int extract_ME (rtx); -extern void rs6000_output_function_entry (FILE *, const char *); -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_sISEL (enum machine_mode, rtx[]); -extern void rs6000_emit_sCOND (enum machine_mode, rtx[]); -extern void rs6000_emit_cbranch (enum machine_mode, rtx[]); -extern char * output_cbranch (rtx, const char *, int, rtx); -extern char * output_e500_flip_gt_bit (rtx, rtx); -extern const char * output_probe_stack_range (rtx, rtx); -extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int); -extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx); -extern int rs6000_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx); -extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx); -extern void rs6000_expand_atomic_compare_and_swap (rtx op[]); -extern void rs6000_expand_atomic_exchange (rtx op[]); -extern void rs6000_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx); -extern void rs6000_emit_swdiv (rtx, rtx, rtx, bool); -extern void rs6000_emit_swrsqrt (rtx, rtx); -extern void output_toc (FILE *, rtx, int, enum machine_mode); -extern rtx rs6000_longcall_ref (rtx); -extern void rs6000_fatal_bad_address (rtx); -extern rtx create_TOC_reference (rtx, rtx); -extern void rs6000_split_multireg_move (rtx, rtx); -extern void rs6000_emit_move (rtx, rtx, enum machine_mode); -extern rtx rs6000_secondary_memory_needed_rtx (enum machine_mode); -extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, - int, int, int, int *); -extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx, - bool, bool); -extern rtx rs6000_find_base_term (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 void rs6000_emit_popcount (rtx, rtx); -extern void rs6000_emit_parity (rtx, rtx); - -extern rtx rs6000_machopic_legitimize_pic_address (rtx, enum machine_mode, - rtx); -extern rtx rs6000_address_for_fpconvert (rtx); -extern rtx rs6000_address_for_altivec (rtx); -extern rtx rs6000_allocate_stack_temp (enum machine_mode, bool, bool); -extern int rs6000_loop_align (rtx); -#endif /* RTX_CODE */ - -#ifdef TREE_CODE -extern unsigned int rs6000_special_round_type_align (tree, unsigned int, - unsigned int); -extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int, - unsigned int); -extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *); -extern rtx rs6000_libcall_value (enum machine_mode); -extern rtx rs6000_va_arg (tree, tree); -extern int function_ok_for_sibcall (tree); -extern void rs6000_elf_declare_function_name (FILE *, const char *, tree); -extern bool rs6000_elf_in_small_data_p (const_tree); -#ifdef ARGS_SIZE_RTX -/* expr.h defines ARGS_SIZE_RTX and `enum direction' */ -extern enum direction function_arg_padding (enum machine_mode, const_tree); -#endif /* ARGS_SIZE_RTX */ - -#endif /* TREE_CODE */ - -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 alias_set_type get_TOC_alias_set (void); -extern void rs6000_emit_prologue (void); -extern void rs6000_emit_load_toc_table (int); -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 void rs6000_call_indirect_aix (rtx, rtx, rtx); -extern void rs6000_aix_asm_output_dwarf_table_ref (char *); -extern void get_ppc476_thunk_name (char name[32]); -extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins); -extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void); - -/* Declare functions in rs6000-c.c */ - -extern void rs6000_pragma_longcall (struct cpp_reader *); -extern void rs6000_cpu_cpp_builtins (struct cpp_reader *); -#ifdef TREE_CODE -extern bool rs6000_pragma_target_parse (tree, tree); -#endif -extern void rs6000_target_modify_macros (bool, HOST_WIDE_INT, HOST_WIDE_INT); -extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, - HOST_WIDE_INT); - -#if TARGET_MACHO -char *output_call (rtx, rtx *, int, int); -#endif - -#ifdef NO_DOLLAR_IN_LABEL -const char * rs6000_xcoff_strip_dollar (const char *); -#endif - -void rs6000_final_prescan_insn (rtx, rtx *operand, int num_operands); - -extern bool rs6000_hard_regno_mode_ok_p[][FIRST_PSEUDO_REGISTER]; -extern unsigned char rs6000_class_max_nregs[][LIM_REG_CLASSES]; -extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER]; -#endif /* rs6000-protos.h */ diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000-tables.opt b/gcc-4.8.1/gcc/config/rs6000/rs6000-tables.opt deleted file mode 100644 index fa87c7fb4..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000-tables.opt +++ /dev/null @@ -1,190 +0,0 @@ -; -*- buffer-read-only: t -*- -; Generated automatically by genopt.sh from rs6000-cpus.def. - -; Copyright (C) 2011-2013 Free Software Foundation, Inc. -; -; This file is part of GCC. -; -; GCC is free software; you can redistribute it and/or modify it under -; the terms of the GNU General Public License as published by the Free -; Software Foundation; either version 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -; WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -Enum -Name(rs6000_cpu_opt_value) Type(int) -Known CPUs (for use with the -mcpu= and -mtune= options): - -EnumValue -Enum(rs6000_cpu_opt_value) String(native) Value(RS6000_CPU_OPTION_NATIVE) DriverOnly - -EnumValue -Enum(rs6000_cpu_opt_value) String(401) Value(0) - -EnumValue -Enum(rs6000_cpu_opt_value) String(403) Value(1) - -EnumValue -Enum(rs6000_cpu_opt_value) String(405) Value(2) - -EnumValue -Enum(rs6000_cpu_opt_value) String(405fp) Value(3) - -EnumValue -Enum(rs6000_cpu_opt_value) String(440) Value(4) - -EnumValue -Enum(rs6000_cpu_opt_value) String(440fp) Value(5) - -EnumValue -Enum(rs6000_cpu_opt_value) String(464) Value(6) - -EnumValue -Enum(rs6000_cpu_opt_value) String(464fp) Value(7) - -EnumValue -Enum(rs6000_cpu_opt_value) String(476) Value(8) - -EnumValue -Enum(rs6000_cpu_opt_value) String(476fp) Value(9) - -EnumValue -Enum(rs6000_cpu_opt_value) String(505) Value(10) - -EnumValue -Enum(rs6000_cpu_opt_value) String(601) Value(11) - -EnumValue -Enum(rs6000_cpu_opt_value) String(602) Value(12) - -EnumValue -Enum(rs6000_cpu_opt_value) String(603) Value(13) - -EnumValue -Enum(rs6000_cpu_opt_value) String(603e) Value(14) - -EnumValue -Enum(rs6000_cpu_opt_value) String(604) Value(15) - -EnumValue -Enum(rs6000_cpu_opt_value) String(604e) Value(16) - -EnumValue -Enum(rs6000_cpu_opt_value) String(620) Value(17) - -EnumValue -Enum(rs6000_cpu_opt_value) String(630) Value(18) - -EnumValue -Enum(rs6000_cpu_opt_value) String(740) Value(19) - -EnumValue -Enum(rs6000_cpu_opt_value) String(7400) Value(20) - -EnumValue -Enum(rs6000_cpu_opt_value) String(7450) Value(21) - -EnumValue -Enum(rs6000_cpu_opt_value) String(750) Value(22) - -EnumValue -Enum(rs6000_cpu_opt_value) String(801) Value(23) - -EnumValue -Enum(rs6000_cpu_opt_value) String(821) Value(24) - -EnumValue -Enum(rs6000_cpu_opt_value) String(823) Value(25) - -EnumValue -Enum(rs6000_cpu_opt_value) String(8540) Value(26) - -EnumValue -Enum(rs6000_cpu_opt_value) String(8548) Value(27) - -EnumValue -Enum(rs6000_cpu_opt_value) String(a2) Value(28) - -EnumValue -Enum(rs6000_cpu_opt_value) String(e300c2) Value(29) - -EnumValue -Enum(rs6000_cpu_opt_value) String(e300c3) Value(30) - -EnumValue -Enum(rs6000_cpu_opt_value) String(e500mc) Value(31) - -EnumValue -Enum(rs6000_cpu_opt_value) String(e500mc64) Value(32) - -EnumValue -Enum(rs6000_cpu_opt_value) String(e5500) Value(33) - -EnumValue -Enum(rs6000_cpu_opt_value) String(e6500) Value(34) - -EnumValue -Enum(rs6000_cpu_opt_value) String(860) Value(35) - -EnumValue -Enum(rs6000_cpu_opt_value) String(970) Value(36) - -EnumValue -Enum(rs6000_cpu_opt_value) String(cell) Value(37) - -EnumValue -Enum(rs6000_cpu_opt_value) String(ec603e) Value(38) - -EnumValue -Enum(rs6000_cpu_opt_value) String(G3) Value(39) - -EnumValue -Enum(rs6000_cpu_opt_value) String(G4) Value(40) - -EnumValue -Enum(rs6000_cpu_opt_value) String(G5) Value(41) - -EnumValue -Enum(rs6000_cpu_opt_value) String(titan) Value(42) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power3) Value(43) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power4) Value(44) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power5) Value(45) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power5+) Value(46) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power6) Value(47) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power6x) Value(48) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power7) Value(49) - -EnumValue -Enum(rs6000_cpu_opt_value) String(power8) Value(50) - -EnumValue -Enum(rs6000_cpu_opt_value) String(powerpc) Value(51) - -EnumValue -Enum(rs6000_cpu_opt_value) String(powerpc64) Value(52) - -EnumValue -Enum(rs6000_cpu_opt_value) String(rs64) Value(53) - diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000.c b/gcc-4.8.1/gcc/config/rs6000/rs6000.c deleted file mode 100644 index cc358dcef..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000.c +++ /dev/null @@ -1,28681 +0,0 @@ -/* Subroutines used for code generation on IBM RS/6000. - Copyright (C) 1991-2013 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "rtl.h" -#include "regs.h" -#include "hard-reg-set.h" -#include "insn-config.h" -#include "conditions.h" -#include "insn-attr.h" -#include "flags.h" -#include "recog.h" -#include "obstack.h" -#include "tree.h" -#include "expr.h" -#include "optabs.h" -#include "except.h" -#include "function.h" -#include "output.h" -#include "dbxout.h" -#include "basic-block.h" -#include "diagnostic-core.h" -#include "toplev.h" -#include "ggc.h" -#include "hashtab.h" -#include "tm_p.h" -#include "target.h" -#include "target-def.h" -#include "common/common-target.h" -#include "langhooks.h" -#include "reload.h" -#include "cfgloop.h" -#include "sched-int.h" -#include "gimple.h" -#include "tree-flow.h" -#include "intl.h" -#include "params.h" -#include "tm-constrs.h" -#include "opts.h" -#include "tree-vectorizer.h" -#include "dumpfile.h" -#if TARGET_XCOFF -#include "xcoffout.h" /* get declarations of xcoff_*_section_name */ -#endif -#if TARGET_MACHO -#include "gstab.h" /* for N_SLINE */ -#endif - -#ifndef TARGET_NO_PROTOTYPE -#define TARGET_NO_PROTOTYPE 0 -#endif - -#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 reload_completed; /* stack info won't change from here on */ - 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 push_p; /* true if we need to allocate stack space */ - int calls_p; /* true if the function makes any calls */ - int world_save_p; /* true if we're saving *everything*: - r13-r31, cr, f14-f31, vrsave, v20-v31 */ - 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 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) */ - 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 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; - HOST_WIDE_INT total_size; /* total bytes allocated for stack */ - int spe_64bit_regs_used; - int savres_strategy; -} rs6000_stack_t; - -/* A C structure for machine-specific, per-function data. - This is added to the cfun structure. */ -typedef struct GTY(()) machine_function -{ - /* 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 (n) with n >= 1 was used. */ - int ra_needs_full_frame; - /* Flags if __builtin_return_address (0) was used. */ - int ra_need_lr; - /* Cache lr_save_p after expansion of builtin_eh_return. */ - int lr_save_state; - /* Whether we need to save the TOC to the reserved stack location in the - function prologue. */ - bool save_toc_in_prologue; - /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4 - varargs save area. */ - HOST_WIDE_INT varargs_save_offset; - /* Temporary stack slot to use for SDmode copies. This slot is - 64-bits wide and is allocated early enough so that the offset - does not overflow the 16-bit load/store offset field. */ - rtx sdmode_stack_slot; -} machine_function; - -/* Support targetm.vectorize.builtin_mask_for_load. */ -static GTY(()) tree altivec_builtin_mask_for_load; - -/* Set to nonzero once AIX common-mode calls have been defined. */ -static GTY(()) int common_mode_defined; - -/* Label number of label created for -mrelocatable, to call to so we can - get the address of the GOT section */ -static int rs6000_pic_labelno; - -#ifdef USING_ELFOS_H -/* Counter for labels which are to be placed in .fixup. */ -int fixuplabelno = 0; -#endif - -/* Whether to use variant of AIX ABI for PowerPC64 Linux. */ -int dot_symbols; - -/* Specify the machine mode that pointers have. After generation of rtl, the - compiler makes no further distinction between pointers and any other objects - of this machine mode. The type is unsigned since not all things that - include rs6000.h also include machmode.h. */ -unsigned rs6000_pmode; - -/* Width in bits of a pointer. */ -unsigned rs6000_pointer_size; - -#ifdef HAVE_AS_GNU_ATTRIBUTE -/* Flag whether floating point values have been passed/returned. */ -static bool rs6000_passes_float; -/* Flag whether vector values have been passed/returned. */ -static bool rs6000_passes_vector; -/* Flag whether small (<= 8 byte) structures have been returned. */ -static bool rs6000_returns_struct; -#endif - -/* Value is TRUE if register/mode pair is acceptable. */ -bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; - -/* Maximum number of registers needed for a given register class and mode. */ -unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES]; - -/* How many registers are needed for a given register and mode. */ -unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; - -/* Map register number to register class. */ -enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER]; - -/* Reload functions based on the type and the vector unit. */ -static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2]; - -static int dbg_cost_ctrl; - -/* Built in types. */ -tree rs6000_builtin_types[RS6000_BTI_MAX]; -tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; - -/* Flag to say the TOC is initialized */ -int toc_initialized; -char toc_label_name[10]; - -/* Cached value of rs6000_variable_issue. This is cached in - rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */ -static short cached_can_issue_more; - -static GTY(()) section *read_only_data_section; -static GTY(()) section *private_data_section; -static GTY(()) section *tls_data_section; -static GTY(()) section *tls_private_data_section; -static GTY(()) section *read_only_private_data_section; -static GTY(()) section *sdata2_section; -static GTY(()) section *toc_section; - -struct builtin_description -{ - const HOST_WIDE_INT mask; - const enum insn_code icode; - const char *const name; - const enum rs6000_builtins code; -}; - -/* Describe the vector unit used for modes. */ -enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES]; -enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES]; - -/* Register classes for various constraints that are based on the target - switches. */ -enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; - -/* Describe the alignment of a vector. */ -int rs6000_vector_align[NUM_MACHINE_MODES]; - -/* Map selected modes to types for builtins. */ -static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2]; - -/* What modes to automatically generate reciprocal divide estimate (fre) and - reciprocal sqrt (frsqrte) for. */ -unsigned char rs6000_recip_bits[MAX_MACHINE_MODE]; - -/* Masks to determine which reciprocal esitmate instructions to generate - automatically. */ -enum rs6000_recip_mask { - RECIP_SF_DIV = 0x001, /* Use divide estimate */ - RECIP_DF_DIV = 0x002, - RECIP_V4SF_DIV = 0x004, - RECIP_V2DF_DIV = 0x008, - - RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */ - RECIP_DF_RSQRT = 0x020, - RECIP_V4SF_RSQRT = 0x040, - RECIP_V2DF_RSQRT = 0x080, - - /* Various combination of flags for -mrecip=xxx. */ - RECIP_NONE = 0, - RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV - | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT - | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT), - - RECIP_HIGH_PRECISION = RECIP_ALL, - - /* On low precision machines like the power5, don't enable double precision - reciprocal square root estimate, since it isn't accurate enough. */ - RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT)) -}; - -/* -mrecip options. */ -static struct -{ - const char *string; /* option name */ - unsigned int mask; /* mask bits to set */ -} recip_options[] = { - { "all", RECIP_ALL }, - { "none", RECIP_NONE }, - { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV - | RECIP_V2DF_DIV) }, - { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) }, - { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) }, - { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT - | RECIP_V2DF_RSQRT) }, - { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) }, - { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) }, -}; - -/* 2 argument gen function typedef. */ -typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx); - -/* Pointer to function (in rs6000-c.c) that can define or undefine target - macros that have changed. Languages that don't support the preprocessor - don't link in rs6000-c.c, so we can't call it directly. */ -void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, HOST_WIDE_INT); - - -/* Target cpu costs. */ - -struct processor_costs { - const int mulsi; /* cost of SImode multiplication. */ - const int mulsi_const; /* cost of SImode multiplication by constant. */ - const int mulsi_const9; /* cost of SImode mult by short constant. */ - const int muldi; /* cost of DImode multiplication. */ - const int divsi; /* cost of SImode division. */ - const int divdi; /* cost of DImode division. */ - const int fp; /* cost of simple SFmode and DFmode insns. */ - const int dmul; /* cost of DFmode multiplication (and fmadd). */ - const int sdiv; /* cost of SFmode division (fdivs). */ - const int ddiv; /* cost of DFmode division (fdiv). */ - const int cache_line_size; /* cache line size in bytes. */ - const int l1_cache_size; /* size of l1 cache, in kilobytes. */ - const int l2_cache_size; /* size of l2 cache, in kilobytes. */ - const int simultaneous_prefetches; /* number of parallel prefetch - operations. */ -}; - -const struct processor_costs *rs6000_cost; - -/* Processor costs (relative to an add) */ - -/* Instruction size costs on 32bit processors. */ -static const -struct processor_costs size32_cost = { - COSTS_N_INSNS (1), /* mulsi */ - COSTS_N_INSNS (1), /* mulsi_const */ - COSTS_N_INSNS (1), /* mulsi_const9 */ - COSTS_N_INSNS (1), /* muldi */ - COSTS_N_INSNS (1), /* divsi */ - COSTS_N_INSNS (1), /* divdi */ - COSTS_N_INSNS (1), /* fp */ - COSTS_N_INSNS (1), /* dmul */ - COSTS_N_INSNS (1), /* sdiv */ - COSTS_N_INSNS (1), /* ddiv */ - 32, - 0, - 0, - 0, -}; - -/* Instruction size costs on 64bit processors. */ -static const -struct processor_costs size64_cost = { - COSTS_N_INSNS (1), /* mulsi */ - COSTS_N_INSNS (1), /* mulsi_const */ - COSTS_N_INSNS (1), /* mulsi_const9 */ - COSTS_N_INSNS (1), /* muldi */ - COSTS_N_INSNS (1), /* divsi */ - COSTS_N_INSNS (1), /* divdi */ - COSTS_N_INSNS (1), /* fp */ - COSTS_N_INSNS (1), /* dmul */ - COSTS_N_INSNS (1), /* sdiv */ - COSTS_N_INSNS (1), /* ddiv */ - 128, - 0, - 0, - 0, -}; - -/* Instruction costs on RS64A processors. */ -static const -struct processor_costs rs64a_cost = { - COSTS_N_INSNS (20), /* mulsi */ - COSTS_N_INSNS (12), /* mulsi_const */ - COSTS_N_INSNS (8), /* mulsi_const9 */ - COSTS_N_INSNS (34), /* muldi */ - COSTS_N_INSNS (65), /* divsi */ - COSTS_N_INSNS (67), /* divdi */ - COSTS_N_INSNS (4), /* fp */ - COSTS_N_INSNS (4), /* dmul */ - COSTS_N_INSNS (31), /* sdiv */ - COSTS_N_INSNS (31), /* ddiv */ - 128, /* cache line size */ - 128, /* l1 cache */ - 2048, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on MPCCORE processors. */ -static const -struct processor_costs mpccore_cost = { - COSTS_N_INSNS (2), /* mulsi */ - COSTS_N_INSNS (2), /* mulsi_const */ - COSTS_N_INSNS (2), /* mulsi_const9 */ - COSTS_N_INSNS (2), /* muldi */ - COSTS_N_INSNS (6), /* divsi */ - COSTS_N_INSNS (6), /* divdi */ - COSTS_N_INSNS (4), /* fp */ - COSTS_N_INSNS (5), /* dmul */ - COSTS_N_INSNS (10), /* sdiv */ - COSTS_N_INSNS (17), /* ddiv */ - 32, /* cache line size */ - 4, /* l1 cache */ - 16, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC403 processors. */ -static const -struct processor_costs ppc403_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (33), /* divsi */ - COSTS_N_INSNS (33), /* divdi */ - COSTS_N_INSNS (11), /* fp */ - COSTS_N_INSNS (11), /* dmul */ - COSTS_N_INSNS (11), /* sdiv */ - COSTS_N_INSNS (11), /* ddiv */ - 32, /* cache line size */ - 4, /* l1 cache */ - 16, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC405 processors. */ -static const -struct processor_costs ppc405_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (3), /* mulsi_const9 */ - COSTS_N_INSNS (5), /* muldi */ - COSTS_N_INSNS (35), /* divsi */ - COSTS_N_INSNS (35), /* divdi */ - COSTS_N_INSNS (11), /* fp */ - COSTS_N_INSNS (11), /* dmul */ - COSTS_N_INSNS (11), /* sdiv */ - COSTS_N_INSNS (11), /* ddiv */ - 32, /* cache line size */ - 16, /* l1 cache */ - 128, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC440 processors. */ -static const -struct processor_costs ppc440_cost = { - COSTS_N_INSNS (3), /* mulsi */ - COSTS_N_INSNS (2), /* mulsi_const */ - COSTS_N_INSNS (2), /* mulsi_const9 */ - COSTS_N_INSNS (3), /* muldi */ - COSTS_N_INSNS (34), /* divsi */ - COSTS_N_INSNS (34), /* divdi */ - COSTS_N_INSNS (5), /* fp */ - COSTS_N_INSNS (5), /* dmul */ - COSTS_N_INSNS (19), /* sdiv */ - COSTS_N_INSNS (33), /* ddiv */ - 32, /* cache line size */ - 32, /* l1 cache */ - 256, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC476 processors. */ -static const -struct processor_costs ppc476_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (11), /* divsi */ - COSTS_N_INSNS (11), /* divdi */ - COSTS_N_INSNS (6), /* fp */ - COSTS_N_INSNS (6), /* dmul */ - COSTS_N_INSNS (19), /* sdiv */ - COSTS_N_INSNS (33), /* ddiv */ - 32, /* l1 cache line size */ - 32, /* l1 cache */ - 512, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC601 processors. */ -static const -struct processor_costs ppc601_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (5), /* mulsi_const */ - COSTS_N_INSNS (5), /* mulsi_const9 */ - COSTS_N_INSNS (5), /* muldi */ - COSTS_N_INSNS (36), /* divsi */ - COSTS_N_INSNS (36), /* divdi */ - COSTS_N_INSNS (4), /* fp */ - COSTS_N_INSNS (5), /* dmul */ - COSTS_N_INSNS (17), /* sdiv */ - COSTS_N_INSNS (31), /* ddiv */ - 32, /* cache line size */ - 32, /* l1 cache */ - 256, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC603 processors. */ -static const -struct processor_costs ppc603_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (3), /* mulsi_const */ - COSTS_N_INSNS (2), /* mulsi_const9 */ - COSTS_N_INSNS (5), /* muldi */ - COSTS_N_INSNS (37), /* divsi */ - COSTS_N_INSNS (37), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (4), /* dmul */ - COSTS_N_INSNS (18), /* sdiv */ - COSTS_N_INSNS (33), /* ddiv */ - 32, /* cache line size */ - 8, /* l1 cache */ - 64, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC604 processors. */ -static const -struct processor_costs ppc604_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (20), /* divsi */ - COSTS_N_INSNS (20), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (18), /* sdiv */ - COSTS_N_INSNS (32), /* ddiv */ - 32, /* cache line size */ - 16, /* l1 cache */ - 512, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC604e processors. */ -static const -struct processor_costs ppc604e_cost = { - COSTS_N_INSNS (2), /* mulsi */ - COSTS_N_INSNS (2), /* mulsi_const */ - COSTS_N_INSNS (2), /* mulsi_const9 */ - COSTS_N_INSNS (2), /* muldi */ - COSTS_N_INSNS (20), /* divsi */ - COSTS_N_INSNS (20), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (18), /* sdiv */ - COSTS_N_INSNS (32), /* ddiv */ - 32, /* cache line size */ - 32, /* l1 cache */ - 1024, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC620 processors. */ -static const -struct processor_costs ppc620_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (3), /* mulsi_const9 */ - COSTS_N_INSNS (7), /* muldi */ - COSTS_N_INSNS (21), /* divsi */ - COSTS_N_INSNS (37), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (18), /* sdiv */ - COSTS_N_INSNS (32), /* ddiv */ - 128, /* cache line size */ - 32, /* l1 cache */ - 1024, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC630 processors. */ -static const -struct processor_costs ppc630_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (3), /* mulsi_const9 */ - COSTS_N_INSNS (7), /* muldi */ - COSTS_N_INSNS (21), /* divsi */ - COSTS_N_INSNS (37), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (17), /* sdiv */ - COSTS_N_INSNS (21), /* ddiv */ - 128, /* cache line size */ - 64, /* l1 cache */ - 1024, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on Cell processor. */ -/* COSTS_N_INSNS (1) ~ one add. */ -static const -struct processor_costs ppccell_cost = { - COSTS_N_INSNS (9/2)+2, /* mulsi */ - COSTS_N_INSNS (6/2), /* mulsi_const */ - COSTS_N_INSNS (6/2), /* mulsi_const9 */ - COSTS_N_INSNS (15/2)+2, /* muldi */ - COSTS_N_INSNS (38/2), /* divsi */ - COSTS_N_INSNS (70/2), /* divdi */ - COSTS_N_INSNS (10/2), /* fp */ - COSTS_N_INSNS (10/2), /* dmul */ - COSTS_N_INSNS (74/2), /* sdiv */ - COSTS_N_INSNS (74/2), /* ddiv */ - 128, /* cache line size */ - 32, /* l1 cache */ - 512, /* l2 cache */ - 6, /* streams */ -}; - -/* Instruction costs on PPC750 and PPC7400 processors. */ -static const -struct processor_costs ppc750_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (3), /* mulsi_const */ - COSTS_N_INSNS (2), /* mulsi_const9 */ - COSTS_N_INSNS (5), /* muldi */ - COSTS_N_INSNS (17), /* divsi */ - COSTS_N_INSNS (17), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (17), /* sdiv */ - COSTS_N_INSNS (31), /* ddiv */ - 32, /* cache line size */ - 32, /* l1 cache */ - 512, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC7450 processors. */ -static const -struct processor_costs ppc7450_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (3), /* mulsi_const */ - COSTS_N_INSNS (3), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (23), /* divsi */ - COSTS_N_INSNS (23), /* divdi */ - COSTS_N_INSNS (5), /* fp */ - COSTS_N_INSNS (5), /* dmul */ - COSTS_N_INSNS (21), /* sdiv */ - COSTS_N_INSNS (35), /* ddiv */ - 32, /* cache line size */ - 32, /* l1 cache */ - 1024, /* l2 cache */ - 1, /* streams */ -}; - -/* Instruction costs on PPC8540 processors. */ -static const -struct processor_costs ppc8540_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (19), /* divsi */ - COSTS_N_INSNS (19), /* divdi */ - COSTS_N_INSNS (4), /* fp */ - COSTS_N_INSNS (4), /* dmul */ - COSTS_N_INSNS (29), /* sdiv */ - COSTS_N_INSNS (29), /* ddiv */ - 32, /* cache line size */ - 32, /* l1 cache */ - 256, /* l2 cache */ - 1, /* prefetch streams /*/ -}; - -/* Instruction costs on E300C2 and E300C3 cores. */ -static const -struct processor_costs ppce300c2c3_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (19), /* divsi */ - COSTS_N_INSNS (19), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (4), /* dmul */ - COSTS_N_INSNS (18), /* sdiv */ - COSTS_N_INSNS (33), /* ddiv */ - 32, - 16, /* l1 cache */ - 16, /* l2 cache */ - 1, /* prefetch streams /*/ -}; - -/* Instruction costs on PPCE500MC processors. */ -static const -struct processor_costs ppce500mc_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (14), /* divsi */ - COSTS_N_INSNS (14), /* divdi */ - COSTS_N_INSNS (8), /* fp */ - COSTS_N_INSNS (10), /* dmul */ - COSTS_N_INSNS (36), /* sdiv */ - COSTS_N_INSNS (66), /* ddiv */ - 64, /* cache line size */ - 32, /* l1 cache */ - 128, /* l2 cache */ - 1, /* prefetch streams /*/ -}; - -/* Instruction costs on PPCE500MC64 processors. */ -static const -struct processor_costs ppce500mc64_cost = { - COSTS_N_INSNS (4), /* mulsi */ - COSTS_N_INSNS (4), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (14), /* divsi */ - COSTS_N_INSNS (14), /* divdi */ - COSTS_N_INSNS (4), /* fp */ - COSTS_N_INSNS (10), /* dmul */ - COSTS_N_INSNS (36), /* sdiv */ - COSTS_N_INSNS (66), /* ddiv */ - 64, /* cache line size */ - 32, /* l1 cache */ - 128, /* l2 cache */ - 1, /* prefetch streams /*/ -}; - -/* Instruction costs on PPCE5500 processors. */ -static const -struct processor_costs ppce5500_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (5), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (5), /* muldi */ - COSTS_N_INSNS (14), /* divsi */ - COSTS_N_INSNS (14), /* divdi */ - COSTS_N_INSNS (7), /* fp */ - COSTS_N_INSNS (10), /* dmul */ - COSTS_N_INSNS (36), /* sdiv */ - COSTS_N_INSNS (66), /* ddiv */ - 64, /* cache line size */ - 32, /* l1 cache */ - 128, /* l2 cache */ - 1, /* prefetch streams /*/ -}; - -/* Instruction costs on PPCE6500 processors. */ -static const -struct processor_costs ppce6500_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (5), /* mulsi_const */ - COSTS_N_INSNS (4), /* mulsi_const9 */ - COSTS_N_INSNS (5), /* muldi */ - COSTS_N_INSNS (14), /* divsi */ - COSTS_N_INSNS (14), /* divdi */ - COSTS_N_INSNS (7), /* fp */ - COSTS_N_INSNS (10), /* dmul */ - COSTS_N_INSNS (36), /* sdiv */ - COSTS_N_INSNS (66), /* ddiv */ - 64, /* cache line size */ - 32, /* l1 cache */ - 128, /* l2 cache */ - 1, /* prefetch streams /*/ -}; - -/* Instruction costs on AppliedMicro Titan processors. */ -static const -struct processor_costs titan_cost = { - COSTS_N_INSNS (5), /* mulsi */ - COSTS_N_INSNS (5), /* mulsi_const */ - COSTS_N_INSNS (5), /* mulsi_const9 */ - COSTS_N_INSNS (5), /* muldi */ - COSTS_N_INSNS (18), /* divsi */ - COSTS_N_INSNS (18), /* divdi */ - COSTS_N_INSNS (10), /* fp */ - COSTS_N_INSNS (10), /* dmul */ - COSTS_N_INSNS (46), /* sdiv */ - COSTS_N_INSNS (72), /* ddiv */ - 32, /* cache line size */ - 32, /* l1 cache */ - 512, /* l2 cache */ - 1, /* prefetch streams /*/ -}; - -/* Instruction costs on POWER4 and POWER5 processors. */ -static const -struct processor_costs power4_cost = { - COSTS_N_INSNS (3), /* mulsi */ - COSTS_N_INSNS (2), /* mulsi_const */ - COSTS_N_INSNS (2), /* mulsi_const9 */ - COSTS_N_INSNS (4), /* muldi */ - COSTS_N_INSNS (18), /* divsi */ - COSTS_N_INSNS (34), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (17), /* sdiv */ - COSTS_N_INSNS (17), /* ddiv */ - 128, /* cache line size */ - 32, /* l1 cache */ - 1024, /* l2 cache */ - 8, /* prefetch streams /*/ -}; - -/* Instruction costs on POWER6 processors. */ -static const -struct processor_costs power6_cost = { - COSTS_N_INSNS (8), /* mulsi */ - COSTS_N_INSNS (8), /* mulsi_const */ - COSTS_N_INSNS (8), /* mulsi_const9 */ - COSTS_N_INSNS (8), /* muldi */ - COSTS_N_INSNS (22), /* divsi */ - COSTS_N_INSNS (28), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (13), /* sdiv */ - COSTS_N_INSNS (16), /* ddiv */ - 128, /* cache line size */ - 64, /* l1 cache */ - 2048, /* l2 cache */ - 16, /* prefetch streams */ -}; - -/* Instruction costs on POWER7 processors. */ -static const -struct processor_costs power7_cost = { - COSTS_N_INSNS (2), /* mulsi */ - COSTS_N_INSNS (2), /* mulsi_const */ - COSTS_N_INSNS (2), /* mulsi_const9 */ - COSTS_N_INSNS (2), /* muldi */ - COSTS_N_INSNS (18), /* divsi */ - COSTS_N_INSNS (34), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (13), /* sdiv */ - COSTS_N_INSNS (16), /* ddiv */ - 128, /* cache line size */ - 32, /* l1 cache */ - 256, /* l2 cache */ - 12, /* prefetch streams */ -}; - -/* Instruction costs on POWER A2 processors. */ -static const -struct processor_costs ppca2_cost = { - COSTS_N_INSNS (16), /* mulsi */ - COSTS_N_INSNS (16), /* mulsi_const */ - COSTS_N_INSNS (16), /* mulsi_const9 */ - COSTS_N_INSNS (16), /* muldi */ - COSTS_N_INSNS (22), /* divsi */ - COSTS_N_INSNS (28), /* divdi */ - COSTS_N_INSNS (3), /* fp */ - COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (59), /* sdiv */ - COSTS_N_INSNS (72), /* ddiv */ - 64, - 16, /* l1 cache */ - 2048, /* l2 cache */ - 16, /* prefetch streams */ -}; - - -/* Table that classifies rs6000 builtin functions (pure, const, etc.). */ -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) \ - { NAME, ICODE, MASK, ATTR }, - -struct rs6000_builtin_info_type { - const char *name; - const enum insn_code icode; - const HOST_WIDE_INT mask; - const unsigned attr; -}; - -static const struct rs6000_builtin_info_type rs6000_builtin_info[] = -{ -#include "rs6000-builtin.def" -}; - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -/* Support for -mveclibabi=<xxx> to control which vector library to use. */ -static tree (*rs6000_veclib_handler) (tree, tree, tree); - - -static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool); -static bool spe_func_has_64bit_regs_p (void); -static struct machine_function * rs6000_init_machine_status (void); -static int rs6000_ra_ever_killed (void); -static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *); -static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *); -static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *); -static tree rs6000_builtin_vectorized_libmass (tree, tree, tree); -static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT); -static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool); -static bool rs6000_debug_rtx_costs (rtx, int, int, int, int *, bool); -static int rs6000_debug_address_cost (rtx, enum machine_mode, addr_space_t, - bool); -static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int); -static bool is_microcoded_insn (rtx); -static bool is_nonpipeline_insn (rtx); -static bool is_cracked_insn (rtx); -static bool is_load_insn (rtx, rtx *); -static bool is_store_insn (rtx, rtx *); -static bool set_to_load_agen (rtx,rtx); -static bool insn_terminates_group_p (rtx , enum group_termination); -static bool insn_must_be_first_in_group (rtx); -static bool insn_must_be_last_in_group (rtx); -static void altivec_init_builtins (void); -static tree builtin_function_type (enum machine_mode, enum machine_mode, - enum machine_mode, enum machine_mode, - enum rs6000_builtins, const char *name); -static void rs6000_common_init_builtins (void); -static void paired_init_builtins (void); -static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx); -static void spe_init_builtins (void); -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 is_altivec_return_reg (rtx, void *); -int easy_vector_constant (rtx, enum machine_mode); -static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode); -static rtx rs6000_legitimize_tls_address (rtx, enum tls_model); -static int rs6000_tls_symbol_ref_1 (rtx *, void *); -static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *); -static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, - bool, bool); -#if TARGET_MACHO -static void macho_branch_islands (void); -#endif -static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int, - int, int *); -static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int, - int, int, int *); -static bool rs6000_mode_dependent_address (const_rtx); -static bool rs6000_debug_mode_dependent_address (const_rtx); -static enum reg_class rs6000_secondary_reload_class (enum reg_class, - enum machine_mode, rtx); -static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class, - enum machine_mode, - rtx); -static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class); -static enum reg_class rs6000_debug_preferred_reload_class (rtx, - enum reg_class); -static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class, - enum machine_mode); -static bool rs6000_debug_secondary_memory_needed (enum reg_class, - enum reg_class, - enum machine_mode); -static bool rs6000_cannot_change_mode_class (enum machine_mode, - enum machine_mode, - enum reg_class); -static bool rs6000_debug_cannot_change_mode_class (enum machine_mode, - enum machine_mode, - enum reg_class); -static bool rs6000_save_toc_in_prologue_p (void); - -rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int, - int, int *) - = rs6000_legitimize_reload_address; - -static bool (*rs6000_mode_dependent_address_ptr) (const_rtx) - = rs6000_mode_dependent_address; - -enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, - enum machine_mode, rtx) - = rs6000_secondary_reload_class; - -enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class) - = rs6000_preferred_reload_class; - -bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class, - enum machine_mode) - = rs6000_secondary_memory_needed; - -bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode, - enum machine_mode, - enum reg_class) - = rs6000_cannot_change_mode_class; - -const int INSN_NOT_AVAILABLE = -1; - -static void rs6000_print_isa_options (FILE *, int, const char *, - HOST_WIDE_INT); -static void rs6000_print_builtin_options (FILE *, int, const char *, - HOST_WIDE_INT); - -/* Hash table stuff for keeping track of TOC entries. */ - -struct GTY(()) 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 GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table; - -/* Hash table to keep track of the argument types for builtin functions. */ - -struct GTY(()) builtin_hash_struct -{ - tree type; - enum machine_mode mode[4]; /* return value + 3 arguments. */ - unsigned char uns_p[4]; /* and whether the types are unsigned. */ -}; - -static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table; - - -/* Default register names. */ -char rs6000_reg_names[][8] = -{ - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", - "mq", "lr", "ctr","ap", - "0", "1", "2", "3", "4", "5", "6", "7", - "ca", - /* AltiVec registers. */ - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "10", "11", "12", "13", "14", "15", - "16", "17", "18", "19", "20", "21", "22", "23", - "24", "25", "26", "27", "28", "29", "30", "31", - "vrsave", "vscr", - /* SPE registers. */ - "spe_acc", "spefscr", - /* Soft frame pointer. */ - "sfp" -}; - -#ifdef TARGET_REGNAMES -static const char alt_reg_names[][8] = -{ - "%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", - "ca", - /* AltiVec registers. */ - "%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 registers. */ - "spe_acc", "spefscr", - /* Soft frame pointer. */ - "sfp" -}; -#endif - -/* Table of valid machine attributes. */ - -static const struct attribute_spec rs6000_attribute_table[] = -{ - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, - affects_type_identity } */ - { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute, - false }, - { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute, - false }, - { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute, - false }, - { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute, - false }, - { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute, - false }, -#ifdef SUBTARGET_ATTRIBUTE_TABLE - SUBTARGET_ATTRIBUTE_TABLE, -#endif - { NULL, 0, 0, false, false, false, NULL, false } -}; - -#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)) - -/* Initialize the GCC target structure. */ -#undef TARGET_ATTRIBUTE_TABLE -#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table -#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES -#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes -#undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P -#define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p - -#undef TARGET_ASM_ALIGNED_DI_OP -#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP - -/* Default unaligned ops are only provided for ELF. Find the ops needed - for non-ELF systems. */ -#ifndef OBJECT_FORMAT_ELF -#if TARGET_XCOFF -/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on - 64-bit targets. */ -#undef TARGET_ASM_UNALIGNED_HI_OP -#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2," -#undef TARGET_ASM_UNALIGNED_SI_OP -#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4," -#undef TARGET_ASM_UNALIGNED_DI_OP -#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8," -#else -/* For Darwin. */ -#undef TARGET_ASM_UNALIGNED_HI_OP -#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t" -#undef TARGET_ASM_UNALIGNED_SI_OP -#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t" -#undef TARGET_ASM_UNALIGNED_DI_OP -#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t" -#undef TARGET_ASM_ALIGNED_DI_OP -#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t" -#endif -#endif - -/* This hook deals with fixups for relocatable code and DI-mode objects - in 64-bit code. */ -#undef TARGET_ASM_INTEGER -#define TARGET_ASM_INTEGER rs6000_assemble_integer - -#if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO -#undef TARGET_ASM_ASSEMBLE_VISIBILITY -#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility -#endif - -#undef TARGET_SET_UP_BY_PROLOGUE -#define TARGET_SET_UP_BY_PROLOGUE rs6000_set_up_by_prologue - -#undef TARGET_HAVE_TLS -#define TARGET_HAVE_TLS HAVE_AS_TLS - -#undef TARGET_CANNOT_FORCE_CONST_MEM -#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem - -#undef TARGET_DELEGITIMIZE_ADDRESS -#define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address - -#undef TARGET_CONST_NOT_OK_FOR_DEBUG_P -#define TARGET_CONST_NOT_OK_FOR_DEBUG_P rs6000_const_not_ok_for_debug_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_ASM_OUTPUT_ADDR_CONST_EXTRA -#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra - -#undef TARGET_LEGITIMIZE_ADDRESS -#define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address - -#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_INIT -#define TARGET_SCHED_INIT rs6000_sched_init -#undef TARGET_SCHED_FINISH -#define TARGET_SCHED_FINISH rs6000_sched_finish -#undef TARGET_SCHED_REORDER -#define TARGET_SCHED_REORDER rs6000_sched_reorder -#undef TARGET_SCHED_REORDER2 -#define TARGET_SCHED_REORDER2 rs6000_sched_reorder2 - -#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD -#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead - -#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD -#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard - -#undef TARGET_SCHED_ALLOC_SCHED_CONTEXT -#define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context -#undef TARGET_SCHED_INIT_SCHED_CONTEXT -#define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context -#undef TARGET_SCHED_SET_SCHED_CONTEXT -#define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context -#undef TARGET_SCHED_FREE_SCHED_CONTEXT -#define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context - -#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD -#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load -#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT -#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \ - rs6000_builtin_support_vector_misalignment -#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE -#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable -#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST -#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \ - rs6000_builtin_vectorization_cost -#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE -#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \ - rs6000_preferred_simd_mode -#undef TARGET_VECTORIZE_INIT_COST -#define TARGET_VECTORIZE_INIT_COST rs6000_init_cost -#undef TARGET_VECTORIZE_ADD_STMT_COST -#define TARGET_VECTORIZE_ADD_STMT_COST rs6000_add_stmt_cost -#undef TARGET_VECTORIZE_FINISH_COST -#define TARGET_VECTORIZE_FINISH_COST rs6000_finish_cost -#undef TARGET_VECTORIZE_DESTROY_COST_DATA -#define TARGET_VECTORIZE_DESTROY_COST_DATA rs6000_destroy_cost_data - -#undef TARGET_INIT_BUILTINS -#define TARGET_INIT_BUILTINS rs6000_init_builtins -#undef TARGET_BUILTIN_DECL -#define TARGET_BUILTIN_DECL rs6000_builtin_decl - -#undef TARGET_EXPAND_BUILTIN -#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin - -#undef TARGET_MANGLE_TYPE -#define TARGET_MANGLE_TYPE rs6000_mangle_type - -#undef TARGET_INIT_LIBFUNCS -#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs - -#if TARGET_MACHO -#undef TARGET_BINDS_LOCAL_P -#define TARGET_BINDS_LOCAL_P darwin_binds_local_p -#endif - -#undef TARGET_MS_BITFIELD_LAYOUT_P -#define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p - -#undef TARGET_ASM_OUTPUT_MI_THUNK -#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk - -#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK -#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true - -#undef TARGET_FUNCTION_OK_FOR_SIBCALL -#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall - -#undef TARGET_INVALID_WITHIN_DOLOOP -#define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop - -#undef TARGET_REGISTER_MOVE_COST -#define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost -#undef TARGET_MEMORY_MOVE_COST -#define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost -#undef TARGET_RTX_COSTS -#define TARGET_RTX_COSTS rs6000_rtx_costs -#undef TARGET_ADDRESS_COST -#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0 - -#undef TARGET_DWARF_REGISTER_SPAN -#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span - -#undef TARGET_INIT_DWARF_REG_SIZES_EXTRA -#define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra - -#undef TARGET_MEMBER_TYPE_FORCES_BLK -#define TARGET_MEMBER_TYPE_FORCES_BLK rs6000_member_type_forces_blk - -/* On rs6000, function arguments are promoted, as are function return - values. */ -#undef TARGET_PROMOTE_FUNCTION_MODE -#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote - -#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_const_tree_true -#undef TARGET_MUST_PASS_IN_STACK -#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack -#undef TARGET_PASS_BY_REFERENCE -#define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference -#undef TARGET_ARG_PARTIAL_BYTES -#define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes -#undef TARGET_FUNCTION_ARG_ADVANCE -#define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance -#undef TARGET_FUNCTION_ARG -#define TARGET_FUNCTION_ARG rs6000_function_arg -#undef TARGET_FUNCTION_ARG_BOUNDARY -#define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary - -#undef TARGET_BUILD_BUILTIN_VA_LIST -#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list - -#undef TARGET_EXPAND_BUILTIN_VA_START -#define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start - -#undef TARGET_GIMPLIFY_VA_ARG_EXPR -#define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg - -#undef TARGET_EH_RETURN_FILTER_MODE -#define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode - -#undef TARGET_SCALAR_MODE_SUPPORTED_P -#define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p - -#undef TARGET_VECTOR_MODE_SUPPORTED_P -#define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p - -#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN -#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn - -#undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP -#define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip - -#undef TARGET_OPTION_OVERRIDE -#define TARGET_OPTION_OVERRIDE rs6000_option_override - -#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION -#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ - rs6000_builtin_vectorized_function - -#if !TARGET_MACHO -#undef TARGET_STACK_PROTECT_FAIL -#define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail -#endif - -/* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors - The PowerPC architecture requires only weak consistency among - processors--that is, memory accesses between processors need not be - sequentially consistent and memory accesses among processors can occur - in any order. The ability to order memory accesses weakly provides - opportunities for more efficient use of the system bus. Unless a - dependency exists, the 604e allows read operations to precede store - operations. */ -#undef TARGET_RELAXED_ORDERING -#define TARGET_RELAXED_ORDERING true - -#ifdef HAVE_AS_TLS -#undef TARGET_ASM_OUTPUT_DWARF_DTPREL -#define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel -#endif - -/* Use a 32-bit anchor range. This leads to sequences like: - - addis tmp,anchor,high - add dest,tmp,low - - where tmp itself acts as an anchor, and can be shared between - accesses to the same 64k page. */ -#undef TARGET_MIN_ANCHOR_OFFSET -#define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1 -#undef TARGET_MAX_ANCHOR_OFFSET -#define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff -#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P -#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p -#undef TARGET_USE_BLOCKS_FOR_DECL_P -#define TARGET_USE_BLOCKS_FOR_DECL_P rs6000_use_blocks_for_decl_p - -#undef TARGET_BUILTIN_RECIPROCAL -#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal - -#undef TARGET_EXPAND_TO_RTL_HOOK -#define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot - -#undef TARGET_INSTANTIATE_DECLS -#define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls - -#undef TARGET_SECONDARY_RELOAD -#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload - -#undef TARGET_LEGITIMATE_ADDRESS_P -#define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p - -#undef TARGET_MODE_DEPENDENT_ADDRESS_P -#define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p - -#undef TARGET_CAN_ELIMINATE -#define TARGET_CAN_ELIMINATE rs6000_can_eliminate - -#undef TARGET_CONDITIONAL_REGISTER_USAGE -#define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage - -#undef TARGET_TRAMPOLINE_INIT -#define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init - -#undef TARGET_FUNCTION_VALUE -#define TARGET_FUNCTION_VALUE rs6000_function_value - -#undef TARGET_OPTION_VALID_ATTRIBUTE_P -#define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p - -#undef TARGET_OPTION_SAVE -#define TARGET_OPTION_SAVE rs6000_function_specific_save - -#undef TARGET_OPTION_RESTORE -#define TARGET_OPTION_RESTORE rs6000_function_specific_restore - -#undef TARGET_OPTION_PRINT -#define TARGET_OPTION_PRINT rs6000_function_specific_print - -#undef TARGET_CAN_INLINE_P -#define TARGET_CAN_INLINE_P rs6000_can_inline_p - -#undef TARGET_SET_CURRENT_FUNCTION -#define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function - -#undef TARGET_LEGITIMATE_CONSTANT_P -#define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p - -#undef TARGET_VECTORIZE_VEC_PERM_CONST_OK -#define TARGET_VECTORIZE_VEC_PERM_CONST_OK rs6000_vectorize_vec_perm_const_ok - - -/* Processor table. */ -struct rs6000_ptt -{ - const char *const name; /* Canonical processor name. */ - const enum processor_type processor; /* Processor type enum value. */ - const HOST_WIDE_INT target_enable; /* Target flags to enable. */ -}; - -static struct rs6000_ptt const processor_target_table[] = -{ -#define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS }, -#include "rs6000-cpus.def" -#undef RS6000_CPU -}; - -/* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the - name is invalid. */ - -static int -rs6000_cpu_name_lookup (const char *name) -{ - size_t i; - - if (name != NULL) - { - for (i = 0; i < ARRAY_SIZE (processor_target_table); i++) - if (! strcmp (name, processor_target_table[i].name)) - return (int)i; - } - - return -1; -} - - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. - This is ordinarily the length in words of a value of mode MODE - but can be less for certain modes in special long registers. - - For the SPE, GPRs are 64 bits but only 32 bits are visible in - scalar instructions. The upper 32 bits are only available to the - SIMD instructions. - - POWER and PowerPC GPRs hold 32 bits worth; - PowerPC64 GPRs and FPRs point register holds 64 bits worth. */ - -static int -rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode) -{ - unsigned HOST_WIDE_INT reg_size; - - if (FP_REGNO_P (regno)) - reg_size = (VECTOR_MEM_VSX_P (mode) - ? UNITS_PER_VSX_WORD - : UNITS_PER_FP_WORD); - - else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) - reg_size = UNITS_PER_SPE_WORD; - - else if (ALTIVEC_REGNO_P (regno)) - reg_size = UNITS_PER_ALTIVEC_WORD; - - /* The value returned for SCmode in the E500 double case is 2 for - ABI compatibility; storing an SCmode value in a single register - would require function_arg and rs6000_spe_function_arg to handle - SCmode so as to pass the value correctly in a pair of - registers. */ - else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode - && !DECIMAL_FLOAT_MODE_P (mode)) - reg_size = UNITS_PER_FP_WORD; - - else - reg_size = UNITS_PER_WORD; - - return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size; -} - -/* Value is 1 if hard register REGNO can hold a value of machine-mode - MODE. */ -static int -rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode) -{ - int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1; - - /* VSX registers that overlap the FPR registers are larger than for non-VSX - implementations. Don't allow an item to be split between a FP register - and an Altivec register. */ - if (VECTOR_MEM_VSX_P (mode)) - { - if (FP_REGNO_P (regno)) - return FP_REGNO_P (last_regno); - - if (ALTIVEC_REGNO_P (regno)) - return ALTIVEC_REGNO_P (last_regno); - } - - /* The GPRs can hold any mode, but values bigger than one register - cannot go past R31. */ - if (INT_REGNO_P (regno)) - return INT_REGNO_P (last_regno); - - /* The float registers (except for VSX vector modes) can only hold floating - modes and DImode. This excludes the 32-bit decimal float mode for - now. */ - if (FP_REGNO_P (regno)) - { - if (SCALAR_FLOAT_MODE_P (mode) - && (mode != TDmode || (regno % 2) == 0) - && FP_REGNO_P (last_regno)) - return 1; - - if (GET_MODE_CLASS (mode) == MODE_INT - && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD) - return 1; - - if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT - && PAIRED_VECTOR_MODE (mode)) - return 1; - - return 0; - } - - /* The CR register can only hold CC modes. */ - if (CR_REGNO_P (regno)) - return GET_MODE_CLASS (mode) == MODE_CC; - - if (CA_REGNO_P (regno)) - return mode == BImode; - - /* AltiVec only in AldyVec registers. */ - if (ALTIVEC_REGNO_P (regno)) - return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode); - - /* ...but GPRs can hold SIMD data on the SPE in one register. */ - if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) - return 1; - - /* We cannot put TImode anywhere except general register and it must be able - to fit within the register set. In the future, allow TImode in the - Altivec or VSX registers. */ - - return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; -} - -/* Print interesting facts about registers. */ -static void -rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name) -{ - int r, m; - - for (r = first_regno; r <= last_regno; ++r) - { - const char *comma = ""; - int len; - - if (first_regno == last_regno) - fprintf (stderr, "%s:\t", reg_name); - else - fprintf (stderr, "%s%d:\t", reg_name, r - first_regno); - - len = 8; - for (m = 0; m < NUM_MACHINE_MODES; ++m) - if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r]) - { - if (len > 70) - { - fprintf (stderr, ",\n\t"); - len = 8; - comma = ""; - } - - if (rs6000_hard_regno_nregs[m][r] > 1) - len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m), - rs6000_hard_regno_nregs[m][r]); - else - len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m)); - - comma = ", "; - } - - if (call_used_regs[r]) - { - if (len > 70) - { - fprintf (stderr, ",\n\t"); - len = 8; - comma = ""; - } - - len += fprintf (stderr, "%s%s", comma, "call-used"); - comma = ", "; - } - - if (fixed_regs[r]) - { - if (len > 70) - { - fprintf (stderr, ",\n\t"); - len = 8; - comma = ""; - } - - len += fprintf (stderr, "%s%s", comma, "fixed"); - comma = ", "; - } - - if (len > 70) - { - fprintf (stderr, ",\n\t"); - comma = ""; - } - - fprintf (stderr, "%sregno = %d\n", comma, r); - } -} - -#define DEBUG_FMT_ID "%-32s= " -#define DEBUG_FMT_D DEBUG_FMT_ID "%d\n" -#define DEBUG_FMT_WX DEBUG_FMT_ID "%#.12" HOST_WIDE_INT_PRINT "x: " -#define DEBUG_FMT_S DEBUG_FMT_ID "%s\n" - -/* Print various interesting information with -mdebug=reg. */ -static void -rs6000_debug_reg_global (void) -{ - static const char *const tf[2] = { "false", "true" }; - const char *nl = (const char *)0; - int m; - char costly_num[20]; - char nop_num[20]; - char flags_buffer[40]; - const char *costly_str; - const char *nop_str; - const char *trace_str; - const char *abi_str; - const char *cmodel_str; - struct cl_target_option cl_opts; - - /* Map enum rs6000_vector to string. */ - static const char *rs6000_debug_vector_unit[] = { - "none", - "altivec", - "vsx", - "paired", - "spe", - "other" - }; - - fprintf (stderr, "Register information: (last virtual reg = %d)\n", - LAST_VIRTUAL_REGISTER); - rs6000_debug_reg_print (0, 31, "gr"); - rs6000_debug_reg_print (32, 63, "fp"); - rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO, - LAST_ALTIVEC_REGNO, - "vs"); - rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr"); - rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr"); - rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr"); - rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca"); - rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave"); - rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr"); - rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a"); - rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f"); - - fprintf (stderr, - "\n" - "d reg_class = %s\n" - "f reg_class = %s\n" - "v reg_class = %s\n" - "wa reg_class = %s\n" - "wd reg_class = %s\n" - "wf reg_class = %s\n" - "ws reg_class = %s\n\n", - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]], - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]], - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]], - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]], - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]], - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]], - reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]); - - for (m = 0; m < NUM_MACHINE_MODES; ++m) - if (rs6000_vector_unit[m] || rs6000_vector_mem[m]) - { - nl = "\n"; - fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n", - GET_MODE_NAME (m), - rs6000_debug_vector_unit[ rs6000_vector_unit[m] ], - rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]); - } - - if (nl) - fputs (nl, stderr); - - if (rs6000_recip_control) - { - fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control); - - for (m = 0; m < NUM_MACHINE_MODES; ++m) - if (rs6000_recip_bits[m]) - { - fprintf (stderr, - "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n", - GET_MODE_NAME (m), - (RS6000_RECIP_AUTO_RE_P (m) - ? "auto" - : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")), - (RS6000_RECIP_AUTO_RSQRTE_P (m) - ? "auto" - : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none"))); - } - - fputs ("\n", stderr); - } - - if (rs6000_cpu_index >= 0) - { - const char *name = processor_target_table[rs6000_cpu_index].name; - HOST_WIDE_INT flags - = processor_target_table[rs6000_cpu_index].target_enable; - - sprintf (flags_buffer, "-mcpu=%s flags", name); - rs6000_print_isa_options (stderr, 0, flags_buffer, flags); - } - else - fprintf (stderr, DEBUG_FMT_S, "cpu", "<none>"); - - if (rs6000_tune_index >= 0) - { - const char *name = processor_target_table[rs6000_tune_index].name; - HOST_WIDE_INT flags - = processor_target_table[rs6000_tune_index].target_enable; - - sprintf (flags_buffer, "-mtune=%s flags", name); - rs6000_print_isa_options (stderr, 0, flags_buffer, flags); - } - else - fprintf (stderr, DEBUG_FMT_S, "tune", "<none>"); - - cl_target_option_save (&cl_opts, &global_options); - rs6000_print_isa_options (stderr, 0, "rs6000_isa_flags", - rs6000_isa_flags); - - rs6000_print_isa_options (stderr, 0, "rs6000_isa_flags_explicit", - rs6000_isa_flags_explicit); - - rs6000_print_builtin_options (stderr, 0, "rs6000_builtin_mask", - rs6000_builtin_mask); - - rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT); - - fprintf (stderr, DEBUG_FMT_S, "--with-cpu default", - OPTION_TARGET_CPU_DEFAULT ? OPTION_TARGET_CPU_DEFAULT : "<none>"); - - switch (rs6000_sched_costly_dep) - { - case max_dep_latency: - costly_str = "max_dep_latency"; - break; - - case no_dep_costly: - costly_str = "no_dep_costly"; - break; - - case all_deps_costly: - costly_str = "all_deps_costly"; - break; - - case true_store_to_load_dep_costly: - costly_str = "true_store_to_load_dep_costly"; - break; - - case store_to_load_dep_costly: - costly_str = "store_to_load_dep_costly"; - break; - - default: - costly_str = costly_num; - sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep); - break; - } - - fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str); - - switch (rs6000_sched_insert_nops) - { - case sched_finish_regroup_exact: - nop_str = "sched_finish_regroup_exact"; - break; - - case sched_finish_pad_groups: - nop_str = "sched_finish_pad_groups"; - break; - - case sched_finish_none: - nop_str = "sched_finish_none"; - break; - - default: - nop_str = nop_num; - sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops); - break; - } - - fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str); - - switch (rs6000_sdata) - { - default: - case SDATA_NONE: - break; - - case SDATA_DATA: - fprintf (stderr, DEBUG_FMT_S, "sdata", "data"); - break; - - case SDATA_SYSV: - fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv"); - break; - - case SDATA_EABI: - fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi"); - break; - - } - - switch (rs6000_traceback) - { - case traceback_default: trace_str = "default"; break; - case traceback_none: trace_str = "none"; break; - case traceback_part: trace_str = "part"; break; - case traceback_full: trace_str = "full"; break; - default: trace_str = "unknown"; break; - } - - fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str); - - switch (rs6000_current_cmodel) - { - case CMODEL_SMALL: cmodel_str = "small"; break; - case CMODEL_MEDIUM: cmodel_str = "medium"; break; - case CMODEL_LARGE: cmodel_str = "large"; break; - default: cmodel_str = "unknown"; break; - } - - fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str); - - switch (rs6000_current_abi) - { - case ABI_NONE: abi_str = "none"; break; - case ABI_AIX: abi_str = "aix"; break; - case ABI_V4: abi_str = "V4"; break; - case ABI_DARWIN: abi_str = "darwin"; break; - default: abi_str = "unknown"; break; - } - - fprintf (stderr, DEBUG_FMT_S, "abi", abi_str); - - if (rs6000_altivec_abi) - fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true"); - - if (rs6000_spe_abi) - fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true"); - - if (rs6000_darwin64_abi) - fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true"); - - if (rs6000_float_gprs) - fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true"); - - if (TARGET_LINK_STACK) - fprintf (stderr, DEBUG_FMT_S, "link_stack", "true"); - - fprintf (stderr, DEBUG_FMT_S, "plt-format", - TARGET_SECURE_PLT ? "secure" : "bss"); - fprintf (stderr, DEBUG_FMT_S, "struct-return", - aix_struct_return ? "aix" : "sysv"); - fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]); - fprintf (stderr, DEBUG_FMT_S, "sched_groups", tf[!!rs6000_sched_groups]); - fprintf (stderr, DEBUG_FMT_S, "align_branch", - tf[!!rs6000_align_branch_targets]); - fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size); - fprintf (stderr, DEBUG_FMT_D, "long_double_size", - rs6000_long_double_type_size); - fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority", - (int)rs6000_sched_restricted_insns_priority); - fprintf (stderr, DEBUG_FMT_D, "Number of standard builtins", - (int)END_BUILTINS); - fprintf (stderr, DEBUG_FMT_D, "Number of rs6000 builtins", - (int)RS6000_BUILTIN_COUNT); -} - -/* Initialize the various global tables that are based on register size. */ -static void -rs6000_init_hard_regno_mode_ok (bool global_init_p) -{ - int r, m, c; - int align64; - int align32; - - /* Precalculate REGNO_REG_CLASS. */ - rs6000_regno_regclass[0] = GENERAL_REGS; - for (r = 1; r < 32; ++r) - rs6000_regno_regclass[r] = BASE_REGS; - - for (r = 32; r < 64; ++r) - rs6000_regno_regclass[r] = FLOAT_REGS; - - for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r) - rs6000_regno_regclass[r] = NO_REGS; - - for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r) - rs6000_regno_regclass[r] = ALTIVEC_REGS; - - rs6000_regno_regclass[CR0_REGNO] = CR0_REGS; - for (r = CR1_REGNO; r <= CR7_REGNO; ++r) - rs6000_regno_regclass[r] = CR_REGS; - - rs6000_regno_regclass[LR_REGNO] = LINK_REGS; - rs6000_regno_regclass[CTR_REGNO] = CTR_REGS; - rs6000_regno_regclass[CA_REGNO] = CA_REGS; - rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS; - rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS; - rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS; - rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS; - rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS; - rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS; - - /* Precalculate vector information, this must be set up before the - rs6000_hard_regno_nregs_internal below. */ - for (m = 0; m < NUM_MACHINE_MODES; ++m) - { - rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE; - rs6000_vector_reload[m][0] = CODE_FOR_nothing; - rs6000_vector_reload[m][1] = CODE_FOR_nothing; - } - - for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++) - rs6000_constraints[c] = NO_REGS; - - /* The VSX hardware allows native alignment for vectors, but control whether the compiler - believes it can use native alignment or still uses 128-bit alignment. */ - if (TARGET_VSX && !TARGET_VSX_ALIGN_128) - { - align64 = 64; - align32 = 32; - } - else - { - align64 = 128; - align32 = 128; - } - - /* V2DF mode, VSX only. */ - if (TARGET_VSX) - { - rs6000_vector_unit[V2DFmode] = VECTOR_VSX; - rs6000_vector_mem[V2DFmode] = VECTOR_VSX; - rs6000_vector_align[V2DFmode] = align64; - } - - /* V4SF mode, either VSX or Altivec. */ - if (TARGET_VSX) - { - rs6000_vector_unit[V4SFmode] = VECTOR_VSX; - rs6000_vector_mem[V4SFmode] = VECTOR_VSX; - rs6000_vector_align[V4SFmode] = align32; - } - else if (TARGET_ALTIVEC) - { - rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC; - rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC; - rs6000_vector_align[V4SFmode] = align32; - } - - /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads - and stores. */ - if (TARGET_ALTIVEC) - { - rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC; - rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC; - rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC; - rs6000_vector_align[V4SImode] = align32; - rs6000_vector_align[V8HImode] = align32; - rs6000_vector_align[V16QImode] = align32; - - if (TARGET_VSX) - { - rs6000_vector_mem[V4SImode] = VECTOR_VSX; - rs6000_vector_mem[V8HImode] = VECTOR_VSX; - rs6000_vector_mem[V16QImode] = VECTOR_VSX; - } - else - { - rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC; - rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC; - rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC; - } - } - - /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract. - Altivec doesn't have 64-bit support. */ - if (TARGET_VSX) - { - rs6000_vector_mem[V2DImode] = VECTOR_VSX; - rs6000_vector_unit[V2DImode] = VECTOR_NONE; - rs6000_vector_align[V2DImode] = align64; - } - - /* DFmode, see if we want to use the VSX unit. */ - if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE) - { - rs6000_vector_unit[DFmode] = VECTOR_VSX; - rs6000_vector_mem[DFmode] - = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE); - rs6000_vector_align[DFmode] = align64; - } - - /* TODO add SPE and paired floating point vector support. */ - - /* Register class constraints for the constraints that depend on compile - switches. */ - if (TARGET_HARD_FLOAT && TARGET_FPRS) - rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS; - - if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) - rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS; - - if (TARGET_VSX) - { - /* At present, we just use VSX_REGS, but we have different constraints - based on the use, in case we want to fine tune the default register - class used. wa = any VSX register, wf = register class to use for - V4SF, wd = register class to use for V2DF, and ws = register classs to - use for DF scalars. */ - rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS; - rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS; - rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS; - rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY - ? VSX_REGS - : FLOAT_REGS); - } - - if (TARGET_ALTIVEC) - rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS; - - /* Set up the reload helper functions. */ - if (TARGET_VSX || TARGET_ALTIVEC) - { - if (TARGET_64BIT) - { - rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store; - rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load; - rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store; - rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load; - rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store; - rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load; - rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store; - rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load; - rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store; - rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load; - rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store; - rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load; - if (TARGET_VSX && TARGET_VSX_SCALAR_MEMORY) - { - rs6000_vector_reload[DFmode][0] = CODE_FOR_reload_df_di_store; - rs6000_vector_reload[DFmode][1] = CODE_FOR_reload_df_di_load; - } - } - else - { - rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store; - rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load; - rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store; - rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load; - rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store; - rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load; - rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store; - rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load; - rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store; - rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load; - rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store; - rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load; - if (TARGET_VSX && TARGET_VSX_SCALAR_MEMORY) - { - rs6000_vector_reload[DFmode][0] = CODE_FOR_reload_df_si_store; - rs6000_vector_reload[DFmode][1] = CODE_FOR_reload_df_si_load; - } - } - } - - /* Precalculate HARD_REGNO_NREGS. */ - for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) - for (m = 0; m < NUM_MACHINE_MODES; ++m) - rs6000_hard_regno_nregs[m][r] - = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m); - - /* Precalculate HARD_REGNO_MODE_OK. */ - for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) - for (m = 0; m < NUM_MACHINE_MODES; ++m) - if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m)) - rs6000_hard_regno_mode_ok_p[m][r] = true; - - /* Precalculate CLASS_MAX_NREGS sizes. */ - for (c = 0; c < LIM_REG_CLASSES; ++c) - { - int reg_size; - - if (TARGET_VSX && VSX_REG_CLASS_P (c)) - reg_size = UNITS_PER_VSX_WORD; - - else if (c == ALTIVEC_REGS) - reg_size = UNITS_PER_ALTIVEC_WORD; - - else if (c == FLOAT_REGS) - reg_size = UNITS_PER_FP_WORD; - - else - reg_size = UNITS_PER_WORD; - - for (m = 0; m < NUM_MACHINE_MODES; ++m) - { - int reg_size2 = reg_size; - - /* TFmode/TDmode always takes 2 registers, even in VSX. */ - if (m == TDmode || m == TFmode) - reg_size2 = UNITS_PER_FP_WORD; - - rs6000_class_max_nregs[m][c] - = (GET_MODE_SIZE (m) + reg_size2 - 1) / reg_size2; - } - } - - if (TARGET_E500_DOUBLE) - rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1; - - /* Calculate which modes to automatically generate code to use a the - reciprocal divide and square root instructions. In the future, possibly - automatically generate the instructions even if the user did not specify - -mrecip. The older machines double precision reciprocal sqrt estimate is - not accurate enough. */ - memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits)); - if (TARGET_FRES) - rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE; - if (TARGET_FRE) - rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE; - if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)) - rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE; - if (VECTOR_UNIT_VSX_P (V2DFmode)) - rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE; - - if (TARGET_FRSQRTES) - rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; - if (TARGET_FRSQRTE) - rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; - if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)) - rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; - if (VECTOR_UNIT_VSX_P (V2DFmode)) - rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; - - if (rs6000_recip_control) - { - if (!flag_finite_math_only) - warning (0, "-mrecip requires -ffinite-math or -ffast-math"); - if (flag_trapping_math) - warning (0, "-mrecip requires -fno-trapping-math or -ffast-math"); - if (!flag_reciprocal_math) - warning (0, "-mrecip requires -freciprocal-math or -ffast-math"); - if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math) - { - if (RS6000_RECIP_HAVE_RE_P (SFmode) - && (rs6000_recip_control & RECIP_SF_DIV) != 0) - rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE; - - if (RS6000_RECIP_HAVE_RE_P (DFmode) - && (rs6000_recip_control & RECIP_DF_DIV) != 0) - rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE; - - if (RS6000_RECIP_HAVE_RE_P (V4SFmode) - && (rs6000_recip_control & RECIP_V4SF_DIV) != 0) - rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE; - - if (RS6000_RECIP_HAVE_RE_P (V2DFmode) - && (rs6000_recip_control & RECIP_V2DF_DIV) != 0) - rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE; - - if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode) - && (rs6000_recip_control & RECIP_SF_RSQRT) != 0) - rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; - - if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode) - && (rs6000_recip_control & RECIP_DF_RSQRT) != 0) - rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; - - if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode) - && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0) - rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; - - if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode) - && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0) - rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; - } - } - - if (global_init_p || TARGET_DEBUG_TARGET) - { - if (TARGET_DEBUG_REG) - rs6000_debug_reg_global (); - - if (TARGET_DEBUG_COST || TARGET_DEBUG_REG) - fprintf (stderr, - "SImode variable mult cost = %d\n" - "SImode constant mult cost = %d\n" - "SImode short constant mult cost = %d\n" - "DImode multipliciation cost = %d\n" - "SImode division cost = %d\n" - "DImode division cost = %d\n" - "Simple fp operation cost = %d\n" - "DFmode multiplication cost = %d\n" - "SFmode division cost = %d\n" - "DFmode division cost = %d\n" - "cache line size = %d\n" - "l1 cache size = %d\n" - "l2 cache size = %d\n" - "simultaneous prefetches = %d\n" - "\n", - rs6000_cost->mulsi, - rs6000_cost->mulsi_const, - rs6000_cost->mulsi_const9, - rs6000_cost->muldi, - rs6000_cost->divsi, - rs6000_cost->divdi, - rs6000_cost->fp, - rs6000_cost->dmul, - rs6000_cost->sdiv, - rs6000_cost->ddiv, - rs6000_cost->cache_line_size, - rs6000_cost->l1_cache_size, - rs6000_cost->l2_cache_size, - rs6000_cost->simultaneous_prefetches); - } -} - -#if TARGET_MACHO -/* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */ - -static void -darwin_rs6000_override_options (void) -{ - /* The Darwin ABI always includes AltiVec, can't be (validly) turned - off. */ - rs6000_altivec_abi = 1; - TARGET_ALTIVEC_VRSAVE = 1; - rs6000_current_abi = ABI_DARWIN; - - if (DEFAULT_ABI == ABI_DARWIN - && TARGET_64BIT) - darwin_one_byte_bool = 1; - - if (TARGET_64BIT && ! TARGET_POWERPC64) - { - rs6000_isa_flags |= OPTION_MASK_POWERPC64; - warning (0, "-m64 requires PowerPC64 architecture, enabling"); - } - if (flag_mkernel) - { - rs6000_default_long_calls = 1; - rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; - } - - /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes - Altivec. */ - if (!flag_mkernel && !flag_apple_kext - && TARGET_64BIT - && ! (rs6000_isa_flags_explicit & OPTION_MASK_ALTIVEC)) - rs6000_isa_flags |= OPTION_MASK_ALTIVEC; - - /* Unless the user (not the configurer) has explicitly overridden - it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to - G4 unless targeting the kernel. */ - if (!flag_mkernel - && !flag_apple_kext - && strverscmp (darwin_macosx_version_min, "10.5") >= 0 - && ! (rs6000_isa_flags_explicit & OPTION_MASK_ALTIVEC) - && ! global_options_set.x_rs6000_cpu_index) - { - rs6000_isa_flags |= OPTION_MASK_ALTIVEC; - } -} -#endif - -/* If not otherwise specified by a target, make 'long double' equivalent to - 'double'. */ - -#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE -#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 -#endif - -/* Return the builtin mask of the various options used that could affect which - builtins were used. In the past we used target_flags, but we've run out of - bits, and some options like SPE and PAIRED are no longer in - target_flags. */ - -HOST_WIDE_INT -rs6000_builtin_mask_calculate (void) -{ - return (((TARGET_ALTIVEC) ? RS6000_BTM_ALTIVEC : 0) - | ((TARGET_VSX) ? RS6000_BTM_VSX : 0) - | ((TARGET_SPE) ? RS6000_BTM_SPE : 0) - | ((TARGET_PAIRED_FLOAT) ? RS6000_BTM_PAIRED : 0) - | ((TARGET_FRE) ? RS6000_BTM_FRE : 0) - | ((TARGET_FRES) ? RS6000_BTM_FRES : 0) - | ((TARGET_FRSQRTE) ? RS6000_BTM_FRSQRTE : 0) - | ((TARGET_FRSQRTES) ? RS6000_BTM_FRSQRTES : 0) - | ((TARGET_POPCNTD) ? RS6000_BTM_POPCNTD : 0) - | ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL : 0)); -} - -/* Override command line options. Mostly we process the processor type and - sometimes adjust other TARGET_ options. */ - -static bool -rs6000_option_override_internal (bool global_init_p) -{ - bool ret = true; - bool have_cpu = false; - - /* The default cpu requested at configure time, if any. */ - const char *implicit_cpu = OPTION_TARGET_CPU_DEFAULT; - - HOST_WIDE_INT set_masks; - int cpu_index; - int tune_index; - struct cl_target_option *main_target_opt - = ((global_init_p || target_option_default_node == NULL) - ? NULL : TREE_TARGET_OPTION (target_option_default_node)); - - /* On 64-bit Darwin, power alignment is ABI-incompatible with some C - library functions, so warn about it. The flag may be useful for - performance studies from time to time though, so don't disable it - entirely. */ - if (global_options_set.x_rs6000_alignment_flags - && rs6000_alignment_flags == MASK_ALIGN_POWER - && DEFAULT_ABI == ABI_DARWIN - && TARGET_64BIT) - warning (0, "-malign-power is not supported for 64-bit Darwin;" - " it is incompatible with the installed C and C++ libraries"); - - /* Numerous experiment shows that IRA based loop pressure - calculation works better for RTL loop invariant motion on targets - with enough (>= 32) registers. It is an expensive optimization. - So it is on only for peak performance. */ - if (optimize >= 3 && global_init_p) - flag_ira_loop_pressure = 1; - - /* Set the pointer size. */ - if (TARGET_64BIT) - { - rs6000_pmode = (int)DImode; - rs6000_pointer_size = 64; - } - else - { - rs6000_pmode = (int)SImode; - rs6000_pointer_size = 32; - } - - /* 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 OPTION_MASK_POWERPC64 or OPTION_MASK_ALTIVEC settings; - if the user wants either, the user must explicitly specify them and we - won't interfere with the user's specification. */ - - set_masks = POWERPC_MASKS; -#ifdef OS_MISSING_POWERPC64 - if (OS_MISSING_POWERPC64) - set_masks &= ~OPTION_MASK_POWERPC64; -#endif -#ifdef OS_MISSING_ALTIVEC - if (OS_MISSING_ALTIVEC) - set_masks &= ~(OPTION_MASK_ALTIVEC | OPTION_MASK_VSX); -#endif - - /* Don't override by the processor default if given explicitly. */ - set_masks &= ~rs6000_isa_flags_explicit; - - /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed - the cpu in a target attribute or pragma, but did not specify a tuning - option, use the cpu for the tuning option rather than the option specified - with -mtune on the command line. Process a '--with-cpu' configuration - request as an implicit --cpu. */ - if (rs6000_cpu_index >= 0) - { - cpu_index = rs6000_cpu_index; - have_cpu = true; - } - else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index >= 0) - { - rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index; - have_cpu = true; - } - else if (implicit_cpu) - { - rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (implicit_cpu); - have_cpu = true; - } - else - { - const char *default_cpu = (TARGET_POWERPC64 ? "powerpc64" : "powerpc"); - rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu); - have_cpu = false; - } - - gcc_assert (cpu_index >= 0); - - /* If we have a cpu, either through an explicit -mcpu=<xxx> or if the - compiler was configured with --with-cpu=<xxx>, replace all of the ISA bits - with those from the cpu, except for options that were explicitly set. If - we don't have a cpu, do not override the target bits set in - TARGET_DEFAULT. */ - if (have_cpu) - { - rs6000_isa_flags &= ~set_masks; - rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable - & set_masks); - } - else - rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable - & ~rs6000_isa_flags_explicit); - - /* If no -mcpu=<xxx>, inherit any default options that were cleared via - POWERPC_MASKS. Originally, TARGET_DEFAULT was used to initialize - target_flags via the TARGET_DEFAULT_TARGET_FLAGS hook. When we switched - to using rs6000_isa_flags, we need to do the initialization here. */ - if (!have_cpu) - rs6000_isa_flags |= (TARGET_DEFAULT & ~rs6000_isa_flags_explicit); - - if (rs6000_tune_index >= 0) - tune_index = rs6000_tune_index; - else if (have_cpu) - rs6000_tune_index = tune_index = cpu_index; - else - { - size_t i; - enum processor_type tune_proc - = (TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT); - - tune_index = -1; - for (i = 0; i < ARRAY_SIZE (processor_target_table); i++) - if (processor_target_table[i].processor == tune_proc) - { - rs6000_tune_index = tune_index = i; - break; - } - } - - gcc_assert (tune_index >= 0); - rs6000_cpu = processor_target_table[tune_index].processor; - - /* Pick defaults for SPE related control flags. Do this early to make sure - that the TARGET_ macros are representative ASAP. */ - { - int spe_capable_cpu = - (rs6000_cpu == PROCESSOR_PPC8540 - || rs6000_cpu == PROCESSOR_PPC8548); - - if (!global_options_set.x_rs6000_spe_abi) - rs6000_spe_abi = spe_capable_cpu; - - if (!global_options_set.x_rs6000_spe) - rs6000_spe = spe_capable_cpu; - - if (!global_options_set.x_rs6000_float_gprs) - rs6000_float_gprs = - (rs6000_cpu == PROCESSOR_PPC8540 ? 1 - : rs6000_cpu == PROCESSOR_PPC8548 ? 2 - : 0); - } - - if (global_options_set.x_rs6000_spe_abi - && rs6000_spe_abi - && !TARGET_SPE_ABI) - error ("not configured for SPE ABI"); - - if (global_options_set.x_rs6000_spe - && rs6000_spe - && !TARGET_SPE) - error ("not configured for SPE instruction set"); - - if (main_target_opt != NULL - && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi) - || (main_target_opt->x_rs6000_spe != rs6000_spe) - || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs))) - error ("target attribute or pragma changes SPE ABI"); - - if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 - || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64 - || rs6000_cpu == PROCESSOR_PPCE5500) - { - if (TARGET_ALTIVEC) - error ("AltiVec not supported in this target"); - if (TARGET_SPE) - error ("SPE not supported in this target"); - } - if (rs6000_cpu == PROCESSOR_PPCE6500) - { - if (TARGET_SPE) - error ("SPE not supported in this target"); - } - - /* Disable Cell microcode if we are optimizing for the Cell - and not optimizing for size. */ - if (rs6000_gen_cell_microcode == -1) - rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL - && !optimize_size); - - /* If we are optimizing big endian systems for space and it's OK to - use instructions that would be microcoded on the Cell, use the - load/store multiple and string instructions. */ - if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode) - rs6000_isa_flags |= ~rs6000_isa_flags_explicit & (OPTION_MASK_MULTIPLE - | OPTION_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 - instructions used in little endian mode, and causes an alignment - trap. The 750 does not cause an alignment trap (except when the - target is unaligned). */ - - if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750) - { - if (TARGET_MULTIPLE) - { - rs6000_isa_flags &= ~OPTION_MASK_MULTIPLE; - if ((rs6000_isa_flags_explicit & OPTION_MASK_MULTIPLE) != 0) - warning (0, "-mmultiple is not supported on little endian systems"); - } - - if (TARGET_STRING) - { - rs6000_isa_flags &= ~OPTION_MASK_STRING; - if ((rs6000_isa_flags_explicit & OPTION_MASK_STRING) != 0) - warning (0, "-mstring is not supported on little endian systems"); - } - } - - /* Add some warnings for VSX. */ - if (TARGET_VSX) - { - const char *msg = NULL; - if (!TARGET_HARD_FLOAT || !TARGET_FPRS - || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT) - { - if (rs6000_isa_flags_explicit & OPTION_MASK_VSX) - msg = N_("-mvsx requires hardware floating point"); - else - rs6000_isa_flags &= ~ OPTION_MASK_VSX; - } - else if (TARGET_PAIRED_FLOAT) - msg = N_("-mvsx and -mpaired are incompatible"); - /* The hardware will allow VSX and little endian, but until we make sure - things like vector select, etc. work don't allow VSX on little endian - systems at this point. */ - else if (!BYTES_BIG_ENDIAN) - msg = N_("-mvsx used with little endian code"); - else if (TARGET_AVOID_XFORM > 0) - msg = N_("-mvsx needs indexed addressing"); - else if (!TARGET_ALTIVEC && (rs6000_isa_flags_explicit - & OPTION_MASK_ALTIVEC)) - { - if (rs6000_isa_flags_explicit & OPTION_MASK_VSX) - msg = N_("-mvsx and -mno-altivec are incompatible"); - else - msg = N_("-mno-altivec disables vsx"); - } - - if (msg) - { - warning (0, msg); - rs6000_isa_flags &= ~ OPTION_MASK_VSX; - rs6000_isa_flags_explicit |= OPTION_MASK_VSX; - } - } - - /* For the newer switches (vsx, dfp, etc.) set some of the older options, - unless the user explicitly used the -mno-<option> to disable the code. */ - if (TARGET_VSX) - rs6000_isa_flags |= (ISA_2_6_MASKS_SERVER & ~rs6000_isa_flags_explicit); - else if (TARGET_POPCNTD) - rs6000_isa_flags |= (ISA_2_6_MASKS_EMBEDDED & ~rs6000_isa_flags_explicit); - else if (TARGET_DFP) - rs6000_isa_flags |= (ISA_2_5_MASKS_SERVER & ~rs6000_isa_flags_explicit); - else if (TARGET_CMPB) - rs6000_isa_flags |= (ISA_2_5_MASKS_EMBEDDED & ~rs6000_isa_flags_explicit); - else if (TARGET_FPRND) - rs6000_isa_flags |= (ISA_2_4_MASKS & ~rs6000_isa_flags_explicit); - else if (TARGET_POPCNTB) - rs6000_isa_flags |= (ISA_2_2_MASKS & ~rs6000_isa_flags_explicit); - else if (TARGET_ALTIVEC) - rs6000_isa_flags |= (OPTION_MASK_PPC_GFXOPT & ~rs6000_isa_flags_explicit); - - /* E500mc does "better" if we inline more aggressively. Respect the - user's opinion, though. */ - if (rs6000_block_move_inline_limit == 0 - && (rs6000_cpu == PROCESSOR_PPCE500MC - || rs6000_cpu == PROCESSOR_PPCE500MC64 - || rs6000_cpu == PROCESSOR_PPCE5500 - || rs6000_cpu == PROCESSOR_PPCE6500)) - rs6000_block_move_inline_limit = 128; - - /* store_one_arg depends on expand_block_move to handle at least the - size of reg_parm_stack_space. */ - if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32)) - rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32); - - if (global_init_p) - { - /* If the appropriate debug option is enabled, replace the target hooks - with debug versions that call the real version and then prints - debugging information. */ - if (TARGET_DEBUG_COST) - { - targetm.rtx_costs = rs6000_debug_rtx_costs; - targetm.address_cost = rs6000_debug_address_cost; - targetm.sched.adjust_cost = rs6000_debug_adjust_cost; - } - - if (TARGET_DEBUG_ADDR) - { - targetm.legitimate_address_p = rs6000_debug_legitimate_address_p; - targetm.legitimize_address = rs6000_debug_legitimize_address; - rs6000_secondary_reload_class_ptr - = rs6000_debug_secondary_reload_class; - rs6000_secondary_memory_needed_ptr - = rs6000_debug_secondary_memory_needed; - rs6000_cannot_change_mode_class_ptr - = rs6000_debug_cannot_change_mode_class; - rs6000_preferred_reload_class_ptr - = rs6000_debug_preferred_reload_class; - rs6000_legitimize_reload_address_ptr - = rs6000_debug_legitimize_reload_address; - rs6000_mode_dependent_address_ptr - = rs6000_debug_mode_dependent_address; - } - - if (rs6000_veclibabi_name) - { - if (strcmp (rs6000_veclibabi_name, "mass") == 0) - rs6000_veclib_handler = rs6000_builtin_vectorized_libmass; - else - { - error ("unknown vectorization library ABI type (%s) for " - "-mveclibabi= switch", rs6000_veclibabi_name); - ret = false; - } - } - } - - if (!global_options_set.x_rs6000_long_double_type_size) - { - if (main_target_opt != NULL - && (main_target_opt->x_rs6000_long_double_type_size - != RS6000_DEFAULT_LONG_DOUBLE_SIZE)) - error ("target attribute or pragma changes long double size"); - else - rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE; - } - -#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD) - if (!global_options_set.x_rs6000_ieeequad) - rs6000_ieeequad = 1; -#endif - - /* Disable VSX and Altivec silently if the user switched cpus to power7 in a - target attribute or pragma which automatically enables both options, - unless the altivec ABI was set. This is set by default for 64-bit, but - not for 32-bit. */ - if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi) - rs6000_isa_flags &= ~((OPTION_MASK_VSX | OPTION_MASK_ALTIVEC) - & ~rs6000_isa_flags_explicit); - - /* Enable Altivec ABI for AIX -maltivec. */ - if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX)) - { - if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi) - error ("target attribute or pragma changes AltiVec ABI"); - else - rs6000_altivec_abi = 1; - } - - /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For - PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can - be explicitly overridden in either case. */ - if (TARGET_ELF) - { - if (!global_options_set.x_rs6000_altivec_abi - && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX)) - { - if (main_target_opt != NULL && - !main_target_opt->x_rs6000_altivec_abi) - error ("target attribute or pragma changes AltiVec ABI"); - else - rs6000_altivec_abi = 1; - } - } - - /* Set the Darwin64 ABI as default for 64-bit Darwin. - So far, the only darwin64 targets are also MACH-O. */ - if (TARGET_MACHO - && DEFAULT_ABI == ABI_DARWIN - && TARGET_64BIT) - { - if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi) - error ("target attribute or pragma changes darwin64 ABI"); - else - { - rs6000_darwin64_abi = 1; - /* Default to natural alignment, for better performance. */ - rs6000_alignment_flags = MASK_ALIGN_NATURAL; - } - } - - /* Place FP constants in the constant pool instead of TOC - if section anchors enabled. */ - if (flag_section_anchors) - TARGET_NO_FP_IN_TOC = 1; - -#ifdef SUBTARGET_OVERRIDE_OPTIONS - SUBTARGET_OVERRIDE_OPTIONS; -#endif -#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS - SUBSUBTARGET_OVERRIDE_OPTIONS; -#endif -#ifdef SUB3TARGET_OVERRIDE_OPTIONS - SUB3TARGET_OVERRIDE_OPTIONS; -#endif - - /* For the E500 family of cores, reset the single/double FP flags to let us - check that they remain constant across attributes or pragmas. Also, - clear a possible request for string instructions, not supported and which - we might have silently queried above for -Os. - - For other families, clear ISEL in case it was set implicitly. - */ - - switch (rs6000_cpu) - { - case PROCESSOR_PPC8540: - case PROCESSOR_PPC8548: - case PROCESSOR_PPCE500MC: - case PROCESSOR_PPCE500MC64: - case PROCESSOR_PPCE5500: - case PROCESSOR_PPCE6500: - - rs6000_single_float = TARGET_E500_SINGLE || TARGET_E500_DOUBLE; - rs6000_double_float = TARGET_E500_DOUBLE; - - rs6000_isa_flags &= ~OPTION_MASK_STRING; - - break; - - default: - - if (have_cpu && !(rs6000_isa_flags_explicit & OPTION_MASK_ISEL)) - rs6000_isa_flags &= ~OPTION_MASK_ISEL; - - break; - } - - if (main_target_opt) - { - if (main_target_opt->x_rs6000_single_float != rs6000_single_float) - error ("target attribute or pragma changes single precision floating " - "point"); - if (main_target_opt->x_rs6000_double_float != rs6000_double_float) - error ("target attribute or pragma changes double precision floating " - "point"); - } - - /* Detect invalid option combinations with E500. */ - CHECK_E500_OPTIONS; - - rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4 - && rs6000_cpu != PROCESSOR_POWER5 - && rs6000_cpu != PROCESSOR_POWER6 - && rs6000_cpu != PROCESSOR_POWER7 - && rs6000_cpu != PROCESSOR_PPCA2 - && rs6000_cpu != PROCESSOR_CELL - && rs6000_cpu != PROCESSOR_PPC476); - rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4 - || rs6000_cpu == PROCESSOR_POWER5 - || rs6000_cpu == PROCESSOR_POWER7); - rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4 - || rs6000_cpu == PROCESSOR_POWER5 - || rs6000_cpu == PROCESSOR_POWER6 - || rs6000_cpu == PROCESSOR_POWER7 - || rs6000_cpu == PROCESSOR_PPCE500MC - || rs6000_cpu == PROCESSOR_PPCE500MC64 - || rs6000_cpu == PROCESSOR_PPCE5500 - || rs6000_cpu == PROCESSOR_PPCE6500); - - /* Allow debug switches to override the above settings. These are set to -1 - in rs6000.opt to indicate the user hasn't directly set the switch. */ - if (TARGET_ALWAYS_HINT >= 0) - rs6000_always_hint = TARGET_ALWAYS_HINT; - - if (TARGET_SCHED_GROUPS >= 0) - rs6000_sched_groups = TARGET_SCHED_GROUPS; - - if (TARGET_ALIGN_BRANCH_TARGETS >= 0) - rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS; - - rs6000_sched_restricted_insns_priority - = (rs6000_sched_groups ? 1 : 0); - - /* Handle -msched-costly-dep option. */ - rs6000_sched_costly_dep - = (rs6000_sched_groups ? true_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 = ((enum rs6000_dependence_cost) - 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 = ((enum rs6000_nop_insertion) - atoi (rs6000_sched_insert_nops_str)); - } - - if (global_init_p) - { -#ifdef TARGET_REGNAMES - /* If the user desires alternate register names, copy in the - alternate names now. */ - if (TARGET_REGNAMES) - memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names)); -#endif - - /* Set aix_struct_return 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 (!global_options_set.x_aix_struct_return) - aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET); - -#if 0 - /* IBM XL compiler defaults to unsigned bitfields. */ - if (TARGET_XL_COMPAT) - flag_signed_bitfields = 0; -#endif - - if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD) - REAL_MODE_FORMAT (TFmode) = &ibm_extended_format; - - if (TARGET_TOC) - ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1); - - /* We can only guarantee the availability of DI pseudo-ops when - assembling for 64-bit targets. */ - if (!TARGET_64BIT) - { - targetm.asm_out.aligned_op.di = NULL; - targetm.asm_out.unaligned_op.di = NULL; - } - - - /* Set branch target alignment, if not optimizing for size. */ - if (!optimize_size) - { - /* Cell wants to be aligned 8byte for dual issue. Titan wants to be - aligned 8byte to avoid misprediction by the branch predictor. */ - if (rs6000_cpu == PROCESSOR_TITAN - || rs6000_cpu == PROCESSOR_CELL) - { - if (align_functions <= 0) - align_functions = 8; - if (align_jumps <= 0) - align_jumps = 8; - if (align_loops <= 0) - align_loops = 8; - } - if (rs6000_align_branch_targets) - { - if (align_functions <= 0) - align_functions = 16; - if (align_jumps <= 0) - align_jumps = 16; - if (align_loops <= 0) - { - can_override_loop_align = 1; - align_loops = 16; - } - } - if (align_jumps_max_skip <= 0) - align_jumps_max_skip = 15; - if (align_loops_max_skip <= 0) - align_loops_max_skip = 15; - } - - /* 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; - } - - /* Initialize rs6000_cost with the appropriate target costs. */ - if (optimize_size) - rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost; - else - switch (rs6000_cpu) - { - case PROCESSOR_RS64A: - rs6000_cost = &rs64a_cost; - break; - - case PROCESSOR_MPCCORE: - rs6000_cost = &mpccore_cost; - break; - - case PROCESSOR_PPC403: - rs6000_cost = &ppc403_cost; - break; - - case PROCESSOR_PPC405: - rs6000_cost = &ppc405_cost; - break; - - case PROCESSOR_PPC440: - rs6000_cost = &ppc440_cost; - break; - - case PROCESSOR_PPC476: - rs6000_cost = &ppc476_cost; - break; - - case PROCESSOR_PPC601: - rs6000_cost = &ppc601_cost; - break; - - case PROCESSOR_PPC603: - rs6000_cost = &ppc603_cost; - break; - - case PROCESSOR_PPC604: - rs6000_cost = &ppc604_cost; - break; - - case PROCESSOR_PPC604e: - rs6000_cost = &ppc604e_cost; - break; - - case PROCESSOR_PPC620: - rs6000_cost = &ppc620_cost; - break; - - case PROCESSOR_PPC630: - rs6000_cost = &ppc630_cost; - break; - - case PROCESSOR_CELL: - rs6000_cost = &ppccell_cost; - break; - - case PROCESSOR_PPC750: - case PROCESSOR_PPC7400: - rs6000_cost = &ppc750_cost; - break; - - case PROCESSOR_PPC7450: - rs6000_cost = &ppc7450_cost; - break; - - case PROCESSOR_PPC8540: - case PROCESSOR_PPC8548: - rs6000_cost = &ppc8540_cost; - break; - - case PROCESSOR_PPCE300C2: - case PROCESSOR_PPCE300C3: - rs6000_cost = &ppce300c2c3_cost; - break; - - case PROCESSOR_PPCE500MC: - rs6000_cost = &ppce500mc_cost; - break; - - case PROCESSOR_PPCE500MC64: - rs6000_cost = &ppce500mc64_cost; - break; - - case PROCESSOR_PPCE5500: - rs6000_cost = &ppce5500_cost; - break; - - case PROCESSOR_PPCE6500: - rs6000_cost = &ppce6500_cost; - break; - - case PROCESSOR_TITAN: - rs6000_cost = &titan_cost; - break; - - case PROCESSOR_POWER4: - case PROCESSOR_POWER5: - rs6000_cost = &power4_cost; - break; - - case PROCESSOR_POWER6: - rs6000_cost = &power6_cost; - break; - - case PROCESSOR_POWER7: - rs6000_cost = &power7_cost; - break; - - case PROCESSOR_PPCA2: - rs6000_cost = &ppca2_cost; - break; - - default: - gcc_unreachable (); - } - - if (global_init_p) - { - maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES, - rs6000_cost->simultaneous_prefetches, - global_options.x_param_values, - global_options_set.x_param_values); - maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size, - global_options.x_param_values, - global_options_set.x_param_values); - maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE, - rs6000_cost->cache_line_size, - global_options.x_param_values, - global_options_set.x_param_values); - maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size, - global_options.x_param_values, - global_options_set.x_param_values); - - /* Increase loop peeling limits based on performance analysis. */ - maybe_set_param_value (PARAM_MAX_PEELED_INSNS, 400, - global_options.x_param_values, - global_options_set.x_param_values); - maybe_set_param_value (PARAM_MAX_COMPLETELY_PEELED_INSNS, 400, - global_options.x_param_values, - global_options_set.x_param_values); - - /* If using typedef char *va_list, signal that - __builtin_va_start (&ap, 0) can be optimized to - ap = __builtin_next_arg (0). */ - if (DEFAULT_ABI != ABI_V4) - targetm.expand_builtin_va_start = NULL; - } - - /* Set up single/double float flags. - If TARGET_HARD_FLOAT is set, but neither single or double is set, - then set both flags. */ - if (TARGET_HARD_FLOAT && TARGET_FPRS - && rs6000_single_float == 0 && rs6000_double_float == 0) - rs6000_single_float = rs6000_double_float = 1; - - /* If not explicitly specified via option, decide whether to generate indexed - load/store instructions. */ - if (TARGET_AVOID_XFORM == -1) - /* Avoid indexed addressing when targeting Power6 in order to avoid the - DERAT mispredict penalty. However the LVE and STVE altivec instructions - need indexed accesses and the type used is the scalar type of the element - being loaded or stored. */ - TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB - && !TARGET_ALTIVEC); - - /* Set the -mrecip options. */ - if (rs6000_recip_name) - { - char *p = ASTRDUP (rs6000_recip_name); - char *q; - unsigned int mask, i; - bool invert; - - while ((q = strtok (p, ",")) != NULL) - { - p = NULL; - if (*q == '!') - { - invert = true; - q++; - } - else - invert = false; - - if (!strcmp (q, "default")) - mask = ((TARGET_RECIP_PRECISION) - ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION); - else - { - for (i = 0; i < ARRAY_SIZE (recip_options); i++) - if (!strcmp (q, recip_options[i].string)) - { - mask = recip_options[i].mask; - break; - } - - if (i == ARRAY_SIZE (recip_options)) - { - error ("unknown option for -mrecip=%s", q); - invert = false; - mask = 0; - ret = false; - } - } - - if (invert) - rs6000_recip_control &= ~mask; - else - rs6000_recip_control |= mask; - } - } - - /* Set the builtin mask of the various options used that could affect which - builtins were used. In the past we used target_flags, but we've run out - of bits, and some options like SPE and PAIRED are no longer in - target_flags. */ - rs6000_builtin_mask = rs6000_builtin_mask_calculate (); - if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) - { - fprintf (stderr, - "new builtin mask = " HOST_WIDE_INT_PRINT_HEX ", ", - rs6000_builtin_mask); - rs6000_print_builtin_options (stderr, 0, NULL, rs6000_builtin_mask); - } - - /* Initialize all of the registers. */ - rs6000_init_hard_regno_mode_ok (global_init_p); - - /* Save the initial options in case the user does function specific options */ - if (global_init_p) - target_option_default_node = target_option_current_node - = build_target_option_node (); - - /* If not explicitly specified via option, decide whether to generate the - extra blr's required to preserve the link stack on some cpus (eg, 476). */ - if (TARGET_LINK_STACK == -1) - SET_TARGET_LINK_STACK (rs6000_cpu == PROCESSOR_PPC476 && flag_pic); - - return ret; -} - -/* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to - define the target cpu type. */ - -static void -rs6000_option_override (void) -{ - (void) rs6000_option_override_internal (true); -} - - -/* Implement targetm.vectorize.builtin_mask_for_load. */ -static tree -rs6000_builtin_mask_for_load (void) -{ - if (TARGET_ALTIVEC || TARGET_VSX) - return altivec_builtin_mask_for_load; - else - return 0; -} - -/* Implement LOOP_ALIGN. */ -int -rs6000_loop_align (rtx label) -{ - basic_block bb; - int ninsns; - - /* Don't override loop alignment if -falign-loops was specified. */ - if (!can_override_loop_align) - return align_loops_log; - - bb = BLOCK_FOR_INSN (label); - ninsns = num_loop_insns(bb->loop_father); - - /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */ - if (ninsns > 4 && ninsns <= 8 - && (rs6000_cpu == PROCESSOR_POWER4 - || rs6000_cpu == PROCESSOR_POWER5 - || rs6000_cpu == PROCESSOR_POWER6 - || rs6000_cpu == PROCESSOR_POWER7)) - return 5; - else - return align_loops_log; -} - -/* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */ -static int -rs6000_loop_align_max_skip (rtx label) -{ - return (1 << rs6000_loop_align (label)) - 1; -} - -/* Return true iff, data reference of TYPE can reach vector alignment (16) - after applying N number of iterations. This routine does not determine - how may iterations are required to reach desired alignment. */ - -static bool -rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed) -{ - if (is_packed) - return false; - - if (TARGET_32BIT) - { - if (rs6000_alignment_flags == MASK_ALIGN_NATURAL) - return true; - - if (rs6000_alignment_flags == MASK_ALIGN_POWER) - return true; - - return false; - } - else - { - if (TARGET_MACHO) - return false; - - /* Assuming that all other types are naturally aligned. CHECKME! */ - return true; - } -} - -/* Return true if the vector misalignment factor is supported by the - target. */ -static bool -rs6000_builtin_support_vector_misalignment (enum machine_mode mode, - const_tree type, - int misalignment, - bool is_packed) -{ - if (TARGET_VSX) - { - /* Return if movmisalign pattern is not supported for this mode. */ - if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing) - return false; - - if (misalignment == -1) - { - /* Misalignment factor is unknown at compile time but we know - it's word aligned. */ - if (rs6000_vector_alignment_reachable (type, is_packed)) - { - int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type)); - - if (element_size == 64 || element_size == 32) - return true; - } - - return false; - } - - /* VSX supports word-aligned vector. */ - if (misalignment % 4 == 0) - return true; - } - return false; -} - -/* Implement targetm.vectorize.builtin_vectorization_cost. */ -static int -rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, - tree vectype, int misalign) -{ - unsigned elements; - tree elem_type; - - switch (type_of_cost) - { - case scalar_stmt: - case scalar_load: - case scalar_store: - case vector_stmt: - case vector_load: - case vector_store: - case vec_to_scalar: - case scalar_to_vec: - case cond_branch_not_taken: - return 1; - - case vec_perm: - if (TARGET_VSX) - return 3; - else - return 1; - - case vec_promote_demote: - if (TARGET_VSX) - return 4; - else - return 1; - - case cond_branch_taken: - return 3; - - case unaligned_load: - if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN) - { - elements = TYPE_VECTOR_SUBPARTS (vectype); - if (elements == 2) - /* Double word aligned. */ - return 2; - - if (elements == 4) - { - switch (misalign) - { - case 8: - /* Double word aligned. */ - return 2; - - case -1: - /* Unknown misalignment. */ - case 4: - case 12: - /* Word aligned. */ - return 22; - - default: - gcc_unreachable (); - } - } - } - - if (TARGET_ALTIVEC) - /* Misaligned loads are not supported. */ - gcc_unreachable (); - - return 2; - - case unaligned_store: - if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN) - { - elements = TYPE_VECTOR_SUBPARTS (vectype); - if (elements == 2) - /* Double word aligned. */ - return 2; - - if (elements == 4) - { - switch (misalign) - { - case 8: - /* Double word aligned. */ - return 2; - - case -1: - /* Unknown misalignment. */ - case 4: - case 12: - /* Word aligned. */ - return 23; - - default: - gcc_unreachable (); - } - } - } - - if (TARGET_ALTIVEC) - /* Misaligned stores are not supported. */ - gcc_unreachable (); - - return 2; - - case vec_construct: - elements = TYPE_VECTOR_SUBPARTS (vectype); - elem_type = TREE_TYPE (vectype); - /* 32-bit vectors loaded into registers are stored as double - precision, so we need n/2 converts in addition to the usual - n/2 merges to construct a vector of short floats from them. */ - if (SCALAR_FLOAT_TYPE_P (elem_type) - && TYPE_PRECISION (elem_type) == 32) - return elements + 1; - else - return elements / 2 + 1; - - default: - gcc_unreachable (); - } -} - -/* Implement targetm.vectorize.preferred_simd_mode. */ - -static enum machine_mode -rs6000_preferred_simd_mode (enum machine_mode mode) -{ - if (TARGET_VSX) - switch (mode) - { - case DFmode: - return V2DFmode; - default:; - } - if (TARGET_ALTIVEC || TARGET_VSX) - switch (mode) - { - case SFmode: - return V4SFmode; - case DImode: - return V2DImode; - case SImode: - return V4SImode; - case HImode: - return V8HImode; - case QImode: - return V16QImode; - default:; - } - if (TARGET_SPE) - switch (mode) - { - case SFmode: - return V2SFmode; - case SImode: - return V2SImode; - default:; - } - if (TARGET_PAIRED_FLOAT - && mode == SFmode) - return V2SFmode; - return word_mode; -} - -typedef struct _rs6000_cost_data -{ - struct loop *loop_info; - unsigned cost[3]; -} rs6000_cost_data; - -/* Test for likely overcommitment of vector hardware resources. If a - loop iteration is relatively large, and too large a percentage of - instructions in the loop are vectorized, the cost model may not - adequately reflect delays from unavailable vector resources. - Penalize the loop body cost for this case. */ - -static void -rs6000_density_test (rs6000_cost_data *data) -{ - const int DENSITY_PCT_THRESHOLD = 85; - const int DENSITY_SIZE_THRESHOLD = 70; - const int DENSITY_PENALTY = 10; - struct loop *loop = data->loop_info; - basic_block *bbs = get_loop_body (loop); - int nbbs = loop->num_nodes; - int vec_cost = data->cost[vect_body], not_vec_cost = 0; - int i, density_pct; - - for (i = 0; i < nbbs; i++) - { - basic_block bb = bbs[i]; - gimple_stmt_iterator gsi; - - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - stmt_vec_info stmt_info = vinfo_for_stmt (stmt); - - if (!STMT_VINFO_RELEVANT_P (stmt_info) - && !STMT_VINFO_IN_PATTERN_P (stmt_info)) - not_vec_cost++; - } - } - - free (bbs); - density_pct = (vec_cost * 100) / (vec_cost + not_vec_cost); - - if (density_pct > DENSITY_PCT_THRESHOLD - && vec_cost + not_vec_cost > DENSITY_SIZE_THRESHOLD) - { - data->cost[vect_body] = vec_cost * (100 + DENSITY_PENALTY) / 100; - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "density %d%%, cost %d exceeds threshold, penalizing " - "loop body cost by %d%%", density_pct, - vec_cost + not_vec_cost, DENSITY_PENALTY); - } -} - -/* Implement targetm.vectorize.init_cost. */ - -static void * -rs6000_init_cost (struct loop *loop_info) -{ - rs6000_cost_data *data = XNEW (struct _rs6000_cost_data); - data->loop_info = loop_info; - data->cost[vect_prologue] = 0; - data->cost[vect_body] = 0; - data->cost[vect_epilogue] = 0; - return data; -} - -/* Implement targetm.vectorize.add_stmt_cost. */ - -static unsigned -rs6000_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind, - struct _stmt_vec_info *stmt_info, int misalign, - enum vect_cost_model_location where) -{ - rs6000_cost_data *cost_data = (rs6000_cost_data*) data; - unsigned retval = 0; - - if (flag_vect_cost_model) - { - tree vectype = stmt_info ? stmt_vectype (stmt_info) : NULL_TREE; - int stmt_cost = rs6000_builtin_vectorization_cost (kind, vectype, - misalign); - /* Statements in an inner loop relative to the loop being - vectorized are weighted more heavily. The value here is - arbitrary and could potentially be improved with analysis. */ - if (where == vect_body && stmt_info && stmt_in_inner_loop_p (stmt_info)) - count *= 50; /* FIXME. */ - - retval = (unsigned) (count * stmt_cost); - cost_data->cost[where] += retval; - } - - return retval; -} - -/* Implement targetm.vectorize.finish_cost. */ - -static void -rs6000_finish_cost (void *data, unsigned *prologue_cost, - unsigned *body_cost, unsigned *epilogue_cost) -{ - rs6000_cost_data *cost_data = (rs6000_cost_data*) data; - - if (cost_data->loop_info) - rs6000_density_test (cost_data); - - *prologue_cost = cost_data->cost[vect_prologue]; - *body_cost = cost_data->cost[vect_body]; - *epilogue_cost = cost_data->cost[vect_epilogue]; -} - -/* Implement targetm.vectorize.destroy_cost_data. */ - -static void -rs6000_destroy_cost_data (void *data) -{ - free (data); -} - -/* Handler for the Mathematical Acceleration Subsystem (mass) interface to a - library with vectorized intrinsics. */ - -static tree -rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in) -{ - char name[32]; - const char *suffix = NULL; - tree fntype, new_fndecl, bdecl = NULL_TREE; - int n_args = 1; - const char *bname; - enum machine_mode el_mode, in_mode; - int n, in_n; - - /* Libmass is suitable for unsafe math only as it does not correctly support - parts of IEEE with the required precision such as denormals. Only support - it if we have VSX to use the simd d2 or f4 functions. - XXX: Add variable length support. */ - if (!flag_unsafe_math_optimizations || !TARGET_VSX) - return NULL_TREE; - - el_mode = TYPE_MODE (TREE_TYPE (type_out)); - n = TYPE_VECTOR_SUBPARTS (type_out); - in_mode = TYPE_MODE (TREE_TYPE (type_in)); - in_n = TYPE_VECTOR_SUBPARTS (type_in); - if (el_mode != in_mode - || n != in_n) - return NULL_TREE; - - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) - { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); - switch (fn) - { - case BUILT_IN_ATAN2: - case BUILT_IN_HYPOT: - case BUILT_IN_POW: - n_args = 2; - /* fall through */ - - case BUILT_IN_ACOS: - case BUILT_IN_ACOSH: - case BUILT_IN_ASIN: - case BUILT_IN_ASINH: - case BUILT_IN_ATAN: - case BUILT_IN_ATANH: - case BUILT_IN_CBRT: - case BUILT_IN_COS: - case BUILT_IN_COSH: - case BUILT_IN_ERF: - case BUILT_IN_ERFC: - case BUILT_IN_EXP2: - case BUILT_IN_EXP: - case BUILT_IN_EXPM1: - case BUILT_IN_LGAMMA: - case BUILT_IN_LOG10: - case BUILT_IN_LOG1P: - case BUILT_IN_LOG2: - case BUILT_IN_LOG: - case BUILT_IN_SIN: - case BUILT_IN_SINH: - case BUILT_IN_SQRT: - case BUILT_IN_TAN: - case BUILT_IN_TANH: - bdecl = builtin_decl_implicit (fn); - suffix = "d2"; /* pow -> powd2 */ - if (el_mode != DFmode - || n != 2 - || !bdecl) - return NULL_TREE; - break; - - case BUILT_IN_ATAN2F: - case BUILT_IN_HYPOTF: - case BUILT_IN_POWF: - n_args = 2; - /* fall through */ - - case BUILT_IN_ACOSF: - case BUILT_IN_ACOSHF: - case BUILT_IN_ASINF: - case BUILT_IN_ASINHF: - case BUILT_IN_ATANF: - case BUILT_IN_ATANHF: - case BUILT_IN_CBRTF: - case BUILT_IN_COSF: - case BUILT_IN_COSHF: - case BUILT_IN_ERFF: - case BUILT_IN_ERFCF: - case BUILT_IN_EXP2F: - case BUILT_IN_EXPF: - case BUILT_IN_EXPM1F: - case BUILT_IN_LGAMMAF: - case BUILT_IN_LOG10F: - case BUILT_IN_LOG1PF: - case BUILT_IN_LOG2F: - case BUILT_IN_LOGF: - case BUILT_IN_SINF: - case BUILT_IN_SINHF: - case BUILT_IN_SQRTF: - case BUILT_IN_TANF: - case BUILT_IN_TANHF: - bdecl = builtin_decl_implicit (fn); - suffix = "4"; /* powf -> powf4 */ - if (el_mode != SFmode - || n != 4 - || !bdecl) - return NULL_TREE; - break; - - default: - return NULL_TREE; - } - } - else - return NULL_TREE; - - gcc_assert (suffix != NULL); - bname = IDENTIFIER_POINTER (DECL_NAME (bdecl)); - if (!bname) - return NULL_TREE; - - strcpy (name, bname + sizeof ("__builtin_") - 1); - strcat (name, suffix); - - if (n_args == 1) - fntype = build_function_type_list (type_out, type_in, NULL); - else if (n_args == 2) - fntype = build_function_type_list (type_out, type_in, type_in, NULL); - else - gcc_unreachable (); - - /* Build a function declaration for the vectorized function. */ - new_fndecl = build_decl (BUILTINS_LOCATION, - FUNCTION_DECL, get_identifier (name), fntype); - TREE_PUBLIC (new_fndecl) = 1; - DECL_EXTERNAL (new_fndecl) = 1; - DECL_IS_NOVOPS (new_fndecl) = 1; - TREE_READONLY (new_fndecl) = 1; - - return new_fndecl; -} - -/* Returns a function decl for a vectorized version of the builtin function - with builtin function code FN and the result vector type TYPE, or NULL_TREE - if it is not available. */ - -static tree -rs6000_builtin_vectorized_function (tree fndecl, tree type_out, - tree type_in) -{ - enum machine_mode in_mode, out_mode; - int in_n, out_n; - - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "rs6000_builtin_vectorized_function (%s, %s, %s)\n", - IDENTIFIER_POINTER (DECL_NAME (fndecl)), - GET_MODE_NAME (TYPE_MODE (type_out)), - GET_MODE_NAME (TYPE_MODE (type_in))); - - if (TREE_CODE (type_out) != VECTOR_TYPE - || TREE_CODE (type_in) != VECTOR_TYPE - || !TARGET_VECTORIZE_BUILTINS) - return NULL_TREE; - - out_mode = TYPE_MODE (TREE_TYPE (type_out)); - out_n = TYPE_VECTOR_SUBPARTS (type_out); - in_mode = TYPE_MODE (TREE_TYPE (type_in)); - in_n = TYPE_VECTOR_SUBPARTS (type_in); - - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) - { - enum built_in_function fn = DECL_FUNCTION_CODE (fndecl); - switch (fn) - { - case BUILT_IN_COPYSIGN: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP]; - break; - case BUILT_IN_COPYSIGNF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF]; - break; - case BUILT_IN_SQRT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP]; - break; - case BUILT_IN_SQRTF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP]; - break; - case BUILT_IN_CEIL: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP]; - break; - case BUILT_IN_CEILF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP]; - break; - case BUILT_IN_FLOOR: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM]; - break; - case BUILT_IN_FLOORF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM]; - break; - case BUILT_IN_FMA: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP]; - break; - case BUILT_IN_FMAF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP]; - else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP]; - break; - case BUILT_IN_TRUNC: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ]; - break; - case BUILT_IN_TRUNCF: - if (out_mode != SFmode || out_n != 4 - || in_mode != SFmode || in_n != 4) - break; - if (VECTOR_UNIT_VSX_P (V4SFmode)) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ]; - if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ]; - break; - case BUILT_IN_NEARBYINT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && flag_unsafe_math_optimizations - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI]; - break; - case BUILT_IN_NEARBYINTF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && flag_unsafe_math_optimizations - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI]; - break; - case BUILT_IN_RINT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && !flag_trapping_math - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC]; - break; - case BUILT_IN_RINTF: - if (VECTOR_UNIT_VSX_P (V4SFmode) - && !flag_trapping_math - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC]; - break; - default: - break; - } - } - - else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) - { - enum rs6000_builtins fn - = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl); - switch (fn) - { - case RS6000_BUILTIN_RSQRTF: - if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP]; - break; - case RS6000_BUILTIN_RSQRT: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF]; - break; - case RS6000_BUILTIN_RECIPF: - if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) - && out_mode == SFmode && out_n == 4 - && in_mode == SFmode && in_n == 4) - return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP]; - break; - case RS6000_BUILTIN_RECIP: - if (VECTOR_UNIT_VSX_P (V2DFmode) - && out_mode == DFmode && out_n == 2 - && in_mode == DFmode && in_n == 2) - return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF]; - break; - default: - break; - } - } - - /* Generate calls to libmass if appropriate. */ - if (rs6000_veclib_handler) - return rs6000_veclib_handler (fndecl, type_out, type_in); - - return NULL_TREE; -} - -/* Default CPU string for rs6000*_file_start functions. */ -static const char *rs6000_default_cpu; - -/* Do anything needed at the start of the asm file. */ - -static void -rs6000_file_start (void) -{ - char buffer[80]; - const char *start = buffer; - FILE *file = asm_out_file; - - rs6000_default_cpu = TARGET_CPU_DEFAULT; - - default_file_start (); - - if (flag_verbose_asm) - { - sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START); - - if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0') - { - fprintf (file, "%s --with-cpu=%s", start, rs6000_default_cpu); - start = ""; - } - - if (global_options_set.x_rs6000_cpu_index) - { - fprintf (file, "%s -mcpu=%s", start, - processor_target_table[rs6000_cpu_index].name); - start = ""; - } - - if (global_options_set.x_rs6000_tune_index) - { - fprintf (file, "%s -mtune=%s", start, - processor_target_table[rs6000_tune_index].name); - start = ""; - } - - if (PPC405_ERRATUM77) - { - fprintf (file, "%s PPC405CR_ERRATUM77", start); - start = ""; - } - -#ifdef USING_ELFOS_H - switch (rs6000_sdata) - { - case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break; - case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break; - case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break; - case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break; - } - - if (rs6000_sdata && g_switch_value) - { - fprintf (file, "%s -G %d", start, - g_switch_value); - start = ""; - } -#endif - - if (*start == '\0') - putc ('\n', file); - } - - if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2)) - { - switch_to_section (toc_section); - switch_to_section (text_section); - } -} - - -/* Return nonzero if this function is known to have a null epilogue. */ - -int -direct_return (void) -{ - if (reload_completed) - { - rs6000_stack_t *info = rs6000_stack_info (); - - if (info->first_gp_reg_save == 32 - && info->first_fp_reg_save == 64 - && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1 - && ! info->lr_save_p - && ! info->cr_save_p - && info->vrsave_mask == 0 - && ! info->push_p) - return 1; - } - - return 0; -} - -/* Return the number of instructions it takes to form a constant in an - integer register. */ - -int -num_insns_constant_wide (HOST_WIDE_INT value) -{ - /* signed constant loadable with addi */ - if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000) - return 1; - - /* constant loadable with addis */ - else if ((value & 0xffff) == 0 - && (value >> 31 == -1 || value >> 31 == 0)) - return 1; - -#if HOST_BITS_PER_WIDE_INT == 64 - else if (TARGET_POWERPC64) - { - HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; - HOST_WIDE_INT high = value >> 31; - - if (high == 0 || high == -1) - return 2; - - high >>= 1; - - if (low == 0) - return num_insns_constant_wide (high) + 1; - else if (high == 0) - return num_insns_constant_wide (low) + 1; - else - return (num_insns_constant_wide (high) - + num_insns_constant_wide (low) + 1); - } -#endif - - else - return 2; -} - -int -num_insns_constant (rtx op, enum machine_mode mode) -{ - HOST_WIDE_INT low, high; - - switch (GET_CODE (op)) - { - case CONST_INT: -#if HOST_BITS_PER_WIDE_INT == 64 - if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1 - && mask64_operand (op, mode)) - return 2; - else -#endif - return num_insns_constant_wide (INTVAL (op)); - - case CONST_DOUBLE: - if (mode == SFmode || mode == SDmode) - { - long l; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - if (DECIMAL_FLOAT_MODE_P (mode)) - REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l); - else - REAL_VALUE_TO_TARGET_SINGLE (rv, l); - return num_insns_constant_wide ((HOST_WIDE_INT) l); - } - - if (mode == VOIDmode || mode == DImode) - { - high = CONST_DOUBLE_HIGH (op); - low = CONST_DOUBLE_LOW (op); - } - else - { - long l[2]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, op); - if (DECIMAL_FLOAT_MODE_P (mode)) - REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l); - else - REAL_VALUE_TO_TARGET_DOUBLE (rv, l); - high = l[WORDS_BIG_ENDIAN == 0]; - low = l[WORDS_BIG_ENDIAN != 0]; - } - - if (TARGET_32BIT) - return (num_insns_constant_wide (low) - + num_insns_constant_wide (high)); - else - { - if ((high == 0 && low >= 0) - || (high == -1 && low < 0)) - return num_insns_constant_wide (low); - - else if (mask64_operand (op, mode)) - return 2; - - else if (low == 0) - return num_insns_constant_wide (high) + 1; - - else - return (num_insns_constant_wide (high) - + num_insns_constant_wide (low) + 1); - } - - default: - gcc_unreachable (); - } -} - -/* Interpret element ELT of the CONST_VECTOR OP as an integer value. - If the mode of OP is MODE_VECTOR_INT, this simply returns the - corresponding element of the vector, but for V4SFmode and V2SFmode, - the corresponding "float" is interpreted as an SImode integer. */ - -HOST_WIDE_INT -const_vector_elt_as_int (rtx op, unsigned int elt) -{ - rtx tmp; - - /* We can't handle V2DImode and V2DFmode vector constants here yet. */ - gcc_assert (GET_MODE (op) != V2DImode - && GET_MODE (op) != V2DFmode); - - tmp = CONST_VECTOR_ELT (op, elt); - if (GET_MODE (op) == V4SFmode - || GET_MODE (op) == V2SFmode) - tmp = gen_lowpart (SImode, tmp); - return INTVAL (tmp); -} - -/* Return true if OP can be synthesized with a particular vspltisb, vspltish - or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used - depends on STEP and COPIES, one of which will be 1. If COPIES > 1, - all items are set to the same value and contain COPIES replicas of the - vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's - operand and the others are set to the value of the operand's msb. */ - -static bool -vspltis_constant (rtx op, unsigned step, unsigned copies) -{ - enum machine_mode mode = GET_MODE (op); - enum machine_mode inner = GET_MODE_INNER (mode); - - unsigned i; - unsigned nunits; - unsigned bitsize; - unsigned mask; - - HOST_WIDE_INT val; - HOST_WIDE_INT splat_val; - HOST_WIDE_INT msb_val; - - if (mode == V2DImode || mode == V2DFmode) - return false; - - nunits = GET_MODE_NUNITS (mode); - bitsize = GET_MODE_BITSIZE (inner); - mask = GET_MODE_MASK (inner); - - val = const_vector_elt_as_int (op, nunits - 1); - splat_val = val; - msb_val = val > 0 ? 0 : -1; - - /* Construct the value to be splatted, if possible. If not, return 0. */ - for (i = 2; i <= copies; i *= 2) - { - HOST_WIDE_INT small_val; - bitsize /= 2; - small_val = splat_val >> bitsize; - mask >>= bitsize; - if (splat_val != ((small_val << bitsize) | (small_val & mask))) - return false; - splat_val = small_val; - } - - /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */ - if (EASY_VECTOR_15 (splat_val)) - ; - - /* Also check if we can splat, and then add the result to itself. Do so if - the value is positive, of if the splat instruction is using OP's mode; - for splat_val < 0, the splat and the add should use the same mode. */ - else if (EASY_VECTOR_15_ADD_SELF (splat_val) - && (splat_val >= 0 || (step == 1 && copies == 1))) - ; - - /* Also check if are loading up the most significant bit which can be done by - loading up -1 and shifting the value left by -1. */ - else if (EASY_VECTOR_MSB (splat_val, inner)) - ; - - else - return false; - - /* Check if VAL is present in every STEP-th element, and the - other elements are filled with its most significant bit. */ - for (i = 0; i < nunits - 1; ++i) - { - HOST_WIDE_INT desired_val; - if (((i + 1) & (step - 1)) == 0) - desired_val = val; - else - desired_val = msb_val; - - if (desired_val != const_vector_elt_as_int (op, i)) - return false; - } - - return true; -} - - -/* Return true if OP is of the given MODE and can be synthesized - with a vspltisb, vspltish or vspltisw. */ - -bool -easy_altivec_constant (rtx op, enum machine_mode mode) -{ - unsigned step, copies; - - if (mode == VOIDmode) - mode = GET_MODE (op); - else if (mode != GET_MODE (op)) - return false; - - /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy - constants. */ - if (mode == V2DFmode) - return zero_constant (op, mode); - - if (mode == V2DImode) - { - /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not - easy. */ - if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT - || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT) - return false; - - if (zero_constant (op, mode)) - return true; - - if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1 - && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1) - return true; - - return false; - } - - /* Start with a vspltisw. */ - step = GET_MODE_NUNITS (mode) / 4; - copies = 1; - - if (vspltis_constant (op, step, copies)) - return true; - - /* Then try with a vspltish. */ - if (step == 1) - copies <<= 1; - else - step >>= 1; - - if (vspltis_constant (op, step, copies)) - return true; - - /* And finally a vspltisb. */ - if (step == 1) - copies <<= 1; - else - step >>= 1; - - if (vspltis_constant (op, step, copies)) - return true; - - return false; -} - -/* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose - result is OP. Abort if it is not possible. */ - -rtx -gen_easy_altivec_constant (rtx op) -{ - enum machine_mode mode = GET_MODE (op); - int nunits = GET_MODE_NUNITS (mode); - rtx last = CONST_VECTOR_ELT (op, nunits - 1); - unsigned step = nunits / 4; - unsigned copies = 1; - - /* Start with a vspltisw. */ - if (vspltis_constant (op, step, copies)) - return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last)); - - /* Then try with a vspltish. */ - if (step == 1) - copies <<= 1; - else - step >>= 1; - - if (vspltis_constant (op, step, copies)) - return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last)); - - /* And finally a vspltisb. */ - if (step == 1) - copies <<= 1; - else - step >>= 1; - - if (vspltis_constant (op, step, copies)) - return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last)); - - gcc_unreachable (); -} - -const char * -output_vec_const_move (rtx *operands) -{ - int cst, cst2; - enum machine_mode mode; - rtx dest, vec; - - dest = operands[0]; - vec = operands[1]; - mode = GET_MODE (dest); - - if (TARGET_VSX) - { - if (zero_constant (vec, mode)) - return "xxlxor %x0,%x0,%x0"; - - if (mode == V2DImode - && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1 - && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1) - return "vspltisw %0,-1"; - } - - if (TARGET_ALTIVEC) - { - rtx splat_vec; - if (zero_constant (vec, mode)) - return "vxor %0,%0,%0"; - - splat_vec = gen_easy_altivec_constant (vec); - gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE); - operands[1] = XEXP (splat_vec, 0); - if (!EASY_VECTOR_15 (INTVAL (operands[1]))) - return "#"; - - switch (GET_MODE (splat_vec)) - { - case V4SImode: - return "vspltisw %0,%1"; - - case V8HImode: - return "vspltish %0,%1"; - - case V16QImode: - return "vspltisb %0,%1"; - - default: - gcc_unreachable (); - } - } - - gcc_assert (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 ;-). */ - cst = INTVAL (CONST_VECTOR_ELT (vec, 0)); - cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1)); - operands[1] = CONST_VECTOR_ELT (vec, 0); - operands[2] = CONST_VECTOR_ELT (vec, 1); - 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"; -} - -/* Initialize TARGET of vector PAIRED to VALS. */ - -void -paired_expand_vector_init (rtx target, rtx vals) -{ - enum machine_mode mode = GET_MODE (target); - int n_elts = GET_MODE_NUNITS (mode); - int n_var = 0; - rtx x, new_rtx, tmp, constant_op, op1, op2; - int i; - - for (i = 0; i < n_elts; ++i) - { - x = XVECEXP (vals, 0, i); - if (!(CONST_INT_P (x) - || GET_CODE (x) == CONST_DOUBLE - || GET_CODE (x) == CONST_FIXED)) - ++n_var; - } - if (n_var == 0) - { - /* Load from constant pool. */ - emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0))); - return; - } - - if (n_var == 2) - { - /* The vector is initialized only with non-constants. */ - new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0), - XVECEXP (vals, 0, 1)); - - emit_move_insn (target, new_rtx); - return; - } - - /* One field is non-constant and the other one is a constant. Load the - constant from the constant pool and use ps_merge instruction to - construct the whole vector. */ - op1 = XVECEXP (vals, 0, 0); - op2 = XVECEXP (vals, 0, 1); - - constant_op = (CONSTANT_P (op1)) ? op1 : op2; - - tmp = gen_reg_rtx (GET_MODE (constant_op)); - emit_move_insn (tmp, constant_op); - - if (CONSTANT_P (op1)) - new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2); - else - new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp); - - emit_move_insn (target, new_rtx); -} - -void -paired_expand_vector_move (rtx operands[]) -{ - rtx op0 = operands[0], op1 = operands[1]; - - emit_move_insn (op0, op1); -} - -/* Emit vector compare for code RCODE. DEST is destination, OP1 and - OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two - operands for the relation operation COND. This is a recursive - function. */ - -static void -paired_emit_vector_compare (enum rtx_code rcode, - rtx dest, rtx op0, rtx op1, - rtx cc_op0, rtx cc_op1) -{ - rtx tmp = gen_reg_rtx (V2SFmode); - rtx tmp1, max, min; - - gcc_assert (TARGET_PAIRED_FLOAT); - gcc_assert (GET_MODE (op0) == GET_MODE (op1)); - - switch (rcode) - { - case LT: - case LTU: - paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1); - return; - case GE: - case GEU: - emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1)); - emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode))); - return; - case LE: - case LEU: - paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0); - return; - case GT: - paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1); - return; - case EQ: - tmp1 = gen_reg_rtx (V2SFmode); - max = gen_reg_rtx (V2SFmode); - min = gen_reg_rtx (V2SFmode); - gen_reg_rtx (V2SFmode); - - emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1)); - emit_insn (gen_selv2sf4 - (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode))); - emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0)); - emit_insn (gen_selv2sf4 - (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode))); - emit_insn (gen_subv2sf3 (tmp1, min, max)); - emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode))); - return; - case NE: - paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1); - return; - case UNLE: - paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1); - return; - case UNLT: - paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1); - return; - case UNGE: - paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1); - return; - case UNGT: - paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1); - return; - default: - gcc_unreachable (); - } - - return; -} - -/* Emit vector conditional expression. - DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands. - CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */ - -int -paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2, - rtx cond, rtx cc_op0, rtx cc_op1) -{ - enum rtx_code rcode = GET_CODE (cond); - - if (!TARGET_PAIRED_FLOAT) - return 0; - - paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1); - - return 1; -} - -/* Initialize vector TARGET to VALS. */ - -void -rs6000_expand_vector_init (rtx target, rtx vals) -{ - enum machine_mode mode = GET_MODE (target); - enum machine_mode inner_mode = GET_MODE_INNER (mode); - int n_elts = GET_MODE_NUNITS (mode); - int n_var = 0, one_var = -1; - bool all_same = true, all_const_zero = true; - rtx x, mem; - int i; - - for (i = 0; i < n_elts; ++i) - { - x = XVECEXP (vals, 0, i); - if (!(CONST_INT_P (x) - || GET_CODE (x) == CONST_DOUBLE - || GET_CODE (x) == CONST_FIXED)) - ++n_var, one_var = i; - else if (x != CONST0_RTX (inner_mode)) - all_const_zero = false; - - if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0))) - all_same = false; - } - - if (n_var == 0) - { - rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)); - bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT); - if ((int_vector_p || TARGET_VSX) && all_const_zero) - { - /* Zero register. */ - emit_insn (gen_rtx_SET (VOIDmode, target, - gen_rtx_XOR (mode, target, target))); - return; - } - else if (int_vector_p && easy_vector_constant (const_vec, mode)) - { - /* Splat immediate. */ - emit_insn (gen_rtx_SET (VOIDmode, target, const_vec)); - return; - } - else - { - /* Load from constant pool. */ - emit_move_insn (target, const_vec); - return; - } - } - - /* Double word values on VSX can use xxpermdi or lxvdsx. */ - if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) - { - rtx op0 = XVECEXP (vals, 0, 0); - rtx op1 = XVECEXP (vals, 0, 1); - if (all_same) - { - if (!MEM_P (op0) && !REG_P (op0)) - op0 = force_reg (inner_mode, op0); - if (mode == V2DFmode) - emit_insn (gen_vsx_splat_v2df (target, op0)); - else - emit_insn (gen_vsx_splat_v2di (target, op0)); - } - else - { - op0 = force_reg (inner_mode, op0); - op1 = force_reg (inner_mode, op1); - if (mode == V2DFmode) - emit_insn (gen_vsx_concat_v2df (target, op0, op1)); - else - emit_insn (gen_vsx_concat_v2di (target, op0, op1)); - } - return; - } - - /* With single precision floating point on VSX, know that internally single - precision is actually represented as a double, and either make 2 V2DF - vectors, and convert these vectors to single precision, or do one - conversion, and splat the result to the other elements. */ - if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode)) - { - if (all_same) - { - rtx freg = gen_reg_rtx (V4SFmode); - rtx sreg = force_reg (SFmode, XVECEXP (vals, 0, 0)); - - emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg)); - emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx)); - } - else - { - rtx dbl_even = gen_reg_rtx (V2DFmode); - rtx dbl_odd = gen_reg_rtx (V2DFmode); - rtx flt_even = gen_reg_rtx (V4SFmode); - rtx flt_odd = gen_reg_rtx (V4SFmode); - rtx op0 = force_reg (SFmode, XVECEXP (vals, 0, 0)); - rtx op1 = force_reg (SFmode, XVECEXP (vals, 0, 1)); - rtx op2 = force_reg (SFmode, XVECEXP (vals, 0, 2)); - rtx op3 = force_reg (SFmode, XVECEXP (vals, 0, 3)); - - emit_insn (gen_vsx_concat_v2sf (dbl_even, op0, op1)); - emit_insn (gen_vsx_concat_v2sf (dbl_odd, op2, op3)); - emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even)); - emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd)); - rs6000_expand_extract_even (target, flt_even, flt_odd); - } - return; - } - - /* Store value to stack temp. Load vector element. Splat. However, splat - of 64-bit items is not supported on Altivec. */ - if (all_same && GET_MODE_SIZE (inner_mode) <= 4) - { - mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode)); - emit_move_insn (adjust_address_nv (mem, inner_mode, 0), - XVECEXP (vals, 0, 0)); - x = gen_rtx_UNSPEC (VOIDmode, - gen_rtvec (1, const0_rtx), UNSPEC_LVE); - emit_insn (gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (2, - gen_rtx_SET (VOIDmode, - target, mem), - x))); - x = gen_rtx_VEC_SELECT (inner_mode, target, - gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (1, const0_rtx))); - emit_insn (gen_rtx_SET (VOIDmode, target, - gen_rtx_VEC_DUPLICATE (mode, x))); - return; - } - - /* One field is non-constant. Load constant then overwrite - varying field. */ - if (n_var == 1) - { - rtx copy = copy_rtx (vals); - - /* Load constant part of vector, substitute neighboring value for - varying element. */ - XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts); - rs6000_expand_vector_init (target, copy); - - /* Insert variable. */ - rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var); - return; - } - - /* Construct the vector in memory one field at a time - and load the whole vector. */ - mem = assign_stack_temp (mode, GET_MODE_SIZE (mode)); - for (i = 0; i < n_elts; i++) - emit_move_insn (adjust_address_nv (mem, inner_mode, - i * GET_MODE_SIZE (inner_mode)), - XVECEXP (vals, 0, i)); - emit_move_insn (target, mem); -} - -/* Set field ELT of TARGET to VAL. */ - -void -rs6000_expand_vector_set (rtx target, rtx val, int elt) -{ - enum machine_mode mode = GET_MODE (target); - enum machine_mode inner_mode = GET_MODE_INNER (mode); - rtx reg = gen_reg_rtx (mode); - rtx mask, mem, x; - int width = GET_MODE_SIZE (inner_mode); - int i; - - if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode)) - { - rtx (*set_func) (rtx, rtx, rtx, rtx) - = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di); - emit_insn (set_func (target, target, val, GEN_INT (elt))); - return; - } - - /* Load single variable value. */ - mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode)); - emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val); - x = gen_rtx_UNSPEC (VOIDmode, - gen_rtvec (1, const0_rtx), UNSPEC_LVE); - emit_insn (gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (2, - gen_rtx_SET (VOIDmode, - reg, mem), - x))); - - /* Linear sequence. */ - mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16)); - for (i = 0; i < 16; ++i) - XVECEXP (mask, 0, i) = GEN_INT (i); - - /* Set permute mask to insert element into target. */ - for (i = 0; i < width; ++i) - XVECEXP (mask, 0, elt*width + i) - = GEN_INT (i + 0x10); - x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0)); - x = gen_rtx_UNSPEC (mode, - gen_rtvec (3, target, reg, - force_reg (V16QImode, x)), - UNSPEC_VPERM); - emit_insn (gen_rtx_SET (VOIDmode, target, x)); -} - -/* Extract field ELT from VEC into TARGET. */ - -void -rs6000_expand_vector_extract (rtx target, rtx vec, int elt) -{ - enum machine_mode mode = GET_MODE (vec); - enum machine_mode inner_mode = GET_MODE_INNER (mode); - rtx mem; - - if (VECTOR_MEM_VSX_P (mode)) - { - switch (mode) - { - default: - break; - case V2DFmode: - emit_insn (gen_vsx_extract_v2df (target, vec, GEN_INT (elt))); - return; - case V2DImode: - emit_insn (gen_vsx_extract_v2di (target, vec, GEN_INT (elt))); - return; - case V4SFmode: - emit_insn (gen_vsx_extract_v4sf (target, vec, GEN_INT (elt))); - return; - } - } - - /* Allocate mode-sized buffer. */ - mem = assign_stack_temp (mode, GET_MODE_SIZE (mode)); - - emit_move_insn (mem, vec); - - /* Add offset to field within buffer matching vector element. */ - mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode)); - - emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0)); -} - -/* Generates shifts and masks for a pair of rldicl or rldicr insns to - implement ANDing by the mask IN. */ -void -build_mask64_2_operands (rtx in, rtx *out) -{ -#if HOST_BITS_PER_WIDE_INT >= 64 - unsigned HOST_WIDE_INT c, lsb, m1, m2; - int shift; - - gcc_assert (GET_CODE (in) == CONST_INT); - - c = INTVAL (in); - if (c & 1) - { - /* Assume c initially something like 0x00fff000000fffff. The idea - is to rotate the word so that the middle ^^^^^^ group of zeros - is at the MS end and can be cleared with an rldicl mask. We then - rotate back and clear off the MS ^^ group of zeros with a - second rldicl. */ - c = ~c; /* c == 0xff000ffffff00000 */ - lsb = c & -c; /* lsb == 0x0000000000100000 */ - m1 = -lsb; /* m1 == 0xfffffffffff00000 */ - c = ~c; /* c == 0x00fff000000fffff */ - c &= -lsb; /* c == 0x00fff00000000000 */ - lsb = c & -c; /* lsb == 0x0000100000000000 */ - c = ~c; /* c == 0xff000fffffffffff */ - c &= -lsb; /* c == 0xff00000000000000 */ - shift = 0; - while ((lsb >>= 1) != 0) - shift++; /* shift == 44 on exit from loop */ - m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */ - m1 = ~m1; /* m1 == 0x000000ffffffffff */ - m2 = ~c; /* m2 == 0x00ffffffffffffff */ - } - else - { - /* Assume c initially something like 0xff000f0000000000. The idea - is to rotate the word so that the ^^^ middle group of zeros - is at the LS end and can be cleared with an rldicr mask. We then - rotate back and clear off the LS group of ^^^^^^^^^^ zeros with - a second rldicr. */ - lsb = c & -c; /* lsb == 0x0000010000000000 */ - m2 = -lsb; /* m2 == 0xffffff0000000000 */ - c = ~c; /* c == 0x00fff0ffffffffff */ - c &= -lsb; /* c == 0x00fff00000000000 */ - lsb = c & -c; /* lsb == 0x0000100000000000 */ - c = ~c; /* c == 0xff000fffffffffff */ - c &= -lsb; /* c == 0xff00000000000000 */ - shift = 0; - while ((lsb >>= 1) != 0) - shift++; /* shift == 44 on exit from loop */ - m1 = ~c; /* m1 == 0x00ffffffffffffff */ - m1 >>= shift; /* m1 == 0x0000000000000fff */ - m1 = ~m1; /* m1 == 0xfffffffffffff000 */ - } - - /* Note that when we only have two 0->1 and 1->0 transitions, one of the - masks will be all 1's. We are guaranteed more than one transition. */ - out[0] = GEN_INT (64 - shift); - out[1] = GEN_INT (m1); - out[2] = GEN_INT (shift); - out[3] = GEN_INT (m2); -#else - (void)in; - (void)out; - gcc_unreachable (); -#endif -} - -/* Return TRUE if OP is an invalid SUBREG operation on the e500. */ - -bool -invalid_e500_subreg (rtx op, enum machine_mode mode) -{ - if (TARGET_E500_DOUBLE) - { - /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or - subreg:TI and reg:TF. Decimal float modes are like integer - modes (only low part of each register used) for this - purpose. */ - if (GET_CODE (op) == SUBREG - && (mode == SImode || mode == DImode || mode == TImode - || mode == DDmode || mode == TDmode) - && REG_P (SUBREG_REG (op)) - && (GET_MODE (SUBREG_REG (op)) == DFmode - || GET_MODE (SUBREG_REG (op)) == TFmode)) - return true; - - /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and - reg:TI. */ - if (GET_CODE (op) == SUBREG - && (mode == DFmode || mode == TFmode) - && REG_P (SUBREG_REG (op)) - && (GET_MODE (SUBREG_REG (op)) == DImode - || GET_MODE (SUBREG_REG (op)) == TImode - || GET_MODE (SUBREG_REG (op)) == DDmode - || GET_MODE (SUBREG_REG (op)) == TDmode)) - return true; - } - - if (TARGET_SPE - && GET_CODE (op) == SUBREG - && mode == SImode - && REG_P (SUBREG_REG (op)) - && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op)))) - return true; - - return false; -} - -/* 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, unsigned int computed, - unsigned int specified) -{ - unsigned int align = MAX (computed, specified); - tree field = TYPE_FIELDS (type); - - /* Skip all non field decls */ - while (field != NULL && TREE_CODE (field) != FIELD_DECL) - field = DECL_CHAIN (field); - - if (field != NULL && field != type) - { - type = TREE_TYPE (field); - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - - if (type != error_mark_node && TYPE_MODE (type) == DFmode) - align = MAX (align, 64); - } - - return align; -} - -/* Darwin increases record alignment to the natural alignment of - the first field. */ - -unsigned int -darwin_rs6000_special_round_type_align (tree type, unsigned int computed, - unsigned int specified) -{ - unsigned int align = MAX (computed, specified); - - if (TYPE_PACKED (type)) - return align; - - /* Find the first field, looking down into aggregates. */ - do { - tree field = TYPE_FIELDS (type); - /* Skip all non field decls */ - while (field != NULL && TREE_CODE (field) != FIELD_DECL) - field = DECL_CHAIN (field); - if (! field) - break; - /* A packed field does not contribute any extra alignment. */ - if (DECL_PACKED (field)) - return align; - type = TREE_TYPE (field); - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - } while (AGGREGATE_TYPE_P (type)); - - if (! AGGREGATE_TYPE_P (type) && type != error_mark_node) - align = MAX (align, TYPE_ALIGN (type)); - - return align; -} - -/* Return 1 for an operand in small memory on V.4/eabi. */ - -int -small_data_operand (rtx op ATTRIBUTE_UNUSED, - enum machine_mode mode ATTRIBUTE_UNUSED) -{ -#if TARGET_ELF - rtx sym_ref; - - if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA) - return 0; - - if (DEFAULT_ABI != ABI_V4) - return 0; - - /* Vector and float memory instructions have a limited offset on the - SPE, so using a vector or float variable directly as an operand is - not useful. */ - if (TARGET_SPE - && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode))) - return 0; - - if (GET_CODE (op) == SYMBOL_REF) - sym_ref = op; - - else if (GET_CODE (op) != CONST - || GET_CODE (XEXP (op, 0)) != PLUS - || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF - || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT) - return 0; - - else - { - rtx sum = XEXP (op, 0); - HOST_WIDE_INT summand; - - /* 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) - return 0; - - sym_ref = XEXP (sum, 0); - } - - return SYMBOL_REF_SMALL_P (sym_ref); -#else - return 0; -#endif -} - -/* 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)))); -} - -/* Given an address, return a constant offset term if one exists. */ - -static rtx -address_offset (rtx op) -{ - if (GET_CODE (op) == PRE_INC - || GET_CODE (op) == PRE_DEC) - op = XEXP (op, 0); - else if (GET_CODE (op) == PRE_MODIFY - || GET_CODE (op) == LO_SUM) - op = XEXP (op, 1); - - if (GET_CODE (op) == CONST) - op = XEXP (op, 0); - - if (GET_CODE (op) == PLUS) - op = XEXP (op, 1); - - if (CONST_INT_P (op)) - return op; - - return NULL_RTX; -} - -/* Return true if the MEM operand is a memory operand suitable for use - with a (full width, possibly multiple) gpr load/store. On - powerpc64 this means the offset must be divisible by 4. - Implements 'Y' constraint. - - Accept direct, indexed, offset, lo_sum and tocref. Since this is - a constraint function we know the operand has satisfied a suitable - memory predicate. Also accept some odd rtl generated by reload - (see rs6000_legitimize_reload_address for various forms). It is - important that reload rtl be accepted by appropriate constraints - but not by the operand predicate. - - Offsetting a lo_sum should not be allowed, except where we know by - alignment that a 32k boundary is not crossed, but see the ??? - comment in rs6000_legitimize_reload_address. Note that by - "offsetting" here we mean a further offset to access parts of the - MEM. It's fine to have a lo_sum where the inner address is offset - from a sym, since the same sym+offset will appear in the high part - of the address calculation. */ - -bool -mem_operand_gpr (rtx op, enum machine_mode mode) -{ - unsigned HOST_WIDE_INT offset; - int extra; - rtx addr = XEXP (op, 0); - - op = address_offset (addr); - if (op == NULL_RTX) - return true; - - offset = INTVAL (op); - if (TARGET_POWERPC64 && (offset & 3) != 0) - return false; - - extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD; - gcc_assert (extra >= 0); - - if (GET_CODE (addr) == LO_SUM) - /* For lo_sum addresses, we must allow any offset except one that - causes a wrap, so test only the low 16 bits. */ - offset = ((offset & 0xffff) ^ 0x8000) - 0x8000; - - return offset + 0x8000 < 0x10000u - extra; -} - -/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */ - -static bool -reg_offset_addressing_ok_p (enum machine_mode mode) -{ - switch (mode) - { - case V16QImode: - case V8HImode: - case V4SFmode: - case V4SImode: - case V2DFmode: - case V2DImode: - /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */ - if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) - return false; - break; - - case V4HImode: - case V2SImode: - case V1DImode: - case V2SFmode: - /* Paired vector modes. Only reg+reg addressing is valid. */ - if (TARGET_PAIRED_FLOAT) - return false; - break; - - default: - break; - } - - return true; -} - -static bool -virtual_stack_registers_memory_p (rtx op) -{ - int regnum; - - if (GET_CODE (op) == REG) - regnum = REGNO (op); - - else if (GET_CODE (op) == PLUS - && GET_CODE (XEXP (op, 0)) == REG - && GET_CODE (XEXP (op, 1)) == CONST_INT) - regnum = REGNO (XEXP (op, 0)); - - else - return false; - - return (regnum >= FIRST_VIRTUAL_REGISTER - && regnum <= LAST_VIRTUAL_POINTER_REGISTER); -} - -/* Return true if memory accesses to OP are known to never straddle - a 32k boundary. */ - -static bool -offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset, - enum machine_mode mode) -{ - tree decl, type; - unsigned HOST_WIDE_INT dsize, dalign; - - if (GET_CODE (op) != SYMBOL_REF) - return false; - - decl = SYMBOL_REF_DECL (op); - if (!decl) - { - if (GET_MODE_SIZE (mode) == 0) - return false; - - /* -fsection-anchors loses the original SYMBOL_REF_DECL when - replacing memory addresses with an anchor plus offset. We - could find the decl by rummaging around in the block->objects - VEC for the given offset but that seems like too much work. */ - dalign = 1; - if (SYMBOL_REF_HAS_BLOCK_INFO_P (op) - && SYMBOL_REF_ANCHOR_P (op) - && SYMBOL_REF_BLOCK (op) != NULL) - { - struct object_block *block = SYMBOL_REF_BLOCK (op); - HOST_WIDE_INT lsb, mask; - - /* Given the alignment of the block.. */ - dalign = block->alignment; - mask = dalign / BITS_PER_UNIT - 1; - - /* ..and the combined offset of the anchor and any offset - to this block object.. */ - offset += SYMBOL_REF_BLOCK_OFFSET (op); - lsb = offset & -offset; - - /* ..find how many bits of the alignment we know for the - object. */ - mask &= lsb - 1; - dalign = mask + 1; - } - return dalign >= GET_MODE_SIZE (mode); - } - - if (DECL_P (decl)) - { - if (TREE_CODE (decl) == FUNCTION_DECL) - return true; - - if (!DECL_SIZE_UNIT (decl)) - return false; - - if (!host_integerp (DECL_SIZE_UNIT (decl), 1)) - return false; - - dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1); - if (dsize > 32768) - return false; - - dalign = DECL_ALIGN_UNIT (decl); - return dalign >= dsize; - } - - type = TREE_TYPE (decl); - - if (TREE_CODE (decl) == STRING_CST) - dsize = TREE_STRING_LENGTH (decl); - else if (TYPE_SIZE_UNIT (type) - && host_integerp (TYPE_SIZE_UNIT (type), 1)) - dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1); - else - return false; - if (dsize > 32768) - return false; - - dalign = TYPE_ALIGN (type); - if (CONSTANT_CLASS_P (decl)) - dalign = CONSTANT_ALIGNMENT (decl, dalign); - else - dalign = DATA_ALIGNMENT (decl, dalign); - dalign /= BITS_PER_UNIT; - return dalign >= dsize; -} - -static bool -constant_pool_expr_p (rtx op) -{ - rtx base, offset; - - split_const (op, &base, &offset); - return (GET_CODE (base) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (base) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode)); -} - -static const_rtx tocrel_base, tocrel_offset; - -/* Return true if OP is a toc pointer relative address (the output - of create_TOC_reference). If STRICT, do not match high part or - non-split -mcmodel=large/medium toc pointer relative addresses. */ - -bool -toc_relative_expr_p (const_rtx op, bool strict) -{ - if (!TARGET_TOC) - return false; - - if (TARGET_CMODEL != CMODEL_SMALL) - { - /* Only match the low part. */ - if (GET_CODE (op) == LO_SUM - && REG_P (XEXP (op, 0)) - && INT_REG_OK_FOR_BASE_P (XEXP (op, 0), strict)) - op = XEXP (op, 1); - else if (strict) - return false; - } - - tocrel_base = op; - tocrel_offset = const0_rtx; - if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1))) - { - tocrel_base = XEXP (op, 0); - tocrel_offset = XEXP (op, 1); - } - - return (GET_CODE (tocrel_base) == UNSPEC - && XINT (tocrel_base, 1) == UNSPEC_TOCREL); -} - -/* Return true if X is a constant pool address, and also for cmodel=medium - if X is a toc-relative address known to be offsettable within MODE. */ - -bool -legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode, - bool strict) -{ - return (toc_relative_expr_p (x, strict) - && (TARGET_CMODEL != CMODEL_MEDIUM - || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0)) - || mode == QImode - || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0), - INTVAL (tocrel_offset), mode))); -} - -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)); -} - -/* SPE offset addressing is limited to 5-bits worth of double words. */ -#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0) - -bool -rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, - bool strict, bool worst_case) -{ - unsigned HOST_WIDE_INT offset; - unsigned int extra; - - if (GET_CODE (x) != PLUS) - return false; - if (!REG_P (XEXP (x, 0))) - return false; - if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)) - return false; - if (!reg_offset_addressing_ok_p (mode)) - return virtual_stack_registers_memory_p (x); - if (legitimate_constant_pool_address_p (x, mode, strict)) - return true; - if (GET_CODE (XEXP (x, 1)) != CONST_INT) - return false; - - offset = INTVAL (XEXP (x, 1)); - extra = 0; - switch (mode) - { - case V4HImode: - case V2SImode: - case V1DImode: - case V2SFmode: - /* SPE vector modes. */ - return SPE_CONST_OFFSET_OK (offset); - - case DFmode: - case DDmode: - case DImode: - /* On e500v2, we may have: - - (subreg:DF (mem:DI (plus (reg) (const_int))) 0). - - Which gets addressed with evldd instructions. */ - if (TARGET_E500_DOUBLE) - return SPE_CONST_OFFSET_OK (offset); - - /* If we are using VSX scalar loads, restrict ourselves to reg+reg - addressing. */ - if (mode == DFmode && VECTOR_MEM_VSX_P (DFmode)) - return false; - - if (!worst_case) - break; - if (!TARGET_POWERPC64) - extra = 4; - else if (offset & 3) - return false; - break; - - case TFmode: - case TDmode: - case TImode: - if (TARGET_E500_DOUBLE) - return (SPE_CONST_OFFSET_OK (offset) - && SPE_CONST_OFFSET_OK (offset + 8)); - - extra = 8; - if (!worst_case) - break; - if (!TARGET_POWERPC64) - extra = 12; - else if (offset & 3) - return false; - break; - - default: - break; - } - - offset += 0x8000; - return offset < 0x10000 - extra; -} - -bool -legitimate_indexed_address_p (rtx x, int strict) -{ - rtx op0, op1; - - if (GET_CODE (x) != PLUS) - return false; - - op0 = XEXP (x, 0); - op1 = XEXP (x, 1); - - /* Recognize the rtl generated by reload which we know will later be - replaced with proper base and index regs. */ - if (!strict - && reload_in_progress - && (REG_P (op0) || GET_CODE (op0) == PLUS) - && REG_P (op1)) - return true; - - return (REG_P (op0) && REG_P (op1) - && ((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)))); -} - -bool -avoiding_indexed_address_p (enum machine_mode mode) -{ - /* Avoid indexed addressing for modes that have non-indexed - load/store instruction forms. */ - return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode)); -} - -bool -legitimate_indirect_address_p (rtx x, int strict) -{ - return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict); -} - -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; - /* Restrict addressing for DI because of our SUBREG hackery. */ - if (TARGET_E500_DOUBLE && GET_MODE_SIZE (mode) > UNITS_PER_WORD) - 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_SIZE (mode) > UNITS_PER_WORD - && !(/* ??? Assume floating point reg based on mode? */ - TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && (mode == DFmode || mode == DDmode))) - 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. - - OLDX is the address as it was before break_out_memory_refs was - called. In some cases it is useful to look at this to decide what - needs to be done. - - It is always safe for this function to do nothing. It exists to - recognize opportunities to optimize the output. - - On RS/6000, first check for the sum of a register with a constant - integer that is out of range. If so, generate code to add the - constant with the low-order 16 bits masked to the register and force - this result into another register (this can be done with `cau'). - Then generate an address of REG+(CONST&0xffff), allowing for the - possibility of bit 16 being a one. - - 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. */ - -static rtx -rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, - enum machine_mode mode) -{ - unsigned int extra; - - if (!reg_offset_addressing_ok_p (mode)) - { - if (virtual_stack_registers_memory_p (x)) - return x; - - /* In theory we should not be seeing addresses of the form reg+0, - but just in case it is generated, optimize it away. */ - if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx) - return force_reg (Pmode, XEXP (x, 0)); - - /* Make sure both operands are registers. */ - else if (GET_CODE (x) == PLUS) - return gen_rtx_PLUS (Pmode, - force_reg (Pmode, XEXP (x, 0)), - force_reg (Pmode, XEXP (x, 1))); - else - return force_reg (Pmode, x); - } - 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); - } - - extra = 0; - switch (mode) - { - case TFmode: - case TDmode: - case TImode: - /* As in legitimate_offset_address_p we do not assume - worst-case. The mode here is just a hint as to the registers - used. A TImode is usually in gprs, but may actually be in - fprs. Leave worst-case scenario for reload to handle via - insn constraints. */ - extra = 8; - break; - default: - break; - } - - if (GET_CODE (x) == PLUS - && GET_CODE (XEXP (x, 0)) == REG - && GET_CODE (XEXP (x, 1)) == CONST_INT - && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) - >= 0x10000 - extra) - && !(SPE_VECTOR_MODE (mode) - || (TARGET_E500_DOUBLE && GET_MODE_SIZE (mode) > UNITS_PER_WORD))) - { - HOST_WIDE_INT high_int, low_int; - rtx sum; - low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000; - if (low_int >= 0x8000 - extra) - low_int = 0; - high_int = INTVAL (XEXP (x, 1)) - low_int; - sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0), - GEN_INT (high_int)), 0); - return plus_constant (Pmode, sum, low_int); - } - else if (GET_CODE (x) == PLUS - && GET_CODE (XEXP (x, 0)) == REG - && GET_CODE (XEXP (x, 1)) != CONST_INT - && GET_MODE_NUNITS (mode) == 1 - && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD - || (/* ??? Assume floating point reg based on mode? */ - (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) - && (mode == DFmode || mode == DDmode))) - && !avoiding_indexed_address_p (mode)) - { - return gen_rtx_PLUS (Pmode, XEXP (x, 0), - force_reg (Pmode, force_operand (XEXP (x, 1), 0))); - } - else if (SPE_VECTOR_MODE (mode) - || (TARGET_E500_DOUBLE && GET_MODE_SIZE (mode) > UNITS_PER_WORD)) - { - if (mode == DImode) - return x; - /* We accept [reg + reg] and [reg + OFFSET]. */ - - if (GET_CODE (x) == PLUS) - { - rtx op1 = XEXP (x, 0); - rtx op2 = XEXP (x, 1); - rtx y; - - op1 = force_reg (Pmode, op1); - - if (GET_CODE (op2) != REG - && (GET_CODE (op2) != CONST_INT - || !SPE_CONST_OFFSET_OK (INTVAL (op2)) - || (GET_MODE_SIZE (mode) > 8 - && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8)))) - op2 = force_reg (Pmode, op2); - - /* We can't always do [reg + reg] for these, because [reg + - reg + offset] is not a legitimate addressing mode. */ - y = gen_rtx_PLUS (Pmode, op1, op2); - - if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2)) - return force_reg (Pmode, y); - else - return y; - } - - return force_reg (Pmode, x); - } - else if ((TARGET_ELF -#if TARGET_MACHO - || !MACHO_DYNAMIC_NO_PIC_P -#endif - ) - && TARGET_32BIT - && TARGET_NO_TOC - && ! flag_pic - && GET_CODE (x) != CONST_INT - && GET_CODE (x) != CONST_DOUBLE - && CONSTANT_P (x) - && GET_MODE_NUNITS (mode) == 1 - && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD - || (/* ??? Assume floating point reg based on mode? */ - (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) - && (mode == DFmode || mode == DDmode)))) - { - rtx reg = gen_reg_rtx (Pmode); - if (TARGET_ELF) - emit_insn (gen_elf_high (reg, x)); - else - emit_insn (gen_macho_high (reg, x)); - return gen_rtx_LO_SUM (Pmode, reg, x); - } - else if (TARGET_TOC - && GET_CODE (x) == SYMBOL_REF - && constant_pool_expr_p (x) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode)) - return create_TOC_reference (x, NULL_RTX); - else - return x; -} - -/* Debug version of rs6000_legitimize_address. */ -static rtx -rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode) -{ - rtx ret; - rtx insns; - - start_sequence (); - ret = rs6000_legitimize_address (x, oldx, mode); - insns = get_insns (); - end_sequence (); - - if (ret != x) - { - fprintf (stderr, - "\nrs6000_legitimize_address: mode %s, old code %s, " - "new code %s, modified\n", - GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)), - GET_RTX_NAME (GET_CODE (ret))); - - fprintf (stderr, "Original address:\n"); - debug_rtx (x); - - fprintf (stderr, "oldx:\n"); - debug_rtx (oldx); - - fprintf (stderr, "New address:\n"); - debug_rtx (ret); - - if (insns) - { - fprintf (stderr, "Insns added:\n"); - debug_rtx_list (insns, 20); - } - } - else - { - fprintf (stderr, - "\nrs6000_legitimize_address: mode %s, code %s, no change:\n", - GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x))); - - debug_rtx (x); - } - - if (insns) - emit_insn (insns); - - return ret; -} - -/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL. - We need to emit DTP-relative relocations. */ - -static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; -static 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: - gcc_unreachable (); - } - output_addr_const (file, x); - fputs ("@dtprel+0x8000", file); -} - -/* In the name of slightly smaller debug output, and to cater to - general assembler lossage, recognize various UNSPEC sequences - and turn them back into a direct symbol reference. */ - -static rtx -rs6000_delegitimize_address (rtx orig_x) -{ - rtx x, y, offset; - - orig_x = delegitimize_mem_from_attrs (orig_x); - x = orig_x; - if (MEM_P (x)) - x = XEXP (x, 0); - - y = x; - if (TARGET_CMODEL != CMODEL_SMALL - && GET_CODE (y) == LO_SUM) - y = XEXP (y, 1); - - offset = NULL_RTX; - if (GET_CODE (y) == PLUS - && GET_MODE (y) == Pmode - && CONST_INT_P (XEXP (y, 1))) - { - offset = XEXP (y, 1); - y = XEXP (y, 0); - } - - if (GET_CODE (y) == UNSPEC - && XINT (y, 1) == UNSPEC_TOCREL) - { -#ifdef ENABLE_CHECKING - if (REG_P (XVECEXP (y, 0, 1)) - && REGNO (XVECEXP (y, 0, 1)) == TOC_REGISTER) - { - /* All good. */ - } - else if (GET_CODE (XVECEXP (y, 0, 1)) == DEBUG_EXPR) - { - /* Weirdness alert. df_note_compute can replace r2 with a - debug_expr when this unspec is in a debug_insn. - Seen in gcc.dg/pr51957-1.c */ - } - else - { - debug_rtx (orig_x); - abort (); - } -#endif - y = XVECEXP (y, 0, 0); - -#ifdef HAVE_AS_TLS - /* Do not associate thread-local symbols with the original - constant pool symbol. */ - if (TARGET_XCOFF - && GET_CODE (y) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (y) - && SYMBOL_REF_TLS_MODEL (get_pool_constant (y)) >= TLS_MODEL_REAL) - return orig_x; -#endif - - if (offset != NULL_RTX) - y = gen_rtx_PLUS (Pmode, y, offset); - if (!MEM_P (orig_x)) - return y; - else - return replace_equiv_address_nv (orig_x, y); - } - - if (TARGET_MACHO - && GET_CODE (orig_x) == LO_SUM - && GET_CODE (XEXP (orig_x, 1)) == CONST) - { - y = XEXP (XEXP (orig_x, 1), 0); - if (GET_CODE (y) == UNSPEC - && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET) - return XVECEXP (y, 0, 0); - } - - return orig_x; -} - -/* Return true if X shouldn't be emitted into the debug info. - The linker doesn't like .toc section references from - .debug_* sections, so reject .toc section symbols. */ - -static bool -rs6000_const_not_ok_for_debug_p (rtx x) -{ - if (GET_CODE (x) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (x)) - { - rtx c = get_pool_constant (x); - enum machine_mode cmode = get_pool_mode (x); - if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (c, cmode)) - return true; - } - - return false; -} - -/* 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; -} - -/* AIX Thread-Local Address support. */ - -static rtx -rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model) -{ - rtx sym, mem, tocref, tlsreg, tmpreg, dest, tlsaddr; - const char *name; - char *tlsname; - - name = XSTR (addr, 0); - /* Append TLS CSECT qualifier, unless the symbol already is qualified - or the symbol will be in TLS private data section. */ - if (name[strlen (name) - 1] != ']' - && (TREE_PUBLIC (SYMBOL_REF_DECL (addr)) - || bss_initializer_p (SYMBOL_REF_DECL (addr)))) - { - tlsname = XALLOCAVEC (char, strlen (name) + 4); - strcpy (tlsname, name); - strcat (tlsname, - bss_initializer_p (SYMBOL_REF_DECL (addr)) ? "[UL]" : "[TL]"); - tlsaddr = copy_rtx (addr); - XSTR (tlsaddr, 0) = ggc_strdup (tlsname); - } - else - tlsaddr = addr; - - /* Place addr into TOC constant pool. */ - sym = force_const_mem (GET_MODE (tlsaddr), tlsaddr); - - /* Output the TOC entry and create the MEM referencing the value. */ - if (constant_pool_expr_p (XEXP (sym, 0)) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (XEXP (sym, 0)), Pmode)) - { - tocref = create_TOC_reference (XEXP (sym, 0), NULL_RTX); - mem = gen_const_mem (Pmode, tocref); - set_mem_alias_set (mem, get_TOC_alias_set ()); - } - else - return sym; - - /* Use global-dynamic for local-dynamic. */ - if (model == TLS_MODEL_GLOBAL_DYNAMIC - || model == TLS_MODEL_LOCAL_DYNAMIC) - { - /* Create new TOC reference for @m symbol. */ - name = XSTR (XVECEXP (XEXP (mem, 0), 0, 0), 0); - tlsname = XALLOCAVEC (char, strlen (name) + 1); - strcpy (tlsname, "*LCM"); - strcat (tlsname, name + 3); - rtx modaddr = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tlsname)); - SYMBOL_REF_FLAGS (modaddr) |= SYMBOL_FLAG_LOCAL; - tocref = create_TOC_reference (modaddr, NULL_RTX); - rtx modmem = gen_const_mem (Pmode, tocref); - set_mem_alias_set (modmem, get_TOC_alias_set ()); - - rtx modreg = gen_reg_rtx (Pmode); - emit_insn (gen_rtx_SET (VOIDmode, modreg, modmem)); - - tmpreg = gen_reg_rtx (Pmode); - emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem)); - - dest = gen_reg_rtx (Pmode); - if (TARGET_32BIT) - emit_insn (gen_tls_get_addrsi (dest, modreg, tmpreg)); - else - emit_insn (gen_tls_get_addrdi (dest, modreg, tmpreg)); - return dest; - } - /* Obtain TLS pointer: 32 bit call or 64 bit GPR 13. */ - else if (TARGET_32BIT) - { - tlsreg = gen_reg_rtx (SImode); - emit_insn (gen_tls_get_tpointer (tlsreg)); - } - else - tlsreg = gen_rtx_REG (DImode, 13); - - /* Load the TOC value into temporary register. */ - tmpreg = gen_reg_rtx (Pmode); - emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem)); - set_unique_reg_note (get_last_insn (), REG_EQUAL, - gen_rtx_MINUS (Pmode, addr, tlsreg)); - - /* Add TOC symbol value to TLS pointer. */ - dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tmpreg, tlsreg)); - - return dest; -} - -/* 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; - - if (TARGET_XCOFF) - return rs6000_legitimize_tls_address_aix (addr, model); - - 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, call_insn; - - /* We currently use relocations like @got@tlsgd for tls, which - means the linker will handle allocation of tls entries, placing - them in the .got section. So use a pointer to the .got section, - not one to secondary TOC sections used by 64-bit -mminimal-toc, - or to secondary GOT sections used by 32-bit -fPIC. */ - if (TARGET_64BIT) - got = gen_rtx_REG (Pmode, 2); - 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 - { - rtx mem, lab, last; - - tmp1 = gen_reg_rtx (Pmode); - tmp2 = gen_reg_rtx (Pmode); - mem = gen_const_mem (Pmode, tmp1); - lab = gen_label_rtx (); - emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab)); - emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO)); - if (TARGET_LINK_STACK) - emit_insn (gen_addsi3 (tmp1, tmp1, GEN_INT (4))); - emit_move_insn (tmp2, mem); - last = emit_insn (gen_addsi3 (got, tmp1, tmp2)); - set_unique_reg_note (last, REG_EQUAL, gsym); - } - } - } - - if (model == TLS_MODEL_GLOBAL_DYNAMIC) - { - tga = rs6000_tls_get_addr (); - emit_library_call_value (tga, dest, LCT_CONST, Pmode, - 1, const0_rtx, Pmode); - - r3 = gen_rtx_REG (Pmode, 3); - if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT) - insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx); - else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT) - insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx); - else if (DEFAULT_ABI == ABI_V4) - insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx); - else - gcc_unreachable (); - call_insn = last_call_insn (); - PATTERN (call_insn) = insn; - if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), - pic_offset_table_rtx); - } - else if (model == TLS_MODEL_LOCAL_DYNAMIC) - { - tga = rs6000_tls_get_addr (); - tmp1 = gen_reg_rtx (Pmode); - emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, - 1, const0_rtx, Pmode); - - r3 = gen_rtx_REG (Pmode, 3); - if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT) - insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx); - else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT) - insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx); - else if (DEFAULT_ABI == ABI_V4) - insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx); - else - gcc_unreachable (); - call_insn = last_call_insn (); - PATTERN (call_insn) = insn; - if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) - use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), - pic_offset_table_rtx); - - 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 contains a thread-local symbol. */ - -static bool -rs6000_tls_referenced_p (rtx x) -{ - if (! TARGET_HAVE_TLS) - return false; - - return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0); -} - -/* Implement TARGET_CANNOT_FORCE_CONST_MEM. */ - -static bool -rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) -{ - if (GET_CODE (x) == HIGH - && GET_CODE (XEXP (x, 0)) == UNSPEC) - return true; - - /* A TLS symbol in the TOC cannot contain a sum. */ - if (GET_CODE (x) == CONST - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF - && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) != 0) - return true; - - /* Do not place an ELF TLS symbol in the constant pool. */ - return TARGET_ELF && rs6000_tls_referenced_p (x); -} - -/* 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 int -rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED) -{ - return RS6000_SYMBOL_REF_TLS_P (*x); -} - -/* Return true iff the given SYMBOL_REF refers to a constant pool entry - that we have put in the TOC, or for cmodel=medium, if the SYMBOL_REF - can be addressed relative to the toc pointer. */ - -static bool -use_toc_relative_ref (rtx sym) -{ - return ((constant_pool_expr_p (sym) - && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (sym), - get_pool_mode (sym))) - || (TARGET_CMODEL == CMODEL_MEDIUM - && !CONSTANT_POOL_ADDRESS_P (sym) - && SYMBOL_REF_LOCAL_P (sym))); -} - -/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to - replace the input X, or the original X if no replacement is called for. - The output parameter *WIN is 1 if the calling macro should goto WIN, - 0 if it should not. - - For RS/6000, we wish to handle large displacements off a base - register by splitting the addend across an addiu/addis and the mem insn. - This cuts number of extra insns needed from 3 to 1. - - On Darwin, we use this to generate code for floating point constants. - A movsf_low is generated so we wind up with 2 instructions rather than 3. - The Darwin code is inside #if TARGET_MACHO because only then are the - machopic_* functions defined. */ -static rtx -rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, - int opnum, int type, - int ind_levels ATTRIBUTE_UNUSED, int *win) -{ - bool reg_offset_p = reg_offset_addressing_ok_p (mode); - - /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a - DFmode/DImode MEM. */ - if (reg_offset_p - && opnum == 1 - && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode) - || (mode == DImode && recog_data.operand_mode[0] == V2DImode))) - reg_offset_p = false; - - /* We must recognize output that we have already generated ourselves. */ - if (GET_CODE (x) == PLUS - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && GET_CODE (XEXP (x, 1)) == CONST_INT) - { - push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, - BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, - opnum, (enum reload_type) type); - *win = 1; - return x; - } - - /* Likewise for (lo_sum (high ...) ...) output we have generated. */ - if (GET_CODE (x) == LO_SUM - && GET_CODE (XEXP (x, 0)) == HIGH) - { - push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, - BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, - opnum, (enum reload_type) type); - *win = 1; - return x; - } - -#if TARGET_MACHO - if (DEFAULT_ABI == ABI_DARWIN && flag_pic - && GET_CODE (x) == LO_SUM - && GET_CODE (XEXP (x, 0)) == PLUS - && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx - && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH - && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1) - && machopic_operand_p (XEXP (x, 1))) - { - /* Result of previous invocation of this function on Darwin - floating point constant. */ - push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, - BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, - opnum, (enum reload_type) type); - *win = 1; - return x; - } -#endif - - if (TARGET_CMODEL != CMODEL_SMALL - && reg_offset_p - && small_toc_ref (x, VOIDmode)) - { - rtx hi = gen_rtx_HIGH (Pmode, copy_rtx (x)); - x = gen_rtx_LO_SUM (Pmode, hi, x); - push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, - BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, - opnum, (enum reload_type) type); - *win = 1; - return x; - } - - if (GET_CODE (x) == PLUS - && GET_CODE (XEXP (x, 0)) == REG - && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER - && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1) - && GET_CODE (XEXP (x, 1)) == CONST_INT - && reg_offset_p - && !SPE_VECTOR_MODE (mode) - && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode - || mode == DDmode || mode == TDmode - || mode == DImode)) - && VECTOR_MEM_NONE_P (mode)) - { - HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); - HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; - HOST_WIDE_INT high - = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000; - - /* Check for 32-bit overflow. */ - if (high + low != val) - { - *win = 0; - return x; - } - - /* Reload the high part into a base reg; leave the low part - in the mem directly. */ - - x = gen_rtx_PLUS (GET_MODE (x), - gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), - GEN_INT (high)), - GEN_INT (low)); - - push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, - BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, - opnum, (enum reload_type) type); - *win = 1; - return x; - } - - if (GET_CODE (x) == SYMBOL_REF - && reg_offset_p - && VECTOR_MEM_NONE_P (mode) - && !SPE_VECTOR_MODE (mode) -#if TARGET_MACHO - && DEFAULT_ABI == ABI_DARWIN - && (flag_pic || MACHO_DYNAMIC_NO_PIC_P) - && machopic_symbol_defined_p (x) -#else - && DEFAULT_ABI == ABI_V4 - && !flag_pic -#endif - /* Don't do this for TFmode or TDmode, since the result isn't offsettable. - The same goes for DImode without 64-bit gprs and DFmode and DDmode - without fprs. - ??? Assume floating point reg based on mode? This assumption is - violated by eg. powerpc-linux -m32 compile of gcc.dg/pr28796-2.c - where reload ends up doing a DFmode load of a constant from - mem using two gprs. Unfortunately, at this point reload - hasn't yet selected regs so poking around in reload data - won't help and even if we could figure out the regs reliably, - we'd still want to allow this transformation when the mem is - naturally aligned. Since we say the address is good here, we - can't disable offsets from LO_SUMs in mem_operand_gpr. - FIXME: Allow offset from lo_sum for other modes too, when - mem is sufficiently aligned. */ - && mode != TFmode - && mode != TDmode - && (mode != DImode || TARGET_POWERPC64) - && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64 - || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT))) - { -#if TARGET_MACHO - if (flag_pic) - { - rtx offset = machopic_gen_offset (x); - x = gen_rtx_LO_SUM (GET_MODE (x), - gen_rtx_PLUS (Pmode, pic_offset_table_rtx, - gen_rtx_HIGH (Pmode, offset)), offset); - } - else -#endif - 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); - *win = 1; - return x; - } - - /* Reload an offset address wrapped by an AND that represents the - masking of the lower bits. Strip the outer AND and let reload - convert the offset address into an indirect address. For VSX, - force reload to create the address with an AND in a separate - register, because we can't guarantee an altivec register will - be used. */ - if (VECTOR_MEM_ALTIVEC_P (mode) - && GET_CODE (x) == AND - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) == -16) - { - x = XEXP (x, 0); - *win = 1; - return x; - } - - if (TARGET_TOC - && reg_offset_p - && GET_CODE (x) == SYMBOL_REF - && use_toc_relative_ref (x)) - { - x = create_TOC_reference (x, NULL_RTX); - if (TARGET_CMODEL != CMODEL_SMALL) - push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, - BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, - opnum, (enum reload_type) type); - *win = 1; - return x; - } - *win = 0; - return x; -} - -/* Debug version of rs6000_legitimize_reload_address. */ -static rtx -rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode, - int opnum, int type, - int ind_levels, int *win) -{ - rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type, - ind_levels, win); - fprintf (stderr, - "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, " - "type = %d, ind_levels = %d, win = %d, original addr:\n", - GET_MODE_NAME (mode), opnum, type, ind_levels, *win); - debug_rtx (x); - - if (x == ret) - fprintf (stderr, "Same address returned\n"); - else if (!ret) - fprintf (stderr, "NULL returned\n"); - else - { - fprintf (stderr, "New address:\n"); - debug_rtx (ret); - } - - return ret; -} - -/* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression - that is a valid memory address for an instruction. - The MODE argument is the machine mode for the MEM expression - that wants to use this address. - - On the RS/6000, there are four valid address: a SYMBOL_REF that - 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, DDmode and DImode with a constant plus - register, we must ensure that both words are addressable or PowerPC64 - with offset word aligned. - - For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs, - 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used - because adjacent memory cells are accessed by adding word-sized offsets - during assembly output. */ -static bool -rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict) -{ - bool reg_offset_p = reg_offset_addressing_ok_p (mode); - - /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */ - if (VECTOR_MEM_ALTIVEC_P (mode) - && GET_CODE (x) == AND - && GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) == -16) - x = XEXP (x, 0); - - if (TARGET_ELF && 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) - && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) - && !SPE_VECTOR_MODE (mode) - && mode != TFmode - && mode != TDmode - /* Restrict addressing for DI because of our SUBREG hackery. */ - && !(TARGET_E500_DOUBLE - && (mode == DFmode || mode == DDmode || mode == DImode)) - && TARGET_UPDATE - && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)) - return 1; - if (virtual_stack_registers_memory_p (x)) - return 1; - if (reg_offset_p && legitimate_small_data_p (mode, x)) - return 1; - if (reg_offset_p - && legitimate_constant_pool_address_p (x, mode, reg_ok_strict)) - return 1; - /* If not REG_OK_STRICT (before reload) let pass any stack offset. */ - if (! reg_ok_strict - && reg_offset_p - && GET_CODE (x) == PLUS - && GET_CODE (XEXP (x, 0)) == REG - && (XEXP (x, 0) == virtual_stack_vars_rtx - || XEXP (x, 0) == arg_pointer_rtx) - && GET_CODE (XEXP (x, 1)) == CONST_INT) - return 1; - if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict, false)) - return 1; - if (mode != TImode - && mode != TFmode - && mode != TDmode - && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) - || TARGET_POWERPC64 - || (mode != DFmode && mode != DDmode) - || (TARGET_E500_DOUBLE && mode != DDmode)) - && (TARGET_POWERPC64 || mode != DImode) - && !avoiding_indexed_address_p (mode) - && legitimate_indexed_address_p (x, reg_ok_strict)) - return 1; - if (GET_CODE (x) == PRE_MODIFY - && mode != TImode - && mode != TFmode - && mode != TDmode - && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) - || TARGET_POWERPC64 - || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE)) - && (TARGET_POWERPC64 || mode != DImode) - && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) - && !SPE_VECTOR_MODE (mode) - /* Restrict addressing for DI because of our SUBREG hackery. */ - && !(TARGET_E500_DOUBLE - && (mode == DFmode || mode == DDmode || mode == DImode)) - && TARGET_UPDATE - && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict) - && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), - reg_ok_strict, false) - || (!avoiding_indexed_address_p (mode) - && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict))) - && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0))) - return 1; - if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict)) - return 1; - return 0; -} - -/* Debug version of rs6000_legitimate_address_p. */ -static bool -rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x, - bool reg_ok_strict) -{ - bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict); - fprintf (stderr, - "\nrs6000_legitimate_address_p: return = %s, mode = %s, " - "strict = %d, code = %s\n", - ret ? "true" : "false", - GET_MODE_NAME (mode), - reg_ok_strict, - GET_RTX_NAME (GET_CODE (x))); - debug_rtx (x); - - return ret; -} - -/* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */ - -static bool -rs6000_mode_dependent_address_p (const_rtx addr, - addr_space_t as ATTRIBUTE_UNUSED) -{ - return rs6000_mode_dependent_address_ptr (addr); -} - -/* 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 - and VSX 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. */ - -static bool -rs6000_mode_dependent_address (const_rtx addr) -{ - switch (GET_CODE (addr)) - { - case PLUS: - /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx - is considered a legitimate address before reload, so there - are no offset restrictions in that case. Note that this - condition is safe in strict mode because any address involving - virtual_stack_vars_rtx or arg_pointer_rtx would already have - been rejected as illegitimate. */ - if (XEXP (addr, 0) != virtual_stack_vars_rtx - && XEXP (addr, 0) != arg_pointer_rtx - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - { - unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1)); - return val + 0x8000 >= 0x10000 - (TARGET_POWERPC64 ? 8 : 12); - } - break; - - case LO_SUM: - /* Anything in the constant pool is sufficiently aligned that - all bytes have the same high part address. */ - return !legitimate_constant_pool_address_p (addr, QImode, false); - - /* Auto-increment cases are now treated generically in recog.c. */ - case PRE_MODIFY: - return TARGET_UPDATE; - - /* AND is only allowed in Altivec loads. */ - case AND: - return true; - - default: - break; - } - - return false; -} - -/* Debug version of rs6000_mode_dependent_address. */ -static bool -rs6000_debug_mode_dependent_address (const_rtx addr) -{ - bool ret = rs6000_mode_dependent_address (addr); - - fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n", - ret ? "true" : "false"); - debug_rtx (addr); - - return ret; -} - -/* Implement FIND_BASE_TERM. */ - -rtx -rs6000_find_base_term (rtx op) -{ - rtx base; - - base = op; - if (GET_CODE (base) == CONST) - base = XEXP (base, 0); - if (GET_CODE (base) == PLUS) - base = XEXP (base, 0); - if (GET_CODE (base) == UNSPEC) - switch (XINT (base, 1)) - { - case UNSPEC_TOCREL: - case UNSPEC_MACHOPIC_OFFSET: - /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term - for aliasing purposes. */ - return XVECEXP (base, 0, 0); - } - - return op; -} - -/* More elaborate version of recog's offsettable_memref_p predicate - that works around the ??? note of rs6000_mode_dependent_address. - In particular it accepts - - (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8]))) - - in 32-bit mode, that the recog predicate rejects. */ - -static bool -rs6000_offsettable_memref_p (rtx op, enum machine_mode reg_mode) -{ - bool worst_case; - - if (!MEM_P (op)) - return false; - - /* First mimic offsettable_memref_p. */ - if (offsettable_address_p (true, GET_MODE (op), XEXP (op, 0))) - return true; - - /* offsettable_address_p invokes rs6000_mode_dependent_address, but - the latter predicate knows nothing about the mode of the memory - reference and, therefore, assumes that it is the largest supported - mode (TFmode). As a consequence, legitimate offsettable memory - references are rejected. rs6000_legitimate_offset_address_p contains - the correct logic for the PLUS case of rs6000_mode_dependent_address, - at least with a little bit of help here given that we know the - actual registers used. */ - worst_case = ((TARGET_POWERPC64 && GET_MODE_CLASS (reg_mode) == MODE_INT) - || GET_MODE_SIZE (reg_mode) == 4); - return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), - true, worst_case); -} - -/* Change register usage conditional on target flags. */ -static void -rs6000_conditional_register_usage (void) -{ - int i; - - if (TARGET_DEBUG_TARGET) - fprintf (stderr, "rs6000_conditional_register_usage called\n"); - - /* Set MQ register fixed (already call_used) so that it will not be - allocated. */ - fixed_regs[64] = 1; - - /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */ - if (TARGET_64BIT) - fixed_regs[13] = call_used_regs[13] - = call_really_used_regs[13] = 1; - - /* Conditionally disable FPRs. */ - if (TARGET_SOFT_FLOAT || !TARGET_FPRS) - for (i = 32; i < 64; i++) - fixed_regs[i] = call_used_regs[i] - = call_really_used_regs[i] = 1; - - /* The TOC register is not killed across calls in a way that is - visible to the compiler. */ - if (DEFAULT_ABI == ABI_AIX) - call_really_used_regs[2] = 0; - - if (DEFAULT_ABI == ABI_V4 - && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM - && flag_pic == 2) - fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; - - if (DEFAULT_ABI == ABI_V4 - && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM - && flag_pic == 1) - fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; - - if (DEFAULT_ABI == ABI_DARWIN - && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) - fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; - - if (TARGET_TOC && TARGET_MINIMAL_TOC) - fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] - = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; - - if (TARGET_SPE) - { - global_regs[SPEFSCR_REGNO] = 1; - /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit - registers in prologues and epilogues. We no longer use r14 - for FIXED_SCRATCH, but we're keeping r14 out of the allocation - pool for link-compatibility with older versions of GCC. Once - "old" code has died out, we can return r14 to the allocation - pool. */ - fixed_regs[14] - = call_used_regs[14] - = call_really_used_regs[14] = 1; - } - - if (!TARGET_ALTIVEC && !TARGET_VSX) - { - for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) - fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; - call_really_used_regs[VRSAVE_REGNO] = 1; - } - - if (TARGET_ALTIVEC || TARGET_VSX) - global_regs[VSCR_REGNO] = 1; - - if (TARGET_ALTIVEC_ABI) - { - for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) - call_used_regs[i] = call_really_used_regs[i] = 1; - - /* AIX reserves VR20:31 in non-extended ABI mode. */ - if (TARGET_XCOFF) - for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i) - fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; - } -} - -/* Try to output insns to set TARGET equal to the constant C if it can - be done in less than N insns. Do all computations in MODE. - Returns the place where the output has been placed if it can be - done and the insns have been emitted. If it would take more than N - insns, zero is returned and no insns and emitted. */ - -rtx -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; - - switch (mode) - { - case QImode: - case HImode: - if (dest == NULL) - dest = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, dest, source)); - return dest; - - case SImode: - result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode); - - emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result), - GEN_INT (INTVAL (source) - & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_rtx_SET (VOIDmode, dest, - gen_rtx_IOR (SImode, copy_rtx (result), - GEN_INT (INTVAL (source) & 0xffff)))); - result = dest; - break; - - case DImode: - switch (GET_CODE (source)) - { - case CONST_INT: - c0 = INTVAL (source); - c1 = -(c0 < 0); - break; - - case CONST_DOUBLE: -#if HOST_BITS_PER_WIDE_INT >= 64 - c0 = CONST_DOUBLE_LOW (source); - c1 = -(c0 < 0); -#else - c0 = CONST_DOUBLE_LOW (source); - c1 = CONST_DOUBLE_HIGH (source); -#endif - break; - - default: - gcc_unreachable (); - } - - result = rs6000_emit_set_long_const (dest, c0, c1); - break; - - default: - gcc_unreachable (); - } - - insn = get_last_insn (); - set = single_set (insn); - if (! CONSTANT_P (SET_SRC (set))) - set_unique_reg_note (insn, REG_EQUAL, source); - - return result; -} - -/* Having failed to find a 3 insn sequence in rs6000_emit_set_const, - fall back to a straight forward decomposition. We do this to avoid - exponential run times encountered when looking for longer sequences - with rs6000_emit_set_const. */ -static rtx -rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2) -{ - if (!TARGET_POWERPC64) - { - rtx operand1, operand2; - - operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0, - DImode); - operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0, - DImode); - emit_move_insn (operand1, GEN_INT (c1)); - emit_move_insn (operand2, GEN_INT (c2)); - } - else - { - HOST_WIDE_INT ud1, ud2, ud3, ud4; - - ud1 = c1 & 0xffff; - ud2 = (c1 & 0xffff0000) >> 16; -#if HOST_BITS_PER_WIDE_INT >= 64 - c2 = c1 >> 32; -#endif - ud3 = c2 & 0xffff; - ud4 = (c2 & 0xffff0000) >> 16; - - if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000)) - || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000))) - { - if (ud1 & 0x8000) - emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000))); - else - emit_move_insn (dest, GEN_INT (ud1)); - } - - else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000)) - || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000))) - { - if (ud2 & 0x8000) - emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000) - - 0x80000000)); - else - emit_move_insn (dest, GEN_INT (ud2 << 16)); - if (ud1 != 0) - emit_move_insn (copy_rtx (dest), - gen_rtx_IOR (DImode, copy_rtx (dest), - GEN_INT (ud1))); - } - else if (ud3 == 0 && ud4 == 0) - { - gcc_assert (ud2 & 0x8000); - emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000) - - 0x80000000)); - if (ud1 != 0) - emit_move_insn (copy_rtx (dest), - gen_rtx_IOR (DImode, copy_rtx (dest), - GEN_INT (ud1))); - emit_move_insn (copy_rtx (dest), - gen_rtx_ZERO_EXTEND (DImode, - gen_lowpart (SImode, - copy_rtx (dest)))); - } - else if ((ud4 == 0xffff && (ud3 & 0x8000)) - || (ud4 == 0 && ! (ud3 & 0x8000))) - { - if (ud3 & 0x8000) - emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000) - - 0x80000000)); - else - emit_move_insn (dest, GEN_INT (ud3 << 16)); - - if (ud2 != 0) - emit_move_insn (copy_rtx (dest), - gen_rtx_IOR (DImode, copy_rtx (dest), - GEN_INT (ud2))); - emit_move_insn (copy_rtx (dest), - gen_rtx_ASHIFT (DImode, copy_rtx (dest), - GEN_INT (16))); - if (ud1 != 0) - emit_move_insn (copy_rtx (dest), - gen_rtx_IOR (DImode, copy_rtx (dest), - GEN_INT (ud1))); - } - else - { - if (ud4 & 0x8000) - emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000) - - 0x80000000)); - else - emit_move_insn (dest, GEN_INT (ud4 << 16)); - - if (ud3 != 0) - emit_move_insn (copy_rtx (dest), - gen_rtx_IOR (DImode, copy_rtx (dest), - GEN_INT (ud3))); - - emit_move_insn (copy_rtx (dest), - gen_rtx_ASHIFT (DImode, copy_rtx (dest), - GEN_INT (32))); - if (ud2 != 0) - emit_move_insn (copy_rtx (dest), - gen_rtx_IOR (DImode, copy_rtx (dest), - GEN_INT (ud2 << 16))); - if (ud1 != 0) - emit_move_insn (copy_rtx (dest), - gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1))); - } - } - return dest; -} - -/* Helper for the following. Get rid of [r+r] memory refs - in cases where it won't work (TImode, TFmode, TDmode). */ - -static void -rs6000_eliminate_indexed_memrefs (rtx operands[2]) -{ - if (reload_in_progress) - return; - - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) != REG - && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), - GET_MODE (operands[0]), false)) - operands[0] - = replace_equiv_address (operands[0], - copy_addr_to_reg (XEXP (operands[0], 0))); - - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) != REG - && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), - GET_MODE (operands[1]), false)) - operands[1] - = replace_equiv_address (operands[1], - copy_addr_to_reg (XEXP (operands[1], 0))); -} - -/* Emit a move from SOURCE to DEST in mode MODE. */ -void -rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode) -{ - rtx operands[2]; - operands[0] = dest; - operands[1] = source; - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, - "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, " - "reload_completed = %d, can_create_pseudos = %d.\ndest:\n", - GET_MODE_NAME (mode), - reload_in_progress, - reload_completed, - can_create_pseudo_p ()); - debug_rtx (dest); - fprintf (stderr, "source:\n"); - debug_rtx (source); - } - - /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */ - if (GET_CODE (operands[1]) == CONST_DOUBLE - && ! FLOAT_MODE_P (mode) - && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) - { - /* FIXME. This should never happen. */ - /* Since it seems that it does, do the safe thing and convert - to a CONST_INT. */ - operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode); - } - gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE - || FLOAT_MODE_P (mode) - || ((CONST_DOUBLE_HIGH (operands[1]) != 0 - || CONST_DOUBLE_LOW (operands[1]) < 0) - && (CONST_DOUBLE_HIGH (operands[1]) != -1 - || CONST_DOUBLE_LOW (operands[1]) >= 0))); - - /* Check if GCC is setting up a block move that will end up using FP - registers as temporaries. We must make sure this is acceptable. */ - if (GET_CODE (operands[0]) == MEM - && GET_CODE (operands[1]) == MEM - && mode == DImode - && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0])) - || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1]))) - && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32 - ? 32 : MEM_ALIGN (operands[0]))) - || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32 - ? 32 - : MEM_ALIGN (operands[1])))) - && ! MEM_VOLATILE_P (operands [0]) - && ! MEM_VOLATILE_P (operands [1])) - { - emit_move_insn (adjust_address (operands[0], SImode, 0), - adjust_address (operands[1], SImode, 0)); - emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4), - adjust_address (copy_rtx (operands[1]), SImode, 4)); - return; - } - - if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM - && !gpc_reg_operand (operands[1], mode)) - operands[1] = force_reg (mode, operands[1]); - - /* Recognize the case where operand[1] is a reference to thread-local - data and load its address to a register. */ - if (rs6000_tls_referenced_p (operands[1])) - { - enum tls_model model; - rtx tmp = operands[1]; - rtx addend = NULL; - - if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS) - { - addend = XEXP (XEXP (tmp, 0), 1); - tmp = XEXP (XEXP (tmp, 0), 0); - } - - gcc_assert (GET_CODE (tmp) == SYMBOL_REF); - model = SYMBOL_REF_TLS_MODEL (tmp); - gcc_assert (model != 0); - - tmp = rs6000_legitimize_tls_address (tmp, model); - if (addend) - { - tmp = gen_rtx_PLUS (mode, tmp, addend); - tmp = force_operand (tmp, operands[0]); - } - operands[1] = tmp; - } - - /* Handle the case where reload calls us with an invalid address. */ - if (reload_in_progress && mode == Pmode - && (! general_operand (operands[1], mode) - || ! nonimmediate_operand (operands[0], mode))) - goto emit_set; - - /* 128-bit constant floating-point values on Darwin should really be - loaded as two parts. */ - if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128 - && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE) - { - rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode, 0), - simplify_gen_subreg (DFmode, operands[1], mode, 0), - DFmode); - rs6000_emit_move (simplify_gen_subreg (DFmode, operands[0], mode, - GET_MODE_SIZE (DFmode)), - simplify_gen_subreg (DFmode, operands[1], mode, - GET_MODE_SIZE (DFmode)), - DFmode); - return; - } - - if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX) - cfun->machine->sdmode_stack_slot = - eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX); - - if (reload_in_progress - && mode == SDmode - && MEM_P (operands[0]) - && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot) - && REG_P (operands[1])) - { - if (FP_REGNO_P (REGNO (operands[1]))) - { - rtx mem = adjust_address_nv (operands[0], DDmode, 0); - mem = eliminate_regs (mem, VOIDmode, NULL_RTX); - emit_insn (gen_movsd_store (mem, operands[1])); - } - else if (INT_REGNO_P (REGNO (operands[1]))) - { - rtx mem = adjust_address_nv (operands[0], mode, 4); - mem = eliminate_regs (mem, VOIDmode, NULL_RTX); - emit_insn (gen_movsd_hardfloat (mem, operands[1])); - } - else - gcc_unreachable(); - return; - } - if (reload_in_progress - && mode == SDmode - && REG_P (operands[0]) - && MEM_P (operands[1]) - && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot)) - { - if (FP_REGNO_P (REGNO (operands[0]))) - { - rtx mem = adjust_address_nv (operands[1], DDmode, 0); - mem = eliminate_regs (mem, VOIDmode, NULL_RTX); - emit_insn (gen_movsd_load (operands[0], mem)); - } - else if (INT_REGNO_P (REGNO (operands[0]))) - { - rtx mem = adjust_address_nv (operands[1], mode, 4); - mem = eliminate_regs (mem, VOIDmode, NULL_RTX); - emit_insn (gen_movsd_hardfloat (operands[0], mem)); - } - else - gcc_unreachable(); - 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. */ - switch (mode) - { - case HImode: - case QImode: - if (CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != CONST_INT) - operands[1] = force_const_mem (mode, operands[1]); - break; - - case TFmode: - case TDmode: - rs6000_eliminate_indexed_memrefs (operands); - /* fall through */ - - case DFmode: - case DDmode: - case SFmode: - case SDmode: - if (CONSTANT_P (operands[1]) - && ! easy_fp_constant (operands[1], mode)) - operands[1] = force_const_mem (mode, operands[1]); - break; - - case V16QImode: - case V8HImode: - case V4SFmode: - case V4SImode: - case V4HImode: - case V2SFmode: - case V2SImode: - case V1DImode: - case V2DFmode: - case V2DImode: - if (CONSTANT_P (operands[1]) - && !easy_vector_constant (operands[1], mode)) - operands[1] = force_const_mem (mode, operands[1]); - break; - - case SImode: - case DImode: - /* Use default pattern for address of ELF small data */ - if (TARGET_ELF - && mode == Pmode - && DEFAULT_ABI == ABI_V4 - && (GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST) - && small_data_operand (operands[1], mode)) - { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); - return; - } - - if (DEFAULT_ABI == ABI_V4 - && mode == Pmode && mode == SImode - && flag_pic == 1 && got_operand (operands[1], mode)) - { - emit_insn (gen_movsi_got (operands[0], operands[1])); - return; - } - - if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN) - && TARGET_NO_TOC - && ! flag_pic - && mode == Pmode - && CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != HIGH - && GET_CODE (operands[1]) != CONST_INT) - { - rtx target = (!can_create_pseudo_p () - ? operands[0] - : gen_reg_rtx (mode)); - - /* If this is a function address on -mcall-aixdesc, - convert it to the address of the descriptor. */ - if (DEFAULT_ABI == ABI_AIX - && GET_CODE (operands[1]) == SYMBOL_REF - && XSTR (operands[1], 0)[0] == '.') - { - const char *name = XSTR (operands[1], 0); - rtx new_ref; - while (*name == '.') - name++; - new_ref = gen_rtx_SYMBOL_REF (Pmode, name); - CONSTANT_POOL_ADDRESS_P (new_ref) - = CONSTANT_POOL_ADDRESS_P (operands[1]); - SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]); - SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]); - SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (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; - } - - emit_insn (gen_elf_high (target, operands[1])); - emit_insn (gen_elf_low (operands[0], target, operands[1])); - return; - } - - /* If this is a SYMBOL_REF that refers to a constant pool entry, - and we have put it in the TOC, we just need to make a TOC-relative - reference to it. */ - if (TARGET_TOC - && GET_CODE (operands[1]) == SYMBOL_REF - && use_toc_relative_ref (operands[1])) - operands[1] = create_TOC_reference (operands[1], operands[0]); - else if (mode == Pmode - && CONSTANT_P (operands[1]) - && GET_CODE (operands[1]) != HIGH - && ((GET_CODE (operands[1]) != CONST_INT - && ! easy_fp_constant (operands[1], mode)) - || (GET_CODE (operands[1]) == CONST_INT - && (num_insns_constant (operands[1], mode) - > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2))) - || (GET_CODE (operands[0]) == REG - && FP_REGNO_P (REGNO (operands[0])))) - && !toc_relative_expr_p (operands[1], false) - && (TARGET_CMODEL == CMODEL_SMALL - || can_create_pseudo_p () - || (REG_P (operands[0]) - && INT_REG_OK_FOR_BASE_P (operands[0], true)))) - { - -#if TARGET_MACHO - /* Darwin uses a special PIC legitimizer. */ - if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT) - { - 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 - - /* If we are to limit the number of things we put in the TOC and - this is a symbol plus a constant we can add in one insn, - just put the symbol in the TOC and add the constant. Don't do - this if reload is in progress. */ - if (GET_CODE (operands[1]) == CONST - && TARGET_NO_SUM_IN_TOC && ! reload_in_progress - && GET_CODE (XEXP (operands[1], 0)) == PLUS - && add_operand (XEXP (XEXP (operands[1], 0), 1), mode) - && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF - || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF) - && ! side_effects_p (operands[0])) - { - rtx sym = - force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0)); - rtx other = XEXP (XEXP (operands[1], 0), 1); - - sym = force_reg (mode, sym); - emit_insn (gen_add3_insn (operands[0], sym, other)); - return; - } - - operands[1] = force_const_mem (mode, operands[1]); - - if (TARGET_TOC - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF - && 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)))) - { - rtx tocref = create_TOC_reference (XEXP (operands[1], 0), - operands[0]); - operands[1] = gen_const_mem (mode, tocref); - set_mem_alias_set (operands[1], get_TOC_alias_set ()); - } - } - break; - - case TImode: - rs6000_eliminate_indexed_memrefs (operands); - break; - - default: - fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source)); - } - - /* Above, we may have called force_const_mem which may have returned - an invalid address. If we can, fix this up; otherwise, reload will - have to deal with it. */ - if (GET_CODE (operands[1]) == MEM && ! reload_in_progress) - operands[1] = validize_mem (operands[1]); - - emit_set: - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); -} - -/* Return true if a structure, union or array containing FIELD should be - accessed using `BLKMODE'. - - For the SPE, simd types are V2SI, and gcc can be tempted to put the - entire thing in a DI and use subregs to access the internals. - store_bit_field() will force (subreg:DI (reg:V2SI x))'s to the - back-end. Because a single GPR can hold a V2SI, but not a DI, the - best thing to do is set structs to BLKmode and avoid Severe Tire - Damage. - - On e500 v2, DF and DI modes suffer from the same anomaly. DF can - fit into 1, whereas DI still needs two. */ - -static bool -rs6000_member_type_forces_blk (const_tree field, enum machine_mode mode) -{ - return ((TARGET_SPE && TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE) - || (TARGET_E500_DOUBLE && mode == DFmode)); -} - -/* Nonzero if we can use a floating-point register to pass this arg. */ -#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \ - (SCALAR_FLOAT_MODE_P (MODE) \ - && (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_OR_VSX_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. - - For the Darwin 64 Bit ABI, a function result can be returned in - registers or in memory, depending on the size of the return data - type. If it is returned in registers, the value occupies the same - registers as it would if it were the first and only function - argument. Otherwise, the function places its result in memory at - the location pointed to by GPR3. - - 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, aix_struct_return - 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_option_override_internal 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 (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) -{ - /* For the Darwin64 ABI, test if we can fit the return value in regs. */ - if (TARGET_MACHO - && rs6000_darwin64_abi - && TREE_CODE (type) == RECORD_TYPE - && int_size_in_bytes (type) > 0) - { - CUMULATIVE_ARGS valcum; - rtx valret; - - valcum.words = 0; - valcum.fregno = FP_ARG_MIN_REG; - valcum.vregno = ALTIVEC_ARG_MIN_REG; - /* Do a trial code generation as if this were going to be passed - as an argument; if any part goes in memory, we return NULL. */ - valret = rs6000_darwin64_record_arg (&valcum, type, true, true); - if (valret) - return false; - /* Otherwise fall through to more conventional ABI rules. */ - } - - if (AGGREGATE_TYPE_P (type) - && (aix_struct_return - || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8)) - return true; - - /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector - modes only exist for GCC vector types if -maltivec. */ - if (TARGET_32BIT && !TARGET_ALTIVEC_ABI - && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))) - return false; - - /* Return synthetic vectors in memory. */ - if (TREE_CODE (type) == VECTOR_TYPE - && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8)) - { - static bool warned_for_return_big_vectors = false; - if (!warned_for_return_big_vectors) - { - warning (0, "GCC vector returned by reference: " - "non-standard ABI extension with no compatibility guarantee"); - warned_for_return_big_vectors = true; - } - return true; - } - - if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode) - return true; - - return false; -} - -#ifdef HAVE_AS_GNU_ATTRIBUTE -/* Return TRUE if a call to function FNDECL may be one that - potentially affects the function calling ABI of the object file. */ - -static bool -call_ABI_of_interest (tree fndecl) -{ - if (cgraph_state == CGRAPH_STATE_EXPANSION) - { - struct cgraph_node *c_node; - - /* Libcalls are always interesting. */ - if (fndecl == NULL_TREE) - return true; - - /* Any call to an external function is interesting. */ - if (DECL_EXTERNAL (fndecl)) - return true; - - /* Interesting functions that we are emitting in this object file. */ - c_node = cgraph_get_node (fndecl); - c_node = cgraph_function_or_thunk_node (c_node, NULL); - return !cgraph_only_called_directly_p (c_node); - } - return false; -} -#endif - -/* 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 and RETURN_MODE the return value mode. - - For incoming args we set the number of arguments in the prototype large - so we never return a PARALLEL. */ - -void -init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, - rtx libname ATTRIBUTE_UNUSED, int incoming, - int libcall, int n_named_args, - tree fndecl ATTRIBUTE_UNUSED, - enum machine_mode return_mode ATTRIBUTE_UNUSED) -{ - static CUMULATIVE_ARGS zero_cumulative; - - *cum = zero_cumulative; - cum->words = 0; - cum->fregno = FP_ARG_MIN_REG; - cum->vregno = ALTIVEC_ARG_MIN_REG; - cum->prototype = (fntype && prototype_p (fntype)); - cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall) - ? CALL_LIBCALL : CALL_NORMAL); - cum->sysv_gregno = GP_ARG_MIN_REG; - cum->stdarg = stdarg_p (fntype); - - cum->nargs_prototype = 0; - if (incoming || cum->prototype) - cum->nargs_prototype = n_named_args; - - /* Check for a longcall attribute. */ - if ((!fntype && rs6000_default_long_calls) - || (fntype - && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)) - && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))) - cum->call_cookie |= CALL_LONG; - - if (TARGET_DEBUG_ARG) - { - fprintf (stderr, "\ninit_cumulative_args:"); - if (fntype) - { - tree ret_type = TREE_TYPE (fntype); - fprintf (stderr, " ret code = %s,", - tree_code_name[ (int)TREE_CODE (ret_type) ]); - } - - if (cum->call_cookie & CALL_LONG) - fprintf (stderr, " longcall,"); - - fprintf (stderr, " proto = %d, nargs = %d\n", - cum->prototype, cum->nargs_prototype); - } - -#ifdef HAVE_AS_GNU_ATTRIBUTE - if (DEFAULT_ABI == ABI_V4) - { - cum->escapes = call_ABI_of_interest (fndecl); - if (cum->escapes) - { - tree return_type; - - if (fntype) - { - return_type = TREE_TYPE (fntype); - return_mode = TYPE_MODE (return_type); - } - else - return_type = lang_hooks.types.type_for_mode (return_mode, 0); - - if (return_type != NULL) - { - if (TREE_CODE (return_type) == RECORD_TYPE - && TYPE_TRANSPARENT_AGGR (return_type)) - { - return_type = TREE_TYPE (first_field (return_type)); - return_mode = TYPE_MODE (return_type); - } - if (AGGREGATE_TYPE_P (return_type) - && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type) - <= 8)) - rs6000_returns_struct = true; - } - if (SCALAR_FLOAT_MODE_P (return_mode)) - rs6000_passes_float = true; - else if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode) - || SPE_VECTOR_MODE (return_mode)) - rs6000_passes_vector = true; - } - } -#endif - - 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"); - } -} - -/* Return true if TYPE must be passed on the stack and not in registers. */ - -static bool -rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type) -{ - if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT) - return must_pass_in_stack_var_size (mode, type); - else - return must_pass_in_stack_var_size_or_pad (mode, type); -} - -/* If defined, a C expression which determines whether, and in which - direction, to pad out an argument with extra space. The value - should be of type `enum direction': either `upward' to pad above - the argument, `downward' to pad below, or `none' to inhibit - padding. - - For the AIX ABI structs are always stored left shifted in their - argument slot. */ - -enum direction -function_arg_padding (enum machine_mode mode, const_tree type) -{ -#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. - i.e. 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; - } - - /* Fall back to the default. */ - return DEFAULT_FUNCTION_ARG_PADDING (mode, type); -} - -/* If defined, a C expression that gives the alignment boundary, in bits, - of an argument with the specified mode and type. If it is not defined, - PARM_BOUNDARY is used for all arguments. - - V.4 wants long longs and doubles to be double word aligned. Just - testing the mode size is a boneheaded way to do this as it means - that other types such as complex int are also double word aligned. - However, we're stuck with this because changing the ABI might break - existing library interfaces. - - Doubleword align SPE vectors. - Quadword align Altivec/VSX vectors. - Quadword align large synthetic vector types. */ - -static unsigned int -rs6000_function_arg_boundary (enum machine_mode mode, const_tree type) -{ - if (DEFAULT_ABI == ABI_V4 - && (GET_MODE_SIZE (mode) == 8 - || (TARGET_HARD_FLOAT - && TARGET_FPRS - && (mode == TFmode || mode == TDmode)))) - return 64; - else if (SPE_VECTOR_MODE (mode) - || (type && TREE_CODE (type) == VECTOR_TYPE - && int_size_in_bytes (type) >= 8 - && int_size_in_bytes (type) < 16)) - return 64; - else if (ALTIVEC_OR_VSX_VECTOR_MODE (mode) - || (type && TREE_CODE (type) == VECTOR_TYPE - && int_size_in_bytes (type) >= 16)) - return 128; - else if (TARGET_MACHO - && rs6000_darwin64_abi - && mode == BLKmode - && type && TYPE_ALIGN (type) > 64) - return 128; - else - return PARM_BOUNDARY; -} - -/* For a function parm of MODE and TYPE, return the starting word in - the parameter area. NWORDS of the parameter area are already used. */ - -static unsigned int -rs6000_parm_start (enum machine_mode mode, const_tree type, - unsigned int nwords) -{ - unsigned int align; - unsigned int parm_offset; - - align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1; - parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6; - return nwords + (-(parm_offset + nwords) & align); -} - -/* Compute the size (in words) of a function argument. */ - -static unsigned long -rs6000_arg_size (enum machine_mode mode, const_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; -} - -/* Use this to flush pending int fields. */ - -static void -rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum, - HOST_WIDE_INT bitpos, int final) -{ - unsigned int startbit, endbit; - int intregs, intoffset; - enum machine_mode mode; - - /* Handle the situations where a float is taking up the first half - of the GPR, and the other half is empty (typically due to - alignment restrictions). We can detect this by a 8-byte-aligned - int field, or by seeing that this is the final flush for this - argument. Count the word and continue on. */ - if (cum->floats_in_gpr == 1 - && (cum->intoffset % 64 == 0 - || (cum->intoffset == -1 && final))) - { - cum->words++; - cum->floats_in_gpr = 0; - } - - if (cum->intoffset == -1) - return; - - intoffset = cum->intoffset; - cum->intoffset = -1; - cum->floats_in_gpr = 0; - - if (intoffset % BITS_PER_WORD != 0) - { - mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD, - MODE_INT, 0); - if (mode == BLKmode) - { - /* We couldn't find an appropriate mode, which happens, - e.g., in packed structs when there are 3 bytes to load. - Back intoffset back to the beginning of the word in this - case. */ - intoffset = intoffset & -BITS_PER_WORD; - } - } - - startbit = intoffset & -BITS_PER_WORD; - endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD; - intregs = (endbit - startbit) / BITS_PER_WORD; - cum->words += intregs; - /* words should be unsigned. */ - if ((unsigned)cum->words < (endbit/BITS_PER_WORD)) - { - int pad = (endbit/BITS_PER_WORD) - cum->words; - cum->words += pad; - } -} - -/* The darwin64 ABI calls for us to recurse down through structs, - looking for elements passed in registers. Unfortunately, we have - to track int register count here also because of misalignments - in powerpc alignment mode. */ - -static void -rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum, - const_tree type, - HOST_WIDE_INT startbitpos) -{ - tree f; - - for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f)) - if (TREE_CODE (f) == FIELD_DECL) - { - HOST_WIDE_INT bitpos = startbitpos; - tree ftype = TREE_TYPE (f); - enum machine_mode mode; - if (ftype == error_mark_node) - continue; - mode = TYPE_MODE (ftype); - - if (DECL_SIZE (f) != 0 - && host_integerp (bit_position (f), 1)) - bitpos += int_bit_position (f); - - /* ??? FIXME: else assume zero offset. */ - - if (TREE_CODE (ftype) == RECORD_TYPE) - rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos); - else if (USE_FP_FOR_ARG_P (cum, mode, ftype)) - { - unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3; - rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0); - cum->fregno += n_fpregs; - /* Single-precision floats present a special problem for - us, because they are smaller than an 8-byte GPR, and so - the structure-packing rules combined with the standard - varargs behavior mean that we want to pack float/float - and float/int combinations into a single register's - space. This is complicated by the arg advance flushing, - which works on arbitrarily large groups of int-type - fields. */ - if (mode == SFmode) - { - if (cum->floats_in_gpr == 1) - { - /* Two floats in a word; count the word and reset - the float count. */ - cum->words++; - cum->floats_in_gpr = 0; - } - else if (bitpos % 64 == 0) - { - /* A float at the beginning of an 8-byte word; - count it and put off adjusting cum->words until - we see if a arg advance flush is going to do it - for us. */ - cum->floats_in_gpr++; - } - else - { - /* The float is at the end of a word, preceded - by integer fields, so the arg advance flush - just above has already set cum->words and - everything is taken care of. */ - } - } - else - cum->words += n_fpregs; - } - else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1)) - { - rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0); - cum->vregno++; - cum->words += 2; - } - else if (cum->intoffset == -1) - cum->intoffset = bitpos; - } -} - -/* Check for an item that needs to be considered specially under the darwin 64 - bit ABI. These are record types where the mode is BLK or the structure is - 8 bytes in size. */ -static int -rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type) -{ - return rs6000_darwin64_abi - && ((mode == BLKmode - && TREE_CODE (type) == RECORD_TYPE - && int_size_in_bytes (type) > 0) - || (type && TREE_CODE (type) == RECORD_TYPE - && int_size_in_bytes (type) == 8)) ? 1 : 0; -} - -/* 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.) - - 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. */ - -static void -rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode, - const_tree type, bool named, int depth) -{ - /* Only tick off an argument if we're not recursing. */ - if (depth == 0) - cum->nargs_prototype--; - -#ifdef HAVE_AS_GNU_ATTRIBUTE - if (DEFAULT_ABI == ABI_V4 - && cum->escapes) - { - if (SCALAR_FLOAT_MODE_P (mode)) - rs6000_passes_float = true; - else if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode)) - rs6000_passes_vector = true; - else if (SPE_VECTOR_MODE (mode) - && !cum->stdarg - && cum->sysv_gregno <= GP_ARG_MAX_REG) - rs6000_passes_vector = true; - } -#endif - - if (TARGET_ALTIVEC_ABI - && (ALTIVEC_OR_VSX_VECTOR_MODE (mode) - || (type && TREE_CODE (type) == VECTOR_TYPE - && int_size_in_bytes (type) == 16))) - { - 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 - 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) - && !cum->stdarg - && cum->sysv_gregno <= GP_ARG_MAX_REG) - cum->sysv_gregno++; - - else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type)) - { - int size = int_size_in_bytes (type); - /* Variable sized types have size == -1 and are - treated as if consisting entirely of ints. - Pad to 16 byte boundary if needed. */ - if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD - && (cum->words % 2) != 0) - cum->words++; - /* For varargs, we can just go up by the size of the struct. */ - if (!named) - cum->words += (size + 7) / 8; - else - { - /* It is tempting to say int register count just goes up by - sizeof(type)/8, but this is wrong in a case such as - { int; double; int; } [powerpc alignment]. We have to - grovel through the fields for these too. */ - cum->intoffset = 0; - cum->floats_in_gpr = 0; - rs6000_darwin64_record_arg_advance_recurse (cum, type, 0); - rs6000_darwin64_record_arg_advance_flush (cum, - size * BITS_PER_UNIT, 1); - } - if (TARGET_DEBUG_ARG) - { - fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d", - cum->words, TYPE_ALIGN (type), size); - fprintf (stderr, - "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n", - cum->nargs_prototype, cum->prototype, - GET_MODE_NAME (mode)); - } - } - else if (DEFAULT_ABI == ABI_V4) - { - if (TARGET_HARD_FLOAT && TARGET_FPRS - && ((TARGET_SINGLE_FLOAT && mode == SFmode) - || (TARGET_DOUBLE_FLOAT && mode == DFmode) - || (mode == TFmode && !TARGET_IEEEQUAD) - || mode == SDmode || mode == DDmode || mode == TDmode)) - { - /* _Decimal128 must use an even/odd register pair. This assumes - that the register number is odd when fregno is odd. */ - if (mode == TDmode && (cum->fregno % 2) == 1) - cum->fregno++; - - if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0) - <= FP_ARG_V4_MAX_REG) - cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3; - else - { - cum->fregno = FP_ARG_V4_MAX_REG + 1; - if (mode == DFmode || mode == TFmode - || mode == DDmode || mode == TDmode) - cum->words += cum->words & 1; - cum->words += rs6000_arg_size (mode, type); - } - } - else - { - int n_words = rs6000_arg_size (mode, type); - int gregno = cum->sysv_gregno; - - /* 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; - - /* Multi-reg args are not split between registers and stack. */ - if (gregno + n_words - 1 > GP_ARG_MAX_REG) - { - /* 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; - } - - /* Note: continuing to accumulate gregno past when we've started - spilling to the stack indicates the fact that we've started - spilling to the stack to expand_builtin_saveregs. */ - cum->sysv_gregno = gregno + n_words; - } - - if (TARGET_DEBUG_ARG) - { - fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ", - cum->words, cum->fregno); - fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ", - cum->sysv_gregno, cum->nargs_prototype, cum->prototype); - fprintf (stderr, "mode = %4s, named = %d\n", - GET_MODE_NAME (mode), named); - } - } - else - { - int n_words = rs6000_arg_size (mode, type); - int start_words = cum->words; - int align_words = rs6000_parm_start (mode, type, start_words); - - cum->words = align_words + n_words; - - if (SCALAR_FLOAT_MODE_P (mode) - && TARGET_HARD_FLOAT && TARGET_FPRS) - { - /* _Decimal128 must be passed in an even/odd float register pair. - This assumes that the register number is odd when fregno is - odd. */ - if (mode == TDmode && (cum->fregno % 2) == 1) - cum->fregno++; - cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3; - } - - if (TARGET_DEBUG_ARG) - { - fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ", - cum->words, cum->fregno); - fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ", - cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode)); - fprintf (stderr, "named = %d, align = %d, depth = %d\n", - named, align_words - start_words, depth); - } - } -} - -static void -rs6000_function_arg_advance (cumulative_args_t cum, enum machine_mode mode, - const_tree type, bool named) -{ - rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named, - 0); -} - -static rtx -spe_build_register_parallel (enum machine_mode mode, int gregno) -{ - rtx r1, r3, r5, r7; - - switch (mode) - { - case DFmode: - r1 = gen_rtx_REG (DImode, gregno); - r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); - return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1)); - - case DCmode: - case TFmode: - r1 = gen_rtx_REG (DImode, gregno); - r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); - r3 = gen_rtx_REG (DImode, gregno + 2); - r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8)); - return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3)); - - case TCmode: - r1 = gen_rtx_REG (DImode, gregno); - r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); - r3 = gen_rtx_REG (DImode, gregno + 2); - r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8)); - r5 = gen_rtx_REG (DImode, gregno + 4); - r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16)); - r7 = gen_rtx_REG (DImode, gregno + 6); - r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24)); - return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7)); - - default: - gcc_unreachable (); - } -} - -/* Determine where to put a SIMD argument on the SPE. */ -static rtx -rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode, - const_tree type) -{ - int gregno = cum->sysv_gregno; - - /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but - are passed and returned in a pair of GPRs for ABI compatibility. */ - if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode - || mode == DCmode || mode == TCmode)) - { - int n_words = rs6000_arg_size (mode, type); - - /* Doubles go in an odd/even register pair (r5/r6, etc). */ - if (mode == DFmode) - gregno += (1 - gregno) & 1; - - /* Multi-reg args are not split between registers and stack. */ - if (gregno + n_words - 1 > GP_ARG_MAX_REG) - return NULL_RTX; - - return spe_build_register_parallel (mode, gregno); - } - if (cum->stdarg) - { - 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 (gregno <= GP_ARG_MAX_REG) - return gen_rtx_REG (mode, gregno); - else - return NULL_RTX; - } -} - -/* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the - structure between cum->intoffset and bitpos to integer registers. */ - -static void -rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum, - HOST_WIDE_INT bitpos, rtx rvec[], int *k) -{ - enum machine_mode mode; - unsigned int regno; - unsigned int startbit, endbit; - int this_regno, intregs, intoffset; - rtx reg; - - if (cum->intoffset == -1) - return; - - intoffset = cum->intoffset; - cum->intoffset = -1; - - /* If this is the trailing part of a word, try to only load that - much into the register. Otherwise load the whole register. Note - that in the latter case we may pick up unwanted bits. It's not a - problem at the moment but may wish to revisit. */ - - if (intoffset % BITS_PER_WORD != 0) - { - mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD, - MODE_INT, 0); - if (mode == BLKmode) - { - /* We couldn't find an appropriate mode, which happens, - e.g., in packed structs when there are 3 bytes to load. - Back intoffset back to the beginning of the word in this - case. */ - intoffset = intoffset & -BITS_PER_WORD; - mode = word_mode; - } - } - else - mode = word_mode; - - startbit = intoffset & -BITS_PER_WORD; - endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD; - intregs = (endbit - startbit) / BITS_PER_WORD; - this_regno = cum->words + intoffset / BITS_PER_WORD; - - if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno) - cum->use_stack = 1; - - intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno); - if (intregs <= 0) - return; - - intoffset /= BITS_PER_UNIT; - do - { - regno = GP_ARG_MIN_REG + this_regno; - reg = gen_rtx_REG (mode, regno); - rvec[(*k)++] = - gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset)); - - this_regno += 1; - intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1; - mode = word_mode; - intregs -= 1; - } - while (intregs > 0); -} - -/* Recursive workhorse for the following. */ - -static void -rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type, - HOST_WIDE_INT startbitpos, rtx rvec[], - int *k) -{ - tree f; - - for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f)) - if (TREE_CODE (f) == FIELD_DECL) - { - HOST_WIDE_INT bitpos = startbitpos; - tree ftype = TREE_TYPE (f); - enum machine_mode mode; - if (ftype == error_mark_node) - continue; - mode = TYPE_MODE (ftype); - - if (DECL_SIZE (f) != 0 - && host_integerp (bit_position (f), 1)) - bitpos += int_bit_position (f); - - /* ??? FIXME: else assume zero offset. */ - - if (TREE_CODE (ftype) == RECORD_TYPE) - rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k); - else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype)) - { - unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3; -#if 0 - switch (mode) - { - case SCmode: mode = SFmode; break; - case DCmode: mode = DFmode; break; - case TCmode: mode = TFmode; break; - default: break; - } -#endif - rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k); - if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1) - { - gcc_assert (cum->fregno == FP_ARG_MAX_REG - && (mode == TFmode || mode == TDmode)); - /* Long double or _Decimal128 split over regs and memory. */ - mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode; - cum->use_stack=1; - } - rvec[(*k)++] - = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (mode, cum->fregno++), - GEN_INT (bitpos / BITS_PER_UNIT)); - if (mode == TFmode || mode == TDmode) - cum->fregno++; - } - else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1)) - { - rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k); - rvec[(*k)++] - = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (mode, cum->vregno++), - GEN_INT (bitpos / BITS_PER_UNIT)); - } - else if (cum->intoffset == -1) - cum->intoffset = bitpos; - } -} - -/* For the darwin64 ABI, we want to construct a PARALLEL consisting of - the register(s) to be used for each field and subfield of a struct - being passed by value, along with the offset of where the - register's value may be found in the block. FP fields go in FP - register, vector fields go in vector registers, and everything - else goes in int registers, packed as in memory. - - This code is also used for function return values. RETVAL indicates - whether this is the case. - - Much of this is taken from the SPARC V9 port, which has a similar - calling convention. */ - -static rtx -rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type, - bool named, bool retval) -{ - rtx rvec[FIRST_PSEUDO_REGISTER]; - int k = 1, kbase = 1; - HOST_WIDE_INT typesize = int_size_in_bytes (type); - /* This is a copy; modifications are not visible to our caller. */ - CUMULATIVE_ARGS copy_cum = *orig_cum; - CUMULATIVE_ARGS *cum = ©_cum; - - /* Pad to 16 byte boundary if needed. */ - if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD - && (cum->words % 2) != 0) - cum->words++; - - cum->intoffset = 0; - cum->use_stack = 0; - cum->named = named; - - /* Put entries into rvec[] for individual FP and vector fields, and - for the chunks of memory that go in int regs. Note we start at - element 1; 0 is reserved for an indication of using memory, and - may or may not be filled in below. */ - rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k); - rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k); - - /* If any part of the struct went on the stack put all of it there. - This hack is because the generic code for - FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register - parts of the struct are not at the beginning. */ - if (cum->use_stack) - { - if (retval) - return NULL_RTX; /* doesn't go in registers at all */ - kbase = 0; - rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx); - } - if (k > 1 || cum->use_stack) - return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase])); - else - return NULL_RTX; -} - -/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */ - -static rtx -rs6000_mixed_function_arg (enum machine_mode mode, const_tree type, - int align_words) -{ - int n_units; - int i, k; - rtx rvec[GP_ARG_NUM_REG + 1]; - - if (align_words >= GP_ARG_NUM_REG) - return NULL_RTX; - - n_units = rs6000_arg_size (mode, type); - - /* Optimize the simple case where the arg fits in one gpr, except in - the case of BLKmode due to assign_parms assuming that registers are - BITS_PER_WORD wide. */ - if (n_units == 0 - || (n_units == 1 && mode != BLKmode)) - return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); - - k = 0; - if (align_words + n_units > GP_ARG_NUM_REG) - /* Not all of the arg fits in gprs. Say that it goes in memory too, - using a magic NULL_RTX component. - This is not strictly correct. Only some of the arg belongs in - memory, not all of it. However, the normal scheme using - function_arg_partial_nregs can result in unusual subregs, eg. - (subreg:SI (reg:DF) 4), which are not handled well. The code to - store the whole arg to memory is often more efficient than code - to store pieces, and we know that space is available in the right - place for the whole arg. */ - rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx); - - i = 0; - do - { - rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words); - rtx off = GEN_INT (i++ * 4); - rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off); - } - while (++align_words < GP_ARG_NUM_REG && --n_units != 0); - - return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec)); -} - -/* 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. - - MODE is the argument's machine mode. - TYPE is the data type of the argument (as a tree). - This is null for libcalls where that information may - not be available. - CUM is a variable of type CUMULATIVE_ARGS which gives info about - the preceding args and about the function being called. It is - not modified in this routine. - NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). - - On RS/6000 the first eight words of non-FP are normally in registers - and the rest are pushed. Under AIX, the first 13 FP args are in registers. - Under V.4, the first 8 FP args are in registers. - - If this is floating-point and no prototype is specified, we use - 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. - - 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. */ - -static rtx -rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode, - const_tree type, bool named) -{ - CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); - enum rs6000_abi abi = DEFAULT_ABI; - - /* Return a marker to indicate whether CR1 needs to set or clear the - bit that V.4 uses to say fp args were passed in registers. - Assume that we don't need the marker for software floating point, - or compiler generated library calls. */ - if (mode == VOIDmode) - { - if (abi == ABI_V4 - && (cum->call_cookie & CALL_LIBCALL) == 0 - && (cum->stdarg - || (cum->nargs_prototype < 0 - && (cum->prototype || TARGET_NO_PROTOTYPE)))) - { - /* For the SPE, we need to crxor CR6 always. */ - if (TARGET_SPE_ABI) - return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS); - else if (TARGET_HARD_FLOAT && TARGET_FPRS) - return GEN_INT (cum->call_cookie - | ((cum->fregno == FP_ARG_MIN_REG) - ? CALL_V4_SET_FP_ARGS - : CALL_V4_CLEAR_FP_ARGS)); - } - - return GEN_INT (cum->call_cookie & ~CALL_LIBCALL); - } - - if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type)) - { - rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false); - if (rslt != NULL_RTX) - return rslt; - /* Else fall through to usual handling. */ - } - - 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_OR_VSX_VECTOR_MODE (mode) - || (type && TREE_CODE (type) == VECTOR_TYPE - && int_size_in_bytes (type) == 16))) - { - if (named || abi == ABI_V4) - return NULL_RTX; - else - { - /* Vector parameters to varargs functions under AIX or Darwin - get passed in memory and possibly also in GPRs. */ - int align, align_words, n_words; - enum machine_mode part_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; - - if (TARGET_32BIT && TARGET_POWERPC64) - return rs6000_mixed_function_arg (mode, type, align_words); - - /* The vector value goes in GPRs. Only the part of the - value in GPRs is reported here. */ - part_mode = mode; - n_words = rs6000_arg_size (mode, type); - if (align_words + n_words > 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) - || (TARGET_E500_DOUBLE && (mode == DFmode - || mode == DCmode - || mode == TFmode - || mode == TCmode)))) - return rs6000_spe_function_arg (cum, mode, type); - - else if (abi == ABI_V4) - { - if (TARGET_HARD_FLOAT && TARGET_FPRS - && ((TARGET_SINGLE_FLOAT && mode == SFmode) - || (TARGET_DOUBLE_FLOAT && mode == DFmode) - || (mode == TFmode && !TARGET_IEEEQUAD) - || mode == SDmode || mode == DDmode || mode == TDmode)) - { - /* _Decimal128 must use an even/odd register pair. This assumes - that the register number is odd when fregno is odd. */ - if (mode == TDmode && (cum->fregno % 2) == 1) - cum->fregno++; - - if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0) - <= FP_ARG_V4_MAX_REG) - return gen_rtx_REG (mode, cum->fregno); - else - return NULL_RTX; - } - else - { - int n_words = rs6000_arg_size (mode, type); - int gregno = cum->sysv_gregno; - - /* 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; - - /* Multi-reg args are not split between registers and stack. */ - if (gregno + n_words - 1 > GP_ARG_MAX_REG) - return NULL_RTX; - - if (TARGET_32BIT && TARGET_POWERPC64) - return rs6000_mixed_function_arg (mode, type, - gregno - GP_ARG_MIN_REG); - return gen_rtx_REG (mode, gregno); - } - } - else - { - int align_words = rs6000_parm_start (mode, type, cum->words); - - /* _Decimal128 must be passed in an even/odd float register pair. - This assumes that the register number is odd when fregno is odd. */ - if (mode == TDmode && (cum->fregno % 2) == 1) - cum->fregno++; - - if (USE_FP_FOR_ARG_P (cum, mode, type)) - { - rtx rvec[GP_ARG_NUM_REG + 1]; - rtx r; - int k; - bool needs_psave; - enum machine_mode fmode = mode; - unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3; - - if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1) - { - /* Currently, we only ever need one reg here because complex - doubles are split. */ - gcc_assert (cum->fregno == FP_ARG_MAX_REG - && (fmode == TFmode || fmode == TDmode)); - - /* Long double or _Decimal128 split over regs and memory. */ - fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode; - } - - /* 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_COMPAT - && align_words >= GP_ARG_NUM_REG))); - - if (!needs_psave && mode == fmode) - return gen_rtx_REG (fmode, cum->fregno); - - k = 0; - if (needs_psave) - { - /* Describe the part that goes in gprs or the stack. - This piece must come first, before the fprs. */ - if (align_words < GP_ARG_NUM_REG) - { - unsigned long n_words = rs6000_arg_size (mode, type); - - if (align_words + n_words > GP_ARG_NUM_REG - || (TARGET_32BIT && TARGET_POWERPC64)) - { - /* If this is partially on the stack, then we only - include the portion actually in registers here. */ - enum machine_mode rmode = TARGET_32BIT ? SImode : DImode; - rtx off; - int i = 0; - if (align_words + n_words > GP_ARG_NUM_REG) - /* Not all of the arg fits in gprs. Say that it - goes in memory too, using a magic NULL_RTX - component. Also see comment in - rs6000_mixed_function_arg for why the normal - function_arg_partial_nregs scheme doesn't work - in this case. */ - rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, - const0_rtx); - do - { - r = gen_rtx_REG (rmode, - GP_ARG_MIN_REG + align_words); - off = GEN_INT (i++ * GET_MODE_SIZE (rmode)); - rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off); - } - while (++align_words < GP_ARG_NUM_REG && --n_words != 0); - } - else - { - /* The whole arg fits in gprs. */ - r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); - rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx); - } - } - else - /* It's entirely in memory. */ - rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx); - } - - /* Describe where this piece goes in the fprs. */ - r = gen_rtx_REG (fmode, cum->fregno); - rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx); - - return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec)); - } - else if (align_words < GP_ARG_NUM_REG) - { - if (TARGET_32BIT && TARGET_POWERPC64) - return rs6000_mixed_function_arg (mode, type, align_words); - - if (mode == BLKmode) - mode = Pmode; - - return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); - } - else - return NULL_RTX; - } -} - -/* For an arg passed partly in registers and partly in memory, this is - the number of bytes passed in registers. For args passed entirely in - registers or entirely in memory, zero. When an arg is described by a - PARALLEL, perhaps using more than one register type, this function - returns the number of bytes used by the first element of the PARALLEL. */ - -static int -rs6000_arg_partial_bytes (cumulative_args_t cum_v, enum machine_mode mode, - tree type, bool named) -{ - CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); - int ret = 0; - int align_words; - - if (DEFAULT_ABI == ABI_V4) - return 0; - - if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named) - && cum->nargs_prototype >= 0) - return 0; - - /* In this complicated case we just disable the partial_nregs code. */ - if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type)) - return 0; - - align_words = rs6000_parm_start (mode, type, cum->words); - - if (USE_FP_FOR_ARG_P (cum, mode, type)) - { - /* If we are passing this arg in the fixed parameter save area - (gprs or memory) as well as fprs, then this function should - return the number of partial bytes passed in the parameter - save area rather than partial bytes passed in fprs. */ - if (type - && (cum->nargs_prototype <= 0 - || (DEFAULT_ABI == ABI_AIX - && TARGET_XL_COMPAT - && align_words >= GP_ARG_NUM_REG))) - return 0; - else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) - > FP_ARG_MAX_REG + 1) - ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8; - else if (cum->nargs_prototype >= 0) - return 0; - } - - if (align_words < GP_ARG_NUM_REG - && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type)) - ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8); - - if (ret != 0 && TARGET_DEBUG_ARG) - fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret); - - return ret; -} - -/* A C expression that indicates when an argument must be passed by - reference. If nonzero for an argument, a copy of that argument is - made in memory and a pointer to the argument is passed instead of - the argument itself. The pointer is passed in whatever way is - appropriate for passing a pointer to that type. - - 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. */ - -static bool -rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - enum machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) -{ - if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode) - { - if (TARGET_DEBUG_ARG) - fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n"); - return 1; - } - - if (!type) - return 0; - - if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type)) - { - if (TARGET_DEBUG_ARG) - fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n"); - return 1; - } - - if (int_size_in_bytes (type) < 0) - { - if (TARGET_DEBUG_ARG) - fprintf (stderr, "function_arg_pass_by_reference: variable size\n"); - return 1; - } - - /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector - modes only exist for GCC vector types if -maltivec. */ - if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) - { - if (TARGET_DEBUG_ARG) - fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n"); - return 1; - } - - /* Pass synthetic vectors in memory. */ - if (TREE_CODE (type) == VECTOR_TYPE - && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8)) - { - static bool warned_for_pass_big_vectors = false; - if (TARGET_DEBUG_ARG) - fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n"); - if (!warned_for_pass_big_vectors) - { - warning (0, "GCC vector passed by reference: " - "non-standard ABI extension with no compatibility guarantee"); - warned_for_pass_big_vectors = true; - } - return 1; - } - - 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)); - - gcc_assert (tem); - - 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. - - 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. */ - -static void -setup_incoming_varargs (cumulative_args_t 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; - alias_set_type set; - - /* Skip the last named argument. */ - next_cum = *get_cumulative_args (cum); - rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0); - - if (DEFAULT_ABI == ABI_V4) - { - first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG; - - if (! no_rtl) - { - int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0; - HOST_WIDE_INT offset = 0; - - /* Try to optimize the size of the varargs save area. - The ABI requires that ap.reg_save_area is doubleword - aligned, but we don't need to allocate space for all - the bytes, only those to which we actually will save - anything. */ - if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG) - gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset; - if (TARGET_HARD_FLOAT && TARGET_FPRS - && next_cum.fregno <= FP_ARG_V4_MAX_REG - && cfun->va_list_fpr_size) - { - if (gpr_reg_num) - fpr_size = (next_cum.fregno - FP_ARG_MIN_REG) - * UNITS_PER_FP_WORD; - if (cfun->va_list_fpr_size - < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno) - fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD; - else - fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno) - * UNITS_PER_FP_WORD; - } - if (gpr_reg_num) - { - offset = -((first_reg_offset * reg_size) & ~7); - if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size) - { - gpr_reg_num = cfun->va_list_gpr_size; - if (reg_size == 4 && (first_reg_offset & 1)) - gpr_reg_num++; - } - gpr_size = (gpr_reg_num * reg_size + 7) & ~7; - } - else if (fpr_size) - offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG) - * UNITS_PER_FP_WORD - - (int) (GP_ARG_NUM_REG * reg_size); - - if (gpr_size + fpr_size) - { - rtx reg_save_area - = assign_stack_local (BLKmode, gpr_size + fpr_size, 64); - gcc_assert (GET_CODE (reg_save_area) == MEM); - reg_save_area = XEXP (reg_save_area, 0); - if (GET_CODE (reg_save_area) == PLUS) - { - gcc_assert (XEXP (reg_save_area, 0) - == virtual_stack_vars_rtx); - gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT); - offset += INTVAL (XEXP (reg_save_area, 1)); - } - else - gcc_assert (reg_save_area == virtual_stack_vars_rtx); - } - - cfun->machine->varargs_save_offset = offset; - save_area = plus_constant (Pmode, virtual_stack_vars_rtx, offset); - } - } - else - { - first_reg_offset = next_cum.words; - save_area = virtual_incoming_args_rtx; - - if (targetm.calls.must_pass_in_stack (mode, type)) - first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type); - } - - set = get_varargs_alias_set (); - if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG - && cfun->va_list_gpr_size) - { - int nregs = GP_ARG_NUM_REG - first_reg_offset; - - if (va_list_gpr_counter_field) - { - /* V4 va_list_gpr_size counts number of registers needed. */ - if (nregs > cfun->va_list_gpr_size) - nregs = cfun->va_list_gpr_size; - } - else - { - /* char * va_list instead counts number of bytes needed. */ - if (nregs > cfun->va_list_gpr_size / reg_size) - nregs = cfun->va_list_gpr_size / reg_size; - } - - mem = gen_rtx_MEM (BLKmode, - plus_constant (Pmode, save_area, - first_reg_offset * reg_size)); - MEM_NOTRAP_P (mem) = 1; - set_mem_alias_set (mem, set); - set_mem_align (mem, BITS_PER_WORD); - - rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem, - nregs); - } - - /* Save FP registers if needed. */ - if (DEFAULT_ABI == ABI_V4 - && TARGET_HARD_FLOAT && TARGET_FPRS - && ! no_rtl - && next_cum.fregno <= FP_ARG_V4_MAX_REG - && cfun->va_list_fpr_size) - { - int fregno = next_cum.fregno, nregs; - rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO); - rtx lab = gen_label_rtx (); - int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) - * UNITS_PER_FP_WORD); - - emit_jump_insn - (gen_rtx_SET (VOIDmode, - pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, - gen_rtx_NE (VOIDmode, cr1, - const0_rtx), - gen_rtx_LABEL_REF (VOIDmode, lab), - pc_rtx))); - - for (nregs = 0; - fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size; - fregno++, off += UNITS_PER_FP_WORD, nregs++) - { - mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) - ? DFmode : SFmode, - plus_constant (Pmode, save_area, off)); - MEM_NOTRAP_P (mem) = 1; - set_mem_alias_set (mem, set); - set_mem_align (mem, GET_MODE_ALIGNMENT ( - (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) - ? DFmode : SFmode)); - emit_move_insn (mem, gen_rtx_REG ( - (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) - ? DFmode : SFmode, fregno)); - } - - emit_label (lab); - } -} - -/* Create the va_list data type. */ - -static tree -rs6000_build_builtin_va_list (void) -{ - 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. */ - if (DEFAULT_ABI != ABI_V4) - return build_pointer_type (char_type_node); - - record = (*lang_hooks.types.make_type) (RECORD_TYPE); - type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL, - get_identifier ("__va_list_tag"), record); - - f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"), - unsigned_char_type_node); - f_fpr = build_decl (BUILTINS_LOCATION, 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 (BUILTINS_LOCATION, FIELD_DECL, - get_identifier ("reserved"), short_unsigned_type_node); - f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL, - get_identifier ("overflow_arg_area"), - ptr_type_node); - f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL, - get_identifier ("reg_save_area"), - ptr_type_node); - - va_list_gpr_counter_field = f_gpr; - va_list_fpr_counter_field = f_fpr; - - 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; - - TYPE_STUB_DECL (record) = type_decl; - TYPE_NAME (record) = type_decl; - TYPE_FIELDS (record) = f_gpr; - DECL_CHAIN (f_gpr) = f_fpr; - DECL_CHAIN (f_fpr) = f_res; - DECL_CHAIN (f_res) = f_ovf; - DECL_CHAIN (f_ovf) = f_sav; - - layout_type (record); - - /* The correct type is an array type of one element. */ - return build_array_type (record, build_index_type (size_zero_node)); -} - -/* Implement va_start. */ - -static void -rs6000_va_start (tree valist, rtx nextarg) -{ - HOST_WIDE_INT words, n_gpr, n_fpr; - tree f_gpr, f_fpr, f_res, f_ovf, f_sav; - tree gpr, fpr, ovf, sav, t; - - /* Only SVR4 needs something special. */ - if (DEFAULT_ABI != ABI_V4) - { - std_expand_builtin_va_start (valist, nextarg); - return; - } - - f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_fpr = DECL_CHAIN (f_gpr); - f_res = DECL_CHAIN (f_fpr); - f_ovf = DECL_CHAIN (f_res); - f_sav = DECL_CHAIN (f_ovf); - - valist = build_simple_mem_ref (valist); - gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE); - fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist), - f_fpr, NULL_TREE); - ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist), - f_ovf, NULL_TREE); - sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist), - f_sav, NULL_TREE); - - /* Count number of gp and fp argument registers used. */ - words = crtl->args.info.words; - n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG, - GP_ARG_NUM_REG); - n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG, - FP_ARG_NUM_REG); - - if (TARGET_DEBUG_ARG) - 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); - - if (cfun->va_list_gpr_size) - { - t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr, - build_int_cst (NULL_TREE, n_gpr)); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - - if (cfun->va_list_fpr_size) - { - t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr, - build_int_cst (NULL_TREE, n_fpr)); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - -#ifdef HAVE_AS_GNU_ATTRIBUTE - if (call_ABI_of_interest (cfun->decl)) - rs6000_passes_float = true; -#endif - } - - /* Find the overflow area. */ - t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx); - if (words != 0) - t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD); - t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - - /* If there were no va_arg invocations, don't set up the register - save area. */ - if (!cfun->va_list_gpr_size - && !cfun->va_list_fpr_size - && n_gpr < GP_ARG_NUM_REG - && n_fpr < FP_ARG_V4_MAX_REG) - return; - - /* Find the register save area. */ - t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx); - if (cfun->machine->varargs_save_offset) - t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset); - t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); -} - -/* Implement va_arg. */ - -static tree -rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, - gimple_seq *post_p) -{ - tree f_gpr, f_fpr, f_res, f_ovf, f_sav; - tree gpr, fpr, ovf, sav, reg, t, u; - int size, rsize, n_reg, sav_ofs, sav_scale; - tree lab_false, lab_over, addr; - int align; - tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true); - int regalign = 0; - gimple stmt; - - if (pass_by_reference (NULL, TYPE_MODE (type), type, false)) - { - t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p); - return build_va_arg_indirect_ref (t); - } - - /* We need to deal with the fact that the darwin ppc64 ABI is defined by an - earlier version of gcc, with the property that it always applied alignment - adjustments to the va-args (even for zero-sized types). The cheapest way - to deal with this is to replicate the effect of the part of - std_gimplify_va_arg_expr that carries out the align adjust, for the case - of relevance. - We don't need to check for pass-by-reference because of the test above. - We can return a simplifed answer, since we know there's no offset to add. */ - - if (TARGET_MACHO - && rs6000_darwin64_abi - && integer_zerop (TYPE_SIZE (type))) - { - unsigned HOST_WIDE_INT align, boundary; - tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); - align = PARM_BOUNDARY / BITS_PER_UNIT; - boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type); - if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT) - boundary = MAX_SUPPORTED_STACK_ALIGNMENT; - boundary /= BITS_PER_UNIT; - if (boundary > align) - { - tree t ; - /* This updates arg ptr by the amount that would be necessary - to align the zero-sized (but not zero-alignment) item. */ - t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, - fold_build_pointer_plus_hwi (valist_tmp, boundary - 1)); - gimplify_and_add (t, pre_p); - - t = fold_convert (sizetype, valist_tmp); - t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, - fold_convert (TREE_TYPE (valist), - fold_build2 (BIT_AND_EXPR, sizetype, t, - size_int (-boundary)))); - t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); - gimplify_and_add (t, pre_p); - } - /* Since it is zero-sized there's no increment for the item itself. */ - valist_tmp = fold_convert (build_pointer_type (type), valist_tmp); - return build_va_arg_indirect_ref (valist_tmp); - } - - if (DEFAULT_ABI != ABI_V4) - { - 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) - { - tree real_part, imag_part; - gimple_seq post = NULL; - - real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p, - &post); - /* Copy the value into a temporary, lest the formal temporary - be reused out from under us. */ - real_part = get_initialized_tmp_var (real_part, pre_p, &post); - gimple_seq_add_seq (pre_p, post); - - imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p, - post_p); - - return build2 (COMPLEX_EXPR, type, real_part, imag_part); - } - } - - return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); - } - - f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); - f_fpr = DECL_CHAIN (f_gpr); - f_res = DECL_CHAIN (f_fpr); - f_ovf = DECL_CHAIN (f_res); - f_sav = DECL_CHAIN (f_ovf); - - valist = build_va_arg_indirect_ref (valist); - gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE); - fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist), - f_fpr, NULL_TREE); - ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist), - f_ovf, NULL_TREE); - sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist), - f_sav, NULL_TREE); - - size = int_size_in_bytes (type); - rsize = (size + 3) / 4; - align = 1; - - if (TARGET_HARD_FLOAT && TARGET_FPRS - && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode) - || (TARGET_DOUBLE_FLOAT - && (TYPE_MODE (type) == DFmode - || TYPE_MODE (type) == TFmode - || TYPE_MODE (type) == SDmode - || TYPE_MODE (type) == DDmode - || TYPE_MODE (type) == TDmode)))) - { - /* FP args go in FP registers, if present. */ - reg = fpr; - n_reg = (size + 7) / 8; - sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4; - sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4); - if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode) - align = 8; - } - else - { - /* Otherwise into GP registers. */ - reg = gpr; - n_reg = rsize; - sav_ofs = 0; - sav_scale = 4; - if (n_reg == 2) - align = 8; - } - - /* Pull the value out of the saved registers.... */ - - lab_over = NULL; - addr = create_tmp_var (ptr_type_node, "addr"); - - /* AltiVec vectors never go in registers when -mabi=altivec. */ - if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))) - align = 16; - else - { - lab_false = create_artificial_label (input_location); - lab_over = create_artificial_label (input_location); - - /* 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 && reg == gpr) - { - regalign = 1; - u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg), - build_int_cst (TREE_TYPE (reg), n_reg - 1)); - u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), - unshare_expr (reg), u); - } - /* _Decimal128 is passed in even/odd fpr pairs; the stored - reg number is 0 for f1, so we want to make it odd. */ - else if (reg == fpr && TYPE_MODE (type) == TDmode) - { - t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg), - build_int_cst (TREE_TYPE (reg), 1)); - u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t); - } - - t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1)); - t = build2 (GE_EXPR, boolean_type_node, u, t); - u = build1 (GOTO_EXPR, void_type_node, lab_false); - t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE); - gimplify_and_add (t, pre_p); - - t = sav; - if (sav_ofs) - t = fold_build_pointer_plus_hwi (sav, sav_ofs); - - u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg), - build_int_cst (TREE_TYPE (reg), n_reg)); - u = fold_convert (sizetype, u); - u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale)); - t = fold_build_pointer_plus (t, u); - - /* _Decimal32 varargs are located in the second word of the 64-bit - FP register for 32-bit binaries. */ - if (!TARGET_POWERPC64 - && TARGET_HARD_FLOAT && TARGET_FPRS - && TYPE_MODE (type) == SDmode) - t = fold_build_pointer_plus_hwi (t, size); - - gimplify_assign (addr, t, pre_p); - - gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over)); - - stmt = gimple_build_label (lab_false); - gimple_seq_add_stmt (pre_p, stmt); - - if ((n_reg == 2 && !regalign) || n_reg > 2) - { - /* Ensure that we don't find any more args in regs. - Alignment has taken care of for special cases. */ - gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p); - } - } - - /* ... otherwise out of the overflow area. */ - - /* Care for on-stack alignment if needed. */ - t = ovf; - if (align != 1) - { - t = fold_build_pointer_plus_hwi (t, align - 1); - t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, - build_int_cst (TREE_TYPE (t), -align)); - } - gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue); - - gimplify_assign (unshare_expr (addr), t, pre_p); - - t = fold_build_pointer_plus_hwi (t, size); - gimplify_assign (unshare_expr (ovf), t, pre_p); - - if (lab_over) - { - stmt = gimple_build_label (lab_over); - gimple_seq_add_stmt (pre_p, stmt); - } - - if (STRICT_ALIGNMENT - && (TYPE_ALIGN (type) - > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align))) - { - /* The value (of type complex double, for example) may not be - aligned in memory in the saved registers, so copy via a - temporary. (This is the same code as used for SPARC.) */ - tree tmp = create_tmp_var (type, "va_arg_tmp"); - tree dest_addr = build_fold_addr_expr (tmp); - - tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY), - 3, dest_addr, addr, size_int (rsize * 4)); - - gimplify_and_add (copy, pre_p); - addr = dest_addr; - } - - addr = fold_convert (ptrtype, addr); - return build_va_arg_indirect_ref (addr); -} - -/* Builtins. */ - -static void -def_builtin (const char *name, tree type, enum rs6000_builtins code) -{ - tree t; - unsigned classify = rs6000_builtin_info[(int)code].attr; - const char *attr_string = ""; - - gcc_assert (name != NULL); - gcc_assert (IN_RANGE ((int)code, 0, (int)RS6000_BUILTIN_COUNT)); - - if (rs6000_builtin_decls[(int)code]) - fatal_error ("internal error: builtin function %s already processed", name); - - rs6000_builtin_decls[(int)code] = t = - add_builtin_function (name, type, (int)code, BUILT_IN_MD, NULL, NULL_TREE); - - /* Set any special attributes. */ - if ((classify & RS6000_BTC_CONST) != 0) - { - /* const function, function only depends on the inputs. */ - TREE_READONLY (t) = 1; - TREE_NOTHROW (t) = 1; - attr_string = ", pure"; - } - else if ((classify & RS6000_BTC_PURE) != 0) - { - /* pure function, function can read global memory, but does not set any - external state. */ - DECL_PURE_P (t) = 1; - TREE_NOTHROW (t) = 1; - attr_string = ", const"; - } - else if ((classify & RS6000_BTC_FP) != 0) - { - /* Function is a math function. If rounding mode is on, then treat the - function as not reading global memory, but it can have arbitrary side - effects. If it is off, then assume the function is a const function. - This mimics the ATTR_MATHFN_FPROUNDING attribute in - builtin-attribute.def that is used for the math functions. */ - TREE_NOTHROW (t) = 1; - if (flag_rounding_math) - { - DECL_PURE_P (t) = 1; - DECL_IS_NOVOPS (t) = 1; - attr_string = ", fp, pure"; - } - else - { - TREE_READONLY (t) = 1; - attr_string = ", fp, const"; - } - } - else if ((classify & RS6000_BTC_ATTR_MASK) != 0) - gcc_unreachable (); - - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "rs6000_builtin, code = %4d, %s%s\n", - (int)code, name, attr_string); -} - -/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */ - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_3arg[] = -{ -#include "rs6000-builtin.def" -}; - -/* DST operations: void foo (void *, const int, const char). */ - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_dst[] = -{ -#include "rs6000-builtin.def" -}; - -/* Simple binary operations: VECc = foo (VECa, VECb). */ - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_2arg[] = -{ -#include "rs6000-builtin.def" -}; - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -/* AltiVec predicates. */ - -static const struct builtin_description bdesc_altivec_preds[] = -{ -#include "rs6000-builtin.def" -}; - -/* SPE predicates. */ -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_spe_predicates[] = -{ -#include "rs6000-builtin.def" -}; - -/* SPE evsel predicates. */ -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_spe_evsel[] = -{ -#include "rs6000-builtin.def" -}; - -/* PAIRED predicates. */ -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_paired_preds[] = -{ -#include "rs6000-builtin.def" -}; - -/* ABS* operations. */ - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_abs[] = -{ -#include "rs6000-builtin.def" -}; - -/* Simple unary operations: VECb = foo (unsigned literal) or VECb = - foo (VECa). */ - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \ - { MASK, ICODE, NAME, ENUM }, - -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) - -static const struct builtin_description bdesc_1arg[] = -{ -#include "rs6000-builtin.def" -}; - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -/* Return true if a builtin function is overloaded. */ -bool -rs6000_overloaded_builtin_p (enum rs6000_builtins fncode) -{ - return (rs6000_builtin_info[(int)fncode].attr & RS6000_BTC_OVERLOADED) != 0; -} - -/* Expand an expression EXP that calls a builtin without arguments. */ -static rtx -rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target) -{ - rtx pat; - enum machine_mode tmode = insn_data[icode].operand[0].mode; - - if (icode == CODE_FOR_nothing) - /* Builtin not supported on this processor. */ - return 0; - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - pat = GEN_FCN (icode) (target); - if (! pat) - return 0; - emit_insn (pat); - - return target; -} - - -static rtx -rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat; - tree arg0 = CALL_EXPR_ARG (exp, 0); - rtx op0 = expand_normal (arg0); - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - - 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) - return const0_rtx; - - if (icode == CODE_FOR_altivec_vspltisb - || icode == CODE_FOR_altivec_vspltish - || icode == CODE_FOR_altivec_vspltisw - || icode == CODE_FOR_spe_evsplatfi - || icode == CODE_FOR_spe_evsplati) - { - /* Only allow 5-bit *signed* literals. */ - if (GET_CODE (op0) != CONST_INT - || INTVAL (op0) > 15 - || INTVAL (op0) < -16) - { - error ("argument 1 must be a 5-bit signed literal"); - return const0_rtx; - } - } - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - - pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); - - return target; -} - -static rtx -altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat, scratch1, scratch2; - tree arg0 = CALL_EXPR_ARG (exp, 0); - rtx op0 = expand_normal (arg0); - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - - /* If we have invalid arguments, bail out before generating bad rtl. */ - if (arg0 == 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); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - - scratch1 = gen_reg_rtx (mode0); - scratch2 = gen_reg_rtx (mode0); - - pat = GEN_FCN (icode) (target, op0, scratch1, scratch2); - if (! pat) - return 0; - emit_insn (pat); - - return target; -} - -static rtx -rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat; - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - enum machine_mode mode1 = insn_data[icode].operand[2].mode; - - if (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 (icode == CODE_FOR_altivec_vcfux - || icode == CODE_FOR_altivec_vcfsx - || icode == CODE_FOR_altivec_vctsxs - || icode == CODE_FOR_altivec_vctuxs - || icode == CODE_FOR_altivec_vspltb - || icode == CODE_FOR_altivec_vsplth - || icode == CODE_FOR_altivec_vspltw - || icode == CODE_FOR_spe_evaddiw - || icode == CODE_FOR_spe_evldd - || icode == CODE_FOR_spe_evldh - || icode == CODE_FOR_spe_evldw - || icode == CODE_FOR_spe_evlhhesplat - || icode == CODE_FOR_spe_evlhhossplat - || icode == CODE_FOR_spe_evlhhousplat - || icode == CODE_FOR_spe_evlwhe - || icode == CODE_FOR_spe_evlwhos - || icode == CODE_FOR_spe_evlwhou - || icode == CODE_FOR_spe_evlwhsplat - || icode == CODE_FOR_spe_evlwwsplat - || 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. */ - STRIP_NOPS (arg1); - if (TREE_CODE (arg1) != INTEGER_CST - || TREE_INT_CST_LOW (arg1) & ~0x1f) - { - error ("argument 2 must be a 5-bit unsigned literal"); - return const0_rtx; - } - } - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - - pat = GEN_FCN (icode) (target, op0, op1); - if (! pat) - return 0; - emit_insn (pat); - - return target; -} - -static rtx -altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat, scratch; - tree cr6_form = CALL_EXPR_ARG (exp, 0); - tree arg0 = CALL_EXPR_ARG (exp, 1); - tree arg1 = CALL_EXPR_ARG (exp, 2); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - enum machine_mode tmode = SImode; - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - enum machine_mode mode1 = insn_data[icode].operand[2].mode; - int cr6_form_int; - - if (TREE_CODE (cr6_form) != INTEGER_CST) - { - error ("argument 1 of __builtin_altivec_predicate must be a constant"); - return const0_rtx; - } - else - cr6_form_int = TREE_INT_CST_LOW (cr6_form); - - gcc_assert (mode0 == mode1); - - /* If we have 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); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - - scratch = gen_reg_rtx (mode0); - - pat = GEN_FCN (icode) (scratch, op0, op1); - if (! pat) - return 0; - emit_insn (pat); - - /* The vec_any* and vec_all* predicates use the same opcodes for two - different operations, but the bits in CR6 will be different - depending on what information we want. So we have to play tricks - with CR6 to get the right bits out. - - If you think this is disgusting, look at the specs for the - AltiVec predicates. */ - - switch (cr6_form_int) - { - case 0: - emit_insn (gen_cr6_test_for_zero (target)); - break; - case 1: - emit_insn (gen_cr6_test_for_zero_reverse (target)); - break; - case 2: - emit_insn (gen_cr6_test_for_lt (target)); - break; - case 3: - emit_insn (gen_cr6_test_for_lt_reverse (target)); - break; - default: - error ("argument 1 of __builtin_altivec_predicate is out of range"); - break; - } - - return target; -} - -static rtx -paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat, addr; - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode0 = Pmode; - enum machine_mode mode1 = Pmode; - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - - 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 -altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk) -{ - rtx pat, addr; - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode0 = Pmode; - enum machine_mode mode1 = Pmode; - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - - 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 (blk ? BLKmode : tmode, op1); - } - else - { - op0 = copy_to_mode_reg (mode0, op0); - addr = gen_rtx_MEM (blk ? BLKmode : 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 exp) -{ - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - tree arg2 = CALL_EXPR_ARG (exp, 2); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); - rtx pat; - enum machine_mode mode0 = insn_data[icode].operand[0].mode; - enum machine_mode mode1 = insn_data[icode].operand[1].mode; - enum machine_mode mode2 = insn_data[icode].operand[2].mode; - - /* 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[2].predicate) (op0, mode2)) - op0 = copy_to_mode_reg (mode2, op0); - if (! (*insn_data[icode].operand[0].predicate) (op1, mode0)) - op1 = copy_to_mode_reg (mode0, op1); - if (! (*insn_data[icode].operand[1].predicate) (op2, mode1)) - op2 = copy_to_mode_reg (mode1, op2); - - pat = GEN_FCN (icode) (op1, op2, op0); - if (pat) - emit_insn (pat); - return NULL_RTX; -} - -static rtx -paired_expand_stv_builtin (enum insn_code icode, tree exp) -{ - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - tree arg2 = CALL_EXPR_ARG (exp, 2); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); - 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 -altivec_expand_stv_builtin (enum insn_code icode, tree exp) -{ - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - tree arg2 = CALL_EXPR_ARG (exp, 2); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); - rtx pat, addr; - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode smode = insn_data[icode].operand[1].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, smode)) - op0 = copy_to_mode_reg (smode, 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 exp, rtx target) -{ - rtx pat; - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - tree arg2 = CALL_EXPR_ARG (exp, 2); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - enum machine_mode mode1 = insn_data[icode].operand[2].mode; - enum machine_mode mode2 = insn_data[icode].operand[3].mode; - - 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 - || arg2 == error_mark_node) - return const0_rtx; - - /* Check and prepare argument depending on the instruction code. - - Note that a switch statement instead of the sequence of tests - would be incorrect as many of the CODE_FOR values could be - CODE_FOR_nothing and that would yield multiple alternatives - with identical values. We'd never reach here at runtime in - this case. */ - if (icode == CODE_FOR_altivec_vsldoi_v4sf - || icode == CODE_FOR_altivec_vsldoi_v4si - || icode == CODE_FOR_altivec_vsldoi_v8hi - || icode == CODE_FOR_altivec_vsldoi_v16qi) - { - /* Only allow 4-bit unsigned literals. */ - STRIP_NOPS (arg2); - if (TREE_CODE (arg2) != INTEGER_CST - || TREE_INT_CST_LOW (arg2) & ~0xf) - { - error ("argument 3 must be a 4-bit unsigned literal"); - return const0_rtx; - } - } - else if (icode == CODE_FOR_vsx_xxpermdi_v2df - || icode == CODE_FOR_vsx_xxpermdi_v2di - || icode == CODE_FOR_vsx_xxsldwi_v16qi - || icode == CODE_FOR_vsx_xxsldwi_v8hi - || icode == CODE_FOR_vsx_xxsldwi_v4si - || icode == CODE_FOR_vsx_xxsldwi_v4sf - || icode == CODE_FOR_vsx_xxsldwi_v2di - || icode == CODE_FOR_vsx_xxsldwi_v2df) - { - /* Only allow 2-bit unsigned literals. */ - STRIP_NOPS (arg2); - if (TREE_CODE (arg2) != INTEGER_CST - || TREE_INT_CST_LOW (arg2) & ~0x3) - { - error ("argument 3 must be a 2-bit unsigned literal"); - return const0_rtx; - } - } - else if (icode == CODE_FOR_vsx_set_v2df - || icode == CODE_FOR_vsx_set_v2di) - { - /* Only allow 1-bit unsigned literals. */ - STRIP_NOPS (arg2); - if (TREE_CODE (arg2) != INTEGER_CST - || TREE_INT_CST_LOW (arg2) & ~0x1) - { - error ("argument 3 must be a 1-bit unsigned literal"); - return const0_rtx; - } - } - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - if (! (*insn_data[icode].operand[3].predicate) (op2, mode2)) - op2 = copy_to_mode_reg (mode2, op2); - - if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4) - pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode)); - else - pat = GEN_FCN (icode) (target, op0, op1, op2); - if (! pat) - return 0; - emit_insn (pat); - - return target; -} - -/* Expand the lvx builtins. */ -static rtx -altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - tree arg0; - enum machine_mode tmode, mode0; - rtx pat, op0; - enum insn_code icode; - - switch (fcode) - { - case ALTIVEC_BUILTIN_LD_INTERNAL_16qi: - icode = CODE_FOR_vector_altivec_load_v16qi; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_8hi: - icode = CODE_FOR_vector_altivec_load_v8hi; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_4si: - icode = CODE_FOR_vector_altivec_load_v4si; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_4sf: - icode = CODE_FOR_vector_altivec_load_v4sf; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_2df: - icode = CODE_FOR_vector_altivec_load_v2df; - break; - case ALTIVEC_BUILTIN_LD_INTERNAL_2di: - icode = CODE_FOR_vector_altivec_load_v2di; - break; - default: - *expandedp = false; - return NULL_RTX; - } - - *expandedp = true; - - arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); - tmode = insn_data[icode].operand[0].mode; - mode0 = insn_data[icode].operand[1].mode; - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - - pat = GEN_FCN (icode) (target, op0); - if (! pat) - return 0; - emit_insn (pat); - return target; -} - -/* Expand the stvx builtins. */ -static rtx -altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, - bool *expandedp) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - unsigned int fcode = DECL_FUNCTION_CODE (fndecl); - tree arg0, arg1; - enum machine_mode mode0, mode1; - rtx pat, op0, op1; - enum insn_code icode; - - switch (fcode) - { - case ALTIVEC_BUILTIN_ST_INTERNAL_16qi: - icode = CODE_FOR_vector_altivec_store_v16qi; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_8hi: - icode = CODE_FOR_vector_altivec_store_v8hi; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_4si: - icode = CODE_FOR_vector_altivec_store_v4si; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_4sf: - icode = CODE_FOR_vector_altivec_store_v4sf; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_2df: - icode = CODE_FOR_vector_altivec_store_v2df; - break; - case ALTIVEC_BUILTIN_ST_INTERNAL_2di: - icode = CODE_FOR_vector_altivec_store_v2di; - break; - default: - *expandedp = false; - return NULL_RTX; - } - - arg0 = CALL_EXPR_ARG (exp, 0); - arg1 = CALL_EXPR_ARG (exp, 1); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; - - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0)); - if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - - pat = GEN_FCN (icode) (op0, op1); - if (pat) - emit_insn (pat); - - *expandedp = true; - return NULL_RTX; -} - -/* Expand the dst builtins. */ -static rtx -altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, - bool *expandedp) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl); - tree arg0, arg1, arg2; - enum machine_mode mode0, mode1; - rtx pat, op0, op1, op2; - const struct builtin_description *d; - size_t i; - - *expandedp = false; - - /* Handle DST variants. */ - d = bdesc_dst; - for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++) - if (d->code == fcode) - { - arg0 = CALL_EXPR_ARG (exp, 0); - arg1 = CALL_EXPR_ARG (exp, 1); - arg2 = CALL_EXPR_ARG (exp, 2); - op0 = expand_normal (arg0); - op1 = expand_normal (arg1); - op2 = expand_normal (arg2); - mode0 = insn_data[d->icode].operand[0].mode; - mode1 = insn_data[d->icode].operand[1].mode; - - /* Invalid arguments, bail out before generating bad rtl. */ - if (arg0 == error_mark_node - || arg1 == error_mark_node - || arg2 == error_mark_node) - return const0_rtx; - - *expandedp = true; - STRIP_NOPS (arg2); - if (TREE_CODE (arg2) != INTEGER_CST - || TREE_INT_CST_LOW (arg2) & ~0x3) - { - error ("argument to %qs must be a 2-bit unsigned literal", d->name); - return const0_rtx; - } - - if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (Pmode, op0); - if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - - pat = GEN_FCN (d->icode) (op0, op1, op2); - if (pat != 0) - emit_insn (pat); - - return NULL_RTX; - } - - return NULL_RTX; -} - -/* Expand vec_init builtin. */ -static rtx -altivec_expand_vec_init_builtin (tree type, tree exp, rtx target) -{ - enum machine_mode tmode = TYPE_MODE (type); - enum machine_mode inner_mode = GET_MODE_INNER (tmode); - int i, n_elt = GET_MODE_NUNITS (tmode); - rtvec v = rtvec_alloc (n_elt); - - gcc_assert (VECTOR_MODE_P (tmode)); - gcc_assert (n_elt == call_expr_nargs (exp)); - - for (i = 0; i < n_elt; ++i) - { - rtx x = expand_normal (CALL_EXPR_ARG (exp, i)); - RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x); - } - - if (!target || !register_operand (target, tmode)) - target = gen_reg_rtx (tmode); - - rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v)); - return target; -} - -/* Return the integer constant in ARG. Constrain it to be in the range - of the subparts of VEC_TYPE; issue an error if not. */ - -static int -get_element_number (tree vec_type, tree arg) -{ - unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1; - - if (!host_integerp (arg, 1) - || (elt = tree_low_cst (arg, 1), elt > max)) - { - error ("selector must be an integer constant in the range 0..%wi", max); - return 0; - } - - return elt; -} - -/* Expand vec_set builtin. */ -static rtx -altivec_expand_vec_set_builtin (tree exp) -{ - enum machine_mode tmode, mode1; - tree arg0, arg1, arg2; - int elt; - rtx op0, op1; - - arg0 = CALL_EXPR_ARG (exp, 0); - arg1 = CALL_EXPR_ARG (exp, 1); - arg2 = CALL_EXPR_ARG (exp, 2); - - tmode = TYPE_MODE (TREE_TYPE (arg0)); - mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); - gcc_assert (VECTOR_MODE_P (tmode)); - - op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL); - op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL); - elt = get_element_number (TREE_TYPE (arg0), arg2); - - if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode) - op1 = convert_modes (mode1, GET_MODE (op1), op1, true); - - op0 = force_reg (tmode, op0); - op1 = force_reg (mode1, op1); - - rs6000_expand_vector_set (op0, op1, elt); - - return op0; -} - -/* Expand vec_ext builtin. */ -static rtx -altivec_expand_vec_ext_builtin (tree exp, rtx target) -{ - enum machine_mode tmode, mode0; - tree arg0, arg1; - int elt; - rtx op0; - - arg0 = CALL_EXPR_ARG (exp, 0); - arg1 = CALL_EXPR_ARG (exp, 1); - - op0 = expand_normal (arg0); - elt = get_element_number (TREE_TYPE (arg0), arg1); - - tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))); - mode0 = TYPE_MODE (TREE_TYPE (arg0)); - gcc_assert (VECTOR_MODE_P (mode0)); - - op0 = force_reg (mode0, op0); - - if (optimize || !target || !register_operand (target, tmode)) - target = gen_reg_rtx (tmode); - - rs6000_expand_vector_extract (target, op0, elt); - - return target; -} - -/* 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 (tree exp, rtx target, bool *expandedp) -{ - const struct builtin_description *d; - size_t i; - enum insn_code icode; - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - tree arg0; - rtx op0, pat; - enum machine_mode tmode, mode0; - enum rs6000_builtins fcode - = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl); - - if (rs6000_overloaded_builtin_p (fcode)) - { - *expandedp = true; - error ("unresolved overload for Altivec builtin %qF", fndecl); - - /* Given it is invalid, just generate a normal call. */ - return expand_call (exp, target, false); - } - - target = altivec_expand_ld_builtin (exp, target, expandedp); - if (*expandedp) - return target; - - target = altivec_expand_st_builtin (exp, target, expandedp); - if (*expandedp) - return target; - - target = altivec_expand_dst_builtin (exp, target, expandedp); - if (*expandedp) - return target; - - *expandedp = true; - - switch (fcode) - { - case ALTIVEC_BUILTIN_STVX: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp); - case ALTIVEC_BUILTIN_STVEBX: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp); - case ALTIVEC_BUILTIN_STVEHX: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp); - case ALTIVEC_BUILTIN_STVEWX: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp); - case ALTIVEC_BUILTIN_STVXL: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp); - - case ALTIVEC_BUILTIN_STVLX: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp); - case ALTIVEC_BUILTIN_STVLXL: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp); - case ALTIVEC_BUILTIN_STVRX: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp); - case ALTIVEC_BUILTIN_STVRXL: - return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp); - - case VSX_BUILTIN_STXVD2X_V2DF: - return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp); - case VSX_BUILTIN_STXVD2X_V2DI: - return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp); - case VSX_BUILTIN_STXVW4X_V4SF: - return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp); - case VSX_BUILTIN_STXVW4X_V4SI: - return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp); - case VSX_BUILTIN_STXVW4X_V8HI: - return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp); - case VSX_BUILTIN_STXVW4X_V16QI: - return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp); - - case ALTIVEC_BUILTIN_MFVSCR: - icode = CODE_FOR_altivec_mfvscr; - tmode = insn_data[icode].operand[0].mode; - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - pat = GEN_FCN (icode) (target); - if (! pat) - return 0; - emit_insn (pat); - return target; - - case ALTIVEC_BUILTIN_MTVSCR: - icode = CODE_FOR_altivec_mtvscr; - arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); - mode0 = insn_data[icode].operand[0].mode; - - /* If we got invalid arguments bail out before generating bad rtl. */ - if (arg0 == error_mark_node) - return const0_rtx; - - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - - pat = GEN_FCN (icode) (op0); - if (pat) - emit_insn (pat); - return NULL_RTX; - - case ALTIVEC_BUILTIN_DSSALL: - emit_insn (gen_altivec_dssall ()); - return NULL_RTX; - - case ALTIVEC_BUILTIN_DSS: - icode = CODE_FOR_altivec_dss; - arg0 = CALL_EXPR_ARG (exp, 0); - STRIP_NOPS (arg0); - op0 = expand_normal (arg0); - mode0 = insn_data[icode].operand[0].mode; - - /* If we got invalid arguments bail out before generating bad rtl. */ - if (arg0 == error_mark_node) - return const0_rtx; - - if (TREE_CODE (arg0) != INTEGER_CST - || TREE_INT_CST_LOW (arg0) & ~0x3) - { - error ("argument to dss must be a 2-bit unsigned literal"); - return const0_rtx; - } - - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - - emit_insn (gen_altivec_dss (op0)); - return NULL_RTX; - - case ALTIVEC_BUILTIN_VEC_INIT_V4SI: - case ALTIVEC_BUILTIN_VEC_INIT_V8HI: - case ALTIVEC_BUILTIN_VEC_INIT_V16QI: - case ALTIVEC_BUILTIN_VEC_INIT_V4SF: - case VSX_BUILTIN_VEC_INIT_V2DF: - case VSX_BUILTIN_VEC_INIT_V2DI: - return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target); - - case ALTIVEC_BUILTIN_VEC_SET_V4SI: - case ALTIVEC_BUILTIN_VEC_SET_V8HI: - case ALTIVEC_BUILTIN_VEC_SET_V16QI: - case ALTIVEC_BUILTIN_VEC_SET_V4SF: - case VSX_BUILTIN_VEC_SET_V2DF: - case VSX_BUILTIN_VEC_SET_V2DI: - return altivec_expand_vec_set_builtin (exp); - - case ALTIVEC_BUILTIN_VEC_EXT_V4SI: - case ALTIVEC_BUILTIN_VEC_EXT_V8HI: - case ALTIVEC_BUILTIN_VEC_EXT_V16QI: - case ALTIVEC_BUILTIN_VEC_EXT_V4SF: - case VSX_BUILTIN_VEC_EXT_V2DF: - case VSX_BUILTIN_VEC_EXT_V2DI: - return altivec_expand_vec_ext_builtin (exp, target); - - default: - break; - /* Fall through. */ - } - - /* Expand abs* operations. */ - d = bdesc_abs; - for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++) - if (d->code == fcode) - return altivec_expand_abs_builtin (d->icode, exp, target); - - /* Expand the AltiVec predicates. */ - d = bdesc_altivec_preds; - for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, d++) - if (d->code == fcode) - return altivec_expand_predicate_builtin (d->icode, exp, target); - - /* LV* are funky. We initialized them differently. */ - switch (fcode) - { - case ALTIVEC_BUILTIN_LVSL: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl, - exp, target, false); - case ALTIVEC_BUILTIN_LVSR: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr, - exp, target, false); - case ALTIVEC_BUILTIN_LVEBX: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx, - exp, target, false); - case ALTIVEC_BUILTIN_LVEHX: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx, - exp, target, false); - case ALTIVEC_BUILTIN_LVEWX: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx, - exp, target, false); - case ALTIVEC_BUILTIN_LVXL: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl, - exp, target, false); - case ALTIVEC_BUILTIN_LVX: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si, - exp, target, false); - case ALTIVEC_BUILTIN_LVLX: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx, - exp, target, true); - case ALTIVEC_BUILTIN_LVLXL: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl, - exp, target, true); - case ALTIVEC_BUILTIN_LVRX: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx, - exp, target, true); - case ALTIVEC_BUILTIN_LVRXL: - return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl, - exp, target, true); - case VSX_BUILTIN_LXVD2X_V2DF: - return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df, - exp, target, false); - case VSX_BUILTIN_LXVD2X_V2DI: - return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di, - exp, target, false); - case VSX_BUILTIN_LXVW4X_V4SF: - return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf, - exp, target, false); - case VSX_BUILTIN_LXVW4X_V4SI: - return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si, - exp, target, false); - case VSX_BUILTIN_LXVW4X_V8HI: - return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi, - exp, target, false); - case VSX_BUILTIN_LXVW4X_V16QI: - return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi, - exp, target, false); - break; - default: - break; - /* Fall through. */ - } - - *expandedp = false; - return NULL_RTX; -} - -/* Expand the builtin in EXP and store the result in TARGET. Store - true in *EXPANDEDP if we found a builtin to expand. */ -static rtx -paired_expand_builtin (tree exp, rtx target, bool * expandedp) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl); - const struct builtin_description *d; - size_t i; - - *expandedp = true; - - switch (fcode) - { - case PAIRED_BUILTIN_STX: - return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp); - case PAIRED_BUILTIN_LX: - return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target); - default: - break; - /* Fall through. */ - } - - /* Expand the paired predicates. */ - d = bdesc_paired_preds; - for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++) - if (d->code == fcode) - return paired_expand_predicate_builtin (d->icode, exp, target); - - *expandedp = false; - return NULL_RTX; -} - -/* Binops that need to be initialized manually, but can be expanded - automagically by rs6000_expand_binop_builtin. */ -static const struct builtin_description bdesc_2arg_spe[] = -{ - { RS6000_BTM_SPE, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX }, - { RS6000_BTM_SPE, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD }, - { RS6000_BTM_SPE, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW }, - { RS6000_BTM_SPE, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT }, - { RS6000_BTM_SPE, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT } -}; - -/* Expand the builtin in EXP and store the result in TARGET. Store - true in *EXPANDEDP if we found a builtin to expand. - - This expands the SPE builtins that are not simple unary and binary - operations. */ -static rtx -spe_expand_builtin (tree exp, rtx target, bool *expandedp) -{ - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); - tree arg1, arg0; - enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl); - enum insn_code icode; - enum machine_mode tmode, mode0; - rtx pat, op0; - const struct builtin_description *d; - size_t i; - - *expandedp = true; - - /* Syntax check for a 5-bit unsigned immediate. */ - switch (fcode) - { - case SPE_BUILTIN_EVSTDD: - case SPE_BUILTIN_EVSTDH: - case SPE_BUILTIN_EVSTDW: - case SPE_BUILTIN_EVSTWHE: - case SPE_BUILTIN_EVSTWHO: - case SPE_BUILTIN_EVSTWWE: - case SPE_BUILTIN_EVSTWWO: - arg1 = CALL_EXPR_ARG (exp, 2); - if (TREE_CODE (arg1) != INTEGER_CST - || TREE_INT_CST_LOW (arg1) & ~0x1f) - { - error ("argument 2 must be a 5-bit unsigned literal"); - return const0_rtx; - } - break; - default: - break; - } - - /* The evsplat*i instructions are not quite generic. */ - switch (fcode) - { - case SPE_BUILTIN_EVSPLATFI: - return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi, - exp, target); - case SPE_BUILTIN_EVSPLATI: - return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati, - exp, target); - default: - break; - } - - d = bdesc_2arg_spe; - for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d) - if (d->code == fcode) - return rs6000_expand_binop_builtin (d->icode, exp, target); - - d = bdesc_spe_predicates; - for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d) - if (d->code == fcode) - return spe_expand_predicate_builtin (d->icode, exp, target); - - d = bdesc_spe_evsel; - for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d) - if (d->code == fcode) - return spe_expand_evsel_builtin (d->icode, exp, target); - - switch (fcode) - { - case SPE_BUILTIN_EVSTDDX: - return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp); - case SPE_BUILTIN_EVSTDHX: - return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp); - case SPE_BUILTIN_EVSTDWX: - return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp); - case SPE_BUILTIN_EVSTWHEX: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp); - case SPE_BUILTIN_EVSTWHOX: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp); - case SPE_BUILTIN_EVSTWWEX: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp); - case SPE_BUILTIN_EVSTWWOX: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp); - case SPE_BUILTIN_EVSTDD: - return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp); - case SPE_BUILTIN_EVSTDH: - return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp); - case SPE_BUILTIN_EVSTDW: - return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp); - case SPE_BUILTIN_EVSTWHE: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp); - case SPE_BUILTIN_EVSTWHO: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp); - case SPE_BUILTIN_EVSTWWE: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp); - case SPE_BUILTIN_EVSTWWO: - return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp); - case SPE_BUILTIN_MFSPEFSCR: - icode = CODE_FOR_spe_mfspefscr; - tmode = insn_data[icode].operand[0].mode; - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - pat = GEN_FCN (icode) (target); - if (! pat) - return 0; - emit_insn (pat); - return target; - case SPE_BUILTIN_MTSPEFSCR: - icode = CODE_FOR_spe_mtspefscr; - arg0 = CALL_EXPR_ARG (exp, 0); - op0 = expand_normal (arg0); - mode0 = insn_data[icode].operand[0].mode; - - if (arg0 == error_mark_node) - return const0_rtx; - - if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - - pat = GEN_FCN (icode) (op0); - if (pat) - emit_insn (pat); - return NULL_RTX; - default: - break; - } - - *expandedp = false; - return NULL_RTX; -} - -static rtx -paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat, scratch, tmp; - tree form = CALL_EXPR_ARG (exp, 0); - tree arg0 = CALL_EXPR_ARG (exp, 1); - tree arg1 = CALL_EXPR_ARG (exp, 2); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - enum machine_mode mode1 = insn_data[icode].operand[2].mode; - int form_int; - enum rtx_code code; - - if (TREE_CODE (form) != INTEGER_CST) - { - error ("argument 1 of __builtin_paired_predicate must be a constant"); - return const0_rtx; - } - else - form_int = TREE_INT_CST_LOW (form); - - gcc_assert (mode0 == mode1); - - if (arg0 == error_mark_node || arg1 == error_mark_node) - return const0_rtx; - - if (target == 0 - || GET_MODE (target) != SImode - || !(*insn_data[icode].operand[0].predicate) (target, SImode)) - target = gen_reg_rtx (SImode); - if (!(*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - if (!(*insn_data[icode].operand[2].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - - scratch = gen_reg_rtx (CCFPmode); - - pat = GEN_FCN (icode) (scratch, op0, op1); - if (!pat) - return const0_rtx; - - emit_insn (pat); - - switch (form_int) - { - /* LT bit. */ - case 0: - code = LT; - break; - /* GT bit. */ - case 1: - code = GT; - break; - /* EQ bit. */ - case 2: - code = EQ; - break; - /* UN bit. */ - case 3: - emit_insn (gen_move_from_CR_ov_bit (target, scratch)); - return target; - default: - error ("argument 1 of __builtin_paired_predicate is out of range"); - return const0_rtx; - } - - tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx); - emit_move_insn (target, tmp); - return target; -} - -static rtx -spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat, scratch, tmp; - tree form = CALL_EXPR_ARG (exp, 0); - tree arg0 = CALL_EXPR_ARG (exp, 1); - tree arg1 = CALL_EXPR_ARG (exp, 2); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - enum machine_mode mode1 = insn_data[icode].operand[2].mode; - int form_int; - enum rtx_code code; - - if (TREE_CODE (form) != INTEGER_CST) - { - error ("argument 1 of __builtin_spe_predicate must be a constant"); - return const0_rtx; - } - else - form_int = TREE_INT_CST_LOW (form); - - gcc_assert (mode0 == mode1); - - if (arg0 == error_mark_node || arg1 == error_mark_node) - return const0_rtx; - - if (target == 0 - || GET_MODE (target) != SImode - || ! (*insn_data[icode].operand[0].predicate) (target, SImode)) - target = gen_reg_rtx (SImode); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - if (! (*insn_data[icode].operand[2].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode1, op1); - - scratch = gen_reg_rtx (CCmode); - - pat = GEN_FCN (icode) (scratch, op0, op1); - if (! pat) - return const0_rtx; - emit_insn (pat); - - /* There are 4 variants for each predicate: _any_, _all_, _upper_, - _lower_. We use one compare, but look in different bits of the - CR for each variant. - - There are 2 elements in each SPE simd type (upper/lower). The CR - bits are set as follows: - - BIT0 | BIT 1 | BIT 2 | BIT 3 - U | L | (U | L) | (U & L) - - So, for an "all" relationship, BIT 3 would be set. - For an "any" relationship, BIT 2 would be set. Etc. - - Following traditional nomenclature, these bits map to: - - BIT0 | BIT 1 | BIT 2 | BIT 3 - LT | GT | EQ | OV - - Later, we will generate rtl to look in the LT/EQ/EQ/OV bits. - */ - - switch (form_int) - { - /* All variant. OV bit. */ - case 0: - /* We need to get to the OV bit, which is the ORDERED bit. We - could generate (ordered:SI (reg:CC xx) (const_int 0)), but - that's ugly and will make validate_condition_mode die. - So let's just use another pattern. */ - emit_insn (gen_move_from_CR_ov_bit (target, scratch)); - return target; - /* Any variant. EQ bit. */ - case 1: - code = EQ; - break; - /* Upper variant. LT bit. */ - case 2: - code = LT; - break; - /* Lower variant. GT bit. */ - case 3: - code = GT; - break; - default: - error ("argument 1 of __builtin_spe_predicate is out of range"); - return const0_rtx; - } - - tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx); - emit_move_insn (target, tmp); - - return target; -} - -/* The evsel builtins look like this: - - e = __builtin_spe_evsel_OP (a, b, c, d); - - and work like this: - - e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper]; - e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower]; -*/ - -static rtx -spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target) -{ - rtx pat, scratch; - tree arg0 = CALL_EXPR_ARG (exp, 0); - tree arg1 = CALL_EXPR_ARG (exp, 1); - tree arg2 = CALL_EXPR_ARG (exp, 2); - tree arg3 = CALL_EXPR_ARG (exp, 3); - rtx op0 = expand_normal (arg0); - rtx op1 = expand_normal (arg1); - rtx op2 = expand_normal (arg2); - rtx op3 = expand_normal (arg3); - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - enum machine_mode mode1 = insn_data[icode].operand[2].mode; - - gcc_assert (mode0 == mode1); - - if (arg0 == error_mark_node || arg1 == error_mark_node - || arg2 == error_mark_node || arg3 == error_mark_node) - return const0_rtx; - - if (target == 0 - || GET_MODE (target) != mode0 - || ! (*insn_data[icode].operand[0].predicate) (target, mode0)) - target = gen_reg_rtx (mode0); - - if (! (*insn_data[icode].operand[1].predicate) (op0, mode0)) - op0 = copy_to_mode_reg (mode0, op0); - if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) - op1 = copy_to_mode_reg (mode0, op1); - if (! (*insn_data[icode].operand[1].predicate) (op2, mode1)) - op2 = copy_to_mode_reg (mode0, op2); - if (! (*insn_data[icode].operand[1].predicate) (op3, mode1)) - op3 = copy_to_mode_reg (mode0, op3); - - /* Generate the compare. */ - scratch = gen_reg_rtx (CCmode); - pat = GEN_FCN (icode) (scratch, op0, op1); - if (! pat) - return const0_rtx; - emit_insn (pat); - - if (mode0 == V2SImode) - emit_insn (gen_spe_evsel (target, op2, op3, scratch)); - else - emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch)); - - return target; -} - -/* Raise an error message for a builtin function that is called without the - appropriate target options being set. */ - -static void -rs6000_invalid_builtin (enum rs6000_builtins fncode) -{ - size_t uns_fncode = (size_t)fncode; - const char *name = rs6000_builtin_info[uns_fncode].name; - HOST_WIDE_INT fnmask = rs6000_builtin_info[uns_fncode].mask; - - gcc_assert (name != NULL); - if ((fnmask & RS6000_BTM_CELL) != 0) - error ("Builtin function %s is only valid for the cell processor", name); - else if ((fnmask & RS6000_BTM_VSX) != 0) - error ("Builtin function %s requires the -mvsx option", name); - else if ((fnmask & RS6000_BTM_ALTIVEC) != 0) - error ("Builtin function %s requires the -maltivec option", name); - else if ((fnmask & RS6000_BTM_PAIRED) != 0) - error ("Builtin function %s requires the -mpaired option", name); - else if ((fnmask & RS6000_BTM_SPE) != 0) - error ("Builtin function %s requires the -mspe option", name); - else - error ("Builtin function %s is not supported with the current options", - name); -} - -/* Expand an expression EXP that calls a built-in function, - with result going to TARGET if that's convenient - (and in mode MODE if that's convenient). - SUBTARGET may be used as the target for computing one of EXP's operands. - IGNORE is nonzero if the value is to be ignored. */ - -static rtx -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 (CALL_EXPR_FN (exp), 0); - enum rs6000_builtins fcode - = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl); - size_t uns_fcode = (size_t)fcode; - const struct builtin_description *d; - size_t i; - rtx ret; - bool success; - HOST_WIDE_INT mask = rs6000_builtin_info[uns_fcode].mask; - bool func_valid_p = ((rs6000_builtin_mask & mask) == mask); - - if (TARGET_DEBUG_BUILTIN) - { - enum insn_code icode = rs6000_builtin_info[uns_fcode].icode; - const char *name1 = rs6000_builtin_info[uns_fcode].name; - const char *name2 = ((icode != CODE_FOR_nothing) - ? get_insn_name ((int)icode) - : "nothing"); - const char *name3; - - switch (rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK) - { - default: name3 = "unknown"; break; - case RS6000_BTC_SPECIAL: name3 = "special"; break; - case RS6000_BTC_UNARY: name3 = "unary"; break; - case RS6000_BTC_BINARY: name3 = "binary"; break; - case RS6000_BTC_TERNARY: name3 = "ternary"; break; - case RS6000_BTC_PREDICATE: name3 = "predicate"; break; - case RS6000_BTC_ABS: name3 = "abs"; break; - case RS6000_BTC_EVSEL: name3 = "evsel"; break; - case RS6000_BTC_DST: name3 = "dst"; break; - } - - - fprintf (stderr, - "rs6000_expand_builtin, %s (%d), insn = %s (%d), type=%s%s\n", - (name1) ? name1 : "---", fcode, - (name2) ? name2 : "---", (int)icode, - name3, - func_valid_p ? "" : ", not valid"); - } - - if (!func_valid_p) - { - rs6000_invalid_builtin (fcode); - - /* Given it is invalid, just generate a normal call. */ - return expand_call (exp, target, ignore); - } - - switch (fcode) - { - case RS6000_BUILTIN_RECIP: - return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target); - - case RS6000_BUILTIN_RECIPF: - return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target); - - case RS6000_BUILTIN_RSQRTF: - return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target); - - case RS6000_BUILTIN_RSQRT: - return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target); - - case POWER7_BUILTIN_BPERMD: - return rs6000_expand_binop_builtin (((TARGET_64BIT) - ? CODE_FOR_bpermd_di - : CODE_FOR_bpermd_si), exp, target); - - case RS6000_BUILTIN_GET_TB: - return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_get_timebase, - target); - - case RS6000_BUILTIN_MFTB: - return rs6000_expand_zeroop_builtin (((TARGET_64BIT) - ? CODE_FOR_rs6000_mftb_di - : CODE_FOR_rs6000_mftb_si), - target); - - case ALTIVEC_BUILTIN_MASK_FOR_LOAD: - case ALTIVEC_BUILTIN_MASK_FOR_STORE: - { - int icode = (int) CODE_FOR_altivec_lvsr; - enum machine_mode tmode = insn_data[icode].operand[0].mode; - enum machine_mode mode = insn_data[icode].operand[1].mode; - tree arg; - rtx op, addr, pat; - - gcc_assert (TARGET_ALTIVEC); - - arg = CALL_EXPR_ARG (exp, 0); - gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg))); - op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL); - addr = memory_address (mode, op); - if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE) - op = addr; - else - { - /* For the load case need to negate the address. */ - op = gen_reg_rtx (GET_MODE (addr)); - emit_insn (gen_rtx_SET (VOIDmode, op, - gen_rtx_NEG (GET_MODE (addr), addr))); - } - op = gen_rtx_MEM (mode, op); - - if (target == 0 - || GET_MODE (target) != tmode - || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) - target = gen_reg_rtx (tmode); - - /*pat = gen_altivec_lvsr (target, op);*/ - pat = GEN_FCN (icode) (target, op); - if (!pat) - return 0; - emit_insn (pat); - - return target; - } - - case ALTIVEC_BUILTIN_VCFUX: - case ALTIVEC_BUILTIN_VCFSX: - case ALTIVEC_BUILTIN_VCTUXS: - case ALTIVEC_BUILTIN_VCTSXS: - /* FIXME: There's got to be a nicer way to handle this case than - constructing a new CALL_EXPR. */ - if (call_expr_nargs (exp) == 1) - { - exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp), - 2, CALL_EXPR_ARG (exp, 0), integer_zero_node); - } - break; - - default: - break; - } - - if (TARGET_ALTIVEC) - { - ret = altivec_expand_builtin (exp, target, &success); - - if (success) - return ret; - } - if (TARGET_SPE) - { - ret = spe_expand_builtin (exp, target, &success); - - if (success) - return ret; - } - if (TARGET_PAIRED_FLOAT) - { - ret = paired_expand_builtin (exp, target, &success); - - if (success) - return ret; - } - - gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT); - - /* Handle simple unary operations. */ - d = bdesc_1arg; - for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++) - if (d->code == fcode) - return rs6000_expand_unop_builtin (d->icode, exp, target); - - /* Handle simple binary operations. */ - d = bdesc_2arg; - for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++) - if (d->code == fcode) - return rs6000_expand_binop_builtin (d->icode, exp, target); - - /* Handle simple ternary operations. */ - d = bdesc_3arg; - for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++) - if (d->code == fcode) - return rs6000_expand_ternop_builtin (d->icode, exp, target); - - gcc_unreachable (); -} - -static void -rs6000_init_builtins (void) -{ - tree tdecl; - tree ftype; - enum machine_mode mode; - - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "rs6000_init_builtins%s%s%s%s\n", - (TARGET_PAIRED_FLOAT) ? ", paired" : "", - (TARGET_SPE) ? ", spe" : "", - (TARGET_ALTIVEC) ? ", altivec" : "", - (TARGET_VSX) ? ", vsx" : ""); - - V2SI_type_node = build_vector_type (intSI_type_node, 2); - V2SF_type_node = build_vector_type (float_type_node, 2); - V2DI_type_node = build_vector_type (intDI_type_node, 2); - V2DF_type_node = build_vector_type (double_type_node, 2); - V4HI_type_node = build_vector_type (intHI_type_node, 4); - V4SI_type_node = build_vector_type (intSI_type_node, 4); - V4SF_type_node = build_vector_type (float_type_node, 4); - V8HI_type_node = build_vector_type (intHI_type_node, 8); - V16QI_type_node = build_vector_type (intQI_type_node, 16); - - unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16); - unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8); - unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4); - unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2); - - opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2); - opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2); - opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node); - opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4); - - /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...' - types, especially in C++ land. Similarly, 'vector pixel' is distinct from - 'vector unsigned short'. */ - - bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node); - bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node); - bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node); - bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node); - pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node); - - long_integer_type_internal_node = long_integer_type_node; - long_unsigned_type_internal_node = long_unsigned_type_node; - long_long_integer_type_internal_node = long_long_integer_type_node; - long_long_unsigned_type_internal_node = long_long_unsigned_type_node; - intQI_type_internal_node = intQI_type_node; - uintQI_type_internal_node = unsigned_intQI_type_node; - intHI_type_internal_node = intHI_type_node; - uintHI_type_internal_node = unsigned_intHI_type_node; - intSI_type_internal_node = intSI_type_node; - uintSI_type_internal_node = unsigned_intSI_type_node; - intDI_type_internal_node = intDI_type_node; - uintDI_type_internal_node = unsigned_intDI_type_node; - float_type_internal_node = float_type_node; - double_type_internal_node = double_type_node; - void_type_internal_node = void_type_node; - - /* Initialize the modes for builtin_function_type, mapping a machine mode to - tree type node. */ - builtin_mode_to_type[QImode][0] = integer_type_node; - builtin_mode_to_type[HImode][0] = integer_type_node; - builtin_mode_to_type[SImode][0] = intSI_type_node; - builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node; - builtin_mode_to_type[DImode][0] = intDI_type_node; - builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node; - builtin_mode_to_type[SFmode][0] = float_type_node; - builtin_mode_to_type[DFmode][0] = double_type_node; - builtin_mode_to_type[V2SImode][0] = V2SI_type_node; - builtin_mode_to_type[V2SFmode][0] = V2SF_type_node; - builtin_mode_to_type[V2DImode][0] = V2DI_type_node; - builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node; - builtin_mode_to_type[V2DFmode][0] = V2DF_type_node; - builtin_mode_to_type[V4HImode][0] = V4HI_type_node; - builtin_mode_to_type[V4SImode][0] = V4SI_type_node; - builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node; - builtin_mode_to_type[V4SFmode][0] = V4SF_type_node; - builtin_mode_to_type[V8HImode][0] = V8HI_type_node; - builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node; - builtin_mode_to_type[V16QImode][0] = V16QI_type_node; - builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node; - - tdecl = add_builtin_type ("__bool char", bool_char_type_node); - TYPE_NAME (bool_char_type_node) = tdecl; - - tdecl = add_builtin_type ("__bool short", bool_short_type_node); - TYPE_NAME (bool_short_type_node) = tdecl; - - tdecl = add_builtin_type ("__bool int", bool_int_type_node); - TYPE_NAME (bool_int_type_node) = tdecl; - - tdecl = add_builtin_type ("__pixel", pixel_type_node); - TYPE_NAME (pixel_type_node) = tdecl; - - bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16); - bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8); - bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4); - bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2); - pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8); - - tdecl = add_builtin_type ("__vector unsigned char", unsigned_V16QI_type_node); - TYPE_NAME (unsigned_V16QI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector signed char", V16QI_type_node); - TYPE_NAME (V16QI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector __bool char", bool_V16QI_type_node); - TYPE_NAME ( bool_V16QI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector unsigned short", unsigned_V8HI_type_node); - TYPE_NAME (unsigned_V8HI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector signed short", V8HI_type_node); - TYPE_NAME (V8HI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector __bool short", bool_V8HI_type_node); - TYPE_NAME (bool_V8HI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector unsigned int", unsigned_V4SI_type_node); - TYPE_NAME (unsigned_V4SI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector signed int", V4SI_type_node); - TYPE_NAME (V4SI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector __bool int", bool_V4SI_type_node); - TYPE_NAME (bool_V4SI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector float", V4SF_type_node); - TYPE_NAME (V4SF_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector __pixel", pixel_V8HI_type_node); - TYPE_NAME (pixel_V8HI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector double", V2DF_type_node); - TYPE_NAME (V2DF_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector long", V2DI_type_node); - TYPE_NAME (V2DI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector unsigned long", unsigned_V2DI_type_node); - TYPE_NAME (unsigned_V2DI_type_node) = tdecl; - - tdecl = add_builtin_type ("__vector __bool long", bool_V2DI_type_node); - TYPE_NAME (bool_V2DI_type_node) = tdecl; - - /* Paired and SPE builtins are only available if you build a compiler with - the appropriate options, so only create those builtins with the - appropriate compiler option. Create Altivec and VSX builtins on machines - with at least the general purpose extensions (970 and newer) to allow the - use of the target attribute. */ - if (TARGET_PAIRED_FLOAT) - paired_init_builtins (); - if (TARGET_SPE) - spe_init_builtins (); - if (TARGET_EXTRA_BUILTINS) - altivec_init_builtins (); - if (TARGET_EXTRA_BUILTINS || TARGET_SPE || TARGET_PAIRED_FLOAT) - rs6000_common_init_builtins (); - - ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode, - RS6000_BUILTIN_RECIP, "__builtin_recipdiv"); - def_builtin ("__builtin_recipdiv", ftype, RS6000_BUILTIN_RECIP); - - ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode, - RS6000_BUILTIN_RECIPF, "__builtin_recipdivf"); - def_builtin ("__builtin_recipdivf", ftype, RS6000_BUILTIN_RECIPF); - - ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode, - RS6000_BUILTIN_RSQRT, "__builtin_rsqrt"); - def_builtin ("__builtin_rsqrt", ftype, RS6000_BUILTIN_RSQRT); - - ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode, - RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf"); - def_builtin ("__builtin_rsqrtf", ftype, RS6000_BUILTIN_RSQRTF); - - mode = (TARGET_64BIT) ? DImode : SImode; - ftype = builtin_function_type (mode, mode, mode, VOIDmode, - POWER7_BUILTIN_BPERMD, "__builtin_bpermd"); - def_builtin ("__builtin_bpermd", ftype, POWER7_BUILTIN_BPERMD); - - ftype = build_function_type_list (unsigned_intDI_type_node, - NULL_TREE); - def_builtin ("__builtin_ppc_get_timebase", ftype, RS6000_BUILTIN_GET_TB); - - if (TARGET_64BIT) - ftype = build_function_type_list (unsigned_intDI_type_node, - NULL_TREE); - else - ftype = build_function_type_list (unsigned_intSI_type_node, - NULL_TREE); - def_builtin ("__builtin_ppc_mftb", ftype, RS6000_BUILTIN_MFTB); - -#if TARGET_XCOFF - /* AIX libm provides clog as __clog. */ - if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE) - set_user_assembler_name (tdecl, "__clog"); -#endif - -#ifdef SUBTARGET_INIT_BUILTINS - SUBTARGET_INIT_BUILTINS; -#endif -} - -/* Returns the rs6000 builtin decl for CODE. */ - -static tree -rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED) -{ - HOST_WIDE_INT fnmask; - - if (code >= RS6000_BUILTIN_COUNT) - return error_mark_node; - - fnmask = rs6000_builtin_info[code].mask; - if ((fnmask & rs6000_builtin_mask) != fnmask) - { - rs6000_invalid_builtin ((enum rs6000_builtins)code); - return error_mark_node; - } - - return rs6000_builtin_decls[code]; -} - -static void -spe_init_builtins (void) -{ - tree puint_type_node = build_pointer_type (unsigned_type_node); - tree pushort_type_node = build_pointer_type (short_unsigned_type_node); - const struct builtin_description *d; - size_t i; - - tree v2si_ftype_4_v2si - = build_function_type_list (opaque_V2SI_type_node, - opaque_V2SI_type_node, - opaque_V2SI_type_node, - opaque_V2SI_type_node, - opaque_V2SI_type_node, - NULL_TREE); - - tree v2sf_ftype_4_v2sf - = build_function_type_list (opaque_V2SF_type_node, - opaque_V2SF_type_node, - opaque_V2SF_type_node, - opaque_V2SF_type_node, - opaque_V2SF_type_node, - NULL_TREE); - - tree int_ftype_int_v2si_v2si - = build_function_type_list (integer_type_node, - integer_type_node, - opaque_V2SI_type_node, - opaque_V2SI_type_node, - NULL_TREE); - - tree int_ftype_int_v2sf_v2sf - = build_function_type_list (integer_type_node, - integer_type_node, - opaque_V2SF_type_node, - opaque_V2SF_type_node, - NULL_TREE); - - tree void_ftype_v2si_puint_int - = build_function_type_list (void_type_node, - opaque_V2SI_type_node, - puint_type_node, - integer_type_node, - NULL_TREE); - - tree void_ftype_v2si_puint_char - = build_function_type_list (void_type_node, - opaque_V2SI_type_node, - puint_type_node, - char_type_node, - NULL_TREE); - - tree void_ftype_v2si_pv2si_int - = build_function_type_list (void_type_node, - opaque_V2SI_type_node, - opaque_p_V2SI_type_node, - integer_type_node, - NULL_TREE); - - tree void_ftype_v2si_pv2si_char - = build_function_type_list (void_type_node, - opaque_V2SI_type_node, - opaque_p_V2SI_type_node, - char_type_node, - NULL_TREE); - - tree void_ftype_int - = build_function_type_list (void_type_node, integer_type_node, NULL_TREE); - - tree int_ftype_void - = build_function_type_list (integer_type_node, NULL_TREE); - - tree v2si_ftype_pv2si_int - = build_function_type_list (opaque_V2SI_type_node, - opaque_p_V2SI_type_node, - integer_type_node, - NULL_TREE); - - tree v2si_ftype_puint_int - = build_function_type_list (opaque_V2SI_type_node, - puint_type_node, - integer_type_node, - NULL_TREE); - - tree v2si_ftype_pushort_int - = build_function_type_list (opaque_V2SI_type_node, - pushort_type_node, - integer_type_node, - NULL_TREE); - - tree v2si_ftype_signed_char - = build_function_type_list (opaque_V2SI_type_node, - signed_char_type_node, - NULL_TREE); - - add_builtin_type ("__ev64_opaque__", opaque_V2SI_type_node); - - /* Initialize irregular SPE builtins. */ - - def_builtin ("__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR); - def_builtin ("__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR); - def_builtin ("__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX); - def_builtin ("__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX); - def_builtin ("__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX); - def_builtin ("__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX); - def_builtin ("__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX); - def_builtin ("__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX); - def_builtin ("__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX); - def_builtin ("__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD); - def_builtin ("__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH); - def_builtin ("__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW); - def_builtin ("__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE); - def_builtin ("__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO); - def_builtin ("__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE); - def_builtin ("__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO); - def_builtin ("__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI); - def_builtin ("__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI); - - /* Loads. */ - def_builtin ("__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX); - def_builtin ("__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX); - def_builtin ("__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX); - def_builtin ("__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX); - def_builtin ("__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX); - def_builtin ("__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX); - def_builtin ("__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX); - def_builtin ("__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX); - def_builtin ("__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX); - def_builtin ("__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX); - def_builtin ("__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX); - def_builtin ("__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD); - def_builtin ("__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW); - def_builtin ("__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH); - def_builtin ("__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT); - def_builtin ("__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT); - def_builtin ("__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT); - def_builtin ("__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE); - def_builtin ("__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS); - def_builtin ("__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU); - def_builtin ("__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT); - def_builtin ("__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT); - - /* Predicates. */ - d = bdesc_spe_predicates; - for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++) - { - tree type; - - switch (insn_data[d->icode].operand[1].mode) - { - case V2SImode: - type = int_ftype_int_v2si_v2si; - break; - case V2SFmode: - type = int_ftype_int_v2sf_v2sf; - break; - default: - gcc_unreachable (); - } - - def_builtin (d->name, type, d->code); - } - - /* Evsel predicates. */ - d = bdesc_spe_evsel; - for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++) - { - tree type; - - switch (insn_data[d->icode].operand[1].mode) - { - case V2SImode: - type = v2si_ftype_4_v2si; - break; - case V2SFmode: - type = v2sf_ftype_4_v2sf; - break; - default: - gcc_unreachable (); - } - - def_builtin (d->name, type, d->code); - } -} - -static void -paired_init_builtins (void) -{ - const struct builtin_description *d; - size_t i; - - tree int_ftype_int_v2sf_v2sf - = build_function_type_list (integer_type_node, - integer_type_node, - V2SF_type_node, - V2SF_type_node, - NULL_TREE); - tree pcfloat_type_node = - build_pointer_type (build_qualified_type - (float_type_node, TYPE_QUAL_CONST)); - - tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node, - long_integer_type_node, - pcfloat_type_node, - NULL_TREE); - tree void_ftype_v2sf_long_pcfloat = - build_function_type_list (void_type_node, - V2SF_type_node, - long_integer_type_node, - pcfloat_type_node, - NULL_TREE); - - - def_builtin ("__builtin_paired_lx", v2sf_ftype_long_pcfloat, - PAIRED_BUILTIN_LX); - - - def_builtin ("__builtin_paired_stx", void_ftype_v2sf_long_pcfloat, - PAIRED_BUILTIN_STX); - - /* Predicates. */ - d = bdesc_paired_preds; - for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++) - { - tree type; - - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "paired pred #%d, insn = %s [%d], mode = %s\n", - (int)i, get_insn_name (d->icode), (int)d->icode, - GET_MODE_NAME (insn_data[d->icode].operand[1].mode)); - - switch (insn_data[d->icode].operand[1].mode) - { - case V2SFmode: - type = int_ftype_int_v2sf_v2sf; - break; - default: - gcc_unreachable (); - } - - def_builtin (d->name, type, d->code); - } -} - -static void -altivec_init_builtins (void) -{ - const struct builtin_description *d; - size_t i; - tree ftype; - tree decl; - - tree pvoid_type_node = build_pointer_type (void_type_node); - - tree pcvoid_type_node - = build_pointer_type (build_qualified_type (void_type_node, - TYPE_QUAL_CONST)); - - tree int_ftype_opaque - = build_function_type_list (integer_type_node, - opaque_V4SI_type_node, NULL_TREE); - tree opaque_ftype_opaque - = build_function_type_list (integer_type_node, NULL_TREE); - tree opaque_ftype_opaque_int - = build_function_type_list (opaque_V4SI_type_node, - opaque_V4SI_type_node, integer_type_node, NULL_TREE); - tree opaque_ftype_opaque_opaque_int - = build_function_type_list (opaque_V4SI_type_node, - opaque_V4SI_type_node, opaque_V4SI_type_node, - integer_type_node, NULL_TREE); - tree int_ftype_int_opaque_opaque - = build_function_type_list (integer_type_node, - integer_type_node, opaque_V4SI_type_node, - opaque_V4SI_type_node, NULL_TREE); - tree int_ftype_int_v4si_v4si - = build_function_type_list (integer_type_node, - integer_type_node, V4SI_type_node, - V4SI_type_node, NULL_TREE); - tree void_ftype_v4si - = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE); - tree v8hi_ftype_void - = build_function_type_list (V8HI_type_node, NULL_TREE); - tree void_ftype_void - = build_function_type_list (void_type_node, NULL_TREE); - tree void_ftype_int - = build_function_type_list (void_type_node, integer_type_node, NULL_TREE); - - tree opaque_ftype_long_pcvoid - = build_function_type_list (opaque_V4SI_type_node, - long_integer_type_node, pcvoid_type_node, - NULL_TREE); - tree v16qi_ftype_long_pcvoid - = build_function_type_list (V16QI_type_node, - long_integer_type_node, pcvoid_type_node, - NULL_TREE); - tree v8hi_ftype_long_pcvoid - = build_function_type_list (V8HI_type_node, - long_integer_type_node, pcvoid_type_node, - NULL_TREE); - tree v4si_ftype_long_pcvoid - = build_function_type_list (V4SI_type_node, - long_integer_type_node, pcvoid_type_node, - NULL_TREE); - tree v4sf_ftype_long_pcvoid - = build_function_type_list (V4SF_type_node, - long_integer_type_node, pcvoid_type_node, - NULL_TREE); - tree v2df_ftype_long_pcvoid - = build_function_type_list (V2DF_type_node, - long_integer_type_node, pcvoid_type_node, - NULL_TREE); - tree v2di_ftype_long_pcvoid - = build_function_type_list (V2DI_type_node, - long_integer_type_node, pcvoid_type_node, - NULL_TREE); - - tree void_ftype_opaque_long_pvoid - = build_function_type_list (void_type_node, - opaque_V4SI_type_node, long_integer_type_node, - pvoid_type_node, NULL_TREE); - tree void_ftype_v4si_long_pvoid - = build_function_type_list (void_type_node, - V4SI_type_node, long_integer_type_node, - pvoid_type_node, NULL_TREE); - tree void_ftype_v16qi_long_pvoid - = build_function_type_list (void_type_node, - V16QI_type_node, long_integer_type_node, - pvoid_type_node, NULL_TREE); - tree void_ftype_v8hi_long_pvoid - = build_function_type_list (void_type_node, - V8HI_type_node, long_integer_type_node, - pvoid_type_node, NULL_TREE); - tree void_ftype_v4sf_long_pvoid - = build_function_type_list (void_type_node, - V4SF_type_node, long_integer_type_node, - pvoid_type_node, NULL_TREE); - tree void_ftype_v2df_long_pvoid - = build_function_type_list (void_type_node, - V2DF_type_node, long_integer_type_node, - pvoid_type_node, NULL_TREE); - tree void_ftype_v2di_long_pvoid - = build_function_type_list (void_type_node, - V2DI_type_node, long_integer_type_node, - pvoid_type_node, NULL_TREE); - tree int_ftype_int_v8hi_v8hi - = build_function_type_list (integer_type_node, - integer_type_node, V8HI_type_node, - V8HI_type_node, NULL_TREE); - tree int_ftype_int_v16qi_v16qi - = build_function_type_list (integer_type_node, - integer_type_node, V16QI_type_node, - V16QI_type_node, NULL_TREE); - tree int_ftype_int_v4sf_v4sf - = build_function_type_list (integer_type_node, - integer_type_node, V4SF_type_node, - V4SF_type_node, NULL_TREE); - tree int_ftype_int_v2df_v2df - = build_function_type_list (integer_type_node, - integer_type_node, V2DF_type_node, - V2DF_type_node, NULL_TREE); - tree v4si_ftype_v4si - = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE); - tree v8hi_ftype_v8hi - = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE); - tree v16qi_ftype_v16qi - = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE); - tree v4sf_ftype_v4sf - = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE); - tree v2df_ftype_v2df - = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE); - tree void_ftype_pcvoid_int_int - = build_function_type_list (void_type_node, - pcvoid_type_node, integer_type_node, - integer_type_node, NULL_TREE); - - def_builtin ("__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR); - def_builtin ("__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR); - def_builtin ("__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL); - def_builtin ("__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS); - def_builtin ("__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL); - def_builtin ("__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR); - def_builtin ("__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX); - def_builtin ("__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX); - def_builtin ("__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX); - def_builtin ("__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL); - def_builtin ("__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX); - def_builtin ("__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX); - def_builtin ("__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX); - def_builtin ("__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL); - def_builtin ("__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX); - def_builtin ("__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX); - def_builtin ("__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD); - def_builtin ("__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE); - def_builtin ("__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL); - def_builtin ("__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL); - def_builtin ("__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR); - def_builtin ("__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX); - def_builtin ("__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX); - def_builtin ("__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX); - def_builtin ("__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST); - def_builtin ("__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE); - def_builtin ("__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL); - def_builtin ("__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX); - def_builtin ("__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX); - def_builtin ("__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX); - - def_builtin ("__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid, - VSX_BUILTIN_LXVD2X_V2DF); - def_builtin ("__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid, - VSX_BUILTIN_LXVD2X_V2DI); - def_builtin ("__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid, - VSX_BUILTIN_LXVW4X_V4SF); - def_builtin ("__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid, - VSX_BUILTIN_LXVW4X_V4SI); - def_builtin ("__builtin_vsx_lxvw4x_v8hi", v8hi_ftype_long_pcvoid, - VSX_BUILTIN_LXVW4X_V8HI); - def_builtin ("__builtin_vsx_lxvw4x_v16qi", v16qi_ftype_long_pcvoid, - VSX_BUILTIN_LXVW4X_V16QI); - def_builtin ("__builtin_vsx_stxvd2x_v2df", void_ftype_v2df_long_pvoid, - VSX_BUILTIN_STXVD2X_V2DF); - def_builtin ("__builtin_vsx_stxvd2x_v2di", void_ftype_v2di_long_pvoid, - VSX_BUILTIN_STXVD2X_V2DI); - def_builtin ("__builtin_vsx_stxvw4x_v4sf", void_ftype_v4sf_long_pvoid, - VSX_BUILTIN_STXVW4X_V4SF); - def_builtin ("__builtin_vsx_stxvw4x_v4si", void_ftype_v4si_long_pvoid, - VSX_BUILTIN_STXVW4X_V4SI); - def_builtin ("__builtin_vsx_stxvw4x_v8hi", void_ftype_v8hi_long_pvoid, - VSX_BUILTIN_STXVW4X_V8HI); - def_builtin ("__builtin_vsx_stxvw4x_v16qi", void_ftype_v16qi_long_pvoid, - VSX_BUILTIN_STXVW4X_V16QI); - def_builtin ("__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid, - VSX_BUILTIN_VEC_LD); - def_builtin ("__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid, - VSX_BUILTIN_VEC_ST); - - def_builtin ("__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP); - def_builtin ("__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS); - def_builtin ("__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE); - - def_builtin ("__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD); - def_builtin ("__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT); - def_builtin ("__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT); - def_builtin ("__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT); - def_builtin ("__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW); - def_builtin ("__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH); - def_builtin ("__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB); - def_builtin ("__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF); - def_builtin ("__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX); - def_builtin ("__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX); - def_builtin ("__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS); - def_builtin ("__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU); - - /* Cell builtins. */ - def_builtin ("__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX); - def_builtin ("__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL); - def_builtin ("__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX); - def_builtin ("__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL); - - def_builtin ("__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX); - def_builtin ("__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL); - def_builtin ("__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX); - def_builtin ("__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL); - - def_builtin ("__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX); - def_builtin ("__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL); - def_builtin ("__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX); - def_builtin ("__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL); - - def_builtin ("__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX); - def_builtin ("__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL); - def_builtin ("__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX); - def_builtin ("__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL); - - /* Add the DST variants. */ - d = bdesc_dst; - for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++) - def_builtin (d->name, void_ftype_pcvoid_int_int, d->code); - - /* Initialize the predicates. */ - d = bdesc_altivec_preds; - for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, d++) - { - enum machine_mode mode1; - tree type; - - if (rs6000_overloaded_builtin_p (d->code)) - mode1 = VOIDmode; - else - mode1 = insn_data[d->icode].operand[1].mode; - - switch (mode1) - { - case VOIDmode: - type = int_ftype_int_opaque_opaque; - break; - case V4SImode: - type = int_ftype_int_v4si_v4si; - break; - case V8HImode: - type = int_ftype_int_v8hi_v8hi; - break; - case V16QImode: - type = int_ftype_int_v16qi_v16qi; - break; - case V4SFmode: - type = int_ftype_int_v4sf_v4sf; - break; - case V2DFmode: - type = int_ftype_int_v2df_v2df; - break; - default: - gcc_unreachable (); - } - - def_builtin (d->name, type, d->code); - } - - /* Initialize the abs* operators. */ - d = bdesc_abs; - for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++) - { - enum machine_mode mode0; - tree type; - - mode0 = insn_data[d->icode].operand[0].mode; - - switch (mode0) - { - case V4SImode: - type = v4si_ftype_v4si; - break; - case V8HImode: - type = v8hi_ftype_v8hi; - break; - case V16QImode: - type = v16qi_ftype_v16qi; - break; - case V4SFmode: - type = v4sf_ftype_v4sf; - break; - case V2DFmode: - type = v2df_ftype_v2df; - break; - default: - gcc_unreachable (); - } - - def_builtin (d->name, type, d->code); - } - - /* Initialize target builtin that implements - targetm.vectorize.builtin_mask_for_load. */ - - decl = add_builtin_function ("__builtin_altivec_mask_for_load", - v16qi_ftype_long_pcvoid, - ALTIVEC_BUILTIN_MASK_FOR_LOAD, - BUILT_IN_MD, NULL, NULL_TREE); - TREE_READONLY (decl) = 1; - /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */ - altivec_builtin_mask_for_load = decl; - - /* Access to the vec_init patterns. */ - ftype = build_function_type_list (V4SI_type_node, integer_type_node, - integer_type_node, integer_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_init_v4si", ftype, ALTIVEC_BUILTIN_VEC_INIT_V4SI); - - ftype = build_function_type_list (V8HI_type_node, short_integer_type_node, - short_integer_type_node, - short_integer_type_node, - short_integer_type_node, - short_integer_type_node, - short_integer_type_node, - short_integer_type_node, - short_integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_init_v8hi", ftype, ALTIVEC_BUILTIN_VEC_INIT_V8HI); - - ftype = build_function_type_list (V16QI_type_node, char_type_node, - char_type_node, char_type_node, - char_type_node, char_type_node, - char_type_node, char_type_node, - char_type_node, char_type_node, - char_type_node, char_type_node, - char_type_node, char_type_node, - char_type_node, char_type_node, - char_type_node, NULL_TREE); - def_builtin ("__builtin_vec_init_v16qi", ftype, - ALTIVEC_BUILTIN_VEC_INIT_V16QI); - - ftype = build_function_type_list (V4SF_type_node, float_type_node, - float_type_node, float_type_node, - float_type_node, NULL_TREE); - def_builtin ("__builtin_vec_init_v4sf", ftype, ALTIVEC_BUILTIN_VEC_INIT_V4SF); - - /* VSX builtins. */ - ftype = build_function_type_list (V2DF_type_node, double_type_node, - double_type_node, NULL_TREE); - def_builtin ("__builtin_vec_init_v2df", ftype, VSX_BUILTIN_VEC_INIT_V2DF); - - ftype = build_function_type_list (V2DI_type_node, intDI_type_node, - intDI_type_node, NULL_TREE); - def_builtin ("__builtin_vec_init_v2di", ftype, VSX_BUILTIN_VEC_INIT_V2DI); - - /* Access to the vec_set patterns. */ - ftype = build_function_type_list (V4SI_type_node, V4SI_type_node, - intSI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_set_v4si", ftype, ALTIVEC_BUILTIN_VEC_SET_V4SI); - - ftype = build_function_type_list (V8HI_type_node, V8HI_type_node, - intHI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_set_v8hi", ftype, ALTIVEC_BUILTIN_VEC_SET_V8HI); - - ftype = build_function_type_list (V16QI_type_node, V16QI_type_node, - intQI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_set_v16qi", ftype, ALTIVEC_BUILTIN_VEC_SET_V16QI); - - ftype = build_function_type_list (V4SF_type_node, V4SF_type_node, - float_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_set_v4sf", ftype, ALTIVEC_BUILTIN_VEC_SET_V4SF); - - ftype = build_function_type_list (V2DF_type_node, V2DF_type_node, - double_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_set_v2df", ftype, VSX_BUILTIN_VEC_SET_V2DF); - - ftype = build_function_type_list (V2DI_type_node, V2DI_type_node, - intDI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_set_v2di", ftype, VSX_BUILTIN_VEC_SET_V2DI); - - /* Access to the vec_extract patterns. */ - ftype = build_function_type_list (intSI_type_node, V4SI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_ext_v4si", ftype, ALTIVEC_BUILTIN_VEC_EXT_V4SI); - - ftype = build_function_type_list (intHI_type_node, V8HI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_ext_v8hi", ftype, ALTIVEC_BUILTIN_VEC_EXT_V8HI); - - ftype = build_function_type_list (intQI_type_node, V16QI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_ext_v16qi", ftype, ALTIVEC_BUILTIN_VEC_EXT_V16QI); - - ftype = build_function_type_list (float_type_node, V4SF_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_ext_v4sf", ftype, ALTIVEC_BUILTIN_VEC_EXT_V4SF); - - ftype = build_function_type_list (double_type_node, V2DF_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_ext_v2df", ftype, VSX_BUILTIN_VEC_EXT_V2DF); - - ftype = build_function_type_list (intDI_type_node, V2DI_type_node, - integer_type_node, NULL_TREE); - def_builtin ("__builtin_vec_ext_v2di", ftype, VSX_BUILTIN_VEC_EXT_V2DI); -} - -/* Hash function for builtin functions with up to 3 arguments and a return - type. */ -static unsigned -builtin_hash_function (const void *hash_entry) -{ - unsigned ret = 0; - int i; - const struct builtin_hash_struct *bh = - (const struct builtin_hash_struct *) hash_entry; - - for (i = 0; i < 4; i++) - { - ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]); - ret = (ret * 2) + bh->uns_p[i]; - } - - return ret; -} - -/* Compare builtin hash entries H1 and H2 for equivalence. */ -static int -builtin_hash_eq (const void *h1, const void *h2) -{ - const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1; - const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2; - - return ((p1->mode[0] == p2->mode[0]) - && (p1->mode[1] == p2->mode[1]) - && (p1->mode[2] == p2->mode[2]) - && (p1->mode[3] == p2->mode[3]) - && (p1->uns_p[0] == p2->uns_p[0]) - && (p1->uns_p[1] == p2->uns_p[1]) - && (p1->uns_p[2] == p2->uns_p[2]) - && (p1->uns_p[3] == p2->uns_p[3])); -} - -/* Map types for builtin functions with an explicit return type and up to 3 - arguments. Functions with fewer than 3 arguments use VOIDmode as the type - of the argument. */ -static tree -builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0, - enum machine_mode mode_arg1, enum machine_mode mode_arg2, - enum rs6000_builtins builtin, const char *name) -{ - struct builtin_hash_struct h; - struct builtin_hash_struct *h2; - void **found; - int num_args = 3; - int i; - tree ret_type = NULL_TREE; - tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE }; - - /* Create builtin_hash_table. */ - if (builtin_hash_table == NULL) - builtin_hash_table = htab_create_ggc (1500, builtin_hash_function, - builtin_hash_eq, NULL); - - h.type = NULL_TREE; - h.mode[0] = mode_ret; - h.mode[1] = mode_arg0; - h.mode[2] = mode_arg1; - h.mode[3] = mode_arg2; - h.uns_p[0] = 0; - h.uns_p[1] = 0; - h.uns_p[2] = 0; - h.uns_p[3] = 0; - - /* If the builtin is a type that produces unsigned results or takes unsigned - arguments, and it is returned as a decl for the vectorizer (such as - widening multiplies, permute), make sure the arguments and return value - are type correct. */ - switch (builtin) - { - /* unsigned 2 argument functions. */ - case ALTIVEC_BUILTIN_VMULEUB_UNS: - case ALTIVEC_BUILTIN_VMULEUH_UNS: - case ALTIVEC_BUILTIN_VMULOUB_UNS: - case ALTIVEC_BUILTIN_VMULOUH_UNS: - h.uns_p[0] = 1; - h.uns_p[1] = 1; - h.uns_p[2] = 1; - break; - - /* unsigned 3 argument functions. */ - case ALTIVEC_BUILTIN_VPERM_16QI_UNS: - case ALTIVEC_BUILTIN_VPERM_8HI_UNS: - case ALTIVEC_BUILTIN_VPERM_4SI_UNS: - case ALTIVEC_BUILTIN_VPERM_2DI_UNS: - case ALTIVEC_BUILTIN_VSEL_16QI_UNS: - case ALTIVEC_BUILTIN_VSEL_8HI_UNS: - case ALTIVEC_BUILTIN_VSEL_4SI_UNS: - case ALTIVEC_BUILTIN_VSEL_2DI_UNS: - case VSX_BUILTIN_VPERM_16QI_UNS: - case VSX_BUILTIN_VPERM_8HI_UNS: - case VSX_BUILTIN_VPERM_4SI_UNS: - case VSX_BUILTIN_VPERM_2DI_UNS: - case VSX_BUILTIN_XXSEL_16QI_UNS: - case VSX_BUILTIN_XXSEL_8HI_UNS: - case VSX_BUILTIN_XXSEL_4SI_UNS: - case VSX_BUILTIN_XXSEL_2DI_UNS: - h.uns_p[0] = 1; - h.uns_p[1] = 1; - h.uns_p[2] = 1; - h.uns_p[3] = 1; - break; - - /* signed permute functions with unsigned char mask. */ - case ALTIVEC_BUILTIN_VPERM_16QI: - case ALTIVEC_BUILTIN_VPERM_8HI: - case ALTIVEC_BUILTIN_VPERM_4SI: - case ALTIVEC_BUILTIN_VPERM_4SF: - case ALTIVEC_BUILTIN_VPERM_2DI: - case ALTIVEC_BUILTIN_VPERM_2DF: - case VSX_BUILTIN_VPERM_16QI: - case VSX_BUILTIN_VPERM_8HI: - case VSX_BUILTIN_VPERM_4SI: - case VSX_BUILTIN_VPERM_4SF: - case VSX_BUILTIN_VPERM_2DI: - case VSX_BUILTIN_VPERM_2DF: - h.uns_p[3] = 1; - break; - - /* unsigned args, signed return. */ - case VSX_BUILTIN_XVCVUXDDP_UNS: - case ALTIVEC_BUILTIN_UNSFLOAT_V4SI_V4SF: - h.uns_p[1] = 1; - break; - - /* signed args, unsigned return. */ - case VSX_BUILTIN_XVCVDPUXDS_UNS: - case ALTIVEC_BUILTIN_FIXUNS_V4SF_V4SI: - h.uns_p[0] = 1; - break; - - default: - break; - } - - /* Figure out how many args are present. */ - while (num_args > 0 && h.mode[num_args] == VOIDmode) - num_args--; - - if (num_args == 0) - fatal_error ("internal error: builtin function %s had no type", name); - - ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]]; - if (!ret_type && h.uns_p[0]) - ret_type = builtin_mode_to_type[h.mode[0]][0]; - - if (!ret_type) - fatal_error ("internal error: builtin function %s had an unexpected " - "return type %s", name, GET_MODE_NAME (h.mode[0])); - - for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++) - arg_type[i] = NULL_TREE; - - for (i = 0; i < num_args; i++) - { - int m = (int) h.mode[i+1]; - int uns_p = h.uns_p[i+1]; - - arg_type[i] = builtin_mode_to_type[m][uns_p]; - if (!arg_type[i] && uns_p) - arg_type[i] = builtin_mode_to_type[m][0]; - - if (!arg_type[i]) - fatal_error ("internal error: builtin function %s, argument %d " - "had unexpected argument type %s", name, i, - GET_MODE_NAME (m)); - } - - found = htab_find_slot (builtin_hash_table, &h, INSERT); - if (*found == NULL) - { - h2 = ggc_alloc_builtin_hash_struct (); - *h2 = h; - *found = (void *)h2; - - h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1], - arg_type[2], NULL_TREE); - } - - return ((struct builtin_hash_struct *)(*found))->type; -} - -static void -rs6000_common_init_builtins (void) -{ - const struct builtin_description *d; - size_t i; - - tree opaque_ftype_opaque = NULL_TREE; - tree opaque_ftype_opaque_opaque = NULL_TREE; - tree opaque_ftype_opaque_opaque_opaque = NULL_TREE; - tree v2si_ftype_qi = NULL_TREE; - tree v2si_ftype_v2si_qi = NULL_TREE; - tree v2si_ftype_int_qi = NULL_TREE; - HOST_WIDE_INT builtin_mask = rs6000_builtin_mask; - - if (!TARGET_PAIRED_FLOAT) - { - builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node; - builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node; - } - - /* Paired and SPE builtins are only available if you build a compiler with - the appropriate options, so only create those builtins with the - appropriate compiler option. Create Altivec and VSX builtins on machines - with at least the general purpose extensions (970 and newer) to allow the - use of the target attribute.. */ - - if (TARGET_EXTRA_BUILTINS) - builtin_mask |= RS6000_BTM_COMMON; - - /* Add the ternary operators. */ - d = bdesc_3arg; - for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++) - { - tree type; - HOST_WIDE_INT mask = d->mask; - - if ((mask & builtin_mask) != mask) - { - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "rs6000_builtin, skip ternary %s\n", d->name); - continue; - } - - if (rs6000_overloaded_builtin_p (d->code)) - { - if (! (type = opaque_ftype_opaque_opaque_opaque)) - type = opaque_ftype_opaque_opaque_opaque - = build_function_type_list (opaque_V4SI_type_node, - opaque_V4SI_type_node, - opaque_V4SI_type_node, - opaque_V4SI_type_node, - NULL_TREE); - } - else - { - enum insn_code icode = d->icode; - if (d->name == 0 || icode == CODE_FOR_nothing) - continue; - - type = builtin_function_type (insn_data[icode].operand[0].mode, - insn_data[icode].operand[1].mode, - insn_data[icode].operand[2].mode, - insn_data[icode].operand[3].mode, - d->code, d->name); - } - - def_builtin (d->name, type, d->code); - } - - /* Add the binary operators. */ - d = bdesc_2arg; - for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++) - { - enum machine_mode mode0, mode1, mode2; - tree type; - HOST_WIDE_INT mask = d->mask; - - if ((mask & builtin_mask) != mask) - { - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "rs6000_builtin, skip binary %s\n", d->name); - continue; - } - - if (rs6000_overloaded_builtin_p (d->code)) - { - if (! (type = opaque_ftype_opaque_opaque)) - type = opaque_ftype_opaque_opaque - = build_function_type_list (opaque_V4SI_type_node, - opaque_V4SI_type_node, - opaque_V4SI_type_node, - NULL_TREE); - } - else - { - enum insn_code icode = d->icode; - if (d->name == 0 || icode == CODE_FOR_nothing) - continue; - - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; - mode2 = insn_data[icode].operand[2].mode; - - if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode) - { - if (! (type = v2si_ftype_v2si_qi)) - type = v2si_ftype_v2si_qi - = build_function_type_list (opaque_V2SI_type_node, - opaque_V2SI_type_node, - char_type_node, - NULL_TREE); - } - - else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT - && mode2 == QImode) - { - if (! (type = v2si_ftype_int_qi)) - type = v2si_ftype_int_qi - = build_function_type_list (opaque_V2SI_type_node, - integer_type_node, - char_type_node, - NULL_TREE); - } - - else - type = builtin_function_type (mode0, mode1, mode2, VOIDmode, - d->code, d->name); - } - - def_builtin (d->name, type, d->code); - } - - /* Add the simple unary operators. */ - d = bdesc_1arg; - for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++) - { - enum machine_mode mode0, mode1; - tree type; - HOST_WIDE_INT mask = d->mask; - - if ((mask & builtin_mask) != mask) - { - if (TARGET_DEBUG_BUILTIN) - fprintf (stderr, "rs6000_builtin, skip unary %s\n", d->name); - continue; - } - - if (rs6000_overloaded_builtin_p (d->code)) - { - if (! (type = opaque_ftype_opaque)) - type = opaque_ftype_opaque - = build_function_type_list (opaque_V4SI_type_node, - opaque_V4SI_type_node, - NULL_TREE); - } - else - { - enum insn_code icode = d->icode; - if (d->name == 0 || icode == CODE_FOR_nothing) - continue; - - mode0 = insn_data[icode].operand[0].mode; - mode1 = insn_data[icode].operand[1].mode; - - if (mode0 == V2SImode && mode1 == QImode) - { - if (! (type = v2si_ftype_qi)) - type = v2si_ftype_qi - = build_function_type_list (opaque_V2SI_type_node, - char_type_node, - NULL_TREE); - } - - else - type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode, - d->code, d->name); - } - - def_builtin (d->name, type, d->code); - } -} - -static void -rs6000_init_libfuncs (void) -{ - if (!TARGET_IEEEQUAD) - /* AIX/Darwin/64-bit Linux quad floating point routines. */ - if (!TARGET_XL_COMPAT) - { - set_optab_libfunc (add_optab, TFmode, "__gcc_qadd"); - set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub"); - set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul"); - set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv"); - - if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE))) - { - set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg"); - set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq"); - set_optab_libfunc (ne_optab, TFmode, "__gcc_qne"); - set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt"); - set_optab_libfunc (ge_optab, TFmode, "__gcc_qge"); - set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt"); - set_optab_libfunc (le_optab, TFmode, "__gcc_qle"); - - set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq"); - set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq"); - set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos"); - set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod"); - set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi"); - set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou"); - set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq"); - set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq"); - } - - if (!(TARGET_HARD_FLOAT && TARGET_FPRS)) - set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord"); - } - else - { - 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) - 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"); - set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq"); - } -} - - -/* Expand a block clear operation, and return 1 if successful. Return 0 - if we should let the compiler generate normal code. - - operands[0] is the destination - operands[1] is the length - operands[3] is the alignment */ - -int -expand_block_clear (rtx operands[]) -{ - rtx orig_dest = operands[0]; - rtx bytes_rtx = operands[1]; - rtx align_rtx = operands[3]; - bool constp = (GET_CODE (bytes_rtx) == CONST_INT); - HOST_WIDE_INT align; - HOST_WIDE_INT bytes; - int offset; - int clear_bytes; - int clear_step; - - /* If this is not a fixed size move, just call memcpy */ - if (! constp) - return 0; - - /* This must be a fixed size alignment */ - gcc_assert (GET_CODE (align_rtx) == CONST_INT); - align = INTVAL (align_rtx) * BITS_PER_UNIT; - - /* Anything to clear? */ - bytes = INTVAL (bytes_rtx); - if (bytes <= 0) - return 1; - - /* Use the builtin memset after a point, to avoid huge code bloat. - When optimize_size, avoid any significant code bloat; calling - memset is about 4 instructions, so allow for one instruction to - load zero and three to do clearing. */ - if (TARGET_ALTIVEC && align >= 128) - clear_step = 16; - else if (TARGET_POWERPC64 && align >= 32) - clear_step = 8; - else if (TARGET_SPE && align >= 64) - clear_step = 8; - else - clear_step = 4; - - if (optimize_size && bytes > 3 * clear_step) - return 0; - if (! optimize_size && bytes > 8 * clear_step) - return 0; - - for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes) - { - enum machine_mode mode = BLKmode; - rtx dest; - - if (bytes >= 16 && TARGET_ALTIVEC && align >= 128) - { - clear_bytes = 16; - mode = V4SImode; - } - else if (bytes >= 8 && TARGET_SPE && align >= 64) - { - clear_bytes = 8; - mode = V2SImode; - } - else if (bytes >= 8 && TARGET_POWERPC64 - /* 64-bit loads and stores require word-aligned - displacements. */ - && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32))) - { - clear_bytes = 8; - mode = DImode; - } - else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT)) - { /* move 4 bytes */ - clear_bytes = 4; - mode = SImode; - } - else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT)) - { /* move 2 bytes */ - clear_bytes = 2; - mode = HImode; - } - else /* move 1 byte at a time */ - { - clear_bytes = 1; - mode = QImode; - } - - dest = adjust_address (orig_dest, mode, offset); - - emit_move_insn (dest, CONST0_RTX (mode)); - } - - return 1; -} - - -/* Expand a block move operation, and return 1 if successful. Return 0 - if we should let the compiler generate normal code. - - operands[0] is the destination - operands[1] is the source - operands[2] is the length - operands[3] is the alignment */ - -#define MAX_MOVE_REG 4 - -int -expand_block_move (rtx operands[]) -{ - rtx orig_dest = operands[0]; - rtx orig_src = operands[1]; - rtx bytes_rtx = operands[2]; - rtx align_rtx = operands[3]; - int constp = (GET_CODE (bytes_rtx) == CONST_INT); - int align; - 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) - return 0; - - /* This must be a fixed size alignment */ - gcc_assert (GET_CODE (align_rtx) == CONST_INT); - align = INTVAL (align_rtx) * BITS_PER_UNIT; - - /* Anything to move? */ - bytes = INTVAL (bytes_rtx); - if (bytes <= 0) - return 1; - - if (bytes > rs6000_block_move_inline_limit) - return 0; - - for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes) - { - union { - rtx (*movmemsi) (rtx, rtx, rtx, rtx); - rtx (*mov) (rtx, rtx); - } gen_func; - enum machine_mode mode = BLKmode; - rtx src, dest; - - /* Altivec first, since it will be faster than a string move - when it applies, and usually not significantly larger. */ - if (TARGET_ALTIVEC && bytes >= 16 && align >= 128) - { - move_bytes = 16; - mode = V4SImode; - gen_func.mov = gen_movv4si; - } - else if (TARGET_SPE && bytes >= 8 && align >= 64) - { - move_bytes = 8; - mode = V2SImode; - gen_func.mov = gen_movv2si; - } - else 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.movmemsi = gen_movmemsi_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.movmemsi = gen_movmemsi_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.movmemsi = gen_movmemsi_4reg; - } - else if (bytes >= 8 && TARGET_POWERPC64 - /* 64-bit loads and stores require word-aligned - displacements. */ - && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32))) - { - 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.movmemsi = gen_movmemsi_2reg; - } - else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT)) - { /* move 4 bytes */ - move_bytes = 4; - mode = SImode; - gen_func.mov = gen_movsi; - } - else if (bytes >= 2 && (align >= 16 || !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.movmemsi = gen_movmemsi_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); - } - - if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes) - { - int i; - for (i = 0; i < num_reg; i++) - emit_insn (stores[i]); - num_reg = 0; - } - - if (mode == BLKmode) - { - /* Move the address into scratch registers. The movmemsi - 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, 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, move_bytes); - - emit_insn ((*gen_func.movmemsi) (dest, src, - GEN_INT (move_bytes & 31), - align_rtx)); - } - } - - return 1; -} - - -/* Return a string to perform a load_multiple operation. - operands[0] is the vector. - operands[1] is the source address. - operands[2] is the first destination register. */ - -const char * -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. */ - int i, j; - int words = XVECLEN (operands[0], 0); - rtx xop[10]; - - if (XVECLEN (operands[0], 0) == 1) - return "lwz %2,0(%1)"; - - for (i = 0; i < words; i++) - if (refers_to_regno_p (REGNO (operands[2]) + i, - REGNO (operands[2]) + i + 1, operands[1], 0)) - { - if (i == words-1) - { - xop[0] = GEN_INT (4 * (words-1)); - xop[1] = operands[1]; - xop[2] = operands[2]; - output_asm_insn ("lswi %2,%1,%0\n\tlwz %1,%0(%1)", xop); - return ""; - } - else if (i == 0) - { - xop[0] = GEN_INT (4 * (words-1)); - xop[1] = operands[1]; - xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1); - output_asm_insn ("addi %1,%1,4\n\tlswi %2,%1,%0\n\tlwz %1,-4(%1)", xop); - return ""; - } - else - { - for (j = 0; j < words; j++) - if (j != i) - { - xop[0] = GEN_INT (j * 4); - xop[1] = operands[1]; - xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j); - output_asm_insn ("lwz %2,%0(%1)", xop); - } - xop[0] = GEN_INT (i * 4); - xop[1] = operands[1]; - output_asm_insn ("lwz %1,%0(%1)", xop); - return ""; - } - } - - return "lswi %2,%1,%N0"; -} - - -/* A validation routine: say whether CODE, a condition code, and MODE - match. The other alternatives either don't make sense or should - never be generated. */ - -void -validate_condition_mode (enum rtx_code code, enum machine_mode mode) -{ - gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE - || GET_RTX_CLASS (code) == RTX_COMM_COMPARE) - && GET_MODE_CLASS (mode) == MODE_CC); - - /* These don't make sense. */ - gcc_assert ((code != GT && code != LT && code != GE && code != LE) - || mode != CCUNSmode); - - gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU) - || mode == CCUNSmode); - - gcc_assert (mode == CCFPmode - || (code != ORDERED && code != UNORDERED - && code != UNEQ && code != LTGT - && code != UNGT && code != UNLT - && code != UNGE && code != UNLE)); - - /* These should never be generated except for - flag_finite_math_only. */ - gcc_assert (mode != CCFPmode - || flag_finite_math_only - || (code != LE && code != GE - && code != UNEQ && code != LTGT - && code != UNGT && code != UNLT)); - - /* These are invalid; the information is not there. */ - gcc_assert (mode != CCEQmode || code == EQ || code == NE); -} - - -/* Return 1 if ANDOP is a mask that has no bits on that are not in the - mask required to convert the result of a rotate insn into a shift - left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */ - -int -includes_lshift_p (rtx shiftop, rtx andop) -{ - unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0; - - shift_mask <<= INTVAL (shiftop); - - return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0; -} - -/* Similar, but for right shift. */ - -int -includes_rshift_p (rtx shiftop, rtx andop) -{ - unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0; - - shift_mask >>= INTVAL (shiftop); - - return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0; -} - -/* 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 - significant 0's, then one or more 1's, then zero or more 0's. */ - -int -includes_rldic_lshift_p (rtx shiftop, rtx andop) -{ - if (GET_CODE (andop) == CONST_INT) - { - HOST_WIDE_INT c, lsb, shift_mask; - - c = INTVAL (andop); - if (c == 0 || c == ~0) - return 0; - - shift_mask = ~0; - shift_mask <<= INTVAL (shiftop); - - /* Find the least significant one bit. */ - lsb = c & -c; - - /* It must coincide with the LSB of the shift mask. */ - if (-lsb != shift_mask) - return 0; - - /* Invert to look for the next transition (if any). */ - c = ~c; - - /* Remove the low group of ones (originally low group of zeros). */ - c &= -lsb; - - /* Again find the lsb, and check we have all 1's above. */ - lsb = c & -c; - return c == -lsb; - } - else if (GET_CODE (andop) == CONST_DOUBLE - && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode)) - { - HOST_WIDE_INT low, high, lsb; - HOST_WIDE_INT shift_mask_low, shift_mask_high; - - low = CONST_DOUBLE_LOW (andop); - if (HOST_BITS_PER_WIDE_INT < 64) - high = CONST_DOUBLE_HIGH (andop); - - if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0)) - || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0))) - return 0; - - if (HOST_BITS_PER_WIDE_INT < 64 && low == 0) - { - shift_mask_high = ~0; - if (INTVAL (shiftop) > 32) - shift_mask_high <<= INTVAL (shiftop) - 32; - - lsb = high & -high; - - if (-lsb != shift_mask_high || INTVAL (shiftop) < 32) - return 0; - - high = ~high; - high &= -lsb; - - lsb = high & -high; - return high == -lsb; - } - - shift_mask_low = ~0; - shift_mask_low <<= INTVAL (shiftop); - - lsb = low & -low; - - if (-lsb != shift_mask_low) - return 0; - - if (HOST_BITS_PER_WIDE_INT < 64) - high = ~high; - low = ~low; - low &= -lsb; - - if (HOST_BITS_PER_WIDE_INT < 64 && low == 0) - { - lsb = high & -high; - return high == -lsb; - } - - lsb = low & -low; - return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0); - } - else - return 0; -} - -/* 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 - significant 0's, with the remainder of the word 1's. */ - -int -includes_rldicr_lshift_p (rtx shiftop, rtx andop) -{ - if (GET_CODE (andop) == CONST_INT) - { - HOST_WIDE_INT c, lsb, shift_mask; - - shift_mask = ~0; - shift_mask <<= INTVAL (shiftop); - c = INTVAL (andop); - - /* Find the least significant one bit. */ - lsb = c & -c; - - /* It must be covered by the shift mask. - This test also rejects c == 0. */ - if ((lsb & shift_mask) == 0) - return 0; - - /* Check we have all 1's above the transition, and reject all 1's. */ - return c == -lsb && lsb != 1; - } - else if (GET_CODE (andop) == CONST_DOUBLE - && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode)) - { - HOST_WIDE_INT low, lsb, shift_mask_low; - - low = CONST_DOUBLE_LOW (andop); - - if (HOST_BITS_PER_WIDE_INT < 64) - { - HOST_WIDE_INT high, shift_mask_high; - - high = CONST_DOUBLE_HIGH (andop); - - if (low == 0) - { - shift_mask_high = ~0; - if (INTVAL (shiftop) > 32) - shift_mask_high <<= INTVAL (shiftop) - 32; - - lsb = high & -high; - - if ((lsb & shift_mask_high) == 0) - return 0; - - return high == -lsb; - } - if (high != ~0) - return 0; - } - - shift_mask_low = ~0; - shift_mask_low <<= INTVAL (shiftop); - - lsb = low & -low; - - if ((lsb & shift_mask_low) == 0) - return 0; - - return low == -lsb && lsb != 1; - } - else - return 0; -} - -/* Return 1 if operands will generate a valid arguments to rlwimi -instruction for insert with right shift in 64-bit mode. The mask may -not start on the first bit or stop on the last bit because wrap-around -effects of instruction do not correspond to semantics of RTL insn. */ - -int -insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop) -{ - if (INTVAL (startop) > 32 - && INTVAL (startop) < 64 - && INTVAL (sizeop) > 1 - && INTVAL (sizeop) + INTVAL (startop) < 64 - && INTVAL (shiftop) > 0 - && INTVAL (sizeop) + INTVAL (shiftop) < 32 - && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop)) - return 1; - - return 0; -} - -/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates - for lfq and stfq insns iff the registers are hard registers. */ - -int -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) - return 0; - - /* We might have been passed non floating point registers. */ - if (!FP_REGNO_P (REGNO (reg1)) - || !FP_REGNO_P (REGNO (reg2))) - return 0; - - return (REGNO (reg1) == REGNO (reg2) - 1); -} - -/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn. - addr1 and addr2 must be in consecutive memory locations - (addr2 == addr1 + 8). */ - -int -mems_ok_for_quad_peep (rtx mem1, rtx mem2) -{ - rtx addr1, addr2; - unsigned int reg1, reg2; - int offset1, offset2; - - /* The mems cannot be volatile. */ - if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2)) - return 0; - - addr1 = XEXP (mem1, 0); - addr2 = XEXP (mem2, 0); - - /* Extract an offset (if used) from the first addr. */ - if (GET_CODE (addr1) == PLUS) - { - /* If not a REG, return zero. */ - if (GET_CODE (XEXP (addr1, 0)) != REG) - return 0; - else - { - reg1 = REGNO (XEXP (addr1, 0)); - /* The offset must be constant! */ - if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) - return 0; - offset1 = INTVAL (XEXP (addr1, 1)); - } - } - else if (GET_CODE (addr1) != REG) - return 0; - else - { - reg1 = REGNO (addr1); - /* This was a simple (mem (reg)) expression. Offset is 0. */ - offset1 = 0; - } - - /* And now for the second addr. */ - if (GET_CODE (addr2) == PLUS) - { - /* If not a REG, return zero. */ - if (GET_CODE (XEXP (addr2, 0)) != REG) - return 0; - else - { - reg2 = REGNO (XEXP (addr2, 0)); - /* The offset must be constant. */ - if (GET_CODE (XEXP (addr2, 1)) != CONST_INT) - return 0; - offset2 = INTVAL (XEXP (addr2, 1)); - } - } - else if (GET_CODE (addr2) != REG) - return 0; - else - { - reg2 = REGNO (addr2); - /* This was a simple (mem (reg)) expression. Offset is 0. */ - offset2 = 0; - } - - /* Both of these must have the same base register. */ - if (reg1 != reg2) - return 0; - - /* The offset for the second addr must be 8 more than the first addr. */ - if (offset2 != offset1 + 8) - return 0; - - /* All the tests passed. addr1 and addr2 are valid for lfq or stfq - instructions. */ - return 1; -} - - -rtx -rs6000_secondary_memory_needed_rtx (enum machine_mode mode) -{ - static bool eliminated = false; - rtx ret; - - if (mode != SDmode) - ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); - else - { - rtx mem = cfun->machine->sdmode_stack_slot; - gcc_assert (mem != NULL_RTX); - - if (!eliminated) - { - mem = eliminate_regs (mem, VOIDmode, NULL_RTX); - cfun->machine->sdmode_stack_slot = mem; - eliminated = true; - } - ret = mem; - } - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n", - GET_MODE_NAME (mode)); - if (!ret) - fprintf (stderr, "\tNULL_RTX\n"); - else - debug_rtx (ret); - } - - return ret; -} - -static tree -rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) -{ - /* Don't walk into types. */ - if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp)) - { - *walk_subtrees = 0; - return NULL_TREE; - } - - switch (TREE_CODE (*tp)) - { - case VAR_DECL: - case PARM_DECL: - case FIELD_DECL: - case RESULT_DECL: - case SSA_NAME: - case REAL_CST: - case MEM_REF: - case VIEW_CONVERT_EXPR: - if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode) - return *tp; - break; - default: - break; - } - - return NULL_TREE; -} - -enum reload_reg_type { - GPR_REGISTER_TYPE, - VECTOR_REGISTER_TYPE, - OTHER_REGISTER_TYPE -}; - -static enum reload_reg_type -rs6000_reload_register_type (enum reg_class rclass) -{ - switch (rclass) - { - case GENERAL_REGS: - case BASE_REGS: - return GPR_REGISTER_TYPE; - - case FLOAT_REGS: - case ALTIVEC_REGS: - case VSX_REGS: - return VECTOR_REGISTER_TYPE; - - default: - return OTHER_REGISTER_TYPE; - } -} - -/* Inform reload about cases where moving X with a mode MODE to a register in - RCLASS requires an extra scratch or immediate register. Return the class - needed for the immediate register. - - For VSX and Altivec, we may need a register to convert sp+offset into - reg+sp. - - For misaligned 64-bit gpr loads and stores we need a register to - convert an offset address to indirect. */ - -static reg_class_t -rs6000_secondary_reload (bool in_p, - rtx x, - reg_class_t rclass_i, - enum machine_mode mode, - secondary_reload_info *sri) -{ - enum reg_class rclass = (enum reg_class) rclass_i; - reg_class_t ret = ALL_REGS; - enum insn_code icode; - bool default_p = false; - - sri->icode = CODE_FOR_nothing; - - /* Convert vector loads and stores into gprs to use an additional base - register. */ - icode = rs6000_vector_reload[mode][in_p != false]; - if (icode != CODE_FOR_nothing) - { - ret = NO_REGS; - sri->icode = CODE_FOR_nothing; - sri->extra_cost = 0; - - if (GET_CODE (x) == MEM) - { - rtx addr = XEXP (x, 0); - - /* Loads to and stores from gprs can do reg+offset, and wouldn't need - an extra register in that case, but it would need an extra - register if the addressing is reg+reg or (reg+reg)&(-16). */ - if (rclass == GENERAL_REGS || rclass == BASE_REGS) - { - if (!legitimate_indirect_address_p (addr, false) - && !rs6000_legitimate_offset_address_p (TImode, addr, - false, true)) - { - sri->icode = icode; - /* account for splitting the loads, and converting the - address from reg+reg to reg. */ - sri->extra_cost = (((TARGET_64BIT) ? 3 : 5) - + ((GET_CODE (addr) == AND) ? 1 : 0)); - } - } - /* Loads to and stores from vector registers can only do reg+reg - addressing. Altivec registers can also do (reg+reg)&(-16). */ - else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS - || rclass == FLOAT_REGS || rclass == NO_REGS) - { - if (!VECTOR_MEM_ALTIVEC_P (mode) - && GET_CODE (addr) == AND - && GET_CODE (XEXP (addr, 1)) == CONST_INT - && INTVAL (XEXP (addr, 1)) == -16 - && (legitimate_indirect_address_p (XEXP (addr, 0), false) - || legitimate_indexed_address_p (XEXP (addr, 0), false))) - { - sri->icode = icode; - sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS) - ? 2 : 1); - } - else if (!legitimate_indirect_address_p (addr, false) - && (rclass == NO_REGS - || !legitimate_indexed_address_p (addr, false))) - { - sri->icode = icode; - sri->extra_cost = 1; - } - else - icode = CODE_FOR_nothing; - } - /* Any other loads, including to pseudo registers which haven't been - assigned to a register yet, default to require a scratch - register. */ - else - { - sri->icode = icode; - sri->extra_cost = 2; - } - } - else if (REG_P (x)) - { - int regno = true_regnum (x); - - icode = CODE_FOR_nothing; - if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER) - default_p = true; - else - { - enum reg_class xclass = REGNO_REG_CLASS (regno); - enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass); - enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass); - - /* If memory is needed, use default_secondary_reload to create the - stack slot. */ - if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE) - default_p = true; - else - ret = NO_REGS; - } - } - else - default_p = true; - } - else if (TARGET_POWERPC64 - && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE - && MEM_P (x) - && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD) - { - rtx addr = XEXP (x, 0); - rtx off = address_offset (addr); - - if (off != NULL_RTX) - { - unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD; - unsigned HOST_WIDE_INT offset = INTVAL (off); - - /* We need a secondary reload when our legitimate_address_p - says the address is good (as otherwise the entire address - will be reloaded), and the offset is not a multiple of - four or we have an address wrap. Address wrap will only - occur for LO_SUMs since legitimate_offset_address_p - rejects addresses for 16-byte mems that will wrap. */ - if (GET_CODE (addr) == LO_SUM - ? (1 /* legitimate_address_p allows any offset for lo_sum */ - && ((offset & 3) != 0 - || ((offset & 0xffff) ^ 0x8000) >= 0x10000 - extra)) - : (offset + 0x8000 < 0x10000 - extra /* legitimate_address_p */ - && (offset & 3) != 0)) - { - if (in_p) - sri->icode = CODE_FOR_reload_di_load; - else - sri->icode = CODE_FOR_reload_di_store; - sri->extra_cost = 2; - ret = NO_REGS; - } - else - default_p = true; - } - else - default_p = true; - } - else if (!TARGET_POWERPC64 - && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE - && MEM_P (x) - && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) - { - rtx addr = XEXP (x, 0); - rtx off = address_offset (addr); - - if (off != NULL_RTX) - { - unsigned int extra = GET_MODE_SIZE (GET_MODE (x)) - UNITS_PER_WORD; - unsigned HOST_WIDE_INT offset = INTVAL (off); - - /* We need a secondary reload when our legitimate_address_p - says the address is good (as otherwise the entire address - will be reloaded), and we have a wrap. - - legitimate_lo_sum_address_p allows LO_SUM addresses to - have any offset so test for wrap in the low 16 bits. - - legitimate_offset_address_p checks for the range - [-0x8000,0x7fff] for mode size of 8 and [-0x8000,0x7ff7] - for mode size of 16. We wrap at [0x7ffc,0x7fff] and - [0x7ff4,0x7fff] respectively, so test for the - intersection of these ranges, [0x7ffc,0x7fff] and - [0x7ff4,0x7ff7] respectively. - - Note that the address we see here may have been - manipulated by legitimize_reload_address. */ - if (GET_CODE (addr) == LO_SUM - ? ((offset & 0xffff) ^ 0x8000) >= 0x10000 - extra - : offset - (0x8000 - extra) < UNITS_PER_WORD) - { - if (in_p) - sri->icode = CODE_FOR_reload_si_load; - else - sri->icode = CODE_FOR_reload_si_store; - sri->extra_cost = 2; - ret = NO_REGS; - } - else - default_p = true; - } - else - default_p = true; - } - else - default_p = true; - - if (default_p) - ret = default_secondary_reload (in_p, x, rclass, mode, sri); - - gcc_assert (ret != ALL_REGS); - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, - "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, " - "mode = %s", - reg_class_names[ret], - in_p ? "true" : "false", - reg_class_names[rclass], - GET_MODE_NAME (mode)); - - if (default_p) - fprintf (stderr, ", default secondary reload"); - - if (sri->icode != CODE_FOR_nothing) - fprintf (stderr, ", reload func = %s, extra cost = %d\n", - insn_data[sri->icode].name, sri->extra_cost); - else - fprintf (stderr, "\n"); - - debug_rtx (x); - } - - return ret; -} - -/* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset - to SP+reg addressing. */ - -void -rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p) -{ - int regno = true_regnum (reg); - enum machine_mode mode = GET_MODE (reg); - enum reg_class rclass; - rtx addr; - rtx and_op2 = NULL_RTX; - rtx addr_op1; - rtx addr_op2; - rtx scratch_or_premodify = scratch; - rtx and_rtx; - rtx cc_clobber; - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n", - store_p ? "store" : "load"); - fprintf (stderr, "reg:\n"); - debug_rtx (reg); - fprintf (stderr, "mem:\n"); - debug_rtx (mem); - fprintf (stderr, "scratch:\n"); - debug_rtx (scratch); - } - - gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER); - gcc_assert (GET_CODE (mem) == MEM); - rclass = REGNO_REG_CLASS (regno); - addr = XEXP (mem, 0); - - switch (rclass) - { - /* GPRs can handle reg + small constant, all other addresses need to use - the scratch register. */ - case GENERAL_REGS: - case BASE_REGS: - if (GET_CODE (addr) == AND) - { - and_op2 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - - if (GET_CODE (addr) == PRE_MODIFY) - { - scratch_or_premodify = XEXP (addr, 0); - gcc_assert (REG_P (scratch_or_premodify)); - gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS); - addr = XEXP (addr, 1); - } - - if (GET_CODE (addr) == PLUS - && (and_op2 != NULL_RTX - || !rs6000_legitimate_offset_address_p (TImode, addr, - false, true))) - { - addr_op1 = XEXP (addr, 0); - addr_op2 = XEXP (addr, 1); - gcc_assert (legitimate_indirect_address_p (addr_op1, false)); - - if (!REG_P (addr_op2) - && (GET_CODE (addr_op2) != CONST_INT - || !satisfies_constraint_I (addr_op2))) - { - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, - "\nMove plus addr to register %s, mode = %s: ", - rs6000_reg_names[REGNO (scratch)], - GET_MODE_NAME (mode)); - debug_rtx (addr_op2); - } - rs6000_emit_move (scratch, addr_op2, Pmode); - addr_op2 = scratch; - } - - emit_insn (gen_rtx_SET (VOIDmode, - scratch_or_premodify, - gen_rtx_PLUS (Pmode, - addr_op1, - addr_op2))); - - addr = scratch_or_premodify; - scratch_or_premodify = scratch; - } - else if (!legitimate_indirect_address_p (addr, false) - && !rs6000_legitimate_offset_address_p (TImode, addr, - false, true)) - { - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nMove addr to register %s, mode = %s: ", - rs6000_reg_names[REGNO (scratch_or_premodify)], - GET_MODE_NAME (mode)); - debug_rtx (addr); - } - rs6000_emit_move (scratch_or_premodify, addr, Pmode); - addr = scratch_or_premodify; - scratch_or_premodify = scratch; - } - break; - - /* Float/Altivec registers can only handle reg+reg addressing. Move - other addresses into a scratch register. */ - case FLOAT_REGS: - case VSX_REGS: - case ALTIVEC_REGS: - - /* With float regs, we need to handle the AND ourselves, since we can't - use the Altivec instruction with an implicit AND -16. Allow scalar - loads to float registers to use reg+offset even if VSX. */ - if (GET_CODE (addr) == AND - && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16 - || GET_CODE (XEXP (addr, 1)) != CONST_INT - || INTVAL (XEXP (addr, 1)) != -16 - || !VECTOR_MEM_ALTIVEC_P (mode))) - { - and_op2 = XEXP (addr, 1); - addr = XEXP (addr, 0); - } - - /* If we aren't using a VSX load, save the PRE_MODIFY register and use it - as the address later. */ - if (GET_CODE (addr) == PRE_MODIFY - && (!VECTOR_MEM_VSX_P (mode) - || and_op2 != NULL_RTX - || !legitimate_indexed_address_p (XEXP (addr, 1), false))) - { - scratch_or_premodify = XEXP (addr, 0); - gcc_assert (legitimate_indirect_address_p (scratch_or_premodify, - false)); - gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS); - addr = XEXP (addr, 1); - } - - if (legitimate_indirect_address_p (addr, false) /* reg */ - || legitimate_indexed_address_p (addr, false) /* reg+reg */ - || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */ - || (GET_CODE (addr) == AND /* Altivec memory */ - && GET_CODE (XEXP (addr, 1)) == CONST_INT - && INTVAL (XEXP (addr, 1)) == -16 - && VECTOR_MEM_ALTIVEC_P (mode)) - || (rclass == FLOAT_REGS /* legacy float mem */ - && GET_MODE_SIZE (mode) == 8 - && and_op2 == NULL_RTX - && scratch_or_premodify == scratch - && rs6000_legitimate_offset_address_p (mode, addr, false, false))) - ; - - else if (GET_CODE (addr) == PLUS) - { - addr_op1 = XEXP (addr, 0); - addr_op2 = XEXP (addr, 1); - gcc_assert (REG_P (addr_op1)); - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ", - rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode)); - debug_rtx (addr_op2); - } - rs6000_emit_move (scratch, addr_op2, Pmode); - emit_insn (gen_rtx_SET (VOIDmode, - scratch_or_premodify, - gen_rtx_PLUS (Pmode, - addr_op1, - scratch))); - addr = scratch_or_premodify; - scratch_or_premodify = scratch; - } - - else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST - || GET_CODE (addr) == CONST_INT || REG_P (addr)) - { - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nMove addr to register %s, mode = %s: ", - rs6000_reg_names[REGNO (scratch_or_premodify)], - GET_MODE_NAME (mode)); - debug_rtx (addr); - } - - rs6000_emit_move (scratch_or_premodify, addr, Pmode); - addr = scratch_or_premodify; - scratch_or_premodify = scratch; - } - - else - gcc_unreachable (); - - break; - - default: - gcc_unreachable (); - } - - /* If the original address involved a pre-modify that we couldn't use the VSX - memory instruction with update, and we haven't taken care of already, - store the address in the pre-modify register and use that as the - address. */ - if (scratch_or_premodify != scratch && scratch_or_premodify != addr) - { - emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr)); - addr = scratch_or_premodify; - } - - /* If the original address involved an AND -16 and we couldn't use an ALTIVEC - memory instruction, recreate the AND now, including the clobber which is - generated by the general ANDSI3/ANDDI3 patterns for the - andi. instruction. */ - if (and_op2 != NULL_RTX) - { - if (! legitimate_indirect_address_p (addr, false)) - { - emit_insn (gen_rtx_SET (VOIDmode, scratch, addr)); - addr = scratch; - } - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nAnd addr to register %s, mode = %s: ", - rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode)); - debug_rtx (and_op2); - } - - and_rtx = gen_rtx_SET (VOIDmode, - scratch, - gen_rtx_AND (Pmode, - addr, - and_op2)); - - cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode)); - emit_insn (gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (2, and_rtx, cc_clobber))); - addr = scratch; - } - - /* Adjust the address if it changed. */ - if (addr != XEXP (mem, 0)) - { - mem = change_address (mem, mode, addr); - if (TARGET_DEBUG_ADDR) - fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n"); - } - - /* Now create the move. */ - if (store_p) - emit_insn (gen_rtx_SET (VOIDmode, mem, reg)); - else - emit_insn (gen_rtx_SET (VOIDmode, reg, mem)); - - return; -} - -/* Convert reloads involving 64-bit gprs and misaligned offset - addressing, or multiple 32-bit gprs and offsets that are too large, - to use indirect addressing. */ - -void -rs6000_secondary_reload_gpr (rtx reg, rtx mem, rtx scratch, bool store_p) -{ - int regno = true_regnum (reg); - enum reg_class rclass; - rtx addr; - rtx scratch_or_premodify = scratch; - - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nrs6000_secondary_reload_gpr, type = %s\n", - store_p ? "store" : "load"); - fprintf (stderr, "reg:\n"); - debug_rtx (reg); - fprintf (stderr, "mem:\n"); - debug_rtx (mem); - fprintf (stderr, "scratch:\n"); - debug_rtx (scratch); - } - - gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER); - gcc_assert (GET_CODE (mem) == MEM); - rclass = REGNO_REG_CLASS (regno); - gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS); - addr = XEXP (mem, 0); - - if (GET_CODE (addr) == PRE_MODIFY) - { - scratch_or_premodify = XEXP (addr, 0); - gcc_assert (REG_P (scratch_or_premodify)); - addr = XEXP (addr, 1); - } - gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); - - rs6000_emit_move (scratch_or_premodify, addr, Pmode); - - mem = replace_equiv_address_nv (mem, scratch_or_premodify); - - /* Now create the move. */ - if (store_p) - emit_insn (gen_rtx_SET (VOIDmode, mem, reg)); - else - emit_insn (gen_rtx_SET (VOIDmode, reg, mem)); - - return; -} - -/* Allocate a 64-bit stack slot to be used for copying SDmode - values through if this function has any SDmode references. */ - -static void -rs6000_alloc_sdmode_stack_slot (void) -{ - tree t; - basic_block bb; - gimple_stmt_iterator gsi; - - gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX); - - FOR_EACH_BB (bb) - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL); - if (ret) - { - rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0); - cfun->machine->sdmode_stack_slot = adjust_address_nv (stack, - SDmode, 0); - return; - } - } - - /* Check for any SDmode parameters of the function. */ - for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t)) - { - if (TREE_TYPE (t) == error_mark_node) - continue; - - if (TYPE_MODE (TREE_TYPE (t)) == SDmode - || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode) - { - rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0); - cfun->machine->sdmode_stack_slot = adjust_address_nv (stack, - SDmode, 0); - return; - } - } -} - -static void -rs6000_instantiate_decls (void) -{ - if (cfun->machine->sdmode_stack_slot != NULL_RTX) - instantiate_decl_rtl (cfun->machine->sdmode_stack_slot); -} - -/* 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 - in some cases it is preferable to use a more restrictive class. - - On the RS/6000, we have to return NO_REGS when we want to reload a - floating-point CONST_DOUBLE to force it to be copied to memory. - - We also don't want to reload integer values into floating-point - registers if we can at all help it. In fact, this can - cause reload to die, if it tries to generate a reload of CTR - into a FP register and discovers it doesn't have the memory location - required. - - ??? Would it be a good idea to have reload do the converse, that is - try to reload floating modes into FP registers if possible? - */ - -static enum reg_class -rs6000_preferred_reload_class (rtx x, enum reg_class rclass) -{ - enum machine_mode mode = GET_MODE (x); - - if (VECTOR_UNIT_VSX_P (mode) - && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass)) - return rclass; - - if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode) - && (rclass == ALTIVEC_REGS || rclass == VSX_REGS) - && easy_vector_constant (x, mode)) - return ALTIVEC_REGS; - - if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS)) - return NO_REGS; - - if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS) - return GENERAL_REGS; - - /* For VSX, prefer the traditional registers for 64-bit values because we can - use the non-VSX loads. Prefer the Altivec registers if Altivec is - handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we - prefer Altivec loads.. */ - if (rclass == VSX_REGS) - { - if (GET_MODE_SIZE (mode) <= 8) - return FLOAT_REGS; - - if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode)) - return ALTIVEC_REGS; - - return rclass; - } - - return rclass; -} - -/* Debug version of rs6000_preferred_reload_class. */ -static enum reg_class -rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass) -{ - enum reg_class ret = rs6000_preferred_reload_class (x, rclass); - - fprintf (stderr, - "\nrs6000_preferred_reload_class, return %s, rclass = %s, " - "mode = %s, x:\n", - reg_class_names[ret], reg_class_names[rclass], - GET_MODE_NAME (GET_MODE (x))); - debug_rtx (x); - - return ret; -} - -/* If we are copying between FP or AltiVec registers and anything else, we need - a memory location. The exception is when we are targeting ppc64 and the - move to/from fpr to gpr instructions are available. Also, under VSX, you - can copy vector registers from the FP register set to the Altivec register - set and vice versa. */ - -static bool -rs6000_secondary_memory_needed (enum reg_class class1, - enum reg_class class2, - enum machine_mode mode) -{ - if (class1 == class2) - return false; - - /* Under VSX, there are 3 register classes that values could be in (VSX_REGS, - ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy - between these classes. But we need memory for other things that can go in - FLOAT_REGS like SFmode. */ - if (TARGET_VSX - && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode)) - && (class1 == VSX_REGS || class1 == ALTIVEC_REGS - || class1 == FLOAT_REGS)) - return (class2 != VSX_REGS && class2 != ALTIVEC_REGS - && class2 != FLOAT_REGS); - - if (class1 == VSX_REGS || class2 == VSX_REGS) - return true; - - if (class1 == FLOAT_REGS - && (!TARGET_MFPGPR || !TARGET_POWERPC64 - || ((mode != DFmode) - && (mode != DDmode) - && (mode != DImode)))) - return true; - - if (class2 == FLOAT_REGS - && (!TARGET_MFPGPR || !TARGET_POWERPC64 - || ((mode != DFmode) - && (mode != DDmode) - && (mode != DImode)))) - return true; - - if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS) - return true; - - return false; -} - -/* Debug version of rs6000_secondary_memory_needed. */ -static bool -rs6000_debug_secondary_memory_needed (enum reg_class class1, - enum reg_class class2, - enum machine_mode mode) -{ - bool ret = rs6000_secondary_memory_needed (class1, class2, mode); - - fprintf (stderr, - "rs6000_secondary_memory_needed, return: %s, class1 = %s, " - "class2 = %s, mode = %s\n", - ret ? "true" : "false", reg_class_names[class1], - reg_class_names[class2], GET_MODE_NAME (mode)); - - return ret; -} - -/* Return the register class of a scratch register needed to copy IN into - or out of a register in RCLASS in MODE. If it can be done directly, - NO_REGS is returned. */ - -static enum reg_class -rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode, - rtx in) -{ - int regno; - - 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 - register from BASE_REGS is needed as an intermediate - register. - - On Darwin, pic addresses require a load from memory, which - needs a base register. */ - if (rclass != BASE_REGS - && (GET_CODE (in) == SYMBOL_REF - || GET_CODE (in) == HIGH - || GET_CODE (in) == LABEL_REF - || GET_CODE (in) == CONST)) - return BASE_REGS; - } - - if (GET_CODE (in) == REG) - { - regno = REGNO (in); - if (regno >= FIRST_PSEUDO_REGISTER) - { - regno = true_regnum (in); - if (regno >= FIRST_PSEUDO_REGISTER) - regno = -1; - } - } - else if (GET_CODE (in) == SUBREG) - { - regno = true_regnum (in); - if (regno >= FIRST_PSEUDO_REGISTER) - regno = -1; - } - else - regno = -1; - - /* We can place anything into GENERAL_REGS and can put GENERAL_REGS - into anything. */ - if (rclass == GENERAL_REGS || rclass == BASE_REGS - || (regno >= 0 && INT_REGNO_P (regno))) - return NO_REGS; - - /* Constants, memory, and FP registers can go into FP registers. */ - if ((regno == -1 || FP_REGNO_P (regno)) - && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS)) - return (mode != SDmode) ? NO_REGS : GENERAL_REGS; - - /* Memory, and FP/altivec registers can go into fp/altivec registers under - VSX. */ - if (TARGET_VSX - && (regno == -1 || VSX_REGNO_P (regno)) - && VSX_REG_CLASS_P (rclass)) - return NO_REGS; - - /* Memory, and AltiVec registers can go into AltiVec registers. */ - if ((regno == -1 || ALTIVEC_REGNO_P (regno)) - && rclass == ALTIVEC_REGS) - return NO_REGS; - - /* We can copy among the CR registers. */ - if ((rclass == CR_REGS || rclass == CR0_REGS) - && regno >= 0 && CR_REGNO_P (regno)) - return NO_REGS; - - /* Otherwise, we need GENERAL_REGS. */ - return GENERAL_REGS; -} - -/* Debug version of rs6000_secondary_reload_class. */ -static enum reg_class -rs6000_debug_secondary_reload_class (enum reg_class rclass, - enum machine_mode mode, rtx in) -{ - enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in); - fprintf (stderr, - "\nrs6000_secondary_reload_class, return %s, rclass = %s, " - "mode = %s, input rtx:\n", - reg_class_names[ret], reg_class_names[rclass], - GET_MODE_NAME (mode)); - debug_rtx (in); - - return ret; -} - -/* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */ - -static bool -rs6000_cannot_change_mode_class (enum machine_mode from, - enum machine_mode to, - enum reg_class rclass) -{ - unsigned from_size = GET_MODE_SIZE (from); - unsigned to_size = GET_MODE_SIZE (to); - - if (from_size != to_size) - { - enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS; - return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD) - && reg_classes_intersect_p (xclass, rclass)); - } - - if (TARGET_E500_DOUBLE - && ((((to) == DFmode) + ((from) == DFmode)) == 1 - || (((to) == TFmode) + ((from) == TFmode)) == 1 - || (((to) == DDmode) + ((from) == DDmode)) == 1 - || (((to) == TDmode) + ((from) == TDmode)) == 1 - || (((to) == DImode) + ((from) == DImode)) == 1)) - return true; - - /* Since the VSX register set includes traditional floating point registers - and altivec registers, just check for the size being different instead of - trying to check whether the modes are vector modes. Otherwise it won't - allow say DF and DI to change classes. */ - if (TARGET_VSX && VSX_REG_CLASS_P (rclass)) - return (from_size != 8 && from_size != 16); - - if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS - && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1) - return true; - - if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1 - && reg_classes_intersect_p (GENERAL_REGS, rclass)) - return true; - - return false; -} - -/* Debug version of rs6000_cannot_change_mode_class. */ -static bool -rs6000_debug_cannot_change_mode_class (enum machine_mode from, - enum machine_mode to, - enum reg_class rclass) -{ - bool ret = rs6000_cannot_change_mode_class (from, to, rclass); - - fprintf (stderr, - "rs6000_cannot_change_mode_class, return %s, from = %s, " - "to = %s, rclass = %s\n", - ret ? "true" : "false", - GET_MODE_NAME (from), GET_MODE_NAME (to), - reg_class_names[rclass]); - - return ret; -} - -/* Given a comparison operation, return the bit number in CCR to test. We - know this is a valid comparison. - - SCC_P is 1 if this is for an scc. That means that %D will have been - used instead of %C, so the bits will be in different places. - - Return -1 if OP isn't a valid comparison for some reason. */ - -int -ccr_bit (rtx op, int scc_p) -{ - enum rtx_code code = GET_CODE (op); - enum machine_mode cc_mode; - int cc_regnum; - int base_bit; - rtx reg; - - if (!COMPARISON_P (op)) - return -1; - - reg = XEXP (op, 0); - - gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg))); - - cc_mode = GET_MODE (reg); - cc_regnum = REGNO (reg); - base_bit = 4 * (cc_regnum - CR0_REGNO); - - validate_condition_mode (code, cc_mode); - - /* When generating a sCOND operation, only positive conditions are - allowed. */ - gcc_assert (!scc_p - || code == EQ || code == GT || code == LT || code == UNORDERED - || code == GTU || code == LTU); - - switch (code) - { - case NE: - return scc_p ? base_bit + 3 : base_bit + 2; - case EQ: - return base_bit + 2; - case GT: case GTU: case UNLE: - return base_bit + 1; - case LT: case LTU: case UNGE: - return base_bit; - case ORDERED: case UNORDERED: - return base_bit + 3; - - case GE: case GEU: - /* If scc, we will have done a cror to put the bit in the - unordered position. So test that bit. For integer, this is ! LT - unless this is an scc insn. */ - return scc_p ? base_bit + 3 : base_bit; - - case LE: case LEU: - return scc_p ? base_bit + 3 : base_bit + 1; - - default: - gcc_unreachable (); - } -} - -/* Return the GOT register. */ - -rtx -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 - update it here to make the prolog/epilogue code happy. */ - if (!can_create_pseudo_p () - && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)) - df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true); - - crtl->uses_pic_offset_table = 1; - - return pic_offset_table_rtx; -} - -static rs6000_stack_t stack_info; - -/* Function to init struct machine_function. - This will be called, via a pointer variable, - from push_function_context. */ - -static struct machine_function * -rs6000_init_machine_status (void) -{ - stack_info.reload_completed = 0; - return ggc_alloc_cleared_machine_function (); -} - -/* These macros test for integers and extract the low-order bits. */ -#define INT_P(X) \ -((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \ - && GET_MODE (X) == VOIDmode) - -#define INT_LOWPART(X) \ - (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X)) - -int -extract_MB (rtx op) -{ - int i; - unsigned long val = INT_LOWPART (op); - - /* If the high bit is zero, the value is the first 1 bit we find - from the left. */ - if ((val & 0x80000000) == 0) - { - gcc_assert (val & 0xffffffff); - - i = 1; - while (((val <<= 1) & 0x80000000) == 0) - ++i; - return i; - } - - /* If the high bit is set and the low bit is not, or the mask is all - 1's, the value is zero. */ - if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff) - return 0; - - /* Otherwise we have a wrap-around mask. Look for the first 0 bit - from the right. */ - i = 31; - while (((val >>= 1) & 1) != 0) - --i; - - return i; -} - -int -extract_ME (rtx op) -{ - int i; - unsigned long val = INT_LOWPART (op); - - /* If the low bit is zero, the value is the first 1 bit we find from - the right. */ - if ((val & 1) == 0) - { - gcc_assert (val & 0xffffffff); - - i = 30; - while (((val >>= 1) & 1) == 0) - --i; - - return i; - } - - /* If the low bit is set and the high bit is not, or the mask is all - 1's, the value is 31. */ - if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff) - return 31; - - /* Otherwise we have a wrap-around mask. Look for the first 0 bit - from the left. */ - i = 0; - while (((val <<= 1) & 0x80000000) != 0) - ++i; - - 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; - - gcc_unreachable (); -} - -/* 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; -} - -/* Write out a function code label. */ - -void -rs6000_output_function_entry (FILE *file, const char *fname) -{ - if (fname[0] != '.') - { - switch (DEFAULT_ABI) - { - default: - gcc_unreachable (); - - case ABI_AIX: - if (DOT_SYMBOLS) - putc ('.', file); - else - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L."); - break; - - case ABI_V4: - case ABI_DARWIN: - break; - } - } - - RS6000_OUTPUT_BASENAME (file, fname); -} - -/* Print an operand. Recognize special options, documented below. */ - -#if TARGET_ELF -#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel") -#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13) -#else -#define SMALL_DATA_RELOC "sda21" -#define SMALL_DATA_REG 0 -#endif - -void -print_operand (FILE *file, rtx x, int code) -{ - int i; - unsigned HOST_WIDE_INT uval; - - switch (code) - { - /* %a is output_address. */ - - case 'b': - /* If constant, low-order 16 bits of constant, unsigned. - Otherwise, write normally. */ - if (INT_P (x)) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff); - else - print_operand (file, x, 0); - return; - - case 'B': - /* If the low-order bit is zero, write 'r'; otherwise, write 'l' - for 64-bit mask direction. */ - putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file); - return; - - /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise - output_operand. */ - - case 'D': - /* Like 'J' but get to the GT bit only. */ - gcc_assert (REG_P (x)); - - /* Bit 1 is GT bit. */ - i = 4 * (REGNO (x) - CR0_REGNO) + 1; - - /* Add one for shift count in rlinm for scc. */ - fprintf (file, "%d", i + 1); - return; - - case 'E': - /* X is a CR register. Print the number of the EQ 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) + 2); - return; - - case 'f': - /* X is a CR register. Print the shift count needed to move it - to the high-order four bits. */ - if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%f value"); - else - fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO)); - return; - - case 'F': - /* Similar, but print the count for the rotate in the opposite - direction. */ - if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%F value"); - else - fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO)); - return; - - case 'G': - /* X is a constant integer. If it is negative, print "m", - otherwise print "z". This is to make an aze or ame insn. */ - if (GET_CODE (x) != CONST_INT) - output_operand_lossage ("invalid %%G value"); - else if (INTVAL (x) >= 0) - putc ('z', file); - else - putc ('m', file); - return; - - case 'h': - /* If constant, output low-order five bits. Otherwise, write - normally. */ - if (INT_P (x)) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31); - else - print_operand (file, x, 0); - return; - - case 'H': - /* If constant, output low-order six bits. Otherwise, write - normally. */ - if (INT_P (x)) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63); - else - print_operand (file, x, 0); - return; - - case 'I': - /* Print `i' if this is a constant, else nothing. */ - if (INT_P (x)) - putc ('i', file); - return; - - case 'j': - /* Write the bit number in CCR for jump. */ - i = ccr_bit (x, 0); - if (i == -1) - output_operand_lossage ("invalid %%j code"); - else - fprintf (file, "%d", i); - return; - - case 'J': - /* Similar, but add one for shift count in rlinm for scc and pass - scc flag to `ccr_bit'. */ - i = ccr_bit (x, 1); - if (i == -1) - output_operand_lossage ("invalid %%J code"); - else - /* If we want bit 31, write a shift count of zero, not 32. */ - fprintf (file, "%d", i == 31 ? 0 : i + 1); - return; - - case 'k': - /* X must be a constant. Write the 1's complement of the - constant. */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%k value"); - else - fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x)); - return; - - case 'K': - /* X must be a symbolic constant on ELF. Write an - expression suitable for an 'addi' that adds in the low 16 - bits of the MEM. */ - if (GET_CODE (x) == CONST) - { - if (GET_CODE (XEXP (x, 0)) != PLUS - || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF - && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF) - || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT) - output_operand_lossage ("invalid %%K value"); - } - print_operand_address (file, x); - fputs ("@l", file); - return; - - /* %l is output_asm_label. */ - - case 'L': - /* Write second word of DImode or DFmode reference. Works on register - or non-indexed memory only. */ - if (REG_P (x)) - fputs (reg_names[REGNO (x) + 1], file); - else if (MEM_P (x)) - { - /* Handle possible auto-increment. Since it is pre-increment and - we have already done it, we can just use an offset of word. */ - if (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC) - output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), - UNITS_PER_WORD)); - else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) - output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), - UNITS_PER_WORD)); - else - output_address (XEXP (adjust_address_nv (x, SImode, - UNITS_PER_WORD), - 0)); - - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - } - return; - - case 'm': - /* MB value for a mask operand. */ - if (! mask_operand (x, SImode)) - output_operand_lossage ("invalid %%m value"); - - fprintf (file, "%d", extract_MB (x)); - return; - - case 'M': - /* ME value for a mask operand. */ - if (! mask_operand (x, SImode)) - output_operand_lossage ("invalid %%M value"); - - fprintf (file, "%d", extract_ME (x)); - return; - - /* %n outputs the negative of its operand. */ - - case 'N': - /* Write the number of elements in the vector times 4. */ - if (GET_CODE (x) != PARALLEL) - output_operand_lossage ("invalid %%N value"); - else - fprintf (file, "%d", XVECLEN (x, 0) * 4); - return; - - case 'O': - /* Similar, but subtract 1 first. */ - if (GET_CODE (x) != PARALLEL) - output_operand_lossage ("invalid %%O value"); - else - fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4); - return; - - case 'p': - /* X is a CONST_INT that is a power of two. Output the logarithm. */ - if (! INT_P (x) - || INT_LOWPART (x) < 0 - || (i = exact_log2 (INT_LOWPART (x))) < 0) - output_operand_lossage ("invalid %%p value"); - else - fprintf (file, "%d", i); - return; - - case 'P': - /* The operand must be an indirect memory reference. The result - is the register name. */ - if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG - || REGNO (XEXP (x, 0)) >= 32) - output_operand_lossage ("invalid %%P value"); - else - fputs (reg_names[REGNO (XEXP (x, 0))], file); - return; - - case 'q': - /* This outputs the logical code corresponding to a boolean - expression. The expression may have one or both operands - negated (if one, only the first one). For condition register - logical operations, it will also treat the negated - CR codes as NOTs, but not handle NOTs of them. */ - { - const char *const *t = 0; - const char *s; - enum rtx_code code = GET_CODE (x); - static const char * const tbl[3][3] = { - { "and", "andc", "nor" }, - { "or", "orc", "nand" }, - { "xor", "eqv", "xor" } }; - - if (code == AND) - t = tbl[0]; - else if (code == IOR) - t = tbl[1]; - else if (code == XOR) - t = tbl[2]; - else - output_operand_lossage ("invalid %%q value"); - - if (GET_CODE (XEXP (x, 0)) != NOT) - s = t[0]; - else - { - if (GET_CODE (XEXP (x, 1)) == NOT) - s = t[2]; - else - s = t[1]; - } - - fputs (s, file); - } - return; - - case 'Q': - if (! TARGET_MFCRF) - return; - fputc (',', file); - /* FALLTHRU */ - - case 'R': - /* X is a CR register. Print the mask for `mtcrf'. */ - if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%R value"); - else - fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO)); - return; - - case 's': - /* Low 5 bits of 32 - value */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%s value"); - else - fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31); - return; - - case 'S': - /* PowerPC64 mask position. All 0's is excluded. - CONST_INT 32-bit mask is considered sign-extended so any - transition must occur within the CONST_INT, not on the boundary. */ - if (! mask64_operand (x, DImode)) - output_operand_lossage ("invalid %%S value"); - - uval = INT_LOWPART (x); - - if (uval & 1) /* Clear Left */ - { -#if HOST_BITS_PER_WIDE_INT > 64 - uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1; -#endif - i = 64; - } - else /* Clear Right */ - { - uval = ~uval; -#if HOST_BITS_PER_WIDE_INT > 64 - uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1; -#endif - i = 63; - } - while (uval != 0) - --i, uval >>= 1; - gcc_assert (i >= 0); - fprintf (file, "%d", i); - return; - - case 't': - /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */ - gcc_assert (REG_P (x) && GET_MODE (x) == CCmode); - - /* Bit 3 is OV bit. */ - i = 4 * (REGNO (x) - CR0_REGNO) + 3; - - /* If we want bit 31, write a shift count of zero, not 32. */ - fprintf (file, "%d", i == 31 ? 0 : i + 1); - return; - - case 'T': - /* Print the symbolic name of a branch target register. */ - if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO - && REGNO (x) != CTR_REGNO)) - output_operand_lossage ("invalid %%T value"); - else if (REGNO (x) == LR_REGNO) - fputs ("lr", file); - else - fputs ("ctr", file); - return; - - case 'u': - /* High-order 16 bits of constant for use in unsigned operand. */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%u value"); - else - fprintf (file, HOST_WIDE_INT_PRINT_HEX, - (INT_LOWPART (x) >> 16) & 0xffff); - return; - - case 'v': - /* High-order 16 bits of constant for use in signed operand. */ - if (! INT_P (x)) - output_operand_lossage ("invalid %%v value"); - else - fprintf (file, HOST_WIDE_INT_PRINT_HEX, - (INT_LOWPART (x) >> 16) & 0xffff); - return; - - case 'U': - /* Print `u' if this has an auto-increment or auto-decrement. */ - if (MEM_P (x) - && (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC - || GET_CODE (XEXP (x, 0)) == PRE_MODIFY)) - putc ('u', file); - return; - - case 'V': - /* Print the trap code for this operand. */ - switch (GET_CODE (x)) - { - case EQ: - fputs ("eq", file); /* 4 */ - break; - case NE: - fputs ("ne", file); /* 24 */ - break; - case LT: - fputs ("lt", file); /* 16 */ - break; - case LE: - fputs ("le", file); /* 20 */ - break; - case GT: - fputs ("gt", file); /* 8 */ - break; - case GE: - fputs ("ge", file); /* 12 */ - break; - case LTU: - fputs ("llt", file); /* 2 */ - break; - case LEU: - fputs ("lle", file); /* 6 */ - break; - case GTU: - fputs ("lgt", file); /* 1 */ - break; - case GEU: - fputs ("lge", file); /* 5 */ - break; - default: - gcc_unreachable (); - } - break; - - case 'w': - /* If constant, low-order 16 bits of constant, signed. Otherwise, write - normally. */ - if (INT_P (x)) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, - ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000); - else - print_operand (file, x, 0); - return; - - case 'W': - /* MB value for a PowerPC64 rldic operand. */ - i = clz_hwi (GET_CODE (x) == CONST_INT - ? INTVAL (x) : CONST_DOUBLE_HIGH (x)); - -#if HOST_BITS_PER_WIDE_INT == 32 - if (GET_CODE (x) == CONST_INT && i > 0) - i += 32; /* zero-extend high-part was all 0's */ - else if (GET_CODE (x) == CONST_DOUBLE && i == 32) - i = clz_hwi (CONST_DOUBLE_LOW (x)) + 32; -#endif - - fprintf (file, "%d", i); - return; - - case 'x': - /* X is a FPR or Altivec register used in a VSX context. */ - if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x))) - output_operand_lossage ("invalid %%x value"); - else - { - int reg = REGNO (x); - int vsx_reg = (FP_REGNO_P (reg) - ? reg - 32 - : reg - FIRST_ALTIVEC_REGNO + 32); - -#ifdef TARGET_REGNAMES - if (TARGET_REGNAMES) - fprintf (file, "%%vs%d", vsx_reg); - else -#endif - fprintf (file, "%d", vsx_reg); - } - return; - - case 'X': - if (MEM_P (x) - && (legitimate_indexed_address_p (XEXP (x, 0), 0) - || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY - && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0)))) - putc ('x', file); - return; - - case 'Y': - /* Like 'L', for third word of TImode */ - if (REG_P (x)) - fputs (reg_names[REGNO (x) + 2], file); - else if (MEM_P (x)) - { - if (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC) - output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 8)); - else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) - output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 8)); - else - output_address (XEXP (adjust_address_nv (x, SImode, 8), 0)); - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - } - return; - - case 'z': - /* X is a SYMBOL_REF. Write out the name preceded by a - period and without any trailing data in brackets. Used for function - names. If we are configured for System V (or the embedded ABI) on - the PowerPC, do not emit the period, since those systems do not use - TOCs and the like. */ - gcc_assert (GET_CODE (x) == SYMBOL_REF); - - /* Mark the decl as referenced so that cgraph will output the - function. */ - if (SYMBOL_REF_DECL (x)) - mark_decl_referenced (SYMBOL_REF_DECL (x)); - - /* For macho, check to see if we need a stub. */ - if (TARGET_MACHO) - { - const char *name = XSTR (x, 0); -#if TARGET_MACHO - if (darwin_emit_branch_islands - && MACHOPIC_INDIRECT - && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION) - name = machopic_indirection_name (x, /*stub_p=*/true); -#endif - assemble_name (file, name); - } - else if (!DOT_SYMBOLS) - assemble_name (file, XSTR (x, 0)); - else - rs6000_output_function_entry (file, XSTR (x, 0)); - return; - - case 'Z': - /* Like 'L', for last word of TImode. */ - if (REG_P (x)) - fputs (reg_names[REGNO (x) + 3], file); - else if (MEM_P (x)) - { - if (GET_CODE (XEXP (x, 0)) == PRE_INC - || GET_CODE (XEXP (x, 0)) == PRE_DEC) - output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 12)); - else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) - output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 12)); - else - output_address (XEXP (adjust_address_nv (x, SImode, 12), 0)); - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - } - return; - - /* Print AltiVec or SPE memory operand. */ - case 'y': - { - rtx tmp; - - gcc_assert (MEM_P (x)); - - tmp = XEXP (x, 0); - - /* Ugly hack because %y is overloaded. */ - if ((TARGET_SPE || TARGET_E500_DOUBLE) - && (GET_MODE_SIZE (GET_MODE (x)) == 8 - || GET_MODE (x) == TFmode - || GET_MODE (x) == TImode)) - { - /* Handle [reg]. */ - if (REG_P (tmp)) - { - fprintf (file, "0(%s)", reg_names[REGNO (tmp)]); - break; - } - /* Handle [reg+UIMM]. */ - else if (GET_CODE (tmp) == PLUS && - GET_CODE (XEXP (tmp, 1)) == CONST_INT) - { - int x; - - gcc_assert (REG_P (XEXP (tmp, 0))); - - x = INTVAL (XEXP (tmp, 1)); - fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]); - break; - } - - /* Fall through. Must be [reg+reg]. */ - } - if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x)) - && GET_CODE (tmp) == AND - && GET_CODE (XEXP (tmp, 1)) == CONST_INT - && INTVAL (XEXP (tmp, 1)) == -16) - tmp = XEXP (tmp, 0); - else if (VECTOR_MEM_VSX_P (GET_MODE (x)) - && GET_CODE (tmp) == PRE_MODIFY) - tmp = XEXP (tmp, 1); - if (REG_P (tmp)) - fprintf (file, "0,%s", reg_names[REGNO (tmp)]); - else - { - if (!GET_CODE (tmp) == PLUS - || !REG_P (XEXP (tmp, 0)) - || !REG_P (XEXP (tmp, 1))) - { - output_operand_lossage ("invalid %%y value, try using the 'Z' constraint"); - break; - } - - if (REGNO (XEXP (tmp, 0)) == 0) - fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ], - reg_names[ REGNO (XEXP (tmp, 0)) ]); - else - fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ], - reg_names[ REGNO (XEXP (tmp, 1)) ]); - } - break; - } - - case 0: - if (REG_P (x)) - fprintf (file, "%s", reg_names[REGNO (x)]); - else if (MEM_P (x)) - { - /* We need to handle PRE_INC and PRE_DEC here, since we need to - know the width from the mode. */ - if (GET_CODE (XEXP (x, 0)) == PRE_INC) - fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)), - reg_names[REGNO (XEXP (XEXP (x, 0), 0))]); - else if (GET_CODE (XEXP (x, 0)) == PRE_DEC) - fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)), - reg_names[REGNO (XEXP (XEXP (x, 0), 0))]); - else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY) - output_address (XEXP (XEXP (x, 0), 1)); - else - output_address (XEXP (x, 0)); - } - else - { - if (toc_relative_expr_p (x, false)) - /* This hack along with a corresponding hack in - rs6000_output_addr_const_extra arranges to output addends - where the assembler expects to find them. eg. - (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 4) - without this hack would be output as "x@toc+4". We - want "x+4@toc". */ - output_addr_const (file, CONST_CAST_RTX (tocrel_base)); - else - output_addr_const (file, x); - } - return; - - case '&': - assemble_name (file, rs6000_get_some_local_dynamic_name ()); - return; - - default: - output_operand_lossage ("invalid %%xn code"); - } -} - -/* Print the address of an operand. */ - -void -print_operand_address (FILE *file, rtx x) -{ - if (REG_P (x)) - fprintf (file, "0(%s)", reg_names[ REGNO (x) ]); - else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST - || GET_CODE (x) == LABEL_REF) - { - output_addr_const (file, x); - if (small_data_operand (x, GET_MODE (x))) - fprintf (file, "@%s(%s)", SMALL_DATA_RELOC, - reg_names[SMALL_DATA_REG]); - else - gcc_assert (!TARGET_TOC); - } - else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) - && REG_P (XEXP (x, 1))) - { - if (REGNO (XEXP (x, 0)) == 0) - fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ], - reg_names[ REGNO (XEXP (x, 0)) ]); - else - fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ], - reg_names[ REGNO (XEXP (x, 1)) ]); - } - else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) - && GET_CODE (XEXP (x, 1)) == CONST_INT) - fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)", - INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]); -#if TARGET_MACHO - else if (GET_CODE (x) == LO_SUM && REG_P (XEXP (x, 0)) - && CONSTANT_P (XEXP (x, 1))) - { - fprintf (file, "lo16("); - output_addr_const (file, XEXP (x, 1)); - fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); - } -#endif -#if TARGET_ELF - else if (GET_CODE (x) == LO_SUM && REG_P (XEXP (x, 0)) - && CONSTANT_P (XEXP (x, 1))) - { - output_addr_const (file, XEXP (x, 1)); - fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); - } -#endif - else if (toc_relative_expr_p (x, false)) - { - /* This hack along with a corresponding hack in - rs6000_output_addr_const_extra arranges to output addends - where the assembler expects to find them. eg. - (lo_sum (reg 9) - . (plus (unspec [(symbol_ref ("x")) (reg 2)] tocrel) 8)) - without this hack would be output as "x@toc+8@l(9)". We - want "x+8@toc@l(9)". */ - output_addr_const (file, CONST_CAST_RTX (tocrel_base)); - if (GET_CODE (x) == LO_SUM) - fprintf (file, "@l(%s)", reg_names[REGNO (XEXP (x, 0))]); - else - fprintf (file, "(%s)", reg_names[REGNO (XVECEXP (tocrel_base, 0, 1))]); - } - else - gcc_unreachable (); -} - -/* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */ - -static bool -rs6000_output_addr_const_extra (FILE *file, rtx x) -{ - if (GET_CODE (x) == UNSPEC) - switch (XINT (x, 1)) - { - case UNSPEC_TOCREL: - gcc_checking_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF - && REG_P (XVECEXP (x, 0, 1)) - && REGNO (XVECEXP (x, 0, 1)) == TOC_REGISTER); - output_addr_const (file, XVECEXP (x, 0, 0)); - if (x == tocrel_base && tocrel_offset != const0_rtx) - { - if (INTVAL (tocrel_offset) >= 0) - fprintf (file, "+"); - output_addr_const (file, CONST_CAST_RTX (tocrel_offset)); - } - if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC)) - { - putc ('-', file); - assemble_name (file, toc_label_name); - } - else if (TARGET_ELF) - fputs ("@toc", file); - return true; - -#if TARGET_MACHO - case UNSPEC_MACHOPIC_OFFSET: - output_addr_const (file, XVECEXP (x, 0, 0)); - putc ('-', file); - machopic_output_function_base_name (file); - return true; -#endif - } - return false; -} - -/* Target hook for assembling integer objects. The PowerPC version has - to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP - is defined. It also needs to handle DI-mode objects on 64-bit - targets. */ - -static bool -rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p) -{ -#ifdef RELOCATABLE_NEEDS_FIXUP - /* Special handling for SI values. */ - if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p) - { - static int recurse = 0; - - /* For -mrelocatable, we mark all addresses that need to be fixed up in - the .fixup section. Since the TOC section is already relocated, we - don't need to mark it here. We used to skip the text section, but it - should never be valid for relocated addresses to be placed in the text - section. */ - if (TARGET_RELOCATABLE - && in_section != toc_section - && !recurse - && GET_CODE (x) != CONST_INT - && GET_CODE (x) != CONST_DOUBLE - && CONSTANT_P (x)) - { - char buf[256]; - - recurse = 1; - ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno); - fixuplabelno++; - ASM_OUTPUT_LABEL (asm_out_file, buf); - fprintf (asm_out_file, "\t.long\t("); - output_addr_const (asm_out_file, x); - fprintf (asm_out_file, ")@fixup\n"); - fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n"); - ASM_OUTPUT_ALIGN (asm_out_file, 2); - fprintf (asm_out_file, "\t.long\t"); - assemble_name (asm_out_file, buf); - fprintf (asm_out_file, "\n\t.previous\n"); - recurse = 0; - return true; - } - /* Remove initial .'s to turn a -mcall-aixdesc function - address into the address of the descriptor, not the function - itself. */ - else if (GET_CODE (x) == SYMBOL_REF - && XSTR (x, 0)[0] == '.' - && DEFAULT_ABI == ABI_AIX) - { - const char *name = XSTR (x, 0); - while (*name == '.') - name++; - - fprintf (asm_out_file, "\t.long\t%s\n", name); - return true; - } - } -#endif /* RELOCATABLE_NEEDS_FIXUP */ - return default_assemble_integer (x, size, aligned_p); -} - -#if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO -/* Emit an assembler directive to set symbol visibility for DECL to - VISIBILITY_TYPE. */ - -static void -rs6000_assemble_visibility (tree decl, int vis) -{ - if (TARGET_XCOFF) - return; - - /* Functions need to have their entry point symbol visibility set as - well as their descriptor symbol visibility. */ - if (DEFAULT_ABI == ABI_AIX - && DOT_SYMBOLS - && TREE_CODE (decl) == FUNCTION_DECL) - { - static const char * const visibility_types[] = { - NULL, "internal", "hidden", "protected" - }; - - const char *name, *type; - - name = ((* targetm.strip_name_encoding) - (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)))); - type = visibility_types[vis]; - - fprintf (asm_out_file, "\t.%s\t%s\n", type, name); - fprintf (asm_out_file, "\t.%s\t.%s\n", type, name); - } - else - default_assemble_visibility (decl, vis); -} -#endif - -enum rtx_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_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); -} - -/* Generate a compare for CODE. Return a brand-new rtx that - represents the result of the compare. */ - -static rtx -rs6000_generate_compare (rtx cmp, enum machine_mode mode) -{ - enum machine_mode comp_mode; - rtx compare_result; - enum rtx_code code = GET_CODE (cmp); - rtx op0 = XEXP (cmp, 0); - rtx op1 = XEXP (cmp, 1); - - if (FLOAT_MODE_P (mode)) - comp_mode = CCFPmode; - else if (code == GTU || code == LTU - || code == GEU || code == LEU) - comp_mode = CCUNSmode; - else if ((code == EQ || code == NE) - && unsigned_reg_p (op0) - && (unsigned_reg_p (op1) - || (CONST_INT_P (op1) && INTVAL (op1) != 0))) - /* These are unsigned values, perhaps there will be a later - ordering compare that can be shared with this one. */ - comp_mode = CCUNSmode; - else - comp_mode = CCmode; - - /* If we have an unsigned compare, make sure we don't have a signed value as - an immediate. */ - if (comp_mode == CCUNSmode && GET_CODE (op1) == CONST_INT - && INTVAL (op1) < 0) - { - op0 = copy_rtx_if_shared (op0); - op1 = force_reg (GET_MODE (op0), op1); - cmp = gen_rtx_fmt_ee (code, GET_MODE (cmp), op0, op1); - } - - /* First, the compare. */ - compare_result = gen_reg_rtx (comp_mode); - - /* E500 FP compare instructions on the GPRs. Yuck! */ - if ((!TARGET_FPRS && TARGET_HARD_FLOAT) - && FLOAT_MODE_P (mode)) - { - rtx cmp, or_result, compare_result2; - enum machine_mode op_mode = GET_MODE (op0); - - if (op_mode == VOIDmode) - op_mode = GET_MODE (op1); - - /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only. - This explains the following mess. */ - - switch (code) - { - case EQ: case UNEQ: case NE: case LTGT: - switch (op_mode) - { - case SFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsfeq_gpr (compare_result, op0, op1) - : gen_cmpsfeq_gpr (compare_result, op0, op1); - break; - - case DFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdfeq_gpr (compare_result, op0, op1) - : gen_cmpdfeq_gpr (compare_result, op0, op1); - break; - - case TFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttfeq_gpr (compare_result, op0, op1) - : gen_cmptfeq_gpr (compare_result, op0, op1); - break; - - default: - gcc_unreachable (); - } - break; - - case GT: case GTU: case UNGT: case UNGE: case GE: case GEU: - switch (op_mode) - { - case SFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsfgt_gpr (compare_result, op0, op1) - : gen_cmpsfgt_gpr (compare_result, op0, op1); - break; - - case DFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdfgt_gpr (compare_result, op0, op1) - : gen_cmpdfgt_gpr (compare_result, op0, op1); - break; - - case TFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttfgt_gpr (compare_result, op0, op1) - : gen_cmptfgt_gpr (compare_result, op0, op1); - break; - - default: - gcc_unreachable (); - } - break; - - case LT: case LTU: case UNLT: case UNLE: case LE: case LEU: - switch (op_mode) - { - case SFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsflt_gpr (compare_result, op0, op1) - : gen_cmpsflt_gpr (compare_result, op0, op1); - break; - - case DFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdflt_gpr (compare_result, op0, op1) - : gen_cmpdflt_gpr (compare_result, op0, op1); - break; - - case TFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttflt_gpr (compare_result, op0, op1) - : gen_cmptflt_gpr (compare_result, op0, op1); - break; - - default: - gcc_unreachable (); - } - break; - default: - gcc_unreachable (); - } - - /* Synthesize LE and GE from LT/GT || EQ. */ - if (code == LE || code == GE || code == LEU || code == GEU) - { - emit_insn (cmp); - - switch (code) - { - case LE: code = LT; break; - case GE: code = GT; break; - case LEU: code = LT; break; - case GEU: code = GT; break; - default: gcc_unreachable (); - } - - compare_result2 = gen_reg_rtx (CCFPmode); - - /* Do the EQ. */ - switch (op_mode) - { - case SFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstsfeq_gpr (compare_result2, op0, op1) - : gen_cmpsfeq_gpr (compare_result2, op0, op1); - break; - - case DFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tstdfeq_gpr (compare_result2, op0, op1) - : gen_cmpdfeq_gpr (compare_result2, op0, op1); - break; - - case TFmode: - cmp = (flag_finite_math_only && !flag_trapping_math) - ? gen_tsttfeq_gpr (compare_result2, op0, op1) - : gen_cmptfeq_gpr (compare_result2, op0, op1); - break; - - default: - gcc_unreachable (); - } - emit_insn (cmp); - - /* OR them together. */ - or_result = gen_reg_rtx (CCFPmode); - cmp = gen_e500_cr_ior_compare (or_result, compare_result, - compare_result2); - compare_result = or_result; - code = EQ; - } - else - { - if (code == NE || code == LTGT) - code = NE; - else - code = EQ; - } - - emit_insn (cmp); - } - else - { - /* Generate XLC-compatible TFmode compare as PARALLEL with extra - CLOBBERs to match cmptf_internal2 pattern. */ - if (comp_mode == CCFPmode && TARGET_XL_COMPAT - && GET_MODE (op0) == TFmode - && !TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128) - emit_insn (gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (10, - gen_rtx_SET (VOIDmode, - compare_result, - gen_rtx_COMPARE (comp_mode, op0, op1)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)), - gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode))))); - else if (GET_CODE (op1) == UNSPEC - && XINT (op1, 1) == UNSPEC_SP_TEST) - { - rtx op1b = XVECEXP (op1, 0, 0); - comp_mode = CCEQmode; - compare_result = gen_reg_rtx (CCEQmode); - if (TARGET_64BIT) - emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b)); - else - emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b)); - } - else - emit_insn (gen_rtx_SET (VOIDmode, compare_result, - gen_rtx_COMPARE (comp_mode, op0, op1))); - } - - /* Some kinds of FP comparisons need an OR operation; - under flag_finite_math_only we don't bother. */ - if (FLOAT_MODE_P (mode) - && !flag_finite_math_only - && !(TARGET_HARD_FLOAT && !TARGET_FPRS) - && (code == LE || code == GE - || code == UNEQ || code == LTGT - || code == UNGT || code == UNLT)) - { - enum rtx_code or1, or2; - rtx or1_rtx, or2_rtx, compare2_rtx; - rtx or_result = gen_reg_rtx (CCEQmode); - - switch (code) - { - case LE: or1 = LT; or2 = EQ; break; - case GE: or1 = GT; or2 = EQ; break; - case UNEQ: or1 = UNORDERED; or2 = EQ; break; - case LTGT: or1 = LT; or2 = GT; break; - case UNGT: or1 = UNORDERED; or2 = GT; break; - case UNLT: or1 = UNORDERED; or2 = LT; break; - default: gcc_unreachable (); - } - validate_condition_mode (or1, comp_mode); - validate_condition_mode (or2, comp_mode); - or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx); - or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx); - compare2_rtx = gen_rtx_COMPARE (CCEQmode, - gen_rtx_IOR (SImode, or1_rtx, or2_rtx), - const_true_rtx); - emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx)); - - compare_result = or_result; - code = EQ; - } - - validate_condition_mode (code, GET_MODE (compare_result)); - - return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx); -} - - -/* Emit the RTL for an sISEL pattern. */ - -void -rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[]) -{ - rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); -} - -void -rs6000_emit_sCOND (enum machine_mode mode, rtx operands[]) -{ - rtx condition_rtx; - enum machine_mode op_mode; - enum rtx_code cond_code; - rtx result = operands[0]; - - if (TARGET_ISEL && (mode == SImode || mode == DImode)) - { - rs6000_emit_sISEL (mode, operands); - return; - } - - condition_rtx = rs6000_generate_compare (operands[1], mode); - cond_code = GET_CODE (condition_rtx); - - if (FLOAT_MODE_P (mode) - && !TARGET_FPRS && TARGET_HARD_FLOAT) - { - rtx t; - - PUT_MODE (condition_rtx, SImode); - t = XEXP (condition_rtx, 0); - - gcc_assert (cond_code == NE || cond_code == EQ); - - 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_fmt_ee (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 (XEXP (operands[1], 0)); - if (op_mode == VOIDmode) - op_mode = GET_MODE (XEXP (operands[1], 1)); - - if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode))) - { - PUT_MODE (condition_rtx, DImode); - convert_move (result, condition_rtx, 0); - } - else - { - PUT_MODE (condition_rtx, SImode); - emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx)); - } -} - -/* Emit a branch of kind CODE to location LOC. */ - -void -rs6000_emit_cbranch (enum machine_mode mode, rtx operands[]) -{ - rtx condition_rtx, loc_ref; - - condition_rtx = rs6000_generate_compare (operands[0], mode); - loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]); - emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx, - loc_ref, pc_rtx))); -} - -/* Return the string to output a conditional branch to LABEL, which is - the operand template of the label, or NULL if the branch is really a - conditional return. - - OP is the conditional expression. XEXP (OP, 0) is assumed to be a - condition code register and its mode specifies what kind of - comparison we made. - - REVERSED is nonzero if we should reverse the sense of the comparison. - - INSN is the insn. */ - -char * -output_cbranch (rtx op, const char *label, int reversed, rtx insn) -{ - static char string[64]; - enum rtx_code code = GET_CODE (op); - rtx cc_reg = XEXP (op, 0); - enum machine_mode mode = GET_MODE (cc_reg); - int cc_regno = REGNO (cc_reg) - CR0_REGNO; - int need_longbranch = label != NULL && get_attr_length (insn) == 8; - int really_reversed = reversed ^ need_longbranch; - char *s = string; - const char *ccode; - const char *pred; - rtx note; - - validate_condition_mode (code, mode); - - /* Work out which way this really branches. We could use - reverse_condition_maybe_unordered here always but this - makes the resulting assembler clearer. */ - if (really_reversed) - { - /* Reversal of FP compares takes care -- an ordered compare - becomes an unordered compare and vice versa. */ - if (mode == CCFPmode) - code = reverse_condition_maybe_unordered (code); - else - code = reverse_condition (code); - } - - if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode) - { - /* The efscmp/tst* instructions twiddle bit 2, which maps nicely - to the GT bit. */ - switch (code) - { - case EQ: - /* Opposite of GT. */ - code = GT; - break; - - case NE: - code = UNLE; - break; - - default: - gcc_unreachable (); - } - } - - switch (code) - { - /* Not all of these are actually distinct opcodes, but - we distinguish them for clarity of the resulting assembler. */ - case NE: case LTGT: - ccode = "ne"; break; - case EQ: case UNEQ: - ccode = "eq"; break; - case GE: case GEU: - ccode = "ge"; break; - case GT: case GTU: case UNGT: - ccode = "gt"; break; - case LE: case LEU: - ccode = "le"; break; - case LT: case LTU: case UNLT: - ccode = "lt"; break; - case UNORDERED: ccode = "un"; break; - case ORDERED: ccode = "nu"; break; - case UNGE: ccode = "nl"; break; - case UNLE: ccode = "ng"; break; - default: - gcc_unreachable (); - } - - /* Maybe we have a guess as to how likely the branch is. */ - pred = ""; - note = find_reg_note (insn, REG_BR_PROB, NULL_RTX); - if (note != NULL_RTX) - { - /* PROB is the difference from 50%. */ - int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2; - - /* Only hint for highly probable/improbable branches on newer - cpus as static prediction overrides processor dynamic - prediction. For older cpus we may as well always hint, but - 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 (rs6000_always_hint - || (abs (prob) > REG_BR_PROB_BASE / 100 * 48 - && br_prob_note_reliable_p (note))) - { - if (abs (prob) > REG_BR_PROB_BASE / 20 - && ((prob > 0) ^ need_longbranch)) - pred = "+"; - else - pred = "-"; - } - } - - if (label == NULL) - s += sprintf (s, "b%slr%s ", ccode, pred); - else - s += sprintf (s, "b%s%s ", ccode, pred); - - /* We need to escape any '%' characters in the reg_names string. - 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]); - - if (label != NULL) - { - /* If the branch distance was too far, we may have to use an - unconditional branch to go the distance. */ - if (need_longbranch) - s += sprintf (s, ",$+8\n\tb %s", label); - else - s += sprintf (s, ",%s", label); - } - - 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; - - gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst)) - && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src))); - - /* 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; -} - -/* Return insn for VSX or Altivec comparisons. */ - -static rtx -rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1) -{ - rtx mask; - enum machine_mode mode = GET_MODE (op0); - - switch (code) - { - default: - break; - - case GE: - if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) - return NULL_RTX; - - case EQ: - case GT: - case GTU: - case ORDERED: - case UNORDERED: - case UNEQ: - case LTGT: - mask = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, - mask, - gen_rtx_fmt_ee (code, mode, op0, op1))); - return mask; - } - - return NULL_RTX; -} - -/* Emit vector compare for operands OP0 and OP1 using code RCODE. - DMODE is expected destination mode. This is a recursive function. */ - -static rtx -rs6000_emit_vector_compare (enum rtx_code rcode, - rtx op0, rtx op1, - enum machine_mode dmode) -{ - rtx mask; - bool swap_operands = false; - bool try_again = false; - - gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode)); - gcc_assert (GET_MODE (op0) == GET_MODE (op1)); - - /* See if the comparison works as is. */ - mask = rs6000_emit_vector_compare_inner (rcode, op0, op1); - if (mask) - return mask; - - switch (rcode) - { - case LT: - rcode = GT; - swap_operands = true; - try_again = true; - break; - case LTU: - rcode = GTU; - swap_operands = true; - try_again = true; - break; - case NE: - case UNLE: - case UNLT: - case UNGE: - case UNGT: - /* Invert condition and try again. - e.g., A != B becomes ~(A==B). */ - { - enum rtx_code rev_code; - enum insn_code nor_code; - rtx mask2; - - rev_code = reverse_condition_maybe_unordered (rcode); - if (rev_code == UNKNOWN) - return NULL_RTX; - - nor_code = optab_handler (one_cmpl_optab, dmode); - if (nor_code == CODE_FOR_nothing) - return NULL_RTX; - - mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode); - if (!mask2) - return NULL_RTX; - - mask = gen_reg_rtx (dmode); - emit_insn (GEN_FCN (nor_code) (mask, mask2)); - return mask; - } - break; - case GE: - case GEU: - case LE: - case LEU: - /* Try GT/GTU/LT/LTU OR EQ */ - { - rtx c_rtx, eq_rtx; - enum insn_code ior_code; - enum rtx_code new_code; - - switch (rcode) - { - case GE: - new_code = GT; - break; - - case GEU: - new_code = GTU; - break; - - case LE: - new_code = LT; - break; - - case LEU: - new_code = LTU; - break; - - default: - gcc_unreachable (); - } - - ior_code = optab_handler (ior_optab, dmode); - if (ior_code == CODE_FOR_nothing) - return NULL_RTX; - - c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode); - if (!c_rtx) - return NULL_RTX; - - eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode); - if (!eq_rtx) - return NULL_RTX; - - mask = gen_reg_rtx (dmode); - emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx)); - return mask; - } - break; - default: - return NULL_RTX; - } - - if (try_again) - { - if (swap_operands) - { - rtx tmp; - tmp = op0; - op0 = op1; - op1 = tmp; - } - - mask = rs6000_emit_vector_compare_inner (rcode, op0, op1); - if (mask) - return mask; - } - - /* You only get two chances. */ - return NULL_RTX; -} - -/* Emit vector conditional expression. DEST is destination. OP_TRUE and - OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two - operands for the relation operation COND. */ - -int -rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false, - rtx cond, rtx cc_op0, rtx cc_op1) -{ - enum machine_mode dest_mode = GET_MODE (dest); - enum machine_mode mask_mode = GET_MODE (cc_op0); - enum rtx_code rcode = GET_CODE (cond); - enum machine_mode cc_mode = CCmode; - rtx mask; - rtx cond2; - rtx tmp; - bool invert_move = false; - - if (VECTOR_UNIT_NONE_P (dest_mode)) - return 0; - - gcc_assert (GET_MODE_SIZE (dest_mode) == GET_MODE_SIZE (mask_mode) - && GET_MODE_NUNITS (dest_mode) == GET_MODE_NUNITS (mask_mode)); - - switch (rcode) - { - /* Swap operands if we can, and fall back to doing the operation as - specified, and doing a NOR to invert the test. */ - case NE: - case UNLE: - case UNLT: - case UNGE: - case UNGT: - /* Invert condition and try again. - e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */ - invert_move = true; - rcode = reverse_condition_maybe_unordered (rcode); - if (rcode == UNKNOWN) - return 0; - break; - - /* Mark unsigned tests with CCUNSmode. */ - case GTU: - case GEU: - case LTU: - case LEU: - cc_mode = CCUNSmode; - break; - - default: - break; - } - - /* Get the vector mask for the given relational operations. */ - mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, mask_mode); - - if (!mask) - return 0; - - if (invert_move) - { - tmp = op_true; - op_true = op_false; - op_false = tmp; - } - - cond2 = gen_rtx_fmt_ee (NE, cc_mode, gen_lowpart (dest_mode, mask), - CONST0_RTX (dest_mode)); - emit_insn (gen_rtx_SET (VOIDmode, - dest, - gen_rtx_IF_THEN_ELSE (dest_mode, - cond2, - op_true, - op_false))); - return 1; -} - -/* 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 (rtx dest, rtx op, rtx true_cond, rtx false_cond) -{ - enum rtx_code code = GET_CODE (op); - rtx op0 = XEXP (op, 0); - rtx op1 = XEXP (op, 1); - REAL_VALUE_TYPE c1; - enum machine_mode compare_mode = GET_MODE (op0); - enum machine_mode result_mode = GET_MODE (dest); - rtx temp; - bool is_against_zero; - - /* 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. */ - && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode))) - return 0; - if (GET_MODE (true_cond) != result_mode) - return 0; - if (GET_MODE (false_cond) != result_mode) - return 0; - - /* Don't allow using floating point comparisons for integer results for - now. */ - if (FLOAT_MODE_P (compare_mode) && !FLOAT_MODE_P (result_mode)) - return 0; - - /* First, work out if the hardware can do this at all, or - if it's too slow.... */ - if (!FLOAT_MODE_P (compare_mode)) - { - if (TARGET_ISEL) - return rs6000_emit_int_cmove (dest, op, true_cond, false_cond); - return 0; - } - else if (TARGET_HARD_FLOAT && !TARGET_FPRS - && SCALAR_FLOAT_MODE_P (compare_mode)) - return 0; - - is_against_zero = op1 == CONST0_RTX (compare_mode); - - /* A floating-point subtract might overflow, underflow, or produce - an inexact result, thus changing the floating-point flags, so it - can't be generated if we care about that. It's safe if one side - of the construct is zero, since then no subtract will be - generated. */ - if (SCALAR_FLOAT_MODE_P (compare_mode) - && flag_trapping_math && ! is_against_zero) - 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 == UNLE) - { - code = reverse_condition_maybe_unordered (code); - temp = true_cond; - true_cond = false_cond; - false_cond = temp; - } - - /* 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 && 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 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 (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. */ - && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond)) - || (! rtx_equal_p (op0, true_cond) - && ! rtx_equal_p (op1, true_cond)))) - return 0; - - /* At this point we know we can use fsel. */ - - /* Reduce the comparison to a comparison against zero. */ - if (! is_against_zero) - { - temp = gen_reg_rtx (compare_mode); - emit_insn (gen_rtx_SET (VOIDmode, temp, - gen_rtx_MINUS (compare_mode, op0, op1))); - op0 = temp; - op1 = CONST0_RTX (compare_mode); - } - - /* If we don't care about NaNs we can reduce some of the comparisons - down to faster ones. */ - if (! HONOR_NANS (compare_mode)) - switch (code) - { - case GT: - code = LE; - temp = true_cond; - true_cond = false_cond; - false_cond = temp; - break; - case UNGE: - code = GE; - break; - case UNEQ: - code = EQ; - break; - default: - break; - } - - /* Now, reduce everything down to a GE. */ - switch (code) - { - case GE: - break; - - case LE: - temp = gen_reg_rtx (compare_mode); - emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0))); - op0 = temp; - break; - - case ORDERED: - temp = gen_reg_rtx (compare_mode); - emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0))); - op0 = temp; - break; - - case EQ: - temp = gen_reg_rtx (compare_mode); - emit_insn (gen_rtx_SET (VOIDmode, temp, - gen_rtx_NEG (compare_mode, - gen_rtx_ABS (compare_mode, op0)))); - op0 = temp; - 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 = true_cond; - true_cond = temp; - - temp = gen_reg_rtx (compare_mode); - emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0))); - op0 = temp; - 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 = false_cond; - false_cond = temp; - - temp = gen_reg_rtx (compare_mode); - emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0))); - op0 = temp; - break; - - default: - gcc_unreachable (); - } - - emit_insn (gen_rtx_SET (VOIDmode, dest, - gen_rtx_IF_THEN_ELSE (result_mode, - gen_rtx_GE (VOIDmode, - op0, op1), - true_cond, false_cond))); - return 1; -} - -/* Same as above, but for ints (isel). */ - -static int -rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) -{ - rtx condition_rtx, cr; - enum machine_mode mode = GET_MODE (dest); - enum rtx_code cond_code; - rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx); - bool signedp; - - if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode)) - return 0; - - /* We still have to do the compare, because isel doesn't do a - compare, it just looks at the CRx bits set by a previous compare - instruction. */ - condition_rtx = rs6000_generate_compare (op, mode); - cond_code = GET_CODE (condition_rtx); - cr = XEXP (condition_rtx, 0); - signedp = GET_MODE (cr) == CCmode; - - isel_func = (mode == SImode - ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si) - : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di)); - - switch (cond_code) - { - case LT: case GT: case LTU: case GTU: case EQ: - /* isel handles these directly. */ - break; - - default: - /* We need to swap the sense of the comparison. */ - { - rtx t = true_cond; - true_cond = false_cond; - false_cond = t; - PUT_CODE (condition_rtx, reverse_condition (cond_code)); - } - break; - } - - false_cond = force_reg (mode, false_cond); - if (true_cond != const0_rtx) - true_cond = force_reg (mode, true_cond); - - emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr)); - - return 1; -} - -const char * -output_isel (rtx *operands) -{ - enum rtx_code code; - - code = GET_CODE (operands[1]); - - if (code == GE || code == GEU || code == LE || code == LEU || code == NE) - { - gcc_assert (GET_CODE (operands[2]) == REG - && GET_CODE (operands[3]) == REG); - PUT_CODE (operands[1], reverse_condition (code)); - return "isel %0,%3,%2,%j1"; - } - - return "isel %0,%2,%3,%j1"; -} - -void -rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1) -{ - enum machine_mode mode = GET_MODE (op0); - enum rtx_code c; - rtx target; - - /* VSX/altivec have direct min/max insns. */ - if ((code == SMAX || code == SMIN) - && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode) - || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode)))) - { - emit_insn (gen_rtx_SET (VOIDmode, - dest, - gen_rtx_fmt_ee (code, mode, op0, op1))); - return; - } - - if (code == SMAX || code == SMIN) - c = GE; - else - c = GEU; - - if (code == SMAX || code == UMAX) - target = emit_conditional_move (dest, c, op0, op1, mode, - op0, op1, mode, 0); - else - target = emit_conditional_move (dest, c, op0, op1, mode, - op1, op0, mode, 0); - gcc_assert (target); - if (target != dest) - emit_move_insn (dest, target); -} - -/* A subroutine of the atomic operation splitters. Jump to LABEL if - COND is true. Mark the jump as unlikely to be taken. */ - -static void -emit_unlikely_jump (rtx cond, rtx label) -{ - rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1); - rtx x; - - x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx); - x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x)); - add_reg_note (x, REG_BR_PROB, very_unlikely); -} - -/* A subroutine of the atomic operation splitters. Emit a load-locked - instruction in MODE. */ - -static void -emit_load_locked (enum machine_mode mode, rtx reg, rtx mem) -{ - rtx (*fn) (rtx, rtx) = NULL; - - switch (mode) - { - case SImode: - fn = gen_load_lockedsi; - break; - case DImode: - fn = gen_load_lockeddi; - break; - default: - gcc_unreachable (); - } - emit_insn (fn (reg, mem)); -} - -/* A subroutine of the atomic operation splitters. Emit a store-conditional - instruction in MODE. */ - -static void -emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val) -{ - rtx (*fn) (rtx, rtx, rtx) = NULL; - - switch (mode) - { - case SImode: - fn = gen_store_conditionalsi; - break; - case DImode: - fn = gen_store_conditionaldi; - break; - default: - gcc_unreachable (); - } - - /* Emit sync before stwcx. to address PPC405 Erratum. */ - if (PPC405_ERRATUM77) - emit_insn (gen_hwsync ()); - - emit_insn (fn (res, mem, val)); -} - -/* Expand barriers before and after a load_locked/store_cond sequence. */ - -static rtx -rs6000_pre_atomic_barrier (rtx mem, enum memmodel model) -{ - rtx addr = XEXP (mem, 0); - int strict_p = (reload_in_progress || reload_completed); - - if (!legitimate_indirect_address_p (addr, strict_p) - && !legitimate_indexed_address_p (addr, strict_p)) - { - addr = force_reg (Pmode, addr); - mem = replace_equiv_address_nv (mem, addr); - } - - switch (model) - { - case MEMMODEL_RELAXED: - case MEMMODEL_CONSUME: - case MEMMODEL_ACQUIRE: - break; - case MEMMODEL_RELEASE: - case MEMMODEL_ACQ_REL: - emit_insn (gen_lwsync ()); - break; - case MEMMODEL_SEQ_CST: - emit_insn (gen_hwsync ()); - break; - default: - gcc_unreachable (); - } - return mem; -} - -static void -rs6000_post_atomic_barrier (enum memmodel model) -{ - switch (model) - { - case MEMMODEL_RELAXED: - case MEMMODEL_CONSUME: - case MEMMODEL_RELEASE: - break; - case MEMMODEL_ACQUIRE: - case MEMMODEL_ACQ_REL: - case MEMMODEL_SEQ_CST: - emit_insn (gen_isync ()); - break; - default: - gcc_unreachable (); - } -} - -/* A subroutine of the various atomic expanders. For sub-word operations, - we must adjust things to operate on SImode. Given the original MEM, - return a new aligned memory. Also build and return the quantities by - which to shift and mask. */ - -static rtx -rs6000_adjust_atomic_subword (rtx orig_mem, rtx *pshift, rtx *pmask) -{ - rtx addr, align, shift, mask, mem; - HOST_WIDE_INT shift_mask; - enum machine_mode mode = GET_MODE (orig_mem); - - /* For smaller modes, we have to implement this via SImode. */ - shift_mask = (mode == QImode ? 0x18 : 0x10); - - addr = XEXP (orig_mem, 0); - addr = force_reg (GET_MODE (addr), addr); - - /* Aligned memory containing subword. Generate a new memory. We - do not want any of the existing MEM_ATTR data, as we're now - accessing memory outside the original object. */ - align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-4), - NULL_RTX, 1, OPTAB_LIB_WIDEN); - mem = gen_rtx_MEM (SImode, align); - MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); - if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER) - set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER); - - /* Shift amount for subword relative to aligned word. */ - shift = gen_reg_rtx (SImode); - addr = gen_lowpart (SImode, addr); - emit_insn (gen_rlwinm (shift, addr, GEN_INT (3), GEN_INT (shift_mask))); - shift = expand_simple_binop (SImode, XOR, shift, GEN_INT (shift_mask), - shift, 1, OPTAB_LIB_WIDEN); - *pshift = shift; - - /* Mask for insertion. */ - mask = expand_simple_binop (SImode, ASHIFT, GEN_INT (GET_MODE_MASK (mode)), - shift, NULL_RTX, 1, OPTAB_LIB_WIDEN); - *pmask = mask; - - return mem; -} - -/* A subroutine of the various atomic expanders. For sub-word operands, - combine OLDVAL and NEWVAL via MASK. Returns a new pseduo. */ - -static rtx -rs6000_mask_atomic_subword (rtx oldval, rtx newval, rtx mask) -{ - rtx x; - - x = gen_reg_rtx (SImode); - emit_insn (gen_rtx_SET (VOIDmode, x, - gen_rtx_AND (SImode, - gen_rtx_NOT (SImode, mask), - oldval))); - - x = expand_simple_binop (SImode, IOR, newval, x, x, 1, OPTAB_LIB_WIDEN); - - return x; -} - -/* A subroutine of the various atomic expanders. For sub-word operands, - extract WIDE to NARROW via SHIFT. */ - -static void -rs6000_finish_atomic_subword (rtx narrow, rtx wide, rtx shift) -{ - wide = expand_simple_binop (SImode, LSHIFTRT, wide, shift, - wide, 1, OPTAB_LIB_WIDEN); - emit_move_insn (narrow, gen_lowpart (GET_MODE (narrow), wide)); -} - -/* Expand an atomic compare and swap operation. */ - -void -rs6000_expand_atomic_compare_and_swap (rtx operands[]) -{ - rtx boolval, retval, mem, oldval, newval, cond; - rtx label1, label2, x, mask, shift; - enum machine_mode mode; - enum memmodel mod_s, mod_f; - bool is_weak; - - boolval = operands[0]; - retval = operands[1]; - mem = operands[2]; - oldval = operands[3]; - newval = operands[4]; - is_weak = (INTVAL (operands[5]) != 0); - mod_s = (enum memmodel) INTVAL (operands[6]); - mod_f = (enum memmodel) INTVAL (operands[7]); - mode = GET_MODE (mem); - - mask = shift = NULL_RTX; - if (mode == QImode || mode == HImode) - { - mem = rs6000_adjust_atomic_subword (mem, &shift, &mask); - - /* Shift and mask OLDVAL into position with the word. */ - oldval = convert_modes (SImode, mode, oldval, 1); - oldval = expand_simple_binop (SImode, ASHIFT, oldval, shift, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - - /* Shift and mask NEWVAL into position within the word. */ - newval = convert_modes (SImode, mode, newval, 1); - newval = expand_simple_binop (SImode, ASHIFT, newval, shift, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - - /* Prepare to adjust the return value. */ - retval = gen_reg_rtx (SImode); - mode = SImode; - } - else if (reg_overlap_mentioned_p (retval, oldval)) - oldval = copy_to_reg (oldval); - - mem = rs6000_pre_atomic_barrier (mem, mod_s); - - label1 = NULL_RTX; - if (!is_weak) - { - label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); - emit_label (XEXP (label1, 0)); - } - label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); - - emit_load_locked (mode, retval, mem); - - x = retval; - if (mask) - { - x = expand_simple_binop (SImode, AND, retval, mask, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - } - - cond = gen_reg_rtx (CCmode); - x = gen_rtx_COMPARE (CCmode, x, oldval); - emit_insn (gen_rtx_SET (VOIDmode, cond, x)); - - x = gen_rtx_NE (VOIDmode, cond, const0_rtx); - emit_unlikely_jump (x, label2); - - x = newval; - if (mask) - x = rs6000_mask_atomic_subword (retval, newval, mask); - - emit_store_conditional (mode, cond, mem, x); - - if (!is_weak) - { - x = gen_rtx_NE (VOIDmode, cond, const0_rtx); - emit_unlikely_jump (x, label1); - } - - if (mod_f != MEMMODEL_RELAXED) - emit_label (XEXP (label2, 0)); - - rs6000_post_atomic_barrier (mod_s); - - if (mod_f == MEMMODEL_RELAXED) - emit_label (XEXP (label2, 0)); - - if (shift) - rs6000_finish_atomic_subword (operands[1], retval, shift); - - /* In all cases, CR0 contains EQ on success, and NE on failure. */ - x = gen_rtx_EQ (SImode, cond, const0_rtx); - emit_insn (gen_rtx_SET (VOIDmode, boolval, x)); -} - -/* Expand an atomic exchange operation. */ - -void -rs6000_expand_atomic_exchange (rtx operands[]) -{ - rtx retval, mem, val, cond; - enum machine_mode mode; - enum memmodel model; - rtx label, x, mask, shift; - - retval = operands[0]; - mem = operands[1]; - val = operands[2]; - model = (enum memmodel) INTVAL (operands[3]); - mode = GET_MODE (mem); - - mask = shift = NULL_RTX; - if (mode == QImode || mode == HImode) - { - mem = rs6000_adjust_atomic_subword (mem, &shift, &mask); - - /* Shift and mask VAL into position with the word. */ - val = convert_modes (SImode, mode, val, 1); - val = expand_simple_binop (SImode, ASHIFT, val, shift, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - - /* Prepare to adjust the return value. */ - retval = gen_reg_rtx (SImode); - mode = SImode; - } - - mem = rs6000_pre_atomic_barrier (mem, model); - - label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ()); - emit_label (XEXP (label, 0)); - - emit_load_locked (mode, retval, mem); - - x = val; - if (mask) - x = rs6000_mask_atomic_subword (retval, val, mask); - - cond = gen_reg_rtx (CCmode); - emit_store_conditional (mode, cond, mem, x); - - x = gen_rtx_NE (VOIDmode, cond, const0_rtx); - emit_unlikely_jump (x, label); - - rs6000_post_atomic_barrier (model); - - if (shift) - rs6000_finish_atomic_subword (operands[0], retval, shift); -} - -/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation - to perform. MEM is the memory on which to operate. VAL is the second - operand of the binary operator. BEFORE and AFTER are optional locations to - return the value of MEM either before of after the operation. MODEL_RTX - is a CONST_INT containing the memory model to use. */ - -void -rs6000_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, - rtx orig_before, rtx orig_after, rtx model_rtx) -{ - enum memmodel model = (enum memmodel) INTVAL (model_rtx); - enum machine_mode mode = GET_MODE (mem); - rtx label, x, cond, mask, shift; - rtx before = orig_before, after = orig_after; - - mask = shift = NULL_RTX; - if (mode == QImode || mode == HImode) - { - mem = rs6000_adjust_atomic_subword (mem, &shift, &mask); - - /* Shift and mask VAL into position with the word. */ - val = convert_modes (SImode, mode, val, 1); - val = expand_simple_binop (SImode, ASHIFT, val, shift, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - - switch (code) - { - case IOR: - case XOR: - /* We've already zero-extended VAL. That is sufficient to - make certain that it does not affect other bits. */ - mask = NULL; - break; - - case AND: - /* If we make certain that all of the other bits in VAL are - set, that will be sufficient to not affect other bits. */ - x = gen_rtx_NOT (SImode, mask); - x = gen_rtx_IOR (SImode, x, val); - emit_insn (gen_rtx_SET (VOIDmode, val, x)); - mask = NULL; - break; - - case NOT: - case PLUS: - case MINUS: - /* These will all affect bits outside the field and need - adjustment via MASK within the loop. */ - break; - - default: - gcc_unreachable (); - } - - /* Prepare to adjust the return value. */ - before = gen_reg_rtx (SImode); - if (after) - after = gen_reg_rtx (SImode); - mode = SImode; - } - - mem = rs6000_pre_atomic_barrier (mem, model); - - label = gen_label_rtx (); - emit_label (label); - label = gen_rtx_LABEL_REF (VOIDmode, label); - - if (before == NULL_RTX) - before = gen_reg_rtx (mode); - - emit_load_locked (mode, before, mem); - - if (code == NOT) - { - x = expand_simple_binop (mode, AND, before, val, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - after = expand_simple_unop (mode, NOT, x, after, 1); - } - else - { - after = expand_simple_binop (mode, code, before, val, - after, 1, OPTAB_LIB_WIDEN); - } - - x = after; - if (mask) - { - x = expand_simple_binop (SImode, AND, after, mask, - NULL_RTX, 1, OPTAB_LIB_WIDEN); - x = rs6000_mask_atomic_subword (before, x, mask); - } - - cond = gen_reg_rtx (CCmode); - emit_store_conditional (mode, cond, mem, x); - - x = gen_rtx_NE (VOIDmode, cond, const0_rtx); - emit_unlikely_jump (x, label); - - rs6000_post_atomic_barrier (model); - - if (shift) - { - if (orig_before) - rs6000_finish_atomic_subword (orig_before, before, shift); - if (orig_after) - rs6000_finish_atomic_subword (orig_after, after, shift); - } - else if (orig_after && after != orig_after) - emit_move_insn (orig_after, after); -} - -/* 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 = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : - ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode); - else if (ALTIVEC_REGNO_P (reg)) - reg_mode = V16QImode; - else if (TARGET_E500_DOUBLE && mode == TFmode) - reg_mode = DFmode; - else - reg_mode = word_mode; - reg_mode_size = GET_MODE_SIZE (reg_mode); - - gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode)); - - 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; - rtx restore_basereg = NULL_RTX; - - if (MEM_P (src) && 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 (gen_add3_insn (breg, breg, delta_rtx)); - src = replace_equiv_address (src, breg); - } - else if (! rs6000_offsettable_memref_p (src, reg_mode)) - { - if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY) - { - rtx basereg = XEXP (XEXP (src, 0), 0); - if (TARGET_UPDATE) - { - rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0); - emit_insn (gen_rtx_SET (VOIDmode, ndst, - gen_rtx_MEM (reg_mode, XEXP (src, 0)))); - used_update = true; - } - else - emit_insn (gen_rtx_SET (VOIDmode, basereg, - XEXP (XEXP (src, 0), 1))); - src = replace_equiv_address (src, basereg); - } - else - { - rtx basereg = gen_rtx_REG (Pmode, reg); - emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0))); - src = replace_equiv_address (src, basereg); - } - } - - breg = XEXP (src, 0); - if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM) - breg = XEXP (breg, 0); - - /* If the base register we are using to address memory is - also a destination reg, then change that register last. */ - if (REG_P (breg) - && REGNO (breg) >= REGNO (dst) - && REGNO (breg) < REGNO (dst) + nregs) - j = REGNO (breg) - REGNO (dst); - } - else if (MEM_P (dst) && 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 - ? (TARGET_POWERPC64 - ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc) - : gen_movsi_update (breg, breg, delta_rtx, nsrc)) - : gen_movdi_di_update (breg, breg, delta_rtx, nsrc)); - used_update = true; - } - else - emit_insn (gen_add3_insn (breg, breg, delta_rtx)); - dst = replace_equiv_address (dst, breg); - } - else if (!rs6000_offsettable_memref_p (dst, reg_mode) - && GET_CODE (XEXP (dst, 0)) != LO_SUM) - { - if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY) - { - rtx basereg = XEXP (XEXP (dst, 0), 0); - if (TARGET_UPDATE) - { - rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0); - emit_insn (gen_rtx_SET (VOIDmode, - gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc)); - used_update = true; - } - else - emit_insn (gen_rtx_SET (VOIDmode, basereg, - XEXP (XEXP (dst, 0), 1))); - dst = replace_equiv_address (dst, basereg); - } - else - { - rtx basereg = XEXP (XEXP (dst, 0), 0); - rtx offsetreg = XEXP (XEXP (dst, 0), 1); - gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS - && REG_P (basereg) - && REG_P (offsetreg) - && REGNO (basereg) != REGNO (offsetreg)); - if (REGNO (basereg) == 0) - { - rtx tmp = offsetreg; - offsetreg = basereg; - basereg = tmp; - } - emit_insn (gen_add3_insn (basereg, basereg, offsetreg)); - restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg); - dst = replace_equiv_address (dst, basereg); - } - } - else if (GET_CODE (XEXP (dst, 0)) != LO_SUM) - gcc_assert (rs6000_offsettable_memref_p (dst, reg_mode)); - } - - for (i = 0; i < nregs; i++) - { - /* Calculate index to next subword. */ - ++j; - if (j == nregs) - j = 0; - - /* If compiler already emitted 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))); - } - if (restore_basereg != NULL_RTX) - emit_insn (restore_basereg); - } -} - - -/* This page contains routines that are used to determine what the - function prologue and epilogue code will do and write them out. */ - -static inline bool -save_reg_p (int r) -{ - return !call_used_regs[r] && df_regs_ever_live_p (r); -} - -/* Return the first fixed-point register that is required to be - saved. 32 if none. */ - -int -first_reg_to_save (void) -{ - int first_reg; - - /* Find lowest numbered live register. */ - for (first_reg = 13; first_reg <= 31; first_reg++) - if (save_reg_p (first_reg)) - break; - - if (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM - && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0) - || (DEFAULT_ABI == ABI_DARWIN && flag_pic) - || (TARGET_TOC && TARGET_MINIMAL_TOC)) - && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)) - first_reg = RS6000_PIC_OFFSET_TABLE_REGNUM; - -#if TARGET_MACHO - if (flag_pic - && crtl->uses_pic_offset_table - && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM) - return RS6000_PIC_OFFSET_TABLE_REGNUM; -#endif - - return first_reg; -} - -/* Similar, for FP regs. */ - -int -first_fp_reg_to_save (void) -{ - int first_reg; - - /* Find lowest numbered live register. */ - for (first_reg = 14 + 32; first_reg <= 63; first_reg++) - if (save_reg_p (first_reg)) - break; - - return first_reg; -} - -/* Similar, for AltiVec regs. */ - -static int -first_altivec_reg_to_save (void) -{ - int i; - - /* Stack frame remains as is unless we are in AltiVec ABI. */ - if (! TARGET_ALTIVEC_ABI) - return LAST_ALTIVEC_REGNO + 1; - - /* On Darwin, the unwind routines are compiled without - TARGET_ALTIVEC, and use save_world to save/restore the - altivec registers when necessary. */ - if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return - && ! TARGET_ALTIVEC) - return FIRST_ALTIVEC_REGNO + 20; - - /* Find lowest numbered live register. */ - for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i) - if (save_reg_p (i)) - break; - - return i; -} - -/* Return a 32-bit mask of the AltiVec registers we need to set in - VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in - the 32-bit word is 0. */ - -static unsigned int -compute_vrsave_mask (void) -{ - unsigned int i, mask = 0; - - /* On Darwin, the unwind routines are compiled without - TARGET_ALTIVEC, and use save_world to save/restore the - call-saved altivec registers when necessary. */ - if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return - && ! TARGET_ALTIVEC) - mask |= 0xFFF; - - /* First, find out if we use _any_ altivec registers. */ - for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) - if (df_regs_ever_live_p (i)) - mask |= ALTIVEC_REG_BIT (i); - - if (mask == 0) - return mask; - - /* 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 = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i) - mask &= ~ALTIVEC_REG_BIT (i); - - /* Similarly, remove the return value from the set. */ - { - bool yes = false; - diddle_return_value (is_altivec_return_reg, &yes); - if (yes) - mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN); - } - - return mask; -} - -/* For a very restricted set of circumstances, we can cut down the - size of prologues/epilogues by calling our own save/restore-the-world - routines. */ - -static void -compute_save_world_info (rs6000_stack_t *info_ptr) -{ - info_ptr->world_save_p = 1; - info_ptr->world_save_p - = (WORLD_SAVE_P (info_ptr) - && DEFAULT_ABI == ABI_DARWIN - && !cfun->has_nonlocal_label - && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO - && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO - && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO - && info_ptr->cr_save_p); - - /* This will not work in conjunction with sibcalls. Make sure there - are none. (This check is expensive, but seldom executed.) */ - if (WORLD_SAVE_P (info_ptr)) - { - rtx insn; - for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn)) - if ( GET_CODE (insn) == CALL_INSN - && SIBLING_CALL_P (insn)) - { - info_ptr->world_save_p = 0; - break; - } - } - - if (WORLD_SAVE_P (info_ptr)) - { - /* Even if we're not touching VRsave, make sure there's room on the - stack for it, if it looks like we're calling SAVE_WORLD, which - will attempt to save it. */ - info_ptr->vrsave_size = 4; - - /* If we are going to save the world, we need to save the link register too. */ - info_ptr->lr_save_p = 1; - - /* "Save" the VRsave register too if we're saving the world. */ - if (info_ptr->vrsave_mask == 0) - info_ptr->vrsave_mask = compute_vrsave_mask (); - - /* Because the Darwin register save/restore routines only handle - F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency - check. */ - gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO - && (info_ptr->first_altivec_reg_save - >= FIRST_SAVED_ALTIVEC_REGNO)); - } - return; -} - - -static void -is_altivec_return_reg (rtx reg, void *xyes) -{ - bool *yes = (bool *) xyes; - if (REGNO (reg) == ALTIVEC_ARG_RETURN) - *yes = true; -} - - -/* Look for user-defined global regs in the range FIRST to LAST-1. - We should not restore these, and so cannot use lmw or out-of-line - restore functions if there are any. We also can't save them - (well, emit frame notes for them), because frame unwinding during - exception handling will restore saved registers. */ - -static bool -global_regs_p (unsigned first, unsigned last) -{ - while (first < last) - if (global_regs[first++]) - return true; - return false; -} - -/* Determine the strategy for savings/restoring registers. */ - -enum { - SAVRES_MULTIPLE = 0x1, - SAVE_INLINE_FPRS = 0x2, - SAVE_INLINE_GPRS = 0x4, - REST_INLINE_FPRS = 0x8, - REST_INLINE_GPRS = 0x10, - SAVE_NOINLINE_GPRS_SAVES_LR = 0x20, - SAVE_NOINLINE_FPRS_SAVES_LR = 0x40, - REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80, - SAVE_INLINE_VRS = 0x100, - REST_INLINE_VRS = 0x200 -}; - -static int -rs6000_savres_strategy (rs6000_stack_t *info, - bool using_static_chain_p) -{ - int strategy = 0; - bool lr_save_p; - - if (TARGET_MULTIPLE - && !TARGET_POWERPC64 - && !(TARGET_SPE_ABI && info->spe_64bit_regs_used) - && info->first_gp_reg_save < 31 - && !global_regs_p (info->first_gp_reg_save, 32)) - strategy |= SAVRES_MULTIPLE; - - if (crtl->calls_eh_return - || cfun->machine->ra_need_lr) - strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS - | SAVE_INLINE_GPRS | REST_INLINE_GPRS - | SAVE_INLINE_VRS | REST_INLINE_VRS); - - if (info->first_fp_reg_save == 64 - /* The out-of-line FP routines use double-precision stores; - we can't use those routines if we don't have such stores. */ - || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT) - || global_regs_p (info->first_fp_reg_save, 64)) - strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS; - - if (info->first_gp_reg_save == 32 - || (!(strategy & SAVRES_MULTIPLE) - && global_regs_p (info->first_gp_reg_save, 32))) - strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS; - - if (info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1 - || global_regs_p (info->first_altivec_reg_save, LAST_ALTIVEC_REGNO + 1)) - strategy |= SAVE_INLINE_VRS | REST_INLINE_VRS; - - /* Define cutoff for using out-of-line functions to save registers. */ - if (DEFAULT_ABI == ABI_V4 || TARGET_ELF) - { - if (!optimize_size) - { - strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS; - strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS; - strategy |= SAVE_INLINE_VRS | REST_INLINE_VRS; - } - else - { - /* Prefer out-of-line restore if it will exit. */ - if (info->first_fp_reg_save > 61) - strategy |= SAVE_INLINE_FPRS; - if (info->first_gp_reg_save > 29) - { - if (info->first_fp_reg_save == 64) - strategy |= SAVE_INLINE_GPRS; - else - strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS; - } - if (info->first_altivec_reg_save == LAST_ALTIVEC_REGNO) - strategy |= SAVE_INLINE_VRS | REST_INLINE_VRS; - } - } - else if (DEFAULT_ABI == ABI_DARWIN) - { - if (info->first_fp_reg_save > 60) - strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS; - if (info->first_gp_reg_save > 29) - strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS; - strategy |= SAVE_INLINE_VRS | REST_INLINE_VRS; - } - else - { - gcc_checking_assert (DEFAULT_ABI == ABI_AIX); - if (info->first_fp_reg_save > 61) - strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS; - strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS; - strategy |= SAVE_INLINE_VRS | REST_INLINE_VRS; - } - - /* Don't bother to try to save things out-of-line if r11 is occupied - by the static chain. It would require too much fiddling and the - static chain is rarely used anyway. FPRs are saved w.r.t the stack - pointer on Darwin, and AIX uses r1 or r12. */ - if (using_static_chain_p && DEFAULT_ABI != ABI_AIX) - strategy |= ((DEFAULT_ABI == ABI_DARWIN ? 0 : SAVE_INLINE_FPRS) - | SAVE_INLINE_GPRS - | SAVE_INLINE_VRS | REST_INLINE_VRS); - - /* We can only use the out-of-line routines to restore if we've - saved all the registers from first_fp_reg_save in the prologue. - Otherwise, we risk loading garbage. */ - if ((strategy & (SAVE_INLINE_FPRS | REST_INLINE_FPRS)) == SAVE_INLINE_FPRS) - { - int i; - - for (i = info->first_fp_reg_save; i < 64; i++) - if (!save_reg_p (i)) - { - strategy |= REST_INLINE_FPRS; - break; - } - } - - /* If we are going to use store multiple, then don't even bother - with the out-of-line routines, since the store-multiple - instruction will always be smaller. */ - if ((strategy & SAVRES_MULTIPLE)) - strategy |= SAVE_INLINE_GPRS; - - /* info->lr_save_p isn't yet set if the only reason lr needs to be - saved is an out-of-line save or restore. Set up the value for - the next test (excluding out-of-line gpr restore). */ - lr_save_p = (info->lr_save_p - || !(strategy & SAVE_INLINE_GPRS) - || !(strategy & SAVE_INLINE_FPRS) - || !(strategy & SAVE_INLINE_VRS) - || !(strategy & REST_INLINE_FPRS) - || !(strategy & REST_INLINE_VRS)); - - /* The situation is more complicated with load multiple. We'd - prefer to use the out-of-line routines for restores, since the - "exit" out-of-line routines can handle the restore of LR and the - frame teardown. However if doesn't make sense to use the - out-of-line routine if that is the only reason we'd need to save - LR, and we can't use the "exit" out-of-line gpr restore if we - have saved some fprs; In those cases it is advantageous to use - load multiple when available. */ - if ((strategy & SAVRES_MULTIPLE) - && (!lr_save_p - || info->first_fp_reg_save != 64)) - strategy |= REST_INLINE_GPRS; - - /* Saving CR interferes with the exit routines used on the SPE, so - just punt here. */ - if (TARGET_SPE_ABI - && info->spe_64bit_regs_used - && info->cr_save_p) - strategy |= REST_INLINE_GPRS; - - /* We can only use load multiple or the out-of-line routines to - restore if we've used store multiple or out-of-line routines - in the prologue, i.e. if we've saved all the registers from - first_gp_reg_save. Otherwise, we risk loading garbage. */ - if ((strategy & (SAVE_INLINE_GPRS | REST_INLINE_GPRS | SAVRES_MULTIPLE)) - == SAVE_INLINE_GPRS) - { - int i; - - for (i = info->first_gp_reg_save; i < 32; i++) - if (!save_reg_p (i)) - { - strategy |= REST_INLINE_GPRS; - break; - } - } - - if (TARGET_ELF && TARGET_64BIT) - { - if (!(strategy & SAVE_INLINE_FPRS)) - strategy |= SAVE_NOINLINE_FPRS_SAVES_LR; - else if (!(strategy & SAVE_INLINE_GPRS) - && info->first_fp_reg_save == 64) - strategy |= SAVE_NOINLINE_GPRS_SAVES_LR; - } - else if (TARGET_AIX && !(strategy & REST_INLINE_FPRS)) - strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR; - - if (TARGET_MACHO && !(strategy & SAVE_INLINE_FPRS)) - strategy |= SAVE_NOINLINE_FPRS_SAVES_LR; - - return strategy; -} - -/* Calculate the stack information for the current function. This is - complicated by having two separate calling sequences, the AIX calling - sequence and the V.4 calling sequence. - - AIX (and Darwin/Mac OS X) stack frames look like: - 32-bit 64-bit - SP----> +---------------------------------------+ - | back chain to caller | 0 0 - +---------------------------------------+ - | saved CR | 4 8 (8-11) - +---------------------------------------+ - | saved LR | 8 16 - +---------------------------------------+ - | reserved for compilers | 12 24 - +---------------------------------------+ - | reserved for binders | 16 32 - +---------------------------------------+ - | saved TOC pointer | 20 40 - +---------------------------------------+ - | Parameter save area (P) | 24 48 - +---------------------------------------+ - | Alloca space (A) | 24+P etc. - +---------------------------------------+ - | Local variable space (L) | 24+P+A - +---------------------------------------+ - | Float/int conversion temporary (X) | 24+P+A+L - +---------------------------------------+ - | Save area for AltiVec registers (W) | 24+P+A+L+X - +---------------------------------------+ - | AltiVec alignment padding (Y) | 24+P+A+L+X+W - +---------------------------------------+ - | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y - +---------------------------------------+ - | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z - +---------------------------------------+ - | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G - +---------------------------------------+ - old SP->| back chain to caller's caller | - +---------------------------------------+ - - The required alignment for AIX configurations is two words (i.e., 8 - or 16 bytes). - - - V.4 stack frames look like: - - SP----> +---------------------------------------+ - | back chain to caller | 0 - +---------------------------------------+ - | caller's saved LR | 4 - +---------------------------------------+ - | Parameter save area (P) | 8 - +---------------------------------------+ - | Alloca space (A) | 8+P - +---------------------------------------+ - | Varargs save area (V) | 8+P+A - +---------------------------------------+ - | Local variable space (L) | 8+P+A+V - +---------------------------------------+ - | Float/int conversion temporary (X) | 8+P+A+V+L - +---------------------------------------+ - | Save area for AltiVec registers (W) | 8+P+A+V+L+X - +---------------------------------------+ - | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W - +---------------------------------------+ - | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y - +---------------------------------------+ - | SPE: area for 64-bit GP registers | - +---------------------------------------+ - | SPE alignment padding | - +---------------------------------------+ - | saved CR (C) | 8+P+A+V+L+X+W+Y+Z - +---------------------------------------+ - | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C - +---------------------------------------+ - | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G - +---------------------------------------+ - old SP->| back chain to caller's caller | - +---------------------------------------+ - - The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is - given. (But note below and in sysv4.h that we require only 8 and - may round up the size of our stack frame anyways. The historical - reason is early versions of powerpc-linux which didn't properly - 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. 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 - above.) */ - -#ifndef ABI_STACK_BOUNDARY -#define ABI_STACK_BOUNDARY STACK_BOUNDARY -#endif - -static rs6000_stack_t * -rs6000_stack_info (void) -{ - rs6000_stack_t *info_ptr = &stack_info; - int reg_size = TARGET_32BIT ? 4 : 8; - int ehrd_size; - int save_align; - int first_gp; - HOST_WIDE_INT non_fixed_size; - bool using_static_chain_p; - - if (reload_completed && info_ptr->reload_completed) - return info_ptr; - - memset (info_ptr, 0, sizeof (*info_ptr)); - info_ptr->reload_completed = reload_completed; - - 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 - = spe_func_has_64bit_regs_p () + 1; - info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1; - } - - /* Select which calling sequence. */ - 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. Reload may need it to - get at a constant; if so, it will have already created a constant - pool entry for it. */ - if (((TARGET_TOC && TARGET_MINIMAL_TOC) - || (flag_pic == 1 && DEFAULT_ABI == ABI_V4) - || (flag_pic && DEFAULT_ABI == ABI_DARWIN)) - && crtl->uses_const_pool - && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM) - first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM; - else - first_gp = info_ptr->first_gp_reg_save; - - info_ptr->gp_size = reg_size * (32 - first_gp); - - /* For the SPE, we have an additional upper 32-bits on each GPR. - Ideally we should save the entire 64-bits only when the upper - half is used in SIMD instructions. Since we only record - 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 if but one register - gets used in 64-bits. Otherwise, all the registers in the frame - get saved in 32-bits. - - 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 && info_ptr->spe_64bit_regs_used != 0) - info_ptr->gp_size = 0; - - info_ptr->first_fp_reg_save = first_fp_reg_to_save (); - info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save); - - info_ptr->first_altivec_reg_save = first_altivec_reg_to_save (); - info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1 - - info_ptr->first_altivec_reg_save); - - /* Does this function call anything? */ - info_ptr->calls_p = (! crtl->is_leaf - || cfun->machine->ra_needs_full_frame); - - /* Determine if we need to save the condition code registers. */ - if (df_regs_ever_live_p (CR2_REGNO) - || df_regs_ever_live_p (CR3_REGNO) - || df_regs_ever_live_p (CR4_REGNO)) - { - info_ptr->cr_save_p = 1; - if (DEFAULT_ABI == ABI_V4) - info_ptr->cr_size = reg_size; - } - - /* If the current function calls __builtin_eh_return, then we need - to allocate stack space for registers that will hold data for - the exception handler. */ - if (crtl->calls_eh_return) - { - unsigned int i; - for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i) - continue; - - /* SPE saves EH registers in 64-bits. */ - ehrd_size = i * (TARGET_SPE_ABI - && info_ptr->spe_64bit_regs_used != 0 - ? UNITS_PER_SPE_WORD : UNITS_PER_WORD); - } - else - ehrd_size = 0; - - /* Determine various sizes. */ - info_ptr->reg_size = reg_size; - info_ptr->fixed_size = RS6000_SAVE_AREA; - info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8); - info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size, - TARGET_ALTIVEC ? 16 : 8); - if (FRAME_GROWS_DOWNWARD) - info_ptr->vars_size - += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size - + info_ptr->parm_size, - ABI_STACK_BOUNDARY / BITS_PER_UNIT) - - (info_ptr->fixed_size + info_ptr->vars_size - + info_ptr->parm_size); - - if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0) - info_ptr->spe_gp_size = 8 * (32 - first_gp); - else - info_ptr->spe_gp_size = 0; - - if (TARGET_ALTIVEC_ABI) - info_ptr->vrsave_mask = compute_vrsave_mask (); - else - info_ptr->vrsave_mask = 0; - - if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask) - info_ptr->vrsave_size = 4; - else - info_ptr->vrsave_size = 0; - - compute_save_world_info (info_ptr); - - /* Calculate the offsets. */ - switch (DEFAULT_ABI) - { - case ABI_NONE: - default: - gcc_unreachable (); - - case ABI_AIX: - 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; - - if (TARGET_ALTIVEC_ABI) - { - info_ptr->vrsave_save_offset - = info_ptr->gp_save_offset - info_ptr->vrsave_size; - - /* Align stack so vector save area is on a quadword boundary. - The padding goes above the vectors. */ - if (info_ptr->altivec_size != 0) - info_ptr->altivec_padding_size - = info_ptr->vrsave_save_offset & 0xF; - else - info_ptr->altivec_padding_size = 0; - - info_ptr->altivec_save_offset - = info_ptr->vrsave_save_offset - - info_ptr->altivec_padding_size - - info_ptr->altivec_size; - gcc_assert (info_ptr->altivec_size == 0 - || info_ptr->altivec_save_offset % 16 == 0); - - /* Adjust for AltiVec case. */ - info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size; - } - else - info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size; - info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */ - info_ptr->lr_save_offset = 2*reg_size; - break; - - case ABI_V4: - info_ptr->fp_save_offset = - info_ptr->fp_size; - 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 && info_ptr->spe_64bit_regs_used != 0) - { - /* Align stack so SPE GPR save area is aligned on a - double-word boundary. */ - if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0) - info_ptr->spe_padding_size - = 8 - (-info_ptr->cr_save_offset % 8); - else - info_ptr->spe_padding_size = 0; - - info_ptr->spe_gp_save_offset - = info_ptr->cr_save_offset - - info_ptr->spe_padding_size - - info_ptr->spe_gp_size; - - /* Adjust for SPE case. */ - info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset; - } - else if (TARGET_ALTIVEC_ABI) - { - info_ptr->vrsave_save_offset - = info_ptr->cr_save_offset - info_ptr->vrsave_size; - - /* Align stack so vector save area is on a quadword boundary. */ - if (info_ptr->altivec_size != 0) - info_ptr->altivec_padding_size - = 16 - (-info_ptr->vrsave_save_offset % 16); - else - info_ptr->altivec_padding_size = 0; - - info_ptr->altivec_save_offset - = info_ptr->vrsave_save_offset - - info_ptr->altivec_padding_size - - info_ptr->altivec_size; - - /* Adjust for AltiVec case. */ - info_ptr->ehrd_offset = info_ptr->altivec_save_offset; - } - else - info_ptr->ehrd_offset = info_ptr->cr_save_offset; - info_ptr->ehrd_offset -= ehrd_size; - info_ptr->lr_save_offset = reg_size; - break; - } - - save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8; - info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size - + info_ptr->gp_size - + info_ptr->altivec_size - + info_ptr->altivec_padding_size - + info_ptr->spe_gp_size - + info_ptr->spe_padding_size - + ehrd_size - + info_ptr->cr_size - + info_ptr->vrsave_size, - save_align); - - non_fixed_size = (info_ptr->vars_size - + info_ptr->parm_size - + info_ptr->save_size); - - info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size, - ABI_STACK_BOUNDARY / BITS_PER_UNIT); - - /* Determine if we need to save the link register. */ - if (info_ptr->calls_p - || (DEFAULT_ABI == ABI_AIX - && crtl->profile - && !TARGET_PROFILE_KERNEL) - || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca) -#ifdef TARGET_RELOCATABLE - || (TARGET_RELOCATABLE && (get_pool_size () != 0)) -#endif - || rs6000_ra_ever_killed ()) - info_ptr->lr_save_p = 1; - - using_static_chain_p = (cfun->static_chain_decl != NULL_TREE - && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) - && call_used_regs[STATIC_CHAIN_REGNUM]); - info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr, - using_static_chain_p); - - if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS) - || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS) - || !(info_ptr->savres_strategy & SAVE_INLINE_VRS) - || !(info_ptr->savres_strategy & REST_INLINE_GPRS) - || !(info_ptr->savres_strategy & REST_INLINE_FPRS) - || !(info_ptr->savres_strategy & REST_INLINE_VRS)) - info_ptr->lr_save_p = 1; - - if (info_ptr->lr_save_p) - df_set_regs_ever_live (LR_REGNO, true); - - /* Determine if we need to allocate any stack frame: - - For AIX we need to push the stack if a frame pointer is needed - (because the stack might be dynamically adjusted), if we are - debugging, if we make calls, or if the sum of fp_save, gp_save, - and local variables are more than the space needed to save all - non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8 - + 18*8 = 288 (GPR13 reserved). - - For V.4 we don't have the stack cushion that AIX uses, but assume - that the debugger can handle stackless frames. */ - - if (info_ptr->calls_p) - info_ptr->push_p = 1; - - 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 = non_fixed_size > (TARGET_32BIT ? 220 : 288); - - /* Zero offsets if we're not saving those registers. */ - if (info_ptr->fp_size == 0) - info_ptr->fp_save_offset = 0; - - if (info_ptr->gp_size == 0) - info_ptr->gp_save_offset = 0; - - if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0) - info_ptr->altivec_save_offset = 0; - - /* Zero VRSAVE offset if not saved and restored. */ - if (! TARGET_ALTIVEC_VRSAVE || info_ptr->vrsave_mask == 0) - info_ptr->vrsave_save_offset = 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) - info_ptr->lr_save_offset = 0; - - if (! info_ptr->cr_save_p) - info_ptr->cr_save_offset = 0; - - return info_ptr; -} - -/* 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 (crtl->calls_eh_return - || cfun->calls_setjmp - || crtl->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; - - /* FIXME: This should be implemented with attributes... - - (set_attr "spe64" "true")....then, - if (get_spe64(insn)) return true; - - It's the only reliable way to do the stuff below. */ - - i = PATTERN (insn); - if (GET_CODE (i) == SET) - { - enum machine_mode mode = GET_MODE (SET_SRC (i)); - - if (SPE_VECTOR_MODE (mode)) - return true; - if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode)) - return true; - } - } - } - - return false; -} - -static void -debug_stack_info (rs6000_stack_t *info) -{ - const char *abi_string; - - if (! info) - info = rs6000_stack_info (); - - fprintf (stderr, "\nStack information for function %s:\n", - ((current_function_decl && DECL_NAME (current_function_decl)) - ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl)) - : "<unknown>")); - - switch (info->abi) - { - default: abi_string = "Unknown"; break; - case ABI_NONE: abi_string = "NONE"; break; - case ABI_AIX: abi_string = "AIX"; break; - case ABI_DARWIN: abi_string = "Darwin"; break; - case ABI_V4: abi_string = "V.4"; break; - } - - fprintf (stderr, "\tABI = %5s\n", abi_string); - - if (TARGET_ALTIVEC_ABI) - fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n"); - - if (TARGET_SPE_ABI) - fprintf (stderr, "\tSPE ABI extensions enabled.\n"); - - if (info->first_gp_reg_save != 32) - fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save); - - if (info->first_fp_reg_save != 64) - fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save); - - if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO) - fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n", - info->first_altivec_reg_save); - - if (info->lr_save_p) - fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p); - - if (info->cr_save_p) - fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p); - - if (info->vrsave_mask) - fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask); - - if (info->push_p) - fprintf (stderr, "\tpush_p = %5d\n", info->push_p); - - if (info->calls_p) - fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p); - - if (info->gp_save_offset) - fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset); - - if (info->fp_save_offset) - fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset); - - if (info->altivec_save_offset) - fprintf (stderr, "\taltivec_save_offset = %5d\n", - info->altivec_save_offset); - - if (info->spe_gp_save_offset) - fprintf (stderr, "\tspe_gp_save_offset = %5d\n", - info->spe_gp_save_offset); - - if (info->vrsave_save_offset) - fprintf (stderr, "\tvrsave_save_offset = %5d\n", - info->vrsave_save_offset); - - if (info->lr_save_offset) - fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset); - - if (info->cr_save_offset) - fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset); - - if (info->varargs_save_offset) - fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset); - - if (info->total_size) - fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n", - info->total_size); - - if (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); - - if (info->fixed_size) - fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size); - - if (info->gp_size) - fprintf (stderr, "\tgp_size = %5d\n", info->gp_size); - - if (info->spe_gp_size) - fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size); - - if (info->fp_size) - fprintf (stderr, "\tfp_size = %5d\n", info->fp_size); - - if (info->altivec_size) - fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size); - - if (info->vrsave_size) - fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size); - - if (info->altivec_padding_size) - fprintf (stderr, "\taltivec_padding_size= %5d\n", - info->altivec_padding_size); - - if (info->spe_padding_size) - fprintf (stderr, "\tspe_padding_size = %5d\n", - info->spe_padding_size); - - if (info->cr_size) - fprintf (stderr, "\tcr_size = %5d\n", info->cr_size); - - if (info->save_size) - fprintf (stderr, "\tsave_size = %5d\n", info->save_size); - - if (info->reg_size != 4) - fprintf (stderr, "\treg_size = %5d\n", info->reg_size); - - fprintf (stderr, "\tsave-strategy = %04x\n", info->savres_strategy); - - fprintf (stderr, "\n"); -} - -rtx -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 || (DEFAULT_ABI != ABI_AIX && flag_pic)) - { - cfun->machine->ra_needs_full_frame = 1; - - return - gen_rtx_MEM - (Pmode, - memory_address - (Pmode, - plus_constant (Pmode, - copy_to_reg - (gen_rtx_MEM (Pmode, - memory_address (Pmode, frame))), - RETURN_ADDRESS_OFFSET))); - } - - cfun->machine->ra_need_lr = 1; - return get_hard_reg_initial_val (Pmode, LR_REGNO); -} - -/* Say whether a function is a candidate for sibcall handling or not. */ - -static bool -rs6000_function_ok_for_sibcall (tree decl, tree exp) -{ - tree fntype; - - if (decl) - fntype = TREE_TYPE (decl); - else - fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp))); - - /* We can't do it if the called function has more vector parameters - than the current function; there's nowhere to put the VRsave code. */ - if (TARGET_ALTIVEC_ABI - && TARGET_ALTIVEC_VRSAVE - && !(decl && decl == current_function_decl)) - { - function_args_iterator args_iter; - tree type; - int nvreg = 0; - - /* Functions with vector parameters are required to have a - prototype, so the argument type info must be available - here. */ - FOREACH_FUNCTION_ARGS(fntype, type, args_iter) - if (TREE_CODE (type) == VECTOR_TYPE - && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type))) - nvreg++; - - FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter) - if (TREE_CODE (type) == VECTOR_TYPE - && ALTIVEC_OR_VSX_VECTOR_MODE (TYPE_MODE (type))) - nvreg--; - - if (nvreg > 0) - return false; - } - - /* Under the AIX ABI we can't allow calls to non-local functions, - because the callee may have a different TOC pointer to the - caller and there's no way to ensure we restore the TOC when we - return. With the secure-plt SYSV ABI we can't make non-local - calls when -fpic/PIC because the plt call stubs use r30. */ - if (DEFAULT_ABI == ABI_DARWIN - || (DEFAULT_ABI == ABI_AIX - && decl - && !DECL_EXTERNAL (decl) - && (*targetm.binds_local_p) (decl)) - || (DEFAULT_ABI == ABI_V4 - && (!TARGET_SECURE_PLT - || !flag_pic - || (decl - && (*targetm.binds_local_p) (decl))))) - { - tree attr_list = TYPE_ATTRIBUTES (fntype); - - if (!lookup_attribute ("longcall", attr_list) - || lookup_attribute ("shortcall", attr_list)) - return true; - } - - return false; -} - -/* NULL if INSN insn is valid within a low-overhead loop. - Otherwise return why doloop cannot be applied. - PowerPC uses the COUNT register for branch on table instructions. */ - -static const char * -rs6000_invalid_within_doloop (const_rtx insn) -{ - if (CALL_P (insn)) - return "Function call in the loop."; - - if (JUMP_P (insn) - && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC - || GET_CODE (PATTERN (insn)) == ADDR_VEC)) - return "Computed branch in the loop."; - - return NULL; -} - -static int -rs6000_ra_ever_killed (void) -{ - rtx top; - rtx reg; - rtx insn; - - if (cfun->is_thunk) - return 0; - - if (cfun->machine->lr_save_state) - return cfun->machine->lr_save_state - 1; - - /* 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. */ - - /* Also, the prologue can generate a store into LR that - doesn't really count, like this: - - move LR->R0 - bcl to set PIC register - move LR->R31 - move R0->LR - - When we're called from the epilogue, we need to avoid counting - this as a store. */ - - push_topmost_sequence (); - top = get_insns (); - pop_topmost_sequence (); - reg = gen_rtx_REG (Pmode, LR_REGNO); - - for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn)) - { - if (INSN_P (insn)) - { - if (CALL_P (insn)) - { - if (!SIBLING_CALL_P (insn)) - return 1; - } - else if (find_regno_note (insn, REG_INC, LR_REGNO)) - return 1; - else if (set_of (reg, insn) != NULL_RTX - && !prologue_epilogue_contains (insn)) - return 1; - } - } - return 0; -} - -/* Emit instructions needed to load the TOC register. - This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is - a constant pool; or for SVR4 -fpic. */ - -void -rs6000_emit_load_toc_table (int fromprolog) -{ - rtx dest; - dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); - - if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic) - { - char buf[30]; - rtx lab, tmp1, tmp2, got; - - lab = gen_label_rtx (); - ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab)); - lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); - if (flag_pic == 2) - got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name); - else - got = rs6000_got_sym (); - tmp1 = tmp2 = dest; - if (!fromprolog) - { - tmp1 = gen_reg_rtx (Pmode); - tmp2 = gen_reg_rtx (Pmode); - } - emit_insn (gen_load_toc_v4_PIC_1 (lab)); - emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO)); - emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab)); - emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab)); - } - else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1) - { - emit_insn (gen_load_toc_v4_pic_si ()); - emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); - } - else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2) - { - char buf[30]; - rtx temp0 = (fromprolog - ? gen_rtx_REG (Pmode, 0) - : gen_reg_rtx (Pmode)); - - if (fromprolog) - { - rtx symF, symL; - - ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); - symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); - - ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); - symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); - - emit_insn (gen_load_toc_v4_PIC_1 (symF)); - emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); - emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF)); - } - else - { - rtx tocsym, lab; - - tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name); - lab = gen_label_rtx (); - emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab)); - emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO)); - if (TARGET_LINK_STACK) - emit_insn (gen_addsi3 (dest, dest, GEN_INT (4))); - emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest)); - } - emit_insn (gen_addsi3 (dest, temp0, dest)); - } - else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC) - { - /* This is for AIX code running in non-PIC ELF32. */ - char buf[30]; - rtx realsym; - ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); - realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); - - emit_insn (gen_elf_high (dest, realsym)); - emit_insn (gen_elf_low (dest, dest, realsym)); - } - else - { - gcc_assert (DEFAULT_ABI == ABI_AIX); - - if (TARGET_32BIT) - emit_insn (gen_load_toc_aix_si (dest)); - else - emit_insn (gen_load_toc_aix_di (dest)); - } -} - -/* 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 - || cfun->calls_alloca - || info->total_size > 32767) - { - tmp = gen_frame_mem (Pmode, frame_rtx); - emit_move_insn (operands[1], tmp); - frame_rtx = operands[1]; - } - else if (info->push_p) - sp_offset = info->total_size; - - tmp = plus_constant (Pmode, frame_rtx, - info->lr_save_offset + sp_offset); - tmp = gen_frame_mem (Pmode, tmp); - emit_move_insn (tmp, operands[0]); - } - else - emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]); - - /* Freeze lr_save_p. We've just emitted rtl that depends on the - state of lr_save_p so any change from here on would be a bug. In - particular, stop rs6000_ra_ever_killed from considering the SET - of lr we may have added just above. */ - cfun->machine->lr_save_state = info->lr_save_p + 1; -} - -static GTY(()) alias_set_type set = -1; - -alias_set_type -get_TOC_alias_set (void) -{ - if (set == -1) - set = new_alias_set (); - return set; -} - -/* 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; - - 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 (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 (rtx symbol, rtx largetoc_reg) -{ - rtx tocrel, tocreg, hi; - - if (TARGET_DEBUG_ADDR) - { - if (GET_CODE (symbol) == SYMBOL_REF) - fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n", - XSTR (symbol, 0)); - else - { - fprintf (stderr, "\ncreate_TOC_reference, code %s:\n", - GET_RTX_NAME (GET_CODE (symbol))); - debug_rtx (symbol); - } - } - - if (!can_create_pseudo_p ()) - df_set_regs_ever_live (TOC_REGISTER, true); - - tocreg = gen_rtx_REG (Pmode, TOC_REGISTER); - tocrel = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, symbol, tocreg), UNSPEC_TOCREL); - if (TARGET_CMODEL == CMODEL_SMALL || can_create_pseudo_p ()) - return tocrel; - - hi = gen_rtx_HIGH (Pmode, copy_rtx (tocrel)); - if (largetoc_reg != NULL) - { - emit_move_insn (largetoc_reg, hi); - hi = largetoc_reg; - } - return gen_rtx_LO_SUM (Pmode, hi, tocrel); -} - -/* Issue assembly directives that create a reference to the given DWARF - FRAME_TABLE_LABEL from the current function section. */ -void -rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label) -{ - fprintf (asm_out_file, "\t.ref %s\n", - (* targetm.strip_name_encoding) (frame_table_label)); -} - -/* This ties together stack memory (MEM with an alias set of frame_alias_set) - and the change to the stack pointer. */ - -static void -rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed) -{ - rtvec p; - int i; - rtx regs[3]; - - i = 0; - regs[i++] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); - if (hard_frame_needed) - regs[i++] = gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM); - if (!(REGNO (fp) == STACK_POINTER_REGNUM - || (hard_frame_needed - && REGNO (fp) == HARD_FRAME_POINTER_REGNUM))) - regs[i++] = fp; - - p = rtvec_alloc (i); - while (--i >= 0) - { - rtx mem = gen_frame_mem (BLKmode, regs[i]); - RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, const0_rtx); - } - - emit_insn (gen_stack_tie (gen_rtx_PARALLEL (VOIDmode, p))); -} - -/* Emit the correct code for allocating stack space, as insns. - If COPY_REG, make sure a copy of the old frame is left there. - The generated code may use hard register 0 as a temporary. */ - -static void -rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg, int copy_off) -{ - rtx insn; - rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); - rtx tmp_reg = gen_rtx_REG (Pmode, 0); - rtx todec = gen_int_mode (-size, Pmode); - rtx par, set, mem; - - if (INTVAL (todec) != -size) - { - warning (0, "stack frame too large"); - emit_insn (gen_trap ()); - return; - } - - if (crtl->limit_stack) - { - if (REG_P (stack_limit_rtx) - && REGNO (stack_limit_rtx) > 1 - && REGNO (stack_limit_rtx) <= 31) - { - emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size))); - emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg, - const0_rtx)); - } - else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF - && TARGET_32BIT - && DEFAULT_ABI == ABI_V4) - { - rtx toload = gen_rtx_CONST (VOIDmode, - 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, - const0_rtx)); - } - else - warning (0, "stack limit expression is not supported"); - } - - if (copy_reg) - { - if (copy_off != 0) - emit_insn (gen_add3_insn (copy_reg, stack_reg, GEN_INT (copy_off))); - else - emit_move_insn (copy_reg, stack_reg); - } - - if (size > 32767) - { - /* Need a note here so that try_split doesn't get confused. */ - if (get_last_insn () == NULL_RTX) - emit_note (NOTE_INSN_DELETED); - insn = emit_move_insn (tmp_reg, todec); - try_split (PATTERN (insn), insn, 0); - todec = tmp_reg; - } - - insn = emit_insn (TARGET_32BIT - ? gen_movsi_update_stack (stack_reg, stack_reg, - todec, stack_reg) - : gen_movdi_di_update_stack (stack_reg, stack_reg, - todec, stack_reg)); - /* Since we didn't use gen_frame_mem to generate the MEM, grab - it now and set the alias set/attributes. The above gen_*_update - calls will generate a PARALLEL with the MEM set being the first - operation. */ - par = PATTERN (insn); - gcc_assert (GET_CODE (par) == PARALLEL); - set = XVECEXP (par, 0, 0); - gcc_assert (GET_CODE (set) == SET); - mem = SET_DEST (set); - gcc_assert (MEM_P (mem)); - MEM_NOTRAP_P (mem) = 1; - set_mem_alias_set (mem, get_frame_alias_set ()); - - RTX_FRAME_RELATED_P (insn) = 1; - add_reg_note (insn, REG_FRAME_RELATED_EXPR, - gen_rtx_SET (VOIDmode, stack_reg, - gen_rtx_PLUS (Pmode, stack_reg, - GEN_INT (-size)))); -} - -#define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP) - -#if PROBE_INTERVAL > 32768 -#error Cannot use indexed addressing mode for stack probing -#endif - -/* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE, - inclusive. These are offsets from the current stack pointer. */ - -static void -rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size) -{ - /* See if we have a constant small number of probes to generate. If so, - that's the easy case. */ - if (first + size <= 32768) - { - HOST_WIDE_INT i; - - /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until - it exceeds SIZE. If only one probe is needed, this will not - generate any code. Then probe at FIRST + SIZE. */ - for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL) - emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, - -(first + i))); - - emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, - -(first + size))); - } - - /* Otherwise, do the same as above, but in a loop. Note that we must be - extra careful with variables wrapping around because we might be at - the very top (or the very bottom) of the address space and we have - to be able to handle this case properly; in particular, we use an - equality test for the loop condition. */ - else - { - HOST_WIDE_INT rounded_size; - rtx r12 = gen_rtx_REG (Pmode, 12); - rtx r0 = gen_rtx_REG (Pmode, 0); - - /* Sanity check for the addressing mode we're going to use. */ - gcc_assert (first <= 32768); - - /* Step 1: round SIZE to the previous multiple of the interval. */ - - rounded_size = size & -PROBE_INTERVAL; - - - /* Step 2: compute initial and final value of the loop counter. */ - - /* TEST_ADDR = SP + FIRST. */ - emit_insn (gen_rtx_SET (VOIDmode, r12, - plus_constant (Pmode, stack_pointer_rtx, - -first))); - - /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */ - if (rounded_size > 32768) - { - emit_move_insn (r0, GEN_INT (-rounded_size)); - emit_insn (gen_rtx_SET (VOIDmode, r0, - gen_rtx_PLUS (Pmode, r12, r0))); - } - else - emit_insn (gen_rtx_SET (VOIDmode, r0, - plus_constant (Pmode, r12, -rounded_size))); - - - /* Step 3: the loop - - while (TEST_ADDR != LAST_ADDR) - { - TEST_ADDR = TEST_ADDR + PROBE_INTERVAL - probe at TEST_ADDR - } - - probes at FIRST + N * PROBE_INTERVAL for values of N from 1 - until it is equal to ROUNDED_SIZE. */ - - if (TARGET_64BIT) - emit_insn (gen_probe_stack_rangedi (r12, r12, r0)); - else - emit_insn (gen_probe_stack_rangesi (r12, r12, r0)); - - - /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time - that SIZE is equal to ROUNDED_SIZE. */ - - if (size != rounded_size) - emit_stack_probe (plus_constant (Pmode, r12, rounded_size - size)); - } -} - -/* Probe a range of stack addresses from REG1 to REG2 inclusive. These are - absolute addresses. */ - -const char * -output_probe_stack_range (rtx reg1, rtx reg2) -{ - static int labelno = 0; - char loop_lab[32], end_lab[32]; - rtx xops[2]; - - ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno); - ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++); - - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab); - - /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */ - xops[0] = reg1; - xops[1] = reg2; - if (TARGET_64BIT) - output_asm_insn ("cmpd 0,%0,%1", xops); - else - output_asm_insn ("cmpw 0,%0,%1", xops); - - fputs ("\tbeq 0,", asm_out_file); - assemble_name_raw (asm_out_file, end_lab); - fputc ('\n', asm_out_file); - - /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */ - xops[1] = GEN_INT (-PROBE_INTERVAL); - output_asm_insn ("addi %0,%0,%1", xops); - - /* Probe at TEST_ADDR and branch. */ - xops[1] = gen_rtx_REG (Pmode, 0); - output_asm_insn ("stw %1,0(%0)", xops); - fprintf (asm_out_file, "\tb "); - assemble_name_raw (asm_out_file, loop_lab); - fputc ('\n', asm_out_file); - - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab); - - return ""; -} - -/* 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 - deduce these equivalences by itself so it wasn't necessary to hold - its hand so much. Don't be tempted to always supply d2_f_d_e with - the actual cfa register, ie. r31 when we are using a hard frame - pointer. That fails when saving regs off r1, and sched moves the - r31 setup past the reg saves. */ - -static rtx -rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val, - rtx reg2, rtx rreg) -{ - rtx real, temp; - - if (REGNO (reg) == STACK_POINTER_REGNUM && reg2 == NULL_RTX) - { - /* No need for any replacement. Just set RTX_FRAME_RELATED_P. */ - int i; - - gcc_checking_assert (val == 0); - real = PATTERN (insn); - if (GET_CODE (real) == PARALLEL) - for (i = 0; i < XVECLEN (real, 0); i++) - if (GET_CODE (XVECEXP (real, 0, i)) == SET) - { - rtx set = XVECEXP (real, 0, i); - - RTX_FRAME_RELATED_P (set) = 1; - } - RTX_FRAME_RELATED_P (insn) = 1; - return insn; - } - - /* copy_rtx will not make unique copies of registers, so we need to - ensure we don't have unwanted sharing here. */ - if (reg == reg2) - reg = gen_raw_REG (GET_MODE (reg), REGNO (reg)); - - if (reg == rreg) - reg = gen_raw_REG (GET_MODE (reg), REGNO (reg)); - - real = copy_rtx (PATTERN (insn)); - - if (reg2 != NULL_RTX) - real = replace_rtx (real, reg2, rreg); - - if (REGNO (reg) == STACK_POINTER_REGNUM) - gcc_checking_assert (val == 0); - else - real = replace_rtx (real, reg, - gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, - STACK_POINTER_REGNUM), - GEN_INT (val))); - - /* We expect that 'real' is either a SET or a PARALLEL containing - SETs (and possibly other stuff). In a PARALLEL, all the SETs - are important so they all have to be marked RTX_FRAME_RELATED_P. */ - - if (GET_CODE (real) == SET) - { - rtx set = real; - - temp = simplify_rtx (SET_SRC (set)); - if (temp) - SET_SRC (set) = temp; - temp = simplify_rtx (SET_DEST (set)); - if (temp) - SET_DEST (set) = temp; - if (GET_CODE (SET_DEST (set)) == MEM) - { - temp = simplify_rtx (XEXP (SET_DEST (set), 0)); - if (temp) - XEXP (SET_DEST (set), 0) = temp; - } - } - else - { - int i; - - gcc_assert (GET_CODE (real) == PARALLEL); - for (i = 0; i < XVECLEN (real, 0); i++) - if (GET_CODE (XVECEXP (real, 0, i)) == SET) - { - rtx set = XVECEXP (real, 0, i); - - temp = simplify_rtx (SET_SRC (set)); - if (temp) - SET_SRC (set) = temp; - temp = simplify_rtx (SET_DEST (set)); - if (temp) - SET_DEST (set) = temp; - if (GET_CODE (SET_DEST (set)) == MEM) - { - temp = simplify_rtx (XEXP (SET_DEST (set), 0)); - if (temp) - XEXP (SET_DEST (set), 0) = temp; - } - RTX_FRAME_RELATED_P (set) = 1; - } - } - - RTX_FRAME_RELATED_P (insn) = 1; - add_reg_note (insn, REG_FRAME_RELATED_EXPR, real); - - return insn; -} - -/* Returns an insn that has a vrsave set operation with the - appropriate CLOBBERs. */ - -static rtx -generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep) -{ - int nclobs, i; - rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1]; - rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO); - - clobs[0] - = gen_rtx_SET (VOIDmode, - vrsave, - gen_rtx_UNSPEC_VOLATILE (SImode, - gen_rtvec (2, reg, vrsave), - UNSPECV_SET_VRSAVE)); - - nclobs = 1; - - /* We need to clobber the registers in the mask so the scheduler - does not move sets to VRSAVE before sets of AltiVec registers. - - However, if the function receives nonlocal gotos, reload will set - all call saved registers live. We will end up with: - - (set (reg 999) (mem)) - (parallel [ (set (reg vrsave) (unspec blah)) - (clobber (reg 999))]) - - The clobber will cause the store into reg 999 to be dead, and - flow will attempt to delete an epilogue insn. In this case, we - need an unspec use/set of the register. */ - - for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) - if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) - { - if (!epiloguep || call_used_regs [i]) - clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode, - gen_rtx_REG (V4SImode, i)); - else - { - rtx reg = gen_rtx_REG (V4SImode, i); - - clobs[nclobs++] - = gen_rtx_SET (VOIDmode, - reg, - gen_rtx_UNSPEC (V4SImode, - gen_rtvec (1, reg), 27)); - } - } - - insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs)); - - for (i = 0; i < nclobs; ++i) - XVECEXP (insn, 0, i) = clobs[i]; - - return insn; -} - -static rtx -gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store) -{ - rtx addr, mem; - - addr = gen_rtx_PLUS (Pmode, frame_reg, GEN_INT (offset)); - mem = gen_frame_mem (GET_MODE (reg), addr); - return gen_rtx_SET (VOIDmode, store ? mem : reg, store ? reg : mem); -} - -static rtx -gen_frame_load (rtx reg, rtx frame_reg, int offset) -{ - return gen_frame_set (reg, frame_reg, offset, false); -} - -static rtx -gen_frame_store (rtx reg, rtx frame_reg, int offset) -{ - return gen_frame_set (reg, frame_reg, offset, true); -} - -/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes. - Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */ - -static rtx -emit_frame_save (rtx frame_reg, enum machine_mode mode, - unsigned int regno, int offset, HOST_WIDE_INT frame_reg_to_sp) -{ - rtx reg, insn; - - /* Some cases that need register indexed addressing. */ - gcc_checking_assert (!((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) - || (TARGET_VSX && ALTIVEC_OR_VSX_VECTOR_MODE (mode)) - || (TARGET_E500_DOUBLE && mode == DFmode) - || (TARGET_SPE_ABI - && SPE_VECTOR_MODE (mode) - && !SPE_CONST_OFFSET_OK (offset)))); - - reg = gen_rtx_REG (mode, regno); - insn = emit_insn (gen_frame_store (reg, frame_reg, offset)); - return rs6000_frame_related (insn, frame_reg, frame_reg_to_sp, - NULL_RTX, NULL_RTX); -} - -/* Emit an offset memory reference suitable for a frame store, while - converting to a valid addressing mode. */ - -static rtx -gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset) -{ - rtx int_rtx, offset_rtx; - - int_rtx = GEN_INT (offset); - - if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode) && !SPE_CONST_OFFSET_OK (offset)) - || (TARGET_E500_DOUBLE && mode == DFmode)) - { - offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH); - emit_move_insn (offset_rtx, int_rtx); - } - else - offset_rtx = int_rtx; - - return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx)); -} - -#ifndef TARGET_FIX_AND_CONTINUE -#define TARGET_FIX_AND_CONTINUE 0 -#endif - -/* It's really GPR 13 or 14, FPR 14 and VR 20. We need the smallest. */ -#define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO -#define LAST_SAVRES_REGISTER 31 -#define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1) - -enum { - SAVRES_LR = 0x1, - SAVRES_SAVE = 0x2, - SAVRES_REG = 0x0c, - SAVRES_GPR = 0, - SAVRES_FPR = 4, - SAVRES_VR = 8 -}; - -static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][12]; - -/* Temporary holding space for an out-of-line register save/restore - routine name. */ -static char savres_routine_name[30]; - -/* Return the name for an out-of-line register save/restore routine. - We are saving/restoring GPRs if GPR is true. */ - -static char * -rs6000_savres_routine_name (rs6000_stack_t *info, int regno, int sel) -{ - const char *prefix = ""; - const char *suffix = ""; - - /* Different targets are supposed to define - {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed - routine name could be defined with: - - sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX) - - This is a nice idea in practice, but in reality, things are - complicated in several ways: - - - ELF targets have save/restore routines for GPRs. - - - SPE targets use different prefixes for 32/64-bit registers, and - neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen. - - - PPC64 ELF targets have routines for save/restore of GPRs that - differ in what they do with the link register, so having a set - prefix doesn't work. (We only use one of the save routines at - the moment, though.) - - - PPC32 elf targets have "exit" versions of the restore routines - that restore the link register and can save some extra space. - These require an extra suffix. (There are also "tail" versions - of the restore routines and "GOT" versions of the save routines, - but we don't generate those at present. Same problems apply, - though.) - - We deal with all this by synthesizing our own prefix/suffix and - using that for the simple sprintf call shown above. */ - if (TARGET_SPE) - { - /* No floating point saves on the SPE. */ - gcc_assert ((sel & SAVRES_REG) == SAVRES_GPR); - - if ((sel & SAVRES_SAVE)) - prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_"; - else - prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_"; - - if ((sel & SAVRES_LR)) - suffix = "_x"; - } - else if (DEFAULT_ABI == ABI_V4) - { - if (TARGET_64BIT) - goto aix_names; - - if ((sel & SAVRES_REG) == SAVRES_GPR) - prefix = (sel & SAVRES_SAVE) ? "_savegpr_" : "_restgpr_"; - else if ((sel & SAVRES_REG) == SAVRES_FPR) - prefix = (sel & SAVRES_SAVE) ? "_savefpr_" : "_restfpr_"; - else if ((sel & SAVRES_REG) == SAVRES_VR) - prefix = (sel & SAVRES_SAVE) ? "_savevr_" : "_restvr_"; - else - abort (); - - if ((sel & SAVRES_LR)) - suffix = "_x"; - } - else if (DEFAULT_ABI == ABI_AIX) - { -#if !defined (POWERPC_LINUX) && !defined (POWERPC_FREEBSD) - /* No out-of-line save/restore routines for GPRs on AIX. */ - gcc_assert (!TARGET_AIX || (sel & SAVRES_REG) != SAVRES_GPR); -#endif - - aix_names: - if ((sel & SAVRES_REG) == SAVRES_GPR) - prefix = ((sel & SAVRES_SAVE) - ? ((sel & SAVRES_LR) ? "_savegpr0_" : "_savegpr1_") - : ((sel & SAVRES_LR) ? "_restgpr0_" : "_restgpr1_")); - else if ((sel & SAVRES_REG) == SAVRES_FPR) - { -#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD) - if ((sel & SAVRES_LR)) - prefix = ((sel & SAVRES_SAVE) ? "_savefpr_" : "_restfpr_"); - else -#endif - { - prefix = (sel & SAVRES_SAVE) ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX; - suffix = (sel & SAVRES_SAVE) ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX; - } - } - else if ((sel & SAVRES_REG) == SAVRES_VR) - prefix = (sel & SAVRES_SAVE) ? "_savevr_" : "_restvr_"; - else - abort (); - } - - if (DEFAULT_ABI == ABI_DARWIN) - { - /* The Darwin approach is (slightly) different, in order to be - compatible with code generated by the system toolchain. There is a - single symbol for the start of save sequence, and the code here - embeds an offset into that code on the basis of the first register - to be saved. */ - prefix = (sel & SAVRES_SAVE) ? "save" : "rest" ; - if ((sel & SAVRES_REG) == SAVRES_GPR) - sprintf (savres_routine_name, "*%sGPR%s%s%.0d ; %s r%d-r31", prefix, - ((sel & SAVRES_LR) ? "x" : ""), (regno == 13 ? "" : "+"), - (regno - 13) * 4, prefix, regno); - else if ((sel & SAVRES_REG) == SAVRES_FPR) - sprintf (savres_routine_name, "*%sFP%s%.0d ; %s f%d-f31", prefix, - (regno == 14 ? "" : "+"), (regno - 14) * 4, prefix, regno); - else if ((sel & SAVRES_REG) == SAVRES_VR) - sprintf (savres_routine_name, "*%sVEC%s%.0d ; %s v%d-v31", prefix, - (regno == 20 ? "" : "+"), (regno - 20) * 8, prefix, regno); - else - abort (); - } - else - sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix); - - return savres_routine_name; -} - -/* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine. - We are saving/restoring GPRs if GPR is true. */ - -static rtx -rs6000_savres_routine_sym (rs6000_stack_t *info, int sel) -{ - int regno = ((sel & SAVRES_REG) == SAVRES_GPR - ? info->first_gp_reg_save - : (sel & SAVRES_REG) == SAVRES_FPR - ? info->first_fp_reg_save - 32 - : (sel & SAVRES_REG) == SAVRES_VR - ? info->first_altivec_reg_save - FIRST_ALTIVEC_REGNO - : -1); - rtx sym; - int select = sel; - - /* On the SPE, we never have any FPRs, but we do have 32/64-bit - versions of the gpr routines. */ - if (TARGET_SPE_ABI && (sel & SAVRES_REG) == SAVRES_GPR - && info->spe_64bit_regs_used) - select ^= SAVRES_FPR ^ SAVRES_GPR; - - /* Don't generate bogus routine names. */ - gcc_assert (FIRST_SAVRES_REGISTER <= regno - && regno <= LAST_SAVRES_REGISTER - && select >= 0 && select <= 12); - - sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]; - - if (sym == NULL) - { - char *name; - - name = rs6000_savres_routine_name (info, regno, sel); - - sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select] - = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); - SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION; - } - - return sym; -} - -/* Emit a sequence of insns, including a stack tie if needed, for - resetting the stack pointer. If UPDT_REGNO is not 1, then don't - reset the stack pointer, but move the base of the frame into - reg UPDT_REGNO for use by out-of-line register restore routines. */ - -static rtx -rs6000_emit_stack_reset (rs6000_stack_t *info, - rtx frame_reg_rtx, HOST_WIDE_INT frame_off, - unsigned updt_regno) -{ - rtx updt_reg_rtx; - - /* This blockage is needed so that sched doesn't decide to move - the sp change before the register restores. */ - if (DEFAULT_ABI == ABI_V4 - || (TARGET_SPE_ABI - && info->spe_64bit_regs_used != 0 - && info->first_gp_reg_save != 32)) - rs6000_emit_stack_tie (frame_reg_rtx, frame_pointer_needed); - - /* If we are restoring registers out-of-line, we will be using the - "exit" variants of the restore routines, which will reset the - stack for us. But we do need to point updt_reg into the - right place for those routines. */ - updt_reg_rtx = gen_rtx_REG (Pmode, updt_regno); - - if (frame_off != 0) - return emit_insn (gen_add3_insn (updt_reg_rtx, - frame_reg_rtx, GEN_INT (frame_off))); - else if (REGNO (frame_reg_rtx) != updt_regno) - return emit_move_insn (updt_reg_rtx, frame_reg_rtx); - - return NULL_RTX; -} - -/* Return the register number used as a pointer by out-of-line - save/restore functions. */ - -static inline unsigned -ptr_regno_for_savres (int sel) -{ - if (DEFAULT_ABI == ABI_AIX) - return (sel & SAVRES_REG) == SAVRES_FPR || (sel & SAVRES_LR) ? 1 : 12; - return DEFAULT_ABI == ABI_DARWIN && (sel & SAVRES_REG) == SAVRES_FPR ? 1 : 11; -} - -/* Construct a parallel rtx describing the effect of a call to an - out-of-line register save/restore routine, and emit the insn - or jump_insn as appropriate. */ - -static rtx -rs6000_emit_savres_rtx (rs6000_stack_t *info, - rtx frame_reg_rtx, int save_area_offset, int lr_offset, - enum machine_mode reg_mode, int sel) -{ - int i; - int offset, start_reg, end_reg, n_regs, use_reg; - int reg_size = GET_MODE_SIZE (reg_mode); - rtx sym; - rtvec p; - rtx par, insn; - - offset = 0; - start_reg = ((sel & SAVRES_REG) == SAVRES_GPR - ? info->first_gp_reg_save - : (sel & SAVRES_REG) == SAVRES_FPR - ? info->first_fp_reg_save - : (sel & SAVRES_REG) == SAVRES_VR - ? info->first_altivec_reg_save - : -1); - end_reg = ((sel & SAVRES_REG) == SAVRES_GPR - ? 32 - : (sel & SAVRES_REG) == SAVRES_FPR - ? 64 - : (sel & SAVRES_REG) == SAVRES_VR - ? LAST_ALTIVEC_REGNO + 1 - : -1); - n_regs = end_reg - start_reg; - p = rtvec_alloc (3 + ((sel & SAVRES_LR) ? 1 : 0) - + ((sel & SAVRES_REG) == SAVRES_VR ? 1 : 0) - + n_regs); - - if (!(sel & SAVRES_SAVE) && (sel & SAVRES_LR)) - RTVEC_ELT (p, offset++) = ret_rtx; - - RTVEC_ELT (p, offset++) - = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO)); - - sym = rs6000_savres_routine_sym (info, sel); - RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym); - - use_reg = ptr_regno_for_savres (sel); - if ((sel & SAVRES_REG) == SAVRES_VR) - { - /* Vector regs are saved/restored using [reg+reg] addressing. */ - RTVEC_ELT (p, offset++) - = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, use_reg)); - RTVEC_ELT (p, offset++) - = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 0)); - } - else - RTVEC_ELT (p, offset++) - = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, use_reg)); - - for (i = 0; i < end_reg - start_reg; i++) - RTVEC_ELT (p, i + offset) - = gen_frame_set (gen_rtx_REG (reg_mode, start_reg + i), - frame_reg_rtx, save_area_offset + reg_size * i, - (sel & SAVRES_SAVE) != 0); - - if ((sel & SAVRES_SAVE) && (sel & SAVRES_LR)) - RTVEC_ELT (p, i + offset) - = gen_frame_store (gen_rtx_REG (Pmode, 0), frame_reg_rtx, lr_offset); - - par = gen_rtx_PARALLEL (VOIDmode, p); - - if (!(sel & SAVRES_SAVE) && (sel & SAVRES_LR)) - { - insn = emit_jump_insn (par); - JUMP_LABEL (insn) = ret_rtx; - } - else - insn = emit_insn (par); - return insn; -} - -/* Determine whether the gp REG is really used. */ - -static bool -rs6000_reg_live_or_pic_offset_p (int reg) -{ - /* If the function calls eh_return, claim used all the registers that would - be checked for liveness otherwise. This is required for the PIC offset - register with -mminimal-toc on AIX, as it is advertised as "fixed" for - register allocation purposes in this case. */ - - return (((crtl->calls_eh_return || df_regs_ever_live_p (reg)) - && (!call_used_regs[reg] - || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM - && !TARGET_SINGLE_PIC_BASE - && TARGET_TOC && TARGET_MINIMAL_TOC))) - || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM - && !TARGET_SINGLE_PIC_BASE - && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0) - || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))); -} - -/* Emit function prologue as insns. */ - -void -rs6000_emit_prologue (void) -{ - rs6000_stack_t *info = rs6000_stack_info (); - 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_reg_rtx = sp_reg_rtx; - unsigned int cr_save_regno; - rtx cr_save_rtx = NULL_RTX; - rtx insn; - int strategy; - int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE - && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) - && call_used_regs[STATIC_CHAIN_REGNUM]); - /* Offset to top of frame for frame_reg and sp respectively. */ - HOST_WIDE_INT frame_off = 0; - HOST_WIDE_INT sp_off = 0; - -#ifdef ENABLE_CHECKING - /* Track and check usage of r0, r11, r12. */ - int reg_inuse = using_static_chain_p ? 1 << 11 : 0; -#define START_USE(R) do \ - { \ - gcc_assert ((reg_inuse & (1 << (R))) == 0); \ - reg_inuse |= 1 << (R); \ - } while (0) -#define END_USE(R) do \ - { \ - gcc_assert ((reg_inuse & (1 << (R))) != 0); \ - reg_inuse &= ~(1 << (R)); \ - } while (0) -#define NOT_INUSE(R) do \ - { \ - gcc_assert ((reg_inuse & (1 << (R))) == 0); \ - } while (0) -#else -#define START_USE(R) do {} while (0) -#define END_USE(R) do {} while (0) -#define NOT_INUSE(R) do {} while (0) -#endif - - if (flag_stack_usage_info) - current_function_static_stack_size = info->total_size; - - if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size) - rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size); - - if (TARGET_FIX_AND_CONTINUE) - { - /* gdb on darwin arranges to forward a function from the old - address by modifying the first 5 instructions of the function - to branch to the overriding function. This is necessary to - permit function pointers that point to the old function to - actually forward to the new function. */ - emit_insn (gen_nop ()); - emit_insn (gen_nop ()); - emit_insn (gen_nop ()); - emit_insn (gen_nop ()); - emit_insn (gen_nop ()); - } - - if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0) - { - reg_mode = V2SImode; - reg_size = 8; - } - - /* Handle world saves specially here. */ - if (WORLD_SAVE_P (info)) - { - int i, j, sz; - rtx treg; - rtvec p; - rtx reg0; - - /* save_world expects lr in r0. */ - reg0 = gen_rtx_REG (Pmode, 0); - if (info->lr_save_p) - { - insn = emit_move_insn (reg0, - gen_rtx_REG (Pmode, LR_REGNO)); - RTX_FRAME_RELATED_P (insn) = 1; - } - - /* The SAVE_WORLD and RESTORE_WORLD routines make a number of - assumptions about the offsets of various bits of the stack - frame. */ - gcc_assert (info->gp_save_offset == -220 - && info->fp_save_offset == -144 - && info->lr_save_offset == 8 - && info->cr_save_offset == 4 - && info->push_p - && info->lr_save_p - && (!crtl->calls_eh_return - || info->ehrd_offset == -432) - && info->vrsave_save_offset == -224 - && info->altivec_save_offset == -416); - - treg = gen_rtx_REG (SImode, 11); - emit_move_insn (treg, GEN_INT (-info->total_size)); - - /* SAVE_WORLD takes the caller's LR in R0 and the frame size - in R11. It also clobbers R12, so beware! */ - - /* Preserve CR2 for save_world prologues */ - sz = 5; - sz += 32 - info->first_gp_reg_save; - sz += 64 - info->first_fp_reg_save; - sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1; - p = rtvec_alloc (sz); - j = 0; - RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode, - gen_rtx_REG (SImode, - LR_REGNO)); - RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, - gen_rtx_SYMBOL_REF (Pmode, - "*save_world")); - /* We do floats first so that the instruction pattern matches - properly. */ - for (i = 0; i < 64 - info->first_fp_reg_save; i++) - RTVEC_ELT (p, j++) - = gen_frame_store (gen_rtx_REG (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode, - info->first_fp_reg_save + i), - frame_reg_rtx, - info->fp_save_offset + frame_off + 8 * i); - for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++) - RTVEC_ELT (p, j++) - = gen_frame_store (gen_rtx_REG (V4SImode, - info->first_altivec_reg_save + i), - frame_reg_rtx, - info->altivec_save_offset + frame_off + 16 * i); - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - RTVEC_ELT (p, j++) - = gen_frame_store (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), - frame_reg_rtx, - info->gp_save_offset + frame_off + reg_size * i); - - /* CR register traditionally saved as CR2. */ - RTVEC_ELT (p, j++) - = gen_frame_store (gen_rtx_REG (SImode, CR2_REGNO), - frame_reg_rtx, info->cr_save_offset + frame_off); - /* Explain about use of R0. */ - if (info->lr_save_p) - RTVEC_ELT (p, j++) - = gen_frame_store (reg0, - frame_reg_rtx, info->lr_save_offset + frame_off); - /* Explain what happens to the stack pointer. */ - { - rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg); - RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval); - } - - insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - treg, GEN_INT (-info->total_size)); - sp_off = frame_off = info->total_size; - } - - strategy = info->savres_strategy; - - /* For V.4, update stack before we do any saving and set back pointer. */ - if (! WORLD_SAVE_P (info) - && info->push_p - && (DEFAULT_ABI == ABI_V4 - || crtl->calls_eh_return)) - { - bool need_r11 = (TARGET_SPE - ? (!(strategy & SAVE_INLINE_GPRS) - && info->spe_64bit_regs_used == 0) - : (!(strategy & SAVE_INLINE_FPRS) - || !(strategy & SAVE_INLINE_GPRS) - || !(strategy & SAVE_INLINE_VRS))); - int ptr_regno = -1; - rtx ptr_reg = NULL_RTX; - int ptr_off = 0; - - if (info->total_size < 32767) - frame_off = info->total_size; - else if (need_r11) - ptr_regno = 11; - else if (info->cr_save_p - || info->lr_save_p - || info->first_fp_reg_save < 64 - || info->first_gp_reg_save < 32 - || info->altivec_size != 0 - || info->vrsave_mask != 0 - || crtl->calls_eh_return) - ptr_regno = 12; - else - { - /* The prologue won't be saving any regs so there is no need - to set up a frame register to access any frame save area. - We also won't be using frame_off anywhere below, but set - the correct value anyway to protect against future - changes to this function. */ - frame_off = info->total_size; - } - if (ptr_regno != -1) - { - /* Set up the frame offset to that needed by the first - out-of-line save function. */ - START_USE (ptr_regno); - ptr_reg = gen_rtx_REG (Pmode, ptr_regno); - frame_reg_rtx = ptr_reg; - if (!(strategy & SAVE_INLINE_FPRS) && info->fp_size != 0) - gcc_checking_assert (info->fp_save_offset + info->fp_size == 0); - else if (!(strategy & SAVE_INLINE_GPRS) && info->first_gp_reg_save < 32) - ptr_off = info->gp_save_offset + info->gp_size; - else if (!(strategy & SAVE_INLINE_VRS) && info->altivec_size != 0) - ptr_off = info->altivec_save_offset + info->altivec_size; - frame_off = -ptr_off; - } - rs6000_emit_allocate_stack (info->total_size, ptr_reg, ptr_off); - sp_off = info->total_size; - if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (frame_reg_rtx, false); - } - - /* If we use the link register, get it into r0. */ - if (!WORLD_SAVE_P (info) && info->lr_save_p) - { - rtx addr, reg, mem; - - reg = gen_rtx_REG (Pmode, 0); - START_USE (0); - insn = emit_move_insn (reg, gen_rtx_REG (Pmode, LR_REGNO)); - RTX_FRAME_RELATED_P (insn) = 1; - - if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR - | SAVE_NOINLINE_FPRS_SAVES_LR))) - { - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->lr_save_offset + frame_off)); - mem = gen_rtx_MEM (Pmode, addr); - /* This should not be of rs6000_sr_alias_set, because of - __builtin_return_address. */ - - insn = emit_move_insn (mem, reg); - rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - NULL_RTX, NULL_RTX); - END_USE (0); - } - } - - /* If we need to save CR, put it into r12 or r11. Choose r12 except when - r12 will be needed by out-of-line gpr restore. */ - cr_save_regno = (DEFAULT_ABI == ABI_AIX - && !(strategy & (SAVE_INLINE_GPRS - | SAVE_NOINLINE_GPRS_SAVES_LR)) - ? 11 : 12); - if (!WORLD_SAVE_P (info) - && info->cr_save_p - && REGNO (frame_reg_rtx) != cr_save_regno - && !(using_static_chain_p && cr_save_regno == 11)) - { - rtx set; - - cr_save_rtx = gen_rtx_REG (SImode, cr_save_regno); - START_USE (cr_save_regno); - insn = emit_insn (gen_movesi_from_cr (cr_save_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - /* Now, there's no way that dwarf2out_frame_debug_expr is going - 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. */ - set = gen_rtx_SET (VOIDmode, cr_save_rtx, - gen_rtx_REG (SImode, CR2_REGNO)); - add_reg_note (insn, REG_FRAME_RELATED_EXPR, set); - } - - /* Do any required saving of fpr's. If only one or two to save, do - it ourselves. Otherwise, call function. */ - if (!WORLD_SAVE_P (info) && (strategy & SAVE_INLINE_FPRS)) - { - int i; - for (i = 0; i < 64 - info->first_fp_reg_save; i++) - if (save_reg_p (info->first_fp_reg_save + i)) - emit_frame_save (frame_reg_rtx, - (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), - info->first_fp_reg_save + i, - info->fp_save_offset + frame_off + 8 * i, - sp_off - frame_off); - } - else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64) - { - bool lr = (strategy & SAVE_NOINLINE_FPRS_SAVES_LR) != 0; - int sel = SAVRES_SAVE | SAVRES_FPR | (lr ? SAVRES_LR : 0); - unsigned ptr_regno = ptr_regno_for_savres (sel); - rtx ptr_reg = frame_reg_rtx; - - if (REGNO (frame_reg_rtx) == ptr_regno) - gcc_checking_assert (frame_off == 0); - else - { - ptr_reg = gen_rtx_REG (Pmode, ptr_regno); - NOT_INUSE (ptr_regno); - emit_insn (gen_add3_insn (ptr_reg, - frame_reg_rtx, GEN_INT (frame_off))); - } - insn = rs6000_emit_savres_rtx (info, ptr_reg, - info->fp_save_offset, - info->lr_save_offset, - DFmode, sel); - rs6000_frame_related (insn, ptr_reg, sp_off, - NULL_RTX, NULL_RTX); - if (lr) - END_USE (0); - } - - /* Save GPRs. This is done as a PARALLEL if we are using - the store-multiple instructions. */ - if (!WORLD_SAVE_P (info) - && TARGET_SPE_ABI - && info->spe_64bit_regs_used != 0 - && info->first_gp_reg_save != 32) - { - int i; - rtx spe_save_area_ptr; - HOST_WIDE_INT save_off; - int ool_adjust = 0; - - /* Determine whether we can address all of the registers that need - to be saved with an offset from frame_reg_rtx that fits in - the small const field for SPE memory instructions. */ - int spe_regs_addressable - = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + frame_off - + reg_size * (32 - info->first_gp_reg_save - 1)) - && (strategy & SAVE_INLINE_GPRS)); - - if (spe_regs_addressable) - { - spe_save_area_ptr = frame_reg_rtx; - save_off = frame_off; - } - else - { - /* Make r11 point to the start of the SPE save area. We need - to be careful here if r11 is holding the static chain. If - it is, then temporarily save it in r0. */ - HOST_WIDE_INT offset; - - if (!(strategy & SAVE_INLINE_GPRS)) - ool_adjust = 8 * (info->first_gp_reg_save - - (FIRST_SAVRES_REGISTER + 1)); - offset = info->spe_gp_save_offset + frame_off - ool_adjust; - spe_save_area_ptr = gen_rtx_REG (Pmode, 11); - save_off = frame_off - offset; - - if (using_static_chain_p) - { - rtx r0 = gen_rtx_REG (Pmode, 0); - - START_USE (0); - gcc_assert (info->first_gp_reg_save > 11); - - emit_move_insn (r0, spe_save_area_ptr); - } - else if (REGNO (frame_reg_rtx) != 11) - START_USE (11); - - emit_insn (gen_addsi3 (spe_save_area_ptr, - frame_reg_rtx, GEN_INT (offset))); - if (!using_static_chain_p && REGNO (frame_reg_rtx) == 11) - frame_off = -info->spe_gp_save_offset + ool_adjust; - } - - if ((strategy & SAVE_INLINE_GPRS)) - { - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) - emit_frame_save (spe_save_area_ptr, reg_mode, - info->first_gp_reg_save + i, - (info->spe_gp_save_offset + save_off - + reg_size * i), - sp_off - save_off); - } - else - { - insn = rs6000_emit_savres_rtx (info, spe_save_area_ptr, - info->spe_gp_save_offset + save_off, - 0, reg_mode, - SAVRES_SAVE | SAVRES_GPR); - - rs6000_frame_related (insn, spe_save_area_ptr, sp_off - save_off, - NULL_RTX, NULL_RTX); - } - - /* Move the static chain pointer back. */ - if (!spe_regs_addressable) - { - if (using_static_chain_p) - { - emit_move_insn (spe_save_area_ptr, gen_rtx_REG (Pmode, 0)); - END_USE (0); - } - else if (REGNO (frame_reg_rtx) != 11) - END_USE (11); - } - } - else if (!WORLD_SAVE_P (info) && !(strategy & SAVE_INLINE_GPRS)) - { - bool lr = (strategy & SAVE_NOINLINE_GPRS_SAVES_LR) != 0; - int sel = SAVRES_SAVE | SAVRES_GPR | (lr ? SAVRES_LR : 0); - unsigned ptr_regno = ptr_regno_for_savres (sel); - rtx ptr_reg = frame_reg_rtx; - bool ptr_set_up = REGNO (ptr_reg) == ptr_regno; - int end_save = info->gp_save_offset + info->gp_size; - int ptr_off; - - if (!ptr_set_up) - ptr_reg = gen_rtx_REG (Pmode, ptr_regno); - - /* Need to adjust r11 (r12) if we saved any FPRs. */ - if (end_save + frame_off != 0) - { - rtx offset = GEN_INT (end_save + frame_off); - - if (ptr_set_up) - frame_off = -end_save; - else - NOT_INUSE (ptr_regno); - emit_insn (gen_add3_insn (ptr_reg, frame_reg_rtx, offset)); - } - else if (!ptr_set_up) - { - NOT_INUSE (ptr_regno); - emit_move_insn (ptr_reg, frame_reg_rtx); - } - ptr_off = -end_save; - insn = rs6000_emit_savres_rtx (info, ptr_reg, - info->gp_save_offset + ptr_off, - info->lr_save_offset + ptr_off, - reg_mode, sel); - rs6000_frame_related (insn, ptr_reg, sp_off - ptr_off, - NULL_RTX, NULL_RTX); - if (lr) - END_USE (0); - } - else if (!WORLD_SAVE_P (info) && (strategy & SAVRES_MULTIPLE)) - { - rtvec p; - int i; - p = rtvec_alloc (32 - info->first_gp_reg_save); - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - RTVEC_ELT (p, i) - = gen_frame_store (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), - frame_reg_rtx, - info->gp_save_offset + frame_off + reg_size * i); - insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - NULL_RTX, NULL_RTX); - } - else if (!WORLD_SAVE_P (info)) - { - int i; - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) - emit_frame_save (frame_reg_rtx, reg_mode, - info->first_gp_reg_save + i, - info->gp_save_offset + frame_off + reg_size * i, - sp_off - frame_off); - } - - if (crtl->calls_eh_return) - { - unsigned int i; - rtvec p; - - for (i = 0; ; ++i) - { - unsigned int regno = EH_RETURN_DATA_REGNO (i); - if (regno == INVALID_REGNUM) - break; - } - - p = rtvec_alloc (i); - - for (i = 0; ; ++i) - { - unsigned int regno = EH_RETURN_DATA_REGNO (i); - if (regno == INVALID_REGNUM) - break; - - insn - = gen_frame_store (gen_rtx_REG (reg_mode, regno), - sp_reg_rtx, - info->ehrd_offset + sp_off + reg_size * (int) i); - RTVEC_ELT (p, i) = insn; - RTX_FRAME_RELATED_P (insn) = 1; - } - - insn = emit_insn (gen_blockage ()); - RTX_FRAME_RELATED_P (insn) = 1; - add_reg_note (insn, REG_FRAME_RELATED_EXPR, gen_rtx_PARALLEL (VOIDmode, p)); - } - - /* In AIX ABI we need to make sure r2 is really saved. */ - if (TARGET_AIX && crtl->calls_eh_return) - { - rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump; - rtx save_insn, join_insn, note; - long toc_restore_insn; - - tmp_reg = gen_rtx_REG (Pmode, 11); - tmp_reg_si = gen_rtx_REG (SImode, 11); - if (using_static_chain_p) - { - START_USE (0); - emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg); - } - else - START_USE (11); - emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO)); - /* Peek at instruction to which this function returns. If it's - restoring r2, then we know we've already saved r2. We can't - unconditionally save r2 because the value we have will already - be updated if we arrived at this function via a plt call or - toc adjusting stub. */ - emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg)); - toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028; - hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode); - emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi)); - compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO); - validate_condition_mode (EQ, CCUNSmode); - lo = gen_int_mode (toc_restore_insn & 0xffff, SImode); - emit_insn (gen_rtx_SET (VOIDmode, compare_result, - gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo))); - toc_save_done = gen_label_rtx (); - jump = gen_rtx_IF_THEN_ELSE (VOIDmode, - gen_rtx_EQ (VOIDmode, compare_result, - const0_rtx), - gen_rtx_LABEL_REF (VOIDmode, toc_save_done), - pc_rtx); - jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump)); - JUMP_LABEL (jump) = toc_save_done; - LABEL_NUSES (toc_save_done) += 1; - - save_insn = emit_frame_save (frame_reg_rtx, reg_mode, - TOC_REGNUM, frame_off + 5 * reg_size, - sp_off - frame_off); - - emit_label (toc_save_done); - - /* ??? If we leave SAVE_INSN as marked as saving R2, then we'll - have a CFG that has different saves along different paths. - Move the note to a dummy blockage insn, which describes that - R2 is unconditionally saved after the label. */ - /* ??? An alternate representation might be a special insn pattern - containing both the branch and the store. That might let the - code that minimizes the number of DW_CFA_advance opcodes better - freedom in placing the annotations. */ - note = find_reg_note (save_insn, REG_FRAME_RELATED_EXPR, NULL); - if (note) - remove_note (save_insn, note); - else - note = alloc_reg_note (REG_FRAME_RELATED_EXPR, - copy_rtx (PATTERN (save_insn)), NULL_RTX); - RTX_FRAME_RELATED_P (save_insn) = 0; - - join_insn = emit_insn (gen_blockage ()); - REG_NOTES (join_insn) = note; - RTX_FRAME_RELATED_P (join_insn) = 1; - - if (using_static_chain_p) - { - emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0)); - END_USE (0); - } - else - END_USE (11); - } - - /* Save CR if we use any that must be preserved. */ - if (!WORLD_SAVE_P (info) && info->cr_save_p) - { - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->cr_save_offset + frame_off)); - rtx mem = gen_frame_mem (SImode, addr); - /* See the large comment above about why CR2_REGNO is used. */ - rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO); - - /* If we didn't copy cr before, do so now using r0. */ - if (cr_save_rtx == NULL_RTX) - { - rtx set; - - START_USE (0); - cr_save_rtx = gen_rtx_REG (SImode, 0); - insn = emit_insn (gen_movesi_from_cr (cr_save_rtx)); - RTX_FRAME_RELATED_P (insn) = 1; - set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg); - add_reg_note (insn, REG_FRAME_RELATED_EXPR, set); - } - insn = emit_move_insn (mem, cr_save_rtx); - END_USE (REGNO (cr_save_rtx)); - - rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - NULL_RTX, NULL_RTX); - } - - /* Update stack and set back pointer unless this is V.4, - for which it was done previously. */ - if (!WORLD_SAVE_P (info) && info->push_p - && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return)) - { - rtx ptr_reg = NULL; - int ptr_off = 0; - - /* If saving altivec regs we need to be able to address all save - locations using a 16-bit offset. */ - if ((strategy & SAVE_INLINE_VRS) == 0 - || (info->altivec_size != 0 - && (info->altivec_save_offset + info->altivec_size - 16 - + info->total_size - frame_off) > 32767) - || (info->vrsave_size != 0 - && (info->vrsave_save_offset - + info->total_size - frame_off) > 32767)) - { - int sel = SAVRES_SAVE | SAVRES_VR; - unsigned ptr_regno = ptr_regno_for_savres (sel); - - if (using_static_chain_p - && ptr_regno == STATIC_CHAIN_REGNUM) - ptr_regno = 12; - if (REGNO (frame_reg_rtx) != ptr_regno) - START_USE (ptr_regno); - ptr_reg = gen_rtx_REG (Pmode, ptr_regno); - frame_reg_rtx = ptr_reg; - ptr_off = info->altivec_save_offset + info->altivec_size; - frame_off = -ptr_off; - } - else if (REGNO (frame_reg_rtx) == 1) - frame_off = info->total_size; - rs6000_emit_allocate_stack (info->total_size, ptr_reg, ptr_off); - sp_off = info->total_size; - if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (frame_reg_rtx, false); - } - - /* Set frame pointer, if needed. */ - if (frame_pointer_needed) - { - insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM), - sp_reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - - /* Save AltiVec registers if needed. Save here because the red zone does - not always include AltiVec registers. */ - if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI - && info->altivec_size != 0 && (strategy & SAVE_INLINE_VRS) == 0) - { - int end_save = info->altivec_save_offset + info->altivec_size; - int ptr_off; - /* Oddly, the vector save/restore functions point r0 at the end - of the save area, then use r11 or r12 to load offsets for - [reg+reg] addressing. */ - rtx ptr_reg = gen_rtx_REG (Pmode, 0); - int scratch_regno = ptr_regno_for_savres (SAVRES_SAVE | SAVRES_VR); - rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno); - - gcc_checking_assert (scratch_regno == 11 || scratch_regno == 12); - NOT_INUSE (0); - if (end_save + frame_off != 0) - { - rtx offset = GEN_INT (end_save + frame_off); - - emit_insn (gen_add3_insn (ptr_reg, frame_reg_rtx, offset)); - } - else - emit_move_insn (ptr_reg, frame_reg_rtx); - - ptr_off = -end_save; - insn = rs6000_emit_savres_rtx (info, scratch_reg, - info->altivec_save_offset + ptr_off, - 0, V4SImode, SAVRES_SAVE | SAVRES_VR); - rs6000_frame_related (insn, scratch_reg, sp_off - ptr_off, - NULL_RTX, NULL_RTX); - if (REGNO (frame_reg_rtx) == REGNO (scratch_reg)) - { - /* The oddity mentioned above clobbered our frame reg. */ - emit_move_insn (frame_reg_rtx, ptr_reg); - frame_off = ptr_off; - } - } - else if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI - && info->altivec_size != 0) - { - int i; - - for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) - if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) - { - rtx areg, savereg, mem; - int offset; - - offset = (info->altivec_save_offset + frame_off - + 16 * (i - info->first_altivec_reg_save)); - - savereg = gen_rtx_REG (V4SImode, i); - - NOT_INUSE (0); - areg = gen_rtx_REG (Pmode, 0); - emit_move_insn (areg, GEN_INT (offset)); - - /* AltiVec addressing mode is [reg+reg]. */ - mem = gen_frame_mem (V4SImode, - gen_rtx_PLUS (Pmode, frame_reg_rtx, areg)); - - insn = emit_move_insn (mem, savereg); - - rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, - areg, GEN_INT (offset)); - } - } - - /* VRSAVE is a bit vector representing which AltiVec registers - are used. The OS uses this to determine which vector - registers to save on a context switch. We need to save - VRSAVE on the stack frame, add whatever AltiVec registers we - used in this function, and do the corresponding magic in the - epilogue. */ - - if (!WORLD_SAVE_P (info) - && TARGET_ALTIVEC - && TARGET_ALTIVEC_VRSAVE - && info->vrsave_mask != 0) - { - rtx reg, vrsave; - int offset; - int save_regno; - - /* Get VRSAVE onto a GPR. Note that ABI_V4 and ABI_DARWIN might - be using r12 as frame_reg_rtx and r11 as the static chain - pointer for nested functions. */ - save_regno = 12; - if (DEFAULT_ABI == ABI_AIX && !using_static_chain_p) - save_regno = 11; - else if (REGNO (frame_reg_rtx) == 12) - { - save_regno = 11; - if (using_static_chain_p) - save_regno = 0; - } - - NOT_INUSE (save_regno); - reg = gen_rtx_REG (SImode, save_regno); - vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO); - if (TARGET_MACHO) - emit_insn (gen_get_vrsave_internal (reg)); - else - emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave)); - - /* Save VRSAVE. */ - offset = info->vrsave_save_offset + frame_off; - insn = emit_insn (gen_frame_store (reg, frame_reg_rtx, offset)); - - /* Include the registers in the mask. */ - emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask))); - - insn = emit_insn (generate_set_vrsave (reg, info, 0)); - } - - /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */ - if (!TARGET_SINGLE_PIC_BASE - && ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) - || (DEFAULT_ABI == ABI_V4 - && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT)) - && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))) - { - /* If emit_load_toc_table will use the link register, we need to save - 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 - && DEFAULT_ABI != ABI_AIX - && flag_pic - && ! info->lr_save_p - && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0); - if (save_LR_around_toc_setup) - { - rtx lr = gen_rtx_REG (Pmode, LR_REGNO); - rtx tmp = gen_rtx_REG (Pmode, 12); - - insn = emit_move_insn (tmp, lr); - RTX_FRAME_RELATED_P (insn) = 1; - - rs6000_emit_load_toc_table (TRUE); - - insn = emit_move_insn (lr, tmp); - add_reg_note (insn, REG_CFA_RESTORE, lr); - RTX_FRAME_RELATED_P (insn) = 1; - } - else - rs6000_emit_load_toc_table (TRUE); - } - -#if TARGET_MACHO - if (!TARGET_SINGLE_PIC_BASE - && DEFAULT_ABI == ABI_DARWIN - && flag_pic && crtl->uses_pic_offset_table) - { - rtx lr = gen_rtx_REG (Pmode, LR_REGNO); - rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); - - /* Save and restore LR locally around this call (in R0). */ - if (!info->lr_save_p) - emit_move_insn (gen_rtx_REG (Pmode, 0), lr); - - emit_insn (gen_load_macho_picbase (src)); - - emit_move_insn (gen_rtx_REG (Pmode, - RS6000_PIC_OFFSET_TABLE_REGNUM), - lr); - - if (!info->lr_save_p) - emit_move_insn (lr, gen_rtx_REG (Pmode, 0)); - } -#endif - - /* If we need to, save the TOC register after doing the stack setup. - Do not emit eh frame info for this save. The unwinder wants info, - conceptually attached to instructions in this function, about - register values in the caller of this function. This R2 may have - already been changed from the value in the caller. - We don't attempt to write accurate DWARF EH frame info for R2 - because code emitted by gcc for a (non-pointer) function call - doesn't save and restore R2. Instead, R2 is managed out-of-line - by a linker generated plt call stub when the function resides in - a shared library. This behaviour is costly to describe in DWARF, - both in terms of the size of DWARF info and the time taken in the - unwinder to interpret it. R2 changes, apart from the - calls_eh_return case earlier in this function, are handled by - linux-unwind.h frob_update_context. */ - if (rs6000_save_toc_in_prologue_p ()) - { - rtx reg = gen_rtx_REG (reg_mode, TOC_REGNUM); - emit_insn (gen_frame_store (reg, sp_reg_rtx, 5 * reg_size)); - } -} - -/* Write function prologue. */ - -static void -rs6000_output_function_prologue (FILE *file, - HOST_WIDE_INT size ATTRIBUTE_UNUSED) -{ - rs6000_stack_t *info = rs6000_stack_info (); - - if (TARGET_DEBUG_STACK) - debug_stack_info (info); - - /* Write .extern for any function we will call to save and restore - fp values. */ - if (info->first_fp_reg_save < 64 - && !TARGET_MACHO - && !TARGET_ELF) - { - char *name; - int regno = info->first_fp_reg_save - 32; - - if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0) - { - bool lr = (info->savres_strategy & SAVE_NOINLINE_FPRS_SAVES_LR) != 0; - int sel = SAVRES_SAVE | SAVRES_FPR | (lr ? SAVRES_LR : 0); - name = rs6000_savres_routine_name (info, regno, sel); - fprintf (file, "\t.extern %s\n", name); - } - if ((info->savres_strategy & REST_INLINE_FPRS) == 0) - { - bool lr = (info->savres_strategy - & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0; - int sel = SAVRES_FPR | (lr ? SAVRES_LR : 0); - name = rs6000_savres_routine_name (info, regno, sel); - fprintf (file, "\t.extern %s\n", name); - } - } - - rs6000_pic_labelno++; -} - -/* Non-zero if vmx regs are restored before the frame pop, zero if - we restore after the pop when possible. */ -#define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0 - -/* Restoring cr is a two step process: loading a reg from the frame - save, then moving the reg to cr. For ABI_V4 we must let the - unwinder know that the stack location is no longer valid at or - before the stack deallocation, but we can't emit a cfa_restore for - cr at the stack deallocation like we do for other registers. - The trouble is that it is possible for the move to cr to be - scheduled after the stack deallocation. So say exactly where cr - is located on each of the two insns. */ - -static rtx -load_cr_save (int regno, rtx frame_reg_rtx, int offset, bool exit_func) -{ - rtx mem = gen_frame_mem_offset (SImode, frame_reg_rtx, offset); - rtx reg = gen_rtx_REG (SImode, regno); - rtx insn = emit_move_insn (reg, mem); - - if (!exit_func && DEFAULT_ABI == ABI_V4) - { - rtx cr = gen_rtx_REG (SImode, CR2_REGNO); - rtx set = gen_rtx_SET (VOIDmode, reg, cr); - - add_reg_note (insn, REG_CFA_REGISTER, set); - RTX_FRAME_RELATED_P (insn) = 1; - } - return reg; -} - -/* Reload CR from REG. */ - -static void -restore_saved_cr (rtx reg, int using_mfcr_multiple, bool exit_func) -{ - int count = 0; - int i; - - if (using_mfcr_multiple) - { - for (i = 0; i < 8; i++) - if (save_reg_p (CR0_REGNO + i)) - count++; - gcc_assert (count); - } - - if (using_mfcr_multiple && count > 1) - { - rtvec p; - int ndx; - - p = rtvec_alloc (count); - - ndx = 0; - for (i = 0; i < 8; i++) - if (save_reg_p (CR0_REGNO + i)) - { - rtvec r = rtvec_alloc (2); - RTVEC_ELT (r, 0) = reg; - 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, UNSPEC_MOVESI_TO_CR)); - ndx++; - } - emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - gcc_assert (ndx == count); - } - else - for (i = 0; i < 8; i++) - if (save_reg_p (CR0_REGNO + i)) - emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, CR0_REGNO + i), - reg)); - - if (!exit_func && (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)) - { - rtx insn = get_last_insn (); - rtx cr = gen_rtx_REG (SImode, CR2_REGNO); - - add_reg_note (insn, REG_CFA_RESTORE, cr); - RTX_FRAME_RELATED_P (insn) = 1; - } -} - -/* Like cr, the move to lr instruction can be scheduled after the - stack deallocation, but unlike cr, its stack frame save is still - valid. So we only need to emit the cfa_restore on the correct - instruction. */ - -static void -load_lr_save (int regno, rtx frame_reg_rtx, int offset) -{ - rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx, offset); - rtx reg = gen_rtx_REG (Pmode, regno); - - emit_move_insn (reg, mem); -} - -static void -restore_saved_lr (int regno, bool exit_func) -{ - rtx reg = gen_rtx_REG (Pmode, regno); - rtx lr = gen_rtx_REG (Pmode, LR_REGNO); - rtx insn = emit_move_insn (lr, reg); - - if (!exit_func && flag_shrink_wrap) - { - add_reg_note (insn, REG_CFA_RESTORE, lr); - RTX_FRAME_RELATED_P (insn) = 1; - } -} - -static rtx -add_crlr_cfa_restore (const rs6000_stack_t *info, rtx cfa_restores) -{ - if (info->cr_save_p) - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, - gen_rtx_REG (SImode, CR2_REGNO), - cfa_restores); - if (info->lr_save_p) - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, - gen_rtx_REG (Pmode, LR_REGNO), - cfa_restores); - return cfa_restores; -} - -/* Return true if OFFSET from stack pointer can be clobbered by signals. - V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes - below stack pointer not cloberred by signals. */ - -static inline bool -offset_below_red_zone_p (HOST_WIDE_INT offset) -{ - return offset < (DEFAULT_ABI == ABI_V4 - ? 0 - : TARGET_32BIT ? -220 : -288); -} - -/* Append CFA_RESTORES to any existing REG_NOTES on the last insn. */ - -static void -emit_cfa_restores (rtx cfa_restores) -{ - rtx insn = get_last_insn (); - rtx *loc = ®_NOTES (insn); - - while (*loc) - loc = &XEXP (*loc, 1); - *loc = cfa_restores; - RTX_FRAME_RELATED_P (insn) = 1; -} - -/* Emit function epilogue as insns. */ - -void -rs6000_emit_epilogue (int sibcall) -{ - rs6000_stack_t *info; - int restoring_GPRs_inline; - int restoring_FPRs_inline; - int using_load_multiple; - int using_mtcr_multiple; - int use_backchain_to_restore_sp; - int restore_lr; - int strategy; - HOST_WIDE_INT frame_off = 0; - rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); - rtx frame_reg_rtx = sp_reg_rtx; - rtx cfa_restores = NULL_RTX; - rtx insn; - rtx cr_save_reg = NULL_RTX; - enum machine_mode reg_mode = Pmode; - int reg_size = TARGET_32BIT ? 4 : 8; - int i; - bool exit_func; - unsigned ptr_regno; - - info = rs6000_stack_info (); - - if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0) - { - reg_mode = V2SImode; - reg_size = 8; - } - - strategy = info->savres_strategy; - using_load_multiple = strategy & SAVRES_MULTIPLE; - restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS); - restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS); - using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601 - || rs6000_cpu == PROCESSOR_PPC603 - || rs6000_cpu == PROCESSOR_PPC750 - || optimize_size); - /* Restore via the backchain when we have a large frame, since this - is more efficient than an addis, addi pair. The second condition - here will not trigger at the moment; We don't actually need a - frame pointer for alloca, but the generic parts of the compiler - give us one anyway. */ - use_backchain_to_restore_sp = (info->total_size > 32767 - info->lr_save_offset - || (cfun->calls_alloca - && !frame_pointer_needed)); - restore_lr = (info->lr_save_p - && (restoring_FPRs_inline - || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR)) - && (restoring_GPRs_inline - || info->first_fp_reg_save < 64)); - - if (WORLD_SAVE_P (info)) - { - int i, j; - char rname[30]; - const char *alloc_rname; - rtvec p; - - /* eh_rest_world_r10 will return to the location saved in the LR - stack slot (which is not likely to be our caller.) - Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8. - rest_world is similar, except any R10 parameter is ignored. - The exception-handling stuff that was here in 2.95 is no - longer necessary. */ - - p = rtvec_alloc (9 - + 1 - + 32 - info->first_gp_reg_save - + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save - + 63 + 1 - info->first_fp_reg_save); - - strcpy (rname, ((crtl->calls_eh_return) ? - "*eh_rest_world_r10" : "*rest_world")); - alloc_rname = ggc_strdup (rname); - - j = 0; - RTVEC_ELT (p, j++) = ret_rtx; - RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, - gen_rtx_REG (Pmode, - LR_REGNO)); - RTVEC_ELT (p, j++) - = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname)); - /* The instruction pattern requires a clobber here; - it is shared with the restVEC helper. */ - RTVEC_ELT (p, j++) - = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11)); - - { - /* CR register traditionally saved as CR2. */ - rtx reg = gen_rtx_REG (SImode, CR2_REGNO); - RTVEC_ELT (p, j++) - = gen_frame_load (reg, frame_reg_rtx, info->cr_save_offset); - if (flag_shrink_wrap) - { - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, - gen_rtx_REG (Pmode, LR_REGNO), - cfa_restores); - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - } - - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - { - rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - RTVEC_ELT (p, j++) - = gen_frame_load (reg, - frame_reg_rtx, info->gp_save_offset + reg_size * i); - if (flag_shrink_wrap) - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++) - { - rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i); - RTVEC_ELT (p, j++) - = gen_frame_load (reg, - frame_reg_rtx, info->altivec_save_offset + 16 * i); - if (flag_shrink_wrap) - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - for (i = 0; info->first_fp_reg_save + i <= 63; i++) - { - rtx reg = gen_rtx_REG ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), - info->first_fp_reg_save + i); - RTVEC_ELT (p, j++) - = gen_frame_load (reg, frame_reg_rtx, info->fp_save_offset + 8 * i); - if (flag_shrink_wrap) - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - RTVEC_ELT (p, j++) - = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0)); - RTVEC_ELT (p, j++) - = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12)); - RTVEC_ELT (p, j++) - = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7)); - RTVEC_ELT (p, j++) - = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8)); - RTVEC_ELT (p, j++) - = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10)); - insn = emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p)); - - if (flag_shrink_wrap) - { - REG_NOTES (insn) = cfa_restores; - add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - return; - } - - /* frame_reg_rtx + frame_off points to the top of this stack frame. */ - if (info->push_p) - frame_off = info->total_size; - - /* Restore AltiVec registers if we must do so before adjusting the - stack. */ - if (TARGET_ALTIVEC_ABI - && info->altivec_size != 0 - && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP - || (DEFAULT_ABI != ABI_V4 - && offset_below_red_zone_p (info->altivec_save_offset)))) - { - int i; - int scratch_regno = ptr_regno_for_savres (SAVRES_VR); - - gcc_checking_assert (scratch_regno == 11 || scratch_regno == 12); - if (use_backchain_to_restore_sp) - { - int frame_regno = 11; - - if ((strategy & REST_INLINE_VRS) == 0) - { - /* Of r11 and r12, select the one not clobbered by an - out-of-line restore function for the frame register. */ - frame_regno = 11 + 12 - scratch_regno; - } - frame_reg_rtx = gen_rtx_REG (Pmode, frame_regno); - emit_move_insn (frame_reg_rtx, - gen_rtx_MEM (Pmode, sp_reg_rtx)); - frame_off = 0; - } - else if (frame_pointer_needed) - frame_reg_rtx = hard_frame_pointer_rtx; - - if ((strategy & REST_INLINE_VRS) == 0) - { - int end_save = info->altivec_save_offset + info->altivec_size; - int ptr_off; - rtx ptr_reg = gen_rtx_REG (Pmode, 0); - rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno); - - if (end_save + frame_off != 0) - { - rtx offset = GEN_INT (end_save + frame_off); - - emit_insn (gen_add3_insn (ptr_reg, frame_reg_rtx, offset)); - } - else - emit_move_insn (ptr_reg, frame_reg_rtx); - - ptr_off = -end_save; - insn = rs6000_emit_savres_rtx (info, scratch_reg, - info->altivec_save_offset + ptr_off, - 0, V4SImode, SAVRES_VR); - } - else - { - for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) - if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) - { - rtx addr, areg, mem, reg; - - areg = gen_rtx_REG (Pmode, 0); - emit_move_insn - (areg, GEN_INT (info->altivec_save_offset - + frame_off - + 16 * (i - info->first_altivec_reg_save))); - - /* AltiVec addressing mode is [reg+reg]. */ - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg); - mem = gen_frame_mem (V4SImode, addr); - - reg = gen_rtx_REG (V4SImode, i); - emit_move_insn (reg, mem); - } - } - - for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) - if (((strategy & REST_INLINE_VRS) == 0 - || (info->vrsave_mask & ALTIVEC_REG_BIT (i)) != 0) - && (flag_shrink_wrap - || (offset_below_red_zone_p - (info->altivec_save_offset - + 16 * (i - info->first_altivec_reg_save))))) - { - rtx reg = gen_rtx_REG (V4SImode, i); - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - } - - /* Restore VRSAVE if we must do so before adjusting the stack. */ - if (TARGET_ALTIVEC - && TARGET_ALTIVEC_VRSAVE - && info->vrsave_mask != 0 - && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP - || (DEFAULT_ABI != ABI_V4 - && offset_below_red_zone_p (info->vrsave_save_offset)))) - { - rtx reg; - - if (frame_reg_rtx == sp_reg_rtx) - { - if (use_backchain_to_restore_sp) - { - frame_reg_rtx = gen_rtx_REG (Pmode, 11); - emit_move_insn (frame_reg_rtx, - gen_rtx_MEM (Pmode, sp_reg_rtx)); - frame_off = 0; - } - else if (frame_pointer_needed) - frame_reg_rtx = hard_frame_pointer_rtx; - } - - reg = gen_rtx_REG (SImode, 12); - emit_insn (gen_frame_load (reg, frame_reg_rtx, - info->vrsave_save_offset + frame_off)); - - emit_insn (generate_set_vrsave (reg, info, 1)); - } - - insn = NULL_RTX; - /* If we have a large stack frame, restore the old stack pointer - using the backchain. */ - if (use_backchain_to_restore_sp) - { - if (frame_reg_rtx == sp_reg_rtx) - { - /* Under V.4, don't reset the stack pointer until after we're done - loading the saved registers. */ - if (DEFAULT_ABI == ABI_V4) - frame_reg_rtx = gen_rtx_REG (Pmode, 11); - - insn = emit_move_insn (frame_reg_rtx, - gen_rtx_MEM (Pmode, sp_reg_rtx)); - frame_off = 0; - } - else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP - && DEFAULT_ABI == ABI_V4) - /* frame_reg_rtx has been set up by the altivec restore. */ - ; - else - { - insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx); - frame_reg_rtx = sp_reg_rtx; - } - } - /* If we have a frame pointer, we can restore the old stack pointer - from it. */ - else if (frame_pointer_needed) - { - frame_reg_rtx = sp_reg_rtx; - if (DEFAULT_ABI == ABI_V4) - frame_reg_rtx = gen_rtx_REG (Pmode, 11); - /* Prevent reordering memory accesses against stack pointer restore. */ - else if (cfun->calls_alloca - || offset_below_red_zone_p (-info->total_size)) - rs6000_emit_stack_tie (frame_reg_rtx, true); - - insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx, - GEN_INT (info->total_size))); - frame_off = 0; - } - else if (info->push_p - && DEFAULT_ABI != ABI_V4 - && !crtl->calls_eh_return) - { - /* Prevent reordering memory accesses against stack pointer restore. */ - if (cfun->calls_alloca - || offset_below_red_zone_p (-info->total_size)) - rs6000_emit_stack_tie (frame_reg_rtx, false); - insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, - GEN_INT (info->total_size))); - frame_off = 0; - } - if (insn && frame_reg_rtx == sp_reg_rtx) - { - if (cfa_restores) - { - REG_NOTES (insn) = cfa_restores; - cfa_restores = NULL_RTX; - } - add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - - /* Restore AltiVec registers if we have not done so already. */ - if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP - && TARGET_ALTIVEC_ABI - && info->altivec_size != 0 - && (DEFAULT_ABI == ABI_V4 - || !offset_below_red_zone_p (info->altivec_save_offset))) - { - int i; - - if ((strategy & REST_INLINE_VRS) == 0) - { - int end_save = info->altivec_save_offset + info->altivec_size; - int ptr_off; - rtx ptr_reg = gen_rtx_REG (Pmode, 0); - int scratch_regno = ptr_regno_for_savres (SAVRES_VR); - rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno); - - if (end_save + frame_off != 0) - { - rtx offset = GEN_INT (end_save + frame_off); - - emit_insn (gen_add3_insn (ptr_reg, frame_reg_rtx, offset)); - } - else - emit_move_insn (ptr_reg, frame_reg_rtx); - - ptr_off = -end_save; - insn = rs6000_emit_savres_rtx (info, scratch_reg, - info->altivec_save_offset + ptr_off, - 0, V4SImode, SAVRES_VR); - if (REGNO (frame_reg_rtx) == REGNO (scratch_reg)) - { - /* Frame reg was clobbered by out-of-line save. Restore it - from ptr_reg, and if we are calling out-of-line gpr or - fpr restore set up the correct pointer and offset. */ - unsigned newptr_regno = 1; - if (!restoring_GPRs_inline) - { - bool lr = info->gp_save_offset + info->gp_size == 0; - int sel = SAVRES_GPR | (lr ? SAVRES_LR : 0); - newptr_regno = ptr_regno_for_savres (sel); - end_save = info->gp_save_offset + info->gp_size; - } - else if (!restoring_FPRs_inline) - { - bool lr = !(strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR); - int sel = SAVRES_FPR | (lr ? SAVRES_LR : 0); - newptr_regno = ptr_regno_for_savres (sel); - end_save = info->gp_save_offset + info->gp_size; - } - - if (newptr_regno != 1 && REGNO (frame_reg_rtx) != newptr_regno) - frame_reg_rtx = gen_rtx_REG (Pmode, newptr_regno); - - if (end_save + ptr_off != 0) - { - rtx offset = GEN_INT (end_save + ptr_off); - - frame_off = -end_save; - emit_insn (gen_add3_insn (frame_reg_rtx, ptr_reg, offset)); - } - else - { - frame_off = ptr_off; - emit_move_insn (frame_reg_rtx, ptr_reg); - } - } - } - else - { - for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) - if (info->vrsave_mask & ALTIVEC_REG_BIT (i)) - { - rtx addr, areg, mem, reg; - - areg = gen_rtx_REG (Pmode, 0); - emit_move_insn - (areg, GEN_INT (info->altivec_save_offset - + frame_off - + 16 * (i - info->first_altivec_reg_save))); - - /* AltiVec addressing mode is [reg+reg]. */ - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg); - mem = gen_frame_mem (V4SImode, addr); - - reg = gen_rtx_REG (V4SImode, i); - emit_move_insn (reg, mem); - } - } - - for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i) - if (((strategy & REST_INLINE_VRS) == 0 - || (info->vrsave_mask & ALTIVEC_REG_BIT (i)) != 0) - && (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)) - { - rtx reg = gen_rtx_REG (V4SImode, i); - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - } - - /* Restore VRSAVE if we have not done so already. */ - if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP - && TARGET_ALTIVEC - && TARGET_ALTIVEC_VRSAVE - && info->vrsave_mask != 0 - && (DEFAULT_ABI == ABI_V4 - || !offset_below_red_zone_p (info->vrsave_save_offset))) - { - rtx reg; - - reg = gen_rtx_REG (SImode, 12); - emit_insn (gen_frame_load (reg, frame_reg_rtx, - info->vrsave_save_offset + frame_off)); - - emit_insn (generate_set_vrsave (reg, info, 1)); - } - - /* If we exit by an out-of-line restore function on ABI_V4 then that - function will deallocate the stack, so we don't need to worry - about the unwinder restoring cr from an invalid stack frame - location. */ - exit_func = (!restoring_FPRs_inline - || (!restoring_GPRs_inline - && info->first_fp_reg_save == 64)); - - /* Get the old lr if we saved it. If we are restoring registers - out-of-line, then the out-of-line routines can do this for us. */ - if (restore_lr && restoring_GPRs_inline) - load_lr_save (0, frame_reg_rtx, info->lr_save_offset + frame_off); - - /* Get the old cr if we saved it. */ - if (info->cr_save_p) - { - unsigned cr_save_regno = 12; - - if (!restoring_GPRs_inline) - { - /* Ensure we don't use the register used by the out-of-line - gpr register restore below. */ - bool lr = info->gp_save_offset + info->gp_size == 0; - int sel = SAVRES_GPR | (lr ? SAVRES_LR : 0); - int gpr_ptr_regno = ptr_regno_for_savres (sel); - - if (gpr_ptr_regno == 12) - cr_save_regno = 11; - gcc_checking_assert (REGNO (frame_reg_rtx) != cr_save_regno); - } - else if (REGNO (frame_reg_rtx) == 12) - cr_save_regno = 11; - - cr_save_reg = load_cr_save (cr_save_regno, frame_reg_rtx, - info->cr_save_offset + frame_off, - exit_func); - } - - /* Set LR here to try to overlap restores below. */ - if (restore_lr && restoring_GPRs_inline) - restore_saved_lr (0, exit_func); - - /* Load exception handler data registers, if needed. */ - if (crtl->calls_eh_return) - { - unsigned int i, regno; - - if (TARGET_AIX) - { - rtx reg = gen_rtx_REG (reg_mode, 2); - emit_insn (gen_frame_load (reg, frame_reg_rtx, - frame_off + 5 * reg_size)); - } - - for (i = 0; ; ++i) - { - rtx mem; - - regno = EH_RETURN_DATA_REGNO (i); - if (regno == INVALID_REGNUM) - break; - - /* Note: possible use of r0 here to address SPE regs. */ - mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx, - info->ehrd_offset + frame_off - + reg_size * (int) i); - - emit_move_insn (gen_rtx_REG (reg_mode, regno), mem); - } - } - - /* Restore GPRs. This is done as a PARALLEL if we are using - the load-multiple instructions. */ - if (TARGET_SPE_ABI - && info->spe_64bit_regs_used - && info->first_gp_reg_save != 32) - { - /* Determine whether we can address all of the registers that need - to be saved with an offset from frame_reg_rtx that fits in - the small const field for SPE memory instructions. */ - int spe_regs_addressable - = (SPE_CONST_OFFSET_OK (info->spe_gp_save_offset + frame_off - + reg_size * (32 - info->first_gp_reg_save - 1)) - && restoring_GPRs_inline); - - if (!spe_regs_addressable) - { - int ool_adjust = 0; - rtx old_frame_reg_rtx = frame_reg_rtx; - /* Make r11 point to the start of the SPE save area. We worried about - not clobbering it when we were saving registers in the prologue. - There's no need to worry here because the static chain is passed - anew to every function. */ - - if (!restoring_GPRs_inline) - ool_adjust = 8 * (info->first_gp_reg_save - - (FIRST_SAVRES_REGISTER + 1)); - frame_reg_rtx = gen_rtx_REG (Pmode, 11); - emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx, - GEN_INT (info->spe_gp_save_offset - + frame_off - - ool_adjust))); - /* Keep the invariant that frame_reg_rtx + frame_off points - at the top of the stack frame. */ - frame_off = -info->spe_gp_save_offset + ool_adjust; - } - - if (restoring_GPRs_inline) - { - HOST_WIDE_INT spe_offset = info->spe_gp_save_offset + frame_off; - - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) - { - rtx offset, addr, mem, reg; - - /* We're doing all this to ensure that the immediate offset - fits into the immediate field of 'evldd'. */ - gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i)); - - offset = GEN_INT (spe_offset + reg_size * i); - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset); - mem = gen_rtx_MEM (V2SImode, addr); - reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - - emit_move_insn (reg, mem); - } - } - else - rs6000_emit_savres_rtx (info, frame_reg_rtx, - info->spe_gp_save_offset + frame_off, - info->lr_save_offset + frame_off, - reg_mode, - SAVRES_GPR | SAVRES_LR); - } - else if (!restoring_GPRs_inline) - { - /* We are jumping to an out-of-line function. */ - rtx ptr_reg; - int end_save = info->gp_save_offset + info->gp_size; - bool can_use_exit = end_save == 0; - int sel = SAVRES_GPR | (can_use_exit ? SAVRES_LR : 0); - int ptr_off; - - /* Emit stack reset code if we need it. */ - ptr_regno = ptr_regno_for_savres (sel); - ptr_reg = gen_rtx_REG (Pmode, ptr_regno); - if (can_use_exit) - rs6000_emit_stack_reset (info, frame_reg_rtx, frame_off, ptr_regno); - else if (end_save + frame_off != 0) - emit_insn (gen_add3_insn (ptr_reg, frame_reg_rtx, - GEN_INT (end_save + frame_off))); - else if (REGNO (frame_reg_rtx) != ptr_regno) - emit_move_insn (ptr_reg, frame_reg_rtx); - if (REGNO (frame_reg_rtx) == ptr_regno) - frame_off = -end_save; - - if (can_use_exit && info->cr_save_p) - restore_saved_cr (cr_save_reg, using_mtcr_multiple, true); - - ptr_off = -end_save; - rs6000_emit_savres_rtx (info, ptr_reg, - info->gp_save_offset + ptr_off, - info->lr_save_offset + ptr_off, - reg_mode, sel); - } - else if (using_load_multiple) - { - rtvec p; - p = rtvec_alloc (32 - info->first_gp_reg_save); - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - RTVEC_ELT (p, i) - = gen_frame_load (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), - frame_reg_rtx, - info->gp_save_offset + frame_off + reg_size * i); - emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - } - else - { - for (i = 0; i < 32 - info->first_gp_reg_save; i++) - if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) - emit_insn (gen_frame_load - (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), - frame_reg_rtx, - info->gp_save_offset + frame_off + reg_size * i)); - } - - if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap) - { - /* If the frame pointer was used then we can't delay emitting - a REG_CFA_DEF_CFA note. This must happen on the insn that - restores the frame pointer, r31. We may have already emitted - a REG_CFA_DEF_CFA note, but that's OK; A duplicate is - discarded by dwarf2cfi.c/dwarf2out.c, and in any case would - be harmless if emitted. */ - if (frame_pointer_needed) - { - insn = get_last_insn (); - add_reg_note (insn, REG_CFA_DEF_CFA, - plus_constant (Pmode, frame_reg_rtx, frame_off)); - RTX_FRAME_RELATED_P (insn) = 1; - } - - /* Set up cfa_restores. We always need these when - shrink-wrapping. If not shrink-wrapping then we only need - the cfa_restore when the stack location is no longer valid. - The cfa_restores must be emitted on or before the insn that - invalidates the stack, and of course must not be emitted - before the insn that actually does the restore. The latter - is why it is a bad idea to emit the cfa_restores as a group - on the last instruction here that actually does a restore: - That insn may be reordered with respect to others doing - restores. */ - if (flag_shrink_wrap - && !restoring_GPRs_inline - && info->first_fp_reg_save == 64) - cfa_restores = add_crlr_cfa_restore (info, cfa_restores); - - for (i = info->first_gp_reg_save; i < 32; i++) - if (!restoring_GPRs_inline - || using_load_multiple - || rs6000_reg_live_or_pic_offset_p (i)) - { - rtx reg = gen_rtx_REG (reg_mode, i); - - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - } - - if (!restoring_GPRs_inline - && info->first_fp_reg_save == 64) - { - /* We are jumping to an out-of-line function. */ - if (cfa_restores) - emit_cfa_restores (cfa_restores); - return; - } - - if (restore_lr && !restoring_GPRs_inline) - { - load_lr_save (0, frame_reg_rtx, info->lr_save_offset + frame_off); - restore_saved_lr (0, exit_func); - } - - /* Restore fpr's if we need to do it without calling a function. */ - if (restoring_FPRs_inline) - for (i = 0; i < 64 - info->first_fp_reg_save; i++) - if (save_reg_p (info->first_fp_reg_save + i)) - { - rtx reg = gen_rtx_REG ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), - info->first_fp_reg_save + i); - emit_insn (gen_frame_load (reg, frame_reg_rtx, - info->fp_save_offset + frame_off + 8 * i)); - if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap) - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); - } - - /* If we saved cr, restore it here. Just those that were used. */ - if (info->cr_save_p) - restore_saved_cr (cr_save_reg, using_mtcr_multiple, exit_func); - - /* If this is V.4, unwind the stack pointer after all of the loads - have been done, or set up r11 if we are restoring fp out of line. */ - ptr_regno = 1; - if (!restoring_FPRs_inline) - { - bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0; - int sel = SAVRES_FPR | (lr ? SAVRES_LR : 0); - ptr_regno = ptr_regno_for_savres (sel); - } - - insn = rs6000_emit_stack_reset (info, frame_reg_rtx, frame_off, ptr_regno); - if (REGNO (frame_reg_rtx) == ptr_regno) - frame_off = 0; - - if (insn && restoring_FPRs_inline) - { - if (cfa_restores) - { - REG_NOTES (insn) = cfa_restores; - cfa_restores = NULL_RTX; - } - add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx); - RTX_FRAME_RELATED_P (insn) = 1; - } - - if (crtl->calls_eh_return) - { - rtx sa = EH_RETURN_STACKADJ_RTX; - emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa)); - } - - if (!sibcall) - { - rtvec p; - bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0; - if (! restoring_FPRs_inline) - { - p = rtvec_alloc (4 + 64 - info->first_fp_reg_save); - RTVEC_ELT (p, 0) = ret_rtx; - } - else - { - if (cfa_restores) - { - /* We can't hang the cfa_restores off a simple return, - since the shrink-wrap code sometimes uses an existing - return. This means there might be a path from - pre-prologue code to this return, and dwarf2cfi code - wants the eh_frame unwinder state to be the same on - all paths to any point. So we need to emit the - cfa_restores before the return. For -m64 we really - don't need epilogue cfa_restores at all, except for - this irritating dwarf2cfi with shrink-wrap - requirement; The stack red-zone means eh_frame info - from the prologue telling the unwinder to restore - from the stack is perfectly good right to the end of - the function. */ - emit_insn (gen_blockage ()); - emit_cfa_restores (cfa_restores); - cfa_restores = NULL_RTX; - } - p = rtvec_alloc (2); - RTVEC_ELT (p, 0) = simple_return_rtx; - } - - RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr) - ? gen_rtx_USE (VOIDmode, - gen_rtx_REG (Pmode, LR_REGNO)) - : gen_rtx_CLOBBER (VOIDmode, - gen_rtx_REG (Pmode, LR_REGNO))); - - /* If we have to restore more than two FP registers, branch to the - restore function. It will return to our caller. */ - if (! restoring_FPRs_inline) - { - int i; - rtx sym; - - if (flag_shrink_wrap) - cfa_restores = add_crlr_cfa_restore (info, cfa_restores); - - sym = rs6000_savres_routine_sym (info, - SAVRES_FPR | (lr ? SAVRES_LR : 0)); - RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym); - RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, - gen_rtx_REG (Pmode, - DEFAULT_ABI == ABI_AIX - ? 1 : 11)); - for (i = 0; i < 64 - info->first_fp_reg_save; i++) - { - rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); - - RTVEC_ELT (p, i + 4) - = gen_frame_load (reg, sp_reg_rtx, info->fp_save_offset + 8 * i); - if (flag_shrink_wrap) - cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, - cfa_restores); - } - } - - emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p)); - } - - if (cfa_restores) - { - if (sibcall) - /* Ensure the cfa_restores are hung off an insn that won't - be reordered above other restores. */ - emit_insn (gen_blockage ()); - - emit_cfa_restores (cfa_restores); - } -} - -/* Write function epilogue. */ - -static void -rs6000_output_function_epilogue (FILE *file, - HOST_WIDE_INT size ATTRIBUTE_UNUSED) -{ -#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. */ - { - rtx insn = get_last_insn (); - rtx deleted_debug_label = NULL_RTX; - while (insn - && NOTE_P (insn) - && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL) - { - /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL - notes only, instead set their CODE_LABEL_NUMBER to -1, - otherwise there would be code generation differences - in between -g and -g0. */ - if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL) - deleted_debug_label = insn; - insn = PREV_INSN (insn); - } - if (insn - && (LABEL_P (insn) - || (NOTE_P (insn) - && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))) - fputs ("\tnop\n", file); - else if (deleted_debug_label) - for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn)) - if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL) - CODE_LABEL_NUMBER (insn) = -1; - } -#endif - - /* Output a traceback table here. See /usr/include/sys/debug.h for info - on its format. - - We don't output a traceback table if -finhibit-size-directive was - used. The documentation for -finhibit-size-directive reads - ``don't output a @code{.size} assembler directive, or anything - else that would cause trouble if the function is split in the - middle, and the two halves are placed at locations far apart in - memory.'' The traceback table has this property, since it - includes the offset from the start of the function to the - traceback table itself. - - System V.4 Powerpc's (and the embedded ABI derived from it) use a - different traceback table. */ - if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive - && rs6000_traceback != traceback_none && !cfun->is_thunk) - { - const char *fname = NULL; - const char *language_string = lang_hooks.name; - int fixed_parms = 0, float_parms = 0, parm_info = 0; - int i; - int optional_tbtab; - rs6000_stack_t *info = rs6000_stack_info (); - - if (rs6000_traceback == traceback_full) - optional_tbtab = 1; - else if (rs6000_traceback == traceback_part) - optional_tbtab = 0; - else - optional_tbtab = !optimize_size && !TARGET_ELF; - - if (optional_tbtab) - { - fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); - while (*fname == '.') /* V.4 encodes . in the name */ - fname++; - - /* Need label immediately before tbtab, so we can compute - its offset from the function start. */ - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); - ASM_OUTPUT_LABEL (file, fname); - } - - /* The .tbtab pseudo-op can only be used for the first eight - expressions, since it can't handle the possibly variable - length fields that follow. However, if you omit the optional - fields, the assembler outputs zeros for all optional fields - anyways, giving each variable length field is minimum length - (as defined in sys/debug.h). Thus we can not use the .tbtab - pseudo-op at all. */ - - /* An all-zero word flags the start of the tbtab, for debuggers - that have to find it by searching forward from the entry - point or from the current pc. */ - fputs ("\t.long 0\n", file); - - /* Tbtab format type. Use format type 0. */ - fputs ("\t.byte 0,", file); - - /* 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. Objective-C++ isn't assigned - a number, so for now use 9. LTO and Go aren't assigned numbers - either, so for now use 0. */ - if (! strcmp (language_string, "GNU C") - || ! strcmp (language_string, "GNU GIMPLE") - || ! strcmp (language_string, "GNU Go")) - i = 0; - else if (! strcmp (language_string, "GNU F77") - || ! strcmp (language_string, "GNU Fortran")) - i = 1; - 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++") - || ! strcmp (language_string, "GNU Objective-C++")) - i = 9; - else if (! strcmp (language_string, "GNU Java")) - i = 13; - else if (! strcmp (language_string, "GNU Objective-C")) - i = 14; - else - gcc_unreachable (); - fprintf (file, "%d,", i); - - /* 8 single bit fields: global linkage (not set for C extern linkage, - apparently a PL/I convention?), out-of-line epilogue/prologue, offset - from start of procedure stored in tbtab, internal function, function - has controlled storage, function has no toc, function uses fp, - function logs/aborts fp operations. */ - /* Assume that fp operations are used if any fp reg must be saved. */ - fprintf (file, "%d,", - (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1)); - - /* 6 bitfields: function is interrupt handler, name present in - proc table, function calls alloca, on condition directives - (controls stack walks, 3 bits), saves condition reg, saves - link reg. */ - /* The `function calls alloca' bit seems to be set whenever reg 31 is - set up as a frame pointer, even when there is no alloca call. */ - fprintf (file, "%d,", - ((optional_tbtab << 6) - | ((optional_tbtab & frame_pointer_needed) << 5) - | (info->cr_save_p << 1) - | (info->lr_save_p))); - - /* 3 bitfields: saves backchain, fixup code, number of fpr saved - (6 bits). */ - fprintf (file, "%d,", - (info->push_p << 7) | (64 - info->first_fp_reg_save)); - - /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */ - fprintf (file, "%d,", (32 - first_reg_to_save ())); - - if (optional_tbtab) - { - /* Compute the parameter info from the function decl argument - list. */ - tree decl; - int next_parm_info_bit = 31; - - for (decl = DECL_ARGUMENTS (current_function_decl); - decl; decl = DECL_CHAIN (decl)) - { - rtx parameter = DECL_INCOMING_RTL (decl); - enum machine_mode mode = GET_MODE (parameter); - - if (GET_CODE (parameter) == REG) - { - if (SCALAR_FLOAT_MODE_P (mode)) - { - int bits; - - float_parms++; - - switch (mode) - { - case SFmode: - case SDmode: - bits = 0x2; - break; - - case DFmode: - case DDmode: - case TFmode: - case TDmode: - bits = 0x3; - break; - - default: - gcc_unreachable (); - } - - /* If only one bit will fit, don't or in this entry. */ - if (next_parm_info_bit > 0) - parm_info |= (bits << (next_parm_info_bit - 1)); - next_parm_info_bit -= 2; - } - else - { - fixed_parms += ((GET_MODE_SIZE (mode) - + (UNITS_PER_WORD - 1)) - / UNITS_PER_WORD); - next_parm_info_bit -= 1; - } - } - } - } - - /* Number of fixed point parameters. */ - /* This is actually the number of words of fixed point parameters; thus - an 8 byte struct counts as 2; and thus the maximum value is 8. */ - fprintf (file, "%d,", fixed_parms); - - /* 2 bitfields: number of floating point parameters (7 bits), parameters - all on stack. */ - /* This is actually the number of fp registers that hold parameters; - and thus the maximum value is 13. */ - /* Set parameters on stack bit if parameters are not in their original - registers, regardless of whether they are on the stack? Xlc - seems to set the bit when not optimizing. */ - fprintf (file, "%d\n", ((float_parms << 1) | (! optimize))); - - if (! optional_tbtab) - return; - - /* Optional fields follow. Some are variable length. */ - - /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float, - 11 double float. */ - /* There is an entry for each parameter in a register, in the order that - they occur in the parameter list. Any intervening arguments on the - stack are ignored. If the list overflows a long (max possible length - 34 bits) then completely leave off all elements that don't fit. */ - /* Only emit this long if there was at least one parameter. */ - if (fixed_parms || float_parms) - fprintf (file, "\t.long %d\n", parm_info); - - /* Offset from start of code to tb table. */ - fputs ("\t.long ", file); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); - RS6000_OUTPUT_BASENAME (file, fname); - putc ('-', file); - rs6000_output_function_entry (file, fname); - putc ('\n', file); - - /* Interrupt handler mask. */ - /* Omit this long, since we never set the interrupt handler bit - above. */ - - /* Number of CTL (controlled storage) anchors. */ - /* Omit this long, since the has_ctl bit is never set above. */ - - /* Displacement into stack of each CTL anchor. */ - /* Omit this list of longs, because there are no CTL anchors. */ - - /* Length of function name. */ - if (*fname == '*') - ++fname; - fprintf (file, "\t.short %d\n", (int) strlen (fname)); - - /* Function name. */ - assemble_string (fname, strlen (fname)); - - /* Register for alloca automatic storage; this is always reg 31. - Only emit this if the alloca bit was set above. */ - if (frame_pointer_needed) - fputs ("\t.byte 31\n", file); - - fputs ("\t.align 2\n", file); - } -} - -/* A C compound statement that outputs the assembler code for a thunk - function, used to implement C++ virtual function calls with - multiple inheritance. The thunk acts as a wrapper around a virtual - function, adjusting the implicit object parameter before handing - control off to the real function. - - First, emit code to add the integer DELTA to the location that - contains the incoming first argument. Assume that this argument - contains a pointer, and is the one used to pass the `this' pointer - in C++. This is the incoming argument *before* the function - prologue, e.g. `%o0' on a sparc. The addition must preserve the - values of all other incoming arguments. - - After the addition, emit code to jump to FUNCTION, which is a - `FUNCTION_DECL'. This is a direct pure jump, not a call, and does - not touch the return address. Hence returning from FUNCTION will - return to whoever called the current `thunk'. - - The effect must be as if FUNCTION had been called directly with the - adjusted first argument. This macro is responsible for emitting - all of the code for a thunk function; output_function_prologue() - and output_function_epilogue() are not invoked. - - The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already - been extracted from it.) It might possibly be useful on some - targets, but probably not. - - If you do not define this macro, the target-independent code in the - C++ frontend will generate a less efficient heavyweight thunk that - calls FUNCTION instead of jumping to it. The generic approach does - not support varargs. */ - -static void -rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, - HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, - tree function) -{ - rtx this_rtx, insn, funexp; - - reload_completed = 1; - epilogue_completed = 1; - - /* Mark the end of the (empty) prologue. */ - emit_note (NOTE_INSN_PROLOGUE_END); - - /* 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_rtx = gen_rtx_REG (Pmode, 4); - else - this_rtx = gen_rtx_REG (Pmode, 3); - - /* Apply the constant offset, if required. */ - if (delta) - emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta))); - - /* Apply the offset from the vtable, if required. */ - if (vcall_offset) - { - rtx vcall_offset_rtx = GEN_INT (vcall_offset); - rtx tmp = gen_rtx_REG (Pmode, 12); - - emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx)); - if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000) - { - emit_insn (gen_add3_insn (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); - - emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc)); - } - emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp)); - } - - /* Generate a tail call to the target function. */ - if (!TREE_USED (function)) - { - assemble_external (function); - TREE_USED (function) = 1; - } - funexp = XEXP (DECL_RTL (function), 0); - funexp = gen_rtx_MEM (FUNCTION_MODE, funexp); - -#if TARGET_MACHO - 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. */ - 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, - LR_REGNO)), - simple_return_rtx))); - 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 (); - shorten_branches (insn); - final_start_function (insn, file, 1); - final (insn, file, 1); - final_end_function (); - - reload_completed = 0; - epilogue_completed = 0; -} - -/* A quick summary of the various types of 'constant-pool tables' - under PowerPC: - - Target Flags Name One table per - AIX (none) AIX TOC object file - AIX -mfull-toc AIX TOC object file - AIX -mminimal-toc AIX minimal TOC translation unit - SVR4/EABI (none) SVR4 SDATA object file - SVR4/EABI -fpic SVR4 pic object file - SVR4/EABI -fPIC SVR4 PIC translation unit - SVR4/EABI -mrelocatable EABI TOC function - SVR4/EABI -maix AIX TOC object file - SVR4/EABI -maix -mminimal-toc - AIX minimal TOC translation unit - - Name Reg. Set by entries contains: - made by addrs? fp? sum? - - AIX TOC 2 crt0 as Y option option - AIX minimal TOC 30 prolog gcc Y Y option - SVR4 SDATA 13 crt0 gcc N Y N - SVR4 pic 30 prolog ld Y not yet N - SVR4 PIC 30 prolog gcc Y option option - EABI TOC 30 prolog gcc Y option option - -*/ - -/* Hash functions for the hash table. */ - -static unsigned -rs6000_hash_constant (rtx k) -{ - enum rtx_code code = GET_CODE (k); - enum machine_mode mode = GET_MODE (k); - unsigned result = (code << 3) ^ mode; - const char *format; - int flen, fidx; - - format = GET_RTX_FORMAT (code); - flen = strlen (format); - fidx = 0; - - switch (code) - { - case LABEL_REF: - return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0)); - - case CONST_DOUBLE: - if (mode != VOIDmode) - return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result; - flen = 2; - break; - - case CODE_LABEL: - fidx = 3; - break; - - default: - break; - } - - for (; fidx < flen; fidx++) - switch (format[fidx]) - { - case 's': - { - unsigned i, len; - const char *str = XSTR (k, fidx); - len = strlen (str); - result = result * 613 + len; - for (i = 0; i < len; i++) - result = result * 613 + (unsigned) str[i]; - break; - } - case 'u': - case 'e': - result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx)); - break; - case 'i': - case 'n': - result = result * 613 + (unsigned) XINT (k, fidx); - break; - case 'w': - if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT)) - result = result * 613 + (unsigned) XWINT (k, fidx); - else - { - size_t i; - for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++) - result = result * 613 + (unsigned) (XWINT (k, fidx) - >> CHAR_BIT * i); - } - break; - case '0': - break; - default: - gcc_unreachable (); - } - - return result; -} - -static unsigned -toc_hash_function (const void *hash_entry) -{ - const struct toc_hash_struct *thc = - (const struct toc_hash_struct *) hash_entry; - return rs6000_hash_constant (thc->key) ^ thc->key_mode; -} - -/* Compare H1 and H2 for equivalence. */ - -static int -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; - - if (((const struct toc_hash_struct *) h1)->key_mode - != ((const struct toc_hash_struct *) h2)->key_mode) - return 0; - - return rtx_equal_p (r1, r2); -} - -/* 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 - to whether or not an object is a vtable. */ - -#define VTABLE_NAME_P(NAME) \ - (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) - -#ifdef NO_DOLLAR_IN_LABEL -/* Return a GGC-allocated character string translating dollar signs in - input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */ - -const char * -rs6000_xcoff_strip_dollar (const char *name) -{ - char *strip, *p; - const char *q; - size_t len; - - q = (const char *) strchr (name, '$'); - - if (q == 0 || q == name) - return name; - - len = strlen (name); - strip = XALLOCAVEC (char, len + 1); - strcpy (strip, name); - p = strip + (q - name); - while (p) - { - *p = '_'; - p = strchr (p + 1, '$'); - } - - return ggc_alloc_string (strip, len); -} -#endif - -void -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 - the case, then the linker will eventually complain that there is - a reference to an unknown section. Thus, for vtables only, - we emit the TOC reference to reference the symbol and not the - section. */ - const char *name = XSTR (x, 0); - - if (VTABLE_NAME_P (name)) - { - RS6000_OUTPUT_BASENAME (file, name); - } - else - assemble_name (file, name); -} - -/* Output a TOC entry. We derive the entry name from what is being - written. */ - -void -output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode) -{ - char buf[256]; - const char *name = buf; - rtx base = x; - HOST_WIDE_INT offset = 0; - - gcc_assert (!TARGET_NO_TOC); - - /* 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). 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 TARGET_OPTION_OVERRIDE - 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_toc_hash_struct (); - h->key = x; - h->key_mode = mode; - h->labelno = labelno; - - found = htab_find_slot (toc_hash_table, h, INSERT); - if (*found == NULL) - *found = h; - else /* This is indeed a duplicate. - Set this label equal to that label. */ - { - fputs ("\t.set ", file); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); - fprintf (file, "%d,", labelno); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); - fprintf (file, "%d\n", ((*(const struct toc_hash_struct **) - found)->labelno)); - -#ifdef HAVE_AS_TLS - if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF - && (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_GLOBAL_DYNAMIC - || SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)) - { - fputs ("\t.set ", file); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM"); - fprintf (file, "%d,", labelno); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM"); - fprintf (file, "%d\n", ((*(const struct toc_hash_struct **) - found)->labelno)); - } -#endif - return; - } - } - - /* If we're going to put a double constant in the TOC, make sure it's - aligned properly when strict alignment is on. */ - if (GET_CODE (x) == CONST_DOUBLE - && STRICT_ALIGNMENT - && GET_MODE_BITSIZE (mode) >= 64 - && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { - ASM_OUTPUT_ALIGN (file, 3); - } - - (*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 - FP constants. */ - if (GET_CODE (x) == CONST_DOUBLE && - (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode)) - { - REAL_VALUE_TYPE rv; - long k[4]; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, x); - if (DECIMAL_FLOAT_MODE_P (GET_MODE (x))) - REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k); - else - REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); - - if (TARGET_64BIT) - { - if (TARGET_MINIMAL_TOC) - fputs (DOUBLE_INT_ASM_OP, file); - else - fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", - k[0] & 0xffffffff, k[1] & 0xffffffff, - k[2] & 0xffffffff, k[3] & 0xffffffff); - fprintf (file, "0x%lx%08lx,0x%lx%08lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff, - k[2] & 0xffffffff, k[3] & 0xffffffff); - return; - } - else - { - if (TARGET_MINIMAL_TOC) - fputs ("\t.long ", file); - else - fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", - k[0] & 0xffffffff, k[1] & 0xffffffff, - k[2] & 0xffffffff, k[3] & 0xffffffff); - fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff, - k[2] & 0xffffffff, k[3] & 0xffffffff); - return; - } - } - else if (GET_CODE (x) == CONST_DOUBLE && - (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode)) - { - REAL_VALUE_TYPE rv; - long k[2]; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, x); - - if (DECIMAL_FLOAT_MODE_P (GET_MODE (x))) - REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k); - else - REAL_VALUE_TO_TARGET_DOUBLE (rv, k); - - if (TARGET_64BIT) - { - if (TARGET_MINIMAL_TOC) - fputs (DOUBLE_INT_ASM_OP, file); - else - fprintf (file, "\t.tc FD_%lx_%lx[TC],", - k[0] & 0xffffffff, k[1] & 0xffffffff); - fprintf (file, "0x%lx%08lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff); - return; - } - else - { - if (TARGET_MINIMAL_TOC) - fputs ("\t.long ", file); - else - fprintf (file, "\t.tc FD_%lx_%lx[TC],", - k[0] & 0xffffffff, k[1] & 0xffffffff); - fprintf (file, "0x%lx,0x%lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff); - return; - } - } - else if (GET_CODE (x) == CONST_DOUBLE && - (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode)) - { - REAL_VALUE_TYPE rv; - long l; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, x); - if (DECIMAL_FLOAT_MODE_P (GET_MODE (x))) - REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l); - else - REAL_VALUE_TO_TARGET_SINGLE (rv, l); - - if (TARGET_64BIT) - { - if (TARGET_MINIMAL_TOC) - fputs (DOUBLE_INT_ASM_OP, file); - else - fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); - fprintf (file, "0x%lx00000000\n", l & 0xffffffff); - return; - } - else - { - if (TARGET_MINIMAL_TOC) - fputs ("\t.long ", file); - else - fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); - fprintf (file, "0x%lx\n", l & 0xffffffff); - return; - } - } - else if (GET_MODE (x) == VOIDmode - && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)) - { - unsigned HOST_WIDE_INT low; - HOST_WIDE_INT high; - - if (GET_CODE (x) == CONST_DOUBLE) - { - low = CONST_DOUBLE_LOW (x); - high = CONST_DOUBLE_HIGH (x); - } - else -#if HOST_BITS_PER_WIDE_INT == 32 - { - low = INTVAL (x); - high = (low & 0x80000000) ? ~0 : 0; - } -#else - { - low = INTVAL (x) & 0xffffffff; - high = (HOST_WIDE_INT) INTVAL (x) >> 32; - } -#endif - - /* TOC entries are always Pmode-sized, but since this - is a bigendian machine then if we're putting smaller - integer constants in the TOC we have to pad them. - (This is still a win over putting the constants in - a separate constant pool, because then we'd have - to have both a TOC entry _and_ the actual constant.) - - For a 32-bit target, CONST_INT values are loaded and shifted - entirely within `low' and can be stored in one TOC entry. */ - - /* It would be easy to make this work, but it doesn't now. */ - gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode)); - - if (POINTER_SIZE > GET_MODE_BITSIZE (mode)) - { -#if HOST_BITS_PER_WIDE_INT == 32 - lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode), - POINTER_SIZE, &low, &high, 0); -#else - low |= high << 32; - low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode); - high = (HOST_WIDE_INT) low >> 32; - low &= 0xffffffff; -#endif - } - - if (TARGET_64BIT) - { - if (TARGET_MINIMAL_TOC) - fputs (DOUBLE_INT_ASM_OP, file); - else - fprintf (file, "\t.tc ID_%lx_%lx[TC],", - (long) high & 0xffffffff, (long) low & 0xffffffff); - fprintf (file, "0x%lx%08lx\n", - (long) high & 0xffffffff, (long) low & 0xffffffff); - return; - } - else - { - if (POINTER_SIZE < GET_MODE_BITSIZE (mode)) - { - if (TARGET_MINIMAL_TOC) - fputs ("\t.long ", file); - else - fprintf (file, "\t.tc ID_%lx_%lx[TC],", - (long) high & 0xffffffff, (long) low & 0xffffffff); - fprintf (file, "0x%lx,0x%lx\n", - (long) high & 0xffffffff, (long) low & 0xffffffff); - } - else - { - if (TARGET_MINIMAL_TOC) - fputs ("\t.long ", file); - else - fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff); - fprintf (file, "0x%lx\n", (long) low & 0xffffffff); - } - return; - } - } - - if (GET_CODE (x) == CONST) - { - gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT); - - base = XEXP (XEXP (x, 0), 0); - offset = INTVAL (XEXP (XEXP (x, 0), 1)); - } - - switch (GET_CODE (base)) - { - case SYMBOL_REF: - name = XSTR (base, 0); - break; - - case LABEL_REF: - ASM_GENERATE_INTERNAL_LABEL (buf, "L", - CODE_LABEL_NUMBER (XEXP (base, 0))); - break; - - case CODE_LABEL: - ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base)); - break; - - default: - gcc_unreachable (); - } - - if (TARGET_MINIMAL_TOC) - fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file); - else - { - fputs ("\t.tc ", file); - RS6000_OUTPUT_BASENAME (file, name); - - if (offset < 0) - fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset); - else if (offset) - fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset); - - /* Mark large TOC symbols on AIX with [TE] so they are mapped - after other TOC symbols, reducing overflow of small TOC access - to [TC] symbols. */ - fputs (TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL - ? "[TE]," : "[TC],", file); - } - - /* Currently C++ toc references to vtables can be emitted before it - is decided whether the vtable is public or private. If this is - the case, then the linker will eventually complain that there is - a TOC reference to an unknown section. Thus, for vtables only, - we emit the TOC reference to reference the symbol and not the - section. */ - if (VTABLE_NAME_P (name)) - { - RS6000_OUTPUT_BASENAME (file, name); - if (offset < 0) - fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset); - else if (offset > 0) - fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset); - } - else - output_addr_const (file, x); - -#if HAVE_AS_TLS - if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF - && SYMBOL_REF_TLS_MODEL (base) != 0) - { - if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC) - fputs ("@le", file); - else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC) - fputs ("@ie", file); - /* Use global-dynamic for local-dynamic. */ - else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_GLOBAL_DYNAMIC - || SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_DYNAMIC) - { - putc ('\n', file); - (*targetm.asm_out.internal_label) (file, "LCM", labelno); - fputs ("\t.tc .", file); - RS6000_OUTPUT_BASENAME (file, name); - fputs ("[TC],", file); - output_addr_const (file, x); - fputs ("@m", file); - } - } -#endif - - putc ('\n', file); -} - -/* Output an assembler pseudo-op to write an ASCII string of N characters - starting at P to FILE. - - On the RS/6000, we have to do this using the .byte operation and - write out special characters outside the quoted string. - Also, the assembler is broken; very long strings are truncated, - so we must artificially break them up early. */ - -void -output_ascii (FILE *file, const char *p, int n) -{ - char c; - int i, count_string; - const char *for_string = "\t.byte \""; - const char *for_decimal = "\t.byte "; - const char *to_close = NULL; - - count_string = 0; - for (i = 0; i < n; i++) - { - c = *p++; - if (c >= ' ' && c < 0177) - { - if (for_string) - fputs (for_string, file); - putc (c, file); - - /* Write two quotes to get one. */ - if (c == '"') - { - putc (c, file); - ++count_string; - } - - for_string = NULL; - for_decimal = "\"\n\t.byte "; - to_close = "\"\n"; - ++count_string; - - if (count_string >= 512) - { - fputs (to_close, file); - - for_string = "\t.byte \""; - for_decimal = "\t.byte "; - to_close = NULL; - count_string = 0; - } - } - else - { - if (for_decimal) - fputs (for_decimal, file); - fprintf (file, "%d", c); - - for_string = "\n\t.byte \""; - for_decimal = ", "; - to_close = "\n"; - count_string = 0; - } - } - - /* Now close the string if we have written one. Then end the line. */ - if (to_close) - fputs (to_close, file); -} - -/* Generate a unique section name for FILENAME for a section type - represented by SECTION_DESC. Output goes into BUF. - - SECTION_DESC can be any string, as long as it is different for each - possible section type. - - We name the section in the same manner as xlc. The name begins with an - underscore followed by the filename (after stripping any leading directory - names) with the last period replaced by the string SECTION_DESC. If - FILENAME does not contain a period, SECTION_DESC is appended to the end of - the name. */ - -void -rs6000_gen_section_name (char **buf, const char *filename, - const char *section_desc) -{ - const char *q, *after_last_slash, *last_period = 0; - char *p; - int len; - - after_last_slash = filename; - for (q = filename; *q; q++) - { - if (*q == '/') - after_last_slash = q + 1; - else if (*q == '.') - last_period = q; - } - - len = strlen (after_last_slash) + strlen (section_desc) + 2; - *buf = (char *) xmalloc (len); - - p = *buf; - *p++ = '_'; - - for (q = after_last_slash; *q; q++) - { - if (q == last_period) - { - strcpy (p, section_desc); - p += strlen (section_desc); - break; - } - - else if (ISALNUM (*q)) - *p++ = *q; - } - - if (last_period == 0) - strcpy (p, section_desc); - else - *p = '\0'; -} - -/* Emit profile function. */ - -void -output_profile_hook (int labelno ATTRIBUTE_UNUSED) -{ - /* 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. */ - if (TARGET_PROFILE_KERNEL) - return; - - if (DEFAULT_ABI == ABI_AIX) - { -#ifndef NO_PROFILE_COUNTERS -# define NO_PROFILE_COUNTERS 0 -#endif - if (NO_PROFILE_COUNTERS) - emit_library_call (init_one_libfunc (RS6000_MCOUNT), - LCT_NORMAL, VOIDmode, 0); - else - { - char buf[30]; - const char *label_name; - rtx fun; - - ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); - label_name = ggc_strdup ((*targetm.strip_name_encoding) (buf)); - fun = gen_rtx_SYMBOL_REF (Pmode, label_name); - - emit_library_call (init_one_libfunc (RS6000_MCOUNT), - LCT_NORMAL, VOIDmode, 1, fun, Pmode); - } - } - else if (DEFAULT_ABI == ABI_DARWIN) - { - const char *mcount_name = RS6000_MCOUNT; - int caller_addr_regno = LR_REGNO; - - /* Be conservative and always set this, at least for now. */ - crtl->uses_pic_offset_table = 1; - -#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 (MACHOPIC_INDIRECT - && crtl->uses_pic_offset_table) - caller_addr_regno = 0; -#endif - emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name), - LCT_NORMAL, VOIDmode, 1, - gen_rtx_REG (Pmode, caller_addr_regno), Pmode); - } -} - -/* Write function profiler code. */ - -void -output_function_profiler (FILE *file, int labelno) -{ - char buf[100]; - - switch (DEFAULT_ABI) - { - default: - gcc_unreachable (); - - case ABI_V4: - if (!TARGET_32BIT) - { - warning (0, "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 (NO_PROFILE_COUNTERS) - { - asm_fprintf (file, "\tstw %s,4(%s)\n", - reg_names[0], reg_names[1]); - } - else if (TARGET_SECURE_PLT && flag_pic) - { - if (TARGET_LINK_STACK) - { - char name[32]; - get_ppc476_thunk_name (name); - asm_fprintf (file, "\tbl %s\n", name); - } - else - asm_fprintf (file, "\tbcl 20,31,1f\n1:\n"); - asm_fprintf (file, "\tstw %s,4(%s)\n", - reg_names[0], reg_names[1]); - asm_fprintf (file, "\tmflr %s\n", reg_names[12]); - asm_fprintf (file, "\taddis %s,%s,", - reg_names[12], reg_names[12]); - assemble_name (file, buf); - asm_fprintf (file, "-1b@ha\n\tla %s,", reg_names[0]); - assemble_name (file, buf); - asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]); - } - else if (flag_pic == 1) - { - fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); - asm_fprintf (file, "\tstw %s,4(%s)\n", - reg_names[0], reg_names[1]); - asm_fprintf (file, "\tmflr %s\n", reg_names[12]); - asm_fprintf (file, "\tlwz %s,", reg_names[0]); - assemble_name (file, buf); - asm_fprintf (file, "@got(%s)\n", reg_names[12]); - } - else if (flag_pic > 1) - { - asm_fprintf (file, "\tstw %s,4(%s)\n", - reg_names[0], reg_names[1]); - /* Now, we need to get the address of the label. */ - if (TARGET_LINK_STACK) - { - char name[32]; - get_ppc476_thunk_name (name); - asm_fprintf (file, "\tbl %s\n\tb 1f\n\t.long ", name); - assemble_name (file, buf); - fputs ("-.\n1:", file); - asm_fprintf (file, "\tmflr %s\n", reg_names[11]); - asm_fprintf (file, "\taddi %s,%s,4\n", - reg_names[11], reg_names[11]); - } - else - { - fputs ("\tbcl 20,31,1f\n\t.long ", file); - assemble_name (file, buf); - fputs ("-.\n1:", file); - asm_fprintf (file, "\tmflr %s\n", reg_names[11]); - } - asm_fprintf (file, "\tlwz %s,0(%s)\n", - reg_names[0], reg_names[11]); - asm_fprintf (file, "\tadd %s,%s,%s\n", - reg_names[0], reg_names[0], reg_names[11]); - } - else - { - asm_fprintf (file, "\tlis %s,", reg_names[12]); - assemble_name (file, buf); - fputs ("@ha\n", file); - asm_fprintf (file, "\tstw %s,4(%s)\n", - reg_names[0], reg_names[1]); - asm_fprintf (file, "\tla %s,", reg_names[0]); - assemble_name (file, buf); - asm_fprintf (file, "@l(%s)\n", reg_names[12]); - } - - /* 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: - if (!TARGET_PROFILE_KERNEL) - { - /* Don't do anything, done in output_profile_hook (). */ - } - else - { - gcc_assert (!TARGET_32BIT); - - asm_fprintf (file, "\tmflr %s\n", reg_names[0]); - asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]); - - if (cfun->static_chain_decl != NULL) - { - 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; - } -} - - - -/* The following variable value is the last issued insn. */ - -static rtx last_scheduled_insn; - -/* The following variable helps to balance issuing of load and - store instructions */ - -static int load_store_pendulum; - -/* 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_1 (rtx insn, int more) -{ - last_scheduled_insn = insn; - if (GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER) - { - cached_can_issue_more = more; - return cached_can_issue_more; - } - - if (insn_terminates_group_p (insn, current_group)) - { - cached_can_issue_more = 0; - return cached_can_issue_more; - } - - /* If no reservation, but reach here */ - if (recog_memoized (insn) < 0) - return more; - - if (rs6000_sched_groups) - { - if (is_microcoded_insn (insn)) - cached_can_issue_more = 0; - else if (is_cracked_insn (insn)) - cached_can_issue_more = more > 2 ? more - 2 : 0; - else - cached_can_issue_more = more - 1; - - return cached_can_issue_more; - } - - if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn)) - return 0; - - cached_can_issue_more = more - 1; - return cached_can_issue_more; -} - -static int -rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more) -{ - int r = rs6000_variable_issue_1 (insn, more); - if (verbose) - fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r); - return r; -} - -/* 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 (rtx insn, rtx link, rtx dep_insn, int cost) -{ - enum attr_type attr_type; - - if (! recog_memoized (insn)) - return 0; - - switch (REG_NOTE_KIND (link)) - { - case REG_DEP_TRUE: - { - /* Data dependency; DEP_INSN writes a register that INSN reads - some cycles later. */ - - /* Separate a load from a narrower, dependent store. */ - if (rs6000_sched_groups - && GET_CODE (PATTERN (insn)) == SET - && GET_CODE (PATTERN (dep_insn)) == SET - && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM - && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM - && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1))) - > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0))))) - return cost + 14; - - attr_type = get_attr_type (insn); - - switch (attr_type) - { - case TYPE_JMPREG: - /* Tell the first scheduling pass about the latency between - a mtctr and bctr (and mtlr and br/blr). The first - scheduling pass will not know about this latency since - the mtctr instruction, which has the latency associated - to it, will be generated by reload. */ - return 4; - case TYPE_BRANCH: - /* Leave some extra cycles between a compare and its - dependent branch, to inhibit expensive mispredicts. */ - if ((rs6000_cpu_attr == CPU_PPC603 - || rs6000_cpu_attr == CPU_PPC604 - || rs6000_cpu_attr == CPU_PPC604E - || rs6000_cpu_attr == CPU_PPC620 - || rs6000_cpu_attr == CPU_PPC630 - || rs6000_cpu_attr == CPU_PPC750 - || rs6000_cpu_attr == CPU_PPC7400 - || rs6000_cpu_attr == CPU_PPC7450 - || rs6000_cpu_attr == CPU_PPCE5500 - || rs6000_cpu_attr == CPU_PPCE6500 - || rs6000_cpu_attr == CPU_POWER4 - || rs6000_cpu_attr == CPU_POWER5 - || rs6000_cpu_attr == CPU_POWER7 - || rs6000_cpu_attr == CPU_CELL) - && recog_memoized (dep_insn) - && (INSN_CODE (dep_insn) >= 0)) - - switch (get_attr_type (dep_insn)) - { - case TYPE_CMP: - case TYPE_COMPARE: - case TYPE_DELAYED_COMPARE: - case TYPE_IMUL_COMPARE: - case TYPE_LMUL_COMPARE: - case TYPE_FPCOMPARE: - case TYPE_CR_LOGICAL: - case TYPE_DELAYED_CR: - return cost + 2; - default: - break; - } - break; - - case TYPE_STORE: - case TYPE_STORE_U: - case TYPE_STORE_UX: - case TYPE_FPSTORE: - case TYPE_FPSTORE_U: - case TYPE_FPSTORE_UX: - if ((rs6000_cpu == PROCESSOR_POWER6) - && recog_memoized (dep_insn) - && (INSN_CODE (dep_insn) >= 0)) - { - - if (GET_CODE (PATTERN (insn)) != SET) - /* If this happens, we have to extend this to schedule - optimally. Return default for now. */ - return cost; - - /* Adjust the cost for the case where the value written - by a fixed point operation is used as the address - gen value on a store. */ - switch (get_attr_type (dep_insn)) - { - case TYPE_LOAD: - case TYPE_LOAD_U: - case TYPE_LOAD_UX: - case TYPE_CNTLZ: - { - if (! store_data_bypass_p (dep_insn, insn)) - return 4; - break; - } - case TYPE_LOAD_EXT: - case TYPE_LOAD_EXT_U: - case TYPE_LOAD_EXT_UX: - case TYPE_VAR_SHIFT_ROTATE: - case TYPE_VAR_DELAYED_COMPARE: - { - if (! store_data_bypass_p (dep_insn, insn)) - return 6; - break; - } - case TYPE_INTEGER: - case TYPE_COMPARE: - case TYPE_FAST_COMPARE: - case TYPE_EXTS: - case TYPE_SHIFT: - case TYPE_INSERT_WORD: - case TYPE_INSERT_DWORD: - case TYPE_FPLOAD_U: - case TYPE_FPLOAD_UX: - case TYPE_STORE_U: - case TYPE_STORE_UX: - case TYPE_FPSTORE_U: - case TYPE_FPSTORE_UX: - { - if (! store_data_bypass_p (dep_insn, insn)) - return 3; - break; - } - case TYPE_IMUL: - case TYPE_IMUL2: - case TYPE_IMUL3: - case TYPE_LMUL: - case TYPE_IMUL_COMPARE: - case TYPE_LMUL_COMPARE: - { - if (! store_data_bypass_p (dep_insn, insn)) - return 17; - break; - } - case TYPE_IDIV: - { - if (! store_data_bypass_p (dep_insn, insn)) - return 45; - break; - } - case TYPE_LDIV: - { - if (! store_data_bypass_p (dep_insn, insn)) - return 57; - break; - } - default: - break; - } - } - break; - - case TYPE_LOAD: - case TYPE_LOAD_U: - case TYPE_LOAD_UX: - case TYPE_LOAD_EXT: - case TYPE_LOAD_EXT_U: - case TYPE_LOAD_EXT_UX: - if ((rs6000_cpu == PROCESSOR_POWER6) - && recog_memoized (dep_insn) - && (INSN_CODE (dep_insn) >= 0)) - { - - /* Adjust the cost for the case where the value written - by a fixed point instruction is used within the address - gen portion of a subsequent load(u)(x) */ - switch (get_attr_type (dep_insn)) - { - case TYPE_LOAD: - case TYPE_LOAD_U: - case TYPE_LOAD_UX: - case TYPE_CNTLZ: - { - if (set_to_load_agen (dep_insn, insn)) - return 4; - break; - } - case TYPE_LOAD_EXT: - case TYPE_LOAD_EXT_U: - case TYPE_LOAD_EXT_UX: - case TYPE_VAR_SHIFT_ROTATE: - case TYPE_VAR_DELAYED_COMPARE: - { - if (set_to_load_agen (dep_insn, insn)) - return 6; - break; - } - case TYPE_INTEGER: - case TYPE_COMPARE: - case TYPE_FAST_COMPARE: - case TYPE_EXTS: - case TYPE_SHIFT: - case TYPE_INSERT_WORD: - case TYPE_INSERT_DWORD: - case TYPE_FPLOAD_U: - case TYPE_FPLOAD_UX: - case TYPE_STORE_U: - case TYPE_STORE_UX: - case TYPE_FPSTORE_U: - case TYPE_FPSTORE_UX: - { - if (set_to_load_agen (dep_insn, insn)) - return 3; - break; - } - case TYPE_IMUL: - case TYPE_IMUL2: - case TYPE_IMUL3: - case TYPE_LMUL: - case TYPE_IMUL_COMPARE: - case TYPE_LMUL_COMPARE: - { - if (set_to_load_agen (dep_insn, insn)) - return 17; - break; - } - case TYPE_IDIV: - { - if (set_to_load_agen (dep_insn, insn)) - return 45; - break; - } - case TYPE_LDIV: - { - if (set_to_load_agen (dep_insn, insn)) - return 57; - break; - } - default: - break; - } - } - break; - - case TYPE_FPLOAD: - if ((rs6000_cpu == PROCESSOR_POWER6) - && recog_memoized (dep_insn) - && (INSN_CODE (dep_insn) >= 0) - && (get_attr_type (dep_insn) == TYPE_MFFGPR)) - return 2; - - default: - break; - } - - /* Fall out to return default cost. */ - } - break; - - case REG_DEP_OUTPUT: - /* Output dependency; DEP_INSN writes a register that INSN writes some - cycles later. */ - if ((rs6000_cpu == PROCESSOR_POWER6) - && recog_memoized (dep_insn) - && (INSN_CODE (dep_insn) >= 0)) - { - attr_type = get_attr_type (insn); - - switch (attr_type) - { - case TYPE_FP: - if (get_attr_type (dep_insn) == TYPE_FP) - return 1; - break; - case TYPE_FPLOAD: - if (get_attr_type (dep_insn) == TYPE_MFFGPR) - return 2; - break; - default: - break; - } - } - case REG_DEP_ANTI: - /* Anti dependency; DEP_INSN reads a register that INSN writes some - cycles later. */ - return 0; - - default: - gcc_unreachable (); - } - - return cost; -} - -/* Debug version of rs6000_adjust_cost. */ - -static int -rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost) -{ - int ret = rs6000_adjust_cost (insn, link, dep_insn, cost); - - if (ret != cost) - { - const char *dep; - - switch (REG_NOTE_KIND (link)) - { - default: dep = "unknown depencency"; break; - case REG_DEP_TRUE: dep = "data dependency"; break; - case REG_DEP_OUTPUT: dep = "output dependency"; break; - case REG_DEP_ANTI: dep = "anti depencency"; break; - } - - fprintf (stderr, - "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, " - "%s, insn:\n", ret, cost, dep); - - debug_rtx (insn); - } - - return ret; -} - -/* The function returns a true if INSN is microcoded. - Return false otherwise. */ - -static bool -is_microcoded_insn (rtx insn) -{ - if (!insn || !NONDEBUG_INSN_P (insn) - || GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER) - return false; - - if (rs6000_cpu_attr == CPU_CELL) - return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS; - - 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 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 || !NONDEBUG_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 || !NONDEBUG_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; -} - -/* The function returns true if out_inst sets a value that is - used in the address generation computation of in_insn */ -static bool -set_to_load_agen (rtx out_insn, rtx in_insn) -{ - rtx out_set, in_set; - - /* For performance reasons, only handle the simple case where - both loads are a single_set. */ - out_set = single_set (out_insn); - if (out_set) - { - in_set = single_set (in_insn); - if (in_set) - return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set)); - } - - return false; -} - -/* Try to determine base/offset/size parts of the given MEM. - Return true if successful, false if all the values couldn't - be determined. - - This function only looks for REG or REG+CONST address forms. - REG+REG address form will return false. */ - -static bool -get_memref_parts (rtx mem, rtx *base, HOST_WIDE_INT *offset, - HOST_WIDE_INT *size) -{ - rtx addr_rtx; - if MEM_SIZE_KNOWN_P (mem) - *size = MEM_SIZE (mem); - else - return false; - - if (GET_CODE (XEXP (mem, 0)) == PRE_MODIFY) - addr_rtx = XEXP (XEXP (mem, 0), 1); - else - addr_rtx = (XEXP (mem, 0)); - - if (GET_CODE (addr_rtx) == REG) - { - *base = addr_rtx; - *offset = 0; - } - else if (GET_CODE (addr_rtx) == PLUS - && CONST_INT_P (XEXP (addr_rtx, 1))) - { - *base = XEXP (addr_rtx, 0); - *offset = INTVAL (XEXP (addr_rtx, 1)); - } - else - return false; - - return true; -} - -/* The function returns true if the target storage location of - mem1 is adjacent to the target storage location of mem2 */ -/* Return 1 if memory locations are adjacent. */ - -static bool -adjacent_mem_locations (rtx mem1, rtx mem2) -{ - rtx reg1, reg2; - HOST_WIDE_INT off1, size1, off2, size2; - - if (get_memref_parts (mem1, ®1, &off1, &size1) - && get_memref_parts (mem2, ®2, &off2, &size2)) - return ((REGNO (reg1) == REGNO (reg2)) - && ((off1 + size1 == off2) - || (off2 + size2 == off1))); - - return false; -} - -/* This function returns true if it can be determined that the two MEM - locations overlap by at least 1 byte based on base reg/offset/size. */ - -static bool -mem_locations_overlap (rtx mem1, rtx mem2) -{ - rtx reg1, reg2; - HOST_WIDE_INT off1, size1, off2, size2; - - if (get_memref_parts (mem1, ®1, &off1, &size1) - && get_memref_parts (mem2, ®2, &off2, &size2)) - return ((REGNO (reg1) == REGNO (reg2)) - && (((off1 <= off2) && (off1 + size1 > off2)) - || ((off2 <= off1) && (off2 + size2 > off1)))); - - return false; -} - -/* A C statement (sans semicolon) to update the integer scheduling - 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 (rtx insn ATTRIBUTE_UNUSED, int priority) -{ - rtx load_mem, str_mem; - /* On machines (like the 750) which have asymmetric integer units, - where one integer unit can do multiply and divides and the other - can't, reduce the priority of multiply/divide so it is scheduled - before other integer operations. */ - -#if 0 - if (! INSN_P (insn)) - return priority; - - if (GET_CODE (PATTERN (insn)) == USE) - return priority; - - switch (rs6000_cpu_attr) { - case CPU_PPC750: - switch (get_attr_type (insn)) - { - default: - break; - - case TYPE_IMUL: - case TYPE_IDIV: - fprintf (stderr, "priority was %#x (%d) before adjustment\n", - priority, priority); - if (priority >= 0 && priority < 0x01000000) - priority >>= 3; - break; - } - } -#endif - - if (insn_must_be_first_in_group (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); - } - - if (rs6000_cpu == PROCESSOR_POWER6 - && ((load_store_pendulum == -2 && is_load_insn (insn, &load_mem)) - || (load_store_pendulum == 2 && is_store_insn (insn, &str_mem)))) - /* Attach highest priority to insn if the scheduler has just issued two - stores and this instruction is a load, or two loads and this instruction - is a store. Power6 wants loads and stores scheduled alternately - when possible */ - return current_sched_info->sched_max_insns_priority; - - return priority; -} - -/* Return true if the instruction is nonpipelined on the Cell. */ -static bool -is_nonpipeline_insn (rtx insn) -{ - enum attr_type type; - if (!insn || !NONDEBUG_INSN_P (insn) - || GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER) - return false; - - type = get_attr_type (insn); - if (type == TYPE_IMUL - || type == TYPE_IMUL2 - || type == TYPE_IMUL3 - || type == TYPE_LMUL - || type == TYPE_IDIV - || type == TYPE_LDIV - || type == TYPE_SDIV - || type == TYPE_DDIV - || type == TYPE_SSQRT - || type == TYPE_DSQRT - || type == TYPE_MFCR - || type == TYPE_MFCRF - || type == TYPE_MFJMPR) - { - return true; - } - return false; -} - - -/* Return how many instructions the machine can issue per cycle. */ - -static int -rs6000_issue_rate (void) -{ - /* Unless scheduling for register pressure, use issue rate of 1 for - first scheduling pass to decrease degradation. */ - if (!reload_completed && !flag_sched_pressure) - return 1; - - switch (rs6000_cpu_attr) { - 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: - case CPU_PPC8548: - case CPU_CELL: - case CPU_PPCE300C2: - case CPU_PPCE300C3: - case CPU_PPCE500MC: - case CPU_PPCE500MC64: - case CPU_PPCE5500: - case CPU_PPCE6500: - case CPU_TITAN: - return 2; - case CPU_PPC476: - case CPU_PPC604: - case CPU_PPC604E: - case CPU_PPC620: - case CPU_PPC630: - return 4; - case CPU_POWER4: - case CPU_POWER5: - case CPU_POWER6: - case CPU_POWER7: - return 5; - default: - return 1; - } -} - -/* Return how many instructions to look ahead for better insn - scheduling. */ - -static int -rs6000_use_sched_lookahead (void) -{ - switch (rs6000_cpu_attr) - { - case CPU_PPC8540: - case CPU_PPC8548: - return 4; - - case CPU_CELL: - return (reload_completed ? 8 : 0); - - default: - return 0; - } -} - -/* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */ -static int -rs6000_use_sched_lookahead_guard (rtx insn) -{ - if (rs6000_cpu_attr != CPU_CELL) - return 1; - - if (insn == NULL_RTX || !INSN_P (insn)) - abort (); - - if (!reload_completed - || is_nonpipeline_insn (insn) - || is_microcoded_insn (insn)) - return 0; - - return 1; -} - -/* Determine if PAT refers to memory. If so, set MEM_REF to the MEM rtx - and return true. */ - -static bool -find_mem_ref (rtx pat, rtx *mem_ref) -{ - const char * fmt; - int i, j; - - /* stack_tie does not produce any real memory traffic. */ - if (tie_operand (pat, VOIDmode)) - return false; - - if (GET_CODE (pat) == MEM) - { - *mem_ref = pat; - return true; - } - - /* Recursively process the pattern. */ - fmt = GET_RTX_FORMAT (GET_CODE (pat)); - - for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--) - { - if (fmt[i] == 'e') - { - if (find_mem_ref (XEXP (pat, i), mem_ref)) - return true; - } - else if (fmt[i] == 'E') - for (j = XVECLEN (pat, i) - 1; j >= 0; j--) - { - if (find_mem_ref (XVECEXP (pat, i, j), mem_ref)) - return true; - } - } - - return false; -} - -/* Determine if PAT is a PATTERN of a load insn. */ - -static bool -is_load_insn1 (rtx pat, rtx *load_mem) -{ - if (!pat || pat == NULL_RTX) - return false; - - if (GET_CODE (pat) == SET) - return find_mem_ref (SET_SRC (pat), load_mem); - - if (GET_CODE (pat) == PARALLEL) - { - int i; - - for (i = 0; i < XVECLEN (pat, 0); i++) - if (is_load_insn1 (XVECEXP (pat, 0, i), load_mem)) - return true; - } - - return false; -} - -/* Determine if INSN loads from memory. */ - -static bool -is_load_insn (rtx insn, rtx *load_mem) -{ - if (!insn || !INSN_P (insn)) - return false; - - if (GET_CODE (insn) == CALL_INSN) - return false; - - return is_load_insn1 (PATTERN (insn), load_mem); -} - -/* Determine if PAT is a PATTERN of a store insn. */ - -static bool -is_store_insn1 (rtx pat, rtx *str_mem) -{ - if (!pat || pat == NULL_RTX) - return false; - - if (GET_CODE (pat) == SET) - return find_mem_ref (SET_DEST (pat), str_mem); - - if (GET_CODE (pat) == PARALLEL) - { - int i; - - for (i = 0; i < XVECLEN (pat, 0); i++) - if (is_store_insn1 (XVECEXP (pat, 0, i), str_mem)) - return true; - } - - return false; -} - -/* Determine if INSN stores to memory. */ - -static bool -is_store_insn (rtx insn, rtx *str_mem) -{ - if (!insn || !INSN_P (insn)) - return false; - - return is_store_insn1 (PATTERN (insn), str_mem); -} - -/* Returns whether the dependence between INSN and NEXT is considered - costly by the given target. */ - -static bool -rs6000_is_costly_dependence (dep_t dep, int cost, int distance) -{ - rtx insn; - rtx next; - rtx load_mem, str_mem; - - /* If the flag is not enabled - 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; - - insn = DEP_PRO (dep); - next = DEP_CON (dep); - - if (rs6000_sched_costly_dep == store_to_load_dep_costly - && is_load_insn (next, &load_mem) - && is_store_insn (insn, &str_mem)) - /* 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, &load_mem) - && is_store_insn (insn, &str_mem) - && DEP_TYPE (dep) == REG_DEP_TRUE - && mem_locations_overlap(str_mem, load_mem)) - /* 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) -{ - if (insn == NULL_RTX || insn == tail) - return NULL_RTX; - - while (1) - { - insn = NEXT_INSN (insn); - if (insn == NULL_RTX || insn == tail) - return NULL_RTX; - - if (CALL_P (insn) - || JUMP_P (insn) - || (NONJUMP_INSN_P (insn) - && GET_CODE (PATTERN (insn)) != USE - && GET_CODE (PATTERN (insn)) != CLOBBER - && INSN_CODE (insn) != CODE_FOR_stack_tie)) - break; - } - return insn; -} - -/* We are about to begin issuing insns for this clock cycle. */ - -static int -rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose, - rtx *ready ATTRIBUTE_UNUSED, - int *pn_ready ATTRIBUTE_UNUSED, - int clock_var ATTRIBUTE_UNUSED) -{ - int n_ready = *pn_ready; - - if (sched_verbose) - fprintf (dump, "// rs6000_sched_reorder :\n"); - - /* Reorder the ready list, if the second to last ready insn - is a nonepipeline insn. */ - if (rs6000_cpu_attr == CPU_CELL && n_ready > 1) - { - if (is_nonpipeline_insn (ready[n_ready - 1]) - && (recog_memoized (ready[n_ready - 2]) > 0)) - /* Simply swap first two insns. */ - { - rtx tmp = ready[n_ready - 1]; - ready[n_ready - 1] = ready[n_ready - 2]; - ready[n_ready - 2] = tmp; - } - } - - if (rs6000_cpu == PROCESSOR_POWER6) - load_store_pendulum = 0; - - return rs6000_issue_rate (); -} - -/* Like rs6000_sched_reorder, but called after issuing each insn. */ - -static int -rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready, - int *pn_ready, int clock_var ATTRIBUTE_UNUSED) -{ - if (sched_verbose) - fprintf (dump, "// rs6000_sched_reorder2 :\n"); - - /* For Power6, we need to handle some special cases to try and keep the - store queue from overflowing and triggering expensive flushes. - - This code monitors how load and store instructions are being issued - and skews the ready list one way or the other to increase the likelihood - that a desired instruction is issued at the proper time. - - A couple of things are done. First, we maintain a "load_store_pendulum" - to track the current state of load/store issue. - - - If the pendulum is at zero, then no loads or stores have been - issued in the current cycle so we do nothing. - - - If the pendulum is 1, then a single load has been issued in this - cycle and we attempt to locate another load in the ready list to - issue with it. - - - If the pendulum is -2, then two stores have already been - issued in this cycle, so we increase the priority of the first load - in the ready list to increase it's likelihood of being chosen first - in the next cycle. - - - If the pendulum is -1, then a single store has been issued in this - cycle and we attempt to locate another store in the ready list to - issue with it, preferring a store to an adjacent memory location to - facilitate store pairing in the store queue. - - - If the pendulum is 2, then two loads have already been - issued in this cycle, so we increase the priority of the first store - in the ready list to increase it's likelihood of being chosen first - in the next cycle. - - - If the pendulum < -2 or > 2, then do nothing. - - Note: This code covers the most common scenarios. There exist non - load/store instructions which make use of the LSU and which - would need to be accounted for to strictly model the behavior - of the machine. Those instructions are currently unaccounted - for to help minimize compile time overhead of this code. - */ - if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn) - { - int pos; - int i; - rtx tmp, load_mem, str_mem; - - if (is_store_insn (last_scheduled_insn, &str_mem)) - /* Issuing a store, swing the load_store_pendulum to the left */ - load_store_pendulum--; - else if (is_load_insn (last_scheduled_insn, &load_mem)) - /* Issuing a load, swing the load_store_pendulum to the right */ - load_store_pendulum++; - else - return cached_can_issue_more; - - /* If the pendulum is balanced, or there is only one instruction on - the ready list, then all is well, so return. */ - if ((load_store_pendulum == 0) || (*pn_ready <= 1)) - return cached_can_issue_more; - - if (load_store_pendulum == 1) - { - /* A load has been issued in this cycle. Scan the ready list - for another load to issue with it */ - pos = *pn_ready-1; - - while (pos >= 0) - { - if (is_load_insn (ready[pos], &load_mem)) - { - /* Found a load. Move it to the head of the ready list, - and adjust it's priority so that it is more likely to - stay there */ - tmp = ready[pos]; - for (i=pos; i<*pn_ready-1; i++) - ready[i] = ready[i + 1]; - ready[*pn_ready-1] = tmp; - - if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp)) - INSN_PRIORITY (tmp)++; - break; - } - pos--; - } - } - else if (load_store_pendulum == -2) - { - /* Two stores have been issued in this cycle. Increase the - priority of the first load in the ready list to favor it for - issuing in the next cycle. */ - pos = *pn_ready-1; - - while (pos >= 0) - { - if (is_load_insn (ready[pos], &load_mem) - && !sel_sched_p () - && INSN_PRIORITY_KNOWN (ready[pos])) - { - INSN_PRIORITY (ready[pos])++; - - /* Adjust the pendulum to account for the fact that a load - was found and increased in priority. This is to prevent - increasing the priority of multiple loads */ - load_store_pendulum--; - - break; - } - pos--; - } - } - else if (load_store_pendulum == -1) - { - /* A store has been issued in this cycle. Scan the ready list for - another store to issue with it, preferring a store to an adjacent - memory location */ - int first_store_pos = -1; - - pos = *pn_ready-1; - - while (pos >= 0) - { - if (is_store_insn (ready[pos], &str_mem)) - { - rtx str_mem2; - /* Maintain the index of the first store found on the - list */ - if (first_store_pos == -1) - first_store_pos = pos; - - if (is_store_insn (last_scheduled_insn, &str_mem2) - && adjacent_mem_locations (str_mem, str_mem2)) - { - /* Found an adjacent store. Move it to the head of the - ready list, and adjust it's priority so that it is - more likely to stay there */ - tmp = ready[pos]; - for (i=pos; i<*pn_ready-1; i++) - ready[i] = ready[i + 1]; - ready[*pn_ready-1] = tmp; - - if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp)) - INSN_PRIORITY (tmp)++; - - first_store_pos = -1; - - break; - }; - } - pos--; - } - - if (first_store_pos >= 0) - { - /* An adjacent store wasn't found, but a non-adjacent store was, - so move the non-adjacent store to the front of the ready - list, and adjust its priority so that it is more likely to - stay there. */ - tmp = ready[first_store_pos]; - for (i=first_store_pos; i<*pn_ready-1; i++) - ready[i] = ready[i + 1]; - ready[*pn_ready-1] = tmp; - if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp)) - INSN_PRIORITY (tmp)++; - } - } - else if (load_store_pendulum == 2) - { - /* Two loads have been issued in this cycle. Increase the priority - of the first store in the ready list to favor it for issuing in - the next cycle. */ - pos = *pn_ready-1; - - while (pos >= 0) - { - if (is_store_insn (ready[pos], &str_mem) - && !sel_sched_p () - && INSN_PRIORITY_KNOWN (ready[pos])) - { - INSN_PRIORITY (ready[pos])++; - - /* Adjust the pendulum to account for the fact that a store - was found and increased in priority. This is to prevent - increasing the priority of multiple stores */ - load_store_pendulum++; - - break; - } - pos--; - } - } - } - - return cached_can_issue_more; -} - -/* 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) -{ - bool first, last; - - if (! insn) - return false; - - first = insn_must_be_first_in_group (insn); - last = insn_must_be_last_in_group (insn); - - if (first && last) - return true; - - if (which_group == current_group) - return last; - else if (which_group == previous_group) - return first; - - return false; -} - - -static bool -insn_must_be_first_in_group (rtx insn) -{ - enum attr_type type; - - if (!insn - || GET_CODE (insn) == NOTE - || DEBUG_INSN_P (insn) - || GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER) - return false; - - switch (rs6000_cpu) - { - case PROCESSOR_POWER5: - if (is_cracked_insn (insn)) - return true; - case PROCESSOR_POWER4: - if (is_microcoded_insn (insn)) - return true; - - if (!rs6000_sched_groups) - return false; - - 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: - case TYPE_IDIV: - case TYPE_LDIV: - case TYPE_LOAD_L: - case TYPE_STORE_C: - case TYPE_ISYNC: - case TYPE_SYNC: - return true; - default: - break; - } - break; - case PROCESSOR_POWER6: - type = get_attr_type (insn); - - switch (type) - { - case TYPE_INSERT_DWORD: - case TYPE_EXTS: - case TYPE_CNTLZ: - case TYPE_SHIFT: - case TYPE_VAR_SHIFT_ROTATE: - case TYPE_TRAP: - case TYPE_IMUL: - case TYPE_IMUL2: - case TYPE_IMUL3: - case TYPE_LMUL: - case TYPE_IDIV: - case TYPE_INSERT_WORD: - case TYPE_DELAYED_COMPARE: - case TYPE_IMUL_COMPARE: - case TYPE_LMUL_COMPARE: - case TYPE_FPCOMPARE: - case TYPE_MFCR: - case TYPE_MTCR: - case TYPE_MFJMPR: - case TYPE_MTJMPR: - case TYPE_ISYNC: - case TYPE_SYNC: - case TYPE_LOAD_L: - case TYPE_STORE_C: - case TYPE_LOAD_U: - case TYPE_LOAD_UX: - case TYPE_LOAD_EXT_UX: - case TYPE_STORE_U: - case TYPE_STORE_UX: - case TYPE_FPLOAD_U: - case TYPE_FPLOAD_UX: - case TYPE_FPSTORE_U: - case TYPE_FPSTORE_UX: - return true; - default: - break; - } - break; - case PROCESSOR_POWER7: - type = get_attr_type (insn); - - switch (type) - { - case TYPE_CR_LOGICAL: - case TYPE_MFCR: - case TYPE_MFCRF: - case TYPE_MTCR: - case TYPE_IDIV: - case TYPE_LDIV: - case TYPE_COMPARE: - case TYPE_DELAYED_COMPARE: - case TYPE_VAR_DELAYED_COMPARE: - case TYPE_ISYNC: - case TYPE_LOAD_L: - case TYPE_STORE_C: - case TYPE_LOAD_U: - case TYPE_LOAD_UX: - case TYPE_LOAD_EXT: - case TYPE_LOAD_EXT_U: - case TYPE_LOAD_EXT_UX: - case TYPE_STORE_U: - case TYPE_STORE_UX: - case TYPE_FPLOAD_U: - case TYPE_FPLOAD_UX: - case TYPE_FPSTORE_U: - case TYPE_FPSTORE_UX: - case TYPE_MFJMPR: - case TYPE_MTJMPR: - return true; - default: - break; - } - break; - default: - break; - } - - return false; -} - -static bool -insn_must_be_last_in_group (rtx insn) -{ - enum attr_type type; - - if (!insn - || GET_CODE (insn) == NOTE - || DEBUG_INSN_P (insn) - || GET_CODE (PATTERN (insn)) == USE - || GET_CODE (PATTERN (insn)) == CLOBBER) - return false; - - switch (rs6000_cpu) { - case PROCESSOR_POWER4: - case PROCESSOR_POWER5: - if (is_microcoded_insn (insn)) - return true; - - if (is_branch_slot_insn (insn)) - return true; - - break; - case PROCESSOR_POWER6: - type = get_attr_type (insn); - - switch (type) - { - case TYPE_EXTS: - case TYPE_CNTLZ: - case TYPE_SHIFT: - case TYPE_VAR_SHIFT_ROTATE: - case TYPE_TRAP: - case TYPE_IMUL: - case TYPE_IMUL2: - case TYPE_IMUL3: - case TYPE_LMUL: - case TYPE_IDIV: - case TYPE_DELAYED_COMPARE: - case TYPE_IMUL_COMPARE: - case TYPE_LMUL_COMPARE: - case TYPE_FPCOMPARE: - case TYPE_MFCR: - case TYPE_MTCR: - case TYPE_MFJMPR: - case TYPE_MTJMPR: - case TYPE_ISYNC: - case TYPE_SYNC: - case TYPE_LOAD_L: - case TYPE_STORE_C: - return true; - default: - break; - } - break; - case PROCESSOR_POWER7: - type = get_attr_type (insn); - - switch (type) - { - case TYPE_ISYNC: - case TYPE_SYNC: - case TYPE_LOAD_L: - case TYPE_STORE_C: - case TYPE_LOAD_EXT_U: - case TYPE_LOAD_EXT_UX: - case TYPE_STORE_UX: - return true; - default: - break; - } - break; - default: - break; - } - - 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; - int issue_rate = rs6000_issue_rate (); - - for (i = 0; i < issue_rate; i++) - { - sd_iterator_def sd_it; - dep_t dep; - rtx insn = group_insns[i]; - - if (!insn) - continue; - - FOR_EACH_DEP (insn, SD_LIST_RES_FORW, sd_it, dep) - { - rtx next = DEP_CON (dep); - - if (next == next_insn - && rs6000_is_costly_dependence (dep, dep_cost (dep), 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 || DEBUG_INSN_P (next_insn)) - 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--; - - /* Power6 and Power7 have special group ending nop. */ - if (rs6000_cpu_attr == CPU_POWER6 || rs6000_cpu_attr == CPU_POWER7) - { - nop = gen_group_ending_nop (); - emit_insn_before (nop, next_insn); - can_issue_more = 0; - } - else - 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++; - - /* Is next_insn going to start a new group? */ - *group_end - = (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 - follows: 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 = XALLOCAVEC (rtx, issue_rate); - 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; - - /* Is next_insn going to start a new group? */ - group_end - = (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_insn), 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; -} - -/* We're beginning a new block. Initialize data structures as necessary. */ - -static void -rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED, - int sched_verbose ATTRIBUTE_UNUSED, - int max_ready ATTRIBUTE_UNUSED) -{ - last_scheduled_insn = NULL_RTX; - load_store_pendulum = 0; -} - -/* 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) - { - /* Do not run sched_finish hook when selective scheduling enabled. */ - if (sel_sched_p ()) - return; - - 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"); - } - } -} - -struct _rs6000_sched_context -{ - short cached_can_issue_more; - rtx last_scheduled_insn; - int load_store_pendulum; -}; - -typedef struct _rs6000_sched_context rs6000_sched_context_def; -typedef rs6000_sched_context_def *rs6000_sched_context_t; - -/* Allocate store for new scheduling context. */ -static void * -rs6000_alloc_sched_context (void) -{ - return xmalloc (sizeof (rs6000_sched_context_def)); -} - -/* If CLEAN_P is true then initializes _SC with clean data, - and from the global context otherwise. */ -static void -rs6000_init_sched_context (void *_sc, bool clean_p) -{ - rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc; - - if (clean_p) - { - sc->cached_can_issue_more = 0; - sc->last_scheduled_insn = NULL_RTX; - sc->load_store_pendulum = 0; - } - else - { - sc->cached_can_issue_more = cached_can_issue_more; - sc->last_scheduled_insn = last_scheduled_insn; - sc->load_store_pendulum = load_store_pendulum; - } -} - -/* Sets the global scheduling context to the one pointed to by _SC. */ -static void -rs6000_set_sched_context (void *_sc) -{ - rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc; - - gcc_assert (sc != NULL); - - cached_can_issue_more = sc->cached_can_issue_more; - last_scheduled_insn = sc->last_scheduled_insn; - load_store_pendulum = sc->load_store_pendulum; -} - -/* Free _SC. */ -static void -rs6000_free_sched_context (void *_sc) -{ - gcc_assert (_sc != NULL); - - free (_sc); -} - - -/* Length in units of the trampoline for entering a nested function. */ - -int -rs6000_trampoline_size (void) -{ - int ret = 0; - - switch (DEFAULT_ABI) - { - default: - gcc_unreachable (); - - case ABI_AIX: - ret = (TARGET_32BIT) ? 12 : 24; - break; - - case ABI_DARWIN: - case ABI_V4: - ret = (TARGET_32BIT) ? 40 : 48; - break; - } - - return ret; -} - -/* Emit RTL insns to initialize the variable parts of a trampoline. - FNADDR is an RTX for the address of the function's pure code. - CXT is an RTX for the static chain value for the function. */ - -static void -rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt) -{ - int regsize = (TARGET_32BIT) ? 4 : 8; - rtx fnaddr = XEXP (DECL_RTL (fndecl), 0); - rtx ctx_reg = force_reg (Pmode, cxt); - rtx addr = force_reg (Pmode, XEXP (m_tramp, 0)); - - switch (DEFAULT_ABI) - { - default: - gcc_unreachable (); - - /* Under AIX, just build the 3 word function descriptor */ - case ABI_AIX: - { - rtx fnmem, fn_reg, toc_reg; - - if (!TARGET_POINTERS_TO_NESTED_FUNCTIONS) - error ("You cannot take the address of a nested function if you use " - "the -mno-pointers-to-nested-functions option."); - - fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr)); - fn_reg = gen_reg_rtx (Pmode); - toc_reg = gen_reg_rtx (Pmode); - - /* Macro to shorten the code expansions below. */ -# define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET) - - m_tramp = replace_equiv_address (m_tramp, addr); - - emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0)); - emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize)); - emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg); - emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg); - emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg); - -# undef MEM_PLUS - } - break; - - /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */ - case ABI_DARWIN: - case ABI_V4: - emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"), - LCT_NORMAL, VOIDmode, 4, - addr, Pmode, - GEN_INT (rs6000_trampoline_size ()), SImode, - fnaddr, Pmode, - ctx_reg, Pmode); - break; - } -} - - -/* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain - identifier as an argument, so the front end shouldn't look it up. */ - -static bool -rs6000_attribute_takes_identifier_p (const_tree attr_id) -{ - return is_attribute_p ("altivec", attr_id); -} - -/* Handle the "altivec" attribute. The attribute may have - arguments as follows: - - __attribute__((altivec(vector__))) - __attribute__((altivec(pixel__))) (always followed by 'unsigned short') - __attribute__((altivec(bool__))) (always followed by 'unsigned') - - and may appear more than once (e.g., 'vector bool char') in a - given declaration. */ - -static tree -rs6000_handle_altivec_attribute (tree *node, - tree name ATTRIBUTE_UNUSED, - tree args, - int flags ATTRIBUTE_UNUSED, - bool *no_add_attrs) -{ - tree type = *node, result = NULL_TREE; - enum machine_mode mode; - int unsigned_p; - char altivec_type - = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args) - && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE) - ? *IDENTIFIER_POINTER (TREE_VALUE (args)) - : '?'); - - while (POINTER_TYPE_P (type) - || TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE - || TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - - mode = TYPE_MODE (type); - - /* Check for invalid AltiVec type qualifiers. */ - if (type == long_double_type_node) - error ("use of %<long double%> in AltiVec types is invalid"); - else if (type == boolean_type_node) - error ("use of boolean types in AltiVec types is invalid"); - else if (TREE_CODE (type) == COMPLEX_TYPE) - error ("use of %<complex%> in AltiVec types is invalid"); - else if (DECIMAL_FLOAT_MODE_P (mode)) - error ("use of decimal floating point types in AltiVec types is invalid"); - else if (!TARGET_VSX) - { - if (type == long_unsigned_type_node || type == long_integer_type_node) - { - if (TARGET_64BIT) - error ("use of %<long%> in AltiVec types is invalid for " - "64-bit code without -mvsx"); - else if (rs6000_warn_altivec_long) - warning (0, "use of %<long%> in AltiVec types is deprecated; " - "use %<int%>"); - } - else if (type == long_long_unsigned_type_node - || type == long_long_integer_type_node) - error ("use of %<long long%> in AltiVec types is invalid without " - "-mvsx"); - else if (type == double_type_node) - error ("use of %<double%> in AltiVec types is invalid without -mvsx"); - } - - switch (altivec_type) - { - case 'v': - unsigned_p = TYPE_UNSIGNED (type); - switch (mode) - { - case DImode: - result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); - break; - case SImode: - result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); - break; - case HImode: - result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node); - break; - case QImode: - result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); - break; - case SFmode: result = V4SF_type_node; break; - case DFmode: result = V2DF_type_node; break; - /* If the user says 'vector int bool', we may be handed the 'bool' - attribute _before_ the 'vector' attribute, and so select the - proper type in the 'b' case below. */ - case V4SImode: case V8HImode: case V16QImode: case V4SFmode: - case V2DImode: case V2DFmode: - result = type; - default: break; - } - break; - case 'b': - switch (mode) - { - case DImode: case V2DImode: result = bool_V2DI_type_node; break; - case SImode: case V4SImode: result = bool_V4SI_type_node; break; - case HImode: case V8HImode: result = bool_V8HI_type_node; break; - case QImode: case V16QImode: result = bool_V16QI_type_node; - default: break; - } - break; - case 'p': - switch (mode) - { - case V8HImode: result = pixel_V8HI_type_node; - default: break; - } - default: break; - } - - /* Propagate qualifiers attached to the element type - onto the vector type. */ - if (result && result != type && TYPE_QUALS (type)) - result = build_qualified_type (result, TYPE_QUALS (type)); - - *no_add_attrs = true; /* No need to hang on to the attribute. */ - - if (result) - *node = lang_hooks.types.reconstruct_complex_type (*node, result); - - return NULL_TREE; -} - -/* AltiVec defines four built-in scalar types that serve as vector - elements; we must teach the compiler how to mangle them. */ - -static const char * -rs6000_mangle_type (const_tree type) -{ - type = TYPE_MAIN_VARIANT (type); - - if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE - && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) - return NULL; - - if (type == bool_char_type_node) return "U6__boolc"; - if (type == bool_short_type_node) return "U6__bools"; - if (type == pixel_type_node) return "u7__pixel"; - if (type == bool_int_type_node) return "U6__booli"; - if (type == bool_long_type_node) return "U6__booll"; - - /* Mangle IBM extended float long double as `g' (__float128) on - powerpc*-linux where long-double-64 previously was the default. */ - if (TYPE_MAIN_VARIANT (type) == long_double_type_node - && TARGET_ELF - && TARGET_LONG_DOUBLE_128 - && !TARGET_IEEEQUAD) - return "g"; - - /* For all other types, use normal C++ mangling. */ - return NULL; -} - -/* Handle a "longcall" or "shortcall" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -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 - && TREE_CODE (*node) != TYPE_DECL) - { - warning (OPT_Wattributes, "%qE attribute only applies to functions", - name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Set longcall attributes on all functions declared when - rs6000_default_long_calls is true. */ -static void -rs6000_set_default_type_attributes (tree type) -{ - if (rs6000_default_long_calls - && (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE)) - TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"), - NULL_TREE, - TYPE_ATTRIBUTES (type)); - -#if TARGET_MACHO - darwin_set_default_type_attributes (type); -#endif -} - -/* Return a reference suitable for calling a function with the - longcall attribute. */ - -rtx -rs6000_longcall_ref (rtx call_ref) -{ - const char *call_name; - tree node; - - if (GET_CODE (call_ref) != SYMBOL_REF) - return call_ref; - - /* System V adds '.' to the internal name, so skip them. */ - call_name = XSTR (call_ref, 0); - if (*call_name == '.') - { - while (*call_name == '.') - call_name++; - - node = get_identifier (call_name); - call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node)); - } - - return force_reg (Pmode, call_ref); -} - -#ifndef TARGET_USE_MS_BITFIELD_LAYOUT -#define TARGET_USE_MS_BITFIELD_LAYOUT 0 -#endif - -/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in - struct attribute_spec.handler. */ -static tree -rs6000_handle_struct_attribute (tree *node, tree name, - tree args ATTRIBUTE_UNUSED, - int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) -{ - tree *type = NULL; - if (DECL_P (*node)) - { - if (TREE_CODE (*node) == TYPE_DECL) - type = &TREE_TYPE (*node); - } - else - type = node; - - if (!(type && (TREE_CODE (*type) == RECORD_TYPE - || TREE_CODE (*type) == UNION_TYPE))) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - else if ((is_attribute_p ("ms_struct", name) - && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type))) - || ((is_attribute_p ("gcc_struct", name) - && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type))))) - { - warning (OPT_Wattributes, "%qE incompatible attribute ignored", - name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -static bool -rs6000_ms_bitfield_layout_p (const_tree record_type) -{ - return (TARGET_USE_MS_BITFIELD_LAYOUT && - !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type))) - || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)); -} - -#ifdef USING_ELFOS_H - -/* A get_unnamed_section callback, used for switching to toc_section. */ - -static void -rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED) -{ - if (DEFAULT_ABI == ABI_AIX - && TARGET_MINIMAL_TOC - && !TARGET_RELOCATABLE) - { - if (!toc_initialized) - { - toc_initialized = 1; - fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); - (*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"); - fprintf (asm_out_file, "\n"); - - fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); - fprintf (asm_out_file, " = .+32768\n"); - } - else - fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); - } - else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE) - fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); - else - { - fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); - if (!toc_initialized) - { - ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); - fprintf (asm_out_file, " = .+32768\n"); - toc_initialized = 1; - } - } -} - -/* Implement TARGET_ASM_INIT_SECTIONS. */ - -static void -rs6000_elf_asm_init_sections (void) -{ - toc_section - = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL); - - sdata2_section - = get_unnamed_section (SECTION_WRITE, output_section_asm_op, - SDATA2_SECTION_ASM_OP); -} - -/* Implement TARGET_SELECT_RTX_SECTION. */ - -static section * -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)) - return toc_section; - else - return default_elf_select_rtx_section (mode, x, align); -} - -/* 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 (tree, rtx, int) ATTRIBUTE_UNUSED; -static void -rs6000_elf_encode_section_info (tree decl, rtx rtl, int first) -{ - default_encode_section_info (decl, rtl, first); - - if (first - && TREE_CODE (decl) == FUNCTION_DECL - && !TARGET_AIX - && DEFAULT_ABI == ABI_AIX) - { - rtx sym_ref = XEXP (rtl, 0); - size_t len = strlen (XSTR (sym_ref, 0)); - char *str = XALLOCAVEC (char, len + 2); - str[0] = '.'; - memcpy (str + 1, XSTR (sym_ref, 0), len + 1); - XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1); - } -} - -static inline bool -compare_section_name (const char *section, const char *templ) -{ - int len; - - len = strlen (templ); - return (strncmp (section, templ, len) == 0 - && (section[len] == 0 || section[len] == '.')); -} - -bool -rs6000_elf_in_small_data_p (const_tree decl) -{ - if (rs6000_sdata == SDATA_NONE) - return false; - - /* We want to merge strings, so we never consider them small data. */ - if (TREE_CODE (decl) == STRING_CST) - return false; - - /* Functions are never in the small data area. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - return false; - - if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl)) - { - const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); - if (compare_section_name (section, ".sdata") - || compare_section_name (section, ".sdata2") - || compare_section_name (section, ".gnu.linkonce.s") - || compare_section_name (section, ".sbss") - || compare_section_name (section, ".sbss2") - || compare_section_name (section, ".gnu.linkonce.sb") - || strcmp (section, ".PPC.EMB.sdata0") == 0 - || strcmp (section, ".PPC.EMB.sbss0") == 0) - return true; - } - else - { - HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl)); - - if (size > 0 - && 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; - } - - return false; -} - -#endif /* USING_ELFOS_H */ - -/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */ - -static bool -rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x) -{ - return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode); -} - -/* Do not place thread-local symbols refs in the object blocks. */ - -static bool -rs6000_use_blocks_for_decl_p (const_tree decl) -{ - return !DECL_THREAD_LOCAL_P (decl); -} - -/* Return a REG that occurs in ADDR with coefficient 1. - ADDR can be effectively incremented by incrementing REG. - - r0 is special and we must not select it as an address - register by this routine since our caller will try to - increment the returned register via an "la" instruction. */ - -rtx -find_addr_reg (rtx addr) -{ - while (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == REG - && REGNO (XEXP (addr, 0)) != 0) - addr = XEXP (addr, 0); - else if (GET_CODE (XEXP (addr, 1)) == REG - && REGNO (XEXP (addr, 1)) != 0) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 0))) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 1))) - addr = XEXP (addr, 0); - else - gcc_unreachable (); - } - gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0); - return addr; -} - -void -rs6000_fatal_bad_address (rtx op) -{ - fatal_insn ("bad address", op); -} - -#if TARGET_MACHO - -typedef struct branch_island_d { - tree function_name; - tree label_name; - int line_number; -} branch_island; - - -static vec<branch_island, va_gc> *branch_islands; - -/* Remember to generate a branch island for far calls to the given - function. */ - -static void -add_compiler_branch_island (tree label_name, tree function_name, - int line_number) -{ - branch_island bi = {function_name, label_name, line_number}; - vec_safe_push (branch_islands, bi); -} - -/* Generate far-jump branch islands for everything recorded in - branch_islands. 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]; - - while (!vec_safe_is_empty (branch_islands)) - { - branch_island *bi = &branch_islands->last (); - const char *label = IDENTIFIER_POINTER (bi->label_name); - const char *name = IDENTIFIER_POINTER (bi->function_name); - 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) - dbxout_stabd (N_SLINE, bi->line_number); -#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ - if (flag_pic) - { - if (TARGET_LINK_STACK) - { - char name[32]; - get_ppc476_thunk_name (name); - strcat (tmp_buf, ":\n\tmflr r0\n\tbl "); - strcat (tmp_buf, name); - strcat (tmp_buf, "\n"); - strcat (tmp_buf, label); - strcat (tmp_buf, "_pic:\n\tmflr r11\n"); - } - else - { - 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) - dbxout_stabd (N_SLINE, bi->line_number); -#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */ - branch_islands->pop (); - } -} - -/* NO_PREVIOUS_DEF checks in the link list whether the function name is - already there or not. */ - -static int -no_previous_def (tree function_name) -{ - branch_island *bi; - unsigned ix; - - FOR_EACH_VEC_SAFE_ELT (branch_islands, ix, bi) - if (function_name == bi->function_name) - return 0; - return 1; -} - -/* GET_PREV_LABEL gets the label name from the previous definition of - the function. */ - -static tree -get_prev_label (tree function_name) -{ - branch_island *bi; - unsigned ix; - - FOR_EACH_VEC_SAFE_ELT (branch_islands, ix, bi) - if (function_name == bi->function_name) - return bi->label_name; - return NULL_TREE; -} - -/* INSN is either a function call or a millicode call. It may have an - unconditional jump in its delay slot. - - CALL_DEST is the routine we are calling. */ - -char * -output_call (rtx insn, rtx *operands, int dest_operand_number, - int cookie_operand_number) -{ - static char buf[256]; - if (darwin_emit_branch_islands - && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF - && (INTVAL (operands[cookie_operand_number]) & CALL_LONG)) - { - tree labelname; - tree funname = get_identifier (XSTR (operands[dest_operand_number], 0)); - - if (no_previous_def (funname)) - { - rtx label_rtx = gen_label_rtx (); - char *label_buf, temp_buf[256]; - ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L", - CODE_LABEL_NUMBER (label_rtx)); - label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf; - labelname = get_identifier (label_buf); - add_compiler_branch_island (labelname, funname, insn_line (insn)); - } - 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", - dest_operand_number, IDENTIFIER_POINTER (labelname)); - } - else - sprintf (buf, "bl %%z%d", dest_operand_number); - return buf; -} - -/* Generate PIC and indirect symbol stubs. */ - -void -machopic_output_stub (FILE *file, const char *symb, const char *stub) -{ - unsigned int length; - char *symbol_name, *lazy_ptr_name; - char *local_label_0; - static int label = 0; - - /* Lose our funky encoding stuff so it doesn't contaminate the stub. */ - symb = (*targetm.strip_name_encoding) (symb); - - - length = strlen (symb); - symbol_name = XALLOCAVEC (char, length + 32); - GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length); - - lazy_ptr_name = XALLOCAVEC (char, length + 32); - GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length); - - if (flag_pic == 2) - switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]); - else - switch_to_section (darwin_sections[machopic_symbol_stub1_section]); - - if (flag_pic == 2) - { - fprintf (file, "\t.align 5\n"); - - fprintf (file, "%s:\n", stub); - fprintf (file, "\t.indirect_symbol %s\n", symbol_name); - - label++; - local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\"")); - sprintf (local_label_0, "\"L%011d$spb\"", label); - - fprintf (file, "\tmflr r0\n"); - if (TARGET_LINK_STACK) - { - char name[32]; - get_ppc476_thunk_name (name); - fprintf (file, "\tbl %s\n", name); - fprintf (file, "%s:\n\tmflr r11\n", local_label_0); - } - else - { - 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, "\t%s r12,lo16(%s-%s)(r11)\n", - (TARGET_64BIT ? "ldu" : "lwzu"), - lazy_ptr_name, local_label_0); - fprintf (file, "\tmtctr r12\n"); - fprintf (file, "\tbctr\n"); - } - else - { - fprintf (file, "\t.align 4\n"); - - fprintf (file, "%s:\n", stub); - fprintf (file, "\t.indirect_symbol %s\n", symbol_name); - - fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name); - fprintf (file, "\t%s r12,lo16(%s)(r11)\n", - (TARGET_64BIT ? "ldu" : "lwzu"), - lazy_ptr_name); - fprintf (file, "\tmtctr r12\n"); - fprintf (file, "\tbctr\n"); - } - - switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]); - fprintf (file, "%s:\n", lazy_ptr_name); - fprintf (file, "\t.indirect_symbol %s\n", symbol_name); - fprintf (file, "%sdyld_stub_binding_helper\n", - (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t")); -} - -/* Legitimize PIC addresses. If the address is already - position-independent, we return ORIG. Newly generated - position-independent addresses go into a reg. This is REG if non - zero, otherwise we allocate register(s) as necessary. */ - -#define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000) - -rtx -rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, - rtx reg) -{ - rtx base, offset; - - if (reg == NULL && ! reload_in_progress && ! reload_completed) - reg = gen_reg_rtx (Pmode); - - if (GET_CODE (orig) == CONST) - { - rtx reg_temp; - - if (GET_CODE (XEXP (orig, 0)) == PLUS - && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) - return orig; - - gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); - - /* Use a different reg for the intermediate value, as - it will be marked UNCHANGING. */ - reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode); - base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), - Pmode, reg_temp); - offset = - rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), - Pmode, reg); - - if (GET_CODE (offset) == CONST_INT) - { - if (SMALL_INT (offset)) - return plus_constant (Pmode, base, INTVAL (offset)); - else if (! reload_in_progress && ! reload_completed) - offset = force_reg (Pmode, offset); - else - { - rtx mem = force_const_mem (Pmode, orig); - return machopic_legitimize_pic_address (mem, Pmode, reg); - } - } - return gen_rtx_PLUS (Pmode, base, offset); - } - - /* Fall back on generic machopic code. */ - return machopic_legitimize_pic_address (orig, mode, reg); -} - -/* Output a .machine directive for the Darwin assembler, and call - the generic start_file routine. */ - -static void -rs6000_darwin_file_start (void) -{ - static const struct - { - const char *arg; - const char *name; - HOST_WIDE_INT if_set; - } mapping[] = { - { "ppc64", "ppc64", MASK_64BIT }, - { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 }, - { "power4", "ppc970", 0 }, - { "G5", "ppc970", 0 }, - { "7450", "ppc7450", 0 }, - { "7400", "ppc7400", MASK_ALTIVEC }, - { "G4", "ppc7400", 0 }, - { "750", "ppc750", 0 }, - { "740", "ppc750", 0 }, - { "G3", "ppc750", 0 }, - { "604e", "ppc604e", 0 }, - { "604", "ppc604", 0 }, - { "603e", "ppc603", 0 }, - { "603", "ppc603", 0 }, - { "601", "ppc601", 0 }, - { NULL, "ppc", 0 } }; - const char *cpu_id = ""; - size_t i; - - rs6000_file_start (); - darwin_file_start (); - - /* Determine the argument to -mcpu=. Default to G3 if not specified. */ - - if (rs6000_default_cpu != 0 && rs6000_default_cpu[0] != '\0') - cpu_id = rs6000_default_cpu; - - if (global_options_set.x_rs6000_cpu_index) - cpu_id = processor_target_table[rs6000_cpu_index].name; - - /* Look through the mapping array. Pick the first name that either - matches the argument, has a bit set in IF_SET that is also set - in the target flags, or has a NULL name. */ - - i = 0; - while (mapping[i].arg != NULL - && strcmp (mapping[i].arg, cpu_id) != 0 - && (mapping[i].if_set & rs6000_isa_flags) == 0) - i++; - - fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name); -} - -#endif /* TARGET_MACHO */ - -#if TARGET_ELF -static int -rs6000_elf_reloc_rw_mask (void) -{ - if (flag_pic) - return 3; - else if (DEFAULT_ABI == ABI_AIX) - return 2; - else - return 0; -} - -/* Record an element in the table of global constructors. SYMBOL is - a SYMBOL_REF of the function to be called; PRIORITY is a number - between 0 and MAX_INIT_PRIORITY. - - This differs from default_named_section_asm_out_constructor in - that we have special handling for -mrelocatable. */ - -static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED; -static void -rs6000_elf_asm_out_constructor (rtx symbol, int priority) -{ - const char *section = ".ctors"; - char buf[16]; - - if (priority != DEFAULT_INIT_PRIORITY) - { - sprintf (buf, ".ctors.%.5u", - /* Invert the numbering so the linker puts us in the proper - order; constructors are run from right to left, and the - linker sorts in increasing order. */ - MAX_INIT_PRIORITY - priority); - section = buf; - } - - switch_to_section (get_section (section, SECTION_WRITE, NULL)); - assemble_align (POINTER_SIZE); - - if (TARGET_RELOCATABLE) - { - fputs ("\t.long (", asm_out_file); - output_addr_const (asm_out_file, symbol); - fputs (")@fixup\n", asm_out_file); - } - else - assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); -} - -static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED; -static void -rs6000_elf_asm_out_destructor (rtx symbol, int priority) -{ - const char *section = ".dtors"; - char buf[16]; - - if (priority != DEFAULT_INIT_PRIORITY) - { - sprintf (buf, ".dtors.%.5u", - /* Invert the numbering so the linker puts us in the proper - order; constructors are run from right to left, and the - linker sorts in increasing order. */ - MAX_INIT_PRIORITY - priority); - section = buf; - } - - switch_to_section (get_section (section, SECTION_WRITE, NULL)); - assemble_align (POINTER_SIZE); - - if (TARGET_RELOCATABLE) - { - fputs ("\t.long (", asm_out_file); - output_addr_const (asm_out_file, symbol); - fputs (")@fixup\n", asm_out_file); - } - 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); - rs6000_output_function_entry (file, name); - fputs (",.TOC.@tocbase,0\n\t.previous\n", file); - if (DOT_SYMBOLS) - { - fputs ("\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); - } - } - else - ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); - ASM_DECLARE_RESULT (file, DECL_RESULT (decl)); - rs6000_output_function_entry (file, name); - fputs (":\n", file); - return; - } - - if (TARGET_RELOCATABLE - && !TARGET_SECURE_PLT - && (get_pool_size () != 0 || crtl->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); -} - -static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED; -static void -rs6000_elf_file_end (void) -{ -#ifdef HAVE_AS_GNU_ATTRIBUTE - if (TARGET_32BIT && DEFAULT_ABI == ABI_V4) - { - if (rs6000_passes_float) - fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", - ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1 - : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3 - : 2)); - if (rs6000_passes_vector) - fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n", - (TARGET_ALTIVEC_ABI ? 2 - : TARGET_SPE_ABI ? 3 - : 1)); - if (rs6000_returns_struct) - fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n", - aix_struct_return ? 2 : 1); - } -#endif -#if defined (POWERPC_LINUX) || defined (POWERPC_FREEBSD) - if (TARGET_32BIT) - file_end_indicate_exec_stack (); -#endif -} -#endif - -#if TARGET_XCOFF -static void -rs6000_xcoff_asm_output_anchor (rtx symbol) -{ - char buffer[100]; - - sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC, - SYMBOL_REF_BLOCK_OFFSET (symbol)); - ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer); -} - -static void -rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name) -{ - fputs (GLOBAL_ASM_OP, stream); - RS6000_OUTPUT_BASENAME (stream, name); - putc ('\n', stream); -} - -/* A get_unnamed_decl callback, used for read-only sections. PTR - points to the section string variable. */ - -static void -rs6000_xcoff_output_readonly_section_asm_op (const void *directive) -{ - fprintf (asm_out_file, "\t.csect %s[RO],%s\n", - *(const char *const *) directive, - XCOFF_CSECT_DEFAULT_ALIGNMENT_STR); -} - -/* Likewise for read-write sections. */ - -static void -rs6000_xcoff_output_readwrite_section_asm_op (const void *directive) -{ - fprintf (asm_out_file, "\t.csect %s[RW],%s\n", - *(const char *const *) directive, - XCOFF_CSECT_DEFAULT_ALIGNMENT_STR); -} - -static void -rs6000_xcoff_output_tls_section_asm_op (const void *directive) -{ - fprintf (asm_out_file, "\t.csect %s[TL],%s\n", - *(const char *const *) directive, - XCOFF_CSECT_DEFAULT_ALIGNMENT_STR); -} - -/* A get_unnamed_section callback, used for switching to toc_section. */ - -static void -rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED) -{ - if (TARGET_MINIMAL_TOC) - { - /* toc_section is always selected 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); - fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); - toc_initialized = 1; - } - fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n", - (TARGET_32BIT ? "" : ",3")); - } - else - fputs ("\t.toc\n", asm_out_file); -} - -/* Implement TARGET_ASM_INIT_SECTIONS. */ - -static void -rs6000_xcoff_asm_init_sections (void) -{ - read_only_data_section - = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op, - &xcoff_read_only_section_name); - - private_data_section - = get_unnamed_section (SECTION_WRITE, - rs6000_xcoff_output_readwrite_section_asm_op, - &xcoff_private_data_section_name); - - tls_data_section - = get_unnamed_section (SECTION_TLS, - rs6000_xcoff_output_tls_section_asm_op, - &xcoff_tls_data_section_name); - - tls_private_data_section - = get_unnamed_section (SECTION_TLS, - rs6000_xcoff_output_tls_section_asm_op, - &xcoff_private_data_section_name); - - read_only_private_data_section - = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op, - &xcoff_private_data_section_name); - - toc_section - = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL); - - readonly_data_section = read_only_data_section; - exception_section = data_section; -} - -static int -rs6000_xcoff_reloc_rw_mask (void) -{ - return 3; -} - -static void -rs6000_xcoff_asm_named_section (const char *name, unsigned int flags, - tree decl ATTRIBUTE_UNUSED) -{ - int smclass; - static const char * const suffix[4] = { "PR", "RO", "RW", "TL" }; - - if (flags & SECTION_CODE) - smclass = 0; - else if (flags & SECTION_TLS) - smclass = 3; - else if (flags & SECTION_WRITE) - smclass = 2; - else - smclass = 1; - - fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n", - (flags & SECTION_CODE) ? "." : "", - name, suffix[smclass], flags & SECTION_ENTSIZE); -} - -static section * -rs6000_xcoff_select_section (tree decl, int reloc, - unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) -{ - if (decl_readonly_section (decl, reloc)) - { - if (TREE_PUBLIC (decl)) - return read_only_data_section; - else - return read_only_private_data_section; - } - else - { -#if HAVE_AS_TLS - if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl)) - { - if (TREE_PUBLIC (decl)) - return tls_data_section; - else if (bss_initializer_p (decl)) - { - /* Convert to COMMON to emit in BSS. */ - DECL_COMMON (decl) = 1; - return tls_comm_section; - } - else - return tls_private_data_section; - } - else -#endif - if (TREE_PUBLIC (decl)) - return data_section; - else - return private_data_section; - } -} - -static void -rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED) -{ - const char *name; - - /* Use select_section for private and uninitialized data. */ - if (!TREE_PUBLIC (decl) - || DECL_COMMON (decl) - || DECL_INITIAL (decl) == NULL_TREE - || DECL_INITIAL (decl) == error_mark_node - || (flag_zero_initialized_in_bss - && initializer_zerop (DECL_INITIAL (decl)))) - return; - - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - name = (*targetm.strip_name_encoding) (name); - DECL_SECTION_NAME (decl) = build_string (strlen (name), name); -} - -/* Select section for constant in constant pool. - - On RS/6000, all constants are in the private read-only data area. - However, if this is being placed in the TOC it must be output as a - toc entry. */ - -static section * -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)) - return toc_section; - else - return read_only_private_data_section; -} - -/* Remove any trailing [DS] or the like from the symbol name. */ - -static const char * -rs6000_xcoff_strip_name_encoding (const char *name) -{ - size_t len; - if (*name == '*') - name++; - len = strlen (name); - if (name[len - 1] == ']') - return ggc_alloc_string (name, len - 4); - else - return name; -} - -/* Section attributes. AIX is always PIC. */ - -static unsigned int -rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc) -{ - unsigned int align; - unsigned int flags = default_section_type_flags (decl, name, reloc); - - /* Align to at least UNIT size. */ - if ((flags & SECTION_CODE) != 0 || !decl || !DECL_P (decl)) - align = MIN_UNITS_PER_WORD; - else - /* Increase alignment of large objects if not already stricter. */ - align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT), - int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD - ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD); - - return flags | (exact_log2 (align) & SECTION_ENTSIZE); -} - -/* 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. */ - -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_"); - rs6000_gen_section_name (&xcoff_tls_data_section_name, - main_input_filename, ".tls_"); - rs6000_gen_section_name (&xcoff_tbss_section_name, - main_input_filename, ".tbss_[UL]"); - - fputs ("\t.file\t", asm_out_file); - output_quoted_string (asm_out_file, main_input_filename); - fputc ('\n', asm_out_file); - if (write_symbols != NO_DEBUG) - switch_to_section (private_data_section); - switch_to_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_file_end (void) -{ - switch_to_section (text_section); - fputs ("_section_.text:\n", asm_out_file); - switch_to_section (data_section); - fputs (TARGET_32BIT - ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", - asm_out_file); -} - -#ifdef HAVE_AS_TLS -static void -rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first) -{ - rtx symbol; - int flags; - - default_encode_section_info (decl, rtl, first); - - /* Careful not to prod global register variables. */ - if (!MEM_P (rtl)) - return; - symbol = XEXP (rtl, 0); - if (GET_CODE (symbol) != SYMBOL_REF) - return; - - flags = SYMBOL_REF_FLAGS (symbol); - - if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl)) - flags &= ~SYMBOL_FLAG_HAS_BLOCK_INFO; - - SYMBOL_REF_FLAGS (symbol) = flags; -} -#endif /* HAVE_AS_TLS */ -#endif /* TARGET_XCOFF */ - -/* 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_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, - int *total, bool speed) -{ - enum machine_mode mode = GET_MODE (x); - - switch (code) - { - /* On the RS/6000, if it is valid in the insn, it is free. */ - case CONST_INT: - if (((outer_code == SET - || outer_code == PLUS - || outer_code == MINUS) - && (satisfies_constraint_I (x) - || satisfies_constraint_L (x))) - || (outer_code == AND - && (satisfies_constraint_K (x) - || (mode == SImode - ? satisfies_constraint_L (x) - : satisfies_constraint_J (x)) - || mask_operand (x, mode) - || (mode == DImode - && mask64_operand (x, DImode)))) - || ((outer_code == IOR || outer_code == XOR) - && (satisfies_constraint_K (x) - || (mode == SImode - ? satisfies_constraint_L (x) - : satisfies_constraint_J (x)))) - || outer_code == ASHIFT - || outer_code == ASHIFTRT - || outer_code == LSHIFTRT - || outer_code == ROTATE - || outer_code == ROTATERT - || outer_code == ZERO_EXTRACT - || (outer_code == MULT - && satisfies_constraint_I (x)) - || ((outer_code == DIV || outer_code == UDIV - || outer_code == MOD || outer_code == UMOD) - && exact_log2 (INTVAL (x)) >= 0) - || (outer_code == COMPARE - && (satisfies_constraint_I (x) - || satisfies_constraint_K (x))) - || ((outer_code == EQ || outer_code == NE) - && (satisfies_constraint_I (x) - || satisfies_constraint_K (x) - || (mode == SImode - ? satisfies_constraint_L (x) - : satisfies_constraint_J (x)))) - || (outer_code == GTU - && satisfies_constraint_I (x)) - || (outer_code == LTU - && satisfies_constraint_P (x))) - { - *total = 0; - return true; - } - else if ((outer_code == PLUS - && reg_or_add_cint_operand (x, VOIDmode)) - || (outer_code == MINUS - && reg_or_sub_cint_operand (x, VOIDmode)) - || ((outer_code == SET - || outer_code == IOR - || outer_code == XOR) - && (INTVAL (x) - & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0)) - { - *total = COSTS_N_INSNS (1); - return true; - } - /* FALLTHRU */ - - case CONST_DOUBLE: - if (mode == DImode && code == CONST_DOUBLE) - { - if ((outer_code == IOR || outer_code == XOR) - && CONST_DOUBLE_HIGH (x) == 0 - && (CONST_DOUBLE_LOW (x) - & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0) - { - *total = 0; - return true; - } - else if ((outer_code == AND && and64_2_operand (x, DImode)) - || ((outer_code == SET - || outer_code == IOR - || outer_code == XOR) - && CONST_DOUBLE_HIGH (x) == 0)) - { - *total = COSTS_N_INSNS (1); - return true; - } - } - /* FALLTHRU */ - - case CONST: - case HIGH: - case SYMBOL_REF: - case MEM: - /* When optimizing for size, MEM should be slightly more expensive - than generating address, e.g., (plus (reg) (const)). - L1 cache latency is about two instructions. */ - *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2); - return true; - - case LABEL_REF: - *total = 0; - return true; - - case PLUS: - case MINUS: - if (FLOAT_MODE_P (mode)) - *total = rs6000_cost->fp; - else - *total = COSTS_N_INSNS (1); - return false; - - case MULT: - if (GET_CODE (XEXP (x, 1)) == CONST_INT - && satisfies_constraint_I (XEXP (x, 1))) - { - if (INTVAL (XEXP (x, 1)) >= -256 - && INTVAL (XEXP (x, 1)) <= 255) - *total = rs6000_cost->mulsi_const9; - else - *total = rs6000_cost->mulsi_const; - } - else if (mode == SFmode) - *total = rs6000_cost->fp; - else if (FLOAT_MODE_P (mode)) - *total = rs6000_cost->dmul; - else if (mode == DImode) - *total = rs6000_cost->muldi; - else - *total = rs6000_cost->mulsi; - return false; - - case FMA: - if (mode == SFmode) - *total = rs6000_cost->fp; - else - *total = rs6000_cost->dmul; - break; - - case DIV: - case MOD: - if (FLOAT_MODE_P (mode)) - { - *total = mode == DFmode ? rs6000_cost->ddiv - : rs6000_cost->sdiv; - return false; - } - /* FALLTHRU */ - - case UDIV: - case UMOD: - if (GET_CODE (XEXP (x, 1)) == CONST_INT - && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) - { - if (code == DIV || code == MOD) - /* Shift, addze */ - *total = COSTS_N_INSNS (2); - else - /* Shift */ - *total = COSTS_N_INSNS (1); - } - else - { - if (GET_MODE (XEXP (x, 1)) == DImode) - *total = rs6000_cost->divdi; - else - *total = rs6000_cost->divsi; - } - /* Add in shift and subtract for MOD. */ - if (code == MOD || code == UMOD) - *total += COSTS_N_INSNS (2); - return false; - - case CTZ: - case FFS: - *total = COSTS_N_INSNS (4); - return false; - - case POPCOUNT: - *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6); - return false; - - case PARITY: - *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6); - return false; - - case NOT: - if (outer_code == AND || outer_code == IOR || outer_code == XOR) - { - *total = 0; - return false; - } - /* FALLTHRU */ - - case AND: - case CLZ: - case IOR: - case XOR: - case ZERO_EXTRACT: - *total = COSTS_N_INSNS (1); - return false; - - case ASHIFT: - case ASHIFTRT: - case LSHIFTRT: - case ROTATE: - case ROTATERT: - /* Handle mul_highpart. */ - if (outer_code == TRUNCATE - && GET_CODE (XEXP (x, 0)) == MULT) - { - if (mode == DImode) - *total = rs6000_cost->muldi; - else - *total = rs6000_cost->mulsi; - return true; - } - else if (outer_code == AND) - *total = 0; - else - *total = COSTS_N_INSNS (1); - return false; - - case SIGN_EXTEND: - case ZERO_EXTEND: - if (GET_CODE (XEXP (x, 0)) == MEM) - *total = 0; - else - *total = COSTS_N_INSNS (1); - return false; - - case COMPARE: - case NEG: - case ABS: - if (!FLOAT_MODE_P (mode)) - { - *total = COSTS_N_INSNS (1); - return false; - } - /* FALLTHRU */ - - case FLOAT: - case UNSIGNED_FLOAT: - case FIX: - case UNSIGNED_FIX: - case FLOAT_TRUNCATE: - *total = rs6000_cost->fp; - return false; - - case FLOAT_EXTEND: - if (mode == DFmode) - *total = 0; - else - *total = rs6000_cost->fp; - return false; - - case UNSPEC: - switch (XINT (x, 1)) - { - case UNSPEC_FRSP: - *total = rs6000_cost->fp; - return true; - - default: - break; - } - break; - - case CALL: - case IF_THEN_ELSE: - if (!speed) - { - *total = COSTS_N_INSNS (1); - return true; - } - else if (FLOAT_MODE_P (mode) - && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS) - { - *total = rs6000_cost->fp; - return false; - } - break; - - case EQ: - case GTU: - case LTU: - /* Carry bit requires mode == Pmode. - NEG or PLUS already counted so only add one. */ - if (mode == Pmode - && (outer_code == NEG || outer_code == PLUS)) - { - *total = COSTS_N_INSNS (1); - return true; - } - if (outer_code == SET) - { - if (XEXP (x, 1) == const0_rtx) - { - if (TARGET_ISEL && !TARGET_MFCRF) - *total = COSTS_N_INSNS (8); - else - *total = COSTS_N_INSNS (2); - return true; - } - else if (mode == Pmode) - { - *total = COSTS_N_INSNS (3); - return false; - } - } - /* FALLTHRU */ - - case GT: - case LT: - case UNORDERED: - if (outer_code == SET && (XEXP (x, 1) == const0_rtx)) - { - if (TARGET_ISEL && !TARGET_MFCRF) - *total = COSTS_N_INSNS (8); - else - *total = COSTS_N_INSNS (2); - return true; - } - /* CC COMPARE. */ - if (outer_code == COMPARE) - { - *total = 0; - return true; - } - break; - - default: - break; - } - - return false; -} - -/* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */ - -static bool -rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int opno, int *total, - bool speed) -{ - bool ret = rs6000_rtx_costs (x, code, outer_code, opno, total, speed); - - fprintf (stderr, - "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, " - "opno = %d, total = %d, speed = %s, x:\n", - ret ? "complete" : "scan inner", - GET_RTX_NAME (code), - GET_RTX_NAME (outer_code), - opno, - *total, - speed ? "true" : "false"); - - debug_rtx (x); - - return ret; -} - -/* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */ - -static int -rs6000_debug_address_cost (rtx x, enum machine_mode mode, - addr_space_t as, bool speed) -{ - int ret = TARGET_ADDRESS_COST (x, mode, as, speed); - - fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n", - ret, speed ? "true" : "false"); - debug_rtx (x); - - return ret; -} - - -/* A C expression returning the cost of moving data from a register of class - CLASS1 to one of CLASS2. */ - -static int -rs6000_register_move_cost (enum machine_mode mode, - reg_class_t from, reg_class_t to) -{ - int ret; - - if (TARGET_DEBUG_COST) - dbg_cost_ctrl++; - - /* Moves from/to GENERAL_REGS. */ - if (reg_classes_intersect_p (to, GENERAL_REGS) - || reg_classes_intersect_p (from, GENERAL_REGS)) - { - reg_class_t rclass = from; - - if (! reg_classes_intersect_p (to, GENERAL_REGS)) - rclass = to; - - if (rclass == FLOAT_REGS || rclass == ALTIVEC_REGS || rclass == VSX_REGS) - ret = (rs6000_memory_move_cost (mode, rclass, false) - + rs6000_memory_move_cost (mode, GENERAL_REGS, false)); - - /* It's more expensive to move CR_REGS than CR0_REGS because of the - shift. */ - else if (rclass == CR_REGS) - ret = 4; - - /* For those processors that have slow LR/CTR moves, make them more - expensive than memory in order to bias spills to memory .*/ - else if ((rs6000_cpu == PROCESSOR_POWER6 - || rs6000_cpu == PROCESSOR_POWER7) - && reg_classes_intersect_p (rclass, LINK_OR_CTR_REGS)) - ret = 6 * hard_regno_nregs[0][mode]; - - else - /* A move will cost one instruction per GPR moved. */ - ret = 2 * hard_regno_nregs[0][mode]; - } - - /* If we have VSX, we can easily move between FPR or Altivec registers. */ - else if (VECTOR_UNIT_VSX_P (mode) - && reg_classes_intersect_p (to, VSX_REGS) - && reg_classes_intersect_p (from, VSX_REGS)) - ret = 2 * hard_regno_nregs[32][mode]; - - /* Moving between two similar registers is just one instruction. */ - else if (reg_classes_intersect_p (to, from)) - ret = (mode == TFmode || mode == TDmode) ? 4 : 2; - - /* Everything else has to go through GENERAL_REGS. */ - else - ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to) - + rs6000_register_move_cost (mode, from, GENERAL_REGS)); - - if (TARGET_DEBUG_COST) - { - if (dbg_cost_ctrl == 1) - fprintf (stderr, - "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n", - ret, GET_MODE_NAME (mode), reg_class_names[from], - reg_class_names[to]); - dbg_cost_ctrl--; - } - - return ret; -} - -/* A C expressions returning the cost of moving data of MODE from a register to - or from memory. */ - -static int -rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass, - bool in ATTRIBUTE_UNUSED) -{ - int ret; - - if (TARGET_DEBUG_COST) - dbg_cost_ctrl++; - - if (reg_classes_intersect_p (rclass, GENERAL_REGS)) - ret = 4 * hard_regno_nregs[0][mode]; - else if (reg_classes_intersect_p (rclass, FLOAT_REGS)) - ret = 4 * hard_regno_nregs[32][mode]; - else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS)) - ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode]; - else - ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS); - - if (TARGET_DEBUG_COST) - { - if (dbg_cost_ctrl == 1) - fprintf (stderr, - "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n", - ret, GET_MODE_NAME (mode), reg_class_names[rclass], in); - dbg_cost_ctrl--; - } - - return ret; -} - -/* Returns a code for a target-specific builtin that implements - reciprocal of the function, or NULL_TREE if not available. */ - -static tree -rs6000_builtin_reciprocal (unsigned int fn, bool md_fn, - bool sqrt ATTRIBUTE_UNUSED) -{ - if (optimize_insn_for_size_p ()) - return NULL_TREE; - - if (md_fn) - switch (fn) - { - case VSX_BUILTIN_XVSQRTDP: - if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode)) - return NULL_TREE; - - return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF]; - - case VSX_BUILTIN_XVSQRTSP: - if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode)) - return NULL_TREE; - - return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_4SF]; - - default: - return NULL_TREE; - } - - else - switch (fn) - { - case BUILT_IN_SQRT: - if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode)) - return NULL_TREE; - - return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT]; - - case BUILT_IN_SQRTF: - if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode)) - return NULL_TREE; - - return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF]; - - default: - return NULL_TREE; - } -} - -/* Load up a constant. If the mode is a vector mode, splat the value across - all of the vector elements. */ - -static rtx -rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst) -{ - rtx reg; - - if (mode == SFmode || mode == DFmode) - { - rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode); - reg = force_reg (mode, d); - } - else if (mode == V4SFmode) - { - rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode); - rtvec v = gen_rtvec (4, d, d, d, d); - reg = gen_reg_rtx (mode); - rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v)); - } - else if (mode == V2DFmode) - { - rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode); - rtvec v = gen_rtvec (2, d, d); - reg = gen_reg_rtx (mode); - rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v)); - } - else - gcc_unreachable (); - - return reg; -} - -/* Generate an FMA instruction. */ - -static void -rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a) -{ - enum machine_mode mode = GET_MODE (target); - rtx dst; - - dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0); - gcc_assert (dst != NULL); - - if (dst != target) - emit_move_insn (target, dst); -} - -/* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */ - -static void -rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a) -{ - enum machine_mode mode = GET_MODE (target); - rtx dst; - - /* Altivec does not support fms directly; - generate in terms of fma in that case. */ - if (optab_handler (fms_optab, mode) != CODE_FOR_nothing) - dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0); - else - { - a = expand_unop (mode, neg_optab, a, NULL_RTX, 0); - dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0); - } - gcc_assert (dst != NULL); - - if (dst != target) - emit_move_insn (target, dst); -} - -/* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */ - -static void -rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a) -{ - enum machine_mode mode = GET_MODE (dst); - rtx r; - - /* This is a tad more complicated, since the fnma_optab is for - a different expression: fma(-m1, m2, a), which is the same - thing except in the case of signed zeros. - - Fortunately we know that if FMA is supported that FNMSUB is - also supported in the ISA. Just expand it directly. */ - - gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing); - - r = gen_rtx_NEG (mode, a); - r = gen_rtx_FMA (mode, m1, m2, r); - r = gen_rtx_NEG (mode, r); - emit_insn (gen_rtx_SET (VOIDmode, dst, r)); -} - -/* Newton-Raphson approximation of floating point divide with just 2 passes - (either single precision floating point, or newer machines with higher - accuracy estimates). Support both scalar and vector divide. Assumes no - trapping math and finite arguments. */ - -static void -rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d) -{ - enum machine_mode mode = GET_MODE (dst); - rtx x0, e0, e1, y1, u0, v0; - enum insn_code code = optab_handler (smul_optab, mode); - gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code); - rtx one = rs6000_load_constant_and_splat (mode, dconst1); - - gcc_assert (code != CODE_FOR_nothing); - - /* x0 = 1./d estimate */ - x0 = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, x0, - gen_rtx_UNSPEC (mode, gen_rtvec (1, d), - UNSPEC_FRES))); - - e0 = gen_reg_rtx (mode); - rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */ - - e1 = gen_reg_rtx (mode); - rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */ - - y1 = gen_reg_rtx (mode); - rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */ - - u0 = gen_reg_rtx (mode); - emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */ - - v0 = gen_reg_rtx (mode); - rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */ - - rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */ -} - -/* Newton-Raphson approximation of floating point divide that has a low - precision estimate. Assumes no trapping math and finite arguments. */ - -static void -rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d) -{ - enum machine_mode mode = GET_MODE (dst); - rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one; - enum insn_code code = optab_handler (smul_optab, mode); - gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code); - - gcc_assert (code != CODE_FOR_nothing); - - one = rs6000_load_constant_and_splat (mode, dconst1); - - /* x0 = 1./d estimate */ - x0 = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, x0, - gen_rtx_UNSPEC (mode, gen_rtvec (1, d), - UNSPEC_FRES))); - - e0 = gen_reg_rtx (mode); - rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */ - - y1 = gen_reg_rtx (mode); - rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */ - - e1 = gen_reg_rtx (mode); - emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */ - - y2 = gen_reg_rtx (mode); - rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */ - - e2 = gen_reg_rtx (mode); - emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */ - - y3 = gen_reg_rtx (mode); - rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */ - - u0 = gen_reg_rtx (mode); - emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */ - - v0 = gen_reg_rtx (mode); - rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */ - - rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */ -} - -/* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P, - add a reg_note saying that this was a division. Support both scalar and - vector divide. Assumes no trapping math and finite arguments. */ - -void -rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p) -{ - enum machine_mode mode = GET_MODE (dst); - - if (RS6000_RECIP_HIGH_PRECISION_P (mode)) - rs6000_emit_swdiv_high_precision (dst, n, d); - else - rs6000_emit_swdiv_low_precision (dst, n, d); - - if (note_p) - add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d)); -} - -/* Newton-Raphson approximation of single/double-precision floating point - rsqrt. Assumes no trapping math and finite arguments. */ - -void -rs6000_emit_swrsqrt (rtx dst, rtx src) -{ - enum machine_mode mode = GET_MODE (src); - rtx x0 = gen_reg_rtx (mode); - rtx y = gen_reg_rtx (mode); - int passes = (TARGET_RECIP_PRECISION) ? 2 : 3; - REAL_VALUE_TYPE dconst3_2; - int i; - rtx halfthree; - enum insn_code code = optab_handler (smul_optab, mode); - gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code); - - gcc_assert (code != CODE_FOR_nothing); - - /* Load up the constant 1.5 either as a scalar, or as a vector. */ - real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0); - SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1); - - halfthree = rs6000_load_constant_and_splat (mode, dconst3_2); - - /* x0 = rsqrt estimate */ - emit_insn (gen_rtx_SET (VOIDmode, x0, - gen_rtx_UNSPEC (mode, gen_rtvec (1, src), - UNSPEC_RSQRT))); - - /* y = 0.5 * src = 1.5 * src - src -> fewer constants */ - rs6000_emit_msub (y, src, halfthree, src); - - for (i = 0; i < passes; i++) - { - rtx x1 = gen_reg_rtx (mode); - rtx u = gen_reg_rtx (mode); - rtx v = gen_reg_rtx (mode); - - /* x1 = x0 * (1.5 - y * (x0 * x0)) */ - emit_insn (gen_mul (u, x0, x0)); - rs6000_emit_nmsub (v, y, u, halfthree); - emit_insn (gen_mul (x1, x0, v)); - x0 = x1; - } - - emit_move_insn (dst, x0); - return; -} - -/* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD - (Power7) targets. DST is the target, and SRC is the argument operand. */ - -void -rs6000_emit_popcount (rtx dst, rtx src) -{ - enum machine_mode mode = GET_MODE (dst); - rtx tmp1, tmp2; - - /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */ - if (TARGET_POPCNTD) - { - if (mode == SImode) - emit_insn (gen_popcntdsi2 (dst, src)); - else - emit_insn (gen_popcntddi2 (dst, src)); - return; - } - - tmp1 = gen_reg_rtx (mode); - - if (mode == SImode) - { - emit_insn (gen_popcntbsi2 (tmp1, src)); - tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101), - NULL_RTX, 0); - tmp2 = force_reg (SImode, tmp2); - emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24))); - } - else - { - emit_insn (gen_popcntbdi2 (tmp1, src)); - tmp2 = expand_mult (DImode, tmp1, - GEN_INT ((HOST_WIDE_INT) - 0x01010101 << 32 | 0x01010101), - NULL_RTX, 0); - tmp2 = force_reg (DImode, tmp2); - emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56))); - } -} - - -/* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the - target, and SRC is the argument operand. */ - -void -rs6000_emit_parity (rtx dst, rtx src) -{ - enum machine_mode mode = GET_MODE (dst); - rtx tmp; - - tmp = gen_reg_rtx (mode); - - /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */ - if (TARGET_CMPB) - { - if (mode == SImode) - { - emit_insn (gen_popcntbsi2 (tmp, src)); - emit_insn (gen_paritysi2_cmpb (dst, tmp)); - } - else - { - emit_insn (gen_popcntbdi2 (tmp, src)); - emit_insn (gen_paritydi2_cmpb (dst, tmp)); - } - return; - } - - if (mode == SImode) - { - /* Is mult+shift >= shift+xor+shift+xor? */ - if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3)) - { - rtx tmp1, tmp2, tmp3, tmp4; - - tmp1 = gen_reg_rtx (SImode); - emit_insn (gen_popcntbsi2 (tmp1, src)); - - tmp2 = gen_reg_rtx (SImode); - emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16))); - tmp3 = gen_reg_rtx (SImode); - emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2)); - - tmp4 = gen_reg_rtx (SImode); - emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8))); - emit_insn (gen_xorsi3 (tmp, tmp3, tmp4)); - } - else - rs6000_emit_popcount (tmp, src); - emit_insn (gen_andsi3 (dst, tmp, const1_rtx)); - } - else - { - /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */ - if (rs6000_cost->muldi >= COSTS_N_INSNS (5)) - { - rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6; - - tmp1 = gen_reg_rtx (DImode); - emit_insn (gen_popcntbdi2 (tmp1, src)); - - tmp2 = gen_reg_rtx (DImode); - emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32))); - tmp3 = gen_reg_rtx (DImode); - emit_insn (gen_xordi3 (tmp3, tmp1, tmp2)); - - tmp4 = gen_reg_rtx (DImode); - emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16))); - tmp5 = gen_reg_rtx (DImode); - emit_insn (gen_xordi3 (tmp5, tmp3, tmp4)); - - tmp6 = gen_reg_rtx (DImode); - emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8))); - emit_insn (gen_xordi3 (tmp, tmp5, tmp6)); - } - else - rs6000_emit_popcount (tmp, src); - emit_insn (gen_anddi3 (dst, tmp, const1_rtx)); - } -} - -/* Expand an Altivec constant permutation. Return true if we match - an efficient implementation; false to fall back to VPERM. */ - -bool -altivec_expand_vec_perm_const (rtx operands[4]) -{ - struct altivec_perm_insn { - enum insn_code impl; - unsigned char perm[16]; - }; - static const struct altivec_perm_insn patterns[] = { - { CODE_FOR_altivec_vpkuhum, - { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } }, - { CODE_FOR_altivec_vpkuwum, - { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } }, - { CODE_FOR_altivec_vmrghb, - { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } }, - { CODE_FOR_altivec_vmrghh, - { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } }, - { CODE_FOR_altivec_vmrghw, - { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } }, - { CODE_FOR_altivec_vmrglb, - { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } }, - { CODE_FOR_altivec_vmrglh, - { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } }, - { CODE_FOR_altivec_vmrglw, - { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } } - }; - - unsigned int i, j, elt, which; - unsigned char perm[16]; - rtx target, op0, op1, sel, x; - bool one_vec; - - target = operands[0]; - op0 = operands[1]; - op1 = operands[2]; - sel = operands[3]; - - /* Unpack the constant selector. */ - for (i = which = 0; i < 16; ++i) - { - rtx e = XVECEXP (sel, 0, i); - elt = INTVAL (e) & 31; - which |= (elt < 16 ? 1 : 2); - perm[i] = elt; - } - - /* Simplify the constant selector based on operands. */ - switch (which) - { - default: - gcc_unreachable (); - - case 3: - one_vec = false; - if (!rtx_equal_p (op0, op1)) - break; - /* FALLTHRU */ - - case 2: - for (i = 0; i < 16; ++i) - perm[i] &= 15; - op0 = op1; - one_vec = true; - break; - - case 1: - op1 = op0; - one_vec = true; - break; - } - - /* Look for splat patterns. */ - if (one_vec) - { - elt = perm[0]; - - for (i = 0; i < 16; ++i) - if (perm[i] != elt) - break; - if (i == 16) - { - emit_insn (gen_altivec_vspltb (target, op0, GEN_INT (elt))); - return true; - } - - if (elt % 2 == 0) - { - for (i = 0; i < 16; i += 2) - if (perm[i] != elt || perm[i + 1] != elt + 1) - break; - if (i == 16) - { - x = gen_reg_rtx (V8HImode); - emit_insn (gen_altivec_vsplth (x, gen_lowpart (V8HImode, op0), - GEN_INT (elt / 2))); - emit_move_insn (target, gen_lowpart (V16QImode, x)); - return true; - } - } - - if (elt % 4 == 0) - { - for (i = 0; i < 16; i += 4) - if (perm[i] != elt - || perm[i + 1] != elt + 1 - || perm[i + 2] != elt + 2 - || perm[i + 3] != elt + 3) - break; - if (i == 16) - { - x = gen_reg_rtx (V4SImode); - emit_insn (gen_altivec_vspltw (x, gen_lowpart (V4SImode, op0), - GEN_INT (elt / 4))); - emit_move_insn (target, gen_lowpart (V16QImode, x)); - return true; - } - } - } - - /* Look for merge and pack patterns. */ - for (j = 0; j < ARRAY_SIZE (patterns); ++j) - { - bool swapped; - - elt = patterns[j].perm[0]; - if (perm[0] == elt) - swapped = false; - else if (perm[0] == elt + 16) - swapped = true; - else - continue; - for (i = 1; i < 16; ++i) - { - elt = patterns[j].perm[i]; - if (swapped) - elt = (elt >= 16 ? elt - 16 : elt + 16); - else if (one_vec && elt >= 16) - elt -= 16; - if (perm[i] != elt) - break; - } - if (i == 16) - { - enum insn_code icode = patterns[j].impl; - enum machine_mode omode = insn_data[icode].operand[0].mode; - enum machine_mode imode = insn_data[icode].operand[1].mode; - - if (swapped) - x = op0, op0 = op1, op1 = x; - if (imode != V16QImode) - { - op0 = gen_lowpart (imode, op0); - op1 = gen_lowpart (imode, op1); - } - if (omode == V16QImode) - x = target; - else - x = gen_reg_rtx (omode); - emit_insn (GEN_FCN (icode) (x, op0, op1)); - if (omode != V16QImode) - emit_move_insn (target, gen_lowpart (V16QImode, x)); - return true; - } - } - - return false; -} - -/* Expand a Paired Single, VSX Permute Doubleword, or SPE constant permutation. - Return true if we match an efficient implementation. */ - -static bool -rs6000_expand_vec_perm_const_1 (rtx target, rtx op0, rtx op1, - unsigned char perm0, unsigned char perm1) -{ - rtx x; - - /* If both selectors come from the same operand, fold to single op. */ - if ((perm0 & 2) == (perm1 & 2)) - { - if (perm0 & 2) - op0 = op1; - else - op1 = op0; - } - /* If both operands are equal, fold to simpler permutation. */ - if (rtx_equal_p (op0, op1)) - { - perm0 = perm0 & 1; - perm1 = (perm1 & 1) + 2; - } - /* If the first selector comes from the second operand, swap. */ - else if (perm0 & 2) - { - if (perm1 & 2) - return false; - perm0 -= 2; - perm1 += 2; - x = op0, op0 = op1, op1 = x; - } - /* If the second selector does not come from the second operand, fail. */ - else if ((perm1 & 2) == 0) - return false; - - /* Success! */ - if (target != NULL) - { - enum machine_mode vmode, dmode; - rtvec v; - - vmode = GET_MODE (target); - gcc_assert (GET_MODE_NUNITS (vmode) == 2); - dmode = mode_for_vector (GET_MODE_INNER (vmode), 4); - - x = gen_rtx_VEC_CONCAT (dmode, op0, op1); - v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1)); - x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v)); - emit_insn (gen_rtx_SET (VOIDmode, target, x)); - } - return true; -} - -bool -rs6000_expand_vec_perm_const (rtx operands[4]) -{ - rtx target, op0, op1, sel; - unsigned char perm0, perm1; - - target = operands[0]; - op0 = operands[1]; - op1 = operands[2]; - sel = operands[3]; - - /* Unpack the constant selector. */ - perm0 = INTVAL (XVECEXP (sel, 0, 0)) & 3; - perm1 = INTVAL (XVECEXP (sel, 0, 1)) & 3; - - return rs6000_expand_vec_perm_const_1 (target, op0, op1, perm0, perm1); -} - -/* Test whether a constant permutation is supported. */ - -static bool -rs6000_vectorize_vec_perm_const_ok (enum machine_mode vmode, - const unsigned char *sel) -{ - /* AltiVec (and thus VSX) can handle arbitrary permutations. */ - if (TARGET_ALTIVEC) - return true; - - /* Check for ps_merge* or evmerge* insns. */ - if ((TARGET_PAIRED_FLOAT && vmode == V2SFmode) - || (TARGET_SPE && vmode == V2SImode)) - { - rtx op0 = gen_raw_REG (vmode, LAST_VIRTUAL_REGISTER + 1); - rtx op1 = gen_raw_REG (vmode, LAST_VIRTUAL_REGISTER + 2); - return rs6000_expand_vec_perm_const_1 (NULL, op0, op1, sel[0], sel[1]); - } - - return false; -} - -/* A subroutine for rs6000_expand_extract_even & rs6000_expand_interleave. */ - -static void -rs6000_do_expand_vec_perm (rtx target, rtx op0, rtx op1, - enum machine_mode vmode, unsigned nelt, rtx perm[]) -{ - enum machine_mode imode; - rtx x; - - imode = vmode; - if (GET_MODE_CLASS (vmode) != MODE_VECTOR_INT) - { - imode = GET_MODE_INNER (vmode); - imode = mode_for_size (GET_MODE_BITSIZE (imode), MODE_INT, 0); - imode = mode_for_vector (imode, nelt); - } - - x = gen_rtx_CONST_VECTOR (imode, gen_rtvec_v (nelt, perm)); - x = expand_vec_perm (vmode, op0, op1, x, target); - if (x != target) - emit_move_insn (target, x); -} - -/* Expand an extract even operation. */ - -void -rs6000_expand_extract_even (rtx target, rtx op0, rtx op1) -{ - enum machine_mode vmode = GET_MODE (target); - unsigned i, nelt = GET_MODE_NUNITS (vmode); - rtx perm[16]; - - for (i = 0; i < nelt; i++) - perm[i] = GEN_INT (i * 2); - - rs6000_do_expand_vec_perm (target, op0, op1, vmode, nelt, perm); -} - -/* Expand a vector interleave operation. */ - -void -rs6000_expand_interleave (rtx target, rtx op0, rtx op1, bool highp) -{ - enum machine_mode vmode = GET_MODE (target); - unsigned i, high, nelt = GET_MODE_NUNITS (vmode); - rtx perm[16]; - - high = (highp == BYTES_BIG_ENDIAN ? 0 : nelt / 2); - for (i = 0; i < nelt / 2; i++) - { - perm[i * 2] = GEN_INT (i + high); - perm[i * 2 + 1] = GEN_INT (i + nelt + high); - } - - rs6000_do_expand_vec_perm (target, op0, op1, vmode, nelt, perm); -} - -/* 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)); -} - -/* Target hook for TARGET_FUNCTION_VALUE. - - 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. */ - -static rtx -rs6000_function_value (const_tree valtype, - const_tree fn_decl_or_type ATTRIBUTE_UNUSED, - bool outgoing ATTRIBUTE_UNUSED) -{ - enum machine_mode mode; - unsigned int regno; - - /* Special handling for structs in darwin64. */ - if (TARGET_MACHO - && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype)) - { - CUMULATIVE_ARGS valcum; - rtx valret; - - valcum.words = 0; - valcum.fregno = FP_ARG_MIN_REG; - valcum.vregno = ALTIVEC_ARG_MIN_REG; - /* Do a trial code generation as if this were going to be passed as - an argument; if any part goes in memory, we return NULL. */ - valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true); - if (valret) - return valret; - /* Otherwise fall through to standard ABI rules. */ - } - - 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 (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode) - { - return gen_rtx_PARALLEL (DCmode, - gen_rtvec (4, - 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)), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_RETURN + 2), - GEN_INT (8)), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_RETURN + 3), - GEN_INT (12)))); - } - - mode = TYPE_MODE (valtype); - if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD) - || POINTER_TYPE_P (valtype)) - mode = TARGET_32BIT ? SImode : DImode; - - if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS) - /* _Decimal128 must use an even/odd register pair. */ - regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN; - else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS - && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT)) - regno = FP_ARG_RETURN; - else if (TREE_CODE (valtype) == COMPLEX_TYPE - && targetm.calls.split_complex_arg) - return rs6000_complex_function_value (mode); - /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same - return register is used in both cases, and we won't see V2DImode/V2DFmode - for pure altivec, combine the two cases. */ - else if (TREE_CODE (valtype) == VECTOR_TYPE - && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI - && ALTIVEC_OR_VSX_VECTOR_MODE (mode)) - regno = ALTIVEC_ARG_RETURN; - else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT - && (mode == DFmode || mode == DCmode - || mode == TFmode || mode == TCmode)) - return spe_build_register_parallel (mode, GP_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 (TARGET_32BIT && TARGET_POWERPC64 && mode == 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 (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS) - /* _Decimal128 must use an even/odd register pair. */ - regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN; - else if (SCALAR_FLOAT_MODE_P (mode) - && TARGET_HARD_FLOAT && TARGET_FPRS - && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT)) - regno = FP_ARG_RETURN; - /* VSX is a superset of Altivec and adds V2DImode/V2DFmode. Since the same - return register is used in both cases, and we won't see V2DImode/V2DFmode - for pure altivec, combine the two cases. */ - else if (ALTIVEC_OR_VSX_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 if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT - && (mode == DFmode || mode == DCmode - || mode == TFmode || mode == TCmode)) - return spe_build_register_parallel (mode, GP_ARG_RETURN); - else - regno = GP_ARG_RETURN; - - return gen_rtx_REG (mode, regno); -} - - -/* Given FROM and TO register numbers, say whether this elimination is allowed. - Frame pointer elimination is automatically handled. - - For the RS/6000, if frame pointer elimination is being done, we would like - to convert ap into fp, not sp. - - We need r30 if -mminimal-toc was specified, and there are constant pool - references. */ - -static bool -rs6000_can_eliminate (const int from, const int to) -{ - return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM - ? ! frame_pointer_needed - : from == RS6000_PIC_OFFSET_TABLE_REGNUM - ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 - : true); -} - -/* 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 == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) - offset = info->push_p ? 0 : -info->total_size; - else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) - { - offset = info->push_p ? 0 : -info->total_size; - if (FRAME_GROWS_DOWNWARD) - offset += info->fixed_size + info->vars_size + info->parm_size; - } - else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) - offset = FRAME_GROWS_DOWNWARD - ? info->fixed_size + info->vars_size + info->parm_size - : 0; - else if (from == ARG_POINTER_REGNUM && to == HARD_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 - gcc_unreachable (); - - return offset; -} - -static rtx -rs6000_dwarf_register_span (rtx reg) -{ - rtx parts[8]; - int i, words; - unsigned regno = REGNO (reg); - enum machine_mode mode = GET_MODE (reg); - - if (TARGET_SPE - && regno < 32 - && (SPE_VECTOR_MODE (GET_MODE (reg)) - || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) - && mode != SFmode && mode != SDmode && mode != SCmode))) - ; - else - 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. */ - words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD; - gcc_assert (words <= 4); - for (i = 0; i < words; i++, regno++) - { - if (BYTES_BIG_ENDIAN) - { - parts[2 * i] = gen_rtx_REG (SImode, regno + 1200); - parts[2 * i + 1] = gen_rtx_REG (SImode, regno); - } - else - { - parts[2 * i] = gen_rtx_REG (SImode, regno); - parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200); - } - } - - return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts)); -} - -/* Fill in sizes for SPE register high parts in table used by unwinder. */ - -static void -rs6000_init_dwarf_reg_sizes_extra (tree address) -{ - if (TARGET_SPE) - { - int i; - enum machine_mode mode = TYPE_MODE (char_type_node); - rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL); - rtx mem = gen_rtx_MEM (BLKmode, addr); - rtx value = gen_int_mode (4, mode); - - for (i = 1201; i < 1232; i++) - { - int column = DWARF_REG_TO_UNWIND_COLUMN (i); - HOST_WIDE_INT offset - = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode); - - emit_move_insn (adjust_address (mem, mode, offset), value); - } - } -} - -/* 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 == LR_REGNO) - return 108; - if (regno == CTR_REGNO) - return 109; - if (CR_REGNO_P (regno)) - return regno - CR0_REGNO + 86; - if (regno == CA_REGNO) - return 101; /* XER */ - 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. */ - gcc_assert (regno >= 1200 && regno < 1232); - return regno; -} - -/* target hook eh_return_filter_mode */ -static enum machine_mode -rs6000_eh_return_filter_mode (void) -{ - return TARGET_32BIT ? SImode : word_mode; -} - -/* Target hook for scalar_mode_supported_p. */ -static bool -rs6000_scalar_mode_supported_p (enum machine_mode mode) -{ - if (DECIMAL_FLOAT_MODE_P (mode)) - return default_decimal_float_supported_p (); - else - return default_scalar_mode_supported_p (mode); -} - -/* Target hook for vector_mode_supported_p. */ -static bool -rs6000_vector_mode_supported_p (enum machine_mode mode) -{ - - if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode)) - return true; - - if (TARGET_SPE && SPE_VECTOR_MODE (mode)) - return true; - - else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) - return true; - - else - return false; -} - -/* Target hook for invalid_arg_for_unprototyped_fn. */ -static const char * -invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val) -{ - return (!rs6000_darwin64_abi - && typelist == 0 - && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE - && (funcdecl == NULL_TREE - || (TREE_CODE (funcdecl) == FUNCTION_DECL - && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD))) - ? N_("AltiVec argument passed to unprototyped function") - : NULL; -} - -/* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register - setup by using __stack_chk_fail_local hidden function instead of - calling __stack_chk_fail directly. Otherwise it is better to call - __stack_chk_fail directly. */ - -static tree ATTRIBUTE_UNUSED -rs6000_stack_protect_fail (void) -{ - return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic) - ? default_hidden_stack_protect_fail () - : default_external_stack_protect_fail (); -} - -void -rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED, - int num_operands ATTRIBUTE_UNUSED) -{ - if (rs6000_warn_cell_microcode) - { - const char *temp; - int insn_code_number = recog_memoized (insn); - location_t location = INSN_LOCATION (insn); - - /* Punt on insns we cannot recognize. */ - if (insn_code_number < 0) - return; - - temp = get_insn_template (insn_code_number, insn); - - if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS) - warning_at (location, OPT_mwarn_cell_microcode, - "emitting microcode insn %s\t[%s] #%d", - temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn)); - else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL) - warning_at (location, OPT_mwarn_cell_microcode, - "emitting conditional microcode insn %s\t[%s] #%d", - temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn)); - } -} - -/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ - -#if TARGET_ELF -static unsigned HOST_WIDE_INT -rs6000_asan_shadow_offset (void) -{ - return (unsigned HOST_WIDE_INT) 1 << (TARGET_64BIT ? 41 : 29); -} -#endif - -/* Mask options that we want to support inside of attribute((target)) and - #pragma GCC target operations. Note, we do not include things like - 64/32-bit, endianess, hard/soft floating point, etc. that would have - different calling sequences. */ - -struct rs6000_opt_mask { - const char *name; /* option name */ - HOST_WIDE_INT mask; /* mask to set */ - bool invert; /* invert sense of mask */ - bool valid_target; /* option is a target option */ -}; - -static struct rs6000_opt_mask const rs6000_opt_masks[] = -{ - { "altivec", OPTION_MASK_ALTIVEC, false, true }, - { "cmpb", OPTION_MASK_CMPB, false, true }, - { "dlmzb", OPTION_MASK_DLMZB, false, true }, - { "fprnd", OPTION_MASK_FPRND, false, true }, - { "hard-dfp", OPTION_MASK_DFP, false, true }, - { "isel", OPTION_MASK_ISEL, false, true }, - { "mfcrf", OPTION_MASK_MFCRF, false, true }, - { "mfpgpr", OPTION_MASK_MFPGPR, false, true }, - { "mulhw", OPTION_MASK_MULHW, false, true }, - { "multiple", OPTION_MASK_MULTIPLE, false, true }, - { "update", OPTION_MASK_NO_UPDATE, true , true }, - { "popcntb", OPTION_MASK_POPCNTB, false, true }, - { "popcntd", OPTION_MASK_POPCNTD, false, true }, - { "powerpc-gfxopt", OPTION_MASK_PPC_GFXOPT, false, true }, - { "powerpc-gpopt", OPTION_MASK_PPC_GPOPT, false, true }, - { "recip-precision", OPTION_MASK_RECIP_PRECISION, false, true }, - { "string", OPTION_MASK_STRING, false, true }, - { "vsx", OPTION_MASK_VSX, false, true }, -#ifdef OPTION_MASK_64BIT -#if TARGET_AIX_OS - { "aix64", OPTION_MASK_64BIT, false, false }, - { "aix32", OPTION_MASK_64BIT, true, false }, -#else - { "64", OPTION_MASK_64BIT, false, false }, - { "32", OPTION_MASK_64BIT, true, false }, -#endif -#endif -#ifdef OPTION_MASK_EABI - { "eabi", OPTION_MASK_EABI, false, false }, -#endif -#ifdef OPTION_MASK_LITTLE_ENDIAN - { "little", OPTION_MASK_LITTLE_ENDIAN, false, false }, - { "big", OPTION_MASK_LITTLE_ENDIAN, true, false }, -#endif -#ifdef OPTION_MASK_RELOCATABLE - { "relocatable", OPTION_MASK_RELOCATABLE, false, false }, -#endif -#ifdef OPTION_MASK_STRICT_ALIGN - { "strict-align", OPTION_MASK_STRICT_ALIGN, false, false }, -#endif - { "soft-float", OPTION_MASK_SOFT_FLOAT, false, false }, - { "string", OPTION_MASK_STRING, false, false }, -}; - -/* Builtin mask mapping for printing the flags. */ -static struct rs6000_opt_mask const rs6000_builtin_mask_names[] = -{ - { "altivec", RS6000_BTM_ALTIVEC, false, false }, - { "vsx", RS6000_BTM_VSX, false, false }, - { "spe", RS6000_BTM_SPE, false, false }, - { "paired", RS6000_BTM_PAIRED, false, false }, - { "fre", RS6000_BTM_FRE, false, false }, - { "fres", RS6000_BTM_FRES, false, false }, - { "frsqrte", RS6000_BTM_FRSQRTE, false, false }, - { "frsqrtes", RS6000_BTM_FRSQRTES, false, false }, - { "popcntd", RS6000_BTM_POPCNTD, false, false }, - { "cell", RS6000_BTM_CELL, false, false }, -}; - -/* Option variables that we want to support inside attribute((target)) and - #pragma GCC target operations. */ - -struct rs6000_opt_var { - const char *name; /* option name */ - size_t global_offset; /* offset of the option in global_options. */ - size_t target_offset; /* offset of the option in target optiosn. */ -}; - -static struct rs6000_opt_var const rs6000_opt_vars[] = -{ - { "friz", - offsetof (struct gcc_options, x_TARGET_FRIZ), - offsetof (struct cl_target_option, x_TARGET_FRIZ), }, - { "avoid-indexed-addresses", - offsetof (struct gcc_options, x_TARGET_AVOID_XFORM), - offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) }, - { "paired", - offsetof (struct gcc_options, x_rs6000_paired_float), - offsetof (struct cl_target_option, x_rs6000_paired_float), }, - { "longcall", - offsetof (struct gcc_options, x_rs6000_default_long_calls), - offsetof (struct cl_target_option, x_rs6000_default_long_calls), }, -}; - -/* Inner function to handle attribute((target("..."))) and #pragma GCC target - parsing. Return true if there were no errors. */ - -static bool -rs6000_inner_target_options (tree args, bool attr_p) -{ - bool ret = true; - - if (args == NULL_TREE) - ; - - else if (TREE_CODE (args) == STRING_CST) - { - char *p = ASTRDUP (TREE_STRING_POINTER (args)); - char *q; - - while ((q = strtok (p, ",")) != NULL) - { - bool error_p = false; - bool not_valid_p = false; - const char *cpu_opt = NULL; - - p = NULL; - if (strncmp (q, "cpu=", 4) == 0) - { - int cpu_index = rs6000_cpu_name_lookup (q+4); - if (cpu_index >= 0) - rs6000_cpu_index = cpu_index; - else - { - error_p = true; - cpu_opt = q+4; - } - } - else if (strncmp (q, "tune=", 5) == 0) - { - int tune_index = rs6000_cpu_name_lookup (q+5); - if (tune_index >= 0) - rs6000_tune_index = tune_index; - else - { - error_p = true; - cpu_opt = q+5; - } - } - else - { - size_t i; - bool invert = false; - char *r = q; - - error_p = true; - if (strncmp (r, "no-", 3) == 0) - { - invert = true; - r += 3; - } - - for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++) - if (strcmp (r, rs6000_opt_masks[i].name) == 0) - { - HOST_WIDE_INT mask = rs6000_opt_masks[i].mask; - - if (!rs6000_opt_masks[i].valid_target) - not_valid_p = true; - else - { - error_p = false; - rs6000_isa_flags_explicit |= mask; - - /* VSX needs altivec, so -mvsx automagically sets - altivec. */ - if (mask == OPTION_MASK_VSX && !invert) - mask |= OPTION_MASK_ALTIVEC; - - if (rs6000_opt_masks[i].invert) - invert = !invert; - - if (invert) - rs6000_isa_flags &= ~mask; - else - rs6000_isa_flags |= mask; - } - break; - } - - if (error_p && !not_valid_p) - { - for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++) - if (strcmp (r, rs6000_opt_vars[i].name) == 0) - { - size_t j = rs6000_opt_vars[i].global_offset; - *((int *) ((char *)&global_options + j)) = !invert; - error_p = false; - break; - } - } - } - - if (error_p) - { - const char *eprefix, *esuffix; - - ret = false; - if (attr_p) - { - eprefix = "__attribute__((__target__("; - esuffix = ")))"; - } - else - { - eprefix = "#pragma GCC target "; - esuffix = ""; - } - - if (cpu_opt) - error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix, - q, esuffix); - else if (not_valid_p) - error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix); - else - error ("%s\"%s\"%s is invalid", eprefix, q, esuffix); - } - } - } - - else if (TREE_CODE (args) == TREE_LIST) - { - do - { - tree value = TREE_VALUE (args); - if (value) - { - bool ret2 = rs6000_inner_target_options (value, attr_p); - if (!ret2) - ret = false; - } - args = TREE_CHAIN (args); - } - while (args != NULL_TREE); - } - - else - gcc_unreachable (); - - return ret; -} - -/* Print out the target options as a list for -mdebug=target. */ - -static void -rs6000_debug_target_options (tree args, const char *prefix) -{ - if (args == NULL_TREE) - fprintf (stderr, "%s<NULL>", prefix); - - else if (TREE_CODE (args) == STRING_CST) - { - char *p = ASTRDUP (TREE_STRING_POINTER (args)); - char *q; - - while ((q = strtok (p, ",")) != NULL) - { - p = NULL; - fprintf (stderr, "%s\"%s\"", prefix, q); - prefix = ", "; - } - } - - else if (TREE_CODE (args) == TREE_LIST) - { - do - { - tree value = TREE_VALUE (args); - if (value) - { - rs6000_debug_target_options (value, prefix); - prefix = ", "; - } - args = TREE_CHAIN (args); - } - while (args != NULL_TREE); - } - - else - gcc_unreachable (); - - return; -} - - -/* Hook to validate attribute((target("..."))). */ - -static bool -rs6000_valid_attribute_p (tree fndecl, - tree ARG_UNUSED (name), - tree args, - int flags) -{ - struct cl_target_option cur_target; - bool ret; - tree old_optimize = build_optimization_node (); - tree new_target, new_optimize; - tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); - - gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE)); - - if (TARGET_DEBUG_TARGET) - { - tree tname = DECL_NAME (fndecl); - fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n"); - if (tname) - fprintf (stderr, "function: %.*s\n", - (int) IDENTIFIER_LENGTH (tname), - IDENTIFIER_POINTER (tname)); - else - fprintf (stderr, "function: unknown\n"); - - fprintf (stderr, "args:"); - rs6000_debug_target_options (args, " "); - fprintf (stderr, "\n"); - - if (flags) - fprintf (stderr, "flags: 0x%x\n", flags); - - fprintf (stderr, "--------------------\n"); - } - - old_optimize = build_optimization_node (); - func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); - - /* If the function changed the optimization levels as well as setting target - options, start with the optimizations specified. */ - if (func_optimize && func_optimize != old_optimize) - cl_optimization_restore (&global_options, - TREE_OPTIMIZATION (func_optimize)); - - /* The target attributes may also change some optimization flags, so update - the optimization options if necessary. */ - cl_target_option_save (&cur_target, &global_options); - rs6000_cpu_index = rs6000_tune_index = -1; - ret = rs6000_inner_target_options (args, true); - - /* Set up any additional state. */ - if (ret) - { - ret = rs6000_option_override_internal (false); - new_target = build_target_option_node (); - } - else - new_target = NULL; - - new_optimize = build_optimization_node (); - - if (!new_target) - ret = false; - - else if (fndecl) - { - DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target; - - if (old_optimize != new_optimize) - DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; - } - - cl_target_option_restore (&global_options, &cur_target); - - if (old_optimize != new_optimize) - cl_optimization_restore (&global_options, - TREE_OPTIMIZATION (old_optimize)); - - return ret; -} - - -/* Hook to validate the current #pragma GCC target and set the state, and - update the macros based on what was changed. If ARGS is NULL, then - POP_TARGET is used to reset the options. */ - -bool -rs6000_pragma_target_parse (tree args, tree pop_target) -{ - tree prev_tree = build_target_option_node (); - tree cur_tree; - struct cl_target_option *prev_opt, *cur_opt; - HOST_WIDE_INT prev_flags, cur_flags, diff_flags; - HOST_WIDE_INT prev_bumask, cur_bumask, diff_bumask; - - if (TARGET_DEBUG_TARGET) - { - fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n"); - fprintf (stderr, "args:"); - rs6000_debug_target_options (args, " "); - fprintf (stderr, "\n"); - - if (pop_target) - { - fprintf (stderr, "pop_target:\n"); - debug_tree (pop_target); - } - else - fprintf (stderr, "pop_target: <NULL>\n"); - - fprintf (stderr, "--------------------\n"); - } - - if (! args) - { - cur_tree = ((pop_target) - ? pop_target - : target_option_default_node); - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (cur_tree)); - } - else - { - rs6000_cpu_index = rs6000_tune_index = -1; - if (!rs6000_inner_target_options (args, false) - || !rs6000_option_override_internal (false) - || (cur_tree = build_target_option_node ()) == NULL_TREE) - { - if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) - fprintf (stderr, "invalid pragma\n"); - - return false; - } - } - - target_option_current_node = cur_tree; - - /* If we have the preprocessor linked in (i.e. C or C++ languages), possibly - change the macros that are defined. */ - if (rs6000_target_modify_macros_ptr) - { - prev_opt = TREE_TARGET_OPTION (prev_tree); - prev_bumask = prev_opt->x_rs6000_builtin_mask; - prev_flags = prev_opt->x_rs6000_isa_flags; - - cur_opt = TREE_TARGET_OPTION (cur_tree); - cur_flags = cur_opt->x_rs6000_isa_flags; - cur_bumask = cur_opt->x_rs6000_builtin_mask; - - diff_bumask = (prev_bumask ^ cur_bumask); - diff_flags = (prev_flags ^ cur_flags); - - if ((diff_flags != 0) || (diff_bumask != 0)) - { - /* Delete old macros. */ - rs6000_target_modify_macros_ptr (false, - prev_flags & diff_flags, - prev_bumask & diff_bumask); - - /* Define new macros. */ - rs6000_target_modify_macros_ptr (true, - cur_flags & diff_flags, - cur_bumask & diff_bumask); - } - } - - return true; -} - - -/* Remember the last target of rs6000_set_current_function. */ -static GTY(()) tree rs6000_previous_fndecl; - -/* Establish appropriate back-end context for processing the function - FNDECL. The argument might be NULL to indicate processing at top - level, outside of any function scope. */ -static void -rs6000_set_current_function (tree fndecl) -{ - tree old_tree = (rs6000_previous_fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl) - : NULL_TREE); - - tree new_tree = (fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl) - : NULL_TREE); - - if (TARGET_DEBUG_TARGET) - { - bool print_final = false; - fprintf (stderr, "\n==================== rs6000_set_current_function"); - - if (fndecl) - fprintf (stderr, ", fndecl %s (%p)", - (DECL_NAME (fndecl) - ? IDENTIFIER_POINTER (DECL_NAME (fndecl)) - : "<unknown>"), (void *)fndecl); - - if (rs6000_previous_fndecl) - fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl); - - fprintf (stderr, "\n"); - if (new_tree) - { - fprintf (stderr, "\nnew fndecl target specific options:\n"); - debug_tree (new_tree); - print_final = true; - } - - if (old_tree) - { - fprintf (stderr, "\nold fndecl target specific options:\n"); - debug_tree (old_tree); - print_final = true; - } - - if (print_final) - fprintf (stderr, "--------------------\n"); - } - - /* Only change the context if the function changes. This hook is called - several times in the course of compiling a function, and we don't want to - slow things down too much or call target_reinit when it isn't safe. */ - if (fndecl && fndecl != rs6000_previous_fndecl) - { - rs6000_previous_fndecl = fndecl; - if (old_tree == new_tree) - ; - - else if (new_tree) - { - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (new_tree)); - target_reinit (); - } - - else if (old_tree) - { - struct cl_target_option *def - = TREE_TARGET_OPTION (target_option_current_node); - - cl_target_option_restore (&global_options, def); - target_reinit (); - } - } -} - - -/* Save the current options */ - -static void -rs6000_function_specific_save (struct cl_target_option *ptr) -{ - ptr->x_rs6000_isa_flags = rs6000_isa_flags; - ptr->x_rs6000_isa_flags_explicit = rs6000_isa_flags_explicit; -} - -/* Restore the current options */ - -static void -rs6000_function_specific_restore (struct cl_target_option *ptr) -{ - rs6000_isa_flags = ptr->x_rs6000_isa_flags; - rs6000_isa_flags_explicit = ptr->x_rs6000_isa_flags_explicit; - (void) rs6000_option_override_internal (false); -} - -/* Print the current options */ - -static void -rs6000_function_specific_print (FILE *file, int indent, - struct cl_target_option *ptr) -{ - rs6000_print_isa_options (file, indent, "Isa options set", - ptr->x_rs6000_isa_flags); - - rs6000_print_isa_options (file, indent, "Isa options explicit", - ptr->x_rs6000_isa_flags_explicit); -} - -/* Helper function to print the current isa or misc options on a line. */ - -static void -rs6000_print_options_internal (FILE *file, - int indent, - const char *string, - HOST_WIDE_INT flags, - const char *prefix, - const struct rs6000_opt_mask *opts, - size_t num_elements) -{ - size_t i; - size_t start_column = 0; - size_t cur_column; - size_t max_column = 76; - const char *comma = ""; - const char *nl = "\n"; - - if (indent) - start_column += fprintf (file, "%*s", indent, ""); - - if (!flags) - { - fprintf (stderr, DEBUG_FMT_S, string, "<none>"); - return; - } - - start_column += fprintf (stderr, DEBUG_FMT_WX, string, flags); - - /* Print the various mask options. */ - cur_column = start_column; - for (i = 0; i < num_elements; i++) - { - if ((flags & opts[i].mask) != 0) - { - const char *no_str = rs6000_opt_masks[i].invert ? "no-" : ""; - size_t len = (strlen (comma) - + strlen (prefix) - + strlen (no_str) - + strlen (rs6000_opt_masks[i].name)); - - cur_column += len; - if (cur_column > max_column) - { - fprintf (stderr, ", \\\n%*s", (int)start_column, ""); - cur_column = start_column + len; - comma = ""; - nl = "\n\n"; - } - - fprintf (file, "%s%s%s%s", comma, prefix, no_str, - rs6000_opt_masks[i].name); - flags &= ~ opts[i].mask; - comma = ", "; - } - } - - fputs (nl, file); -} - -/* Helper function to print the current isa options on a line. */ - -static void -rs6000_print_isa_options (FILE *file, int indent, const char *string, - HOST_WIDE_INT flags) -{ - rs6000_print_options_internal (file, indent, string, flags, "-m", - &rs6000_opt_masks[0], - ARRAY_SIZE (rs6000_opt_masks)); -} - -static void -rs6000_print_builtin_options (FILE *file, int indent, const char *string, - HOST_WIDE_INT flags) -{ - rs6000_print_options_internal (file, indent, string, flags, "", - &rs6000_builtin_mask_names[0], - ARRAY_SIZE (rs6000_builtin_mask_names)); -} - - -/* Hook to determine if one function can safely inline another. */ - -static bool -rs6000_can_inline_p (tree caller, tree callee) -{ - bool ret = false; - tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller); - tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee); - - /* If callee has no option attributes, then it is ok to inline. */ - if (!callee_tree) - ret = true; - - /* If caller has no option attributes, but callee does then it is not ok to - inline. */ - else if (!caller_tree) - ret = false; - - else - { - struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree); - struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree); - - /* Callee's options should a subset of the caller's, i.e. a vsx function - can inline an altivec function but a non-vsx function can't inline a - vsx function. */ - if ((caller_opts->x_rs6000_isa_flags & callee_opts->x_rs6000_isa_flags) - == callee_opts->x_rs6000_isa_flags) - ret = true; - } - - if (TARGET_DEBUG_TARGET) - fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n", - (DECL_NAME (caller) - ? IDENTIFIER_POINTER (DECL_NAME (caller)) - : "<unknown>"), - (DECL_NAME (callee) - ? IDENTIFIER_POINTER (DECL_NAME (callee)) - : "<unknown>"), - (ret ? "can" : "cannot")); - - return ret; -} - -/* Allocate a stack temp and fixup the address so it meets the particular - memory requirements (either offetable or REG+REG addressing). */ - -rtx -rs6000_allocate_stack_temp (enum machine_mode mode, - bool offsettable_p, - bool reg_reg_p) -{ - rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode)); - rtx addr = XEXP (stack, 0); - int strict_p = (reload_in_progress || reload_completed); - - if (!legitimate_indirect_address_p (addr, strict_p)) - { - if (offsettable_p - && !rs6000_legitimate_offset_address_p (mode, addr, strict_p, true)) - stack = replace_equiv_address (stack, copy_addr_to_reg (addr)); - - else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p)) - stack = replace_equiv_address (stack, copy_addr_to_reg (addr)); - } - - return stack; -} - -/* Given a memory reference, if it is not a reg or reg+reg addressing, convert - to such a form to deal with memory reference instructions like STFIWX that - only take reg+reg addressing. */ - -rtx -rs6000_address_for_fpconvert (rtx x) -{ - int strict_p = (reload_in_progress || reload_completed); - rtx addr; - - gcc_assert (MEM_P (x)); - addr = XEXP (x, 0); - if (! legitimate_indirect_address_p (addr, strict_p) - && ! legitimate_indexed_address_p (addr, strict_p)) - { - if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC) - { - rtx reg = XEXP (addr, 0); - HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x)); - rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size); - gcc_assert (REG_P (reg)); - emit_insn (gen_add3_insn (reg, reg, size_rtx)); - addr = reg; - } - else if (GET_CODE (addr) == PRE_MODIFY) - { - rtx reg = XEXP (addr, 0); - rtx expr = XEXP (addr, 1); - gcc_assert (REG_P (reg)); - gcc_assert (GET_CODE (expr) == PLUS); - emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1))); - addr = reg; - } - - x = replace_equiv_address (x, copy_addr_to_reg (addr)); - } - - return x; -} - -/* Given a memory reference, if it is not in the form for altivec memory - reference instructions (i.e. reg or reg+reg addressing with AND of -16), - convert to the altivec format. */ - -rtx -rs6000_address_for_altivec (rtx x) -{ - gcc_assert (MEM_P (x)); - if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x))) - { - rtx addr = XEXP (x, 0); - int strict_p = (reload_in_progress || reload_completed); - - if (!legitimate_indexed_address_p (addr, strict_p) - && !legitimate_indirect_address_p (addr, strict_p)) - addr = copy_to_mode_reg (Pmode, addr); - - addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16)); - x = change_address (x, GET_MODE (x), addr); - } - - return x; -} - -/* Implement TARGET_LEGITIMATE_CONSTANT_P. - - On the RS/6000, all integer constants are acceptable, most won't be valid - for particular insns, though. Only easy FP constants are acceptable. */ - -static bool -rs6000_legitimate_constant_p (enum machine_mode mode, rtx x) -{ - if (TARGET_ELF && rs6000_tls_referenced_p (x)) - return false; - - return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR) - || GET_MODE (x) == VOIDmode - || (TARGET_POWERPC64 && mode == DImode) - || easy_fp_constant (x, mode) - || easy_vector_constant (x, mode)); -} - - -/* A function pointer under AIX is a pointer to a data area whose first word - contains the actual address of the function, whose second word contains a - pointer to its TOC, and whose third word contains a value to place in the - static chain register (r11). Note that if we load the static chain, our - "trampoline" need not have any executable code. */ - -void -rs6000_call_indirect_aix (rtx value, rtx func_desc, rtx flag) -{ - rtx func_addr; - rtx toc_reg; - rtx sc_reg; - rtx stack_ptr; - rtx stack_toc_offset; - rtx stack_toc_mem; - rtx func_toc_offset; - rtx func_toc_mem; - rtx func_sc_offset; - rtx func_sc_mem; - rtx insn; - rtx (*call_func) (rtx, rtx, rtx, rtx); - rtx (*call_value_func) (rtx, rtx, rtx, rtx, rtx); - - stack_ptr = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); - toc_reg = gen_rtx_REG (Pmode, TOC_REGNUM); - - /* Load up address of the actual function. */ - func_desc = force_reg (Pmode, func_desc); - func_addr = gen_reg_rtx (Pmode); - emit_move_insn (func_addr, gen_rtx_MEM (Pmode, func_desc)); - - if (TARGET_32BIT) - { - - stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_32BIT); - func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_32BIT); - func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_32BIT); - if (TARGET_POINTERS_TO_NESTED_FUNCTIONS) - { - call_func = gen_call_indirect_aix32bit; - call_value_func = gen_call_value_indirect_aix32bit; - } - else - { - call_func = gen_call_indirect_aix32bit_nor11; - call_value_func = gen_call_value_indirect_aix32bit_nor11; - } - } - else - { - stack_toc_offset = GEN_INT (TOC_SAVE_OFFSET_64BIT); - func_toc_offset = GEN_INT (AIX_FUNC_DESC_TOC_64BIT); - func_sc_offset = GEN_INT (AIX_FUNC_DESC_SC_64BIT); - if (TARGET_POINTERS_TO_NESTED_FUNCTIONS) - { - call_func = gen_call_indirect_aix64bit; - call_value_func = gen_call_value_indirect_aix64bit; - } - else - { - call_func = gen_call_indirect_aix64bit_nor11; - call_value_func = gen_call_value_indirect_aix64bit_nor11; - } - } - - /* Reserved spot to store the TOC. */ - stack_toc_mem = gen_frame_mem (Pmode, - gen_rtx_PLUS (Pmode, - stack_ptr, - stack_toc_offset)); - - gcc_assert (cfun); - gcc_assert (cfun->machine); - - /* Can we optimize saving the TOC in the prologue or do we need to do it at - every call? */ - if (TARGET_SAVE_TOC_INDIRECT && !cfun->calls_alloca) - cfun->machine->save_toc_in_prologue = true; - - else - { - MEM_VOLATILE_P (stack_toc_mem) = 1; - emit_move_insn (stack_toc_mem, toc_reg); - } - - /* Calculate the address to load the TOC of the called function. We don't - actually load this until the split after reload. */ - func_toc_mem = gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, - func_desc, - func_toc_offset)); - - /* If we have a static chain, load it up. */ - if (TARGET_POINTERS_TO_NESTED_FUNCTIONS) - { - func_sc_mem = gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, - func_desc, - func_sc_offset)); - - sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); - emit_move_insn (sc_reg, func_sc_mem); - } - - /* Create the call. */ - if (value) - insn = call_value_func (value, func_addr, flag, func_toc_mem, - stack_toc_mem); - else - insn = call_func (func_addr, flag, func_toc_mem, stack_toc_mem); - - emit_call_insn (insn); -} - -/* Return whether we need to always update the saved TOC pointer when we update - the stack pointer. */ - -static bool -rs6000_save_toc_in_prologue_p (void) -{ - return (cfun && cfun->machine && cfun->machine->save_toc_in_prologue); -} - -#ifdef HAVE_GAS_HIDDEN -# define USE_HIDDEN_LINKONCE 1 -#else -# define USE_HIDDEN_LINKONCE 0 -#endif - -/* Fills in the label name that should be used for a 476 link stack thunk. */ - -void -get_ppc476_thunk_name (char name[32]) -{ - gcc_assert (TARGET_LINK_STACK); - - if (USE_HIDDEN_LINKONCE) - sprintf (name, "__ppc476.get_thunk"); - else - ASM_GENERATE_INTERNAL_LABEL (name, "LPPC476_", 0); -} - -/* This function emits the simple thunk routine that is used to preserve - the link stack on the 476 cpu. */ - -static void rs6000_code_end (void) ATTRIBUTE_UNUSED; -static void -rs6000_code_end (void) -{ - char name[32]; - tree decl; - - if (!TARGET_LINK_STACK) - return; - - get_ppc476_thunk_name (name); - - decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, get_identifier (name), - build_function_type_list (void_type_node, NULL_TREE)); - DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, - NULL_TREE, void_type_node); - TREE_PUBLIC (decl) = 1; - TREE_STATIC (decl) = 1; - -#if RS6000_WEAK - if (USE_HIDDEN_LINKONCE) - { - DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl); - targetm.asm_out.unique_section (decl, 0); - switch_to_section (get_named_section (decl, NULL, 0)); - DECL_WEAK (decl) = 1; - ASM_WEAKEN_DECL (asm_out_file, decl, name, 0); - targetm.asm_out.globalize_label (asm_out_file, name); - targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); - ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl); - } - else -#endif - { - switch_to_section (text_section); - ASM_OUTPUT_LABEL (asm_out_file, name); - } - - DECL_INITIAL (decl) = make_node (BLOCK); - current_function_decl = decl; - init_function_start (decl); - first_function_block_is_cold = false; - /* Make sure unwind info is emitted for the thunk if needed. */ - final_start_function (emit_barrier (), asm_out_file, 1); - - fputs ("\tblr\n", asm_out_file); - - final_end_function (); - init_insn_lengths (); - free_after_compilation (cfun); - set_cfun (NULL); - current_function_decl = NULL; -} - -/* Add r30 to hard reg set if the prologue sets it up and it is not - pic_offset_table_rtx. */ - -static void -rs6000_set_up_by_prologue (struct hard_reg_set_container *set) -{ - if (!TARGET_SINGLE_PIC_BASE - && TARGET_TOC - && TARGET_MINIMAL_TOC - && get_pool_size () != 0) - add_to_hard_reg_set (&set->set, Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); -} - -struct gcc_target targetm = TARGET_INITIALIZER; - -#include "gt-rs6000.h" diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000.h b/gcc-4.8.1/gcc/config/rs6000/rs6000.h deleted file mode 100644 index b42f62ac7..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000.h +++ /dev/null @@ -1,2515 +0,0 @@ -/* Definitions of target machine for GNU compiler, for IBM RS/6000. - Copyright (C) 1992-2013 Free Software Foundation, Inc. - Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* Note that some other tm.h files include this one and then override - many of the definitions. */ - -#ifndef RS6000_OPTS_H -#include "config/rs6000/rs6000-opts.h" -#endif - -/* Definitions for the object file format. These are set at - compile-time. */ - -#define OBJECT_XCOFF 1 -#define OBJECT_ELF 2 -#define OBJECT_PEF 3 -#define OBJECT_MACHO 4 - -#define TARGET_ELF (TARGET_OBJECT_FORMAT == OBJECT_ELF) -#define TARGET_XCOFF (TARGET_OBJECT_FORMAT == OBJECT_XCOFF) -#define TARGET_MACOS (TARGET_OBJECT_FORMAT == OBJECT_PEF) -#define TARGET_MACHO (TARGET_OBJECT_FORMAT == OBJECT_MACHO) - -#ifndef TARGET_AIX -#define TARGET_AIX 0 -#endif - -#ifndef TARGET_AIX_OS -#define TARGET_AIX_OS 0 -#endif - -/* Control whether function entry points use a "dot" symbol when - ABI_AIX. */ -#define DOT_SYMBOLS 1 - -/* Default string to use for cpu if not specified. */ -#ifndef TARGET_CPU_DEFAULT -#define TARGET_CPU_DEFAULT ((char *)0) -#endif - -/* If configured for PPC405, support PPC405CR Erratum77. */ -#ifdef CONFIG_PPC405CR -#define PPC405_ERRATUM77 (rs6000_cpu == PROCESSOR_PPC405) -#else -#define PPC405_ERRATUM77 0 -#endif - -#ifndef TARGET_PAIRED_FLOAT -#define TARGET_PAIRED_FLOAT 0 -#endif - -#ifdef HAVE_AS_POPCNTB -#define ASM_CPU_POWER5_SPEC "-mpower5" -#else -#define ASM_CPU_POWER5_SPEC "-mpower4" -#endif - -#ifdef HAVE_AS_DFP -#define ASM_CPU_POWER6_SPEC "-mpower6 -maltivec" -#else -#define ASM_CPU_POWER6_SPEC "-mpower4 -maltivec" -#endif - -#ifdef HAVE_AS_POPCNTD -#define ASM_CPU_POWER7_SPEC "-mpower7" -#else -#define ASM_CPU_POWER7_SPEC "-mpower4 -maltivec" -#endif - -#ifdef HAVE_AS_POWER8 -#define ASM_CPU_POWER8_SPEC "-mpower8" -#else -#define ASM_CPU_POWER8_SPEC "-mpower4 -maltivec" -#endif - -#ifdef HAVE_AS_DCI -#define ASM_CPU_476_SPEC "-m476" -#else -#define ASM_CPU_476_SPEC "-mpower4" -#endif - -/* Common ASM definitions used by ASM_SPEC among the various targets for - handling -mcpu=xxx switches. There is a parallel list in driver-rs6000.c to - provide the default assembler options if the user uses -mcpu=native, so if - you make changes here, make them also there. */ -#define ASM_CPU_SPEC \ -"%{!mcpu*: \ - %{mpowerpc64*: -mppc64} \ - %{!mpowerpc64*: %(asm_default)}} \ -%{mcpu=native: %(asm_cpu_native)} \ -%{mcpu=cell: -mcell} \ -%{mcpu=power3: -mppc64} \ -%{mcpu=power4: -mpower4} \ -%{mcpu=power5: %(asm_cpu_power5)} \ -%{mcpu=power5+: %(asm_cpu_power5)} \ -%{mcpu=power6: %(asm_cpu_power6) -maltivec} \ -%{mcpu=power6x: %(asm_cpu_power6) -maltivec} \ -%{mcpu=power7: %(asm_cpu_power7)} \ -%{mcpu=power8: %(asm_cpu_power8)} \ -%{mcpu=a2: -ma2} \ -%{mcpu=powerpc: -mppc} \ -%{mcpu=rs64a: -mppc64} \ -%{mcpu=401: -mppc} \ -%{mcpu=403: -m403} \ -%{mcpu=405: -m405} \ -%{mcpu=405fp: -m405} \ -%{mcpu=440: -m440} \ -%{mcpu=440fp: -m440} \ -%{mcpu=464: -m440} \ -%{mcpu=464fp: -m440} \ -%{mcpu=476: %(asm_cpu_476)} \ -%{mcpu=476fp: %(asm_cpu_476)} \ -%{mcpu=505: -mppc} \ -%{mcpu=601: -m601} \ -%{mcpu=602: -mppc} \ -%{mcpu=603: -mppc} \ -%{mcpu=603e: -mppc} \ -%{mcpu=ec603e: -mppc} \ -%{mcpu=604: -mppc} \ -%{mcpu=604e: -mppc} \ -%{mcpu=620: -mppc64} \ -%{mcpu=630: -mppc64} \ -%{mcpu=740: -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} \ -%{mcpu=8548: -me500} \ -%{mcpu=e300c2: -me300} \ -%{mcpu=e300c3: -me300} \ -%{mcpu=e500mc: -me500mc} \ -%{mcpu=e500mc64: -me500mc64} \ -%{mcpu=e5500: -me5500} \ -%{mcpu=e6500: -me6500} \ -%{maltivec: -maltivec} \ -%{mvsx: -mvsx %{!maltivec: -maltivec} %{!mcpu*: %(asm_cpu_power7)}} \ --many" - -#define CPP_DEFAULT_SPEC "" - -#define ASM_DEFAULT_SPEC "" - -/* This macro defines names of additional specifications to put in the specs - that can be used in various specifications like CC1_SPEC. Its definition - is an initializer with a subgrouping for each command option. - - Each subgrouping contains a string constant, that defines the - specification name, and a string constant that used by the GCC driver - program. - - Do not define this macro if it does not need to do anything. */ - -#define SUBTARGET_EXTRA_SPECS - -#define EXTRA_SPECS \ - { "cpp_default", CPP_DEFAULT_SPEC }, \ - { "asm_cpu", ASM_CPU_SPEC }, \ - { "asm_cpu_native", ASM_CPU_NATIVE_SPEC }, \ - { "asm_default", ASM_DEFAULT_SPEC }, \ - { "cc1_cpu", CC1_CPU_SPEC }, \ - { "asm_cpu_power5", ASM_CPU_POWER5_SPEC }, \ - { "asm_cpu_power6", ASM_CPU_POWER6_SPEC }, \ - { "asm_cpu_power7", ASM_CPU_POWER7_SPEC }, \ - { "asm_cpu_power8", ASM_CPU_POWER8_SPEC }, \ - { "asm_cpu_476", ASM_CPU_476_SPEC }, \ - SUBTARGET_EXTRA_SPECS - -/* -mcpu=native handling only makes sense with compiler running on - an PowerPC chip. If changing this condition, also change - the condition in driver-rs6000.c. */ -#if defined(__powerpc__) || defined(__POWERPC__) || defined(_AIX) -/* In driver-rs6000.c. */ -extern const char *host_detect_local_cpu (int argc, const char **argv); -#define EXTRA_SPEC_FUNCTIONS \ - { "local_cpu_detect", host_detect_local_cpu }, -#define HAVE_LOCAL_CPU_DETECT -#define ASM_CPU_NATIVE_SPEC "%:local_cpu_detect(asm)" - -#else -#define ASM_CPU_NATIVE_SPEC "%(asm_default)" -#endif - -#ifndef CC1_CPU_SPEC -#ifdef HAVE_LOCAL_CPU_DETECT -#define CC1_CPU_SPEC \ -"%{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)} \ - %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}" -#else -#define CC1_CPU_SPEC "" -#endif -#endif - -/* Architecture type. */ - -/* Define TARGET_MFCRF if the target assembler does not support the - optional field operand for mfcr. */ - -#ifndef HAVE_AS_MFCRF -#undef TARGET_MFCRF -#define TARGET_MFCRF 0 -#endif - -/* Define TARGET_POPCNTB if the target assembler does not support the - popcount byte instruction. */ - -#ifndef HAVE_AS_POPCNTB -#undef TARGET_POPCNTB -#define TARGET_POPCNTB 0 -#endif - -/* Define TARGET_FPRND if the target assembler does not support the - fp rounding instructions. */ - -#ifndef HAVE_AS_FPRND -#undef TARGET_FPRND -#define TARGET_FPRND 0 -#endif - -/* Define TARGET_CMPB if the target assembler does not support the - cmpb instruction. */ - -#ifndef HAVE_AS_CMPB -#undef TARGET_CMPB -#define TARGET_CMPB 0 -#endif - -/* Define TARGET_MFPGPR if the target assembler does not support the - mffpr and mftgpr instructions. */ - -#ifndef HAVE_AS_MFPGPR -#undef TARGET_MFPGPR -#define TARGET_MFPGPR 0 -#endif - -/* Define TARGET_DFP if the target assembler does not support decimal - floating point instructions. */ -#ifndef HAVE_AS_DFP -#undef TARGET_DFP -#define TARGET_DFP 0 -#endif - -/* Define TARGET_POPCNTD if the target assembler does not support the - popcount word and double word instructions. */ - -#ifndef HAVE_AS_POPCNTD -#undef TARGET_POPCNTD -#define TARGET_POPCNTD 0 -#endif - -/* Define TARGET_LWSYNC_INSTRUCTION if the assembler knows about lwsync. If - not, generate the lwsync code as an integer constant. */ -#ifdef HAVE_AS_LWSYNC -#define TARGET_LWSYNC_INSTRUCTION 1 -#else -#define TARGET_LWSYNC_INSTRUCTION 0 -#endif - -/* Define TARGET_TLS_MARKERS if the target assembler does not support - arg markers for __tls_get_addr calls. */ -#ifndef HAVE_AS_TLS_MARKERS -#undef TARGET_TLS_MARKERS -#define TARGET_TLS_MARKERS 0 -#else -#define TARGET_TLS_MARKERS tls_markers -#endif - -#ifndef TARGET_SECURE_PLT -#define TARGET_SECURE_PLT 0 -#endif - -#ifndef TARGET_CMODEL -#define TARGET_CMODEL CMODEL_SMALL -#endif - -#define TARGET_32BIT (! TARGET_64BIT) - -#ifndef HAVE_AS_TLS -#define HAVE_AS_TLS 0 -#endif - -#ifndef TARGET_LINK_STACK -#define TARGET_LINK_STACK 0 -#endif - -#ifndef SET_TARGET_LINK_STACK -#define SET_TARGET_LINK_STACK(X) do { } while (0) -#endif - -/* 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) - -#ifdef IN_LIBGCC2 -/* For libgcc2 we make sure this is a compile time constant */ -#if defined (__64BIT__) || defined (__powerpc64__) || defined (__ppc64__) -#undef TARGET_POWERPC64 -#define TARGET_POWERPC64 1 -#else -#undef TARGET_POWERPC64 -#define TARGET_POWERPC64 0 -#endif -#else - /* The option machinery will define this. */ -#endif - -#define TARGET_DEFAULT (MASK_MULTIPLE | MASK_STRING) - -/* FPU operations supported. - Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must - also test TARGET_HARD_FLOAT. */ -#define TARGET_SINGLE_FLOAT 1 -#define TARGET_DOUBLE_FLOAT 1 -#define TARGET_SINGLE_FPU 0 -#define TARGET_SIMPLE_FPU 0 -#define TARGET_XILINX_FPU 0 - -/* Recast the processor type to the cpu attribute. */ -#define rs6000_cpu_attr ((enum attr_cpu)rs6000_cpu) - -/* Define generic processor types based upon current deployment. */ -#define PROCESSOR_COMMON PROCESSOR_PPC601 -#define PROCESSOR_POWERPC PROCESSOR_PPC604 -#define PROCESSOR_POWERPC64 PROCESSOR_RS64A - -/* Define the default processor. This is overridden by other tm.h files. */ -#define PROCESSOR_DEFAULT PROCESSOR_PPC603 -#define PROCESSOR_DEFAULT64 PROCESSOR_RS64A - -/* Specify the dialect of assembler to use. Only new mnemonics are supported - starting with GCC 4.8, i.e. just one dialect, but for backwards - compatibility with older inline asm ASSEMBLER_DIALECT needs to be - defined. */ -#define ASSEMBLER_DIALECT 1 - -/* Debug support */ -#define MASK_DEBUG_STACK 0x01 /* debug stack applications */ -#define MASK_DEBUG_ARG 0x02 /* debug argument handling */ -#define MASK_DEBUG_REG 0x04 /* debug register handling */ -#define MASK_DEBUG_ADDR 0x08 /* debug memory addressing */ -#define MASK_DEBUG_COST 0x10 /* debug rtx codes */ -#define MASK_DEBUG_TARGET 0x20 /* debug target attribute/pragma */ -#define MASK_DEBUG_BUILTIN 0x40 /* debug builtins */ -#define MASK_DEBUG_ALL (MASK_DEBUG_STACK \ - | MASK_DEBUG_ARG \ - | MASK_DEBUG_REG \ - | MASK_DEBUG_ADDR \ - | MASK_DEBUG_COST \ - | MASK_DEBUG_TARGET \ - | MASK_DEBUG_BUILTIN) - -#define TARGET_DEBUG_STACK (rs6000_debug & MASK_DEBUG_STACK) -#define TARGET_DEBUG_ARG (rs6000_debug & MASK_DEBUG_ARG) -#define TARGET_DEBUG_REG (rs6000_debug & MASK_DEBUG_REG) -#define TARGET_DEBUG_ADDR (rs6000_debug & MASK_DEBUG_ADDR) -#define TARGET_DEBUG_COST (rs6000_debug & MASK_DEBUG_COST) -#define TARGET_DEBUG_TARGET (rs6000_debug & MASK_DEBUG_TARGET) -#define TARGET_DEBUG_BUILTIN (rs6000_debug & MASK_DEBUG_BUILTIN) - -extern enum rs6000_vector rs6000_vector_unit[]; - -#define VECTOR_UNIT_NONE_P(MODE) \ - (rs6000_vector_unit[(MODE)] == VECTOR_NONE) - -#define VECTOR_UNIT_VSX_P(MODE) \ - (rs6000_vector_unit[(MODE)] == VECTOR_VSX) - -#define VECTOR_UNIT_ALTIVEC_P(MODE) \ - (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC) - -#define VECTOR_UNIT_ALTIVEC_OR_VSX_P(MODE) \ - (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC \ - || rs6000_vector_unit[(MODE)] == VECTOR_VSX) - -/* Describe whether to use VSX loads or Altivec loads. For now, just use the - same unit as the vector unit we are using, but we may want to migrate to - using VSX style loads even for types handled by altivec. */ -extern enum rs6000_vector rs6000_vector_mem[]; - -#define VECTOR_MEM_NONE_P(MODE) \ - (rs6000_vector_mem[(MODE)] == VECTOR_NONE) - -#define VECTOR_MEM_VSX_P(MODE) \ - (rs6000_vector_mem[(MODE)] == VECTOR_VSX) - -#define VECTOR_MEM_ALTIVEC_P(MODE) \ - (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC) - -#define VECTOR_MEM_ALTIVEC_OR_VSX_P(MODE) \ - (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC \ - || rs6000_vector_mem[(MODE)] == VECTOR_VSX) - -/* Return the alignment of a given vector type, which is set based on the - vector unit use. VSX for instance can load 32 or 64 bit aligned words - without problems, while Altivec requires 128-bit aligned vectors. */ -extern int rs6000_vector_align[]; - -#define VECTOR_ALIGN(MODE) \ - ((rs6000_vector_align[(MODE)] != 0) \ - ? rs6000_vector_align[(MODE)] \ - : (int)GET_MODE_BITSIZE ((MODE))) - -/* 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_IEEEQUAD rs6000_ieeequad -#define TARGET_ALTIVEC_ABI rs6000_altivec_abi -#define TARGET_LDBRX (TARGET_POPCNTD || rs6000_cpu == PROCESSOR_CELL) - -#define TARGET_SPE_ABI 0 -#define TARGET_SPE 0 -#define TARGET_ISEL64 (TARGET_ISEL && TARGET_POWERPC64) -#define TARGET_FPRS 1 -#define TARGET_E500_SINGLE 0 -#define TARGET_E500_DOUBLE 0 -#define CHECK_E500_OPTIONS do { } while (0) - -/* ISA 2.01 allowed FCFID to be done in 32-bit, previously it was 64-bit only. - Enable 32-bit fcfid's on any of the switches for newer ISA machines or - XILINX. */ -#define TARGET_FCFID (TARGET_POWERPC64 \ - || TARGET_PPC_GPOPT /* 970/power4 */ \ - || TARGET_POPCNTB /* ISA 2.02 */ \ - || TARGET_CMPB /* ISA 2.05 */ \ - || TARGET_POPCNTD /* ISA 2.06 */ \ - || TARGET_XILINX_FPU) - -#define TARGET_FCTIDZ TARGET_FCFID -#define TARGET_STFIWX TARGET_PPC_GFXOPT -#define TARGET_LFIWAX TARGET_CMPB -#define TARGET_LFIWZX TARGET_POPCNTD -#define TARGET_FCFIDS TARGET_POPCNTD -#define TARGET_FCFIDU TARGET_POPCNTD -#define TARGET_FCFIDUS TARGET_POPCNTD -#define TARGET_FCTIDUZ TARGET_POPCNTD -#define TARGET_FCTIWUZ TARGET_POPCNTD - -/* In switching from using target_flags to using rs6000_isa_flags, the options - machinery creates OPTION_MASK_<xxx> instead of MASK_<xxx>. For now map - OPTION_MASK_<xxx> back into MASK_<xxx>. */ -#define MASK_ALTIVEC OPTION_MASK_ALTIVEC -#define MASK_CMPB OPTION_MASK_CMPB -#define MASK_DFP OPTION_MASK_DFP -#define MASK_DLMZB OPTION_MASK_DLMZB -#define MASK_EABI OPTION_MASK_EABI -#define MASK_FPRND OPTION_MASK_FPRND -#define MASK_HARD_FLOAT OPTION_MASK_HARD_FLOAT -#define MASK_ISEL OPTION_MASK_ISEL -#define MASK_MFCRF OPTION_MASK_MFCRF -#define MASK_MFPGPR OPTION_MASK_MFPGPR -#define MASK_MULHW OPTION_MASK_MULHW -#define MASK_MULTIPLE OPTION_MASK_MULTIPLE -#define MASK_NO_UPDATE OPTION_MASK_NO_UPDATE -#define MASK_POPCNTB OPTION_MASK_POPCNTB -#define MASK_POPCNTD OPTION_MASK_POPCNTD -#define MASK_PPC_GFXOPT OPTION_MASK_PPC_GFXOPT -#define MASK_PPC_GPOPT OPTION_MASK_PPC_GPOPT -#define MASK_RECIP_PRECISION OPTION_MASK_RECIP_PRECISION -#define MASK_SOFT_FLOAT OPTION_MASK_SOFT_FLOAT -#define MASK_STRICT_ALIGN OPTION_MASK_STRICT_ALIGN -#define MASK_STRING OPTION_MASK_STRING -#define MASK_UPDATE OPTION_MASK_UPDATE -#define MASK_VSX OPTION_MASK_VSX - -#ifndef IN_LIBGCC2 -#define MASK_POWERPC64 OPTION_MASK_POWERPC64 -#endif - -#ifdef TARGET_64BIT -#define MASK_64BIT OPTION_MASK_64BIT -#endif - -#ifdef TARGET_RELOCATABLE -#define MASK_RELOCATABLE OPTION_MASK_RELOCATABLE -#endif - -#ifdef TARGET_LITTLE_ENDIAN -#define MASK_LITTLE_ENDIAN OPTION_MASK_LITTLE_ENDIAN -#endif - -#ifdef TARGET_MINIMAL_TOC -#define MASK_MINIMAL_TOC OPTION_MASK_MINIMAL_TOC -#endif - -#ifdef TARGET_REGNAMES -#define MASK_REGNAMES OPTION_MASK_REGNAMES -#endif - -#ifdef TARGET_PROTOTYPE -#define MASK_PROTOTYPE OPTION_MASK_PROTOTYPE -#endif - -/* Explicit ISA options that were set. */ -#define rs6000_isa_flags_explicit global_options_set.x_rs6000_isa_flags - -/* For power systems, we want to enable Altivec and VSX builtins even if the - user did not use -maltivec or -mvsx to allow the builtins to be used inside - of #pragma GCC target or the target attribute to change the code level for a - given system. The SPE and Paired builtins are only enabled if you configure - the compiler for those builtins, and those machines don't support altivec or - VSX. */ - -#define TARGET_EXTRA_BUILTINS (!TARGET_SPE && !TARGET_PAIRED_FLOAT \ - && ((TARGET_POWERPC64 \ - || TARGET_PPC_GPOPT /* 970/power4 */ \ - || TARGET_POPCNTB /* ISA 2.02 */ \ - || TARGET_CMPB /* ISA 2.05 */ \ - || TARGET_POPCNTD /* ISA 2.06 */ \ - || TARGET_ALTIVEC \ - || TARGET_VSX))) - -/* E500 cores only support plain "sync", not lwsync. */ -#define TARGET_NO_LWSYNC (rs6000_cpu == PROCESSOR_PPC8540 \ - || rs6000_cpu == PROCESSOR_PPC8548) - - -/* Which machine supports the various reciprocal estimate instructions. */ -#define TARGET_FRES (TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT \ - && TARGET_FPRS && TARGET_SINGLE_FLOAT) - -#define TARGET_FRE (TARGET_HARD_FLOAT && TARGET_FPRS \ - && TARGET_DOUBLE_FLOAT \ - && (TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode))) - -#define TARGET_FRSQRTES (TARGET_HARD_FLOAT && TARGET_POPCNTB \ - && TARGET_FPRS && TARGET_SINGLE_FLOAT) - -#define TARGET_FRSQRTE (TARGET_HARD_FLOAT && TARGET_FPRS \ - && TARGET_DOUBLE_FLOAT \ - && (TARGET_PPC_GFXOPT || VECTOR_UNIT_VSX_P (DFmode))) - -/* Whether the various reciprocal divide/square root estimate instructions - exist, and whether we should automatically generate code for the instruction - by default. */ -#define RS6000_RECIP_MASK_HAVE_RE 0x1 /* have RE instruction. */ -#define RS6000_RECIP_MASK_AUTO_RE 0x2 /* generate RE by default. */ -#define RS6000_RECIP_MASK_HAVE_RSQRTE 0x4 /* have RSQRTE instruction. */ -#define RS6000_RECIP_MASK_AUTO_RSQRTE 0x8 /* gen. RSQRTE by default. */ - -extern unsigned char rs6000_recip_bits[]; - -#define RS6000_RECIP_HAVE_RE_P(MODE) \ - (rs6000_recip_bits[(int)(MODE)] & RS6000_RECIP_MASK_HAVE_RE) - -#define RS6000_RECIP_AUTO_RE_P(MODE) \ - (rs6000_recip_bits[(int)(MODE)] & RS6000_RECIP_MASK_AUTO_RE) - -#define RS6000_RECIP_HAVE_RSQRTE_P(MODE) \ - (rs6000_recip_bits[(int)(MODE)] & RS6000_RECIP_MASK_HAVE_RSQRTE) - -#define RS6000_RECIP_AUTO_RSQRTE_P(MODE) \ - (rs6000_recip_bits[(int)(MODE)] & RS6000_RECIP_MASK_AUTO_RSQRTE) - -#define RS6000_RECIP_HIGH_PRECISION_P(MODE) \ - ((MODE) == SFmode || (MODE) == V4SFmode || TARGET_RECIP_PRECISION) - -/* The default CPU for TARGET_OPTION_OVERRIDE. */ -#define OPTION_TARGET_CPU_DEFAULT TARGET_CPU_DEFAULT - -/* Target pragma. */ -#define REGISTER_TARGET_PRAGMAS() do { \ - c_register_pragma (0, "longcall", rs6000_pragma_longcall); \ - targetm.target_option.pragma_parse = rs6000_pragma_target_parse; \ - targetm.resolve_overloaded_builtin = altivec_resolve_overloaded_builtin; \ - rs6000_target_modify_macros_ptr = rs6000_target_modify_macros; \ -} while (0) - -/* Target #defines. */ -#define TARGET_CPU_CPP_BUILTINS() \ - rs6000_cpu_cpp_builtins (pfile) - -/* This is used by rs6000_cpu_cpp_builtins to indicate the byte order - we're compiling for. Some configurations may need to override it. */ -#define RS6000_CPU_CPP_ENDIAN_BUILTINS() \ - do \ - { \ - if (BYTES_BIG_ENDIAN) \ - { \ - builtin_define ("__BIG_ENDIAN__"); \ - builtin_define ("_BIG_ENDIAN"); \ - builtin_assert ("machine=bigendian"); \ - } \ - else \ - { \ - builtin_define ("__LITTLE_ENDIAN__"); \ - builtin_define ("_LITTLE_ENDIAN"); \ - builtin_assert ("machine=littleendian"); \ - } \ - } \ - while (0) - -/* Target machine storage layout. */ - -/* Define this macro if it is advisable to hold scalars in registers - in a wider mode than that declared by the program. In such cases, - the value is constrained to be within the bounds of the declared - type, but kept valid in the wider mode. The signedness of the - extension may differ from that of the type. */ - -#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ - if (GET_MODE_CLASS (MODE) == MODE_INT \ - && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ - (MODE) = TARGET_32BIT ? SImode : DImode; - -/* Define this if most significant bit is lowest numbered - in instructions that operate on numbered bit-fields. */ -/* That is true on RS/6000. */ -#define BITS_BIG_ENDIAN 1 - -/* Define this if most significant byte of a word is the lowest numbered. */ -/* That is true on RS/6000. */ -#define BYTES_BIG_ENDIAN 1 - -/* Define this if most significant word of a multiword number is lowest - numbered. - - For RS/6000 we can decide arbitrarily since there are no machine - instructions for them. Might as well be consistent with bits and bytes. */ -#define WORDS_BIG_ENDIAN 1 - -#define MAX_BITS_PER_WORD 64 - -/* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8) -#ifdef IN_LIBGCC2 -#define MIN_UNITS_PER_WORD UNITS_PER_WORD -#else -#define MIN_UNITS_PER_WORD 4 -#endif -#define UNITS_PER_FP_WORD 8 -#define UNITS_PER_ALTIVEC_WORD 16 -#define UNITS_PER_VSX_WORD 16 -#define UNITS_PER_SPE_WORD 8 -#define UNITS_PER_PAIRED_WORD 8 - -/* Type used for ptrdiff_t, as a string used in a declaration. */ -#define PTRDIFF_TYPE "int" - -/* Type used for size_t, as a string used in a declaration. */ -#define SIZE_TYPE "long unsigned int" - -/* Type used for wchar_t, as a string used in a declaration. */ -#define WCHAR_TYPE "short unsigned int" - -/* Width of wchar_t in bits. */ -#define WCHAR_TYPE_SIZE 16 - -/* A C expression for the size in bits of the type `short' on the - target machine. If you don't define this, the default is half a - word. (If this would be less than one storage unit, it is - rounded up to one unit.) */ -#define SHORT_TYPE_SIZE 16 - -/* A C expression for the size in bits of the type `int' on the - target machine. If you don't define this, the default is one - word. */ -#define INT_TYPE_SIZE 32 - -/* A C expression for the size in bits of the type `long' on the - target machine. If you don't define this, the default is one - word. */ -#define LONG_TYPE_SIZE (TARGET_32BIT ? 32 : 64) - -/* A C expression for the size in bits of the type `long long' on the - target machine. If you don't define this, the default is two - words. */ -#define LONG_LONG_TYPE_SIZE 64 - -/* A C expression for the size in bits of the type `float' on the - target machine. If you don't define this, the default is one - word. */ -#define FLOAT_TYPE_SIZE 32 - -/* A C expression for the size in bits of the type `double' on the - target machine. If you don't define this, the default is two - words. */ -#define DOUBLE_TYPE_SIZE 64 - -/* A C expression for the size in bits of the type `long double' on - the target machine. If you don't define this, the default is two - words. */ -#define LONG_DOUBLE_TYPE_SIZE rs6000_long_double_type_size - -/* Define this to set long double type size to use in libgcc2.c, which can - not depend on target_flags. */ -#ifdef __LONG_DOUBLE_128__ -#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128 -#else -#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 -#endif - -/* Work around rs6000_long_double_type_size dependency in ada/targtyps.c. */ -#define WIDEST_HARDWARE_FP_SIZE 64 - -/* Width in bits of a pointer. - See also the macro `Pmode' defined below. */ -extern unsigned rs6000_pointer_size; -#define POINTER_SIZE rs6000_pointer_size - -/* Allocation boundary (in *bits*) for storing arguments in argument list. */ -#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64) - -/* Boundary (in *bits*) on which stack pointer should be aligned. */ -#define STACK_BOUNDARY \ - ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI && !TARGET_VSX) \ - ? 64 : 128) - -/* Allocation boundary (in *bits*) for the code of a function. */ -#define FUNCTION_BOUNDARY 32 - -/* No data type wants to be aligned rounder than this. */ -#define BIGGEST_ALIGNMENT 128 - -/* A C expression to compute the alignment for a variables in the - local store. TYPE is the data type, and ALIGN is the alignment - that the object would ordinarily have. */ -#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ - DATA_ALIGNMENT (TYPE, ALIGN) - -/* Alignment of field after `int : 0' in a structure. */ -#define EMPTY_FIELD_BOUNDARY 32 - -/* Every structure's size must be a multiple of this. */ -#define STRUCTURE_SIZE_BOUNDARY 8 - -/* A bit-field declared as `int' forces `int' alignment for the struct. */ -#define PCC_BITFIELD_TYPE_MATTERS 1 - -/* Make strings word-aligned so strcpy from constants will be faster. - Make vector constants quadword aligned. */ -#define CONSTANT_ALIGNMENT(EXP, ALIGN) \ - (TREE_CODE (EXP) == STRING_CST \ - && (STRICT_ALIGNMENT || !optimize_size) \ - && (ALIGN) < BITS_PER_WORD \ - ? BITS_PER_WORD \ - : (ALIGN)) - -/* Make arrays of chars word-aligned for the same reasons. - Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to - 64 bits. */ -#define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == VECTOR_TYPE \ - ? (((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) \ - || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) \ - ? 64 : 128) \ - : ((TARGET_E500_DOUBLE \ - && TREE_CODE (TYPE) == REAL_TYPE \ - && TYPE_MODE (TYPE) == DFmode) \ - ? 64 \ - : (TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))) - -/* Nonzero if move instructions will actually fail to work - when given unaligned data. */ -#define STRICT_ALIGNMENT 0 - -/* Define this macro to be the value 1 if unaligned accesses have a cost - many times greater than aligned accesses, for example if they are - emulated in a trap handler. */ -/* Altivec vector memory instructions simply ignore the low bits; SPE vector - memory instructions trap on unaligned accesses; VSX memory instructions are - aligned to 4 or 8 bytes. */ -#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \ - (STRICT_ALIGNMENT \ - || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \ - || (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode) \ - && (ALIGN) < 32) \ - || (VECTOR_MODE_P ((MODE)) && (((int)(ALIGN)) < VECTOR_ALIGN (MODE)))) - - -/* Standard register usage. */ - -/* Number of actual hardware registers. - The hardware registers are assigned numbers for the compiler - from 0 to just below FIRST_PSEUDO_REGISTER. - All registers that the compiler knows about must be given numbers, - even those that are not normally considered general registers. - - RS/6000 has 32 fixed-point registers, 32 floating-point registers, - a count register, a link register, and 8 condition 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 - register for AP that will later be eliminated in favor of SP or FP. - This is a normal register, but it is fixed. - - We also create a pseudo register for float/int conversions, that will - really represent the memory location used. It is represented here as - a register, in order to work around problems in allocating stack storage - in inline functions. - - Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame - pointer, which is eventually eliminated in favor of SP or FP. */ - -#define FIRST_PSEUDO_REGISTER 114 - -/* 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 - 1) + 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 - 1) : (r)) - -/* Use standard DWARF numbering for DWARF debugging information. */ -#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) - -/* Use gcc hard register numbering for eh_frame. */ -#define DWARF_FRAME_REGNUM(REGNO) (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)) - -/* 1 for registers that have pervasive standard uses - and are not available for the register allocator. - - On RS/6000, r1 is used for the stack. On Darwin, r2 is available - as a local register; for all other OS's r2 is the TOC pointer. - - cr5 is not supposed to be used. - - On System V implementations, r13 is fixed and not available for use. */ - -#define FIXED_REGISTERS \ - {0, 1, FIXED_R2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FIXED_R13, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, \ - /* AltiVec registers. */ \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1 \ - , 1, 1, 1 \ -} - -/* 1 for registers not available across function calls. - These must include the FIXED_REGISTERS and also any - registers that can be used without being saved. - The latter must include the registers where values are returned - and the register where structure-value addresses are passed. - Aside from that, you can include as many other registers as you like. */ - -#define CALL_USED_REGISTERS \ - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, FIXED_R13, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, \ - /* AltiVec registers. */ \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1 \ - , 1, 1, 1 \ -} - -/* Like `CALL_USED_REGISTERS' except this macro doesn't require that - the entire set of `FIXED_REGISTERS' be included. - (`CALL_USED_REGISTERS' must be a superset of `FIXED_REGISTERS'). - This macro is optional. If not specified, it defaults to the value - of `CALL_USED_REGISTERS'. */ - -#define CALL_REALLY_USED_REGISTERS \ - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, FIXED_R13, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, \ - /* AltiVec registers. */ \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0 \ - , 0, 0, 0 \ -} - -#define TOTAL_ALTIVEC_REGS (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1) - -#define FIRST_SAVED_ALTIVEC_REGNO (FIRST_ALTIVEC_REGNO+20) -#define FIRST_SAVED_FP_REGNO (14+32) -#define FIRST_SAVED_GP_REGNO (FIXED_R13 ? 14 : 13) - -/* List the order in which to allocate registers. Each register must be - listed once, even those in FIXED_REGISTERS. - - We allocate in the following order: - fp0 (not saved or used for anything) - fp13 - fp2 (not saved; incoming fp arg registers) - fp1 (not saved; return value) - fp31 - fp14 (saved; order given to save least number) - cr7, cr6 (not saved or special) - cr1 (not saved, but used for FP operations) - cr0 (not saved, but used for arithmetic operations) - cr4, cr3, cr2 (saved) - r9 (not saved; best for TImode) - r10, r8-r4 (not saved; highest first for less conflict with params) - r3 (not saved; return value register) - r11 (not saved; later alloc to help shrink-wrap) - r0 (not saved; cannot be base reg) - r31 - r13 (saved; order given to save least number) - r12 (not saved; if used for DImode or DFmode would use r13) - ctr (not saved; when we have the choice ctr is better) - lr (saved) - cr5, r1, r2, ap, ca (fixed) - v0 - v1 (not saved or used for anything) - v13 - v3 (not saved; incoming vector arg registers) - v2 (not saved; incoming vector arg reg; return value) - v19 - v14 (not saved or used for anything) - v31 - v20 (saved; order given to save least number) - vrsave, vscr (fixed) - spe_acc, spefscr (fixed) - sfp (fixed) -*/ - -#if FIXED_R2 == 1 -#define MAYBE_R2_AVAILABLE -#define MAYBE_R2_FIXED 2, -#else -#define MAYBE_R2_AVAILABLE 2, -#define MAYBE_R2_FIXED -#endif - -#if FIXED_R13 == 1 -#define EARLY_R12 12, -#define LATE_R12 -#else -#define EARLY_R12 -#define LATE_R12 12, -#endif - -#define REG_ALLOC_ORDER \ - {32, \ - 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, \ - 33, \ - 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, \ - MAYBE_R2_AVAILABLE \ - 9, 10, 8, 7, 6, 5, 4, \ - 3, EARLY_R12 11, 0, \ - 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \ - 18, 17, 16, 15, 14, 13, LATE_R12 \ - 66, 65, \ - 73, 1, MAYBE_R2_FIXED 67, 76, \ - /* AltiVec registers. */ \ - 77, 78, \ - 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \ - 79, \ - 96, 95, 94, 93, 92, 91, \ - 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, \ - 109, 110, \ - 111, 112, 113 \ -} - -/* True if register is floating-point. */ -#define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63) - -/* True if register is a condition register. */ -#define CR_REGNO_P(N) ((N) >= CR0_REGNO && (N) <= CR7_REGNO) - -/* True if register is a condition register, but not cr0. */ -#define CR_REGNO_NOT_CR0_P(N) ((N) >= CR1_REGNO && (N) <= CR7_REGNO) - -/* True if register is an integer register. */ -#define INT_REGNO_P(N) \ - ((N) <= 31 || (N) == ARG_POINTER_REGNUM || (N) == FRAME_POINTER_REGNUM) - -/* SPE SIMD registers are just the GPRs. */ -#define SPE_SIMD_REGNO_P(N) ((N) <= 31) - -/* PAIRED SIMD registers are just the FPRs. */ -#define PAIRED_SIMD_REGNO_P(N) ((N) >= 32 && (N) <= 63) - -/* True if register is the CA register. */ -#define CA_REGNO_P(N) ((N) == CA_REGNO) - -/* True if register is an AltiVec register. */ -#define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO) - -/* True if register is a VSX register. */ -#define VSX_REGNO_P(N) (FP_REGNO_P (N) || ALTIVEC_REGNO_P (N)) - -/* Alternate name for any vector register supporting floating point, no matter - which instruction set(s) are available. */ -#define VFLOAT_REGNO_P(N) \ - (ALTIVEC_REGNO_P (N) || (TARGET_VSX && FP_REGNO_P (N))) - -/* Alternate name for any vector register supporting integer, no matter which - instruction set(s) are available. */ -#define VINT_REGNO_P(N) ALTIVEC_REGNO_P (N) - -/* Alternate name for any vector register supporting logical operations, no - matter which instruction set(s) are available. */ -#define VLOGICAL_REGNO_P(N) VFLOAT_REGNO_P (N) - -/* Return number of consecutive hard regs needed starting at reg REGNO - to hold something of mode MODE. */ - -#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)] - -/* When setting up caller-save slots (MODE == VOIDmode) ensure we allocate - enough space to account for vectors in FP regs. However, TFmode/TDmode - should not use VSX instructions to do a caller save. */ -#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ - (TARGET_VSX \ - && ((MODE) == VOIDmode || ALTIVEC_OR_VSX_VECTOR_MODE (MODE)) \ - && FP_REGNO_P (REGNO) \ - ? V2DFmode \ - : ((MODE) == TFmode && FP_REGNO_P (REGNO)) \ - ? DFmode \ - : ((MODE) == TDmode && FP_REGNO_P (REGNO)) \ - ? DImode \ - : choose_hard_reg_mode ((REGNO), (NREGS), false)) - -#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ - (((TARGET_32BIT && TARGET_POWERPC64 \ - && (GET_MODE_SIZE (MODE) > 4) \ - && INT_REGNO_P (REGNO)) ? 1 : 0) \ - || (TARGET_VSX && FP_REGNO_P (REGNO) \ - && GET_MODE_SIZE (MODE) > 8 && ((MODE) != TDmode) \ - && ((MODE) != TFmode))) - -#define VSX_VECTOR_MODE(MODE) \ - ((MODE) == V4SFmode \ - || (MODE) == V2DFmode) \ - -#define ALTIVEC_VECTOR_MODE(MODE) \ - ((MODE) == V16QImode \ - || (MODE) == V8HImode \ - || (MODE) == V4SFmode \ - || (MODE) == V4SImode) - -#define ALTIVEC_OR_VSX_VECTOR_MODE(MODE) \ - (ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE) \ - || (MODE) == V2DImode) - -#define SPE_VECTOR_MODE(MODE) \ - ((MODE) == V4HImode \ - || (MODE) == V2SFmode \ - || (MODE) == V1DImode \ - || (MODE) == V2SImode) - -#define PAIRED_VECTOR_MODE(MODE) \ - ((MODE) == V2SFmode) - -/* Value is TRUE if hard register REGNO can hold a value of - machine-mode MODE. */ -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - rs6000_hard_regno_mode_ok_p[(int)(MODE)][REGNO] - -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - (SCALAR_FLOAT_MODE_P (MODE1) \ - ? SCALAR_FLOAT_MODE_P (MODE2) \ - : SCALAR_FLOAT_MODE_P (MODE2) \ - ? SCALAR_FLOAT_MODE_P (MODE1) \ - : GET_MODE_CLASS (MODE1) == MODE_CC \ - ? 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) \ - : ALTIVEC_OR_VSX_VECTOR_MODE (MODE1) \ - ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \ - : ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \ - ? ALTIVEC_OR_VSX_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) || df_regs_ever_live_p (DST)) - -/* Specify the cost of a branch insn; roughly the number of extra insns that - should be added to avoid a branch. - - Set this to 3 on the RS/6000 since that is roughly the average cost of an - unscheduled conditional branch. */ - -#define BRANCH_COST(speed_p, predictable_p) 3 - -/* Override BRANCH_COST heuristic which empirically produces worse - performance for removing short circuiting from the logical ops. */ - -#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 - -/* A fixed register used at epilogue generation to address SPE registers - with negative offsets. The 64-bit load/store instructions on the SPE - only take positive offsets (and small ones at that), so we need to - reserve a register for consing up negative offsets. */ - -#define FIXED_SCRATCH 0 - -/* Specify the registers used for certain standard purposes. - The values of these macros are register numbers. */ - -/* RS/6000 pc isn't overloaded on a register that the compiler knows about. */ -/* #define PC_REGNUM */ - -/* Register to use for pushing function arguments. */ -#define STACK_POINTER_REGNUM 1 - -/* Base register for access to local variables of the function. */ -#define HARD_FRAME_POINTER_REGNUM 31 - -/* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 113 - -/* Base register for access to arguments of the function. */ -#define ARG_POINTER_REGNUM 67 - -/* Place to put static chain when calling a function that requires it. */ -#define STATIC_CHAIN_REGNUM 11 - - -/* Define the classes of registers for register constraints in the - machine description. Also define ranges of constants. - - One of the classes must always be named ALL_REGS and include all hard regs. - If there is more than one class, another class must be named NO_REGS - and contain no registers. - - The name GENERAL_REGS must be the name of a class (or an alias for - another name such as ALL_REGS). This is the class of registers - that is allowed by "g" or "r" in a register constraint. - Also, registers outside this class are allocated only when - instructions express preferences for them. - - The classes must be numbered in nondecreasing order; that is, - a larger-numbered class must never be contained completely - in a smaller-numbered class. - - For any two classes, it is very desirable that there be another - class that represents their union. */ - -/* The RS/6000 has three types of registers, fixed-point, floating-point, and - condition registers, plus three special registers, CTR, and the link - register. AltiVec adds a vector register class. VSX registers overlap the - FPR registers and the Altivec registers. - - However, r0 is special in that it cannot be used as a base register. - So make a class for registers valid as base registers. - - Also, cr0 is the only condition code register that can be used in - arithmetic insns, so make a separate class for it. */ - -enum reg_class -{ - NO_REGS, - BASE_REGS, - GENERAL_REGS, - FLOAT_REGS, - ALTIVEC_REGS, - VSX_REGS, - VRSAVE_REGS, - VSCR_REGS, - SPE_ACC_REGS, - SPEFSCR_REGS, - NON_SPECIAL_REGS, - LINK_REGS, - CTR_REGS, - LINK_OR_CTR_REGS, - SPECIAL_REGS, - SPEC_OR_GEN_REGS, - CR0_REGS, - CR_REGS, - NON_FLOAT_REGS, - CA_REGS, - ALL_REGS, - LIM_REG_CLASSES -}; - -#define N_REG_CLASSES (int) LIM_REG_CLASSES - -/* Give names of register classes as strings for dump file. */ - -#define REG_CLASS_NAMES \ -{ \ - "NO_REGS", \ - "BASE_REGS", \ - "GENERAL_REGS", \ - "FLOAT_REGS", \ - "ALTIVEC_REGS", \ - "VSX_REGS", \ - "VRSAVE_REGS", \ - "VSCR_REGS", \ - "SPE_ACC_REGS", \ - "SPEFSCR_REGS", \ - "NON_SPECIAL_REGS", \ - "LINK_REGS", \ - "CTR_REGS", \ - "LINK_OR_CTR_REGS", \ - "SPECIAL_REGS", \ - "SPEC_OR_GEN_REGS", \ - "CR0_REGS", \ - "CR_REGS", \ - "NON_FLOAT_REGS", \ - "CA_REGS", \ - "ALL_REGS" \ -} - -/* Define which registers fit in which classes. - This is an initializer for a vector of HARD_REG_SET - of length N_REG_CLASSES. */ - -#define REG_CLASS_CONTENTS \ -{ \ - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ - { 0xfffffffe, 0x00000000, 0x00000008, 0x00020000 }, /* BASE_REGS */ \ - { 0xffffffff, 0x00000000, 0x00000008, 0x00020000 }, /* GENERAL_REGS */ \ - { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \ - { 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */ \ - { 0x00000000, 0xffffffff, 0xffffe000, 0x00001fff }, /* VSX_REGS */ \ - { 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */ \ - { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */ \ - { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */ \ - { 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */ \ - { 0xffffffff, 0xffffffff, 0x00000008, 0x00020000 }, /* NON_SPECIAL_REGS */ \ - { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \ - { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */ \ - { 0x00000000, 0x00000000, 0x00000006, 0x00000000 }, /* LINK_OR_CTR_REGS */ \ - { 0x00000000, 0x00000000, 0x00000006, 0x00002000 }, /* SPECIAL_REGS */ \ - { 0xffffffff, 0x00000000, 0x0000000e, 0x00022000 }, /* SPEC_OR_GEN_REGS */ \ - { 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */ \ - { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \ - { 0xffffffff, 0x00000000, 0x00000ffe, 0x00020000 }, /* NON_FLOAT_REGS */ \ - { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* CA_REGS */ \ - { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0003ffff } /* ALL_REGS */ \ -} - -/* The same information, inverted: - Return the class number of the smallest class containing - reg number REGNO. This could be a conditional expression - or could index an array. */ - -extern enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER]; - -#if ENABLE_CHECKING -#define REGNO_REG_CLASS(REGNO) \ - (gcc_assert (IN_RANGE ((REGNO), 0, FIRST_PSEUDO_REGISTER-1)), \ - rs6000_regno_regclass[(REGNO)]) - -#else -#define REGNO_REG_CLASS(REGNO) rs6000_regno_regclass[(REGNO)] -#endif - -/* Register classes for various constraints that are based on the target - switches. */ -enum r6000_reg_class_enum { - RS6000_CONSTRAINT_d, /* fpr registers for double values */ - RS6000_CONSTRAINT_f, /* fpr registers for single values */ - RS6000_CONSTRAINT_v, /* Altivec registers */ - RS6000_CONSTRAINT_wa, /* Any VSX register */ - RS6000_CONSTRAINT_wd, /* VSX register for V2DF */ - RS6000_CONSTRAINT_wf, /* VSX register for V4SF */ - RS6000_CONSTRAINT_ws, /* VSX register for DF */ - RS6000_CONSTRAINT_MAX -}; - -extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; - -/* The class value for index registers, and the one for base regs. */ -#define INDEX_REG_CLASS GENERAL_REGS -#define BASE_REG_CLASS BASE_REGS - -/* Return whether a given register class can hold VSX objects. */ -#define VSX_REG_CLASS_P(CLASS) \ - ((CLASS) == VSX_REGS || (CLASS) == FLOAT_REGS || (CLASS) == ALTIVEC_REGS) - -/* 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 - in some cases it is preferable to use a more restrictive class. - - On the RS/6000, we have to return NO_REGS when we want to reload a - floating-point CONST_DOUBLE to force it to be copied to memory. - - We also don't want to reload integer values into floating-point - registers if we can at all help it. In fact, this can - cause reload to die, if it tries to generate a reload of CTR - into a FP register and discovers it doesn't have the memory location - required. - - ??? Would it be a good idea to have reload do the converse, that is - try to reload floating modes into FP registers if possible? - */ - -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - rs6000_preferred_reload_class_ptr (X, CLASS) - -/* 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) \ - rs6000_secondary_reload_class_ptr (CLASS, MODE, IN) - -/* If we are copying between FP or AltiVec registers and anything - else, we need a memory location. The exception is when we are - targeting ppc64 and the move to/from fpr to gpr instructions - are available.*/ - -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - rs6000_secondary_memory_needed_ptr (CLASS1, CLASS2, MODE) - -/* For cpus that cannot load/store SDmode values from the 64-bit - FP registers without using a full 64-bit load/store, we need - to allocate a full 64-bit stack slot for them. */ - -#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \ - rs6000_secondary_memory_needed_rtx (MODE) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. - - On RS/6000, this is the size of MODE in words, except in the FP regs, where - a single reg is enough for two words, unless we have VSX, where the FP - registers can hold 128 bits. */ -#define CLASS_MAX_NREGS(CLASS, MODE) rs6000_class_max_nregs[(MODE)][(CLASS)] - -/* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */ - -#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ - rs6000_cannot_change_mode_class_ptr (FROM, TO, CLASS) - -/* Stack layout; function entry, exit and calling. */ - -/* 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 to nonzero 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 - goes at a more negative offset in the frame. - - On the RS/6000, we grow upwards, from the area after the outgoing - arguments. */ -#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0 || flag_asan != 0) - -/* Size of the outgoing register save area */ -#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \ - || 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_DARWIN) ? 24 : 8) \ - << (TARGET_64BIT ? 1 : 0)) - -/* MEM representing address to save the TOC register */ -#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \ - plus_constant (Pmode, stack_pointer_rtx, \ - (TARGET_32BIT ? 20 : 40))) - -/* Align an address */ -#define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1)) - -/* Offset within stack frame to start allocating local variables at. - If FRAME_GROWS_DOWNWARD, this is the offset to the END of the - first local allocated. Otherwise, it is the offset to the BEGINNING - of the first local allocated. - - On the RS/6000, the frame pointer is the same as the stack pointer, - except for dynamic allocations. So we start after the fixed area and - outgoing parameter area. */ - -#define STARTING_FRAME_OFFSET \ - (FRAME_GROWS_DOWNWARD \ - ? 0 \ - : (RS6000_ALIGN (crtl->outgoing_args_size, \ - (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \ - + RS6000_SAVE_AREA)) - -/* Offset from the stack pointer register to an item dynamically - allocated on the stack, e.g., by `alloca'. - - The default value for this macro is `STACK_POINTER_OFFSET' plus the - length of the outgoing arguments. The default is correct for most - machines. See `function.c' for details. */ -#define STACK_DYNAMIC_OFFSET(FUNDECL) \ - (RS6000_ALIGN (crtl->outgoing_args_size, \ - (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \ - + (STACK_POINTER_OFFSET)) - -/* If we generate an insn to push BYTES bytes, - this says how many the stack pointer really advances by. - On RS/6000, don't define this because there are no push insns. */ -/* #define PUSH_ROUNDING(BYTES) */ - -/* Offset of first parameter from the argument pointer register value. - On the RS/6000, we define the argument pointer to the start of the fixed - area. */ -#define FIRST_PARM_OFFSET(FNDECL) RS6000_SAVE_AREA - -/* Offset from the argument pointer register value to the top of - stack. This is different from FIRST_PARM_OFFSET because of the - register save area. */ -#define ARG_POINTER_CFA_OFFSET(FNDECL) 0 - -/* Define this if stack space is still allocated for a parameter passed - in a register. The value is the number of bytes allocated to this - area. */ -#define REG_PARM_STACK_SPACE(FNDECL) RS6000_REG_SAVE - -/* Define this if the above stack space is to be considered part of the - space allocated by the caller. */ -#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 - -/* This is the difference between the logical top of stack and the actual sp. - - For the RS/6000, sp points past the fixed area. */ -#define STACK_POINTER_OFFSET RS6000_SAVE_AREA - -/* Define this if the maximum size of all the outgoing args is to be - accumulated and pushed during the prologue. The amount can be - found in the variable crtl->outgoing_args_size. */ -#define ACCUMULATE_OUTGOING_ARGS 1 - -/* Define how to find the value returned by a library function - assuming the value has mode MODE. */ - -#define LIBCALL_VALUE(MODE) rs6000_libcall_value ((MODE)) - -/* DRAFT_V4_STRUCT_RET defaults off. */ -#define DRAFT_V4_STRUCT_RET 0 - -/* Let TARGET_RETURN_IN_MEMORY control what happens. */ -#define DEFAULT_PCC_STRUCT_RETURN 0 - -/* Mode of stack savearea. - FUNCTION is VOIDmode because calling convention maintains SP. - BLOCK needs Pmode for SP. - NONLOCAL needs twice Pmode to maintain both backchain and SP. */ -#define STACK_SAVEAREA_MODE(LEVEL) \ - (LEVEL == SAVE_FUNCTION ? VOIDmode \ - : LEVEL == SAVE_NONLOCAL ? (TARGET_32BIT ? DImode : TImode) : Pmode) - -/* Minimum and maximum general purpose registers used to hold arguments. */ -#define GP_ARG_MIN_REG 3 -#define GP_ARG_MAX_REG 10 -#define GP_ARG_NUM_REG (GP_ARG_MAX_REG - GP_ARG_MIN_REG + 1) - -/* Minimum and maximum floating point registers used to hold arguments. */ -#define FP_ARG_MIN_REG 33 -#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_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) - -/* Minimum and maximum AltiVec registers used to hold arguments. */ -#define ALTIVEC_ARG_MIN_REG (FIRST_ALTIVEC_REGNO + 2) -#define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11) -#define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1) - -/* Return registers */ -#define GP_ARG_RETURN GP_ARG_MIN_REG -#define FP_ARG_RETURN FP_ARG_MIN_REG -#define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2) - -/* Flags for the call/call_value rtl operations set up by function_arg */ -#define CALL_NORMAL 0x00000000 /* no special processing */ -/* Bits in 0x00000001 are unused. */ -#define CALL_V4_CLEAR_FP_ARGS 0x00000002 /* V.4, no FP args passed */ -#define CALL_V4_SET_FP_ARGS 0x00000004 /* V.4, FP args were passed */ -#define CALL_LONG 0x00000008 /* always call indirect */ -#define CALL_LIBCALL 0x00000010 /* libcall */ - -/* We don't have prologue and epilogue functions to save/restore - everything for most ABIs. */ -#define WORLD_SAVE_P(INFO) 0 - -/* 1 if N is a possible register number for a function value - as seen by the caller. - - On RS/6000, this is r3, fp1, and v2 (for AltiVec). */ -#define FUNCTION_VALUE_REGNO_P(N) \ - ((N) == GP_ARG_RETURN \ - || ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT && TARGET_FPRS) \ - || ((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. - On AltiVec, v2 - v13 are used for passing vectors. */ -#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_ABI) \ - || ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG \ - && TARGET_HARD_FLOAT && TARGET_FPRS)) - -/* Define a data type for recording info about an argument list - during the scan of that argument list. This data type should - hold all necessary information about the function itself - and about the args processed so far, enough to enable macros - such as FUNCTION_ARG to determine where the next arg should go. - - On the RS/6000, this is a structure. The first element is the number of - total argument words, the second is used to store the next - floating-point register number, and the third says how many more args we - have prototype types for. - - For ABI_V4, we treat these slightly differently -- `sysv_gregno' is - 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 - be a multiple of sizeof(int). */ - -typedef struct rs6000_args -{ - int words; /* # words used for passing GP registers */ - int fregno; /* next available FP register */ - int vregno; /* next available AltiVec register */ - int nargs_prototype; /* # args left in the current 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 */ - int intoffset; /* running offset in struct (darwin64) */ - int use_stack; /* any part of struct on stack (darwin64) */ - int floats_in_gpr; /* count of SFmode floats taking up - GPR space (darwin64) */ - int named; /* false for varargs params */ - int escapes; /* if function visible outside tu */ -} CUMULATIVE_ARGS; - -/* 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, FNDECL, N_NAMED_ARGS) \ - init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE, \ - N_NAMED_ARGS, FNDECL, VOIDmode) - -/* 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, \ - 1000, current_function_decl, VOIDmode) - -/* 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, \ - 0, NULL_TREE, MODE) - -/* If defined, a C expression which determines whether, and in which - direction, to pad out an argument with extra space. The value - should be of type `enum direction': either `upward' to pad above - the argument, `downward' to pad below, or `none' to inhibit - padding. */ - -#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding (MODE, TYPE) - -#define PAD_VARARGS_DOWN \ - (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward) - -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - output_function_profiler ((FILE), (LABELNO)); - -/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, - the stack pointer does not matter. No definition is equivalent to - always zero. - - On the RS/6000, this is nonzero because we can restore the stack from - its backpointer, which we maintain. */ -#define EXIT_IGNORE_STACK 1 - -/* Define this macro as a C expression that is nonzero for registers - that are used by the epilogue or the return' pattern. The stack - and frame pointer registers are already be assumed to be used as - needed. */ - -#define EPILOGUE_USES(REGNO) \ - ((reload_completed && (REGNO) == LR_REGNO) \ - || (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO) \ - || (crtl->calls_eh_return \ - && TARGET_AIX \ - && (REGNO) == 2)) - - -/* Length in units of the trampoline for entering a nested function. */ - -#define TRAMPOLINE_SIZE rs6000_trampoline_size () - -/* Definitions for __builtin_return_address and __builtin_frame_address. - __builtin_return_address (0) should give link register (65), enable - this. */ -/* This should be uncommented, so that the link register is used, but - currently this would result in unmatched insns and spilling fixed - registers so we'll leave it for another day. When these problems are - taken care of one additional fetch will be necessary in RETURN_ADDR_RTX. - (mrs) */ -/* #define RETURN_ADDR_IN_PREVIOUS_FRAME */ - -/* Number of bytes into the frame return addresses can be found. See - rs6000_stack_info in rs6000.c for more information on how the different - abi's store the return address. */ -#define RETURN_ADDRESS_OFFSET \ - ((DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_DARWIN) ? (TARGET_32BIT ? 8 : 16) : \ - (DEFAULT_ABI == ABI_V4) ? 4 : \ - (internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0)) - -/* The current return address is in link register (65). The return address - of anything farther back is accessed normally at an offset of 8 from the - frame pointer. */ -#define RETURN_ADDR_RTX(COUNT, FRAME) \ - (rs6000_return_addr (COUNT, FRAME)) - - -/* Definitions for register eliminations. - - We have two registers that can be eliminated on the RS/6000. First, the - frame pointer register can often be eliminated in favor of the stack - pointer register. Secondly, the argument pointer register can always be - eliminated; it is replaced with either the stack or frame pointer. - - In addition, we use the elimination mechanism to see if r30 is needed - Initially we assume that it isn't. If it is, we spill it. This is done - by making it an eliminable register. We replace it with itself so that - if it isn't needed, then existing uses won't be modified. */ - -/* This is an array of structures. Each structure initializes one pair - of eliminable registers. The "from" register number is given first, - followed by "to". Eliminations of the same "from" register are listed - in order of preference. */ -#define ELIMINABLE_REGS \ -{{ HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ - { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ - { RS6000_PIC_OFFSET_TABLE_REGNUM, RS6000_PIC_OFFSET_TABLE_REGNUM } } - -/* 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) \ - ((OFFSET) = rs6000_initial_elimination_offset(FROM, TO)) - -/* Addressing modes, and classification of registers for them. */ - -#define HAVE_PRE_DECREMENT 1 -#define HAVE_PRE_INCREMENT 1 -#define HAVE_PRE_MODIFY_DISP 1 -#define HAVE_PRE_MODIFY_REG 1 - -/* Macros to check register numbers against specific register classes. */ - -/* These assume that REGNO is a hard or pseudo reg number. - They give nonzero only if REGNO is a hard reg of the suitable class - or a pseudo reg currently allocated to a suitable hard reg. - Since they use reg_renumber, they are safe only once reg_renumber - has been allocated, which happens in reginfo.c during register - allocation. */ - -#define REGNO_OK_FOR_INDEX_P(REGNO) \ -((REGNO) < FIRST_PSEUDO_REGISTER \ - ? (REGNO) <= 31 || (REGNO) == 67 \ - || (REGNO) == FRAME_POINTER_REGNUM \ - : (reg_renumber[REGNO] >= 0 \ - && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67 \ - || reg_renumber[REGNO] == FRAME_POINTER_REGNUM))) - -#define REGNO_OK_FOR_BASE_P(REGNO) \ -((REGNO) < FIRST_PSEUDO_REGISTER \ - ? ((REGNO) > 0 && (REGNO) <= 31) || (REGNO) == 67 \ - || (REGNO) == FRAME_POINTER_REGNUM \ - : (reg_renumber[REGNO] > 0 \ - && (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67 \ - || reg_renumber[REGNO] == FRAME_POINTER_REGNUM))) - -/* Nonzero if X is a hard reg that can be used as an index - or if it is a pseudo reg in the non-strict case. */ -#define INT_REG_OK_FOR_INDEX_P(X, STRICT) \ - ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \ - || REGNO_OK_FOR_INDEX_P (REGNO (X))) - -/* Nonzero if X is a hard reg that can be used as a base reg - or if it is a pseudo reg in the non-strict case. */ -#define INT_REG_OK_FOR_BASE_P(X, STRICT) \ - ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \ - || REGNO_OK_FOR_BASE_P (REGNO (X))) - - -/* Maximum number of registers that can appear in a valid memory address. */ - -#define MAX_REGS_PER_ADDRESS 2 - -/* Recognize any constant value that is a valid address. */ - -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) - -#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15) -#define EASY_VECTOR_15_ADD_SELF(n) (!EASY_VECTOR_15((n)) \ - && EASY_VECTOR_15((n) >> 1) \ - && ((n) & 1) == 0) - -#define EASY_VECTOR_MSB(n,mode) \ - (((unsigned HOST_WIDE_INT)n) == \ - ((((unsigned HOST_WIDE_INT)GET_MODE_MASK (mode)) + 1) >> 1)) - - -/* Try a machine-dependent way of reloading an illegitimate address - operand. If we find one, push the reload and jump to WIN. This - macro is used in only one place: `find_reloads_address' in reload.c. - - Implemented on rs6000 by rs6000_legitimize_reload_address. - Note that (X) is evaluated twice; this is safe in current usage. */ - -#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ -do { \ - int win; \ - (X) = rs6000_legitimize_reload_address_ptr ((X), (MODE), (OPNUM), \ - (int)(TYPE), (IND_LEVELS), &win); \ - if ( win ) \ - goto WIN; \ -} while (0) - -#define FIND_BASE_TERM rs6000_find_base_term - -/* The register number of the register used to address a table of - static data addresses in memory. In some cases this register is - defined by a processor's "application binary interface" (ABI). - When this macro is defined, RTL is generated for this register - once, as with the stack pointer and frame pointer registers. If - this macro is not defined, it is up to the machine-dependent files - to allocate such a register (if necessary). */ - -#define RS6000_PIC_OFFSET_TABLE_REGNUM 30 -#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? RS6000_PIC_OFFSET_TABLE_REGNUM : INVALID_REGNUM) - -#define TOC_REGISTER (TARGET_MINIMAL_TOC ? RS6000_PIC_OFFSET_TABLE_REGNUM : 2) - -/* Define this macro if the register defined by - `PIC_OFFSET_TABLE_REGNUM' is clobbered by calls. Do not define - this macro if `PIC_OFFSET_TABLE_REGNUM' is not defined. */ - -/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */ - -/* A C expression that is nonzero if X is a legitimate immediate - operand on the target machine when generating position independent - code. You can assume that X satisfies `CONSTANT_P', so you need - not check this. You can also assume FLAG_PIC is true, so you need - not check it either. You need not define this macro if all - constants (including `SYMBOL_REF') can be immediate operands when - generating position independent code. */ - -/* #define LEGITIMATE_PIC_OPERAND_P (X) */ - -/* Define this if some processing needs to be done immediately before - emitting code for an insn. */ - -#define FINAL_PRESCAN_INSN(INSN,OPERANDS,NOPERANDS) \ - rs6000_final_prescan_insn (INSN, OPERANDS, NOPERANDS) - -/* Specify the machine mode that this machine uses - for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE SImode - -/* Define as C expression which evaluates to nonzero if the tablejump - instruction expects the table to contain offsets from the address of the - table. - Do not define this if the table should contain absolute addresses. */ -#define CASE_VECTOR_PC_RELATIVE 1 - -/* Define this as 1 if `char' should by default be signed; else as 0. */ -#define DEFAULT_SIGNED_CHAR 0 - -/* An integer expression for the size in bits of the largest integer machine - mode that should actually be used. */ - -/* Allow pairs of registers to be used, which is the intent of the default. */ -#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_POWERPC64 ? TImode : DImode) - -/* Max number of bytes we can move from memory to memory - in one reasonably fast instruction. */ -#define MOVE_MAX (! TARGET_POWERPC64 ? 4 : 8) -#define MAX_MOVE_MAX 8 - -/* Nonzero if access to memory by bytes is no faster than for words. - Also nonzero if doing byte operations (specifically shifts) in registers - is undesirable. */ -#define SLOW_BYTE_ACCESS 1 - -/* Define if operations between registers always perform the operation - on the full register even if a narrower mode is specified. */ -#define WORD_REGISTER_OPERATIONS - -/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD - will either zero-extend or sign-extend. The value of this macro should - be the code that says which one of the two operations is implicitly - done, UNKNOWN if none. */ -#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND - -/* Define if loading short immediate values into registers sign extends. */ -#define SHORT_IMMEDIATES_SIGN_EXTEND - -/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits - is done just by pretending it is already truncated. */ -#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 - -/* 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), 1) - -/* The CTZ patterns return -1 for input of zero. */ -#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 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. */ -extern unsigned rs6000_pmode; -#define Pmode ((enum machine_mode)rs6000_pmode) - -/* 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 SImode - -/* Define this if addresses of constant functions - shouldn't be put through pseudo regs where they can be cse'd. - Desirable on machines where ordinary constants are expensive - but a CALL with constant address is cheap. */ -#define NO_FUNCTION_CSE - -/* Define this to be nonzero if shift instructions ignore all but the low-order - few bits. - - The sle and sre instructions which allow SHIFT_COUNT_TRUNCATED - have been dropped from the PowerPC architecture. */ -#define SHIFT_COUNT_TRUNCATED 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 - to express in the length attribute. */ - -/* #define ADJUST_INSN_LENGTH(X,LENGTH) */ - -/* Given a comparison code (EQ, NE, etc.) and the first operand of a - COMPARE, return the mode to be used for the comparison. For - floating-point, CCFPmode should be used. CCUNSmode should be used - for unsigned comparisons. CCEQmode should be used when we are - doing an inequality comparison on the result of a - comparison. CCmode should be used in all other cases. */ - -#define SELECT_CC_MODE(OP,X,Y) \ - (SCALAR_FLOAT_MODE_P (GET_MODE (X)) ? CCFPmode \ - : (OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU ? CCUNSmode \ - : (((OP) == EQ || (OP) == NE) && COMPARISON_P (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) - - -/* Control the assembler format that we output. */ - -/* A C string constant describing how to begin a comment in the target - assembler language. The compiler assumes that the comment will end at - the end of the line. */ -#define ASM_COMMENT_START " #" - -/* Flag to say the TOC is initialized */ -extern int toc_initialized; - -/* Macro to output a special constant pool entry. Go to WIN if we output - it. Otherwise, it is written the usual way. - - On the RS/6000, toc entries are handled this way. */ - -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, X, MODE, ALIGN, LABELNO, WIN) \ -{ if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (X, MODE)) \ - { \ - output_toc (FILE, X, LABELNO, MODE); \ - goto WIN; \ - } \ -} - -#ifdef HAVE_GAS_WEAK -#define RS6000_WEAK 1 -#else -#define RS6000_WEAK 0 -#endif - -#if RS6000_WEAK -/* Used in lieu of ASM_WEAKEN_LABEL. */ -#define ASM_WEAKEN_DECL(FILE, DECL, NAME, VAL) \ - do \ - { \ - fputs ("\t.weak\t", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \ - && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \ - { \ - if (TARGET_XCOFF) \ - fputs ("[DS]", (FILE)); \ - fputs ("\n\t.weak\t.", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - } \ - fputc ('\n', (FILE)); \ - if (VAL) \ - { \ - ASM_OUTPUT_DEF ((FILE), (NAME), (VAL)); \ - if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \ - && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \ - { \ - fputs ("\t.set\t.", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - fputs (",.", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (VAL)); \ - fputc ('\n', (FILE)); \ - } \ - } \ - } \ - while (0) -#endif - -#if HAVE_GAS_WEAKREF -#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE) \ - do \ - { \ - fputs ("\t.weakref\t", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - fputs (", ", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (VALUE)); \ - if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \ - && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \ - { \ - fputs ("\n\t.weakref\t.", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - fputs (", .", (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (VALUE)); \ - } \ - fputc ('\n', (FILE)); \ - } while (0) -#endif - -/* This implements the `alias' attribute. */ -#undef ASM_OUTPUT_DEF_FROM_DECLS -#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \ - do \ - { \ - const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ - const char *name = IDENTIFIER_POINTER (TARGET); \ - if (TREE_CODE (DECL) == FUNCTION_DECL \ - && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \ - { \ - if (TREE_PUBLIC (DECL)) \ - { \ - if (!RS6000_WEAK || !DECL_WEAK (DECL)) \ - { \ - fputs ("\t.globl\t.", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, alias); \ - putc ('\n', FILE); \ - } \ - } \ - else if (TARGET_XCOFF) \ - { \ - fputs ("\t.lglobl\t.", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, alias); \ - putc ('\n', FILE); \ - } \ - fputs ("\t.set\t.", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, alias); \ - fputs (",.", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, name); \ - fputc ('\n', FILE); \ - } \ - ASM_OUTPUT_DEF (FILE, alias, name); \ - } \ - 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. */ - -#define ASM_APP_ON "" - -/* Output to assembler file text saying following lines - no longer contain unusual constructs. */ - -#define ASM_APP_OFF "" - -/* How to refer to registers in assembler output. - This sequence is indexed by compiler's hard-register-number (see above). */ - -extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ - -#define REGISTER_NAMES \ -{ \ - &rs6000_reg_names[ 0][0], /* r0 */ \ - &rs6000_reg_names[ 1][0], /* r1 */ \ - &rs6000_reg_names[ 2][0], /* r2 */ \ - &rs6000_reg_names[ 3][0], /* r3 */ \ - &rs6000_reg_names[ 4][0], /* r4 */ \ - &rs6000_reg_names[ 5][0], /* r5 */ \ - &rs6000_reg_names[ 6][0], /* r6 */ \ - &rs6000_reg_names[ 7][0], /* r7 */ \ - &rs6000_reg_names[ 8][0], /* r8 */ \ - &rs6000_reg_names[ 9][0], /* r9 */ \ - &rs6000_reg_names[10][0], /* r10 */ \ - &rs6000_reg_names[11][0], /* r11 */ \ - &rs6000_reg_names[12][0], /* r12 */ \ - &rs6000_reg_names[13][0], /* r13 */ \ - &rs6000_reg_names[14][0], /* r14 */ \ - &rs6000_reg_names[15][0], /* r15 */ \ - &rs6000_reg_names[16][0], /* r16 */ \ - &rs6000_reg_names[17][0], /* r17 */ \ - &rs6000_reg_names[18][0], /* r18 */ \ - &rs6000_reg_names[19][0], /* r19 */ \ - &rs6000_reg_names[20][0], /* r20 */ \ - &rs6000_reg_names[21][0], /* r21 */ \ - &rs6000_reg_names[22][0], /* r22 */ \ - &rs6000_reg_names[23][0], /* r23 */ \ - &rs6000_reg_names[24][0], /* r24 */ \ - &rs6000_reg_names[25][0], /* r25 */ \ - &rs6000_reg_names[26][0], /* r26 */ \ - &rs6000_reg_names[27][0], /* r27 */ \ - &rs6000_reg_names[28][0], /* r28 */ \ - &rs6000_reg_names[29][0], /* r29 */ \ - &rs6000_reg_names[30][0], /* r30 */ \ - &rs6000_reg_names[31][0], /* r31 */ \ - \ - &rs6000_reg_names[32][0], /* fr0 */ \ - &rs6000_reg_names[33][0], /* fr1 */ \ - &rs6000_reg_names[34][0], /* fr2 */ \ - &rs6000_reg_names[35][0], /* fr3 */ \ - &rs6000_reg_names[36][0], /* fr4 */ \ - &rs6000_reg_names[37][0], /* fr5 */ \ - &rs6000_reg_names[38][0], /* fr6 */ \ - &rs6000_reg_names[39][0], /* fr7 */ \ - &rs6000_reg_names[40][0], /* fr8 */ \ - &rs6000_reg_names[41][0], /* fr9 */ \ - &rs6000_reg_names[42][0], /* fr10 */ \ - &rs6000_reg_names[43][0], /* fr11 */ \ - &rs6000_reg_names[44][0], /* fr12 */ \ - &rs6000_reg_names[45][0], /* fr13 */ \ - &rs6000_reg_names[46][0], /* fr14 */ \ - &rs6000_reg_names[47][0], /* fr15 */ \ - &rs6000_reg_names[48][0], /* fr16 */ \ - &rs6000_reg_names[49][0], /* fr17 */ \ - &rs6000_reg_names[50][0], /* fr18 */ \ - &rs6000_reg_names[51][0], /* fr19 */ \ - &rs6000_reg_names[52][0], /* fr20 */ \ - &rs6000_reg_names[53][0], /* fr21 */ \ - &rs6000_reg_names[54][0], /* fr22 */ \ - &rs6000_reg_names[55][0], /* fr23 */ \ - &rs6000_reg_names[56][0], /* fr24 */ \ - &rs6000_reg_names[57][0], /* fr25 */ \ - &rs6000_reg_names[58][0], /* fr26 */ \ - &rs6000_reg_names[59][0], /* fr27 */ \ - &rs6000_reg_names[60][0], /* fr28 */ \ - &rs6000_reg_names[61][0], /* fr29 */ \ - &rs6000_reg_names[62][0], /* fr30 */ \ - &rs6000_reg_names[63][0], /* fr31 */ \ - \ - &rs6000_reg_names[64][0], /* was mq */ \ - &rs6000_reg_names[65][0], /* lr */ \ - &rs6000_reg_names[66][0], /* ctr */ \ - &rs6000_reg_names[67][0], /* ap */ \ - \ - &rs6000_reg_names[68][0], /* cr0 */ \ - &rs6000_reg_names[69][0], /* cr1 */ \ - &rs6000_reg_names[70][0], /* cr2 */ \ - &rs6000_reg_names[71][0], /* cr3 */ \ - &rs6000_reg_names[72][0], /* cr4 */ \ - &rs6000_reg_names[73][0], /* cr5 */ \ - &rs6000_reg_names[74][0], /* cr6 */ \ - &rs6000_reg_names[75][0], /* cr7 */ \ - \ - &rs6000_reg_names[76][0], /* ca */ \ - \ - &rs6000_reg_names[77][0], /* v0 */ \ - &rs6000_reg_names[78][0], /* v1 */ \ - &rs6000_reg_names[79][0], /* v2 */ \ - &rs6000_reg_names[80][0], /* v3 */ \ - &rs6000_reg_names[81][0], /* v4 */ \ - &rs6000_reg_names[82][0], /* v5 */ \ - &rs6000_reg_names[83][0], /* v6 */ \ - &rs6000_reg_names[84][0], /* v7 */ \ - &rs6000_reg_names[85][0], /* v8 */ \ - &rs6000_reg_names[86][0], /* v9 */ \ - &rs6000_reg_names[87][0], /* v10 */ \ - &rs6000_reg_names[88][0], /* v11 */ \ - &rs6000_reg_names[89][0], /* v12 */ \ - &rs6000_reg_names[90][0], /* v13 */ \ - &rs6000_reg_names[91][0], /* v14 */ \ - &rs6000_reg_names[92][0], /* v15 */ \ - &rs6000_reg_names[93][0], /* v16 */ \ - &rs6000_reg_names[94][0], /* v17 */ \ - &rs6000_reg_names[95][0], /* v18 */ \ - &rs6000_reg_names[96][0], /* v19 */ \ - &rs6000_reg_names[97][0], /* v20 */ \ - &rs6000_reg_names[98][0], /* v21 */ \ - &rs6000_reg_names[99][0], /* v22 */ \ - &rs6000_reg_names[100][0], /* v23 */ \ - &rs6000_reg_names[101][0], /* v24 */ \ - &rs6000_reg_names[102][0], /* v25 */ \ - &rs6000_reg_names[103][0], /* v26 */ \ - &rs6000_reg_names[104][0], /* v27 */ \ - &rs6000_reg_names[105][0], /* v28 */ \ - &rs6000_reg_names[106][0], /* v29 */ \ - &rs6000_reg_names[107][0], /* v30 */ \ - &rs6000_reg_names[108][0], /* v31 */ \ - &rs6000_reg_names[109][0], /* vrsave */ \ - &rs6000_reg_names[110][0], /* vscr */ \ - &rs6000_reg_names[111][0], /* spe_acc */ \ - &rs6000_reg_names[112][0], /* spefscr */ \ - &rs6000_reg_names[113][0], /* sfp */ \ -} - -/* Table of additional register names to use in user input. */ - -#define ADDITIONAL_REGISTER_NAMES \ - {{"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3}, \ - {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7}, \ - {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11}, \ - {"r12", 12}, {"r13", 13}, {"r14", 14}, {"r15", 15}, \ - {"r16", 16}, {"r17", 17}, {"r18", 18}, {"r19", 19}, \ - {"r20", 20}, {"r21", 21}, {"r22", 22}, {"r23", 23}, \ - {"r24", 24}, {"r25", 25}, {"r26", 26}, {"r27", 27}, \ - {"r28", 28}, {"r29", 29}, {"r30", 30}, {"r31", 31}, \ - {"fr0", 32}, {"fr1", 33}, {"fr2", 34}, {"fr3", 35}, \ - {"fr4", 36}, {"fr5", 37}, {"fr6", 38}, {"fr7", 39}, \ - {"fr8", 40}, {"fr9", 41}, {"fr10", 42}, {"fr11", 43}, \ - {"fr12", 44}, {"fr13", 45}, {"fr14", 46}, {"fr15", 47}, \ - {"fr16", 48}, {"fr17", 49}, {"fr18", 50}, {"fr19", 51}, \ - {"fr20", 52}, {"fr21", 53}, {"fr22", 54}, {"fr23", 55}, \ - {"fr24", 56}, {"fr25", 57}, {"fr26", 58}, {"fr27", 59}, \ - {"fr28", 60}, {"fr29", 61}, {"fr30", 62}, {"fr31", 63}, \ - {"v0", 77}, {"v1", 78}, {"v2", 79}, {"v3", 80}, \ - {"v4", 81}, {"v5", 82}, {"v6", 83}, {"v7", 84}, \ - {"v8", 85}, {"v9", 86}, {"v10", 87}, {"v11", 88}, \ - {"v12", 89}, {"v13", 90}, {"v14", 91}, {"v15", 92}, \ - {"v16", 93}, {"v17", 94}, {"v18", 95}, {"v19", 96}, \ - {"v20", 97}, {"v21", 98}, {"v22", 99}, {"v23", 100}, \ - {"v24", 101},{"v25", 102},{"v26", 103},{"v27", 104}, \ - {"v28", 105},{"v29", 106},{"v30", 107},{"v31", 108}, \ - {"vrsave", 109}, {"vscr", 110}, \ - {"spe_acc", 111}, {"spefscr", 112}, \ - /* no additional names for: lr, ctr, ap */ \ - {"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \ - {"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \ - {"cc", 68}, {"sp", 1}, {"toc", 2}, \ - /* CA is only part of XER, but we do not model the other parts (yet). */ \ - {"xer", 76}, \ - /* VSX registers overlaid on top of FR, Altivec registers */ \ - {"vs0", 32}, {"vs1", 33}, {"vs2", 34}, {"vs3", 35}, \ - {"vs4", 36}, {"vs5", 37}, {"vs6", 38}, {"vs7", 39}, \ - {"vs8", 40}, {"vs9", 41}, {"vs10", 42}, {"vs11", 43}, \ - {"vs12", 44}, {"vs13", 45}, {"vs14", 46}, {"vs15", 47}, \ - {"vs16", 48}, {"vs17", 49}, {"vs18", 50}, {"vs19", 51}, \ - {"vs20", 52}, {"vs21", 53}, {"vs22", 54}, {"vs23", 55}, \ - {"vs24", 56}, {"vs25", 57}, {"vs26", 58}, {"vs27", 59}, \ - {"vs28", 60}, {"vs29", 61}, {"vs30", 62}, {"vs31", 63}, \ - {"vs32", 77}, {"vs33", 78}, {"vs34", 79}, {"vs35", 80}, \ - {"vs36", 81}, {"vs37", 82}, {"vs38", 83}, {"vs39", 84}, \ - {"vs40", 85}, {"vs41", 86}, {"vs42", 87}, {"vs43", 88}, \ - {"vs44", 89}, {"vs45", 90}, {"vs46", 91}, {"vs47", 92}, \ - {"vs48", 93}, {"vs49", 94}, {"vs50", 95}, {"vs51", 96}, \ - {"vs52", 97}, {"vs53", 98}, {"vs54", 99}, {"vs55", 100}, \ - {"vs56", 101},{"vs57", 102},{"vs58", 103},{"vs59", 104}, \ - {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108} } - -/* This is how to output an element of a case-vector that is relative. */ - -#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ - do { char buf[100]; \ - fputs ("\t.long ", FILE); \ - ASM_GENERATE_INTERNAL_LABEL (buf, "L", VALUE); \ - assemble_name (FILE, buf); \ - putc ('-', FILE); \ - ASM_GENERATE_INTERNAL_LABEL (buf, "L", REL); \ - assemble_name (FILE, buf); \ - putc ('\n', FILE); \ - } while (0) - -/* This is how to output an assembler line - that says to advance the location counter - to a multiple of 2**LOG bytes. */ - -#define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) != 0) \ - fprintf (FILE, "\t.align %d\n", (LOG)) - -/* How to align the given loop. */ -#define LOOP_ALIGN(LABEL) rs6000_loop_align(LABEL) - -/* Pick up the return address upon entry to a procedure. Used for - dwarf2 unwind information. This also enables the table driven - mechanism. */ - -#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNO) -#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LR_REGNO) - -/* Describe how we implement __builtin_eh_return. */ -#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 3 : INVALID_REGNUM) -#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 10) - -/* Print operand X (an rtx) in assembler syntax to file FILE. - CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. - For `%' followed by punctuation, CODE is the punctuation and X is null. */ - -#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE) - -/* Define which CODE values are valid. */ - -#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '&') - -/* Print a memory address as an operand to reference that memory location. */ - -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) - -/* uncomment for disabling the corresponding default options */ -/* #define MACHINE_no_sched_interblock */ -/* #define MACHINE_no_sched_speculative */ -/* #define MACHINE_no_sched_speculative_load */ - -/* General flags. */ -extern int frame_pointer_needed; - -/* Classification of the builtin functions as to which switches enable the - builtin, and what attributes it should have. We used to use the target - flags macros, but we've run out of bits, so we now map the options into new - settings used here. */ - -/* Builtin attributes. */ -#define RS6000_BTC_SPECIAL 0x00000000 /* Special function. */ -#define RS6000_BTC_UNARY 0x00000001 /* normal unary function. */ -#define RS6000_BTC_BINARY 0x00000002 /* normal binary function. */ -#define RS6000_BTC_TERNARY 0x00000003 /* normal ternary function. */ -#define RS6000_BTC_PREDICATE 0x00000004 /* predicate function. */ -#define RS6000_BTC_ABS 0x00000005 /* Altivec/VSX ABS function. */ -#define RS6000_BTC_EVSEL 0x00000006 /* SPE EVSEL function. */ -#define RS6000_BTC_DST 0x00000007 /* Altivec DST function. */ -#define RS6000_BTC_TYPE_MASK 0x0000000f /* Mask to isolate types */ - -#define RS6000_BTC_MISC 0x00000000 /* No special attributes. */ -#define RS6000_BTC_CONST 0x00000100 /* uses no global state. */ -#define RS6000_BTC_PURE 0x00000200 /* reads global state/mem. */ -#define RS6000_BTC_FP 0x00000400 /* depends on rounding mode. */ -#define RS6000_BTC_ATTR_MASK 0x00000700 /* Mask of the attributes. */ - -/* Miscellaneous information. */ -#define RS6000_BTC_OVERLOADED 0x4000000 /* function is overloaded. */ - -/* Convenience macros to document the instruction type. */ -#define RS6000_BTC_MEM RS6000_BTC_MISC /* load/store touches mem. */ -#define RS6000_BTC_SAT RS6000_BTC_MISC /* saturate sets VSCR. */ - -/* Builtin targets. For now, we reuse the masks for those options that are in - target flags, and pick two random bits for SPE and paired which aren't in - target_flags. */ -#define RS6000_BTM_ALWAYS 0 /* Always enabled. */ -#define RS6000_BTM_ALTIVEC MASK_ALTIVEC /* VMX/altivec vectors. */ -#define RS6000_BTM_VSX MASK_VSX /* VSX (vector/scalar). */ -#define RS6000_BTM_SPE MASK_STRING /* E500 */ -#define RS6000_BTM_PAIRED MASK_MULHW /* 750CL paired insns. */ -#define RS6000_BTM_FRE MASK_POPCNTB /* FRE instruction. */ -#define RS6000_BTM_FRES MASK_PPC_GFXOPT /* FRES instruction. */ -#define RS6000_BTM_FRSQRTE MASK_PPC_GFXOPT /* FRSQRTE instruction. */ -#define RS6000_BTM_FRSQRTES MASK_POPCNTB /* FRSQRTES instruction. */ -#define RS6000_BTM_POPCNTD MASK_POPCNTD /* Target supports ISA 2.06. */ -#define RS6000_BTM_CELL MASK_FPRND /* Target is cell powerpc. */ - -#define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ - | RS6000_BTM_VSX \ - | RS6000_BTM_FRE \ - | RS6000_BTM_FRES \ - | RS6000_BTM_FRSQRTE \ - | RS6000_BTM_FRSQRTES \ - | RS6000_BTM_POPCNTD \ - | RS6000_BTM_CELL) - -/* Define builtin enum index. */ - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) ENUM, -#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) ENUM, - -enum rs6000_builtins -{ -#include "rs6000-builtin.def" - - RS6000_BUILTIN_COUNT -}; - -#undef RS6000_BUILTIN_1 -#undef RS6000_BUILTIN_2 -#undef RS6000_BUILTIN_3 -#undef RS6000_BUILTIN_A -#undef RS6000_BUILTIN_D -#undef RS6000_BUILTIN_E -#undef RS6000_BUILTIN_P -#undef RS6000_BUILTIN_Q -#undef RS6000_BUILTIN_S -#undef RS6000_BUILTIN_X - -enum rs6000_builtin_type_index -{ - RS6000_BTI_NOT_OPAQUE, - RS6000_BTI_opaque_V2SI, - RS6000_BTI_opaque_V2SF, - RS6000_BTI_opaque_p_V2SI, - RS6000_BTI_opaque_V4SI, - RS6000_BTI_V16QI, - RS6000_BTI_V2SI, - RS6000_BTI_V2SF, - RS6000_BTI_V2DI, - RS6000_BTI_V2DF, - RS6000_BTI_V4HI, - RS6000_BTI_V4SI, - RS6000_BTI_V4SF, - RS6000_BTI_V8HI, - RS6000_BTI_unsigned_V16QI, - RS6000_BTI_unsigned_V8HI, - RS6000_BTI_unsigned_V4SI, - RS6000_BTI_unsigned_V2DI, - RS6000_BTI_bool_char, /* __bool char */ - RS6000_BTI_bool_short, /* __bool short */ - RS6000_BTI_bool_int, /* __bool int */ - RS6000_BTI_bool_long, /* __bool long */ - RS6000_BTI_pixel, /* __pixel */ - RS6000_BTI_bool_V16QI, /* __vector __bool char */ - RS6000_BTI_bool_V8HI, /* __vector __bool short */ - RS6000_BTI_bool_V4SI, /* __vector __bool int */ - RS6000_BTI_bool_V2DI, /* __vector __bool long */ - RS6000_BTI_pixel_V8HI, /* __vector __pixel */ - RS6000_BTI_long, /* long_integer_type_node */ - RS6000_BTI_unsigned_long, /* long_unsigned_type_node */ - RS6000_BTI_long_long, /* long_long_integer_type_node */ - RS6000_BTI_unsigned_long_long, /* long_long_unsigned_type_node */ - RS6000_BTI_INTQI, /* intQI_type_node */ - RS6000_BTI_UINTQI, /* unsigned_intQI_type_node */ - RS6000_BTI_INTHI, /* intHI_type_node */ - RS6000_BTI_UINTHI, /* unsigned_intHI_type_node */ - RS6000_BTI_INTSI, /* intSI_type_node */ - RS6000_BTI_UINTSI, /* unsigned_intSI_type_node */ - RS6000_BTI_INTDI, /* intDI_type_node */ - RS6000_BTI_UINTDI, /* unsigned_intDI_type_node */ - RS6000_BTI_float, /* float_type_node */ - RS6000_BTI_double, /* double_type_node */ - RS6000_BTI_void, /* void_type_node */ - RS6000_BTI_MAX -}; - - -#define opaque_V2SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_V2SI]) -#define opaque_V2SF_type_node (rs6000_builtin_types[RS6000_BTI_opaque_V2SF]) -#define opaque_p_V2SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_p_V2SI]) -#define opaque_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_V4SI]) -#define V16QI_type_node (rs6000_builtin_types[RS6000_BTI_V16QI]) -#define V2DI_type_node (rs6000_builtin_types[RS6000_BTI_V2DI]) -#define V2DF_type_node (rs6000_builtin_types[RS6000_BTI_V2DF]) -#define V2SI_type_node (rs6000_builtin_types[RS6000_BTI_V2SI]) -#define V2SF_type_node (rs6000_builtin_types[RS6000_BTI_V2SF]) -#define V4HI_type_node (rs6000_builtin_types[RS6000_BTI_V4HI]) -#define V4SI_type_node (rs6000_builtin_types[RS6000_BTI_V4SI]) -#define V4SF_type_node (rs6000_builtin_types[RS6000_BTI_V4SF]) -#define V8HI_type_node (rs6000_builtin_types[RS6000_BTI_V8HI]) -#define unsigned_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI]) -#define unsigned_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V8HI]) -#define unsigned_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V4SI]) -#define unsigned_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V2DI]) -#define bool_char_type_node (rs6000_builtin_types[RS6000_BTI_bool_char]) -#define bool_short_type_node (rs6000_builtin_types[RS6000_BTI_bool_short]) -#define bool_int_type_node (rs6000_builtin_types[RS6000_BTI_bool_int]) -#define bool_long_type_node (rs6000_builtin_types[RS6000_BTI_bool_long]) -#define pixel_type_node (rs6000_builtin_types[RS6000_BTI_pixel]) -#define bool_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V16QI]) -#define bool_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V8HI]) -#define bool_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V4SI]) -#define bool_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V2DI]) -#define pixel_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_pixel_V8HI]) - -#define long_long_integer_type_internal_node (rs6000_builtin_types[RS6000_BTI_long_long]) -#define long_long_unsigned_type_internal_node (rs6000_builtin_types[RS6000_BTI_unsigned_long_long]) -#define long_integer_type_internal_node (rs6000_builtin_types[RS6000_BTI_long]) -#define long_unsigned_type_internal_node (rs6000_builtin_types[RS6000_BTI_unsigned_long]) -#define intQI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTQI]) -#define uintQI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTQI]) -#define intHI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTHI]) -#define uintHI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTHI]) -#define intSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTSI]) -#define uintSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTSI]) -#define intDI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTDI]) -#define uintDI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTDI]) -#define float_type_internal_node (rs6000_builtin_types[RS6000_BTI_float]) -#define double_type_internal_node (rs6000_builtin_types[RS6000_BTI_double]) -#define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void]) - -extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX]; -extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; - diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000.md b/gcc-4.8.1/gcc/config/rs6000/rs6000.md deleted file mode 100644 index a665fa50a..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000.md +++ /dev/null @@ -1,13988 +0,0 @@ -;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler -;; Copyright (C) 1990-2013 Free Software Foundation, Inc. -;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - -;; -;; REGNOS -;; - -(define_constants - [(STACK_POINTER_REGNUM 1) - (TOC_REGNUM 2) - (STATIC_CHAIN_REGNUM 11) - (HARD_FRAME_POINTER_REGNUM 31) - (LR_REGNO 65) - (CTR_REGNO 66) - (ARG_POINTER_REGNUM 67) - (CR0_REGNO 68) - (CR1_REGNO 69) - (CR2_REGNO 70) - (CR3_REGNO 71) - (CR4_REGNO 72) - (CR5_REGNO 73) - (CR6_REGNO 74) - (CR7_REGNO 75) - (MAX_CR_REGNO 75) - (CA_REGNO 76) - (FIRST_ALTIVEC_REGNO 77) - (LAST_ALTIVEC_REGNO 108) - (VRSAVE_REGNO 109) - (VSCR_REGNO 110) - (SPE_ACC_REGNO 111) - (SPEFSCR_REGNO 112) - (FRAME_POINTER_REGNUM 113) - - ; ABI defined stack offsets for storing the TOC pointer with AIX calls. - (TOC_SAVE_OFFSET_32BIT 20) - (TOC_SAVE_OFFSET_64BIT 40) - - ; Function TOC offset in the AIX function descriptor. - (AIX_FUNC_DESC_TOC_32BIT 4) - (AIX_FUNC_DESC_TOC_64BIT 8) - - ; Static chain offset in the AIX function descriptor. - (AIX_FUNC_DESC_SC_32BIT 8) - (AIX_FUNC_DESC_SC_64BIT 16) - ]) - -;; -;; UNSPEC usage -;; - -(define_c_enum "unspec" - [UNSPEC_FRSP ; frsp for POWER machines - UNSPEC_PROBE_STACK ; probe stack memory reference - UNSPEC_TOCPTR ; address of a word pointing to the TOC - UNSPEC_TOC ; address of the TOC (more-or-less) - UNSPEC_MOVSI_GOT - UNSPEC_MV_CR_OV ; move_from_CR_ov_bit - UNSPEC_FCTIWZ - UNSPEC_FRIM - UNSPEC_FRIN - UNSPEC_FRIP - UNSPEC_FRIZ - UNSPEC_LD_MPIC ; load_macho_picbase - UNSPEC_MPIC_CORRECT ; macho_correct_pic - UNSPEC_TLSGD - UNSPEC_TLSLD - UNSPEC_MOVESI_FROM_CR - UNSPEC_MOVESI_TO_CR - UNSPEC_TLSDTPREL - UNSPEC_TLSDTPRELHA - UNSPEC_TLSDTPRELLO - UNSPEC_TLSGOTDTPREL - UNSPEC_TLSTPREL - UNSPEC_TLSTPRELHA - UNSPEC_TLSTPRELLO - UNSPEC_TLSGOTTPREL - UNSPEC_TLSTLS - UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero - UNSPEC_MV_CR_GT ; move_from_CR_gt_bit - UNSPEC_STFIWX - UNSPEC_POPCNTB - UNSPEC_FRES - UNSPEC_SP_SET - UNSPEC_SP_TEST - UNSPEC_SYNC - UNSPEC_LWSYNC - UNSPEC_SYNC_OP - UNSPEC_ATOMIC - UNSPEC_CMPXCHG - UNSPEC_XCHG - UNSPEC_AND - UNSPEC_DLMZB - UNSPEC_DLMZB_CR - UNSPEC_DLMZB_STRLEN - UNSPEC_RSQRT - UNSPEC_TOCREL - UNSPEC_MACHOPIC_OFFSET - UNSPEC_BPERM - UNSPEC_COPYSIGN - UNSPEC_PARITY - UNSPEC_FCTIW - UNSPEC_FCTID - UNSPEC_LFIWAX - UNSPEC_LFIWZX - UNSPEC_FCTIWUZ - UNSPEC_GRP_END_NOP - ]) - -;; -;; UNSPEC_VOLATILE usage -;; - -(define_c_enum "unspecv" - [UNSPECV_BLOCK - UNSPECV_LL ; load-locked - UNSPECV_SC ; store-conditional - UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses - UNSPECV_EH_RR ; eh_reg_restore - UNSPECV_ISYNC ; isync instruction - UNSPECV_MFTB ; move from time base - ]) - - -;; Define an insn type attribute. This is used in function unit delay -;; computations. -(define_attr "type" "integer,two,three,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,var_delayed_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,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt" - (const_string "integer")) - -;; Define floating point instruction sub-types for use with Xfpu.md -(define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default")) - -;; Length (in bytes). -; '(pc)' in the following doesn't include the instruction itself; it is -; calculated as if the instruction had zero size. -(define_attr "length" "" - (if_then_else (eq_attr "type" "branch") - (if_then_else (and (ge (minus (match_dup 0) (pc)) - (const_int -32768)) - (lt (minus (match_dup 0) (pc)) - (const_int 32764))) - (const_int 4) - (const_int 8)) - (const_int 4))) - -;; Processor type -- this attribute must exactly match the processor_type -;; enumeration in rs6000.h. - -(define_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,power4,power5,power6,power7,cell,ppca2,titan" - (const (symbol_ref "rs6000_cpu_attr"))) - - -;; If this instruction is microcoded on the CELL processor -; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded -(define_attr "cell_micro" "not,conditional,always" - (if_then_else (eq_attr "type" "compare,delayed_compare,imul_compare,lmul_compare,load_ext,load_ext_ux,var_shift_rotate,var_delayed_compare") - (const_string "always") - (const_string "not"))) - -(automata_option "ndfa") - -(include "rs64.md") -(include "mpc.md") -(include "40x.md") -(include "440.md") -(include "476.md") -(include "601.md") -(include "603.md") -(include "6xx.md") -(include "7xx.md") -(include "7450.md") -(include "8540.md") -(include "e300c2c3.md") -(include "e500mc.md") -(include "e500mc64.md") -(include "e5500.md") -(include "e6500.md") -(include "power4.md") -(include "power5.md") -(include "power6.md") -(include "power7.md") -(include "cell.md") -(include "xfpu.md") -(include "a2.md") -(include "titan.md") - -(include "predicates.md") -(include "constraints.md") - -(include "darwin.md") - - -;; Mode iterators - -; This mode iterator allows :GPR to be used to indicate the allowable size -; of whole values in GPRs. -(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) - -; Any supported integer mode. -(define_mode_iterator INT [QI HI SI DI TI]) - -; Any supported integer mode that fits in one register. -(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) - -; extend modes for DImode -(define_mode_iterator QHSI [QI HI SI]) - -; SImode or DImode, even if DImode doesn't fit in GPRs. -(define_mode_iterator SDI [SI DI]) - -; The size of a pointer. Also, the size of the value that a record-condition -; (one with a '.') will compare; and the size used for arithmetic carries. -(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) - -; Any hardware-supported floating-point mode -(define_mode_iterator FP [ - (SF "TARGET_HARD_FLOAT - && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)") - (DF "TARGET_HARD_FLOAT - && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)") - (TF "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128") - (DD "TARGET_DFP") - (TD "TARGET_DFP")]) - -; Any fma capable floating-point mode. -(define_mode_iterator FMA_F [ - (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT") - (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) - || VECTOR_UNIT_VSX_P (DFmode)") - (V2SF "TARGET_PAIRED_FLOAT") - (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") - (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") - ]) - -; These modes do not fit in integer registers in 32-bit mode. -; but on e500v2, the gpr are 64 bit registers -(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD]) - -; Iterator for reciprocal estimate instructions -(define_mode_iterator RECIPF [SF DF V4SF V2DF]) - -; Iterator for just SF/DF -(define_mode_iterator SFDF [SF DF]) - -; Conditional returns. -(define_code_iterator any_return [return simple_return]) -(define_code_attr return_pred [(return "direct_return ()") - (simple_return "1")]) -(define_code_attr return_str [(return "") (simple_return "simple_")]) - -; Various instructions that come in SI and DI forms. -; A generic w/d attribute, for things like cmpw/cmpd. -(define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")]) - -; DImode bits -(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) - -;; ISEL/ISEL64 target selection -(define_mode_attr sel [(SI "") (DI "64")]) - -;; Suffix for reload patterns -(define_mode_attr ptrsize [(SI "32bit") - (DI "64bit")]) - -(define_mode_attr tptrsize [(SI "TARGET_32BIT") - (DI "TARGET_64BIT")]) - -(define_mode_attr mptrsize [(SI "si") - (DI "di")]) - -(define_mode_attr ptrload [(SI "lwz") - (DI "ld")]) - -(define_mode_attr ptrm [(SI "m") - (DI "Y")]) - -(define_mode_attr rreg [(SF "f") - (DF "ws") - (V4SF "wf") - (V2DF "wd")]) - -(define_mode_attr rreg2 [(SF "f") - (DF "d")]) - -(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") - (DF "TARGET_FCFID")]) - -(define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS") - (DF "TARGET_E500_DOUBLE")]) - -(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT") - (DF "TARGET_DOUBLE_FLOAT")]) - -;; Start with fixed-point load and store insns. Here we put only the more -;; complex forms. Basic data transfer is done later. - -(define_expand "zero_extend<mode>di2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "*zero_extend<mode>di2_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_operand:QHSI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64" - "@ - l<wd>z%U1%X1 %0,%1 - rldicl %0,%1,0,<dbits>" - [(set_attr "type" "load,*")]) - -(define_insn "*zero_extend<mode>di2_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 2 "=r,r"))] - "TARGET_64BIT" - "@ - rldicl. %2,%1,0,<dbits> - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (zero_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "*zero_extend<mode>di2_internal3" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI (match_dup 1)))] - "TARGET_64BIT" - "@ - rldicl. %0,%1,0,<dbits> - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "extendqidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64" - "extsb %0,%1" - [(set_attr "type" "exts")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (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_64BIT" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_dup 1)))] - "TARGET_64BIT" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendhidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "TARGET_POWERPC64 && rs6000_gen_cell_microcode" - "@ - lha%U1%X1 %0,%1 - extsh %0,%1" - [(set_attr "type" "load_ext,exts")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" - "extsh %0,%1" - [(set_attr "type" "exts")]) - -(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_64BIT" - "@ - extsh. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_dup 1)))] - "TARGET_64BIT" - "@ - extsh. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendsidi2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))] - "TARGET_POWERPC64 && rs6000_gen_cell_microcode" - "@ - lwa%U1%X1 %0,%1 - extsw %0,%1" - [(set_attr "type" "load_ext,exts")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r")))] - "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" - "extsw %0,%1" - [(set_attr "type" "exts")]) - -(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_64BIT" - "@ - extsw. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 2) - (sign_extend:DI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI (match_dup 1)))] - "TARGET_64BIT" - "@ - extsw. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (sign_extend:DI (match_dup 1)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (sign_extend:DI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] - "" - "@ - lbz%U1%X1 %0,%1 - rlwinm %0,%1,0,0xff" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - andi. %2,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_dup 1)))] - "" - "@ - andi. %0,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "" - "extsb %0,%1" - [(set_attr "type" "exts")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (sign_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (sign_extend:SI (match_dup 1)))] - "" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (sign_extend:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (sign_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r") - (zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] - "" - "@ - lbz%U1%X1 %0,%1 - rlwinm %0,%1,0,0xff" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:HI 2 "=r,r"))] - "" - "@ - andi. %2,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:HI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:HI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") - (zero_extend:HI (match_dup 1)))] - "" - "@ - andi. %0,%1,0xff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "") - (zero_extend:HI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:HI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "gpc_reg_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))] - "" - "extsb %0,%1" - [(set_attr "type" "exts")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:HI 2 "=r,r"))] - "" - "@ - extsb. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:HI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (sign_extend:HI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "=r,r") - (sign_extend:HI (match_dup 1)))] - "" - "@ - extsb. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:HI 0 "gpc_reg_operand" "") - (sign_extend:HI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (sign_extend:HI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "" - "@ - lhz%U1%X1 %0,%1 - rlwinm %0,%1,0,0xffff" - [(set_attr "type" "load,*")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - andi. %2,%1,0xffff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (zero_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (match_dup 1)))] - "" - "@ - andi. %0,%1,0xffff - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] - "rs6000_gen_cell_microcode" - "@ - lha%U1%X1 %0,%1 - extsh %0,%1" - [(set_attr "type" "load_ext,exts")]) - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r")))] - "!rs6000_gen_cell_microcode" - "extsh %0,%1" - [(set_attr "type" "exts")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 2 "=r,r"))] - "" - "@ - extsh. %2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 2 ""))] - "reload_completed" - [(set (match_dup 2) - (sign_extend:SI (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (sign_extend:SI (match_dup 1)))] - "" - "@ - extsh. %0,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (sign_extend:SI (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (sign_extend:SI (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; IBM 405, 440, 464 and 476 half-word multiplication operations. - -(define_insn "*macchwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_dup 2) - (const_int 16)) - (sign_extend:SI - (match_dup 1))) - (match_dup 4)))] - "TARGET_MULHW" - "macchw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*macchw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "macchw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*macchwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_dup 2) - (const_int 16)) - (zero_extend:SI - (match_dup 1))) - (match_dup 4)))] - "TARGET_MULHW" - "macchwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*macchwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "macchwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*machhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_dup 1) - (const_int 16)) - (ashiftrt:SI - (match_dup 2) - (const_int 16))) - (match_dup 4)))] - "TARGET_MULHW" - "machhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*machhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "machhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*machhwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_dup 1) - (const_int 16)) - (lshiftrt:SI - (match_dup 2) - (const_int 16))) - (match_dup 4)))] - "TARGET_MULHW" - "machhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*machhwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (lshiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "machhwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (sign_extend:SI - (match_dup 1)) - (sign_extend:SI - (match_dup 2))) - (match_dup 4)))] - "TARGET_MULHW" - "maclhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "maclhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (plus:SI (mult:SI (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (zero_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 4 "gpc_reg_operand" "0")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (zero_extend:SI - (match_dup 1)) - (zero_extend:SI - (match_dup 2))) - (match_dup 4)))] - "TARGET_MULHW" - "maclhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*maclhwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (mult:SI (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (zero_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (match_operand:SI 3 "gpc_reg_operand" "0")))] - "TARGET_MULHW" - "maclhwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmacchwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r")))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_dup 4) - (mult:SI (ashiftrt:SI - (match_dup 2) - (const_int 16)) - (sign_extend:SI - (match_dup 1)))))] - "TARGET_MULHW" - "nmacchw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmacchw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r")))))] - "TARGET_MULHW" - "nmacchw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmachhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_dup 4) - (mult:SI (ashiftrt:SI - (match_dup 1) - (const_int 16)) - (ashiftrt:SI - (match_dup 2) - (const_int 16)))))] - "TARGET_MULHW" - "nmachhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmachhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") - (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)))))] - "TARGET_MULHW" - "nmachhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmaclhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") - (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r")))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_dup 4) - (mult:SI (sign_extend:SI - (match_dup 1)) - (sign_extend:SI - (match_dup 2)))))] - "TARGET_MULHW" - "nmaclhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*nmaclhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") - (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r")))))] - "TARGET_MULHW" - "nmaclhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulchwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (ashiftrt:SI - (match_dup 2) - (const_int 16)) - (sign_extend:SI - (match_dup 1))))] - "TARGET_MULHW" - "mulchw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulchw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))))] - "TARGET_MULHW" - "mulchw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulchwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (lshiftrt:SI - (match_dup 2) - (const_int 16)) - (zero_extend:SI - (match_dup 1))))] - "TARGET_MULHW" - "mulchwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulchwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16)) - (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "r"))))] - "TARGET_MULHW" - "mulchwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulhhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (ashiftrt:SI - (match_dup 1) - (const_int 16)) - (ashiftrt:SI - (match_dup 2) - (const_int 16))))] - "TARGET_MULHW" - "mulhhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulhhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (ashiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (ashiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))))] - "TARGET_MULHW" - "mulhhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulhhwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (lshiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (lshiftrt:SI - (match_dup 1) - (const_int 16)) - (lshiftrt:SI - (match_dup 2) - (const_int 16))))] - "TARGET_MULHW" - "mulhhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mulhhwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (lshiftrt:SI - (match_operand:SI 1 "gpc_reg_operand" "%r") - (const_int 16)) - (lshiftrt:SI - (match_operand:SI 2 "gpc_reg_operand" "r") - (const_int 16))))] - "TARGET_MULHW" - "mulhhwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mullhwc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (sign_extend:SI - (match_dup 1)) - (sign_extend:SI - (match_dup 2))))] - "TARGET_MULHW" - "mullhw. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mullhw" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (sign_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (sign_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))))] - "TARGET_MULHW" - "mullhw %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mullhwuc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (compare:CC (mult:SI (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (zero_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (zero_extend:SI - (match_dup 1)) - (zero_extend:SI - (match_dup 2))))] - "TARGET_MULHW" - "mullhwu. %0,%1,%2" - [(set_attr "type" "imul3")]) - -(define_insn "*mullhwu" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mult:SI (zero_extend:SI - (match_operand:HI 1 "gpc_reg_operand" "%r")) - (zero_extend:SI - (match_operand:HI 2 "gpc_reg_operand" "r"))))] - "TARGET_MULHW" - "mullhwu %0,%1,%2" - [(set_attr "type" "imul3")]) - -;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support. -(define_insn "dlmzb" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] - UNSPEC_DLMZB_CR)) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec:SI [(match_dup 1) - (match_dup 2)] - UNSPEC_DLMZB))] - "TARGET_DLMZB" - "dlmzb. %0,%1,%2") - -(define_expand "strlensi" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (unspec:SI [(match_operand:BLK 1 "general_operand" "") - (match_operand:QI 2 "const_int_operand" "") - (match_operand 3 "const_int_operand" "")] - UNSPEC_DLMZB_STRLEN)) - (clobber (match_scratch:CC 4 "=x"))] - "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" -{ - rtx result = operands[0]; - rtx src = operands[1]; - rtx search_char = operands[2]; - rtx align = operands[3]; - rtx addr, scratch_string, word1, word2, scratch_dlmzb; - rtx loop_label, end_label, mem, cr0, cond; - if (search_char != const0_rtx - || GET_CODE (align) != CONST_INT - || INTVAL (align) < 8) - FAIL; - word1 = gen_reg_rtx (SImode); - word2 = gen_reg_rtx (SImode); - scratch_dlmzb = gen_reg_rtx (SImode); - scratch_string = gen_reg_rtx (Pmode); - loop_label = gen_label_rtx (); - end_label = gen_label_rtx (); - addr = force_reg (Pmode, XEXP (src, 0)); - emit_move_insn (scratch_string, addr); - emit_label (loop_label); - mem = change_address (src, SImode, scratch_string); - emit_move_insn (word1, mem); - emit_move_insn (word2, adjust_address (mem, SImode, 4)); - cr0 = gen_rtx_REG (CCmode, CR0_REGNO); - emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); - cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); - emit_jump_insn (gen_rtx_SET (VOIDmode, - pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, - cond, - gen_rtx_LABEL_REF - (VOIDmode, - end_label), - pc_rtx))); - emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); - emit_jump_insn (gen_rtx_SET (VOIDmode, - pc_rtx, - gen_rtx_LABEL_REF (VOIDmode, loop_label))); - emit_barrier (); - emit_label (end_label); - emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); - emit_insn (gen_subsi3 (result, scratch_string, addr)); - emit_insn (gen_subsi3 (result, result, const1_rtx)); - DONE; -}) - -;; Fixed-point arithmetic insns. - -(define_expand "add<mode>3" - [(set (match_operand:SDI 0 "gpc_reg_operand" "") - (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "") - (match_operand:SDI 2 "reg_or_add_cint_operand" "")))] - "" -{ - if (<MODE>mode == DImode && ! TARGET_POWERPC64) - { - if (non_short_cint_operand (operands[2], DImode)) - FAIL; - } - else if (GET_CODE (operands[2]) == CONST_INT - && ! add_operand (operands[2], <MODE>mode)) - { - rtx tmp = ((!can_create_pseudo_p () - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (<MODE>mode)); - - HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; - HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); - - if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest))) - FAIL; - - /* The ordering here is important for the prolog expander. - When space is allocated from the stack, adding 'low' first may - produce a temporary deallocation (which would be bad). */ - emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest))); - emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low))); - DONE; - } -}) - -;; Discourage ai/addic because of carry but provide it in an alternative -;; allowing register zero as source. -(define_insn "*add<mode>3_internal1" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,?r,r") - (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,r,b") - (match_operand:GPR 2 "add_operand" "r,I,I,L")))] - "!DECIMAL_FLOAT_MODE_P (GET_MODE (operands[0])) && !DECIMAL_FLOAT_MODE_P (GET_MODE (operands[1]))" - "@ - add %0,%1,%2 - addi %0,%1,%2 - addic %0,%1,%2 - addis %0,%1,%v2" - [(set_attr "length" "4,4,4,4")]) - -(define_insn "addsi3_high" - [(set (match_operand:SI 0 "gpc_reg_operand" "=b") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (high:SI (match_operand 2 "" ""))))] - "TARGET_MACHO && !TARGET_64BIT" - "addis %0,%1,ha16(%2)" - [(set_attr "length" "4")]) - -(define_insn "*add<mode>3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:P 2 "reg_or_short_operand" "r,I,r,I")) - (const_int 0))) - (clobber (match_scratch:P 3 "=r,r,r,r"))] - "" - "@ - add. %3,%1,%2 - addic. %3,%1,%2 - # - #" - [(set_attr "type" "fast_compare,compare,compare,compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "reg_or_short_operand" "")) - (const_int 0))) - (clobber (match_scratch:GPR 3 ""))] - "reload_completed" - [(set (match_dup 3) - (plus:GPR (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*add<mode>3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:P 2 "reg_or_short_operand" "r,I,r,I")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") - (plus:P (match_dup 1) - (match_dup 2)))] - "" - "@ - add. %0,%1,%2 - addic. %0,%1,%2 - # - #" - [(set_attr "type" "fast_compare,compare,compare,compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (plus:P (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (plus:P (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Split an add that we can't do in one insn into two insns, each of which -;; does one 16-bit part. This is used by combine. Note that the low-order -;; add should be last in case the result gets used in an address. - -(define_split - [(set (match_operand:GPR 0 "gpc_reg_operand" "") - (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "non_add_cint_operand" "")))] - "" - [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) - (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] -{ - HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; - HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); - - operands[4] = GEN_INT (low); - if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest))) - operands[3] = GEN_INT (rest); - else if (can_create_pseudo_p ()) - { - operands[3] = gen_reg_rtx (DImode); - emit_move_insn (operands[3], operands[2]); - emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); - DONE; - } - else - FAIL; -}) - -(define_insn "one_cmpl<mode>2" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] - "" - "nor %0,%1,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:P 2 "=r,r"))] - "" - "@ - nor. %2,%1,%1 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:P 2 ""))] - "reload_completed" - [(set (match_dup 2) - (not:P (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (not:P (match_dup 1)))] - "" - "@ - nor. %0,%1,%1 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (not:P (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (not:P (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") - (minus:GPR (match_operand:GPR 1 "reg_or_short_operand" "r,I") - (match_operand:GPR 2 "gpc_reg_operand" "r,r")))] - "" - "@ - subf %0,%2,%1 - subfic %0,%2,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:P 3 "=r,r"))] - "" - "@ - subf. %3,%2,%1 - #" - [(set_attr "type" "fast_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:P 3 ""))] - "reload_completed" - [(set (match_dup 3) - (minus:P (match_dup 1) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (minus:P (match_dup 1) - (match_dup 2)))] - "" - "@ - subf. %0,%2,%1 - #" - [(set_attr "type" "fast_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (minus:P (match_dup 1) - (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (minus:P (match_dup 1) - (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "sub<mode>3" - [(set (match_operand:SDI 0 "gpc_reg_operand" "") - (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "") - (match_operand:SDI 2 "reg_or_sub_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - emit_insn (gen_add<mode>3 (operands[0], operands[1], - negate_rtx (<MODE>mode, operands[2]))); - DONE; - } -}") - -(define_expand "neg<mode>2" - [(set (match_operand:SDI 0 "gpc_reg_operand" "") - (neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))] - "" - "") - -(define_insn "*neg<mode>2_internal" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] - "" - "neg %0,%1") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:P 2 "=r,r"))] - "" - "@ - neg. %2,%1 - #" - [(set_attr "type" "fast_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:P 2 ""))] - "reload_completed" - [(set (match_dup 2) - (neg:P (match_dup 1))) - (set (match_dup 0) - (compare:CC (match_dup 2) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") - (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (neg:P (match_dup 1)))] - "" - "@ - neg. %0,%1 - #" - [(set_attr "type" "fast_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "") - (compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (neg:P (match_dup 1)))] - "reload_completed" - [(set (match_dup 0) - (neg:P (match_dup 1))) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "clz<mode>2" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] - "" - "cntlz<wd> %0,%1" - [(set_attr "type" "cntlz")]) - -(define_expand "ctz<mode>2" - [(set (match_dup 2) - (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) - (parallel [(set (match_dup 3) (and:GPR (match_dup 1) - (match_dup 2))) - (clobber (scratch:CC))]) - (set (match_dup 4) (clz:GPR (match_dup 3))) - (set (match_operand:GPR 0 "gpc_reg_operand" "") - (minus:GPR (match_dup 5) (match_dup 4)))] - "" - { - operands[2] = gen_reg_rtx (<MODE>mode); - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); - operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1); - }) - -(define_expand "ffs<mode>2" - [(set (match_dup 2) - (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) - (parallel [(set (match_dup 3) (and:GPR (match_dup 1) - (match_dup 2))) - (clobber (scratch:CC))]) - (set (match_dup 4) (clz:GPR (match_dup 3))) - (set (match_operand:GPR 0 "gpc_reg_operand" "") - (minus:GPR (match_dup 5) (match_dup 4)))] - "" - { - operands[2] = gen_reg_rtx (<MODE>mode); - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); - operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); - }) - -(define_insn "popcntb<mode>2" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] - UNSPEC_POPCNTB))] - "TARGET_POPCNTB" - "popcntb %0,%1" - [(set_attr "length" "4") - (set_attr "type" "popcnt")]) - -(define_insn "popcntd<mode>2" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] - "TARGET_POPCNTD" - "popcnt<wd> %0,%1" - [(set_attr "length" "4") - (set_attr "type" "popcnt")]) - -(define_expand "popcount<mode>2" - [(set (match_operand:GPR 0 "gpc_reg_operand" "") - (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] - "TARGET_POPCNTB || TARGET_POPCNTD" - { - rs6000_emit_popcount (operands[0], operands[1]); - DONE; - }) - -(define_insn "parity<mode>2_cmpb" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))] - "TARGET_CMPB && TARGET_POPCNTB" - "prty<wd> %0,%1") - -(define_expand "parity<mode>2" - [(set (match_operand:GPR 0 "gpc_reg_operand" "") - (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] - "TARGET_POPCNTB" - { - rs6000_emit_parity (operands[0], operands[1]); - DONE; - }) - -;; Since the hardware zeros the upper part of the register, save generating the -;; AND immediate if we are converting to unsigned -(define_insn "*bswaphi2_extenddi" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] - "TARGET_POWERPC64" - "lhbrx %0,%y1" - [(set_attr "length" "4") - (set_attr "type" "load")]) - -(define_insn "*bswaphi2_extendsi" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] - "" - "lhbrx %0,%y1" - [(set_attr "length" "4") - (set_attr "type" "load")]) - -(define_expand "bswaphi2" - [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "") - (bswap:HI - (match_operand:HI 1 "reg_or_mem_operand" ""))) - (clobber (match_scratch:SI 2 ""))])] - "" -{ - if (!REG_P (operands[0]) && !REG_P (operands[1])) - operands[1] = force_reg (HImode, operands[1]); -}) - -(define_insn "bswaphi2_internal" - [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r") - (bswap:HI - (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r"))) - (clobber (match_scratch:SI 2 "=X,X,&r"))] - "" - "@ - lhbrx %0,%y1 - sthbrx %1,%y0 - #" - [(set_attr "length" "4,4,12") - (set_attr "type" "load,store,*")]) - -(define_split - [(set (match_operand:HI 0 "gpc_reg_operand" "") - (bswap:HI (match_operand:HI 1 "gpc_reg_operand" ""))) - (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] - "reload_completed" - [(set (match_dup 3) - (zero_extract:SI (match_dup 4) - (const_int 8) - (const_int 16))) - (set (match_dup 2) - (and:SI (ashift:SI (match_dup 4) - (const_int 8)) - (const_int 65280))) ;; 0xff00 - (set (match_dup 3) - (ior:SI (match_dup 3) - (match_dup 2)))] - " -{ - operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); - operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); -}") - -(define_insn "*bswapsi2_extenddi" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extend:DI - (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))] - "TARGET_POWERPC64" - "lwbrx %0,%y1" - [(set_attr "length" "4") - (set_attr "type" "load")]) - -(define_expand "bswapsi2" - [(set (match_operand:SI 0 "reg_or_mem_operand" "") - (bswap:SI - (match_operand:SI 1 "reg_or_mem_operand" "")))] - "" -{ - if (!REG_P (operands[0]) && !REG_P (operands[1])) - operands[1] = force_reg (SImode, operands[1]); -}) - -(define_insn "*bswapsi2_internal" - [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r") - (bswap:SI - (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))] - "" - "@ - lwbrx %0,%y1 - stwbrx %1,%y0 - #" - [(set_attr "length" "4,4,12") - (set_attr "type" "load,store,*")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))] - "reload_completed" - [(set (match_dup 0) - (rotate:SI (match_dup 1) (const_int 8))) - (set (zero_extract:SI (match_dup 0) - (const_int 8) - (const_int 0)) - (match_dup 1)) - (set (zero_extract:SI (match_dup 0) - (const_int 8) - (const_int 16)) - (rotate:SI (match_dup 1) - (const_int 16)))] - "") - -(define_expand "bswapdi2" - [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "") - (bswap:DI - (match_operand:DI 1 "reg_or_mem_operand" ""))) - (clobber (match_scratch:DI 2 "")) - (clobber (match_scratch:DI 3 "")) - (clobber (match_scratch:DI 4 ""))])] - "" -{ - if (!REG_P (operands[0]) && !REG_P (operands[1])) - operands[1] = force_reg (DImode, operands[1]); - - if (!TARGET_POWERPC64) - { - /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode - that uses 64-bit registers needs the same scratch registers as 64-bit - mode. */ - emit_insn (gen_bswapdi2_32bit (operands[0], operands[1])); - DONE; - } -}) - -;; Power7/cell has ldbrx/stdbrx, so use it directly -(define_insn "*bswapdi2_ldbrx" - [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r") - (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) - (clobber (match_scratch:DI 2 "=X,X,&r")) - (clobber (match_scratch:DI 3 "=X,X,&r")) - (clobber (match_scratch:DI 4 "=X,X,&r"))] - "TARGET_POWERPC64 && TARGET_LDBRX - && (REG_P (operands[0]) || REG_P (operands[1]))" - "@ - ldbrx %0,%y1 - stdbrx %1,%y0 - #" - [(set_attr "length" "4,4,36") - (set_attr "type" "load,store,*")]) - -;; Non-power7/cell, fall back to use lwbrx/stwbrx -(define_insn "*bswapdi2_64bit" - [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r") - (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) - (clobber (match_scratch:DI 2 "=&b,&b,&r")) - (clobber (match_scratch:DI 3 "=&r,&r,&r")) - (clobber (match_scratch:DI 4 "=&r,X,&r"))] - "TARGET_POWERPC64 && !TARGET_LDBRX - && (REG_P (operands[0]) || REG_P (operands[1]))" - "#" - [(set_attr "length" "16,12,36")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "")) - (clobber (match_operand:DI 3 "gpc_reg_operand" "")) - (clobber (match_operand:DI 4 "gpc_reg_operand" ""))] - "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" - [(const_int 0)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx op3 = operands[3]; - rtx op4 = operands[4]; - rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 4); - rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode, 4); - rtx addr1; - rtx addr2; - rtx word_high; - rtx word_low; - - addr1 = XEXP (src, 0); - if (GET_CODE (addr1) == PLUS) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); - if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); - addr2 = op2; - } - else - addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); - } - else if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); - addr2 = op2; - } - else - { - emit_move_insn (op2, GEN_INT (4)); - addr2 = gen_rtx_PLUS (Pmode, op2, addr1); - } - - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (src, SImode, addr1); - word_low = change_address (src, SImode, addr2); - } - else - { - word_high = change_address (src, SImode, addr2); - word_low = change_address (src, SImode, addr1); - } - - emit_insn (gen_bswapsi2 (op3_32, word_low)); - emit_insn (gen_bswapsi2 (op4_32, word_high)); - emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32))); - emit_insn (gen_iordi3 (dest, dest, op4)); -}") - -(define_split - [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") - (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "")) - (clobber (match_operand:DI 3 "gpc_reg_operand" "")) - (clobber (match_operand:DI 4 "" ""))] - "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" - [(const_int 0)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx op3 = operands[3]; - rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4); - rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4); - rtx addr1; - rtx addr2; - rtx word_high; - rtx word_low; - - addr1 = XEXP (dest, 0); - if (GET_CODE (addr1) == PLUS) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); - if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); - addr2 = op2; - } - else - addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); - } - else if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); - addr2 = op2; - } - else - { - emit_move_insn (op2, GEN_INT (4)); - addr2 = gen_rtx_PLUS (Pmode, op2, addr1); - } - - emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32))); - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (dest, SImode, addr1); - word_low = change_address (dest, SImode, addr2); - emit_insn (gen_bswapsi2 (word_high, src_si)); - emit_insn (gen_bswapsi2 (word_low, op3_si)); - } - else - { - word_high = change_address (dest, SImode, addr2); - word_low = change_address (dest, SImode, addr1); - emit_insn (gen_bswapsi2 (word_low, src_si)); - emit_insn (gen_bswapsi2 (word_high, op3_si)); - } -}") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "")) - (clobber (match_operand:DI 3 "gpc_reg_operand" "")) - (clobber (match_operand:DI 4 "" ""))] - "TARGET_POWERPC64 && reload_completed" - [(const_int 0)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx op3 = operands[3]; - rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, 4); - rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4); - rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, 4); - rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4); - - emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); - emit_insn (gen_bswapsi2 (dest_si, src_si)); - emit_insn (gen_bswapsi2 (op3_si, op2_si)); - emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); - emit_insn (gen_iordi3 (dest, dest, op3)); -}") - -(define_insn "bswapdi2_32bit" - [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r") - (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) - (clobber (match_scratch:SI 2 "=&b,&b,X"))] - "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" - "#" - [(set_attr "length" "16,12,36")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) - (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] - "!TARGET_POWERPC64 && reload_completed" - [(const_int 0)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx dest_hi = simplify_gen_subreg (SImode, dest, DImode, 0); - rtx dest_lo = simplify_gen_subreg (SImode, dest, DImode, 4); - rtx addr1; - rtx addr2; - rtx word_high; - rtx word_low; - - addr1 = XEXP (src, 0); - if (GET_CODE (addr1) == PLUS) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); - if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); - addr2 = op2; - } - else - addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); - } - else if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); - addr2 = op2; - } - else - { - emit_move_insn (op2, GEN_INT (4)); - addr2 = gen_rtx_PLUS (SImode, op2, addr1); - } - - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (src, SImode, addr1); - word_low = change_address (src, SImode, addr2); - } - else - { - word_high = change_address (src, SImode, addr2); - word_low = change_address (src, SImode, addr1); - } - - emit_insn (gen_bswapsi2 (dest_hi, word_low)); - emit_insn (gen_bswapsi2 (dest_lo, word_high)); -}") - -(define_split - [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") - (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) - (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] - "!TARGET_POWERPC64 && reload_completed" - [(const_int 0)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0); - rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4); - rtx addr1; - rtx addr2; - rtx word_high; - rtx word_low; - - addr1 = XEXP (dest, 0); - if (GET_CODE (addr1) == PLUS) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); - if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); - addr2 = op2; - } - else - addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); - } - else if (TARGET_AVOID_XFORM) - { - emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); - addr2 = op2; - } - else - { - emit_move_insn (op2, GEN_INT (4)); - addr2 = gen_rtx_PLUS (SImode, op2, addr1); - } - - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (dest, SImode, addr1); - word_low = change_address (dest, SImode, addr2); - } - else - { - word_high = change_address (dest, SImode, addr2); - word_low = change_address (dest, SImode, addr1); - } - - emit_insn (gen_bswapsi2 (word_high, src_low)); - emit_insn (gen_bswapsi2 (word_low, src_high)); -}") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) - (clobber (match_operand:SI 2 "" ""))] - "!TARGET_POWERPC64 && reload_completed" - [(const_int 0)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0); - rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4); - rtx dest_high = simplify_gen_subreg (SImode, dest, DImode, 0); - rtx dest_low = simplify_gen_subreg (SImode, dest, DImode, 4); - - emit_insn (gen_bswapsi2 (dest_high, src_low)); - emit_insn (gen_bswapsi2 (dest_low, src_high)); -}") - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "reg_or_short_operand" "r,I")))] - "" - "@ - mullw %0,%1,%2 - mulli %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 2 "s8bit_cint_operand" "") - (const_string "imul3") - (match_operand:SI 2 "short_cint_operand" "") - (const_string "imul2")] - (const_string "imul")))]) - -(define_insn "*mulsi3_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")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "" - "@ - mullw. %3,%1,%2 - #" - [(set_attr "type" "imul_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (mult:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*mulsi3_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")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (mult:SI (match_dup 1) (match_dup 2)))] - "" - "@ - mullw. %0,%1,%2 - #" - [(set_attr "type" "imul_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (mult:SI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (mult:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - - -(define_insn "udiv<mode>3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "gpc_reg_operand" "r")))] - "" - "div<wd>u %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 0 "" "") - (const_string "idiv")] - (const_string "ldiv")))]) - - -;; For powers of two we can do srai/aze for divide and then adjust for -;; modulus. If it isn't a power of two, force operands into register and do -;; a normal divide. -(define_expand "div<mode>3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "") - (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "reg_or_cint_operand" "")))] - "" -{ - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 0 - || exact_log2 (INTVAL (operands[2])) < 0) - operands[2] = force_reg (<MODE>mode, operands[2]); -}) - -(define_insn "*div<mode>3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "gpc_reg_operand" "r")))] - "" - "div<wd> %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 0 "" "") - (const_string "idiv")] - (const_string "ldiv")))]) - -(define_expand "mod<mode>3" - [(use (match_operand:GPR 0 "gpc_reg_operand" "")) - (use (match_operand:GPR 1 "gpc_reg_operand" "")) - (use (match_operand:GPR 2 "reg_or_cint_operand" ""))] - "" - " -{ - int i; - rtx temp1; - rtx temp2; - - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 0 - || (i = exact_log2 (INTVAL (operands[2]))) < 0) - FAIL; - - temp1 = gen_reg_rtx (<MODE>mode); - temp2 = gen_reg_rtx (<MODE>mode); - - emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); - emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i))); - emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); - DONE; -}") - -(define_insn "" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "exact_log2_cint_operand" "N")))] - "" - "sra<wd>i %0,%1,%p2\;addze %0,%0" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "exact_log2_cint_operand" "N,N")) - (const_int 0))) - (clobber (match_scratch:P 3 "=r,r"))] - "" - "@ - sra<wd>i %3,%1,%p2\;addze. %3,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12") - (set_attr "cell_micro" "not")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "exact_log2_cint_operand" - "")) - (const_int 0))) - (clobber (match_scratch:GPR 3 ""))] - "reload_completed" - [(set (match_dup 3) - (div:<MODE> (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "exact_log2_cint_operand" "N,N")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (div:P (match_dup 1) (match_dup 2)))] - "" - "@ - sra<wd>i %0,%1,%p2\;addze. %0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12") - (set_attr "cell_micro" "not")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "exact_log2_cint_operand" - "")) - (const_int 0))) - (set (match_operand:GPR 0 "gpc_reg_operand" "") - (div:GPR (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (div:<MODE> (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Logical instructions -;; The logical instructions are mostly combined by using match_operator, -;; but the plain AND insns are somewhat different because there is no -;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all -;; those rotate-and-mask operations. Thus, the AND insns come first. - -(define_expand "andsi3" - [(parallel - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "and_operand" ""))) - (clobber (match_scratch:CC 3 ""))])] - "" - "") - -(define_insn "andsi3_mc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:SI 2 "and_operand" "?r,T,K,L"))) - (clobber (match_scratch:CC 3 "=X,X,x,x"))] - "rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rlwinm %0,%1,0,%m2,%M2 - andi. %0,%1,%b2 - andis. %0,%1,%u2" - [(set_attr "type" "*,*,fast_compare,fast_compare")]) - -(define_insn "andsi3_nomc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "and_operand" "?r,T"))) - (clobber (match_scratch:CC 3 "=X,X"))] - "!rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rlwinm %0,%1,0,%m2,%M2") - -(define_insn "andsi3_internal0_nomc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "and_operand" "?r,T")))] - "!rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rlwinm %0,%1,0,%m2,%M2") - - -;; Note to set cr's other than cr0 we do the and immediate and then -;; the test again -- this avoids a mfcr which on the higher end -;; machines causes an execution serialization - -(define_insn "*andsi3_internal2_mc" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) - (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_32BIT && rs6000_gen_cell_microcode" - "@ - and. %3,%1,%2 - andi. %3,%1,%b2 - andis. %3,%1,%u2 - rlwinm. %3,%1,0,%m2,%M2 - # - # - # - #" - [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\ - compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) - -(define_insn "*andsi3_internal3_mc" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) - (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_64BIT && rs6000_gen_cell_microcode" - "@ - # - andi. %3,%1,%b2 - andis. %3,%1,%u2 - rlwinm. %3,%1,0,%m2,%M2 - # - # - # - #" - [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\ - compare,compare,compare") - (set_attr "length" "8,4,4,4,8,8,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "and_operand" "")) - (const_int 0))) - (clobber (match_scratch:GPR 3 "")) - (clobber (match_scratch:CC 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (and:<MODE> (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -;; We don't have a 32 bit "and. rt,ra,rb" for ppc64. cr is set from the -;; whole 64 bit reg, and we don't know what is in the high 32 bits. - -(define_split - [(set (match_operand:CC 0 "cc_reg_operand" "") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 "")) - (clobber (match_scratch:CC 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 3) - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*andsi3_internal4" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] - "TARGET_32BIT && rs6000_gen_cell_microcode" - "@ - and. %0,%1,%2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - rlwinm. %0,%1,0,%m2,%M2 - # - # - # - #" - [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\ - compare,compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) - -(define_insn "*andsi3_internal5_mc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" - "@ - # - andi. %0,%1,%b2 - andis. %0,%1,%u2 - rlwinm. %0,%1,0,%m2,%M2 - # - # - # - #" - [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\ - compare,compare,compare") - (set_attr "length" "8,4,4,4,8,8,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "and_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 0) - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 3 "cc_reg_operand" "") - (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(parallel [(set (match_dup 0) - (and:SI (match_dup 1) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Handle the PowerPC64 rlwinm corner case - -(define_insn_and_split "*andsi3_internal6" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "mask_operand_wrap" "i")))] - "TARGET_POWERPC64" - "#" - "TARGET_POWERPC64" - [(set (match_dup 0) - (and:SI (rotate:SI (match_dup 1) (match_dup 3)) - (match_dup 4))) - (set (match_dup 0) - (rotate:SI (match_dup 0) (match_dup 5)))] - " -{ - int mb = extract_MB (operands[2]); - int me = extract_ME (operands[2]); - operands[3] = GEN_INT (me + 1); - operands[5] = GEN_INT (32 - (me + 1)); - operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb))); -}" - [(set_attr "length" "8")]) - -(define_expand "iorsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_logical_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], SImode)) - { - HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((!can_create_pseudo_p () - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); - - emit_insn (gen_iorsi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_expand "xorsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (xor:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_logical_cint_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], SImode)) - { - HOST_WIDE_INT value = INTVAL (operands[2]); - rtx tmp = ((!can_create_pseudo_p () - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (SImode)); - - emit_insn (gen_xorsi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_insn "*boolsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (match_operator:SI 3 "boolean_or_operator" - [(match_operand:SI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:SI 2 "logical_operand" "r,K,L")]))] - "" - "@ - %q3 %0,%1,%2 - %q3i %0,%1,%b2 - %q3is %0,%1,%u2") - -(define_insn "*boolsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:SI 4 "boolean_or_operator" - [(match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")]) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_32BIT" - "@ - %q4. %3,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")]) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*boolsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(match_operand:SI 1 "gpc_reg_operand" "%r,r") - (match_operand:SI 2 "gpc_reg_operand" "r,r")]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_32BIT" - "@ - %q4. %0,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "gpc_reg_operand" "")]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; 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 - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (match_operator:SI 3 "boolean_or_operator" - [(match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "non_logical_cint_operand" "")]))] - "" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 0) (match_dup 5))] -" -{ - rtx i; - i = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, - operands[1], i); - i = GEN_INT (INTVAL (operands[2]) & 0xffff); - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, - operands[0], i); -}") - -(define_insn "*boolcsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (match_operator:SI 3 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (match_operand:SI 2 "gpc_reg_operand" "r")]))] - "" - "%q3 %0,%2,%1") - -(define_insn "*boolcsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (match_operand:SI 2 "gpc_reg_operand" "r,r")]) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_32BIT" - "@ - %q4. %3,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")]) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*boolcsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")) - (match_operand:SI 2 "gpc_reg_operand" "r,r")]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_32BIT" - "@ - %q4. %0,%2,%1 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (match_operand:SI 2 "gpc_reg_operand" "")]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*boolccsi3_internal1" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (match_operator:SI 3 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))]))] - "" - "%q3 %0,%1,%2") - -(define_insn "*boolccsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))]) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_32BIT" - "@ - %q4. %3,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))]) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*boolccsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_32BIT" - "@ - %q4. %0,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:SI 4 "boolean_operator" - [(not:SI (match_operand:SI 1 "gpc_reg_operand" "")) - (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))]) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Rotate and shift insns, in all their variants. These support shifts, -;; field inserts and extracts, and various combinations thereof. -(define_expand "insv" - [(set (zero_extract (match_operand 0 "gpc_reg_operand" "") - (match_operand:SI 1 "const_int_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand 3 "gpc_reg_operand" ""))] - "" - " -{ - /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since - the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the - compiler if the address of the structure is taken later. Likewise, do - not handle invalid E500 subregs. */ - if (GET_CODE (operands[0]) == SUBREG - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD - || ((TARGET_E500_DOUBLE || TARGET_SPE) - && invalid_e500_subreg (operands[0], GET_MODE (operands[0]))))) - FAIL; - - if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode) - emit_insn (gen_insvdi_internal (operands[0], operands[1], operands[2], - operands[3])); - else - emit_insn (gen_insvsi_internal (operands[0], operands[1], operands[2], - operands[3])); - DONE; -}") - -(define_insn "insvsi_internal" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "gpc_reg_operand" "r"))] - "" - "* -{ - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (32 - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"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") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" - "* -{ - int shift = INTVAL (operands[4]) & 31; - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (shift - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"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") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" - "* -{ - int shift = INTVAL (operands[4]) & 31; - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (32 - shift - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"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") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])" - "* -{ - int shift = INTVAL (operands[4]) & 31; - int start = INTVAL (operands[2]) & 31; - int size = INTVAL (operands[1]) & 31; - - operands[4] = GEN_INT (32 - shift - start - size); - operands[1] = GEN_INT (start + size - 1); - return \"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") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i") - (match_operand:SI 5 "const_int_operand" "i")))] - "INTVAL (operands[4]) >= INTVAL (operands[1])" - "* -{ - int extract_start = INTVAL (operands[5]) & 31; - int extract_size = INTVAL (operands[4]) & 31; - int insert_start = INTVAL (operands[2]) & 31; - int insert_size = INTVAL (operands[1]) & 31; - -/* Align extract field with insert field */ - operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size); - operands[1] = GEN_INT (insert_start + insert_size - 1); - return \"rlwimi %0,%3,%h5,%h2,%h1\"; -}" - [(set_attr "type" "insert_word")]) - -;; combine patterns for rlwimi -(define_insn "*insvsi_internal5" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0") - (match_operand:SI 1 "mask_operand" "i")) - (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 5 "mask_operand" "i"))))] - "INTVAL(operands[1]) == ~INTVAL(operands[5])" - "* -{ - int me = extract_ME(operands[5]); - int mb = extract_MB(operands[5]); - operands[4] = GEN_INT(32 - INTVAL(operands[2])); - operands[2] = GEN_INT(mb); - operands[1] = GEN_INT(me); - return \"rlwimi %0,%3,%h4,%h2,%h1\"; -}" - [(set_attr "type" "insert_word")]) - -(define_insn "*insvsi_internal6" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 5 "mask_operand" "i")) - (and:SI (match_operand:SI 4 "gpc_reg_operand" "0") - (match_operand:SI 1 "mask_operand" "i"))))] - "INTVAL(operands[1]) == ~INTVAL(operands[5])" - "* -{ - int me = extract_ME(operands[5]); - int mb = extract_MB(operands[5]); - operands[4] = GEN_INT(32 - INTVAL(operands[2])); - operands[2] = GEN_INT(mb); - operands[1] = GEN_INT(me); - return \"rlwimi %0,%3,%h4,%h2,%h1\"; -}" - [(set_attr "type" "insert_word")]) - -(define_insn "insvdi_internal" - [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "gpc_reg_operand" "r"))] - "TARGET_POWERPC64" - "* -{ - int start = INTVAL (operands[2]) & 63; - int size = INTVAL (operands[1]) & 63; - - operands[1] = GEN_INT (64 - start - size); - return \"rldimi %0,%3,%H1,%H2\"; -}" - [(set_attr "type" "insert_dword")]) - -(define_insn "*insvdi_internal2" - [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "TARGET_POWERPC64 - && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])" - "* -{ - int shift = INTVAL (operands[4]) & 63; - int start = (INTVAL (operands[2]) & 63) - 32; - int size = INTVAL (operands[1]) & 63; - - operands[4] = GEN_INT (64 - shift - start - size); - operands[2] = GEN_INT (start); - operands[1] = GEN_INT (start + size - 1); - return \"rlwimi %0,%3,%h4,%h2,%h1\"; -}") - -(define_insn "*insvdi_internal3" - [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r") - (match_operand:SI 4 "const_int_operand" "i")))] - "TARGET_POWERPC64 - && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])" - "* -{ - int shift = INTVAL (operands[4]) & 63; - int start = (INTVAL (operands[2]) & 63) - 32; - int size = INTVAL (operands[1]) & 63; - - operands[4] = GEN_INT (64 - shift - start - size); - operands[2] = GEN_INT (start); - operands[1] = GEN_INT (start + size - 1); - return \"rlwimi %0,%3,%h4,%h2,%h1\"; -}") - -(define_expand "extzv" - [(set (match_operand 0 "gpc_reg_operand" "") - (zero_extract (match_operand 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")))] - "" - " -{ - /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since - the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the - compiler if the address of the structure is taken later. */ - if (GET_CODE (operands[0]) == SUBREG - && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) - FAIL; - - if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode) - emit_insn (gen_extzvdi_internal (operands[0], operands[1], operands[2], - operands[3])); - else - emit_insn (gen_extzvsi_internal (operands[0], operands[1], operands[2], - operands[3])); - DONE; -}") - -(define_insn "extzvsi_internal" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")))] - "" - "* -{ - int start = INTVAL (operands[3]) & 31; - int size = INTVAL (operands[2]) & 31; - - if (start + size >= 32) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - return \"rlwinm %0,%1,%3,%s2,31\"; -}") - -(define_insn "*extzvsi_internal1" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i") - (match_operand:SI 3 "const_int_operand" "i,i")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "" - "* -{ - int start = INTVAL (operands[3]) & 31; - int size = INTVAL (operands[2]) & 31; - - /* Force split for non-cc0 compare. */ - if (which_alternative == 1) - return \"#\"; - - /* If the bit-field being tested fits in the upper or lower half of a - word, it is possible to use andiu. or andil. to test it. This is - useful because the condition register set-use delay is smaller for - andi[ul]. than for rlinm. This doesn't work when the starting bit - position is 0 because the LT and GT bits may be set wrong. */ - - if ((start > 0 && start + size <= 16) || start >= 16) - { - operands[3] = GEN_INT (((1 << (16 - (start & 15))) - - (1 << (16 - (start & 15) - size)))); - if (start < 16) - return \"andis. %4,%1,%3\"; - else - return \"andi. %4,%1,%3\"; - } - - if (start + size >= 32) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - return \"rlwinm. %4,%1,%3,%s2,31\"; -}" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "reload_completed" - [(set (match_dup 4) - (zero_extract:SI (match_dup 1) (match_dup 2) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*extzvsi_internal2" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i") - (match_operand:SI 3 "const_int_operand" "i,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "" - "* -{ - int start = INTVAL (operands[3]) & 31; - int size = INTVAL (operands[2]) & 31; - - /* Force split for non-cc0 compare. */ - if (which_alternative == 1) - return \"#\"; - - /* Since we are using the output value, we can't ignore any need for - a shift. The bit-field must end at the LSB. */ - if (start >= 16 && start + size == 32) - { - operands[3] = GEN_INT ((1 << size) - 1); - return \"andi. %0,%1,%3\"; - } - - if (start + size >= 32) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - return \"rlwinm. %0,%1,%3,%s2,31\"; -}" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "") - (match_operand:SI 3 "const_int_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "reload_completed" - [(set (match_dup 0) - (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "extzvdi_internal" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")))] - "TARGET_POWERPC64" - "* -{ - int start = INTVAL (operands[3]) & 63; - int size = INTVAL (operands[2]) & 63; - - if (start + size >= 64) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - operands[2] = GEN_INT (64 - size); - return \"rldicl %0,%1,%3,%2\"; -}") - -(define_insn "*extzvdi_internal1" - [(set (match_operand:CC 0 "gpc_reg_operand" "=x") - (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" - "* -{ - int start = INTVAL (operands[3]) & 63; - int size = INTVAL (operands[2]) & 63; - - if (start + size >= 64) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - operands[2] = GEN_INT (64 - size); - return \"rldicl. %4,%1,%3,%2\"; -}" - [(set_attr "type" "compare")]) - -(define_insn "*extzvdi_internal2" - [(set (match_operand:CC 4 "gpc_reg_operand" "=x") - (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")) - (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_64BIT && rs6000_gen_cell_microcode" - "* -{ - int start = INTVAL (operands[3]) & 63; - int size = INTVAL (operands[2]) & 63; - - if (start + size >= 64) - operands[3] = const0_rtx; - else - operands[3] = GEN_INT (start + size); - operands[2] = GEN_INT (64 - size); - return \"rldicl. %0,%1,%3,%2\"; -}" - [(set_attr "type" "compare")]) - -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "" - "@ - rlwnm %0,%1,%2,0xffffffff - rlwinm %0,%1,%h2,0xffffffff" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotlsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] - "TARGET_64BIT" - "@ - rlwnm %0,%1,%2,0xffffffff - rlwinm %0,%1,%h2,0xffffffff" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotlsi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" - "@ - rlwnm. %3,%1,%2,0xffffffff - rlwinm. %3,%1,%h2,0xffffffff - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (rotate:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (rotate:SI (match_dup 1) (match_dup 2)))] - "" - "@ - rlwnm. %0,%1,%2,0xffffffff - rlwinm. %0,%1,%h2,0xffffffff - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (rotate:SI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (rotate:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal4" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) - (match_operand:SI 3 "mask_operand" "n,n")))] - "" - "@ - rlwnm %0,%1,%2,%m3,%M3 - rlwinm %0,%1,%h2,%m3,%M3" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotlsi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:SI 3 "mask_operand" "n,n,n,n")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r,r,r"))] - "" - "@ - rlwnm. %4,%1,%2,%m3,%M3 - rlwinm. %4,%1,%h2,%m3,%M3 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "reload_completed" - [(set (match_dup 4) - (and:SI (rotate:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:SI 3 "mask_operand" "n,n,n,n")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "" - "@ - rlwnm. %0,%1,%2,%m3,%M3 - rlwinm. %0,%1,%h2,%m3,%M3 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:SI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "reload_completed" - [(set (match_dup 0) - (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal7" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))] - "" - "rlw%I2nm %0,%1,%h2,0xff" - [(set (attr "cell_micro") - (if_then_else (match_operand:SI 2 "const_int_operand" "") - (const_string "not") - (const_string "always")))]) - -(define_insn "*rotlsi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" - "@ - rlwnm. %3,%1,%2,0xff - rlwinm. %3,%1,%h2,0xff - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (zero_extend:SI (subreg:QI - (rotate:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "" - "@ - rlwnm. %0,%1,%2,0xff - rlwinm. %0,%1,%h2,0xff - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI - (subreg:QI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal10" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")) 0)))] - "" - "@ - rlwnm %0,%1,%2,0xffff - rlwinm %0,%1,%h2,0xffff" - [(set_attr "type" "var_shift_rotate,integer")]) - - -(define_insn "*rotlsi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" - "@ - rlwnm. %3,%1,%2,0xffff - rlwinm. %3,%1,%h2,0xffff - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (zero_extend:SI (subreg:HI - (rotate:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotlsi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "" - "@ - rlwnm. %0,%1,%2,0xffff - rlwinm. %0,%1,%h2,0xffff - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:SI - (subreg:HI - (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))] - "reload_completed" - [(set (match_dup 0) - (zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "" - "@ - slw %0,%1,%2 - slwi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "*ashlsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] - "TARGET_POWERPC64" - "@ - slw %0,%1,%2 - slwi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "TARGET_32BIT" - "@ - slw. %3,%1,%2 - slwi. %3,%1,%h2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) - (ashift:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ashift:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" - "@ - slw. %0,%1,%2 - slwi. %0,%1,%h2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashift:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) - (ashift:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "rlwinm" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "n")))] - "includes_lshift_p (operands[2], operands[3])" - "rlwinm %0,%1,%h2,%m3,%M3") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "n,n")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "includes_lshift_p (operands[2], operands[3])" - "@ - rlwinm. %4,%1,%h2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "includes_lshift_p (operands[2], operands[3]) && reload_completed" - [(set (match_dup 4) - (and:SI (ashift:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "n,n")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_lshift_p (operands[2], operands[3])" - "@ - rlwinm. %0,%1,%h2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_lshift_p (operands[2], operands[3]) && reload_completed" - [(set (match_dup 0) - (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,r,i")))] - "" - "@ - mr %0,%1 - srw %0,%1,%2 - srwi %0,%1,%h2" - [(set_attr "type" "integer,var_shift_rotate,shift")]) - -(define_insn "*lshrsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] - "TARGET_POWERPC64" - "@ - srw %0,%1,%2 - srwi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=X,r,r,X,r,r"))] - "TARGET_32BIT" - "@ - mr. %1,%1 - srw. %3,%1,%2 - srwi. %3,%1,%h2 - # - # - #" - [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,4,8,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) - (lshiftrt:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "O,r,i,O,r,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r") - (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT" - "@ - mr. %0,%1 - srw. %0,%1,%2 - srwi. %0,%1,%h2 - # - # - #" - [(set_attr "type" "delayed_compare,var_delayed_compare,delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,4,8,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 0) - (lshiftrt:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "n")))] - "includes_rshift_p (operands[2], operands[3])" - "rlwinm %0,%1,%s2,%m3,%M3") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "n,n")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=r,r"))] - "includes_rshift_p (operands[2], operands[3])" - "@ - rlwinm. %4,%1,%s2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "includes_rshift_p (operands[2], operands[3]) && reload_completed" - [(set (match_dup 4) - (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "n,n")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_rshift_p (operands[2], operands[3])" - "@ - rlwinm. %0,%1,%s2,%m3,%M3 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "mask_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_rshift_p (operands[2], operands[3]) && reload_completed" - [(set (match_dup 0) - (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)))] - "includes_rshift_p (operands[2], GEN_INT (255))" - "rlwinm %0,%1,%s2,0xff") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "includes_rshift_p (operands[2], GEN_INT (255))" - "@ - rlwinm. %3,%1,%s2,0xff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed" - [(set (match_dup 3) - (zero_extend:SI (subreg:QI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] - "includes_rshift_p (operands[2], GEN_INT (255))" - "@ - rlwinm. %0,%1,%s2,0xff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:QI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] - "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed" - [(set (match_dup 0) - (zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) 0)))] - "includes_rshift_p (operands[2], GEN_INT (65535))" - "rlwinm %0,%1,%s2,0xffff") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r"))] - "includes_rshift_p (operands[2], GEN_INT (65535))" - "@ - rlwinm. %3,%1,%s2,0xffff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed" - [(set (match_dup 3) - (zero_extend:SI (subreg:HI - (lshiftrt:SI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] - "includes_rshift_p (operands[2], GEN_INT (65535))" - "@ - rlwinm. %0,%1,%s2,0xffff - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (zero_extend:SI - (subreg:HI - (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) 0)) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))] - "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed" - [(set (match_dup 0) - (zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "" - "@ - sraw %0,%1,%2 - srawi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "*ashrsi3_64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (sign_extend:DI - (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))] - "TARGET_POWERPC64" - "@ - sraw %0,%1,%2 - srawi %0,%1,%h2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" - "@ - sraw. %3,%1,%2 - srawi. %3,%1,%h2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "reload_completed" - [(set (match_dup 3) - (ashiftrt:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") - (ashiftrt:SI (match_dup 1) (match_dup 2)))] - "" - "@ - sraw. %0,%1,%2 - srawi. %0,%1,%h2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -;; Builtins to replace a division to generate FRE reciprocal estimate -;; instructions and the necessary fixup instructions -(define_expand "recip<mode>3" - [(match_operand:RECIPF 0 "gpc_reg_operand" "") - (match_operand:RECIPF 1 "gpc_reg_operand" "") - (match_operand:RECIPF 2 "gpc_reg_operand" "")] - "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" -{ - rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); - DONE; -}) - -;; Split to create division from FRE/FRES/etc. and fixup instead of the normal -;; hardware division. This is only done before register allocation and with -;; -ffast-math. This must appear before the divsf3/divdf3 insns. -(define_split - [(set (match_operand:RECIPF 0 "gpc_reg_operand" "") - (div:RECIPF (match_operand 1 "gpc_reg_operand" "") - (match_operand 2 "gpc_reg_operand" "")))] - "RS6000_RECIP_AUTO_RE_P (<MODE>mode) - && can_create_pseudo_p () && optimize_insn_for_speed_p () - && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math" - [(const_int 0)] -{ - rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); - DONE; -}) - -;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the -;; appropriate fixup. -(define_expand "rsqrt<mode>2" - [(match_operand:RECIPF 0 "gpc_reg_operand" "") - (match_operand:RECIPF 1 "gpc_reg_operand" "")] - "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" -{ - rs6000_emit_swrsqrt (operands[0], operands[1]); - DONE; -}) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (ashiftrt:SI (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (ashiftrt:SI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Floating-point insns, excluding normal data motion. -;; -;; PowerPC has a full set of single-precision floating point instructions. -;; -;; For the POWER architecture, we pretend that we have both SFmode and -;; DFmode insns, while, in fact, all fp insns are actually done in double. -;; The only conversions we will do will be when storing to memory. In that -;; case, we will use the "frsp" instruction before storing. -;; -;; Note that when we store into a single-precision memory location, we need to -;; use the frsp insn first. If the register being stored isn't dead, we -;; need a scratch register for the frsp. But this is difficult when the store -;; is done by reload. It is not incorrect to do the frsp on the register in -;; this case, we just lose precision that we would have otherwise gotten but -;; is not guaranteed. Perhaps this should be tightened up at some point. - -(define_expand "extendsfdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") - -(define_insn_and_split "*extendsfdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d") - (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "@ - # - fmr %0,%1 - lfs%U1%X1 %0,%1" - "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" - [(const_int 0)] -{ - emit_note (NOTE_INSN_DELETED); - DONE; -} - [(set_attr "type" "fp,fp,fpload")]) - -(define_expand "truncdfsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") - -(define_insn "*truncdfsf2_fpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "frsp %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "negsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" - "") - -(define_insn "*negsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fneg %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "abssf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" - "") - -(define_insn "*abssf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fnabs %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "addsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (plus:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fadds %0,%1,%2" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_addsub_s")]) - -(define_expand "subsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (minus:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fsubs %0,%1,%2" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_addsub_s")]) - -(define_expand "mulsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (mult:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fmuls %0,%1,%2" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_mul_s")]) - -(define_expand "divsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (div:SF (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" - "fdivs %0,%1,%2" - [(set_attr "type" "sdiv")]) - -(define_insn "fres" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] - "TARGET_FRES" - "fres %0,%1" - [(set_attr "type" "fp")]) - -; builtin fmaf support -(define_insn "*fmasf4_fpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fmadds %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_s")]) - -(define_insn "*fmssf4_fpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f") - (neg:SF (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fmsubs %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_s")]) - -(define_insn "*nfmasf4_fpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fnmadds %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_s")]) - -(define_insn "*nfmssf4_fpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f") - (neg:SF (match_operand:SF 3 "gpc_reg_operand" "f")))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fnmsubs %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_s")]) - -(define_expand "sqrtsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "(TARGET_PPC_GPOPT || TARGET_XILINX_FPU) - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && !TARGET_SIMPLE_FPU" - "") - -(define_insn "" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "(TARGET_PPC_GPOPT || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT - && TARGET_FPRS && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" - "fsqrts %0,%1" - [(set_attr "type" "ssqrt")]) - -(define_insn "*rsqrtsf_internal1" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] - UNSPEC_RSQRT))] - "TARGET_FRSQRTES" - "frsqrtes %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "copysign<mode>3" - [(set (match_dup 3) - (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ""))) - (set (match_dup 4) - (neg:SFDF (abs:SFDF (match_dup 1)))) - (set (match_operand:SFDF 0 "gpc_reg_operand" "") - (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "") - (match_dup 5)) - (match_dup 3) - (match_dup 4)))] - "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> - && ((TARGET_PPC_GFXOPT - && !HONOR_NANS (<MODE>mode) - && !HONOR_SIGNED_ZEROS (<MODE>mode)) - || TARGET_CMPB - || VECTOR_UNIT_VSX_P (<MODE>mode))" -{ - if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode)) - { - emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1], - operands[2])); - DONE; - } - - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); - operands[5] = CONST0_RTX (<MODE>mode); - }) - -;; Use an unspec rather providing an if-then-else in RTL, to prevent the -;; compiler from optimizing -0.0 -(define_insn "copysign<mode>3_fcpsgn" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>") - (match_operand:SFDF 2 "gpc_reg_operand" "<rreg2>")] - UNSPEC_COPYSIGN))] - "TARGET_CMPB && !VECTOR_UNIT_VSX_P (<MODE>mode)" - "fcpsgn %0,%2,%1" - [(set_attr "type" "fp")]) - -;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a -;; fsel instruction and some auxiliary computations. Then we just have a -;; single DEFINE_INSN for fsel and the define_splits to make them if made by -;; combine. -(define_expand "smaxsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")) - (match_dup 1) - (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_SINGLE_FLOAT && !flag_trapping_math" - "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") - -(define_expand "sminsf3" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")) - (match_dup 2) - (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_SINGLE_FLOAT && !flag_trapping_math" - "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") - -(define_split - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (match_operator:SF 3 "min_max_operator" - [(match_operand:SF 1 "gpc_reg_operand" "") - (match_operand:SF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_SINGLE_FLOAT && !flag_trapping_math" - [(const_int 0)] - " -{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), - operands[1], operands[2]); - DONE; -}") - -(define_expand "mov<mode>cc" - [(set (match_operand:GPR 0 "gpc_reg_operand" "") - (if_then_else:GPR (match_operand 1 "comparison_operator" "") - (match_operand:GPR 2 "gpc_reg_operand" "") - (match_operand:GPR 3 "gpc_reg_operand" "")))] - "TARGET_ISEL<sel>" - " -{ - if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) - DONE; - else - FAIL; -}") - -;; We use the BASE_REGS for the isel input operands because, if rA is -;; 0, the value of 0 is placed in rD upon truth. Similarly for rB -;; because we may switch the operands and rB may end up being rA. -;; -;; We need 2 patterns: an unsigned and a signed pattern. We could -;; leave out the mode in operand 4 and use one pattern, but reload can -;; change the mode underneath our feet and then gets confused trying -;; to reload the value. -(define_insn "isel_signed_<mode>" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") - (if_then_else:GPR - (match_operator 1 "scc_comparison_operator" - [(match_operand:CC 4 "cc_reg_operand" "y,y") - (const_int 0)]) - (match_operand:GPR 2 "reg_or_cint_operand" "O,b") - (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] - "TARGET_ISEL<sel>" - "* -{ return output_isel (operands); }" - [(set_attr "type" "isel") - (set_attr "length" "4")]) - -(define_insn "isel_unsigned_<mode>" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") - (if_then_else:GPR - (match_operator 1 "scc_comparison_operator" - [(match_operand:CCUNS 4 "cc_reg_operand" "y,y") - (const_int 0)]) - (match_operand:GPR 2 "reg_or_cint_operand" "O,b") - (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] - "TARGET_ISEL<sel>" - "* -{ return output_isel (operands); }" - [(set_attr "type" "isel") - (set_attr "length" "4")]) - -;; These patterns can be useful for combine; they let combine know that -;; isel can handle reversed comparisons so long as the operands are -;; registers. - -(define_insn "*isel_reversed_signed_<mode>" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (if_then_else:GPR - (match_operator 1 "scc_rev_comparison_operator" - [(match_operand:CC 4 "cc_reg_operand" "y") - (const_int 0)]) - (match_operand:GPR 2 "gpc_reg_operand" "b") - (match_operand:GPR 3 "gpc_reg_operand" "b")))] - "TARGET_ISEL<sel>" - "* -{ return output_isel (operands); }" - [(set_attr "type" "isel") - (set_attr "length" "4")]) - -(define_insn "*isel_reversed_unsigned_<mode>" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (if_then_else:GPR - (match_operator 1 "scc_rev_comparison_operator" - [(match_operand:CCUNS 4 "cc_reg_operand" "y") - (const_int 0)]) - (match_operand:GPR 2 "gpc_reg_operand" "b") - (match_operand:GPR 3 "gpc_reg_operand" "b")))] - "TARGET_ISEL<sel>" - "* -{ return output_isel (operands); }" - [(set_attr "type" "isel") - (set_attr "length" "4")]) - -(define_expand "movsfcc" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (if_then_else:SF (match_operand 1 "comparison_operator" "") - (match_operand:SF 2 "gpc_reg_operand" "") - (match_operand:SF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - " -{ - if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) - DONE; - else - FAIL; -}") - -(define_insn "*fselsfsf4" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 4 "zero_fp_constant" "F")) - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "*fseldfsf4" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d") - (match_operand:DF 4 "zero_fp_constant" "F")) - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_expand "negdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") - -(define_insn "*negdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fneg %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "absdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") - -(define_insn "*absdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fabs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "*nabsdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fnabs %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "adddf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (plus:DF (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") - -(define_insn "*adddf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d") - (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fadd %0,%1,%2" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_addsub_d")]) - -(define_expand "subdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (minus:DF (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") - -(define_insn "*subdf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (minus:DF (match_operand:DF 1 "gpc_reg_operand" "d") - (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fsub %0,%1,%2" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_addsub_d")]) - -(define_expand "muldf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - "") - -(define_insn "*muldf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") - (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fmul %0,%1,%2" - [(set_attr "type" "dmul") - (set_attr "fp_type" "fp_mul_d")]) - -(define_expand "divdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (div:DF (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT - && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE) - && !TARGET_SIMPLE_FPU" - "") - -(define_insn "*divdf3_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (div:DF (match_operand:DF 1 "gpc_reg_operand" "d") - (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU - && !VECTOR_UNIT_VSX_P (DFmode)" - "fdiv %0,%1,%2" - [(set_attr "type" "ddiv")]) - -(define_insn "*fred_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] - "TARGET_FRE && !VECTOR_UNIT_VSX_P (DFmode)" - "fre %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "*rsqrtdf_internal1" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] - UNSPEC_RSQRT))] - "TARGET_FRSQRTE && !VECTOR_UNIT_VSX_P (DFmode)" - "frsqrte %0,%1" - [(set_attr "type" "fp")]) - -; builtin fma support -(define_insn "*fmadf4_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && VECTOR_UNIT_NONE_P (DFmode)" - "fmadd %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_insn "*fmsdf4_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f") - (neg:DF (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && VECTOR_UNIT_NONE_P (DFmode)" - "fmsub %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_insn "*nfmadf4_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && VECTOR_UNIT_NONE_P (DFmode)" - "fnmadd %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_insn "*nfmsdf4_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") - (neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f") - (match_operand:DF 2 "gpc_reg_operand" "f") - (neg:DF (match_operand:DF 3 "gpc_reg_operand" "f")))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && VECTOR_UNIT_NONE_P (DFmode)" - "fnmsub %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_expand "sqrtdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "") - -(define_insn "*sqrtdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] - "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fsqrt %0,%1" - [(set_attr "type" "dsqrt")]) - -;; The conditional move instructions allow us to perform max and min -;; operations even when - -(define_expand "smaxdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" "")) - (match_dup 1) - (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !flag_trapping_math" - "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") - -(define_expand "smindf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" "")) - (match_dup 2) - (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !flag_trapping_math" - "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operator:DF 3 "min_max_operator" - [(match_operand:DF 1 "gpc_reg_operand" "") - (match_operand:DF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !flag_trapping_math" - [(const_int 0)] - " -{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), - operands[1], operands[2]); - DONE; -}") - -(define_expand "movdfcc" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (if_then_else:DF (match_operand 1 "comparison_operator" "") - (match_operand:DF 2 "gpc_reg_operand" "") - (match_operand:DF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - " -{ - if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) - DONE; - else - FAIL; -}") - -(define_insn "*fseldfdf4" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d") - (match_operand:DF 4 "zero_fp_constant" "F")) - (match_operand:DF 2 "gpc_reg_operand" "d") - (match_operand:DF 3 "gpc_reg_operand" "d")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -(define_insn "*fselsfdf4" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 4 "zero_fp_constant" "F")) - (match_operand:DF 2 "gpc_reg_operand" "d") - (match_operand:DF 3 "gpc_reg_operand" "d")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT" - "fsel %0,%1,%2,%3" - [(set_attr "type" "fp")]) - -;; Conversions to and from floating-point. - -; We don't define lfiwax/lfiwzx with the normal definition, because we -; don't want to support putting SImode in FPR registers. -(define_insn "lfiwax" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (unspec:DI [(match_operand:SI 1 "indexed_or_indirect_operand" "Z")] - UNSPEC_LFIWAX))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX" - "lfiwax %0,%y1" - [(set_attr "type" "fpload")]) - -; This split must be run before register allocation because it allocates the -; memory slot that is needed to move values to/from the FPR. We don't allocate -; it earlier to allow for the combiner to merge insns together where it might -; not be needed and also in case the insns are deleted as dead code. - -(define_insn_and_split "floatsi<mode>2_lfiwax" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") - (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) - (clobber (match_scratch:DI 2 "=d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX - && <SI_CONVERT_FP> && can_create_pseudo_p ()" - "#" - "" - [(pc)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx tmp; - - if (!MEM_P (src) && TARGET_MFPGPR && TARGET_POWERPC64) - tmp = convert_to_mode (DImode, src, false); - else - { - tmp = operands[2]; - if (GET_CODE (tmp) == SCRATCH) - tmp = gen_reg_rtx (DImode); - if (MEM_P (src)) - { - src = rs6000_address_for_fpconvert (src); - emit_insn (gen_lfiwax (tmp, src)); - } - else - { - rtx stack = rs6000_allocate_stack_temp (SImode, false, true); - emit_move_insn (stack, src); - emit_insn (gen_lfiwax (tmp, stack)); - } - } - emit_insn (gen_floatdi<mode>2 (dest, tmp)); - DONE; -}" - [(set_attr "length" "12") - (set_attr "type" "fpload")]) - -(define_insn_and_split "floatsi<mode>2_lfiwax_mem" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>") - (float:SFDF - (sign_extend:DI - (match_operand:SI 1 "memory_operand" "Z,Z")))) - (clobber (match_scratch:DI 2 "=0,d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX - && <SI_CONVERT_FP>" - "#" - "" - [(pc)] - " -{ - operands[1] = rs6000_address_for_fpconvert (operands[1]); - if (GET_CODE (operands[2]) == SCRATCH) - operands[2] = gen_reg_rtx (DImode); - emit_insn (gen_lfiwax (operands[2], operands[1])); - emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); - DONE; -}" - [(set_attr "length" "8") - (set_attr "type" "fpload")]) - -(define_insn "lfiwzx" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (unspec:DI [(match_operand:SI 1 "indexed_or_indirect_operand" "Z")] - UNSPEC_LFIWZX))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX" - "lfiwzx %0,%y1" - [(set_attr "type" "fpload")]) - -(define_insn_and_split "floatunssi<mode>2_lfiwzx" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") - (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) - (clobber (match_scratch:DI 2 "=d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX - && <SI_CONVERT_FP>" - "#" - "" - [(pc)] - " -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx tmp; - - if (!MEM_P (src) && TARGET_MFPGPR && TARGET_POWERPC64) - tmp = convert_to_mode (DImode, src, true); - else - { - tmp = operands[2]; - if (GET_CODE (tmp) == SCRATCH) - tmp = gen_reg_rtx (DImode); - if (MEM_P (src)) - { - src = rs6000_address_for_fpconvert (src); - emit_insn (gen_lfiwzx (tmp, src)); - } - else - { - rtx stack = rs6000_allocate_stack_temp (SImode, false, true); - emit_move_insn (stack, src); - emit_insn (gen_lfiwzx (tmp, stack)); - } - } - emit_insn (gen_floatdi<mode>2 (dest, tmp)); - DONE; -}" - [(set_attr "length" "12") - (set_attr "type" "fpload")]) - -(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>") - (unsigned_float:SFDF - (zero_extend:DI - (match_operand:SI 1 "memory_operand" "Z,Z")))) - (clobber (match_scratch:DI 2 "=0,d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX - && <SI_CONVERT_FP>" - "#" - "" - [(pc)] - " -{ - operands[1] = rs6000_address_for_fpconvert (operands[1]); - if (GET_CODE (operands[2]) == SCRATCH) - operands[2] = gen_reg_rtx (DImode); - emit_insn (gen_lfiwzx (operands[2], operands[1])); - emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); - DONE; -}" - [(set_attr "length" "8") - (set_attr "type" "fpload")]) - -; For each of these conversions, there is a define_expand, a define_insn -; with a '#' template, and a define_split (with C code). The idea is -; to allow constant folding with the template of the define_insn, -; then to have the insns split later (between sched1 and final). - -(define_expand "floatsidf2" - [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6))])] - "TARGET_HARD_FLOAT - && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - " -{ - if (TARGET_E500_DOUBLE) - { - if (!REG_P (operands[1])) - operands[1] = force_reg (SImode, operands[1]); - emit_insn (gen_spe_floatsidf2 (operands[0], operands[1])); - DONE; - } - else if (TARGET_LFIWAX && TARGET_FCFID) - { - emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); - DONE; - } - else if (TARGET_FCFID) - { - rtx dreg = operands[1]; - if (!REG_P (dreg)) - dreg = force_reg (SImode, dreg); - dreg = convert_to_mode (DImode, dreg, false); - emit_insn (gen_floatdidf2 (operands[0], dreg)); - DONE; - } - - if (!REG_P (operands[1])) - operands[1] = force_reg (SImode, operands[1]); - operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); - operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); - operands[5] = gen_reg_rtx (DFmode); - operands[6] = gen_reg_rtx (SImode); -}") - -(define_insn_and_split "*floatsidf2_internal" - [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") - (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) - (use (match_operand:SI 2 "gpc_reg_operand" "r")) - (use (match_operand:DF 3 "gpc_reg_operand" "d")) - (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) - (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) - (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] - "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "#" - "" - [(pc)] - " -{ - rtx lowword, highword; - gcc_assert (MEM_P (operands[4])); - highword = adjust_address (operands[4], SImode, 0); - lowword = adjust_address (operands[4], SImode, 4); - if (! WORDS_BIG_ENDIAN) - { - rtx tmp; - tmp = highword; highword = lowword; lowword = tmp; - } - - emit_insn (gen_xorsi3 (operands[6], operands[1], - GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); - emit_move_insn (lowword, operands[6]); - emit_move_insn (highword, operands[2]); - emit_move_insn (operands[5], operands[4]); - emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); - DONE; -}" - [(set_attr "length" "24") - (set_attr "type" "fp")]) - -;; If we don't have a direct conversion to single precision, don't enable this -;; conversion for 32-bit without fast math, because we don't have the insn to -;; generate the fixup swizzle to avoid double rounding problems. -(define_expand "floatunssisf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT - && (!TARGET_FPRS - || (TARGET_FPRS - && ((TARGET_FCFIDUS && TARGET_LFIWZX) - || (TARGET_DOUBLE_FLOAT && TARGET_FCFID - && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))" - " -{ - if (!TARGET_FPRS) - { - if (!REG_P (operands[1])) - operands[1] = force_reg (SImode, operands[1]); - } - else if (TARGET_LFIWZX && TARGET_FCFIDUS) - { - emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); - DONE; - } - else - { - rtx dreg = operands[1]; - if (!REG_P (dreg)) - dreg = force_reg (SImode, dreg); - dreg = convert_to_mode (DImode, dreg, true); - emit_insn (gen_floatdisf2 (operands[0], dreg)); - DONE; - } -}") - -(define_expand "floatunssidf2" - [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") - (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5))])] - "TARGET_HARD_FLOAT - && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" - " -{ - if (TARGET_E500_DOUBLE) - { - if (!REG_P (operands[1])) - operands[1] = force_reg (SImode, operands[1]); - emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1])); - DONE; - } - else if (TARGET_LFIWZX && TARGET_FCFID) - { - emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); - DONE; - } - else if (TARGET_FCFID) - { - rtx dreg = operands[1]; - if (!REG_P (dreg)) - dreg = force_reg (SImode, dreg); - dreg = convert_to_mode (DImode, dreg, true); - emit_insn (gen_floatdidf2 (operands[0], dreg)); - DONE; - } - - if (!REG_P (operands[1])) - operands[1] = force_reg (SImode, operands[1]); - operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); - operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); - operands[5] = gen_reg_rtx (DFmode); -}") - -(define_insn_and_split "*floatunssidf2_internal" - [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) - (use (match_operand:SI 2 "gpc_reg_operand" "r")) - (use (match_operand:DF 3 "gpc_reg_operand" "d")) - (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) - (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] - "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !(TARGET_FCFID && TARGET_POWERPC64)" - "#" - "" - [(pc)] - " -{ - rtx lowword, highword; - gcc_assert (MEM_P (operands[4])); - highword = adjust_address (operands[4], SImode, 0); - lowword = adjust_address (operands[4], SImode, 4); - if (! WORDS_BIG_ENDIAN) - { - rtx tmp; - tmp = highword; highword = lowword; lowword = tmp; - } - - emit_move_insn (lowword, operands[1]); - emit_move_insn (highword, operands[2]); - emit_move_insn (operands[5], operands[4]); - emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); - DONE; -}" - [(set_attr "length" "20") - (set_attr "type" "fp")]) - -(define_expand "fix_trunc<mode>si2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)" - " -{ - if (!<E500_CONVERT>) - { - rtx tmp, stack; - - if (TARGET_STFIWX) - emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1])); - else - { - tmp = gen_reg_rtx (DImode); - stack = rs6000_allocate_stack_temp (DImode, true, false); - emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1], - tmp, stack)); - } - DONE; - } -}") - -; Like the convert to float patterns, this insn must be split before -; register allocation so that it can allocate the memory slot if it -; needed -(define_insn_and_split "fix_trunc<mode>si2_stfiwx" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) - (clobber (match_scratch:DI 2 "=d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT) - && TARGET_STFIWX && can_create_pseudo_p ()" - "#" - "" - [(pc)] -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx tmp = operands[2]; - - if (GET_CODE (tmp) == SCRATCH) - tmp = gen_reg_rtx (DImode); - - emit_insn (gen_fctiwz_<mode> (tmp, src)); - if (MEM_P (dest)) - { - dest = rs6000_address_for_fpconvert (dest); - emit_insn (gen_stfiwx (dest, tmp)); - DONE; - } - else if (TARGET_MFPGPR && TARGET_POWERPC64) - { - dest = gen_lowpart (DImode, dest); - emit_move_insn (dest, tmp); - DONE; - } - else - { - rtx stack = rs6000_allocate_stack_temp (SImode, false, true); - emit_insn (gen_stfiwx (stack, tmp)); - emit_move_insn (dest, stack); - DONE; - } -} - [(set_attr "length" "12") - (set_attr "type" "fp")]) - -(define_insn_and_split "fix_trunc<mode>si2_internal" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") - (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) - (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) - (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "#" - "" - [(pc)] - " -{ - rtx lowword; - gcc_assert (MEM_P (operands[3])); - lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); - - emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); - emit_move_insn (operands[3], operands[2]); - emit_move_insn (operands[0], lowword); - DONE; -}" - [(set_attr "length" "16") - (set_attr "type" "fp")]) - -(define_expand "fix_trunc<mode>di2" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS - && TARGET_FCFID" - "") - -(define_insn "*fix_trunc<mode>di2_fctidz" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS - && TARGET_FCFID && !VECTOR_UNIT_VSX_P (<MODE>mode)" - "fctidz %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "fixuns_trunc<mode>si2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT - && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX) - || <E500_CONVERT>)" - " -{ - if (!<E500_CONVERT>) - { - emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); - DONE; - } -}") - -(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) - (clobber (match_scratch:DI 2 "=d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ - && TARGET_STFIWX && can_create_pseudo_p ()" - "#" - "" - [(pc)] -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx tmp = operands[2]; - - if (GET_CODE (tmp) == SCRATCH) - tmp = gen_reg_rtx (DImode); - - emit_insn (gen_fctiwuz_<mode> (tmp, src)); - if (MEM_P (dest)) - { - dest = rs6000_address_for_fpconvert (dest); - emit_insn (gen_stfiwx (dest, tmp)); - DONE; - } - else if (TARGET_MFPGPR && TARGET_POWERPC64) - { - dest = gen_lowpart (DImode, dest); - emit_move_insn (dest, tmp); - DONE; - } - else - { - rtx stack = rs6000_allocate_stack_temp (SImode, false, true); - emit_insn (gen_stfiwx (stack, tmp)); - emit_move_insn (dest, stack); - DONE; - } -} - [(set_attr "length" "12") - (set_attr "type" "fp")]) - -(define_expand "fixuns_trunc<mode>di2" - [(set (match_operand:DI 0 "register_operand" "") - (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))" - "") - -(define_insn "*fixuns_trunc<mode>di2_fctiduz" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS - && TARGET_FCTIDUZ && !VECTOR_UNIT_VSX_P (<MODE>mode)" - "fctiduz %0,%1" - [(set_attr "type" "fp")]) - -; 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_<mode>" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))] - UNSPEC_FCTIWZ))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "fctiwz %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "fctiwuz_<mode>" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (unspec:DI [(unsigned_fix:SI - (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>"))] - UNSPEC_FCTIWUZ))] - "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ" - "fctiwuz %0,%1" - [(set_attr "type" "fp")]) - -;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since -;; since the friz instruction does not truncate the value if the floating -;; point value is < LONG_MIN or > LONG_MAX. -(define_insn "*friz" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND - && !VECTOR_UNIT_VSX_P (DFmode) && flag_unsafe_math_optimizations - && !flag_trapping_math && TARGET_FRIZ" - "friz %0,%1" - [(set_attr "type" "fp")]) - -;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a -;; load to properly sign extend the value, but at least doing a store, load -;; into a GPR to sign extend, a store from the GPR and a load back into the FPR -;; if we have 32-bit memory ops -(define_insn_and_split "*round32<mode>2_fprs" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") - (float:SFDF - (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) - (clobber (match_scratch:DI 2 "=d")) - (clobber (match_scratch:DI 3 "=d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID - && can_create_pseudo_p ()" - "#" - "" - [(pc)] -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx tmp1 = operands[2]; - rtx tmp2 = operands[3]; - rtx stack = rs6000_allocate_stack_temp (SImode, false, true); - - if (GET_CODE (tmp1) == SCRATCH) - tmp1 = gen_reg_rtx (DImode); - if (GET_CODE (tmp2) == SCRATCH) - tmp2 = gen_reg_rtx (DImode); - - emit_insn (gen_fctiwz_<mode> (tmp1, src)); - emit_insn (gen_stfiwx (stack, tmp1)); - emit_insn (gen_lfiwax (tmp2, stack)); - emit_insn (gen_floatdi<mode>2 (dest, tmp2)); - DONE; -} - [(set_attr "type" "fpload") - (set_attr "length" "16")]) - -(define_insn_and_split "*roundu32<mode>2_fprs" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") - (unsigned_float:SFDF - (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) - (clobber (match_scratch:DI 2 "=d")) - (clobber (match_scratch:DI 3 "=d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU - && can_create_pseudo_p ()" - "#" - "" - [(pc)] -{ - rtx dest = operands[0]; - rtx src = operands[1]; - rtx tmp1 = operands[2]; - rtx tmp2 = operands[3]; - rtx stack = rs6000_allocate_stack_temp (SImode, false, true); - - if (GET_CODE (tmp1) == SCRATCH) - tmp1 = gen_reg_rtx (DImode); - if (GET_CODE (tmp2) == SCRATCH) - tmp2 = gen_reg_rtx (DImode); - - emit_insn (gen_fctiwuz_<mode> (tmp1, src)); - emit_insn (gen_stfiwx (stack, tmp1)); - emit_insn (gen_lfiwzx (tmp2, stack)); - emit_insn (gen_floatdi<mode>2 (dest, tmp2)); - DONE; -} - [(set_attr "type" "fpload") - (set_attr "length" "16")]) - -;; No VSX equivalent to fctid -(define_insn "lrint<mode>di2" - [(set (match_operand:DI 0 "gpc_reg_operand" "=d") - (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] - UNSPEC_FCTID))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>" - "fctid %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "btrunc<mode>2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] - UNSPEC_FRIZ))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>" - "") - -(define_insn "*btrunc<mode>2_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] - UNSPEC_FRIZ))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> - && !VECTOR_UNIT_VSX_P (<MODE>mode)" - "friz %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "ceil<mode>2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] - UNSPEC_FRIP))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>" - "") - -(define_insn "*ceil<mode>2_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] - UNSPEC_FRIP))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> - && !VECTOR_UNIT_VSX_P (<MODE>mode)" - "frip %0,%1" - [(set_attr "type" "fp")]) - -(define_expand "floor<mode>2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] - UNSPEC_FRIM))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>" - "") - -(define_insn "*floor<mode>2_fpr" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] - UNSPEC_FRIM))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> - && !VECTOR_UNIT_VSX_P (<MODE>mode)" - "frim %0,%1" - [(set_attr "type" "fp")]) - -;; No VSX equivalent to frin -(define_insn "round<mode>2" - [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") - (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] - UNSPEC_FRIN))] - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>" - "frin %0,%1" - [(set_attr "type" "fp")]) - -; An UNSPEC is used so we don't have to support SImode in FP registers. -(define_insn "stfiwx" - [(set (match_operand:SI 0 "memory_operand" "=Z") - (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")] - UNSPEC_STFIWX))] - "TARGET_PPC_GFXOPT" - "stfiwx %1,%y0" - [(set_attr "type" "fpstore")]) - -;; If we don't have a direct conversion to single precision, don't enable this -;; conversion for 32-bit without fast math, because we don't have the insn to -;; generate the fixup swizzle to avoid double rounding problems. -(define_expand "floatsisf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT - && (!TARGET_FPRS - || (TARGET_FPRS - && ((TARGET_FCFIDS && TARGET_LFIWAX) - || (TARGET_DOUBLE_FLOAT && TARGET_FCFID - && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))" - " -{ - if (!TARGET_FPRS) - { - if (!REG_P (operands[1])) - operands[1] = force_reg (SImode, operands[1]); - } - else if (TARGET_FCFIDS && TARGET_LFIWAX) - { - emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); - DONE; - } - else if (TARGET_FCFID && TARGET_LFIWAX) - { - rtx dfreg = gen_reg_rtx (DFmode); - emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1])); - emit_insn (gen_truncdfsf2 (operands[0], dfreg)); - DONE; - } - else - { - rtx dreg = operands[1]; - if (!REG_P (dreg)) - dreg = force_reg (SImode, dreg); - dreg = convert_to_mode (DImode, dreg, false); - emit_insn (gen_floatdisf2 (operands[0], dreg)); - DONE; - } -}") - -(define_expand "floatdidf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] - "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" - "") - -(define_insn "*floatdidf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))] - "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS - && !VECTOR_UNIT_VSX_P (DFmode)" - "fcfid %0,%1" - [(set_attr "type" "fp")]) - -; Allow the combiner to merge source memory operands to the conversion so that -; the optimizer/register allocator doesn't try to load the value too early in a -; GPR and then use store/load to move it to a FPR and suffer from a store-load -; hit. We will split after reload to avoid the trip through the GPRs - -(define_insn_and_split "*floatdidf2_mem" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (float:DF (match_operand:DI 1 "memory_operand" "m"))) - (clobber (match_scratch:DI 2 "=d"))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID" - "#" - "&& reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 0) (float:DF (match_dup 2)))] - "" - [(set_attr "length" "8") - (set_attr "type" "fpload")]) - -(define_expand "floatunsdidf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (unsigned_float:DF - (match_operand:DI 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" - "") - -(define_insn "*floatunsdidf2_fcfidu" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FCFIDU && !VECTOR_UNIT_VSX_P (DFmode)" - "fcfidu %0,%1" - [(set_attr "type" "fp") - (set_attr "length" "4")]) - -(define_insn_and_split "*floatunsdidf2_mem" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m"))) - (clobber (match_scratch:DI 2 "=d"))] - "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" - "#" - "&& reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 0) (unsigned_float:DF (match_dup 2)))] - "" - [(set_attr "length" "8") - (set_attr "type" "fpload")]) - -(define_expand "floatdisf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] - "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" - " -{ - if (!TARGET_FCFIDS) - { - rtx val = operands[1]; - if (!flag_unsafe_math_optimizations) - { - rtx label = gen_label_rtx (); - val = gen_reg_rtx (DImode); - emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); - emit_label (label); - } - emit_insn (gen_floatdisf2_internal1 (operands[0], val)); - DONE; - } -}") - -(define_insn "floatdisf2_fcfids" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" - "fcfids %0,%1" - [(set_attr "type" "fp")]) - -(define_insn_and_split "*floatdisf2_mem" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float:SF (match_operand:DI 1 "memory_operand" "m"))) - (clobber (match_scratch:DI 2 "=f"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" - "#" - "&& reload_completed" - [(pc)] - " -{ - emit_move_insn (operands[2], operands[1]); - emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); - DONE; -}" - [(set_attr "length" "8")]) - -;; This is not IEEE compliant if rounding mode is "round to nearest". -;; If the DI->DF conversion is inexact, then it's possible to suffer -;; from double rounding. -;; Instead of creating a new cpu type for two FP operations, just use fp -(define_insn_and_split "floatdisf2_internal1" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) - (clobber (match_scratch:DF 2 "=d"))] - "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "#" - "&& reload_completed" - [(set (match_dup 2) - (float:DF (match_dup 1))) - (set (match_dup 0) - (float_truncate:SF (match_dup 2)))] - "" - [(set_attr "length" "8") - (set_attr "type" "fp")]) - -;; Twiddles bits to avoid double rounding. -;; 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" - [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "") - (const_int 53))) - (parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1) - (const_int 2047))) - (clobber (scratch:CC))]) - (set (match_dup 3) (plus:DI (match_dup 3) - (const_int 1))) - (set (match_dup 0) (plus:DI (match_dup 0) - (const_int 2047))) - (set (match_dup 4) (compare:CCUNS (match_dup 3) - (const_int 2))) - (set (match_dup 0) (ior:DI (match_dup 0) - (match_dup 1))) - (parallel [(set (match_dup 0) (and:DI (match_dup 0) - (const_int -2048))) - (clobber (scratch:CC))]) - (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) - (label_ref (match_operand:DI 2 "" "")) - (pc))) - (set (match_dup 0) (match_dup 1))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - " -{ - operands[3] = gen_reg_rtx (DImode); - operands[4] = gen_reg_rtx (CCUNSmode); -}") - -(define_expand "floatunsdisf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" - "") - -(define_insn "floatunsdisf2_fcfidus" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" - "fcfidus %0,%1" - [(set_attr "type" "fp")]) - -(define_insn_and_split "*floatunsdisf2_mem" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m"))) - (clobber (match_scratch:DI 2 "=f"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" - "#" - "&& reload_completed" - [(pc)] - " -{ - emit_move_insn (operands[2], operands[1]); - emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); - DONE; -}" - [(set_attr "length" "8") - (set_attr "type" "fpload")]) - -;; Define the DImode operations that can be done in a small number -;; of instructions. The & constraints are to prevent the register -;; allocator from allocating registers that overlap with the inputs -;; (for example, having an input in 7,8 and an output in 6,7). We -;; also allow for the output being the same as one of the inputs. - -(define_insn "*adddi3_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0") - (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))] - "! TARGET_POWERPC64" - "* -{ - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[2])) != CONST_INT - ? \"addc %L0,%L1,%L2\;adde %0,%1,%2\" - : \"addic %L0,%L1,%2\;add%G2e %0,%1\"; - else - return (GET_CODE (operands[2])) != CONST_INT - ? \"addc %0,%1,%2\;adde %L0,%L1,%L2\" - : \"addic %0,%1,%2\;add%G2e %L0,%L1\"; -}" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*subdi3_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r") - (minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I") - (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))] - "! TARGET_POWERPC64" - "* -{ - if (WORDS_BIG_ENDIAN) - return (GET_CODE (operands[1]) != CONST_INT) - ? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\" - : \"subfic %L0,%L2,%1\;subf%G1e %0,%2\"; - else - return (GET_CODE (operands[1]) != CONST_INT) - ? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\" - : \"subfic %0,%2,%1\;subf%G1e %L0,%L2\"; -}" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*negdi2_noppc64" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))] - "! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"subfic %L0,%L1,0\;subfze %0,%1\" - : \"subfic %0,%1,0\;subfze %L0,%L1\"; -}" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "mulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "! TARGET_POWERPC64" -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\"; -} - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) - (sign_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_insn "umulsidi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))] - "! TARGET_POWERPC64" - "* -{ - return (WORDS_BIG_ENDIAN) - ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\" - : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\"; -}" - [(set_attr "type" "imul") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")) - (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))] - "! TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) - (zero_extend:DI (match_dup 2))) - (const_int 32)))) - (set (match_dup 4) - (mult:SI (match_dup 1) - (match_dup 2)))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - operands[3] = operand_subword (operands[0], endian, 0, DImode); - operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode); -}") - -(define_insn "smulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (sign_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "" - "mulhw %0,%1,%2" - [(set_attr "type" "imul")]) - -(define_insn "umulsi3_highpart" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI - (match_operand:SI 1 "gpc_reg_operand" "%r")) - (zero_extend:DI - (match_operand:SI 2 "gpc_reg_operand" "r"))) - (const_int 32))))] - "" - "mulhwu %0,%1,%2" - [(set_attr "type" "imul")]) - -;; Shift by a variable amount is too complex to be worth open-coding. We -;; just handle shifts by constants. -(define_insn "ashrdi3_no_power" - [(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_POWERPC64 && WORDS_BIG_ENDIAN" - "@ - srawi %0,%1,31\;srawi %L0,%1,%h2 - srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2" - [(set_attr "type" "two,three") - (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. - -(define_insn "muldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") - (match_operand:DI 2 "reg_or_short_operand" "r,I")))] - "TARGET_POWERPC64" - "@ - mulld %0,%1,%2 - mulli %0,%1,%2" - [(set (attr "type") - (cond [(match_operand:SI 2 "s8bit_cint_operand" "") - (const_string "imul3") - (match_operand:SI 2 "short_cint_operand" "") - (const_string "imul2")] - (const_string "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_micro_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 - (lshiftrt:TI (mult:TI (sign_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (sign_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhd %0,%1,%2" - [(set_attr "type" "lmul")]) - -(define_insn "umuldi3_highpart" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (truncate:DI - (lshiftrt:TI (mult:TI (zero_extend:TI - (match_operand:DI 1 "gpc_reg_operand" "%r")) - (zero_extend:TI - (match_operand:DI 2 "gpc_reg_operand" "r"))) - (const_int 64))))] - "TARGET_POWERPC64" - "mulhdu %0,%1,%2" - [(set_attr "type" "lmul")]) - -(define_expand "mulditi3" - [(set (match_operand:TI 0 "gpc_reg_operand") - (mult:TI (sign_extend:TI (match_operand:DI 1 "gpc_reg_operand")) - (sign_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] - "TARGET_POWERPC64" -{ - rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); - emit_insn (gen_muldi3 (l, operands[1], operands[2])); - emit_insn (gen_smuldi3_highpart (h, operands[1], operands[2])); - emit_move_insn (gen_lowpart (DImode, operands[0]), l); - emit_move_insn (gen_highpart (DImode, operands[0]), h); - DONE; -}) - -(define_expand "umulditi3" - [(set (match_operand:TI 0 "gpc_reg_operand") - (mult:TI (zero_extend:TI (match_operand:DI 1 "gpc_reg_operand")) - (zero_extend:TI (match_operand:DI 2 "gpc_reg_operand"))))] - "TARGET_POWERPC64" -{ - rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode); - emit_insn (gen_muldi3 (l, operands[1], operands[2])); - emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2])); - emit_move_insn (gen_lowpart (DImode, operands[0]), l); - emit_move_insn (gen_highpart (DImode, operands[0]), h); - DONE; -}) - -(define_insn "rotldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" - "@ - rldcl %0,%1,%2,0 - rldicl %0,%1,%H2,0" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - rldcl. %3,%1,%2,0 - rldicl. %3,%1,%H2,0 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (rotate:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (rotate:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "@ - rldcl. %0,%1,%2,0 - rldicl. %0,%1,%H2,0 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (rotate:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (rotate:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal4" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) - (match_operand:DI 3 "mask64_operand" "n,n")))] - "TARGET_POWERPC64" - "@ - rldc%B3 %0,%1,%2,%S3 - rldic%B3 %0,%1,%H2,%S3" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:DI 3 "mask64_operand" "n,n,n,n")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - rldc%B3. %4,%1,%2,%S3 - rldic%B3. %4,%1,%H2,%S3 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 4) - (and:DI (rotate:DI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) - (match_operand:DI 3 "mask64_operand" "n,n,n,n")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_64BIT" - "@ - rldc%B3. %0,%1,%2,%S3 - rldic%B3. %0,%1,%H2,%S3 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:DI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal7" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] - "TARGET_POWERPC64" - "@ - rldcl %0,%1,%2,56 - rldicl %0,%1,%H2,56" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - rldcl. %3,%1,%2,56 - rldicl. %3,%1,%H2,56 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:QI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal9" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_64BIT" - "@ - rldcl. %0,%1,%2,56 - rldicl. %0,%1,%H2,56 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:QI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal10" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] - "TARGET_POWERPC64" - "@ - rldcl %0,%1,%2,48 - rldicl %0,%1,%H2,48" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal11" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - rldcl. %3,%1,%2,48 - rldicl. %3,%1,%H2,48 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:HI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal12" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_64BIT" - "@ - rldcl. %0,%1,%2,48 - rldicl. %0,%1,%H2,48 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:HI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal13" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i")) 0)))] - "TARGET_POWERPC64" - "@ - rldcl %0,%1,%2,32 - rldicl %0,%1,%H2,32" - [(set_attr "type" "var_shift_rotate,integer")]) - -(define_insn "*rotldi3_internal14" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - rldcl. %3,%1,%2,32 - rldicl. %3,%1,%H2,32 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (zero_extend:DI (subreg:SI - (rotate:DI (match_dup 1) - (match_dup 2)) 0))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*rotldi3_internal15" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:DI 2 "reg_or_cint_operand" "r,i,r,i")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_64BIT" - "@ - rldcl. %0,%1,%2,32 - rldicl. %0,%1,%H2,32 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (zero_extend:DI - (subreg:SI - (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")) 0)) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "ashldi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "*ashldi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" - "@ - sld %0,%1,%2 - sldi %0,%1,%H2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "*ashldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - sld. %3,%1,%2 - sldi. %3,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (ashift:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*ashldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (ashift:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "@ - sld. %0,%1,%2 - sldi. %0,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashift:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ashift:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*ashldi3_internal4" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "const_int_operand" "n")))] - "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])" - "rldic %0,%1,%H2,%W3") - -(define_insn "ashldi3_internal5" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "const_int_operand" "n,n")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" - "@ - rldic. %4,%1,%H2,%W3 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed - && includes_rldic_lshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*ashldi3_internal6" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "const_int_operand" "n,n")) - (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_64BIT && includes_rldic_lshift_p (operands[2], operands[3])" - "@ - rldic. %0,%1,%H2,%W3 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed - && includes_rldic_lshift_p (operands[2], operands[3])" - [(set (match_dup 0) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*ashldi3_internal7" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "mask64_operand" "n")))] - "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" - "rldicr %0,%1,%H2,%S3") - -(define_insn "ashldi3_internal8" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "n,n")) - (const_int 0))) - (clobber (match_scratch:DI 4 "=r,r"))] - "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" - "@ - rldicr. %4,%1,%H2,%S3 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 4 ""))] - "TARGET_POWERPC64 && reload_completed - && includes_rldicr_lshift_p (operands[2], operands[3])" - [(set (match_dup 4) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*ashldi3_internal9" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "n,n")) - (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_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])" - "@ - rldicr. %0,%1,%H2,%S3 - #" - [(set_attr "type" "compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "const_int_operand" "")) - (match_operand:DI 3 "mask64_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "TARGET_POWERPC64 && reload_completed - && includes_rldicr_lshift_p (operands[2], operands[3])" - [(set (match_dup 0) - (and:DI (ashift:DI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "lshrdi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64" - "") - -(define_insn "*lshrdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" - "@ - srd %0,%1,%2 - srdi %0,%1,%H2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "*lshrdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT " - "@ - srd. %3,%1,%2 - srdi. %3,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (lshiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*lshrdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (lshiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "@ - srd. %0,%1,%2 - srdi. %0,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (lshiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (lshiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "ashrdi3" - [(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) - ; - 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; - } - else - FAIL; -}") - -(define_insn "*ashrdi3_internal1" - [(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 "reg_or_cint_operand" "r,i")))] - "TARGET_POWERPC64" - "@ - srad %0,%1,%2 - sradi %0,%1,%H2" - [(set_attr "type" "var_shift_rotate,shift")]) - -(define_insn "*ashrdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r"))] - "TARGET_64BIT" - "@ - srad. %3,%1,%2 - sradi. %3,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) - (ashiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*ashrdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT" - "@ - srad. %0,%1,%2 - sradi. %0,%1,%H2 - # - #" - [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") - (set_attr "length" "4,4,8,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_cint_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) - (ashiftrt:DI (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_expand "anddi3" - [(parallel - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "and64_2_operand" ""))) - (clobber (match_scratch:CC 3 ""))])] - "TARGET_POWERPC64" - "") - -(define_insn "anddi3_mc" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t"))) - (clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))] - "TARGET_POWERPC64 && rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rldic%B2 %0,%1,0,%S2 - rlwinm %0,%1,0,%m2,%M2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - #" - [(set_attr "type" "*,*,*,fast_compare,fast_compare,*") - (set_attr "length" "4,4,4,4,4,8")]) - -(define_insn "anddi3_nomc" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "?r,S,T,t"))) - (clobber (match_scratch:CC 3 "=X,X,X,X"))] - "TARGET_POWERPC64 && !rs6000_gen_cell_microcode" - "@ - and %0,%1,%2 - rldic%B2 %0,%1,0,%S2 - rlwinm %0,%1,0,%m2,%M2 - #" - [(set_attr "length" "4,4,4,8")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "mask64_2_operand" ""))) - (clobber (match_scratch:CC 3 ""))] - "TARGET_POWERPC64 - && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) - && !mask_operand (operands[2], DImode) - && !mask64_operand (operands[2], DImode)" - [(set (match_dup 0) - (and:DI (rotate:DI (match_dup 1) - (match_dup 4)) - (match_dup 5))) - (set (match_dup 0) - (and:DI (rotate:DI (match_dup 0) - (match_dup 6)) - (match_dup 7)))] -{ - build_mask64_2_operands (operands[2], &operands[4]); -}) - -(define_insn "*anddi3_internal2_mc" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,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,x,X"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" - "@ - and. %3,%1,%2 - rldic%B2. %3,%1,0,%S2 - rlwinm. %3,%1,0,%m2,%M2 - andi. %3,%1,%b2 - andis. %3,%1,%u2 - # - # - # - # - # - # - #" - [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\ - fast_compare,compare,compare,compare,compare,compare,\ - compare,compare") - (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "mask64_2_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 "")) - (clobber (match_scratch:CC 4 ""))] - "TARGET_64BIT && reload_completed - && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) - && !mask_operand (operands[2], DImode) - && !mask64_operand (operands[2], DImode)" - [(set (match_dup 3) - (and:DI (rotate:DI (match_dup 1) - (match_dup 5)) - (match_dup 6))) - (parallel [(set (match_dup 0) - (compare:CC (and:DI (rotate:DI (match_dup 3) - (match_dup 7)) - (match_dup 8)) - (const_int 0))) - (clobber (match_dup 3))])] - " -{ - build_mask64_2_operands (operands[2], &operands[5]); -}") - -(define_insn "*anddi3_internal3_mc" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,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,x,X"))] - "TARGET_64BIT && rs6000_gen_cell_microcode" - "@ - and. %0,%1,%2 - rldic%B2. %0,%1,0,%S2 - rlwinm. %0,%1,0,%m2,%M2 - andi. %0,%1,%b2 - andis. %0,%1,%u2 - # - # - # - # - # - # - #" - [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\ - fast_compare,compare,compare,compare,compare,compare,\ - compare,compare") - (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "and64_2_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "TARGET_64BIT && reload_completed" - [(parallel [(set (match_dup 0) - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_split - [(set (match_operand:CC 3 "cc_reg_operand" "") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "mask64_2_operand" "")) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 ""))] - "TARGET_64BIT && reload_completed - && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) - && !mask_operand (operands[2], DImode) - && !mask64_operand (operands[2], DImode)" - [(set (match_dup 0) - (and:DI (rotate:DI (match_dup 1) - (match_dup 5)) - (match_dup 6))) - (parallel [(set (match_dup 3) - (compare:CC (and:DI (rotate:DI (match_dup 0) - (match_dup 7)) - (match_dup 8)) - (const_int 0))) - (set (match_dup 0) - (and:DI (rotate:DI (match_dup 0) - (match_dup 7)) - (match_dup 8)))])] - " -{ - build_mask64_2_operands (operands[2], &operands[5]); -}") - -(define_expand "iordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_logical_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (non_logical_cint_operand (operands[2], DImode)) - { - HOST_WIDE_INT value; - rtx tmp = ((!can_create_pseudo_p () - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - if (GET_CODE (operands[2]) == CONST_INT) - { - value = INTVAL (operands[2]); - emit_insn (gen_iordi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - } - else - { - value = CONST_DOUBLE_LOW (operands[2]); - emit_insn (gen_iordi3 (tmp, operands[1], - immed_double_const (value - & (~ (HOST_WIDE_INT) 0xffff), - 0, DImode))); - } - - emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_expand "xordi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_logical_cint_operand" "")))] - "TARGET_POWERPC64" - " -{ - if (non_logical_cint_operand (operands[2], DImode)) - { - HOST_WIDE_INT value; - rtx tmp = ((!can_create_pseudo_p () - || rtx_equal_p (operands[0], operands[1])) - ? operands[0] : gen_reg_rtx (DImode)); - - if (GET_CODE (operands[2]) == CONST_INT) - { - value = INTVAL (operands[2]); - emit_insn (gen_xordi3 (tmp, operands[1], - GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff)))); - } - else - { - value = CONST_DOUBLE_LOW (operands[2]); - emit_insn (gen_xordi3 (tmp, operands[1], - immed_double_const (value - & (~ (HOST_WIDE_INT) 0xffff), - 0, DImode))); - } - - emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); - DONE; - } -}") - -(define_insn "*booldi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") - (match_operator:DI 3 "boolean_or_operator" - [(match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,JF")]))] - "TARGET_POWERPC64" - "@ - %q3 %0,%1,%2 - %q3i %0,%1,%b2 - %q3is %0,%1,%u2") - -(define_insn "*booldi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_or_operator" - [(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_64BIT" - "@ - %q4. %3,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(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) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*booldi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_or_operator" - [(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") - (match_dup 4))] - "TARGET_64BIT" - "@ - %q4. %0,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(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" "") - (match_dup 4))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; 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 - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operator:DI 3 "boolean_or_operator" - [(match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")]))] - "TARGET_POWERPC64" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 0) (match_dup 5))] -" -{ - rtx i3,i4; - - if (GET_CODE (operands[2]) == CONST_DOUBLE) - { - HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); - i3 = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff), - 0, DImode); - i4 = GEN_INT (value & 0xffff); - } - else - { - i3 = GEN_INT (INTVAL (operands[2]) - & (~ (HOST_WIDE_INT) 0xffff)); - i4 = GEN_INT (INTVAL (operands[2]) & 0xffff); - } - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode, - operands[1], i3); - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode, - operands[0], i4); -}") - -(define_insn "*boolcdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operator:DI 3 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (match_operand:DI 2 "gpc_reg_operand" "r")]))] - "TARGET_POWERPC64" - "%q3 %0,%2,%1") - -(define_insn "*boolcdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not: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_64BIT" - "@ - %q4. %3,%2,%1 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not: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) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*boolcdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not: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") - (match_dup 4))] - "TARGET_64BIT" - "@ - %q4. %0,%2,%1 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not: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" "") - (match_dup 4))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*boolccdi3_internal1" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operator:DI 3 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))]))] - "TARGET_POWERPC64" - "%q3 %0,%1,%2") - -(define_insn "*boolccdi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))]) - (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r"))] - "TARGET_64BIT" - "@ - %q4. %3,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))]) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 3) (match_dup 4)) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*boolccdi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))]) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (match_dup 4))] - "TARGET_64BIT" - "@ - %q4. %0,%1,%2 - #" - [(set_attr "type" "fast_compare,compare") - (set_attr "length" "4,8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operator:DI 4 "boolean_operator" - [(not:DI (match_operand:DI 1 "gpc_reg_operand" "")) - (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))]) - (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (match_dup 4))] - "TARGET_POWERPC64 && reload_completed" - [(set (match_dup 0) (match_dup 4)) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -;; Now define ways of moving data around. - -;; Set up a register with a value from the GOT table - -(define_expand "movsi_got" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (unspec:SI [(match_operand:SI 1 "got_operand" "") - (match_dup 2)] UNSPEC_MOVSI_GOT))] - "DEFAULT_ABI == ABI_V4 && flag_pic == 1" - " -{ - if (GET_CODE (operands[1]) == CONST) - { - rtx offset = const0_rtx; - HOST_WIDE_INT value; - - operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); - value = INTVAL (offset); - if (value != 0) - { - rtx tmp = (!can_create_pseudo_p () - ? operands[0] - : gen_reg_rtx (Pmode)); - emit_insn (gen_movsi_got (tmp, operands[1])); - emit_insn (gen_addsi3 (operands[0], tmp, offset)); - DONE; - } - } - - operands[2] = rs6000_got_register (operands[1]); -}") - -(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")] - UNSPEC_MOVSI_GOT))] - "DEFAULT_ABI == ABI_V4 && flag_pic == 1" - "lwz %0,%a1@got(%2)" - [(set_attr "type" "load")]) - -;; Used by sched, shorten_branches and final when the GOT pseudo reg -;; didn't get allocated to a hard register. -(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" "")] - 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)] - UNSPEC_MOVSI_GOT))] - "") - -;; For SI, we special-case integers that can't be loaded in one insn. We -;; do the load 16-bits at a time. We could do this by loading from memory, -;; and this is even supposed to be faster, but it is simpler not to get -;; integers in the TOC. -(define_insn "movsi_low" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand 2 "" ""))))] - "TARGET_MACHO && ! TARGET_64BIT" - "lwz %0,lo16(%2)(%1)" - [(set_attr "type" "load") - (set_attr "length" "4")]) - -(define_insn "*movsi_internal1" - [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h") - (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))] - "!TARGET_SINGLE_FPU && - (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" - "@ - mr %0,%1 - la %0,%a1 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - li %0,%1 - lis %0,%v1 - # - mf%1 %0 - mt%0 %1 - mt%0 %1 - nop" - [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*") - (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")]) - -(define_insn "*movsi_internal1_single" - [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f") - (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))] - "TARGET_SINGLE_FPU && - (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" - "@ - mr %0,%1 - la %0,%a1 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - li %0,%1 - lis %0,%v1 - # - mf%1 %0 - mt%0 %1 - mt%0 %1 - nop - stfs%U0%X0 %1,%0 - lfs%U1%X1 %0,%1" - [(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 -;; sequence. - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (match_operand:SI 1 "const_int_operand" ""))] - "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 - && (INTVAL (operands[1]) & 0xffff) != 0" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (ior:SI (match_dup 0) - (match_dup 3)))] - " -{ rtx tem = rs6000_emit_set_const (operands[0], SImode, operands[1], 2); - - if (tem == operands[0]) - DONE; - else - FAIL; -}") - -(define_insn "*mov<mode>_internal2" - [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") - (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] - "" - "@ - cmp<wd>i %2,%0,0 - mr. %0,%1 - #" - [(set_attr "type" "cmp,compare,cmp") - (set_attr "length" "4,4,8")]) - -(define_split - [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (match_operand:P 1 "gpc_reg_operand" "") - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))] - "reload_completed" - [(set (match_dup 0) (match_dup 1)) - (set (match_dup 2) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*movhi_internal" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h") - (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))] - "gpc_reg_operand (operands[0], HImode) - || gpc_reg_operand (operands[1], HImode)" - "@ - mr %0,%1 - lhz%U1%X1 %0,%1 - sth%U0%X0 %1,%0 - li %0,%w1 - mf%1 %0 - mt%0 %1 - nop" - [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")]) - -(define_expand "mov<mode>" - [(set (match_operand:INT 0 "general_operand" "") - (match_operand:INT 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") - -(define_insn "*movqi_internal" - [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h") - (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))] - "gpc_reg_operand (operands[0], QImode) - || gpc_reg_operand (operands[1], QImode)" - "@ - mr %0,%1 - lbz%U1%X1 %0,%1 - stb%U0%X0 %1,%0 - li %0,%1 - mf%1 %0 - mt%0 %1 - nop" - [(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. -;; This lets us not shift in the most common case of CR0. -(define_expand "movcc" - [(set (match_operand:CC 0 "nonimmediate_operand" "") - (match_operand:CC 1 "nonimmediate_operand" ""))] - "" - "") - -(define_insn "*movcc_internal1" - [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m") - (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))] - "register_operand (operands[0], CCmode) - || register_operand (operands[1], CCmode)" - "@ - mcrf %0,%1 - mtcrf 128,%1 - rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff - crxor %0,%0,%0 - mfcr %0%Q1 - mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000 - mr %0,%1 - li %0,%1 - mf%1 %0 - mt%0 %1 - lwz%U1%X1 %0,%1 - stw%U0%U1 %1,%0" - [(set (attr "type") - (cond [(eq_attr "alternative" "0,3") - (const_string "cr_logical") - (eq_attr "alternative" "1,2") - (const_string "mtcr") - (eq_attr "alternative" "6,7") - (const_string "integer") - (eq_attr "alternative" "8") - (const_string "mfjmpr") - (eq_attr "alternative" "9") - (const_string "mtjmpr") - (eq_attr "alternative" "10") - (const_string "load") - (eq_attr "alternative" "11") - (const_string "store") - (match_test "TARGET_MFCRF") - (const_string "mfcrf") - ] - (const_string "mfcr"))) - (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")]) - -;; For floating-point, we normally deal with the floating-point registers -;; unless -msoft-float is used. The sole exception is that parameter passing -;; can produce floating-point values in fixed-point registers. Unless the -;; value is a simple constant or already in memory, we deal with this by -;; allocating memory and copying the value explicitly via that memory location. -(define_expand "movsf" - [(set (match_operand:SF 0 "nonimmediate_operand" "") - (match_operand:SF 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], SFmode); DONE; }") - -(define_split - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (match_operand:SF 1 "const_double_operand" ""))] - "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 3))] - " -{ - long l; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_SINGLE (rv, l); - - if (! TARGET_POWERPC64) - operands[2] = operand_subword (operands[0], 0, 0, SFmode); - else - operands[2] = gen_lowpart (SImode, operands[0]); - - operands[3] = gen_int_mode (l, SImode); -}") - -(define_insn "*movsf_hardfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,*c*l,!r,*h,!r,!r") - (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,h,0,G,Fn"))] - "(gpc_reg_operand (operands[0], SFmode) - || gpc_reg_operand (operands[1], SFmode)) - && (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT)" - "@ - mr %0,%1 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - fmr %0,%1 - lfs%U1%X1 %0,%1 - stfs%U0%X0 %1,%0 - mt%0 %1 - mf%1 %0 - nop - # - #" - [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*") - (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,r,r,m,r,r,r,r,*h") - (match_operand:SF 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))] - "(gpc_reg_operand (operands[0], SFmode) - || gpc_reg_operand (operands[1], SFmode)) - && (TARGET_SOFT_FLOAT || !TARGET_FPRS)" - "@ - mr %0,%1 - mt%0 %1 - mf%1 %0 - lwz%U1%X1 %0,%1 - stw%U0%X0 %1,%0 - li %0,%1 - lis %0,%v1 - # - # - nop" - [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,8,4")]) - - -(define_expand "movdf" - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (match_operand:DF 1 "any_operand" ""))] - "" - "{ rs6000_emit_move (operands[0], operands[1], DFmode); DONE; }") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "const_int_operand" ""))] - "! TARGET_POWERPC64 && 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 1))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - HOST_WIDE_INT value = INTVAL (operands[1]); - - operands[2] = operand_subword (operands[0], endian, 0, DFmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode); -#if HOST_BITS_PER_WIDE_INT == 32 - operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; -#else - operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); -#endif -}") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "const_double_operand" ""))] - "! TARGET_POWERPC64 && 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))] - " -{ - int endian = (WORDS_BIG_ENDIAN == 0); - long l[2]; - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (rv, l); - - operands[2] = operand_subword (operands[0], endian, 0, DFmode); - operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode); - operands[4] = gen_int_mode (l[endian], SImode); - operands[5] = gen_int_mode (l[1 - endian], SImode); -}") - -(define_split - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && 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 3))] - " -{ - 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); - - operands[2] = gen_lowpart (DImode, operands[0]); - /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ -#if HOST_BITS_PER_WIDE_INT >= 64 - val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 - | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - - operands[3] = gen_int_mode (val, DImode); -#else - operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); -#endif -}") - -;; Don't have reload use general registers to load a constant. It is -;; less efficient than loading the constant into an FP register, since -;; it will probably be used there. - -;; The move constraints are ordered to prefer floating point registers before -;; general purpose registers to avoid doing a store and a load to get the value -;; into a floating point register when it is needed for a floating point -;; operation. Prefer traditional floating point registers over VSX registers, -;; since the D-form version of the memory instructions does not need a GPR for -;; reloading. - -(define_insn "*movdf_hardfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,d,d,ws,?wa,Z,?Z,ws,?wa,wa,Y,r,!r,!r,!r,!r") - (match_operand:DF 1 "input_operand" "d,m,d,Z,Z,ws,wa,ws,wa,j,r,Y,r,G,H,F"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && (gpc_reg_operand (operands[0], DFmode) - || gpc_reg_operand (operands[1], DFmode))" - "@ - stfd%U0%X0 %1,%0 - lfd%U1%X1 %0,%1 - fmr %0,%1 - lxsd%U1x %x0,%y1 - lxsd%U1x %x0,%y1 - stxsd%U0x %x1,%y0 - stxsd%U0x %x1,%y0 - xxlor %x0,%x1,%x1 - xxlor %x0,%x1,%x1 - xxlxor %x0,%x0,%x0 - # - # - # - # - # - #" - [(set_attr "type" "fpstore,fpload,fp,fpload,fpload,fpstore,fpstore,vecsimple,vecsimple,vecsimple,store,load,two,fp,fp,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,8,8,8,12,16")]) - -(define_insn "*movdf_softfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,r,r,r,r") - (match_operand:DF 1 "input_operand" "r,Y,r,G,H,F"))] - "! TARGET_POWERPC64 - && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) - || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) - && (gpc_reg_operand (operands[0], DFmode) - || gpc_reg_operand (operands[1], DFmode))" - "#" - [(set_attr "type" "store,load,two,*,*,*") - (set_attr "length" "8,8,8,8,12,16")]) - -;; Reload patterns to support gpr load/store with misaligned mem. -;; and multiple gpr load/store at offset >= 0xfffc -(define_expand "reload_<mode>_store" - [(parallel [(match_operand 0 "memory_operand" "=m") - (match_operand 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "register_operand" "=&b")])] - "" -{ - rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true); - DONE; -}) - -(define_expand "reload_<mode>_load" - [(parallel [(match_operand 0 "gpc_reg_operand" "=r") - (match_operand 1 "memory_operand" "m") - (match_operand:GPR 2 "register_operand" "=b")])] - "" -{ - rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false); - DONE; -}) - -; ld/std require word-aligned displacements -> 'Y' constraint. -; List Y->r and r->Y before r->r for reload. -(define_insn "*movdf_hardfloat64_mfpgpr" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,m,d,d,wa,*c*l,!r,*h,!r,!r,!r,r,d") - (match_operand:DF 1 "input_operand" "r,Y,r,ws,?wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F,d,r"))] - "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_DOUBLE_FLOAT - && (gpc_reg_operand (operands[0], DFmode) - || gpc_reg_operand (operands[1], DFmode))" - "@ - std%U0%X0 %1,%0 - ld%U1%X1 %0,%1 - mr %0,%1 - xxlor %x0,%x1,%x1 - xxlor %x0,%x1,%x1 - lxsd%U1x %x0,%y1 - lxsd%U1x %x0,%y1 - stxsd%U0x %x1,%y0 - stxsd%U0x %x1,%y0 - stfd%U0%X0 %1,%0 - lfd%U1%X1 %0,%1 - fmr %0,%1 - xxlxor %x0,%x0,%x0 - mt%0 %1 - mf%1 %0 - nop - # - # - # - mftgpr %0,%1 - mffgpr %0,%1" - [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fpstore,fpload,fp,vecsimple,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4")]) - -; 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" "=m,d,d,Y,r,!r,ws,?wa,Z,?Z,ws,?wa,wa,*c*l,!r,*h,!r,!r,!r") - (match_operand:DF 1 "input_operand" "d,m,d,r,Y,r,Z,Z,ws,wa,ws,wa,j,r,h,0,G,H,F"))] - "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && TARGET_DOUBLE_FLOAT - && (gpc_reg_operand (operands[0], DFmode) - || gpc_reg_operand (operands[1], DFmode))" - "@ - stfd%U0%X0 %1,%0 - lfd%U1%X1 %0,%1 - fmr %0,%1 - std%U0%X0 %1,%0 - ld%U1%X1 %0,%1 - mr %0,%1 - lxsd%U1x %x0,%y1 - lxsd%U1x %x0,%y1 - stxsd%U0x %x1,%y0 - stxsd%U0x %x1,%y0 - xxlor %x0,%x1,%x1 - xxlor %x0,%x1,%x1 - xxlxor %x0,%x0,%x0 - mt%0 %1 - mf%1 %0 - nop - # - # - #" - [(set_attr "type" "fpstore,fpload,fp,store,load,*,fpload,fpload,fpstore,fpstore,vecsimple,vecsimple,vecsimple,mtjmpr,mfjmpr,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16")]) - -(define_insn "*movdf_softfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h") - (match_operand:DF 1 "input_operand" "r,Y,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))" - "@ - std%U0%X0 %1,%0 - ld%U1%X1 %0,%1 - mr %0,%1 - mt%0 %1 - mf%1 %0 - # - # - # - nop" - [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*") - (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" ""))] - "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128" - "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }") - -;; It's important to list Y->r and r->Y before r->r because otherwise -;; reload, given m->r, will try to pick r->r and reload it, which -;; doesn't make progress. -(define_insn_and_split "*movtf_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=m,d,d,Y,r,r") - (match_operand:TF 1 "input_operand" "d,m,d,r,YGHF,r"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128 - && (gpc_reg_operand (operands[0], TFmode) - || gpc_reg_operand (operands[1], TFmode))" - "#" - "&& reload_completed" - [(pc)] -{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } - [(set_attr "length" "8,8,8,20,20,16")]) - -(define_insn_and_split "*movtf_softfloat" - [(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=Y,r,r") - (match_operand:TF 1 "input_operand" "r,YGHF,r"))] - "!TARGET_IEEEQUAD - && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_LONG_DOUBLE_128 - && (gpc_reg_operand (operands[0], TFmode) - || gpc_reg_operand (operands[1], TFmode))" - "#" - "&& reload_completed" - [(pc)] -{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } - [(set_attr "length" "20,20,16")]) - -(define_expand "extenddftf2" - [(set (match_operand:TF 0 "nonimmediate_operand" "") - (float_extend:TF (match_operand:DF 1 "input_operand" "")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128" -{ - if (TARGET_E500_DOUBLE) - emit_insn (gen_spe_extenddftf2 (operands[0], operands[1])); - else - emit_insn (gen_extenddftf2_fprs (operands[0], operands[1])); - DONE; -}) - -(define_expand "extenddftf2_fprs" - [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "") - (float_extend:TF (match_operand:DF 1 "input_operand" ""))) - (use (match_dup 2))])] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" -{ - operands[2] = CONST0_RTX (DFmode); - /* Generate GOT reference early for SVR4 PIC. */ - if (DEFAULT_ABI == ABI_V4 && flag_pic) - operands[2] = validize_mem (force_const_mem (DFmode, operands[2])); -}) - -(define_insn_and_split "*extenddftf2_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=m,Y,d,&d,r") - (float_extend:TF (match_operand:DF 1 "input_operand" "d,r,md,md,rmGHF"))) - (use (match_operand:DF 2 "zero_reg_mem_operand" "d,r,m,d,n"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" - "#" - "&& reload_completed" - [(pc)] -{ - 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_expand "extendsftf2" - [(set (match_operand:TF 0 "nonimmediate_operand" "") - (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128" -{ - rtx tmp = gen_reg_rtx (DFmode); - emit_insn (gen_extendsfdf2 (tmp, operands[1])); - emit_insn (gen_extenddftf2 (operands[0], tmp)); - DONE; -}) - -(define_expand "trunctfdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128" - "") - -(define_insn_and_split "trunctfdf2_internal1" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))] - "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" - "@ - # - fmr %0,%1" - "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" - [(const_int 0)] -{ - emit_note (NOTE_INSN_DELETED); - DONE; -} - [(set_attr "type" "fp")]) - -(define_insn "trunctfdf2_internal2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=d") - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))] - "!TARGET_IEEEQUAD && TARGET_XL_COMPAT - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" - "fadd %0,%1,%L1" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_addsub_d")]) - -(define_expand "trunctfsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128" -{ - if (TARGET_E500_DOUBLE) - emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1])); - else - emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1])); - DONE; -}) - -(define_insn_and_split "trunctfsf2_fprs" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d"))) - (clobber (match_scratch:DF 2 "=d"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT - && TARGET_LONG_DOUBLE_128" - "#" - "&& reload_completed" - [(set (match_dup 2) - (float_truncate:DF (match_dup 1))) - (set (match_dup 0) - (float_truncate:SF (match_dup 2)))] - "") - -(define_expand "floatsitf2" - [(set (match_operand:TF 0 "gpc_reg_operand" "") - (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128" -{ - rtx tmp = gen_reg_rtx (DFmode); - expand_float (tmp, operands[1], false); - emit_insn (gen_extenddftf2 (operands[0], tmp)); - DONE; -}) - -; 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" "=d") - (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")] - UNSPEC_FIX_TRUNC_TF)) - (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" - "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_expand "fix_trunctfsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))] - "!TARGET_IEEEQUAD && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128" -{ - if (TARGET_E500_DOUBLE) - emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1])); - else - emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1])); - DONE; -}) - -(define_expand "fix_trunctfsi2_fprs" - [(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))])] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" -{ - 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)); -}) - -(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" "d"))) - (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) - (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) - (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) - (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" - "#" - "" - [(pc)] -{ - rtx lowword; - emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3])); - - gcc_assert (MEM_P (operands[5])); - lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); - - emit_insn (gen_fctiwz_df (operands[4], operands[2])); - emit_move_insn (operands[5], operands[4]); - emit_move_insn (operands[0], lowword); - DONE; -}) - -(define_expand "negtf2" - [(set (match_operand:TF 0 "gpc_reg_operand" "") - (neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128" - "") - -(define_insn "negtf2_internal" - [(set (match_operand:TF 0 "gpc_reg_operand" "=d") - (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" - "* -{ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"fneg %L0,%L1\;fneg %0,%1\"; - else - return \"fneg %0,%1\;fneg %L0,%L1\"; -}" - [(set_attr "type" "fp") - (set_attr "length" "8")]) - -(define_expand "abstf2" - [(set (match_operand:TF 0 "gpc_reg_operand" "") - (abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT - && (TARGET_FPRS || TARGET_E500_DOUBLE) - && TARGET_LONG_DOUBLE_128" - " -{ - rtx label = gen_label_rtx (); - if (TARGET_E500_DOUBLE) - { - if (flag_finite_math_only && !flag_trapping_math) - emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label)); - else - emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label)); - } - else - emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); - emit_label (label); - DONE; -}") - -(define_expand "abstf2_internal" - [(set (match_operand:TF 0 "gpc_reg_operand" "") - (match_operand:TF 1 "gpc_reg_operand" "")) - (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)))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && TARGET_LONG_DOUBLE_128" - " -{ - 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. - -;; List r->r after r->Y, otherwise reload will try to reload a -;; non-offsettable address by using r->r which won't make progress. -;; Use of fprs is disparaged slightly otherwise reload prefers to reload -;; a gpr into a fpr instead of reloading an invalid 'Y' address -(define_insn "*movdi_internal32" - [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r,?wa") - (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF,O"))] - "! TARGET_POWERPC64 - && (gpc_reg_operand (operands[0], DImode) - || gpc_reg_operand (operands[1], DImode))" - "@ - # - # - # - stfd%U0%X0 %1,%0 - lfd%U1%X1 %0,%1 - fmr %0,%1 - # - xxlxor %x0,%x0,%x0" - [(set_attr "type" "store,load,*,fpstore,fpload,fp,*,vecsimple")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_int_operand" ""))] - "! TARGET_POWERPC64 && reload_completed - && gpr_or_gpr_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 1))] - " -{ - HOST_WIDE_INT value = INTVAL (operands[1]); - operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, - DImode); - operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, - DImode); -#if HOST_BITS_PER_WIDE_INT == 32 - operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; -#else - operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); -#endif -}") - -(define_split - [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "") - (match_operand:DIFD 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_insn "*movdi_mfpgpr" - [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*d") - (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*d,r"))] - "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS - && (gpc_reg_operand (operands[0], DImode) - || gpc_reg_operand (operands[1], DImode))" - "@ - std%U0%X0 %1,%0 - ld%U1%X1 %0,%1 - mr %0,%1 - li %0,%1 - lis %0,%v1 - # - stfd%U0%X0 %1,%0 - lfd%U1%X1 %0,%1 - fmr %0,%1 - mf%1 %0 - mt%0 %1 - nop - mftgpr %0,%1 - mffgpr %0,%1" - [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr") - (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4")]) - -(define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,?wa") - (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,O"))] - "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS) - && (gpc_reg_operand (operands[0], DImode) - || gpc_reg_operand (operands[1], DImode))" - "@ - std%U0%X0 %1,%0 - ld%U1%X1 %0,%1 - mr %0,%1 - li %0,%1 - lis %0,%v1 - # - stfd%U0%X0 %1,%0 - lfd%U1%X1 %0,%1 - fmr %0,%1 - mf%1 %0 - mt%0 %1 - nop - xxlxor %x0,%x0,%x0" - [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,vecsimple") - (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")]) - -;; immediate value valid for a single instruction hiding in a const_double -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operand:DI 1 "const_double_operand" "F"))] - "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64 - && GET_CODE (operands[1]) == CONST_DOUBLE - && num_insns_constant (operands[1], DImode) == 1" - "* -{ - return ((unsigned HOST_WIDE_INT) - (CONST_DOUBLE_LOW (operands[1]) + 0x8000) < 0x10000) - ? \"li %0,%1\" : \"lis %0,%v1\"; -}") - -;; Generate all one-bits and clear left or right. -;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber. -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "mask64_operand" ""))] - "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" - [(set (match_dup 0) (const_int -1)) - (set (match_dup 0) - (and:DI (rotate:DI (match_dup 0) - (const_int 0)) - (match_dup 1)))] - "") - -;; Split a load of a large constant into the appropriate five-instruction -;; sequence. Handle anything in a constant number of insns. -;; When non-easy constants can go in the TOC, this should use -;; easy_fp_constant predicate. -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_int_operand" ""))] - "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" - [(set (match_dup 0) (match_dup 2)) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] - " -{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5); - - if (tem == operands[0]) - DONE; - else - FAIL; -}") - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (match_operand:DI 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" - [(set (match_dup 0) (match_dup 2)) - (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] - " -{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5); - - if (tem == operands[0]) - DONE; - else - FAIL; -}") - -;; TImode is similar, except that we usually want to compute the address into -;; a register and use lsi/stsi (the exception is during reload). - -(define_insn "*movti_string" - [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r") - (match_operand:TI 1 "input_operand" "r,r,Q,Y,r,n"))] - "! TARGET_POWERPC64 - && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - if (TARGET_STRING) - return \"stswi %1,%P0,16\"; - case 1: - return \"#\"; - case 2: - /* If the address is not used in the output, we can use lsi. Otherwise, - fall through to generating four loads. */ - if (TARGET_STRING - && ! reg_overlap_mentioned_p (operands[0], operands[1])) - return \"lswi %0,%P1,16\"; - /* ... fall through ... */ - case 3: - case 4: - case 5: - return \"#\"; - } -}" - [(set_attr "type" "store_ux,store_ux,load_ux,load_ux,*,*") - (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING") - (const_string "always") - (const_string "conditional")))]) - -(define_insn "*movti_ppc64" - [(set (match_operand:TI 0 "nonimmediate_operand" "=Y,r,r") - (match_operand:TI 1 "input_operand" "r,Y,r"))] - "(TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) - || gpc_reg_operand (operands[1], TImode))) - && VECTOR_MEM_NONE_P (TImode)" - "#" - [(set_attr "type" "store,load,*")]) - -(define_split - [(set (match_operand:TI 0 "gpc_reg_operand" "") - (match_operand:TI 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && VECTOR_MEM_NONE_P (TImode)" - [(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, - TImode); - operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, - TImode); - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); - operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - } - else if (GET_CODE (operands[1]) == CONST_INT) - { - operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); - operands[5] = operands[1]; - } - else - FAIL; -}") - -(define_split - [(set (match_operand:TI 0 "nonimmediate_operand" "") - (match_operand:TI 1 "input_operand" ""))] - "reload_completed && VECTOR_MEM_NONE_P (TImode) - && 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 "" "") - (match_operand:SI 1 "" "")) - (use (match_operand:SI 2 "" ""))])] - "TARGET_STRING && !TARGET_POWERPC64" - " -{ - int regno; - int count; - rtx op1; - int i; - - /* Support only loading a constant number of fixed-point registers from - memory and only bother with this if more than two; the machine - doesn't support more than eight. */ - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 2 - || INTVAL (operands[2]) > 8 - || GET_CODE (operands[1]) != MEM - || GET_CODE (operands[0]) != REG - || REGNO (operands[0]) >= 32) - FAIL; - - count = INTVAL (operands[2]); - regno = REGNO (operands[0]); - - operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); - op1 = replace_equiv_address (operands[1], - force_reg (SImode, XEXP (operands[1], 0))); - - for (i = 0; i < count; i++) - XVECEXP (operands[3], 0, i) - = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i), - adjust_address_nv (op1, SImode, i * 4)); -}") - -(define_insn "*ldmsi8" - [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 2 "gpc_reg_operand" "") - (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 4)))) - (set (match_operand:SI 4 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 8)))) - (set (match_operand:SI 5 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 12)))) - (set (match_operand:SI 6 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 16)))) - (set (match_operand:SI 7 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 20)))) - (set (match_operand:SI 8 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 24)))) - (set (match_operand:SI 9 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 28))))])] - "TARGET_STRING && XVECLEN (operands[0], 0) == 8" - "* -{ return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") - (set_attr "length" "32")]) - -(define_insn "*ldmsi7" - [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 2 "gpc_reg_operand" "") - (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 4)))) - (set (match_operand:SI 4 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 8)))) - (set (match_operand:SI 5 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 12)))) - (set (match_operand:SI 6 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 16)))) - (set (match_operand:SI 7 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 20)))) - (set (match_operand:SI 8 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 24))))])] - "TARGET_STRING && XVECLEN (operands[0], 0) == 7" - "* -{ return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") - (set_attr "length" "32")]) - -(define_insn "*ldmsi6" - [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 2 "gpc_reg_operand" "") - (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 4)))) - (set (match_operand:SI 4 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 8)))) - (set (match_operand:SI 5 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 12)))) - (set (match_operand:SI 6 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 16)))) - (set (match_operand:SI 7 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 20))))])] - "TARGET_STRING && XVECLEN (operands[0], 0) == 6" - "* -{ return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") - (set_attr "length" "32")]) - -(define_insn "*ldmsi5" - [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 2 "gpc_reg_operand" "") - (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 4)))) - (set (match_operand:SI 4 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 8)))) - (set (match_operand:SI 5 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 12)))) - (set (match_operand:SI 6 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 16))))])] - "TARGET_STRING && XVECLEN (operands[0], 0) == 5" - "* -{ return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") - (set_attr "length" "32")]) - -(define_insn "*ldmsi4" - [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 2 "gpc_reg_operand" "") - (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 4)))) - (set (match_operand:SI 4 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 8)))) - (set (match_operand:SI 5 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] - "TARGET_STRING && XVECLEN (operands[0], 0) == 4" - "* -{ return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") - (set_attr "length" "32")]) - -(define_insn "*ldmsi3" - [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 2 "gpc_reg_operand" "") - (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 4)))) - (set (match_operand:SI 4 "gpc_reg_operand" "") - (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] - "TARGET_STRING && XVECLEN (operands[0], 0) == 3" - "* -{ return rs6000_output_load_multiple (operands); }" - [(set_attr "type" "load_ux") - (set_attr "length" "32")]) - -(define_expand "store_multiple" - [(match_par_dup 3 [(set (match_operand:SI 0 "" "") - (match_operand:SI 1 "" "")) - (clobber (scratch:SI)) - (use (match_operand:SI 2 "" ""))])] - "TARGET_STRING && !TARGET_POWERPC64" - " -{ - int regno; - int count; - rtx to; - rtx op0; - int i; - - /* Support only storing a constant number of fixed-point registers to - memory and only bother with this if more than two; the machine - doesn't support more than eight. */ - if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) <= 2 - || INTVAL (operands[2]) > 8 - || GET_CODE (operands[0]) != MEM - || GET_CODE (operands[1]) != REG - || REGNO (operands[1]) >= 32) - FAIL; - - count = INTVAL (operands[2]); - regno = REGNO (operands[1]); - - operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); - to = force_reg (SImode, XEXP (operands[0], 0)); - op0 = replace_equiv_address (operands[0], to); - - XVECEXP (operands[3], 0, 0) - = gen_rtx_SET (VOIDmode, adjust_address_nv (op0, SImode, 0), operands[1]); - XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode, - gen_rtx_SCRATCH (SImode)); - - for (i = 1; i < count; i++) - XVECEXP (operands[3], 0, i + 1) - = gen_rtx_SET (VOIDmode, - adjust_address_nv (op0, SImode, i * 4), - gen_rtx_REG (SImode, regno + i)); -}") - -(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")) - (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 && XVECLEN (operands[0], 0) == 9" - "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always")]) - -(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 && XVECLEN (operands[0], 0) == 8" - "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always")]) - -(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 && XVECLEN (operands[0], 0) == 7" - "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always")]) - -(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 && XVECLEN (operands[0], 0) == 6" - "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always")]) - -(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 && XVECLEN (operands[0], 0) == 5" - "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always")]) - -(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 && XVECLEN (operands[0], 0) == 4" - "stswi %2,%1,%O0" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always")]) - -(define_expand "setmemsi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand 2 "const_int_operand" "")) - (use (match_operand:SI 1 "" "")) - (use (match_operand:SI 3 "" ""))])] - "" - " -{ - /* If value to set is not zero, use the library routine. */ - if (operands[2] != const0_rtx) - FAIL; - - if (expand_block_clear (operands)) - DONE; - else - FAIL; -}") - -;; String/block move insn. -;; Argument 0 is the destination -;; Argument 1 is the source -;; Argument 2 is the length -;; Argument 3 is the alignment - -(define_expand "movmemsi" - [(parallel [(set (match_operand:BLK 0 "" "") - (match_operand:BLK 1 "" "")) - (use (match_operand:SI 2 "" "")) - (use (match_operand:SI 3 "" ""))])] - "" - " -{ - if (expand_block_move (operands)) - DONE; - else - FAIL; -}") - -;; Move up to 32 bytes at a time. The fixed registers are needed because the -;; register allocator doesn't have a clue about allocating 8 word registers. -;; rD/rS = r5 is preferred, efficient form. -(define_expand "movmemsi_8reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (reg:SI 5)) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (reg:SI 11)) - (clobber (reg:SI 12)) - (clobber (match_scratch:SI 5 "=X"))] - "TARGET_STRING - && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) - || INTVAL (operands[2]) == 0) - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) - && REGNO (operands[4]) == 5" - "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always") - (set_attr "length" "8")]) - -;; Move up to 24 bytes at a time. The fixed registers are needed because the -;; register allocator doesn't have a clue about allocating 6 word registers. -;; rD/rS = r5 is preferred, efficient form. -(define_expand "movmemsi_6reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (reg:SI 5)) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (reg:SI 9)) - (clobber (reg:SI 10)) - (clobber (match_scratch:SI 5 "=X"))] - "TARGET_STRING - && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) - && REGNO (operands[4]) == 5" - "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always") - (set_attr "length" "8")]) - -;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill -;; problems with TImode. -;; rD/rS = r5 is preferred, efficient form. -(define_expand "movmemsi_4reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (reg:SI 5)) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (match_scratch:SI 4 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) - (clobber (reg:SI 6)) - (clobber (reg:SI 7)) - (clobber (reg:SI 8)) - (clobber (match_scratch:SI 5 "=X"))] - "TARGET_STRING - && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 - && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8) - && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) - && REGNO (operands[4]) == 5" - "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always") - (set_attr "length" "8")]) - -;; Move up to 8 bytes at a time. -(define_expand "movmemsi_2reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (match_scratch:DI 4 "")) - (clobber (match_scratch:SI 5 ""))])] - "TARGET_STRING && ! TARGET_POWERPC64" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:DI 4 "=&r")) - (clobber (match_scratch:SI 5 "=X"))] - "TARGET_STRING && ! TARGET_POWERPC64 - && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" - "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always") - (set_attr "length" "8")]) - -;; Move up to 4 bytes at a time. -(define_expand "movmemsi_1reg" - [(parallel [(set (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (match_operand 3 "" "")) - (clobber (match_scratch:SI 4 "")) - (clobber (match_scratch:SI 5 ""))])] - "TARGET_STRING" - "") - -(define_insn "" - [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) - (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) - (use (match_operand:SI 2 "immediate_operand" "i")) - (use (match_operand:SI 3 "immediate_operand" "i")) - (clobber (match_scratch:SI 4 "=&r")) - (clobber (match_scratch:SI 5 "=X"))] - "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" - "lswi %4,%1,%2\;stswi %4,%0,%2" - [(set_attr "type" "store_ux") - (set_attr "cell_micro" "always") - (set_attr "length" "8")]) - -;; Define insns that do load or store with update. Some of these we can -;; get by using pre-decrement or pre-increment, but the hardware can also -;; do cases where the increment is not the size of the object. -;; -;; In all these cases, we use operands 0 and 1 for the register being -;; incremented because those are the operands that local-alloc will -;; tie and these are the pair most likely to be tieable (and the ones -;; that will benefit the most). - -(define_insn "*movdi_update1" - [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") - (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") - (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))) - (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && TARGET_UPDATE - && (!avoiding_indexed_address_p (DImode) - || !gpc_reg_operand (operands[2], DImode))" - "@ - ldux %3,%0,%2 - ldu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) - -(define_insn "movdi_<mode>_update" - [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") - (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) - (match_operand:DI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:P 0 "gpc_reg_operand" "=b,b") - (plus:P (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64 && TARGET_UPDATE - && (!avoiding_indexed_address_p (Pmode) - || !gpc_reg_operand (operands[2], Pmode) - || (REG_P (operands[0]) - && REGNO (operands[0]) == STACK_POINTER_REGNUM))" - "@ - stdux %3,%0,%2 - stdu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) - -;; This pattern is only conditional on TARGET_POWERPC64, as it is -;; needed for stack allocation, even if the user passes -mno-update. -(define_insn "movdi_<mode>_update_stack" - [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") - (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) - (match_operand:DI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:P 0 "gpc_reg_operand" "=b,b") - (plus:P (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC64" - "@ - stdux %3,%0,%2 - stdu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) - -(define_insn "*movsi_update1" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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 - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lwzux %3,%0,%2 - lwzu %3,%2(%0)" - [(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 && rs6000_gen_cell_microcode - && !avoiding_indexed_address_p (DImode)" - "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") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode) - || (REG_P (operands[0]) - && REGNO (operands[0]) == STACK_POINTER_REGNUM))" - "@ - stwux %3,%0,%2 - stwu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) - -;; This is an unconditional pattern; needed for stack allocation, even -;; if the user passes -mno-update. -(define_insn "movsi_update_stack" - [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "" - "@ - stwux %3,%0,%2 - stwu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) - -(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")))) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lhzux %3,%0,%2 - lhzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) - -(define_insn "*movhi_update2" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (zero_extend:SI - (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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 - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lhzux %3,%0,%2 - lhzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) - -(define_insn "*movhi_update3" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (sign_extend:SI - (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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 && rs6000_gen_cell_microcode - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lhaux %3,%0,%2 - lhau %3,%2(%0)" - [(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") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:HI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - sthux %3,%0,%2 - sthu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) - -(define_insn "*movqi_update1" - [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") - (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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 - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lbzux %3,%0,%2 - lbzu %3,%2(%0)" - [(set_attr "type" "load_ux,load_u")]) - -(define_insn "*movqi_update2" - [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (zero_extend:SI - (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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 - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lbzux %3,%0,%2 - lbzu %3,%2(%0)" - [(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") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:QI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - stbux %3,%0,%2 - stbu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) - -(define_insn "*movsf_update1" - [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") - (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lfsux %3,%0,%2 - lfsu %3,%2(%0)" - [(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") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:SF 3 "gpc_reg_operand" "f,f")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - stfsux %3,%0,%2 - stfsu %3,%2(%0)" - [(set_attr "type" "fpstore_ux,fpstore_u")]) - -(define_insn "*movsf_update3" - [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") - (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lwzux %3,%0,%2 - lwzu %3,%2(%0)" - [(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") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:SF 3 "gpc_reg_operand" "r,r")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - stwux %3,%0,%2 - stwu %3,%2(%0)" - [(set_attr "type" "store_ux,store_u")]) - -(define_insn "*movdf_update1" - [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") - (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") - (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_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - lfdux %3,%0,%2 - lfdu %3,%2(%0)" - [(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") - (match_operand:SI 2 "reg_or_short_operand" "r,I"))) - (match_operand:DF 3 "gpc_reg_operand" "d,d")) - (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") - (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE - && (!avoiding_indexed_address_p (SImode) - || !gpc_reg_operand (operands[2], SImode))" - "@ - stfdux %3,%0,%2 - stfdu %3,%2(%0)" - [(set_attr "type" "fpstore_ux,fpstore_u")]) - - -;; After inserting conditional returns we can sometimes have -;; unnecessary register moves. Unfortunately we cannot have a -;; modeless peephole here, because some single SImode sets have early -;; clobber outputs. Although those sets expand to multi-ppc-insn -;; sequences, using get_attr_length here will smash the operands -;; array. Neither is there an early_cobbler_p predicate. -;; Disallow subregs for E500 so we don't munge frob_di_df_2. -(define_peephole2 - [(set (match_operand:DF 0 "gpc_reg_operand" "") - (match_operand:DF 1 "any_operand" "")) - (set (match_operand:DF 2 "gpc_reg_operand" "") - (match_dup 0))] - "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG) - && peep2_reg_dead_p (2, operands[0])" - [(set (match_dup 2) (match_dup 1))]) - -(define_peephole2 - [(set (match_operand:SF 0 "gpc_reg_operand" "") - (match_operand:SF 1 "any_operand" "")) - (set (match_operand:SF 2 "gpc_reg_operand" "") - (match_dup 0))] - "peep2_reg_dead_p (2, operands[0])" - [(set (match_dup 2) (match_dup 1))]) - - -;; TLS support. - -;; Mode attributes for different ABIs. -(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")]) -(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")]) -(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")]) -(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")]) - -(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) - (match_operand 4 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" -{ - if (TARGET_CMODEL != CMODEL_SMALL) - return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;" - "bl %z3\;nop"; - else - return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop"; -} - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1) - (match_dup 2)] - UNSPEC_TLSGD)) - (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 3)) - (match_dup 4))) - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))])] - "" - [(set_attr "type" "two") - (set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 16) - (const_int 12)))]) - -(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) - (match_operand 4 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" -{ - if (flag_pic) - { - if (TARGET_SECURE_PLT && flag_pic == 2) - return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt"; - else - return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt"; - } - else - return "addi %0,%1,%2@got@tlsgd\;bl %z3"; -} - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1) - (match_dup 2)] - UNSPEC_TLSGD)) - (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 3)) - (match_dup 4))) - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))])] - "" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS" - "addi %0,%1,%2@got@tlsgd" - "&& TARGET_CMODEL != CMODEL_SMALL" - [(set (match_dup 3) - (high:TLSmode - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) - (set (match_dup 0) - (lo_sum:TLSmode (match_dup 3) - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))] - " -{ - operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); -}" - [(set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD)))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%1,%2@got@tlsgd@ha" - [(set_attr "length" "4")]) - -(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD)))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" - "addi %0,%1,%2@got@tlsgd@l" - [(set_attr "length" "4")]) - -(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS" - "bl %z1(%3@tlsgd)\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" -{ - if (flag_pic) - { - if (TARGET_SECURE_PLT && flag_pic == 2) - return "bl %z1+32768(%3@tlsgd)@plt"; - return "bl %z1(%3@tlsgd)@plt"; - } - return "bl %z1(%3@tlsgd)"; -} - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) - (match_operand 3 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" -{ - if (TARGET_CMODEL != CMODEL_SMALL) - return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;" - "bl %z2\;nop"; - else - return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop"; -} - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1)] - UNSPEC_TLSLD)) - (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 2)) - (match_dup 3))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))])] - "" - [(set_attr "type" "two") - (set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 16) - (const_int 12)))]) - -(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) - (match_operand 3 "" "g"))) - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" -{ - if (flag_pic) - { - if (TARGET_SECURE_PLT && flag_pic == 2) - return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt"; - else - return "addi %0,%1,%&@got@tlsld\;bl %z2@plt"; - } - else - return "addi %0,%1,%&@got@tlsld\;bl %z2"; -} - "&& TARGET_TLS_MARKERS" - [(set (match_dup 0) - (unspec:TLSmode [(match_dup 1)] - UNSPEC_TLSLD)) - (parallel [(set (match_dup 0) - (call (mem:TLSmode (match_dup 2)) - (match_dup 3))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))])] - "" - [(set_attr "length" "8")]) - -(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS" - "addi %0,%1,%&@got@tlsld" - "&& TARGET_CMODEL != CMODEL_SMALL" - [(set (match_dup 2) - (high:TLSmode - (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) - (set (match_dup 0) - (lo_sum:TLSmode (match_dup 2) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))] - " -{ - operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); -}" - [(set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(const_int 0) - (match_operand:TLSmode 1 "gpc_reg_operand" "b")] - UNSPEC_TLSLD)))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%1,%&@got@tlsld@ha" - [(set_attr "length" "4")]) - -(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))] - "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" - "addi %0,%1,%&@got@tlsld@l" - [(set_attr "length" "4")]) - -(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS" - "bl %z1(%&@tlsld)\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) - (clobber (reg:SI LR_REGNO))] - "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" -{ - if (flag_pic) - { - if (TARGET_SECURE_PLT && flag_pic == 2) - return "bl %z1+32768(%&@tlsld)@plt"; - return "bl %z1(%&@tlsld)@plt"; - } - return "bl %z1(%&@tlsld)"; -} - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSDTPREL))] - "HAVE_AS_TLS" - "addi %0,%1,%2@dtprel") - -(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSDTPRELHA))] - "HAVE_AS_TLS" - "addis %0,%1,%2@dtprel@ha") - -(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSDTPRELLO))] - "HAVE_AS_TLS" - "addi %0,%1,%2@dtprel@l") - -(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL))] - "HAVE_AS_TLS" - "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)" - "&& TARGET_CMODEL != CMODEL_SMALL" - [(set (match_dup 3) - (high:TLSmode - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) - (set (match_dup 0) - (lo_sum:TLSmode (match_dup 3) - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))] - " -{ - operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); -}" - [(set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL)))] - "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%1,%2@got@dtprel@ha" - [(set_attr "length" "4")]) - -(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL)))] - "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" - "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)" - [(set_attr "length" "4")]) - -(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTPREL))] - "HAVE_AS_TLS" - "addi %0,%1,%2@tprel") - -(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTPRELHA))] - "HAVE_AS_TLS" - "addis %0,%1,%2@tprel@ha") - -(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTPRELLO))] - "HAVE_AS_TLS" - "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_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL))] - "HAVE_AS_TLS" - "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)" - "&& TARGET_CMODEL != CMODEL_SMALL" - [(set (match_dup 3) - (high:TLSmode - (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) - (set (match_dup 0) - (lo_sum:TLSmode (match_dup 3) - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))] - " -{ - operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); -}" - [(set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) - (const_int 8) - (const_int 4)))]) - -(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL)))] - "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%1,%2@got@tprel@ha" - [(set_attr "length" "4")]) - -(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL)))] - "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" - "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)" - [(set_attr "length" "4")]) - -(define_insn "tls_tls_<TLSmode:tls_abi_suffix>" - [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") - (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") - (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSTLS))] - "TARGET_ELF && HAVE_AS_TLS" - "add %0,%1,%2@tls") - -(define_expand "tls_get_tpointer" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] - "TARGET_XCOFF && HAVE_AS_TLS" - " -{ - emit_insn (gen_tls_get_tpointer_internal ()); - emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); - DONE; -}") - -(define_insn "tls_get_tpointer_internal" - [(set (reg:SI 3) - (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) - (clobber (reg:SI LR_REGNO))] - "TARGET_XCOFF && HAVE_AS_TLS" - "bla __get_tpointer") - -(define_expand "tls_get_addr<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "") - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))] - "TARGET_XCOFF && HAVE_AS_TLS" - " -{ - emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); - emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); - emit_insn (gen_tls_get_addr_internal<mode> ()); - emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); - DONE; -}") - -(define_insn "tls_get_addr_internal<mode>" - [(set (reg:P 3) - (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) - (clobber (reg:P 0)) - (clobber (reg:P 4)) - (clobber (reg:P 5)) - (clobber (reg:P 11)) - (clobber (reg:CC CR0_REGNO)) - (clobber (reg:P LR_REGNO))] - "TARGET_XCOFF && HAVE_AS_TLS" - "bla __tls_get_addr") - -;; Next come insns related to the calling sequence. -;; -;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). -;; We move the back-chain and decrement the stack pointer. - -(define_expand "allocate_stack" - [(set (match_operand 0 "gpc_reg_operand" "") - (minus (reg 1) (match_operand 1 "reg_or_short_operand" ""))) - (set (reg 1) - (minus (reg 1) (match_dup 1)))] - "" - " -{ rtx chain = gen_reg_rtx (Pmode); - rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); - rtx neg_op0; - rtx insn, par, set, mem; - - emit_move_insn (chain, stack_bot); - - /* Check stack bounds if necessary. */ - if (crtl->limit_stack) - { - rtx available; - available = expand_binop (Pmode, sub_optab, - stack_pointer_rtx, stack_limit_rtx, - NULL_RTX, 1, OPTAB_WIDEN); - emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); - } - - if (GET_CODE (operands[1]) != CONST_INT - || INTVAL (operands[1]) < -32767 - || INTVAL (operands[1]) > 32768) - { - neg_op0 = gen_reg_rtx (Pmode); - if (TARGET_32BIT) - emit_insn (gen_negsi2 (neg_op0, operands[1])); - else - emit_insn (gen_negdi2 (neg_op0, operands[1])); - } - else - neg_op0 = GEN_INT (- INTVAL (operands[1])); - - insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack - : gen_movdi_di_update_stack)) - (stack_pointer_rtx, stack_pointer_rtx, neg_op0, - chain)); - /* Since we didn't use gen_frame_mem to generate the MEM, grab - it now and set the alias set/attributes. The above gen_*_update - calls will generate a PARALLEL with the MEM set being the first - operation. */ - par = PATTERN (insn); - gcc_assert (GET_CODE (par) == PARALLEL); - set = XVECEXP (par, 0, 0); - gcc_assert (GET_CODE (set) == SET); - mem = SET_DEST (set); - gcc_assert (MEM_P (mem)); - MEM_NOTRAP_P (mem) = 1; - set_mem_alias_set (mem, get_frame_alias_set ()); - - emit_move_insn (operands[0], virtual_stack_dynamic_rtx); - DONE; -}") - -;; These patterns say how to save and restore the stack pointer. We need not -;; save the stack pointer at function level since we are careful to -;; preserve the backchain. At block level, we have to restore the backchain -;; when we restore the stack pointer. -;; -;; For nonlocal gotos, we must save both the stack pointer and its -;; backchain and restore both. Note that in the nonlocal case, the -;; save area is a memory location. - -(define_expand "save_stack_function" - [(match_operand 0 "any_operand" "") - (match_operand 1 "any_operand" "")] - "" - "DONE;") - -(define_expand "restore_stack_function" - [(match_operand 0 "any_operand" "") - (match_operand 1 "any_operand" "")] - "" - "DONE;") - -;; Adjust stack pointer (op0) to a new value (op1). -;; First copy old stack backchain to new location, and ensure that the -;; scheduler won't reorder the sp assignment before the backchain write. -(define_expand "restore_stack_block" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 2)) - (match_dup 5) - (set (match_operand 0 "register_operand" "") - (match_operand 1 "register_operand" ""))] - "" - " -{ - rtvec p; - - operands[1] = force_reg (Pmode, operands[1]); - operands[2] = gen_reg_rtx (Pmode); - operands[3] = gen_frame_mem (Pmode, operands[0]); - operands[4] = gen_frame_mem (Pmode, operands[1]); - p = rtvec_alloc (1); - RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode, - gen_frame_mem (BLKmode, operands[0]), - const0_rtx); - operands[5] = gen_rtx_PARALLEL (VOIDmode, p); -}") - -(define_expand "save_stack_nonlocal" - [(set (match_dup 3) (match_dup 4)) - (set (match_operand 0 "memory_operand" "") (match_dup 3)) - (set (match_dup 2) (match_operand 1 "register_operand" ""))] - "" - " -{ - int units_per_word = (TARGET_32BIT) ? 4 : 8; - - /* Copy the backchain to the first word, sp to the second. */ - operands[0] = adjust_address_nv (operands[0], Pmode, 0); - operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); - operands[3] = gen_reg_rtx (Pmode); - operands[4] = gen_frame_mem (Pmode, operands[1]); -}") - -(define_expand "restore_stack_nonlocal" - [(set (match_dup 2) (match_operand 1 "memory_operand" "")) - (set (match_dup 3) (match_dup 4)) - (set (match_dup 5) (match_dup 2)) - (match_dup 6) - (set (match_operand 0 "register_operand" "") (match_dup 3))] - "" - " -{ - int units_per_word = (TARGET_32BIT) ? 4 : 8; - rtvec p; - - /* Restore the backchain from the first word, sp from the second. */ - operands[2] = gen_reg_rtx (Pmode); - operands[3] = gen_reg_rtx (Pmode); - operands[1] = adjust_address_nv (operands[1], Pmode, 0); - operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); - operands[5] = gen_frame_mem (Pmode, operands[3]); - p = rtvec_alloc (1); - RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode, - gen_frame_mem (BLKmode, operands[0]), - const0_rtx); - operands[6] = gen_rtx_PARALLEL (VOIDmode, p); -}") - -;; TOC register handling. - -;; Code to initialize the TOC register... - -(define_insn "load_toc_aix_si" - [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec:SI [(const_int 0)] UNSPEC_TOC)) - (use (reg:SI 2))])] - "DEFAULT_ABI == ABI_AIX && TARGET_32BIT" - "* -{ - char buf[30]; - ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); - operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); - operands[2] = gen_rtx_REG (Pmode, 2); - return \"lwz %0,%1(%2)\"; -}" - [(set_attr "type" "load")]) - -(define_insn "load_toc_aix_di" - [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (unspec:DI [(const_int 0)] UNSPEC_TOC)) - (use (reg:DI 2))])] - "DEFAULT_ABI == ABI_AIX && TARGET_64BIT" - "* -{ - char buf[30]; -#ifdef TARGET_RELOCATABLE - ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", - !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE); -#else - ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); -#endif - if (TARGET_ELF) - strcat (buf, \"@toc\"); - operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); - operands[2] = gen_rtx_REG (Pmode, 2); - return \"ld %0,%1(%2)\"; -}" - [(set_attr "type" "load")]) - -(define_insn "load_toc_v4_pic_si" - [(set (reg:SI LR_REGNO) - (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") - (set_attr "length" "4")]) - -(define_expand "load_toc_v4_PIC_1" - [(parallel [(set (reg:SI LR_REGNO) - (match_operand:SI 0 "immediate_operand" "s")) - (use (unspec [(match_dup 0)] UNSPEC_TOC))])] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX - && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" - "") - -(define_insn "load_toc_v4_PIC_1_normal" - [(set (reg:SI LR_REGNO) - (match_operand:SI 0 "immediate_operand" "s")) - (use (unspec [(match_dup 0)] UNSPEC_TOC))] - "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX - && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" - "bcl 20,31,%0\\n%0:" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "load_toc_v4_PIC_1_476" - [(set (reg:SI LR_REGNO) - (match_operand:SI 0 "immediate_operand" "s")) - (use (unspec [(match_dup 0)] UNSPEC_TOC))] - "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX - && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" - "* -{ - char name[32]; - static char templ[32]; - - get_ppc476_thunk_name (name); - sprintf (templ, \"bl %s\\n%%0:\", name); - return templ; -}" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_expand "load_toc_v4_PIC_1b" - [(parallel [(set (reg:SI LR_REGNO) - (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") - (label_ref (match_operand 1 "" ""))] - UNSPEC_TOCPTR)) - (match_dup 1)])] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "") - -(define_insn "load_toc_v4_PIC_1b_normal" - [(set (reg:SI LR_REGNO) - (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") - (label_ref (match_operand 1 "" ""))] - UNSPEC_TOCPTR)) - (match_dup 1)] - "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "bcl 20,31,$+8\;.long %0-$" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "load_toc_v4_PIC_1b_476" - [(set (reg:SI LR_REGNO) - (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") - (label_ref (match_operand 1 "" ""))] - UNSPEC_TOCPTR)) - (match_dup 1)] - "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "* -{ - char name[32]; - static char templ[32]; - - get_ppc476_thunk_name (name); - sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name); - return templ; -}" - [(set_attr "type" "branch") - (set_attr "length" "16")]) - -(define_insn "load_toc_v4_PIC_2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (minus:SI (match_operand:SI 2 "immediate_operand" "s") - (match_operand:SI 3 "immediate_operand" "s")))))] - "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "lwz %0,%2-%3(%1)" - [(set_attr "type" "load")]) - -(define_insn "load_toc_v4_PIC_3b" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (high:SI - (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") - (match_operand:SI 3 "symbol_ref_operand" "s")))))] - "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic" - "addis %0,%1,%2-%3@ha") - -(define_insn "load_toc_v4_PIC_3c" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") - (match_operand:SI 3 "symbol_ref_operand" "s"))))] - "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic" - "addi %0,%1,%2-%3@l") - -;; If the TOC is shared over a translation unit, as happens with all -;; the kinds of PIC that we support, we need to restore the TOC -;; pointer only when jumping over units of translation. -;; On Darwin, we need to reload the picbase. - -(define_expand "builtin_setjmp_receiver" - [(use (label_ref (match_operand 0 "" "")))] - "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) - || (TARGET_TOC && TARGET_MINIMAL_TOC) - || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" - " -{ -#if TARGET_MACHO - if (DEFAULT_ABI == ABI_DARWIN) - { - rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); - rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); - rtx tmplabrtx; - char tmplab[20]; - - crtl->uses_pic_offset_table = 1; - ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\", - CODE_LABEL_NUMBER (operands[0])); - tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); - - emit_insn (gen_load_macho_picbase (tmplabrtx)); - emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); - emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx)); - } - else -#endif - rs6000_emit_load_toc_table (FALSE); - DONE; -}") - -;; Largetoc support -(define_insn "*largetoc_high" - [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") - (high:DI - (unspec [(match_operand:DI 1 "" "") - (match_operand:DI 2 "gpc_reg_operand" "b")] - UNSPEC_TOCREL)))] - "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%2,%1@toc@ha") - -(define_insn "*largetoc_high_aix<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") - (high:P - (unspec [(match_operand:P 1 "" "") - (match_operand:P 2 "gpc_reg_operand" "b")] - UNSPEC_TOCREL)))] - "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%1@u(%2)") - -(define_insn "*largetoc_high_plus" - [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") - (high:DI - (plus:DI - (unspec [(match_operand:DI 1 "" "") - (match_operand:DI 2 "gpc_reg_operand" "b")] - UNSPEC_TOCREL) - (match_operand 3 "const_int_operand" "n"))))] - "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%2,%1+%3@toc@ha") - -(define_insn "*largetoc_high_plus_aix<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") - (high:P - (plus:P - (unspec [(match_operand:P 1 "" "") - (match_operand:P 2 "gpc_reg_operand" "b")] - UNSPEC_TOCREL) - (match_operand 3 "const_int_operand" "n"))))] - "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" - "addis %0,%1+%3@u(%2)") - -(define_insn "*largetoc_low" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") - (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r") - (match_operand:DI 2 "" "")))] - "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" - "@ - addi %0,%1,%2@l - addic %0,%1,%2@l") - -(define_insn "*largetoc_low_aix<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") - (match_operand:P 2 "" "")))] - "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" - "la %0,%2@l(%1)") - -(define_insn_and_split "*tocref<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") - (match_operand:P 1 "small_toc_ref" "R"))] - "TARGET_TOC" - "la %0,%a1" - "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed" - [(set (match_dup 0) (high:P (match_dup 1))) - (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))]) - -;; Elf specific ways of loading addresses for non-PIC code. -;; The output of this could be r0, but we make a very strong -;; preference for a base register because it will usually -;; be needed there. -(define_insn "elf_high" - [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") - (high:SI (match_operand 1 "" "")))] - "TARGET_ELF && ! TARGET_64BIT" - "lis %0,%1@ha") - -(define_insn "elf_low" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r") - (match_operand 2 "" "")))] - "TARGET_ELF && ! TARGET_64BIT" - "@ - la %0,%2@l(%1) - addic %0,%1,%K2") - -;; Call and call_value insns -(define_expand "call" - [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (reg:SI LR_REGNO))])] - "" - " -{ -#if TARGET_MACHO - if (MACHOPIC_INDIRECT) - operands[0] = machopic_indirect_call_target (operands[0]); -#endif - - gcc_assert (GET_CODE (operands[0]) == MEM); - gcc_assert (GET_CODE (operands[1]) == CONST_INT); - - operands[0] = XEXP (operands[0], 0); - - if (GET_CODE (operands[0]) != SYMBOL_REF - || (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]); - - switch (DEFAULT_ABI) - { - case ABI_V4: - case ABI_DARWIN: - operands[0] = force_reg (Pmode, operands[0]); - break; - - case ABI_AIX: - /* AIX function pointers are really pointers to a three word - area. */ - rs6000_call_indirect_aix (NULL_RTX, operands[0], operands[1]); - DONE; - - default: - gcc_unreachable (); - } - } -}") - -(define_expand "call_value" - [(parallel [(set (match_operand 0 "" "") - (call (mem:SI (match_operand 1 "address_operand" "")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (reg:SI LR_REGNO))])] - "" - " -{ -#if TARGET_MACHO - if (MACHOPIC_INDIRECT) - operands[1] = machopic_indirect_call_target (operands[1]); -#endif - - gcc_assert (GET_CODE (operands[1]) == MEM); - gcc_assert (GET_CODE (operands[2]) == CONST_INT); - - operands[1] = XEXP (operands[1], 0); - - if (GET_CODE (operands[1]) != SYMBOL_REF - || (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]); - - switch (DEFAULT_ABI) - { - case ABI_V4: - case ABI_DARWIN: - operands[1] = force_reg (Pmode, operands[1]); - break; - - case ABI_AIX: - /* AIX function pointers are really pointers to a three word - area. */ - rs6000_call_indirect_aix (operands[0], operands[1], operands[2]); - DONE; - - default: - gcc_unreachable (); - } - } -}") - -;; Call to function in current module. No TOC pointer reload needed. -;; Operand2 is nonzero if we are using the V.4 calling sequence and -;; either the function was not prototyped, or it was prototyped as a -;; variable argument function. It is > 0 if FP registers were passed -;; and < 0 if they were not. - -(define_insn "*call_local32" - [(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")) - (clobber (reg:SI LR_REGNO))] - "(INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*call_local64" - [(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")) - (clobber (reg:SI LR_REGNO))] - "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*call_value_local32" - [(set (match_operand 0 "" "") - (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")) - (clobber (reg:SI LR_REGNO))] - "(INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - - -(define_insn "*call_value_local64" - [(set (match_operand 0 "" "") - (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")) - (clobber (reg:SI LR_REGNO))] - "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -;; Call to indirect functions with the AIX abi using a 3 word descriptor. -;; Operand0 is the addresss of the function to call -;; Operand1 is the flag for System V.4 for unprototyped or FP registers -;; Operand2 is the location in the function descriptor to load r2 from -;; Operand3 is the stack location to hold the current TOC pointer - -(define_insn "call_indirect_aix<ptrsize>" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) - (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) - (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) - (use (reg:P STATIC_CHAIN_REGNUM)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS" - "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Like call_indirect_aix<ptrsize>, but no use of the static chain -;; Operand0 is the addresss of the function to call -;; Operand1 is the flag for System V.4 for unprototyped or FP registers -;; Operand2 is the location in the function descriptor to load r2 from -;; Operand3 is the stack location to hold the current TOC pointer - -(define_insn "call_indirect_aix<ptrsize>_nor11" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) - (match_operand 1 "" "g,g")) - (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) - (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS" - "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Operand0 is the return result of the function -;; Operand1 is the addresss of the function to call -;; Operand2 is the flag for System V.4 for unprototyped or FP registers -;; Operand3 is the location in the function descriptor to load r2 from -;; Operand4 is the stack location to hold the current TOC pointer - -(define_insn "call_value_indirect_aix<ptrsize>" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) - (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) - (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>")) - (use (reg:P STATIC_CHAIN_REGNUM)) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS" - "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Like call_value_indirect_aix<ptrsize>, but no use of the static chain -;; Operand0 is the return result of the function -;; Operand1 is the addresss of the function to call -;; Operand2 is the flag for System V.4 for unprototyped or FP registers -;; Operand3 is the location in the function descriptor to load r2 from -;; Operand4 is the stack location to hold the current TOC pointer - -(define_insn "call_value_indirect_aix<ptrsize>_nor11" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) - (match_operand 2 "" "g,g"))) - (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) - (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>")) - (clobber (reg:P LR_REGNO))] - "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS" - "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4" - [(set_attr "type" "jmpreg") - (set_attr "length" "12")]) - -;; Call to function which may be in another module. Restore the TOC -;; pointer (r2) after the call unless this is System V. -;; Operand2 is nonzero if we are using the V.4 calling sequence and -;; either the function was not prototyped, or it was prototyped as a -;; variable argument function. It is > 0 if FP registers were passed -;; and < 0 if they were not. - -(define_insn "*call_nonlocal_aix32" - [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s")) - (match_operand 1 "" "g")) - (use (match_operand:SI 2 "immediate_operand" "O")) - (clobber (reg:SI LR_REGNO))] - "TARGET_32BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "bl %z0\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_nonlocal_aix64" - [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s")) - (match_operand 1 "" "g")) - (use (match_operand:SI 2 "immediate_operand" "O")) - (clobber (reg:SI LR_REGNO))] - "TARGET_64BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "bl %z0\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_value_nonlocal_aix32" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (use (match_operand:SI 3 "immediate_operand" "O")) - (clobber (reg:SI LR_REGNO))] - "TARGET_32BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "bl %z1\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -(define_insn "*call_value_nonlocal_aix64" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s")) - (match_operand 2 "" "g"))) - (use (match_operand:SI 3 "immediate_operand" "O")) - (clobber (reg:SI LR_REGNO))] - "TARGET_64BIT - && DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "bl %z1\;nop" - [(set_attr "type" "branch") - (set_attr "length" "8")]) - -;; A function pointer under System V is just a normal pointer -;; operands[0] is the function pointer -;; operands[1] is the stack size to clean up -;; operands[2] is the value FUNCTION_ARG returns for the VOID argument -;; which indicates how to set cr1 - -(define_insn "*call_indirect_nonlocal_sysv<mode>" - [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) - (match_operand 1 "" "g,g,g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) - (clobber (reg:SI LR_REGNO))] - "DEFAULT_ABI == ABI_V4 - || DEFAULT_ABI == ABI_DARWIN" -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn ("crxor 6,6,6", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn ("creqv 6,6,6", operands); - - return "b%T0l"; -} - [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") - (set_attr "length" "4,4,8,8")]) - -(define_insn_and_split "*call_nonlocal_sysv<mode>" - [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) - (match_operand 1 "" "g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (clobber (reg:SI LR_REGNO))] - "(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); - - 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 - if (DEFAULT_ABI == ABI_V4 && flag_pic) - { - gcc_assert (!TARGET_SECURE_PLT); - return "bl %z0@plt"; - } - else - return "bl %z0"; -#endif -} - "DEFAULT_ABI == ABI_V4 - && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) - && (INTVAL (operands[2]) & CALL_LONG) == 0" - [(parallel [(call (mem:SI (match_dup 0)) - (match_dup 1)) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (reg:SI LR_REGNO))])] -{ - operands[3] = pic_offset_table_rtx; -} - [(set_attr "type" "branch,branch") - (set_attr "length" "4,8")]) - -(define_insn "*call_nonlocal_sysv_secure<mode>" - [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) - (match_operand 1 "" "g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,n")) - (use (match_operand:SI 3 "register_operand" "r,r")) - (clobber (reg:SI LR_REGNO))] - "(DEFAULT_ABI == ABI_V4 - && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) - && (INTVAL (operands[2]) & CALL_LONG) == 0)" -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn ("crxor 6,6,6", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn ("creqv 6,6,6", operands); - - if (flag_pic == 2) - /* The magic 32768 offset here and in the other sysv call insns - corresponds to the offset of r30 in .got2, as given by LCTOC1. - See sysv4.h:toc_section. */ - return "bl %z0+32768@plt"; - else - return "bl %z0@plt"; -} - [(set_attr "type" "branch,branch") - (set_attr "length" "4,8")]) - -(define_insn "*call_value_indirect_nonlocal_sysv<mode>" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l")) - (match_operand 2 "" "g,g,g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) - (clobber (reg:SI LR_REGNO))] - "DEFAULT_ABI == ABI_V4 - || DEFAULT_ABI == ABI_DARWIN" -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn ("crxor 6,6,6", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn ("creqv 6,6,6", operands); - - return "b%T1l"; -} - [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") - (set_attr "length" "4,4,8,8")]) - -(define_insn_and_split "*call_value_nonlocal_sysv<mode>" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (clobber (reg:SI LR_REGNO))] - "(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); - - 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 - if (DEFAULT_ABI == ABI_V4 && flag_pic) - { - gcc_assert (!TARGET_SECURE_PLT); - return "bl %z1@plt"; - } - else - return "bl %z1"; -#endif -} - "DEFAULT_ABI == ABI_V4 - && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) - && (INTVAL (operands[3]) & CALL_LONG) == 0" - [(parallel [(set (match_dup 0) - (call (mem:SI (match_dup 1)) - (match_dup 2))) - (use (match_dup 3)) - (use (match_dup 4)) - (clobber (reg:SI LR_REGNO))])] -{ - operands[4] = pic_offset_table_rtx; -} - [(set_attr "type" "branch,branch") - (set_attr "length" "4,8")]) - -(define_insn "*call_value_nonlocal_sysv_secure<mode>" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n")) - (use (match_operand:SI 4 "register_operand" "r,r")) - (clobber (reg:SI LR_REGNO))] - "(DEFAULT_ABI == ABI_V4 - && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) - && (INTVAL (operands[3]) & CALL_LONG) == 0)" -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn ("crxor 6,6,6", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn ("creqv 6,6,6", operands); - - if (flag_pic == 2) - return "bl %z1+32768@plt"; - else - return "bl %z1@plt"; -} - [(set_attr "type" "branch,branch") - (set_attr "length" "4,8")]) - -;; Call subroutine returning any type. -(define_expand "untyped_call" - [(parallel [(call (match_operand 0 "" "") - (const_int 0)) - (match_operand 1 "" "") - (match_operand 2 "" "")])] - "" - " -{ - int i; - - emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx)); - - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - /* The optimizer does not know that the call sets the function value - registers we stored in the result block. We avoid problems by - claiming that all hard registers are used and clobbered at this - point. */ - emit_insn (gen_blockage ()); - - DONE; -}") - -;; sibling call patterns -(define_expand "sibcall" - [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (use (reg:SI LR_REGNO)) - (simple_return)])] - "" - " -{ -#if TARGET_MACHO - if (MACHOPIC_INDIRECT) - operands[0] = machopic_indirect_call_target (operands[0]); -#endif - - gcc_assert (GET_CODE (operands[0]) == MEM); - gcc_assert (GET_CODE (operands[1]) == CONST_INT); - - operands[0] = XEXP (operands[0], 0); -}") - -;; this and similar patterns must be marked as using LR, otherwise -;; dataflow will try to delete the store into it. This is true -;; even when the actual reg to jump to is in CTR, when LR was -;; saved and restored around the PIC-setting BCL. -(define_insn "*sibcall_local32" - [(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 (reg:SI LR_REGNO)) - (simple_return)] - "(INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*sibcall_local64" - [(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 (reg:SI LR_REGNO)) - (simple_return)] - "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*sibcall_value_local32" - [(set (match_operand 0 "" "") - (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 (reg:SI LR_REGNO)) - (simple_return)] - "(INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - - -(define_insn "*sibcall_value_local64" - [(set (match_operand 0 "" "") - (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 (reg:SI LR_REGNO)) - (simple_return)] - "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" - "* -{ - if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8")]) - -(define_insn "*sibcall_nonlocal_aix<mode>" - [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) - (match_operand 1 "" "g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,O")) - (use (reg:SI LR_REGNO)) - (simple_return)] - "DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[2]) & CALL_LONG) == 0" - "@ - b %z0 - b%T0" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*sibcall_value_nonlocal_aix<mode>" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) - (match_operand 2 "" "g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,O")) - (use (reg:SI LR_REGNO)) - (simple_return)] - "DEFAULT_ABI == ABI_AIX - && (INTVAL (operands[3]) & CALL_LONG) == 0" - "@ - b %z1 - b%T1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*sibcall_nonlocal_sysv<mode>" - [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) - (match_operand 1 "" "")) - (use (match_operand 2 "immediate_operand" "O,n,O,n")) - (use (reg:SI LR_REGNO)) - (simple_return)] - "(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); - - else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - if (which_alternative >= 2) - return \"b%T0\"; - else if (DEFAULT_ABI == ABI_V4 && flag_pic) - { - gcc_assert (!TARGET_SECURE_PLT); - return \"b %z0@plt\"; - } - else - return \"b %z0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8,4,8")]) - -(define_expand "sibcall_value" - [(parallel [(set (match_operand 0 "register_operand" "") - (call (mem:SI (match_operand 1 "address_operand" "")) - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (use (reg:SI LR_REGNO)) - (simple_return)])] - "" - " -{ -#if TARGET_MACHO - if (MACHOPIC_INDIRECT) - operands[1] = machopic_indirect_call_target (operands[1]); -#endif - - gcc_assert (GET_CODE (operands[1]) == MEM); - gcc_assert (GET_CODE (operands[2]) == CONST_INT); - - operands[1] = XEXP (operands[1], 0); -}") - -(define_insn "*sibcall_value_nonlocal_sysv<mode>" - [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) - (match_operand 2 "" ""))) - (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) - (use (reg:SI LR_REGNO)) - (simple_return)] - "(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); - - else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); - - if (which_alternative >= 2) - return \"b%T1\"; - else if (DEFAULT_ABI == ABI_V4 && flag_pic) - { - gcc_assert (!TARGET_SECURE_PLT); - return \"b %z1@plt\"; - } - else - return \"b %z1\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "4,8,4,8")]) - -(define_expand "sibcall_epilogue" - [(use (const_int 0))] - "" -{ - if (!TARGET_SCHED_PROLOG) - emit_insn (gen_blockage ()); - rs6000_emit_epilogue (TRUE); - DONE; -}) - -;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and -;; all of memory. This blocks insns from being moved across this point. - -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] - "" - "") - -(define_expand "probe_stack" - [(set (match_operand 0 "memory_operand" "=m") - (unspec [(const_int 0)] UNSPEC_PROBE_STACK))] - "" -{ - if (TARGET_64BIT) - emit_insn (gen_probe_stack_di (operands[0])); - else - emit_insn (gen_probe_stack_si (operands[0])); - DONE; -}) - -(define_insn "probe_stack_<mode>" - [(set (match_operand:P 0 "memory_operand" "=m") - (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))] - "" -{ - operands[1] = gen_rtx_REG (Pmode, 0); - return "st<wd>%U0%X0 %1,%0"; -} - [(set_attr "type" "store") - (set_attr "length" "4")]) - -(define_insn "probe_stack_range<P:mode>" - [(set (match_operand:P 0 "register_operand" "=r") - (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") - (match_operand:P 2 "register_operand" "r")] - UNSPECV_PROBE_STACK_RANGE))] - "" - "* return output_probe_stack_range (operands[0], operands[2]);" - [(set_attr "type" "three")]) - -;; Compare insns are next. Note that the RS/6000 has two types of compares, -;; signed & unsigned, and one type of branch. -;; -;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc -;; insns, and branches. - -(define_expand "cbranch<mode>4" - [(use (match_operator 0 "rs6000_cbranch_operator" - [(match_operand:GPR 1 "gpc_reg_operand" "") - (match_operand:GPR 2 "reg_or_short_operand" "")])) - (use (match_operand 3 ""))] - "" - " -{ - /* Take care of the possibility that operands[2] might be negative but - this might be a logical operation. That insn doesn't exist. */ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) < 0) - { - operands[2] = force_reg (<MODE>mode, operands[2]); - operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), - GET_MODE (operands[0]), - operands[1], operands[2]); - } - - rs6000_emit_cbranch (<MODE>mode, operands); - DONE; -}") - -(define_expand "cbranch<mode>4" - [(use (match_operator 0 "rs6000_cbranch_operator" - [(match_operand:FP 1 "gpc_reg_operand" "") - (match_operand:FP 2 "gpc_reg_operand" "")])) - (use (match_operand 3 ""))] - "" - " -{ - rs6000_emit_cbranch (<MODE>mode, operands); - DONE; -}") - -(define_expand "cstore<mode>4" - [(use (match_operator 1 "rs6000_cbranch_operator" - [(match_operand:GPR 2 "gpc_reg_operand" "") - (match_operand:GPR 3 "reg_or_short_operand" "")])) - (clobber (match_operand:SI 0 "register_operand"))] - "" - " -{ - /* Take care of the possibility that operands[3] might be negative but - this might be a logical operation. That insn doesn't exist. */ - if (GET_CODE (operands[3]) == CONST_INT - && INTVAL (operands[3]) < 0) - { - operands[3] = force_reg (<MODE>mode, operands[3]); - operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), - GET_MODE (operands[1]), - operands[2], operands[3]); - } - - /* For SNE, we would prefer that the xor/abs sequence be used for integers. - For SEQ, likewise, except that comparisons with zero should be done - with an scc insns. However, due to the order that combine see the - resulting insns, we must, in fact, allow SEQ for integers. Fail in - the cases we don't want to handle or are best handled by portable - code. */ - if (GET_CODE (operands[1]) == NE) - FAIL; - if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE) - && operands[3] == const0_rtx) - FAIL; - rs6000_emit_sCOND (<MODE>mode, operands); - DONE; -}") - -(define_expand "cstore<mode>4" - [(use (match_operator 1 "rs6000_cbranch_operator" - [(match_operand:FP 2 "gpc_reg_operand" "") - (match_operand:FP 3 "gpc_reg_operand" "")])) - (clobber (match_operand:SI 0 "register_operand"))] - "" - " -{ - rs6000_emit_sCOND (<MODE>mode, operands); - DONE; -}") - - -(define_expand "stack_protect_set" - [(match_operand 0 "memory_operand" "") - (match_operand 1 "memory_operand" "")] - "" -{ -#ifdef TARGET_THREAD_SSP_OFFSET - rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); - rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); - operands[1] = gen_rtx_MEM (Pmode, addr); -#endif - if (TARGET_64BIT) - emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); - else - emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); - DONE; -}) - -(define_insn "stack_protect_setsi" - [(set (match_operand:SI 0 "memory_operand" "=m") - (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) - (set (match_scratch:SI 2 "=&r") (const_int 0))] - "TARGET_32BIT" - "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "stack_protect_setdi" - [(set (match_operand:DI 0 "memory_operand" "=Y") - (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET)) - (set (match_scratch:DI 2 "=&r") (const_int 0))] - "TARGET_64BIT" - "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_expand "stack_protect_test" - [(match_operand 0 "memory_operand" "") - (match_operand 1 "memory_operand" "") - (match_operand 2 "" "")] - "" -{ - rtx test, op0, op1; -#ifdef TARGET_THREAD_SSP_OFFSET - rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); - rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); - operands[1] = gen_rtx_MEM (Pmode, addr); -#endif - op0 = operands[0]; - op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST); - test = gen_rtx_EQ (VOIDmode, op0, op1); - emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2])); - DONE; -}) - -(define_insn "stack_protect_testsi" - [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") - (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m") - (match_operand:SI 2 "memory_operand" "m,m")] - UNSPEC_SP_TEST)) - (set (match_scratch:SI 4 "=r,r") (const_int 0)) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "TARGET_32BIT" - "@ - lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 - lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0" - [(set_attr "length" "16,20")]) - -(define_insn "stack_protect_testdi" - [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") - (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y") - (match_operand:DI 2 "memory_operand" "Y,Y")] - UNSPEC_SP_TEST)) - (set (match_scratch:DI 4 "=r,r") (const_int 0)) - (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_64BIT" - "@ - ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 - ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0" - [(set_attr "length" "16,20")]) - - -;; Here are the actual compare insns. -(define_insn "*cmp<mode>_internal1" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "reg_or_short_operand" "rI")))] - "" - "cmp<wd>%I2 %0,%1,%2" - [(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 this is profitable -;; only if the large constant is only used for the comparison (and in this -;; case we already have a register to reuse as scratch). -;; -;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: -;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. - -(define_peephole2 - [(set (match_operand:SI 0 "register_operand") - (match_operand:SI 1 "logical_const_operand" "")) - (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" - [(match_dup 0) - (match_operand:SI 2 "logical_const_operand" "")])) - (set (match_operand:CC 4 "cc_reg_operand" "") - (compare:CC (match_operand:SI 5 "gpc_reg_operand" "") - (match_dup 0))) - (set (pc) - (if_then_else (match_operator 6 "equality_operator" - [(match_dup 4) (const_int 0)]) - (match_operand 7 "" "") - (match_operand 8 "" "")))] - "peep2_reg_dead_p (3, operands[0]) - && peep2_reg_dead_p (4, operands[4])" - [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) - (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) - (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] - -{ - /* Get the constant we are comparing against, and see what it looks like - when sign-extended from 16 to 32 bits. Then see what constant we could - XOR with SEXTC to get the sign-extended value. */ - rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), - SImode, - operands[1], operands[2]); - HOST_WIDE_INT c = INTVAL (cnst); - HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; - HOST_WIDE_INT xorv = c ^ sextc; - - operands[9] = GEN_INT (xorv); - operands[10] = GEN_INT (sextc); -}) - -(define_insn "*cmpsi_internal2" - [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") - (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_u_short_operand" "rK")))] - "" - "cmplw%I2 %0,%1,%b2" - [(set_attr "type" "cmp")]) - -(define_insn "*cmpdi_internal2" - [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") - (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_u_short_operand" "rK")))] - "" - "cmpld%I2 %0,%1,%b2" - [(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 -;; of the required delay between a compare and branch. We generate code for -;; them by splitting. - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=y") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "short_cint_operand" "i"))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] - "" - "#" - [(set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y") - (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "u_short_cint_operand" "i"))) - (set (match_operand:SI 0 "gpc_reg_operand" "=r") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] - "" - "#" - [(set_attr "length" "8")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_operand" "") - (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "short_cint_operand" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] - "" - [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) - -(define_split - [(set (match_operand:CCUNS 3 "cc_reg_operand" "") - (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "u_short_cint_operand" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] - "" - [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2))) - (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) - -(define_insn "*cmpsf_internal1" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f") - (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" - "fcmpu %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -(define_insn "*cmpdf_internal1" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d") - (match_operand:DF 2 "gpc_reg_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && !VECTOR_UNIT_VSX_P (DFmode)" - "fcmpu %0,%1,%2" - [(set_attr "type" "fpcompare")]) - -;; Only need to compare second words if first words equal -(define_insn "*cmptf_internal1" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d") - (match_operand:TF 2 "gpc_reg_operand" "d")))] - "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" - "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" - [(set_attr "type" "fpcompare") - (set_attr "length" "12")]) - -(define_insn_and_split "*cmptf_internal2" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d") - (match_operand:TF 2 "gpc_reg_operand" "d"))) - (clobber (match_scratch:DF 3 "=d")) - (clobber (match_scratch:DF 4 "=d")) - (clobber (match_scratch:DF 5 "=d")) - (clobber (match_scratch:DF 6 "=d")) - (clobber (match_scratch:DF 7 "=d")) - (clobber (match_scratch:DF 8 "=d")) - (clobber (match_scratch:DF 9 "=d")) - (clobber (match_scratch:DF 10 "=d")) - (clobber (match_scratch:GPR 11 "=b"))] - "!TARGET_IEEEQUAD && TARGET_XL_COMPAT - && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" - "#" - "&& reload_completed" - [(set (match_dup 3) (match_dup 14)) - (set (match_dup 4) (match_dup 15)) - (set (match_dup 9) (abs:DF (match_dup 5))) - (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) - (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) - (label_ref (match_dup 12)) - (pc))) - (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) - (set (pc) (label_ref (match_dup 13))) - (match_dup 12) - (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) - (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) - (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) - (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) - (match_dup 13)] -{ - REAL_VALUE_TYPE rv; - 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); - - operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word); - operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word); - operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word); - operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word); - operands[12] = gen_label_rtx (); - operands[13] = gen_label_rtx (); - real_inf (&rv); - operands[14] = force_const_mem (DFmode, - CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode)); - operands[15] = force_const_mem (DFmode, - CONST_DOUBLE_FROM_REAL_VALUE (dconst0, - DFmode)); - if (TARGET_TOC) - { - rtx tocref; - tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); - operands[14] = gen_const_mem (DFmode, tocref); - tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); - operands[15] = gen_const_mem (DFmode, tocref); - set_mem_alias_set (operands[14], get_TOC_alias_set ()); - set_mem_alias_set (operands[15], get_TOC_alias_set ()); - } -}) - -;; Now we have the scc insns. We can do some combinations because of the -;; way the machine works. -;; -;; Note that this is probably faster if we can put an insn between the -;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most -;; cases the insns below which don't use an intermediate CR field will -;; be used instead. -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]))] - "" - "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" - [(set (attr "type") - (cond [(match_test "TARGET_MFCRF") - (const_string "mfcrf") - ] - (const_string "mfcr"))) - (set_attr "length" "8")]) - -;; 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_HARD_FLOAT && !TARGET_FPRS" - "mfcr %0\;rlwinm %0,%0,%D1,31,31" - [(set_attr "type" "mfcr") - (set_attr "length" "8")]) - -;; 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:CC 1 "cc_reg_operand" "y")] - UNSPEC_MV_CR_OV))] - "TARGET_ISEL" - "mfcr %0\;rlwinm %0,%0,%t1,1" - [(set_attr "type" "mfcr") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operator:DI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]))] - "TARGET_POWERPC64" - "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" - [(set (attr "type") - (cond [(match_test "TARGET_MFCRF") - (const_string "mfcrf") - ] - (const_string "mfcr"))) - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y,y") - (const_int 0)]) - (const_int 0))) - (set (match_operand:SI 3 "gpc_reg_operand" "=r,r") - (match_op_dup 1 [(match_dup 2) (const_int 0)]))] - "TARGET_32BIT" - "@ - mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 - #" - [(set_attr "type" "delayed_compare") - (set_attr "length" "8,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "") - (const_int 0)]) - (const_int 0))) - (set (match_operand:SI 3 "gpc_reg_operand" "") - (match_op_dup 1 [(match_dup 2) (const_int 0)]))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) - (match_op_dup 1 [(match_dup 2) (const_int 0)])) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ashift:SI (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "n")))] - "" - "* -{ - int is_bit = ccr_bit (operands[1], 1); - int put_bit = 31 - (INTVAL (operands[3]) & 31); - int count; - - if (is_bit >= put_bit) - count = is_bit - put_bit; - else - count = 32 - (put_bit - is_bit); - - operands[4] = GEN_INT (count); - operands[5] = GEN_INT (put_bit); - - return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\"; -}" - [(set (attr "type") - (cond [(match_test "TARGET_MFCRF") - (const_string "mfcrf") - ] - (const_string "mfcr"))) - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (ashift:SI (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y,y") - (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "n,n")) - (const_int 0))) - (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") - (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) - (match_dup 3)))] - "" - "* -{ - int is_bit = ccr_bit (operands[1], 1); - int put_bit = 31 - (INTVAL (operands[3]) & 31); - int count; - - /* Force split for non-cc0 compare. */ - if (which_alternative == 1) - return \"#\"; - - if (is_bit >= put_bit) - count = is_bit - put_bit; - else - count = 32 - (put_bit - is_bit); - - operands[5] = GEN_INT (count); - operands[6] = GEN_INT (put_bit); - - return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\"; -}" - [(set_attr "type" "delayed_compare") - (set_attr "length" "8,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (ashift:SI (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "") - (const_int 0)]) - (match_operand:SI 3 "const_int_operand" "")) - (const_int 0))) - (set (match_operand:SI 4 "gpc_reg_operand" "") - (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) - (match_dup 3)))] - "reload_completed" - [(set (match_dup 4) - (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -;; There is a 3 cycle delay between consecutive mfcr instructions -;; so it is useful to combine 2 scc instructions to use only one mfcr. - -(define_peephole - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (match_operator:SI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)])) - (set (match_operand:SI 3 "gpc_reg_operand" "=r") - (match_operator:SI 4 "scc_comparison_operator" - [(match_operand 5 "cc_reg_operand" "y") - (const_int 0)]))] - "REGNO (operands[2]) != REGNO (operands[5])" - "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1" - [(set_attr "type" "mfcr") - (set_attr "length" "12")]) - -(define_peephole - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (match_operator:DI 1 "scc_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)])) - (set (match_operand:DI 3 "gpc_reg_operand" "=r") - (match_operator:DI 4 "scc_comparison_operator" - [(match_operand 5 "cc_reg_operand" "y") - (const_int 0)]))] - "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])" - "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1" - [(set_attr "type" "mfcr") - (set_attr "length" "12")]) - -;; There are some scc insns that can be done directly, without a compare. -;; These are faster because they don't involve the communications between -;; the FXU and branch units. In fact, we will be replacing all of the -;; integer scc insns here or in the portable methods in emit_store_flag. -;; -;; Also support (neg (scc ..)) since that construct is used to replace -;; branches, (plus (scc ..) ..) since that construct is common and -;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the -;; cases where it is no more expensive than (neg (scc ..)). - -;; Have reload force a constant into a register for the simple insns that -;; otherwise won't accept constants. We do this because it is faster than -;; the cmp/mfcr sequence we would otherwise generate. - -(define_mode_attr scc_eq_op2 [(SI "rKLI") - (DI "rKJI")]) - -(define_insn_and_split "*eq<mode>" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") - (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))] - "" - "#" - "" - [(set (match_dup 0) - (clz:GPR (match_dup 3))) - (set (match_dup 0) - (lshiftrt:GPR (match_dup 0) (match_dup 4)))] - { - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) - { - /* Use output operand as intermediate. */ - operands[3] = operands[0]; - - if (logical_operand (operands[2], <MODE>mode)) - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_XOR (<MODE>mode, - operands[1], operands[2]))); - else - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_PLUS (<MODE>mode, operands[1], - negate_rtx (<MODE>mode, - operands[2])))); - } - else - operands[3] = operands[1]; - - operands[4] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); - }) - -(define_insn_and_split "*eq<mode>_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=y") - (compare:CC - (eq:P (match_operand:P 1 "gpc_reg_operand" "=r") - (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r") - (eq:P (match_dup 1) (match_dup 2)))] - "optimize_size" - "#" - "optimize_size" - [(set (match_dup 0) - (clz:P (match_dup 4))) - (parallel [(set (match_dup 3) - (compare:CC (lshiftrt:P (match_dup 0) (match_dup 5)) - (const_int 0))) - (set (match_dup 0) - (lshiftrt:P (match_dup 0) (match_dup 5)))])] - { - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) - { - /* Use output operand as intermediate. */ - operands[4] = operands[0]; - - if (logical_operand (operands[2], <MODE>mode)) - emit_insn (gen_rtx_SET (VOIDmode, operands[4], - gen_rtx_XOR (<MODE>mode, - operands[1], operands[2]))); - else - emit_insn (gen_rtx_SET (VOIDmode, operands[4], - gen_rtx_PLUS (<MODE>mode, operands[1], - negate_rtx (<MODE>mode, - operands[2])))); - } - else - operands[4] = operands[1]; - - operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); - }) - -;; We have insns of the form shown by the first define_insn below. If -;; there is something inside the comparison operation, we must split it. -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (plus:SI (match_operator 1 "comparison_operator" - [(match_operand:SI 2 "" "") - (match_operand:SI 3 - "reg_or_cint_operand" "")]) - (match_operand:SI 4 "gpc_reg_operand" ""))) - (clobber (match_operand:SI 5 "register_operand" ""))] - "! gpc_reg_operand (operands[2], SImode)" - [(set (match_dup 5) (match_dup 2)) - (set (match_dup 0) (plus:SI (match_op_dup 1 [(match_dup 5) (match_dup 3)]) - (match_dup 4)))]) - -(define_insn "*plus_eqsi" - [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r") - (plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") - (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))] - "TARGET_32BIT" - "@ - xor %0,%1,%2\;subfic %0,%0,0\;addze %0,%3 - subfic %0,%1,0\;addze %0,%3 - xori %0,%1,%b2\;subfic %0,%0,0\;addze %0,%3 - xoris %0,%1,%u2\;subfic %0,%0,0\;addze %0,%3 - subfic %0,%1,%2\;subfic %0,%0,0\;addze %0,%3" - [(set_attr "type" "three,two,three,three,three") - (set_attr "length" "12,8,12,12,12")]) - -(define_insn "*compare_plus_eqsi" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I")) - (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_32BIT && optimize_size" - "@ - xor %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3 - subfic %4,%1,0\;addze. %4,%3 - xori %4,%1,%b2\;subfic %4,%4,0\;addze. %4,%3 - xoris %4,%1,%u2\;subfic %4,%4,0\;addze. %4,%3 - subfic %4,%1,%2\;subfic %4,%4,0\;addze. %4,%3 - # - # - # - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "scc_eq_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && optimize_size && reload_completed" - [(set (match_dup 4) - (plus:SI (eq:SI (match_dup 1) - (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "*plus_eqsi_compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") - (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r")) - (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_32BIT && optimize_size" - "@ - xor %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3 - subfic %0,%1,0\;addze. %0,%3 - xori %0,%1,%b2\;subfic %0,%0,0\;addze. %0,%3 - xoris %0,%1,%u2\;subfic %0,%0,0\;addze. %0,%3 - subfic %0,%1,%2\;subfic %0,%0,0\;addze. %0,%3 - # - # - # - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,8,12,12,12,16,12,16,16,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI - (eq:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "scc_eq_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (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_32BIT && optimize_size && reload_completed" - [(set (match_dup 0) - (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*neg_eq0<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0))))] - "" - "addic %0,%1,-1\;subfe %0,%0,%0" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn_and_split "*neg_eq<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "%r") - (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (eq:P (match_dup 3) (const_int 0))))] - { - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0) - { - /* Use output operand as intermediate. */ - operands[3] = operands[0]; - - if (logical_operand (operands[2], <MODE>mode)) - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_XOR (<MODE>mode, - operands[1], operands[2]))); - else - emit_insn (gen_rtx_SET (VOIDmode, operands[3], - gen_rtx_PLUS (<MODE>mode, operands[1], - negate_rtx (<MODE>mode, - operands[2])))); - } - else - operands[3] = operands[1]; - }) - -(define_insn "*ne0_<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (ne:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0))) - (clobber (match_scratch:P 2 "=&r"))] - "!(TARGET_32BIT && TARGET_ISEL)" - "addic %2,%1,-1\;subfe %0,%2,%1" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*plus_ne0_<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r"))) - (clobber (match_scratch:P 3 "=&r"))] - "" - "addic %3,%1,-1\;addze %0,%2" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*compare_plus_ne0_<mode>" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:P 3 "=&r,&r")) - (clobber (match_scratch:P 4 "=X,&r"))] - "" - "@ - addic %3,%1,-1\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC (ne:P (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (neg:P (match_operand:P 2 "gpc_reg_operand" "")))) - (clobber (match_scratch:P 3 "")) - (clobber (match_scratch:P 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -; For combine. -(define_insn "*compare_plus_ne0_<mode>_1" - [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") - (compare:CCEQ (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (neg:P (match_operand:P 2 "gpc_reg_operand" "r,r")))) - (clobber (match_scratch:P 3 "=&r,&r")) - (clobber (match_scratch:P 4 "=X,&r"))] - "" - "@ - addic %3,%1,-1\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CCEQ 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CCEQ (ne:P (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (neg:P (match_operand:P 2 "gpc_reg_operand" "")))) - (clobber (match_scratch:P 3 "")) - (clobber (match_scratch:P 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_dup 4))]) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "*plus_ne0_<mode>_compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_scratch:P 3 "=&r,&r"))] - "" - "@ - addic %3,%1,-1\;addze. %0,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_scratch:P 3 ""))] - "reload_completed" - [(parallel [(set (match_dup 0) - (plus:P (ne:P (match_dup 1) - (const_int 0)) - (match_dup 2))) - (clobber (match_dup 3))]) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*leu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")))] - "" - "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*leu<mode>_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (leu:P (match_dup 1) (match_dup 2)))] - "" - "@ - subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (leu:P (match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "reg_or_short_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (leu:P (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (leu:P (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*plus_leu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")) - (match_operand:P 3 "gpc_reg_operand" "r")))] - "" - "subf%I2c %0,%1,%2\;addze %0,%3" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_32BIT" - "@ - subf%I2c %4,%1,%2\;addze. %4,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (plus:SI (leu:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI")) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (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_32BIT" - "@ - subf%I2c %0,%1,%2\;addze. %0,%3 - #" - [(set_attr "type" "compare") - (set_attr "length" "8,12")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (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_32BIT && reload_completed" - [(set (match_dup 0) - (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*neg_leu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (neg:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI"))))] - "" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;nand %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*and_neg_leu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (and:P (neg:P - (leu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI"))) - (match_operand:P 3 "gpc_reg_operand" "r")))] - "" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc %0,%3,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r"))] - "TARGET_32BIT" - "@ - subf%I2c %4,%1,%2\;subfe %4,%4,%4\;andc. %4,%3,%4 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r")) - (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_32BIT" - "@ - subf%I2c %0,%1,%2\;subfe %0,%0,%0\;andc. %0,%3,%0 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (leu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (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_32BIT && reload_completed" - [(set (match_dup 0) - (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) - (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn_and_split "*ltu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (neg:P (match_dup 0)))] - "") - -(define_insn_and_split "*ltu<mode>_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") - (ltu:P (match_dup 1) (match_dup 2)))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 3) - (compare:CC (neg:P (match_dup 0)) (const_int 0))) - (set (match_dup 0) (neg:P (match_dup 0)))])] - "") - -(define_insn_and_split "*plus_ltu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r") - (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:P 3 "reg_or_short_operand" "rI,rI")))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))] - "") - -(define_insn_and_split "*plus_ltu<mode>_compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:P 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:P (ltu:P (match_dup 1) (match_dup 2)) (match_dup 3)))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 4) - (compare:CC (minus:P (match_dup 3) (match_dup 0)) - (const_int 0))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])] - "") - -(define_insn "*neg_ltu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (neg:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))))] - "" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0 - addic %0,%1,%n2\;subfe %0,%0,%0" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "*geu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))] - "" - "@ - subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0 - addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*geu<mode>_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r") - (geu:P (match_dup 1) (match_dup 2)))] - "" - "@ - subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0 - addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (geu:P (match_operand:P 1 "gpc_reg_operand" "") - (match_operand:P 2 "reg_or_neg_short_operand" "")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (geu:P (match_dup 1) (match_dup 2)))] - "reload_completed" - [(set (match_dup 0) - (geu:P (match_dup 1) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*plus_geu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r") - (plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P")) - (match_operand:P 3 "gpc_reg_operand" "r,r")))] - "" - "@ - subfc %0,%2,%1\;addze %0,%3 - addic %0,%1,%n2\;addze %0,%3" - [(set_attr "type" "two") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "TARGET_32BIT" - "@ - subfc %4,%2,%1\;addze. %4,%3 - addic %4,%1,%n2\;addze. %4,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "8,8,12,12")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (plus:SI (geu:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (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_32BIT" - "@ - subfc %0,%2,%1\;addze. %0,%3 - addic %0,%1,%n2\;addze. %0,%3 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "8,8,12,12")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" "")) - (match_operand:SI 3 "gpc_reg_operand" "")) - (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_32BIT && reload_completed" - [(set (match_dup 0) - (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) - (set (match_dup 4) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*neg_geu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (neg:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_short_operand" "r,I"))))] - "" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0\;nand %0,%0,%0 - subfic %0,%1,-1\;add%I2c %0,%0,%2\;subfe %0,%0,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "*and_neg_geu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r") - (and:P (neg:P - (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))) - (match_operand:P 3 "gpc_reg_operand" "r,r")))] - "" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0\;andc %0,%3,%0 - addic %0,%1,%n2\;subfe %0,%0,%0\;andc %0,%3,%0" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))] - "TARGET_32BIT" - "@ - subfc %4,%2,%1\;subfe %4,%4,%4\;andc. %4,%3,%4 - addic %4,%1,%n2\;subfe %4,%4,%4\;andc. %4,%3,%4 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 4 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 4) - (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) - (match_dup 3))) - (set (match_dup 0) - (compare:CC (match_dup 4) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))) - (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r")) - (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_32BIT" - "@ - subfc %0,%2,%1\;subfe %0,%0,%0\;andc. %0,%3,%0 - addic %0,%1,%n2\;subfe %0,%0,%0\;andc. %0,%3,%0 - # - #" - [(set_attr "type" "compare") - (set_attr "length" "12,12,16,16")]) - -(define_split - [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") - (compare:CC - (and:SI (neg:SI - (geu:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "reg_or_neg_short_operand" ""))) - (match_operand:SI 3 "gpc_reg_operand" "")) - (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_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) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "*plus_gt0<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (plus:P (gt:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int 0)) - (match_operand:P 2 "gpc_reg_operand" "r")))] - "" - "addc %0,%1,%1\;subfe %0,%1,%0\;addze %0,%2" - [(set_attr "type" "three") - (set_attr "length" "12")]) - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:SI 3 "=&r,&r"))] - "TARGET_32BIT" - "@ - addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:SI 3 ""))] - "TARGET_32BIT && reload_completed" - [(set (match_dup 3) - (plus:SI (gt:SI (match_dup 1) (const_int 0)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (const_int 0))) - (clobber (match_scratch:DI 3 "=&r,&r"))] - "TARGET_64BIT" - "@ - addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "")) - (const_int 0))) - (clobber (match_scratch:DI 3 ""))] - "TARGET_64BIT && reload_completed" - [(set (match_dup 3) - (plus:DI (gt:DI (match_dup 1) (const_int 0)) - (match_dup 2))) - (set (match_dup 0) - (compare:CC (match_dup 3) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "r,r")) - (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_32BIT" - "@ - addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") - (compare:CC - (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:SI 2 "gpc_reg_operand" "")) - (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_32BIT && reload_completed" - [(set (match_dup 0) - (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn "" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "r,r")) - (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_64BIT" - "@ - addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2 - #" - [(set_attr "type" "compare") - (set_attr "length" "12,16")]) - -(define_split - [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") - (compare:CC - (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "") - (const_int 0)) - (match_operand:DI 2 "gpc_reg_operand" "")) - (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_64BIT && reload_completed" - [(set (match_dup 0) - (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) - (set (match_dup 3) - (compare:CC (match_dup 0) - (const_int 0)))] - "") - -(define_insn_and_split "*gtu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (neg:P (match_dup 0)))] - "") - -(define_insn_and_split "*gtu<mode>_compare" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") - (compare:CC - (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r") - (match_operand:P 2 "reg_or_short_operand" "rI,rI")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=r,r") - (gtu:P (match_dup 1) (match_dup 2)))] - "" - "#" - "" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 3) - (compare:CC (neg:P (match_dup 0)) (const_int 0))) - (set (match_dup 0) (neg:P (match_dup 0)))])] - "") - -(define_insn_and_split "*plus_gtu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=&r") - (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI")) - (match_operand:P 3 "reg_or_short_operand" "rI")))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))] - "") - -(define_insn_and_split "*plus_gtu<mode>_compare" - [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y") - (compare:CC - (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r") - (match_operand:P 2 "reg_or_short_operand" "I,r,I,r")) - (match_operand:P 3 "gpc_reg_operand" "r,r,r,r")) - (const_int 0))) - (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r") - (plus:P (gtu:P (match_dup 1) (match_dup 2)) (match_dup 3)))] - "" - "#" - "&& !reg_overlap_mentioned_p (operands[0], operands[3])" - [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2)))) - (parallel [(set (match_dup 4) - (compare:CC (minus:P (match_dup 3) (match_dup 0)) - (const_int 0))) - (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])] - "") - -(define_insn "*neg_gtu<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_short_operand" "rI"))))] - "" - "subf%I2c %0,%1,%2\;subfe %0,%0,%0" - [(set_attr "type" "two") - (set_attr "length" "8")]) - - -;; Define both directions of branch and return. If we need a reload -;; register, we'd rather use CR0 since it is much easier to copy a -;; register CC value to there. - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(match_operand 2 - "cc_reg_operand" "y") - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - return output_cbranch (operands[1], \"%l0\", 0, insn); -}" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(match_operand 1 - "cc_reg_operand" "y") - (const_int 0)]) - (any_return) - (pc)))] - "<return_pred>" - "* -{ - return output_cbranch (operands[0], NULL, 0, insn); -}" - [(set_attr "type" "jmpreg") - (set_attr "length" "4")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 1 "branch_comparison_operator" - [(match_operand 2 - "cc_reg_operand" "y") - (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - return output_cbranch (operands[1], \"%l0\", 1, insn); -}" - [(set_attr "type" "branch")]) - -(define_insn "" - [(set (pc) - (if_then_else (match_operator 0 "branch_comparison_operator" - [(match_operand 1 - "cc_reg_operand" "y") - (const_int 0)]) - (pc) - (any_return)))] - "<return_pred>" - "* -{ - return output_cbranch (operands[0], NULL, 1, insn); -}" - [(set_attr "type" "jmpreg") - (set_attr "length" "4")]) - -;; Logic on condition register values. - -; This pattern matches things like -; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) -; (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 "*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 - "branch_positive_comparison_operator" - [(match_operand 3 - "cc_reg_operand" "y,y") - (const_int 0)]) - (match_operator:SI 4 - "branch_positive_comparison_operator" - [(match_operand 5 - "cc_reg_operand" "0,y") - (const_int 0)])]) - (const_int 1)))] - "" - "cr%q1 %E0,%j2,%j4" - [(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,?y") - (compare:CCEQ (match_operator:SI 1 "boolean_or_operator" - [(not:SI (match_operator:SI 2 - "branch_positive_comparison_operator" - [(match_operand 3 - "cc_reg_operand" "y,y") - (const_int 0)])) - (match_operator:SI 4 - "branch_positive_comparison_operator" - [(match_operand 5 - "cc_reg_operand" "0,y") - (const_int 0)])]) - (const_int -1)))] - "" - "cr%q1 %E0,%j2,%j4" - [(set_attr "type" "cr_logical,delayed_cr")]) - -(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" "0,y") - (const_int 0)]) - (const_int 0)))] - "" - "crnot %E0,%j1" - [(set_attr "type" "cr_logical,delayed_cr")]) - -;; If we are comparing the result of two comparisons, this can be done -;; using creqv or crxor. - -(define_insn_and_split "" - [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") - (compare:CCEQ (match_operator 1 "branch_comparison_operator" - [(match_operand 2 "cc_reg_operand" "y") - (const_int 0)]) - (match_operator 3 "branch_comparison_operator" - [(match_operand 4 "cc_reg_operand" "y") - (const_int 0)])))] - "" - "#" - "" - [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) - (match_dup 5)))] - " -{ - int positive_1, positive_2; - - positive_1 = branch_positive_comparison_operator (operands[1], - GET_MODE (operands[1])); - positive_2 = branch_positive_comparison_operator (operands[3], - GET_MODE (operands[3])); - - if (! positive_1) - operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), - GET_CODE (operands[1])), - SImode, - operands[2], const0_rtx); - else if (GET_MODE (operands[1]) != SImode) - operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, - operands[2], const0_rtx); - - if (! positive_2) - operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), - GET_CODE (operands[3])), - SImode, - operands[4], const0_rtx); - else if (GET_MODE (operands[3]) != SImode) - operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, - operands[4], const0_rtx); - - if (positive_1 == positive_2) - { - operands[1] = gen_rtx_NOT (SImode, operands[1]); - operands[5] = constm1_rtx; - } - else - { - operands[5] = const1_rtx; - } -}") - -;; Unconditional branch and return. - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "b %l0" - [(set_attr "type" "branch")]) - -(define_insn "<return_str>return" - [(any_return)] - "<return_pred>" - "blr" - [(set_attr "type" "jmpreg")]) - -(define_expand "indirect_jump" - [(set (pc) (match_operand 0 "register_operand" ""))]) - -(define_insn "*indirect_jump<mode>" - [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))] - "" - "@ - bctr - blr" - [(set_attr "type" "jmpreg")]) - -;; Table jump for switch statements: -(define_expand "tablejump" - [(use (match_operand 0 "" "")) - (use (label_ref (match_operand 1 "" "")))] - "" - " -{ - if (TARGET_32BIT) - emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); - else - emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); - DONE; -}") - -(define_expand "tablejumpsi" - [(set (match_dup 3) - (plus:SI (match_operand:SI 0 "" "") - (match_dup 2))) - (parallel [(set (pc) (match_dup 3)) - (use (label_ref (match_operand 1 "" "")))])] - "TARGET_32BIT" - " -{ operands[0] = force_reg (SImode, operands[0]); - operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); - operands[3] = gen_reg_rtx (SImode); -}") - -(define_expand "tablejumpdi" - [(set (match_dup 4) - (sign_extend:DI (match_operand:SI 0 "lwa_operand" ""))) - (set (match_dup 3) - (plus:DI (match_dup 4) - (match_dup 2))) - (parallel [(set (pc) (match_dup 3)) - (use (label_ref (match_operand 1 "" "")))])] - "TARGET_64BIT" - " -{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); - operands[3] = gen_reg_rtx (DImode); - operands[4] = gen_reg_rtx (DImode); -}") - -(define_insn "*tablejump<mode>_internal1" - [(set (pc) - (match_operand:P 0 "register_operand" "c,*l")) - (use (label_ref (match_operand 1 "" "")))] - "" - "@ - bctr - blr" - [(set_attr "type" "jmpreg")]) - -(define_insn "nop" - [(const_int 0)] - "" - "nop") - -(define_insn "group_ending_nop" - [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] - "" - "* -{ - if (rs6000_cpu_attr == CPU_POWER6) - return \"ori 1,1,0\"; - return \"ori 2,2,0\"; -}") - -;; Define the subtract-one-and-jump insns, starting with the template -;; so loop.c knows what to generate. - -(define_expand "doloop_end" - [(use (match_operand 0 "" "")) ; loop pseudo - (use (match_operand 1 "" "")) ; iterations; zero if unknown - (use (match_operand 2 "" "")) ; max iterations - (use (match_operand 3 "" "")) ; loop level - (use (match_operand 4 "" "")) ; label - (use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0 - "" - " -{ - /* Only use this on innermost loops. */ - if (INTVAL (operands[3]) > 1) - FAIL; - if (TARGET_64BIT) - { - if (GET_MODE (operands[0]) != DImode) - FAIL; - emit_jump_insn (gen_ctrdi (operands[0], operands[4])); - } - else - { - if (GET_MODE (operands[0]) != SImode) - FAIL; - emit_jump_insn (gen_ctrsi (operands[0], operands[4])); - } - DONE; -}") - -(define_expand "ctr<mode>" - [(parallel [(set (pc) - (if_then_else (ne (match_operand:P 0 "register_operand" "") - (const_int 1)) - (label_ref (match_operand 1 "" "")) - (pc))) - (set (match_dup 0) - (plus:P (match_dup 0) - (const_int -1))) - (clobber (match_scratch:CC 2 "")) - (clobber (match_scratch:P 3 ""))])] - "" - "") - -;; We need to be able to do this for any operand, including MEM, or we -;; will cause reload to blow up since we don't allow output reloads on -;; JUMP_INSNs. -;; For the length attribute to be calculated correctly, the -;; label MUST be operand 0. - -(define_insn "*ctr<mode>_internal1" - [(set (pc) - (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") - (plus:P (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) - (clobber (match_scratch:P 4 "=X,X,&r,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdnz %l0\"; - else - return \"bdz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16,16")]) - -(define_insn "*ctr<mode>_internal2" - [(set (pc) - (if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r") - (const_int 1)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") - (plus:P (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) - (clobber (match_scratch:P 4 "=X,X,&r,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdz %l0\"; - else - return \"bdnz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16,16")]) - -;; Similar but use EQ - -(define_insn "*ctr<mode>_internal5" - [(set (pc) - (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r") - (const_int 1)) - (label_ref (match_operand 0 "" "")) - (pc))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") - (plus:P (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) - (clobber (match_scratch:P 4 "=X,X,&r,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdz %l0\"; - else - return \"bdnz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16,16")]) - -(define_insn "*ctr<mode>_internal6" - [(set (pc) - (if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r") - (const_int 1)) - (pc) - (label_ref (match_operand 0 "" "")))) - (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*c*l") - (plus:P (match_dup 1) - (const_int -1))) - (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) - (clobber (match_scratch:P 4 "=X,X,&r,r"))] - "" - "* -{ - if (which_alternative != 0) - return \"#\"; - else if (get_attr_length (insn) == 4) - return \"bdnz %l0\"; - else - return \"bdz $+8\;b %l0\"; -}" - [(set_attr "type" "branch") - (set_attr "length" "*,12,16,16")]) - -;; Now the splitters if we could not allocate the CTR register - -(define_split - [(set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:P 1 "gpc_reg_operand" "") - (const_int 1)]) - (match_operand 5 "" "") - (match_operand 6 "" ""))) - (set (match_operand:P 0 "gpc_reg_operand" "") - (plus:P (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:P 4 ""))] - "reload_completed" - [(parallel [(set (match_dup 3) - (compare:CC (plus:P (match_dup 1) - (const_int -1)) - (const_int 0))) - (set (match_dup 0) - (plus:P (match_dup 1) - (const_int -1)))]) - (set (pc) (if_then_else (match_dup 7) - (match_dup 5) - (match_dup 6)))] - " -{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, - operands[3], const0_rtx); }") - -(define_split - [(set (pc) - (if_then_else (match_operator 2 "comparison_operator" - [(match_operand:P 1 "gpc_reg_operand" "") - (const_int 1)]) - (match_operand 5 "" "") - (match_operand 6 "" ""))) - (set (match_operand:P 0 "nonimmediate_operand" "") - (plus:P (match_dup 1) (const_int -1))) - (clobber (match_scratch:CC 3 "")) - (clobber (match_scratch:P 4 ""))] - "reload_completed && ! gpc_reg_operand (operands[0], SImode)" - [(parallel [(set (match_dup 3) - (compare:CC (plus:P (match_dup 1) - (const_int -1)) - (const_int 0))) - (set (match_dup 4) - (plus:P (match_dup 1) - (const_int -1)))]) - (set (match_dup 0) - (match_dup 4)) - (set (pc) (if_then_else (match_dup 7) - (match_dup 5) - (match_dup 6)))] - " -{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, - operands[3], const0_rtx); }") - -(define_insn "trap" - [(trap_if (const_int 1) (const_int 0))] - "" - "trap" - [(set_attr "type" "trap")]) - -(define_expand "ctrap<mode>4" - [(trap_if (match_operator 0 "ordered_comparison_operator" - [(match_operand:GPR 1 "register_operand") - (match_operand:GPR 2 "reg_or_short_operand")]) - (match_operand 3 "zero_constant" ""))] - "" - "") - -(define_insn "" - [(trap_if (match_operator 0 "ordered_comparison_operator" - [(match_operand:GPR 1 "register_operand" "r") - (match_operand:GPR 2 "reg_or_short_operand" "rI")]) - (const_int 0))] - "" - "t<wd>%V0%I2 %1,%2" - [(set_attr "type" "trap")]) - -;; Insns related to generating the function prologue and epilogue. - -(define_expand "prologue" - [(use (const_int 0))] - "" -{ - rs6000_emit_prologue (); - if (!TARGET_SCHED_PROLOG) - emit_insn (gen_blockage ()); - 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 CR0_REGNO) (reg:CC CR1_REGNO) - (reg:CC CR2_REGNO) (reg:CC CR3_REGNO) - (reg:CC CR4_REGNO) (reg:CC CR5_REGNO) - (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)] - UNSPEC_MOVESI_FROM_CR))] - "" - "mfcr %0" - [(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" - "stmw %2,%1" - [(set_attr "type" "store_ux")]) - -; The following comment applies to: -; save_gpregs_* -; save_fpregs_* -; restore_gpregs* -; return_and_restore_gpregs* -; return_and_restore_fpregs* -; return_and_restore_fpregs_aix* -; -; The out-of-line save / restore functions expects one input argument. -; Since those are not standard call_insn's, we must avoid using -; MATCH_OPERAND for that argument. That way the register rename -; optimization will not try to rename this register. -; Each pattern is repeated for each possible register number used in -; various ABIs (r11, r1, and for some functions r12) - -(define_insn "*save_gpregs_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:P 2 "memory_operand" "=m") - (match_operand:P 3 "gpc_reg_operand" "r"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*save_gpregs_<mode>_r12" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 12)) - (set (match_operand:P 2 "memory_operand" "=m") - (match_operand:P 3 "gpc_reg_operand" "r"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*save_gpregs_<mode>_r1" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 1)) - (set (match_operand:P 2 "memory_operand" "=m") - (match_operand:P 3 "gpc_reg_operand" "r"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*save_fpregs_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:DF 2 "memory_operand" "=m") - (match_operand:DF 3 "gpc_reg_operand" "d"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*save_fpregs_<mode>_r12" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 12)) - (set (match_operand:DF 2 "memory_operand" "=m") - (match_operand:DF 3 "gpc_reg_operand" "d"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*save_fpregs_<mode>_r1" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 1)) - (set (match_operand:DF 2 "memory_operand" "=m") - (match_operand:DF 3 "gpc_reg_operand" "d"))])] - "" - "bl %1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -; This is to explain that changes to the stack pointer should -; not be moved over loads from or stores to stack memory. -(define_insn "stack_tie" - [(match_parallel 0 "tie_operand" - [(set (mem:BLK (reg 1)) (const_int 0))])] - "" - "" - [(set_attr "length" "0")]) - -(define_expand "epilogue" - [(use (const_int 0))] - "" -{ - if (!TARGET_SCHED_PROLOG) - emit_insn (gen_blockage ()); - rs6000_emit_epilogue (FALSE); - DONE; -}) - -; On some processors, doing the mtcrf one CC register at a time is -; faster (like on the 604e). On others, doing them all at once is -; faster; for instance, on the 601 and 750. - -(define_expand "movsi_to_cr_one" - [(set (match_operand:CC 0 "cc_reg_operand" "") - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "") - (match_dup 2)] UNSPEC_MOVESI_TO_CR))] - "" - "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") - -(define_insn "*movsi_to_cr" - [(match_parallel 0 "mtcrf_operation" - [(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")] - UNSPEC_MOVESI_TO_CR))])] - "" - "* -{ - 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); - return \"mtcrf %4,%2\"; -}" - [(set_attr "type" "mtcr")]) - -(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")] - 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" "mtcr")]) - -; The load-multiple instructions have similar properties. -; Note that "load_multiple" is a name known to the machine-independent -; code that actually corresponds to the PowerPC load-string. - -(define_insn "*lmw" - [(match_parallel 0 "lmw_operation" - [(set (match_operand:SI 1 "gpc_reg_operand" "=r") - (match_operand:SI 2 "memory_operand" "m"))])] - "TARGET_MULTIPLE" - "lmw %1,%2" - [(set_attr "type" "load_ux") - (set_attr "cell_micro" "always")]) - -(define_insn "*return_internal_<mode>" - [(simple_return) - (use (match_operand:P 0 "register_operand" "lc"))] - "" - "b%T0" - [(set_attr "type" "jmpreg")]) - -; FIXME: This would probably be somewhat simpler if the Cygnus sibcall -; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... - -; The following comment applies to: -; save_gpregs_* -; save_fpregs_* -; restore_gpregs* -; return_and_restore_gpregs* -; return_and_restore_fpregs* -; return_and_restore_fpregs_aix* -; -; The out-of-line save / restore functions expects one input argument. -; Since those are not standard call_insn's, we must avoid using -; MATCH_OPERAND for that argument. That way the register rename -; optimization will not try to rename this register. -; Each pattern is repeated for each possible register number used in -; various ABIs (r11, r1, and for some functions r12) - -(define_insn "*restore_gpregs_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:P 3 "gpc_reg_operand" "=r") - (match_operand:P 4 "memory_operand" "m"))])] - "" - "bl %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*restore_gpregs_<mode>_r12" - [(match_parallel 0 "any_parallel_operand" - [(clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 12)) - (set (match_operand:P 3 "gpc_reg_operand" "=r") - (match_operand:P 4 "memory_operand" "m"))])] - "" - "bl %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*restore_gpregs_<mode>_r1" - [(match_parallel 0 "any_parallel_operand" - [(clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 1)) - (set (match_operand:P 3 "gpc_reg_operand" "=r") - (match_operand:P 4 "memory_operand" "m"))])] - "" - "bl %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_gpregs_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(return) - (clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:P 3 "gpc_reg_operand" "=r") - (match_operand:P 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_gpregs_<mode>_r12" - [(match_parallel 0 "any_parallel_operand" - [(return) - (clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 12)) - (set (match_operand:P 3 "gpc_reg_operand" "=r") - (match_operand:P 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_gpregs_<mode>_r1" - [(match_parallel 0 "any_parallel_operand" - [(return) - (clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 1)) - (set (match_operand:P 3 "gpc_reg_operand" "=r") - (match_operand:P 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_fpregs_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(return) - (clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:DF 3 "gpc_reg_operand" "=d") - (match_operand:DF 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_fpregs_<mode>_r12" - [(match_parallel 0 "any_parallel_operand" - [(return) - (clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 12)) - (set (match_operand:DF 3 "gpc_reg_operand" "=d") - (match_operand:DF 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_fpregs_<mode>_r1" - [(match_parallel 0 "any_parallel_operand" - [(return) - (clobber (match_operand:P 1 "register_operand" "=l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 1)) - (set (match_operand:DF 3 "gpc_reg_operand" "=d") - (match_operand:DF 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" - [(match_parallel 0 "any_parallel_operand" - [(return) - (use (match_operand:P 1 "register_operand" "l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:DF 3 "gpc_reg_operand" "=d") - (match_operand:DF 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" - [(match_parallel 0 "any_parallel_operand" - [(return) - (use (match_operand:P 1 "register_operand" "l")) - (use (match_operand:P 2 "symbol_ref_operand" "s")) - (use (reg:P 1)) - (set (match_operand:DF 3 "gpc_reg_operand" "=d") - (match_operand:DF 4 "memory_operand" "m"))])] - "" - "b %2" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -; This is used in compiling the unwind routines. -(define_expand "eh_return" - [(use (match_operand 0 "general_operand" ""))] - "" - " -{ - if (TARGET_32BIT) - emit_insn (gen_eh_set_lr_si (operands[0])); - else - emit_insn (gen_eh_set_lr_di (operands[0])); - DONE; -}") - -; We can't expand this before we know where the link register is stored. -(define_insn "eh_set_lr_<mode>" - [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] - UNSPECV_EH_RR) - (clobber (match_scratch:P 1 "=&b"))] - "" - "#") - -(define_split - [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR) - (clobber (match_scratch 1 ""))] - "reload_completed" - [(const_int 0)] - " -{ - rs6000_emit_eh_reg_restore (operands[0], operands[1]); - DONE; -}") - -(define_insn "prefetch" - [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n"))] - "" - "* -{ - if (GET_CODE (operands[0]) == REG) - return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\"; - return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\"; -}" - [(set_attr "type" "load")]) - -(define_insn "bpermd_<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] - "TARGET_POPCNTD" - "bpermd %0,%1,%2" - [(set_attr "type" "integer")]) - - -;; Builtin fma support. Handle -;; Note that the conditions for expansion are in the FMA_F iterator. - -(define_expand "fma<mode>4" - [(set (match_operand:FMA_F 0 "register_operand" "") - (fma:FMA_F - (match_operand:FMA_F 1 "register_operand" "") - (match_operand:FMA_F 2 "register_operand" "") - (match_operand:FMA_F 3 "register_operand" "")))] - "" - "") - -; Altivec only has fma and nfms. -(define_expand "fms<mode>4" - [(set (match_operand:FMA_F 0 "register_operand" "") - (fma:FMA_F - (match_operand:FMA_F 1 "register_operand" "") - (match_operand:FMA_F 2 "register_operand" "") - (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))] - "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "") - -;; If signed zeros are ignored, -(a * b - c) = -a * b + c. -(define_expand "fnma<mode>4" - [(set (match_operand:FMA_F 0 "register_operand" "") - (neg:FMA_F - (fma:FMA_F - (match_operand:FMA_F 1 "register_operand" "") - (match_operand:FMA_F 2 "register_operand" "") - (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))] - "!HONOR_SIGNED_ZEROS (<MODE>mode)" - "") - -;; If signed zeros are ignored, -(a * b + c) = -a * b - c. -(define_expand "fnms<mode>4" - [(set (match_operand:FMA_F 0 "register_operand" "") - (neg:FMA_F - (fma:FMA_F - (match_operand:FMA_F 1 "register_operand" "") - (match_operand:FMA_F 2 "register_operand" "") - (match_operand:FMA_F 3 "register_operand" ""))))] - "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "") - -; Not an official optab name, but used from builtins. -(define_expand "nfma<mode>4" - [(set (match_operand:FMA_F 0 "register_operand" "") - (neg:FMA_F - (fma:FMA_F - (match_operand:FMA_F 1 "register_operand" "") - (match_operand:FMA_F 2 "register_operand" "") - (match_operand:FMA_F 3 "register_operand" ""))))] - "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "") - -; Not an official optab name, but used from builtins. -(define_expand "nfms<mode>4" - [(set (match_operand:FMA_F 0 "register_operand" "") - (neg:FMA_F - (fma:FMA_F - (match_operand:FMA_F 1 "register_operand" "") - (match_operand:FMA_F 2 "register_operand" "") - (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))] - "" - "") - -(define_expand "rs6000_get_timebase" - [(use (match_operand:DI 0 "gpc_reg_operand" ""))] - "" -{ - if (TARGET_POWERPC64) - emit_insn (gen_rs6000_mftb_di (operands[0])); - else - emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0])); - DONE; -}) - -(define_insn "rs6000_get_timebase_ppc32" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") - (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB)) - (clobber (match_scratch:SI 1 "=r")) - (clobber (match_scratch:CC 2 "=y"))] - "!TARGET_POWERPC64" -{ - if (WORDS_BIG_ENDIAN) - if (TARGET_MFCRF) - { - return "mfspr %0,269\;" - "mfspr %L0,268\;" - "mfspr %1,269\;" - "cmpw %2,%0,%1\;" - "bne- %2,$-16"; - } - else - { - return "mftbu %0\;" - "mftb %L0\;" - "mftbu %1\;" - "cmpw %2,%0,%1\;" - "bne- %2,$-16"; - } - else - if (TARGET_MFCRF) - { - return "mfspr %L0,269\;" - "mfspr %0,268\;" - "mfspr %1,269\;" - "cmpw %2,%L0,%1\;" - "bne- %2,$-16"; - } - else - { - return "mftbu %L0\;" - "mftb %0\;" - "mftbu %1\;" - "cmpw %2,%L0,%1\;" - "bne- %2,$-16"; - } -}) - -(define_insn "rs6000_mftb_<mode>" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (unspec_volatile:P [(const_int 0)] UNSPECV_MFTB))] - "" -{ - if (TARGET_MFCRF) - return "mfspr %0,268"; - else - return "mftb %0"; -}) - - - -(include "sync.md") -(include "vector.md") -(include "vsx.md") -(include "altivec.md") -(include "spe.md") -(include "dfp.md") -(include "paired.md") diff --git a/gcc-4.8.1/gcc/config/rs6000/rs6000.opt b/gcc-4.8.1/gcc/config/rs6000/rs6000.opt deleted file mode 100644 index 8e3cea121..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs6000.opt +++ /dev/null @@ -1,516 +0,0 @@ -; Options for the rs6000 port of the compiler -; -; Copyright (C) 2005-2013 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 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -; License for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -HeaderInclude -config/rs6000/rs6000-opts.h - -;; ISA flag bits (on/off) -Variable -HOST_WIDE_INT rs6000_isa_flags = TARGET_DEFAULT - -TargetSave -HOST_WIDE_INT x_rs6000_isa_flags - -;; Miscellaneous flag bits that were set explicitly by the user -TargetSave -HOST_WIDE_INT x_rs6000_isa_flags_explicit - -;; Current processor -TargetVariable -enum processor_type rs6000_cpu = PROCESSOR_PPC603 - -;; Always emit branch hint bits. -TargetVariable -unsigned char rs6000_always_hint - -;; Schedule instructions for group formation. -TargetVariable -unsigned char rs6000_sched_groups - -;; Align branch targets. -TargetVariable -unsigned char rs6000_align_branch_targets - -;; Support for -msched-costly-dep option. -TargetVariable -enum rs6000_dependence_cost rs6000_sched_costly_dep = no_dep_costly - -;; Support for -minsert-sched-nops option. -TargetVariable -enum rs6000_nop_insertion rs6000_sched_insert_nops = sched_finish_none - -;; Non-zero to allow overriding loop alignment. -TargetVariable -unsigned char can_override_loop_align - -;; Which small data model to use (for System V targets only) -TargetVariable -enum rs6000_sdata_type rs6000_sdata = SDATA_DATA - -;; Bit size of immediate TLS offsets and string from which it is decoded. -TargetVariable -int rs6000_tls_size = 32 - -;; ABI enumeration available for subtarget to use. -TargetVariable -enum rs6000_abi rs6000_current_abi = ABI_NONE - -;; Type of traceback to use. -TargetVariable -enum rs6000_traceback_type rs6000_traceback = traceback_default - -;; Control alignment for fields within structures. -TargetVariable -unsigned char rs6000_alignment_flags - -;; Code model for 64-bit linux. -TargetVariable -enum rs6000_cmodel rs6000_current_cmodel = CMODEL_SMALL - -;; What type of reciprocal estimation instructions to generate -TargetVariable -unsigned int rs6000_recip_control - -;; Mask of what builtin functions are allowed -TargetVariable -HOST_WIDE_INT rs6000_builtin_mask - -;; Debug flags -TargetVariable -unsigned int rs6000_debug - -;; This option existed in the past, but now is always on. -mpowerpc -Target RejectNegative Undocumented Ignore - -mpowerpc64 -Target Report Mask(POWERPC64) Var(rs6000_isa_flags) -Use PowerPC-64 instruction set - -mpowerpc-gpopt -Target Report Mask(PPC_GPOPT) Var(rs6000_isa_flags) -Use PowerPC General Purpose group optional instructions - -mpowerpc-gfxopt -Target Report Mask(PPC_GFXOPT) Var(rs6000_isa_flags) -Use PowerPC Graphics group optional instructions - -mmfcrf -Target Report Mask(MFCRF) Var(rs6000_isa_flags) -Use PowerPC V2.01 single field mfcr instruction - -mpopcntb -Target Report Mask(POPCNTB) Var(rs6000_isa_flags) -Use PowerPC V2.02 popcntb instruction - -mfprnd -Target Report Mask(FPRND) Var(rs6000_isa_flags) -Use PowerPC V2.02 floating point rounding instructions - -mcmpb -Target Report Mask(CMPB) Var(rs6000_isa_flags) -Use PowerPC V2.05 compare bytes instruction - -mmfpgpr -Target Report Mask(MFPGPR) Var(rs6000_isa_flags) -Use extended PowerPC V2.05 move floating point to/from GPR instructions - -maltivec -Target Report Mask(ALTIVEC) Var(rs6000_isa_flags) -Use AltiVec instructions - -mhard-dfp -Target Report Mask(DFP) Var(rs6000_isa_flags) -Use decimal floating point instructions - -mmulhw -Target Report Mask(MULHW) Var(rs6000_isa_flags) -Use 4xx half-word multiply instructions - -mdlmzb -Target Report Mask(DLMZB) Var(rs6000_isa_flags) -Use 4xx string-search dlmzb instruction - -mmultiple -Target Report Mask(MULTIPLE) Var(rs6000_isa_flags) -Generate load/store multiple instructions - -mstring -Target Report Mask(STRING) Var(rs6000_isa_flags) -Generate string instructions for block moves - -msoft-float -Target Report RejectNegative Mask(SOFT_FLOAT) Var(rs6000_isa_flags) -Do not use hardware floating point - -mhard-float -Target Report RejectNegative InverseMask(SOFT_FLOAT, HARD_FLOAT) Var(rs6000_isa_flags) -Use hardware floating point - -mpopcntd -Target Report Mask(POPCNTD) Var(rs6000_isa_flags) -Use PowerPC V2.06 popcntd instruction - -mfriz -Target Report Var(TARGET_FRIZ) Init(-1) Save -Under -ffast-math, generate a FRIZ instruction for (double)(long long) conversions - -mveclibabi= -Target RejectNegative Joined Var(rs6000_veclibabi_name) -Vector library ABI to use - -mvsx -Target Report Mask(VSX) Var(rs6000_isa_flags) -Use vector/scalar (VSX) instructions - -mvsx-scalar-double -Target Undocumented Report Var(TARGET_VSX_SCALAR_DOUBLE) Init(-1) -; If -mvsx, use VSX arithmetic instructions for scalar double (on by default) - -mvsx-scalar-memory -Target Undocumented Report Var(TARGET_VSX_SCALAR_MEMORY) -; If -mvsx, use VSX scalar memory reference instructions for scalar double (off by default) - -mvsx-align-128 -Target Undocumented Report Var(TARGET_VSX_ALIGN_128) -; If -mvsx, set alignment to 128 bits instead of 32/64 - -mallow-movmisalign -Target Undocumented Var(TARGET_ALLOW_MOVMISALIGN) Init(-1) -; Allow/disallow the movmisalign in DF/DI vectors - -mallow-df-permute -Target Undocumented Var(TARGET_ALLOW_DF_PERMUTE) -; Allow/disallow permutation of DF/DI vectors - -msched-groups -Target Undocumented Report Var(TARGET_SCHED_GROUPS) Init(-1) -; Explicitly set/unset whether rs6000_sched_groups is set - -malways-hint -Target Undocumented Report Var(TARGET_ALWAYS_HINT) Init(-1) -; Explicitly set/unset whether rs6000_always_hint is set - -malign-branch-targets -Target Undocumented Report Var(TARGET_ALIGN_BRANCH_TARGETS) Init(-1) -; Explicitly set/unset whether rs6000_align_branch_targets is set - -mvectorize-builtins -Target Undocumented Report Var(TARGET_VECTORIZE_BUILTINS) Init(-1) -; Explicitly control whether we vectorize the builtins or not. - -mno-update -Target Report RejectNegative Mask(NO_UPDATE) Var(rs6000_isa_flags) -Do not generate load/store with update instructions - -mupdate -Target Report RejectNegative InverseMask(NO_UPDATE, UPDATE) Var(rs6000_isa_flags) -Generate load/store with update instructions - -msingle-pic-base -Target Report Var(TARGET_SINGLE_PIC_BASE) Init(0) -Do not load the PIC register in function prologues - -mavoid-indexed-addresses -Target Report Var(TARGET_AVOID_XFORM) Init(-1) Save -Avoid generation of indexed load/store instructions when possible - -mtls-markers -Target Report Var(tls_markers) Init(1) Save -Mark __tls_get_addr calls with argument info - -msched-epilog -Target Undocumented Var(TARGET_SCHED_PROLOG) Init(1) Save - -msched-prolog -Target Report Var(TARGET_SCHED_PROLOG) Save -Schedule the start and end of the procedure - -maix-struct-return -Target Report RejectNegative Var(aix_struct_return) Save -Return all structures in memory (AIX default) - -msvr4-struct-return -Target Report RejectNegative Var(aix_struct_return,0) Save -Return small structures in registers (SVR4 default) - -mxl-compat -Target Report Var(TARGET_XL_COMPAT) Save -Conform more closely to IBM XLC semantics - -mrecip -Target Report -Generate software reciprocal divide and square root for better throughput. - -mrecip= -Target Report RejectNegative Joined Var(rs6000_recip_name) -Generate software reciprocal divide and square root for better throughput. - -mrecip-precision -Target Report Mask(RECIP_PRECISION) Var(rs6000_isa_flags) -Assume that the reciprocal estimate instructions provide more accuracy. - -mno-fp-in-toc -Target Report RejectNegative Var(TARGET_NO_FP_IN_TOC) Save -Do not place floating point constants in TOC - -mfp-in-toc -Target Report RejectNegative Var(TARGET_NO_FP_IN_TOC,0) Save -Place floating point constants in TOC - -mno-sum-in-toc -Target RejectNegative Var(TARGET_NO_SUM_IN_TOC) Save -Do not place symbol+offset constants in TOC - -msum-in-toc -Target RejectNegative Var(TARGET_NO_SUM_IN_TOC,0) Save -Place symbol+offset constants in TOC - -; Output only one TOC entry per module. Normally linking fails if -; there are more than 16K unique variables/constants in an executable. With -; this option, linking fails only if there are more than 16K modules, or -; if there are more than 16K unique variables/constant in a single module. -; -; This is at the cost of having 2 extra loads and one extra store per -; function, and one less allocable register. -mminimal-toc -Target Report Mask(MINIMAL_TOC) Var(rs6000_isa_flags) -Use only one TOC entry per procedure - -mfull-toc -Target Report -Put everything in the regular TOC - -mvrsave -Target Report Var(TARGET_ALTIVEC_VRSAVE) Save -Generate VRSAVE instructions when generating AltiVec code - -mvrsave=no -Target RejectNegative Alias(mvrsave) NegativeAlias -Deprecated option. Use -mno-vrsave instead - -mvrsave=yes -Target RejectNegative Alias(mvrsave) -Deprecated option. Use -mvrsave instead - -mblock-move-inline-limit= -Target Report Var(rs6000_block_move_inline_limit) Init(0) RejectNegative Joined UInteger Save -Specify how many bytes should be moved inline before calling out to memcpy/memmove - -misel -Target Report Mask(ISEL) Var(rs6000_isa_flags) -Generate isel instructions - -misel=no -Target RejectNegative Alias(misel) NegativeAlias -Deprecated option. Use -mno-isel instead - -misel=yes -Target RejectNegative Alias(misel) -Deprecated option. Use -misel instead - -mspe -Target Var(rs6000_spe) Save -Generate SPE SIMD instructions on E500 - -mpaired -Target Var(rs6000_paired_float) Save -Generate PPC750CL paired-single instructions - -mspe=no -Target RejectNegative Alias(mspe) NegativeAlias -Deprecated option. Use -mno-spe instead - -mspe=yes -Target RejectNegative Alias(mspe) -Deprecated option. Use -mspe instead - -mdebug= -Target RejectNegative Joined --mdebug= Enable debug output - -mabi=altivec -Target RejectNegative Var(rs6000_altivec_abi) Save -Use the AltiVec ABI extensions - -mabi=no-altivec -Target RejectNegative Var(rs6000_altivec_abi, 0) -Do not use the AltiVec ABI extensions - -mabi=spe -Target RejectNegative Var(rs6000_spe_abi) Save -Use the SPE ABI extensions - -mabi=no-spe -Target RejectNegative Var(rs6000_spe_abi, 0) -Do not use the SPE ABI extensions - -; These are here for testing during development only, do not document -; in the manual please. - -; If we want Darwin's struct-by-value-in-regs ABI. -mabi=d64 -Target RejectNegative Undocumented Warn(using darwin64 ABI) Var(rs6000_darwin64_abi) Save - -mabi=d32 -Target RejectNegative Undocumented Warn(using old darwin ABI) Var(rs6000_darwin64_abi, 0) - -mabi=ieeelongdouble -Target RejectNegative Undocumented Warn(using IEEE extended precision long double) Var(rs6000_ieeequad) Save - -mabi=ibmlongdouble -Target RejectNegative Undocumented Warn(using IBM extended precision long double) Var(rs6000_ieeequad, 0) - -mcpu= -Target RejectNegative Joined Var(rs6000_cpu_index) Init(-1) Enum(rs6000_cpu_opt_value) Save --mcpu= Use features of and schedule code for given CPU - -mtune= -Target RejectNegative Joined Var(rs6000_tune_index) Init(-1) Enum(rs6000_cpu_opt_value) Save --mtune= Schedule code for given CPU - -mtraceback= -Target RejectNegative Joined Enum(rs6000_traceback_type) Var(rs6000_traceback) --mtraceback= Select full, part, or no traceback table - -Enum -Name(rs6000_traceback_type) Type(enum rs6000_traceback_type) - -EnumValue -Enum(rs6000_traceback_type) String(full) Value(traceback_full) - -EnumValue -Enum(rs6000_traceback_type) String(part) Value(traceback_part) - -EnumValue -Enum(rs6000_traceback_type) String(no) Value(traceback_none) - -mlongcall -Target Report Var(rs6000_default_long_calls) Save -Avoid all range limits on call instructions - -mgen-cell-microcode -Target Report Var(rs6000_gen_cell_microcode) Init(-1) Save -Generate Cell microcode - -mwarn-cell-microcode -Target Var(rs6000_warn_cell_microcode) Init(0) Warning Save -Warn when a Cell microcoded instruction is emitted - -mwarn-altivec-long -Target Var(rs6000_warn_altivec_long) Init(1) Save -Warn about deprecated 'vector long ...' AltiVec type usage - -mfloat-gprs= -Target RejectNegative Joined Enum(rs6000_float_gprs) Var(rs6000_float_gprs) Save --mfloat-gprs= Select GPR floating point method - -Enum -Name(rs6000_float_gprs) Type(unsigned char) -Valid arguments to -mfloat-gprs=: - -EnumValue -Enum(rs6000_float_gprs) String(yes) Value(1) - -EnumValue -Enum(rs6000_float_gprs) String(single) Value(1) - -EnumValue -Enum(rs6000_float_gprs) String(double) Value(2) - -EnumValue -Enum(rs6000_float_gprs) String(no) Value(0) - -mlong-double- -Target RejectNegative Joined UInteger Var(rs6000_long_double_type_size) Save --mlong-double-<n> Specify size of long double (64 or 128 bits) - -msched-costly-dep= -Target RejectNegative Joined Var(rs6000_sched_costly_dep_str) -Determine which dependences between insns are considered costly - -minsert-sched-nops= -Target RejectNegative Joined Var(rs6000_sched_insert_nops_str) -Specify which post scheduling nop insertion scheme to apply - -malign- -Target RejectNegative Joined Enum(rs6000_alignment_flags) Var(rs6000_alignment_flags) -Specify alignment of structure fields default/natural - -Enum -Name(rs6000_alignment_flags) Type(unsigned char) -Valid arguments to -malign-: - -EnumValue -Enum(rs6000_alignment_flags) String(power) Value(MASK_ALIGN_POWER) - -EnumValue -Enum(rs6000_alignment_flags) String(natural) Value(MASK_ALIGN_NATURAL) - -mprioritize-restricted-insns= -Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority) Save -Specify scheduling priority for dispatch slot restricted insns - -msingle-float -Target RejectNegative Var(rs6000_single_float) Save -Single-precision floating point unit - -mdouble-float -Target RejectNegative Var(rs6000_double_float) Save -Double-precision floating point unit - -msimple-fpu -Target RejectNegative Var(rs6000_simple_fpu) Save -Floating point unit does not support divide & sqrt - -mfpu= -Target RejectNegative Joined Enum(fpu_type_t) Var(rs6000_fpu_type) Init(FPU_NONE) --mfpu= Specify FP (sp, dp, sp-lite, dp-lite) (implies -mxilinx-fpu) - -Enum -Name(fpu_type_t) Type(enum fpu_type_t) - -EnumValue -Enum(fpu_type_t) String(none) Value(FPU_NONE) - -EnumValue -Enum(fpu_type_t) String(sp_lite) Value(FPU_SF_LITE) - -EnumValue -Enum(fpu_type_t) String(dp_lite) Value(FPU_DF_LITE) - -EnumValue -Enum(fpu_type_t) String(sp_full) Value(FPU_SF_FULL) - -EnumValue -Enum(fpu_type_t) String(dp_full) Value(FPU_DF_FULL) - -mxilinx-fpu -Target Var(rs6000_xilinx_fpu) Save -Specify Xilinx FPU. - -mpointers-to-nested-functions -Target Report Var(TARGET_POINTERS_TO_NESTED_FUNCTIONS) Init(1) Save -Use/do not use r11 to hold the static link in calls to functions via pointers. - -msave-toc-indirect -Target Report Var(TARGET_SAVE_TOC_INDIRECT) Save -Control whether we save the TOC in the prologue for indirect calls or generate the save inline diff --git a/gcc-4.8.1/gcc/config/rs6000/rs64.md b/gcc-4.8.1/gcc/config/rs6000/rs64.md deleted file mode 100644 index 9b9645087..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rs64.md +++ /dev/null @@ -1,154 +0,0 @@ -;; Scheduling description for IBM RS64 processors. -;; Copyright (C) 2003-2013 Free Software Foundation, Inc. -;; -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(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" 2 - (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-llsc" 2 - (and (eq_attr "type" "load_l,store_c") - (eq_attr "cpu" "rs64a")) - "lsu_rs64") - -(define_insn_reservation "rs64a-integer" 1 - (and (eq_attr "type" "integer,insert_word,insert_dword,shift,trap,\ - var_shift_rotate,cntlz,exts,isel") - (eq_attr "cpu" "rs64a")) - "iu_rs64") - -(define_insn_reservation "rs64a-two" 1 - (and (eq_attr "type" "two") - (eq_attr "cpu" "rs64a")) - "iu_rs64,iu_rs64") - -(define_insn_reservation "rs64a-three" 1 - (and (eq_attr "type" "three") - (eq_attr "cpu" "rs64a")) - "iu_rs64,iu_rs64,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,var_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") - -(define_insn_reservation "rs64a-isync" 6 - (and (eq_attr "type" "isync") - (eq_attr "cpu" "rs64a")) - "bpu_rs64") - -(define_insn_reservation "rs64a-sync" 1 - (and (eq_attr "type" "sync") - (eq_attr "cpu" "rs64a")) - "lsu_rs64") - diff --git a/gcc-4.8.1/gcc/config/rs6000/rtems.h b/gcc-4.8.1/gcc/config/rs6000/rtems.h deleted file mode 100644 index b910b5ec5..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/rtems.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Definitions for rtems targeting a PowerPC using elf. - Copyright (C) 1996-2013 Free Software Foundation, Inc. - Contributed by Joel Sherrill (joel@OARcorp.com). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Specify predefined symbols in preprocessor. */ - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define_std ("PPC"); \ - builtin_define ("__rtems__"); \ - builtin_define ("__USE_INIT_FINI__"); \ - builtin_assert ("system=rtems"); \ - builtin_assert ("cpu=powerpc"); \ - builtin_assert ("machine=powerpc"); \ - TARGET_OS_SYSV_CPP_BUILTINS (); \ - } \ - while (0) - -#undef CPP_OS_DEFAULT_SPEC -#define CPP_OS_DEFAULT_SPEC "%(cpp_os_rtems)" - -#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} } } \ -%{mcpu=8540: %{!Dppc*: %{!Dmpc*: -Dppc8540} } }" - -#undef SUBSUBTARGET_EXTRA_SPECS -#define SUBSUBTARGET_EXTRA_SPECS \ - { "cpp_os_rtems", CPP_OS_RTEMS_SPEC } diff --git a/gcc-4.8.1/gcc/config/rs6000/secureplt.h b/gcc-4.8.1/gcc/config/rs6000/secureplt.h deleted file mode 100644 index 39ffb8863..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/secureplt.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Default to -msecure-plt. - Copyright (C) 2005-2013 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#define CC1_SECURE_PLT_DEFAULT_SPEC "-msecure-plt" diff --git a/gcc-4.8.1/gcc/config/rs6000/si2vmx.h b/gcc-4.8.1/gcc/config/rs6000/si2vmx.h deleted file mode 100644 index e6e8c68c4..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/si2vmx.h +++ /dev/null @@ -1,2048 +0,0 @@ -/* Cell BEA specific SPU intrinsics to PPU/VMX intrinsics - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _SI2VMX_H_ -#define _SI2VMX_H_ 1 - -#ifndef __SPU__ - -#include <stdlib.h> -#include <vec_types.h> - - -/* Specify a default halt action for spu_hcmpeq and spu_hcmpgt intrinsics. - * Users can override the action by defining it prior to including this - * header file. - */ -#ifndef SPU_HALT_ACTION -#define SPU_HALT_ACTION abort() -#endif - -/* Specify a default stop action for the spu_stop intrinsic. - * Users can override the action by defining it prior to including this - * header file. - */ -#ifndef SPU_STOP_ACTION -#define SPU_STOP_ACTION abort() -#endif - - -/* Specify a default action for unsupported intrinsic. - * Users can override the action by defining it prior to including this - * header file. - */ -#ifndef SPU_UNSUPPORTED_ACTION -#define SPU_UNSUPPORTED_ACTION abort() -#endif - - -/* Casting intrinsics - from scalar to quadword - */ - -static __inline qword si_from_uchar(unsigned char c) { - union { - qword q; - unsigned char c[16]; - } x; - x.c[3] = c; - return (x.q); -} - -static __inline qword si_from_char(signed char c) { - union { - qword q; - signed char c[16]; - } x; - x.c[3] = c; - return (x.q); -} - -static __inline qword si_from_ushort(unsigned short s) { - union { - qword q; - unsigned short s[8]; - } x; - x.s[1] = s; - return (x.q); -} - -static __inline qword si_from_short(short s) { - union { - qword q; - short s[8]; - } x; - x.s[1] = s; - return (x.q); -} - - -static __inline qword si_from_uint(unsigned int i) { - union { - qword q; - unsigned int i[4]; - } x; - x.i[0] = i; - return (x.q); -} - -static __inline qword si_from_int(int i) { - union { - qword q; - int i[4]; - } x; - x.i[0] = i; - return (x.q); -} - -static __inline qword si_from_ullong(unsigned long long l) { - union { - qword q; - unsigned long long l[2]; - } x; - x.l[0] = l; - return (x.q); -} - -static __inline qword si_from_llong(long long l) { - union { - qword q; - long long l[2]; - } x; - x.l[0] = l; - return (x.q); -} - -static __inline qword si_from_float(float f) { - union { - qword q; - float f[4]; - } x; - x.f[0] = f; - return (x.q); -} - -static __inline qword si_from_double(double d) { - union { - qword q; - double d[2]; - } x; - x.d[0] = d; - return (x.q); -} - -static __inline qword si_from_ptr(void *ptr) { - union { - qword q; - void *p; - } x; - x.p = ptr; - return (x.q); -} - - -/* Casting intrinsics - from quadword to scalar - */ -static __inline unsigned char si_to_uchar(qword q) { - union { - qword q; - unsigned char c[16]; - } x; - x.q = q; - return (x.c[3]); -} - -static __inline signed char si_to_char(qword q) { - union { - qword q; - signed char c[16]; - } x; - x.q = q; - return (x.c[3]); -} - -static __inline unsigned short si_to_ushort(qword q) { - union { - qword q; - unsigned short s[8]; - } x; - x.q = q; - return (x.s[1]); -} - -static __inline short si_to_short(qword q) { - union { - qword q; - short s[8]; - } x; - x.q = q; - return (x.s[1]); -} - -static __inline unsigned int si_to_uint(qword q) { - union { - qword q; - unsigned int i[4]; - } x; - x.q = q; - return (x.i[0]); -} - -static __inline int si_to_int(qword q) { - union { - qword q; - int i[4]; - } x; - x.q = q; - return (x.i[0]); -} - -static __inline unsigned long long si_to_ullong(qword q) { - union { - qword q; - unsigned long long l[2]; - } x; - x.q = q; - return (x.l[0]); -} - -static __inline long long si_to_llong(qword q) { - union { - qword q; - long long l[2]; - } x; - x.q = q; - return (x.l[0]); -} - -static __inline float si_to_float(qword q) { - union { - qword q; - float f[4]; - } x; - x.q = q; - return (x.f[0]); -} - -static __inline double si_to_double(qword q) { - union { - qword q; - double d[2]; - } x; - x.q = q; - return (x.d[0]); -} - -static __inline void * si_to_ptr(qword q) { - union { - qword q; - void *p; - } x; - x.q = q; - return (x.p); -} - - -/* Absolute difference - */ -static __inline qword si_absdb(qword a, qword b) -{ - vec_uchar16 ac, bc, dc; - - ac = (vec_uchar16)(a); - bc = (vec_uchar16)(b); - dc = vec_sel(vec_sub(bc, ac), vec_sub(ac, bc), vec_cmpgt(ac, bc)); - - return ((qword)(dc)); -} - -/* Add intrinsics - */ -#define si_a(_a, _b) ((qword)(vec_add((vec_uint4)(_a), (vec_uint4)(_b)))) - -#define si_ah(_a, _b) ((qword)(vec_add((vec_ushort8)(_a), (vec_ushort8)(_b)))) - -static __inline qword si_ai(qword a, int b) -{ - return ((qword)(vec_add((vec_int4)(a), - vec_splat((vec_int4)(si_from_int(b)), 0)))); -} - - -static __inline qword si_ahi(qword a, short b) -{ - return ((qword)(vec_add((vec_short8)(a), - vec_splat((vec_short8)(si_from_short(b)), 1)))); -} - - -#define si_fa(_a, _b) ((qword)(vec_add((vec_float4)(_a), (vec_float4)(_b)))) - - -static __inline qword si_dfa(qword a, qword b) -{ - union { - vec_double2 v; - double d[2]; - } ad, bd, dd; - - ad.v = (vec_double2)(a); - bd.v = (vec_double2)(b); - dd.d[0] = ad.d[0] + bd.d[0]; - dd.d[1] = ad.d[1] + bd.d[1]; - - return ((qword)(dd.v)); -} - -/* Add word extended - */ -#define si_addx(_a, _b, _c) ((qword)(vec_add(vec_add((vec_uint4)(_a), (vec_uint4)(_b)), \ - vec_and((vec_uint4)(_c), vec_splat_u32(1))))) - - -/* Bit-wise AND - */ -#define si_and(_a, _b) ((qword)(vec_and((vec_uint4)(_a), (vec_uint4)(_b)))) - - -static __inline qword si_andbi(qword a, signed char b) -{ - return ((qword)(vec_and((vec_char16)(a), - vec_splat((vec_char16)(si_from_char(b)), 3)))); -} - -static __inline qword si_andhi(qword a, signed short b) -{ - return ((qword)(vec_and((vec_short8)(a), - vec_splat((vec_short8)(si_from_short(b)), 1)))); -} - - -static __inline qword si_andi(qword a, signed int b) -{ - return ((qword)(vec_and((vec_int4)(a), - vec_splat((vec_int4)(si_from_int(b)), 0)))); -} - - -/* Bit-wise AND with complement - */ -#define si_andc(_a, _b) ((qword)(vec_andc((vec_uchar16)(_a), (vec_uchar16)(_b)))) - - -/* Average byte vectors - */ -#define si_avgb(_a, _b) ((qword)(vec_avg((vec_uchar16)(_a), (vec_uchar16)(_b)))) - - -/* Branch indirect and set link on external data - */ -#define si_bisled(_func) /* not mappable */ -#define si_bisledd(_func) /* not mappable */ -#define si_bislede(_func) /* not mappable */ - - -/* Borrow generate - */ -#define si_bg(_a, _b) ((qword)(vec_subc((vec_uint4)(_b), (vec_uint4)(_a)))) - -#define si_bgx(_a, _b, _c) ((qword)(vec_and(vec_or(vec_cmpgt((vec_uint4)(_b), (vec_uint4)(_a)), \ - vec_and(vec_cmpeq((vec_uint4)(_b), (vec_uint4)(_a)), \ - (vec_uint4)(_c))), vec_splat_u32(1)))) - -/* Compare absolute equal - */ -static __inline qword si_fcmeq(qword a, qword b) -{ - vec_float4 msb = (vec_float4)((vec_uint4){0x80000000, 0x80000000, 0x80000000, 0x80000000}); - - return ((qword)(vec_cmpeq(vec_andc((vec_float4)(a), msb), - vec_andc((vec_float4)(b), msb)))); -} - -static __inline qword si_dfcmeq(qword a, qword b) -{ - vec_uint4 sign_mask= (vec_uint4) { 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; - vec_uint4 nan_mask = (vec_uint4) { 0x7FF00000, 0x00000000, 0x7FF00000, 0x00000000 }; - vec_uchar16 hihi_promote = (vec_uchar16) { 0,1,2,3, 16,17,18,19, 8,9,10,11, 24,25,26,27}; - - vec_uint4 biteq; - vec_uint4 aabs; - vec_uint4 babs; - vec_uint4 a_gt; - vec_uint4 ahi_inf; - vec_uint4 anan; - vec_uint4 result; - - union { - vec_uchar16 v; - int i[4]; - } x; - - /* Shift 4 bytes */ - x.i[3] = 4 << 3; - - /* Mask out sign bits */ - aabs = vec_and((vec_uint4)a,sign_mask); - babs = vec_and((vec_uint4)b,sign_mask); - - /* A) Check for bit equality, store in high word */ - biteq = (vec_uint4) vec_cmpeq((vec_uint4)aabs,(vec_uint4)babs); - biteq = vec_and(biteq,(vec_uint4)vec_slo((vec_uchar16)biteq,x.v)); - - /* - B) Check if a is NaN, store in high word - - B1) If the high word is greater than max_exp (indicates a NaN) - B2) If the low word is greater than 0 - */ - a_gt = (vec_uint4)vec_cmpgt(aabs,nan_mask); - - /* B3) Check if the high word is equal to the inf exponent */ - ahi_inf = (vec_uint4)vec_cmpeq(aabs,nan_mask); - - /* anan = B1[hi] or (B2[lo] and B3[hi]) */ - anan = (vec_uint4)vec_or(a_gt,vec_and((vec_uint4)vec_slo((vec_uchar16)a_gt,x.v),ahi_inf)); - - /* result = A and not B */ - result = vec_andc(biteq, anan); - - /* Promote high words to 64 bits and return */ - return ((qword)(vec_perm((vec_uchar16)result, (vec_uchar16)result, hihi_promote))); -} - - -/* Compare absolute greater than - */ -static __inline qword si_fcmgt(qword a, qword b) -{ - vec_float4 msb = (vec_float4)((vec_uint4){0x80000000, 0x80000000, 0x80000000, 0x80000000}); - - return ((qword)(vec_cmpgt(vec_andc((vec_float4)(a), msb), - vec_andc((vec_float4)(b), msb)))); -} - -static __inline qword si_dfcmgt(qword a, qword b) -{ - vec_uchar16 splat_hi = (vec_uchar16) { 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 }; - vec_uint4 nan_mask = (vec_uint4) { 0x7FF00000, 0x0, 0x7FF00000, 0x0 }; - vec_uint4 sign_mask = (vec_uint4) { 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; - - union { - vec_uchar16 v; - int i[4]; - } x; - - /* Shift 4 bytes */ - x.i[3] = 4 << 3; - - // absolute value of a,b - vec_uint4 aabs = vec_and((vec_uint4)a, sign_mask); - vec_uint4 babs = vec_and((vec_uint4)b, sign_mask); - - // check if a is nan - vec_uint4 a_inf = (vec_uint4)vec_cmpeq(aabs, nan_mask); - vec_uint4 a_nan = (vec_uint4)vec_cmpgt(aabs, nan_mask); - a_nan = vec_or(a_nan, vec_and((vec_uint4)vec_slo((vec_uchar16)a_nan,x.v),a_inf)); - a_nan = (vec_uint4)vec_perm((vec_uchar16)a_nan, (vec_uchar16)a_nan, splat_hi); - - // check if b is nan - vec_uint4 b_inf = (vec_uint4)vec_cmpeq(babs, nan_mask); - vec_uint4 b_nan = (vec_uint4)vec_cmpgt(babs, nan_mask); - b_nan = vec_or(b_nan, vec_and((vec_uint4)vec_slo((vec_uchar16)b_nan,x.v),b_inf)); - b_nan = (vec_uint4)vec_perm((vec_uchar16)b_nan, (vec_uchar16)b_nan, splat_hi); - - // A) Check if the exponents are different - vec_uint4 gt_hi = (vec_uint4)vec_cmpgt(aabs,babs); - - // B) Check if high word equal, and low word greater - vec_uint4 gt_lo = (vec_uint4)vec_cmpgt((vec_uint4)aabs, (vec_uint4)babs); - vec_uint4 eq = (vec_uint4)vec_cmpeq(aabs, babs); - vec_uint4 eqgt = vec_and(eq,vec_slo(gt_lo,x.v)); - - // If either A or B is true, return true (unless NaNs detected) - vec_uint4 r = vec_or(gt_hi, eqgt); - - // splat the high words of the comparison step - r = (vec_uint4)vec_perm((vec_uchar16)r,(vec_uchar16)r,splat_hi); - - // correct for NaNs in input - return ((qword)vec_andc(r,vec_or(a_nan,b_nan))); -} - - -/* Compare equal - */ -static __inline qword si_ceqb(qword a, qword b) -{ - return ((qword)(vec_cmpeq((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -static __inline qword si_ceqh(qword a, qword b) -{ - return ((qword)(vec_cmpeq((vec_ushort8)(a), (vec_ushort8)(b)))); -} - -static __inline qword si_ceq(qword a, qword b) -{ - return ((qword)(vec_cmpeq((vec_uint4)(a), (vec_uint4)(b)))); -} - -static __inline qword si_fceq(qword a, qword b) -{ - return ((qword)(vec_cmpeq((vec_float4)(a), (vec_float4)(b)))); -} - -static __inline qword si_ceqbi(qword a, signed char b) -{ - return ((qword)(vec_cmpeq((vec_char16)(a), - vec_splat((vec_char16)(si_from_char(b)), 3)))); -} - -static __inline qword si_ceqhi(qword a, signed short b) -{ - return ((qword)(vec_cmpeq((vec_short8)(a), - vec_splat((vec_short8)(si_from_short(b)), 1)))); -} - -static __inline qword si_ceqi(qword a, signed int b) -{ - return ((qword)(vec_cmpeq((vec_int4)(a), - vec_splat((vec_int4)(si_from_int(b)), 0)))); -} - -static __inline qword si_dfceq(qword a, qword b) -{ - vec_uint4 sign_mask= (vec_uint4) { 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; - vec_uint4 nan_mask = (vec_uint4) { 0x7FF00000, 0x00000000, 0x7FF00000, 0x00000000 }; - vec_uchar16 hihi_promote = (vec_uchar16) { 0,1,2,3, 16,17,18,19, 8,9,10,11, 24,25,26,27}; - - vec_uint4 biteq; - vec_uint4 aabs; - vec_uint4 babs; - vec_uint4 a_gt; - vec_uint4 ahi_inf; - vec_uint4 anan; - vec_uint4 iszero; - vec_uint4 result; - - union { - vec_uchar16 v; - int i[4]; - } x; - - /* Shift 4 bytes */ - x.i[3] = 4 << 3; - - /* A) Check for bit equality, store in high word */ - biteq = (vec_uint4) vec_cmpeq((vec_uint4)a,(vec_uint4)b); - biteq = vec_and(biteq,(vec_uint4)vec_slo((vec_uchar16)biteq,x.v)); - - /* Mask out sign bits */ - aabs = vec_and((vec_uint4)a,sign_mask); - babs = vec_and((vec_uint4)b,sign_mask); - - /* - B) Check if a is NaN, store in high word - - B1) If the high word is greater than max_exp (indicates a NaN) - B2) If the low word is greater than 0 - */ - a_gt = (vec_uint4)vec_cmpgt(aabs,nan_mask); - - /* B3) Check if the high word is equal to the inf exponent */ - ahi_inf = (vec_uint4)vec_cmpeq(aabs,nan_mask); - - /* anan = B1[hi] or (B2[lo] and B3[hi]) */ - anan = (vec_uint4)vec_or(a_gt,vec_and((vec_uint4)vec_slo((vec_uchar16)a_gt,x.v),ahi_inf)); - - /* C) Check for 0 = -0 special case */ - iszero =(vec_uint4)vec_cmpeq((vec_uint4)vec_or(aabs,babs),(vec_uint4)vec_splat_u32(0)); - iszero = vec_and(iszero,(vec_uint4)vec_slo((vec_uchar16)iszero,x.v)); - - /* result = (A or C) and not B */ - result = vec_or(biteq,iszero); - result = vec_andc(result, anan); - - /* Promote high words to 64 bits and return */ - return ((qword)(vec_perm((vec_uchar16)result, (vec_uchar16)result, hihi_promote))); -} - - -/* Compare greater than - */ -static __inline qword si_cgtb(qword a, qword b) -{ - return ((qword)(vec_cmpgt((vec_char16)(a), (vec_char16)(b)))); -} - -static __inline qword si_cgth(qword a, qword b) -{ - return ((qword)(vec_cmpgt((vec_short8)(a), (vec_short8)(b)))); -} - -static __inline qword si_cgt(qword a, qword b) -{ - return ((qword)(vec_cmpgt((vec_int4)(a), (vec_int4)(b)))); -} - -static __inline qword si_clgtb(qword a, qword b) -{ - return ((qword)(vec_cmpgt((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -static __inline qword si_clgth(qword a, qword b) -{ - return ((qword)(vec_cmpgt((vec_ushort8)(a), (vec_ushort8)(b)))); -} - -static __inline qword si_clgt(qword a, qword b) -{ - return ((qword)(vec_cmpgt((vec_uint4)(a), (vec_uint4)(b)))); -} - -static __inline qword si_fcgt(qword a, qword b) -{ - return ((qword)(vec_cmpgt((vec_float4)(a), (vec_float4)(b)))); -} - -static __inline qword si_dfcgt(qword a, qword b) -{ - vec_uchar16 splat_hi = (vec_uchar16) { 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 }; - vec_uchar16 borrow_shuffle = (vec_uchar16) { 4,5,6,7, 192,192,192,192, 12,13,14,15, 192,192,192,192 }; - vec_uint4 nan_mask = (vec_uint4) { 0x7FF00000, 0x0, 0x7FF00000, 0x0 }; - vec_uint4 sign_mask = (vec_uint4) { 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; - - union { - vec_uchar16 v; - int i[4]; - } x; - - /* Shift 4 bytes */ - x.i[3] = 4 << 3; - - // absolute value of a,b - vec_uint4 aabs = vec_and((vec_uint4)a, sign_mask); - vec_uint4 babs = vec_and((vec_uint4)b, sign_mask); - - // check if a is nan - vec_uint4 a_inf = (vec_uint4)vec_cmpeq(aabs, nan_mask); - vec_uint4 a_nan = (vec_uint4)vec_cmpgt(aabs, nan_mask); - a_nan = vec_or(a_nan, vec_and((vec_uint4)vec_slo((vec_uchar16)a_nan,x.v),a_inf)); - a_nan = (vec_uint4)vec_perm((vec_uchar16)a_nan, (vec_uchar16)a_nan, splat_hi); - - // check if b is nan - vec_uint4 b_inf = (vec_uint4)vec_cmpeq(babs, nan_mask); - vec_uint4 b_nan = (vec_uint4)vec_cmpgt(babs, nan_mask); - b_nan = vec_or(b_nan, vec_and((vec_uint4)vec_slo((vec_uchar16)b_nan,x.v),b_inf)); - b_nan = (vec_uint4)vec_perm((vec_uchar16)b_nan, (vec_uchar16)b_nan, splat_hi); - - // sign of a - vec_uint4 asel = (vec_uint4)vec_sra((vec_int4)(a), (vec_uint4)vec_splat(((vec_uint4)si_from_int(31)), 0)); - asel = (vec_uint4)vec_perm((vec_uchar16)asel,(vec_uchar16)asel,splat_hi); - - // sign of b - vec_uint4 bsel = (vec_uint4)vec_sra((vec_int4)(b), (vec_uint4)vec_splat(((vec_uint4)si_from_int(31)), 0)); - bsel = (vec_uint4)vec_perm((vec_uchar16)bsel,(vec_uchar16)bsel,splat_hi); - - // negative a - vec_uint4 abor = vec_subc((vec_uint4)vec_splat_u32(0), aabs); - vec_uchar16 pat = vec_sel(((vec_uchar16){0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}), vec_sr(borrow_shuffle, vec_splat_u8(3)), vec_sra(borrow_shuffle, vec_splat_u8(7))); - abor = (vec_uint4)(vec_perm(vec_perm((vec_uchar16)abor, (vec_uchar16)abor, borrow_shuffle),((vec_uchar16){0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}),pat)); - vec_uint4 aneg = vec_add(vec_add(vec_splat_u32(0), vec_nor(aabs, aabs)), vec_and(abor, vec_splat_u32(1))); - - // pick the one we want - vec_int4 aval = (vec_int4)vec_sel((vec_uchar16)aabs, (vec_uchar16)aneg, (vec_uchar16)asel); - - // negative b - vec_uint4 bbor = vec_subc((vec_uint4)vec_splat_u32(0), babs); - bbor = (vec_uint4)(vec_perm(vec_perm((vec_uchar16)bbor, (vec_uchar16)bbor, borrow_shuffle),((vec_uchar16){0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}),pat)); - vec_uint4 bneg = vec_add(vec_nor(babs, babs), vec_and(bbor, vec_splat_u32(1))); - - // pick the one we want - vec_int4 bval=(vec_int4)vec_sel((vec_uchar16)babs, (vec_uchar16)bneg, (vec_uchar16)bsel); - - // A) Check if the exponents are different - vec_uint4 gt_hi = (vec_uint4)vec_cmpgt(aval,bval); - - // B) Check if high word equal, and low word greater - vec_uint4 gt_lo = (vec_uint4)vec_cmpgt((vec_uint4)aval, (vec_uint4)bval); - vec_uint4 eq = (vec_uint4)vec_cmpeq(aval, bval); - vec_uint4 eqgt = vec_and(eq,vec_slo(gt_lo,x.v)); - - // If either A or B is true, return true (unless NaNs detected) - vec_uint4 r = vec_or(gt_hi, eqgt); - - // splat the high words of the comparison step - r = (vec_uint4)vec_perm((vec_uchar16)r,(vec_uchar16)r,splat_hi); - - // correct for NaNs in input - return ((qword)vec_andc(r,vec_or(a_nan,b_nan))); -} - -static __inline qword si_cgtbi(qword a, signed char b) -{ - return ((qword)(vec_cmpgt((vec_char16)(a), - vec_splat((vec_char16)(si_from_char(b)), 3)))); -} - -static __inline qword si_cgthi(qword a, signed short b) -{ - return ((qword)(vec_cmpgt((vec_short8)(a), - vec_splat((vec_short8)(si_from_short(b)), 1)))); -} - -static __inline qword si_cgti(qword a, signed int b) -{ - return ((qword)(vec_cmpgt((vec_int4)(a), - vec_splat((vec_int4)(si_from_int(b)), 0)))); -} - -static __inline qword si_clgtbi(qword a, unsigned char b) -{ - return ((qword)(vec_cmpgt((vec_uchar16)(a), - vec_splat((vec_uchar16)(si_from_uchar(b)), 3)))); -} - -static __inline qword si_clgthi(qword a, unsigned short b) -{ - return ((qword)(vec_cmpgt((vec_ushort8)(a), - vec_splat((vec_ushort8)(si_from_ushort(b)), 1)))); -} - -static __inline qword si_clgti(qword a, unsigned int b) -{ - return ((qword)(vec_cmpgt((vec_uint4)(a), - vec_splat((vec_uint4)(si_from_uint(b)), 0)))); -} - -static __inline qword si_dftsv(qword a, char b) -{ - vec_uchar16 splat_hi = (vec_uchar16) { 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 }; - vec_uint4 sign_mask = (vec_uint4) { 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; - vec_uint4 result = (vec_uint4){0}; - vec_uint4 sign = (vec_uint4)vec_sra((vec_int4)(a), (vec_uint4)vec_splat(((vec_uint4)si_from_int(31)), 0)); - sign = (vec_uint4)vec_perm((vec_uchar16)sign,(vec_uchar16)sign,splat_hi); - vec_uint4 aabs = vec_and((vec_uint4)a,sign_mask); - - union { - vec_uchar16 v; - int i[4]; - } x; - - /* Shift 4 bytes */ - x.i[3] = 4 << 3; - - /* Nan or +inf or -inf */ - if (b & 0x70) - { - vec_uint4 nan_mask = (vec_uint4) { 0x7FF00000, 0x0, 0x7FF00000, 0x0 }; - vec_uint4 a_inf = (vec_uint4)vec_cmpeq(aabs, nan_mask); - /* NaN */ - if (b & 0x40) - { - vec_uint4 a_nan = (vec_uint4)vec_cmpgt(aabs, nan_mask); - a_nan = vec_or(a_nan, vec_and((vec_uint4)vec_slo((vec_uchar16)a_nan,x.v),a_inf)); - a_nan = (vec_uint4)vec_perm((vec_uchar16)a_nan, (vec_uchar16)a_nan, splat_hi); - result = vec_or(result, a_nan); - } - /* inf */ - if (b & 0x30) - { - a_inf = vec_and((vec_uint4)vec_slo((vec_uchar16)a_inf,x.v), a_inf); - a_inf = (vec_uint4)vec_perm((vec_uchar16)a_inf, (vec_uchar16)a_inf, splat_hi); - /* +inf */ - if (b & 0x20) - result = vec_or(vec_andc(a_inf, sign), result); - /* -inf */ - if (b & 0x10) - result = vec_or(vec_and(a_inf, sign), result); - } - } - /* 0 or denorm */ - if (b & 0xF) - { - vec_uint4 iszero =(vec_uint4)vec_cmpeq(aabs,(vec_uint4)vec_splat_u32(0)); - iszero = vec_and(iszero,(vec_uint4)vec_slo((vec_uchar16)iszero,x.v)); - /* denorm */ - if (b & 0x3) - { - vec_uint4 denorm_mask = (vec_uint4){0xFFFFF, 0xFFFFF, 0xFFFFF, 0xFFFFF}; - vec_uint4 isdenorm = vec_nor((vec_uint4)vec_cmpgt(aabs, denorm_mask), iszero); - isdenorm = (vec_uint4)vec_perm((vec_uchar16)isdenorm, (vec_uchar16)isdenorm, splat_hi); - /* +denorm */ - if (b & 0x2) - result = vec_or(vec_andc(isdenorm, sign), result); - /* -denorm */ - if (b & 0x1) - result = vec_or(vec_and(isdenorm, sign), result); - } - /* 0 */ - if (b & 0xC) - { - iszero = (vec_uint4)vec_perm((vec_uchar16)iszero, (vec_uchar16)iszero, splat_hi); - /* +0 */ - if (b & 0x8) - result = vec_or(vec_andc(iszero, sign), result); - /* -0 */ - if (b & 0x4) - result = vec_or(vec_and(iszero, sign), result); - } - } - return ((qword)result); -} - - -/* Carry generate - */ -#define si_cg(_a, _b) ((qword)(vec_addc((vec_uint4)(_a), (vec_uint4)(_b)))) - -#define si_cgx(_a, _b, _c) ((qword)(vec_or(vec_addc((vec_uint4)(_a), (vec_uint4)(_b)), \ - vec_addc(vec_add((vec_uint4)(_a), (vec_uint4)(_b)), \ - vec_and((vec_uint4)(_c), vec_splat_u32(1)))))) - - -/* Count ones for bytes - */ -static __inline qword si_cntb(qword a) -{ - vec_uchar16 nib_cnt = (vec_uchar16){0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; - vec_uchar16 four = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; - vec_uchar16 av; - - av = (vec_uchar16)(a); - - return ((qword)(vec_add(vec_perm(nib_cnt, nib_cnt, av), - vec_perm(nib_cnt, nib_cnt, vec_sr (av, four))))); -} - -/* Count ones for bytes - */ -static __inline qword si_clz(qword a) -{ - vec_uchar16 av; - vec_uchar16 cnt_hi, cnt_lo, cnt, tmp1, tmp2, tmp3; - vec_uchar16 four = vec_splat_u8(4); - vec_uchar16 nib_cnt = (vec_uchar16){4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; - vec_uchar16 eight = vec_splat_u8(8); - vec_uchar16 sixteen = (vec_uchar16){16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}; - vec_uchar16 twentyfour = (vec_uchar16){24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24}; - - av = (vec_uchar16)(a); - - cnt_hi = vec_perm(nib_cnt, nib_cnt, vec_sr(av, four)); - cnt_lo = vec_perm(nib_cnt, nib_cnt, av); - - cnt = vec_add(cnt_hi, vec_and(cnt_lo, vec_cmpeq(cnt_hi, four))); - - tmp1 = (vec_uchar16)vec_sl((vec_uint4)(cnt), (vec_uint4)(eight)); - tmp2 = (vec_uchar16)vec_sl((vec_uint4)(cnt), (vec_uint4)(sixteen)); - tmp3 = (vec_uchar16)vec_sl((vec_uint4)(cnt), (vec_uint4)(twentyfour)); - - cnt = vec_add(cnt, vec_and(tmp1, vec_cmpeq(cnt, eight))); - cnt = vec_add(cnt, vec_and(tmp2, vec_cmpeq(cnt, sixteen))); - cnt = vec_add(cnt, vec_and(tmp3, vec_cmpeq(cnt, twentyfour))); - - return (qword)((vec_sr((vec_uint4)(cnt), (vec_uint4)(twentyfour)))); -} - -/* Convert to float - */ -#define si_cuflt(_a, _b) ((qword)(vec_ctf((vec_uint4)(_a), _b))) -#define si_csflt(_a, _b) ((qword)(vec_ctf((vec_int4)(_a), _b))) - -/* Convert to signed int - */ -#define si_cflts(_a, _b) ((qword)(vec_cts((vec_float4)(_a), _b))) - -/* Convert to unsigned int - */ -#define si_cfltu(_a, _b) ((qword)(vec_ctu((vec_float4)(_a), _b))) - -/* Synchronize - */ -#define si_dsync() /* do nothing */ -#define si_sync() /* do nothing */ -#define si_syncc() /* do nothing */ - - -/* Equivalence - */ -static __inline qword si_eqv(qword a, qword b) -{ - vec_uchar16 d; - - d = vec_xor((vec_uchar16)(a), (vec_uchar16)(b)); - return ((qword)(vec_nor(d, d))); -} - -/* Extend - */ -static __inline qword si_xsbh(qword a) -{ - vec_char16 av; - - av = (vec_char16)(a); - return ((qword)(vec_unpackh(vec_perm(av, av, ((vec_uchar16){1, 3, 5, 7, 9,11,13,15, - 0, 0, 0, 0, 0, 0, 0, 0}))))); -} - -static __inline qword si_xshw(qword a) -{ - vec_short8 av; - - av = (vec_short8)(a); - return ((qword)(vec_unpackh(vec_perm(av, av, ((vec_uchar16){2, 3, 6, 7, - 10,11,14,15, - 0, 0, 0, 0, - 0, 0, 0, 0}))))); -} - -static __inline qword si_xswd(qword a) -{ - vec_int4 av; - - av = (vec_int4)(a); - return ((qword)(vec_perm(av, vec_sra(av, ((vec_uint4){31,31,31,31})), - ((vec_uchar16){20, 21, 22, 23, - 4, 5, 6, 7, - 28, 29, 30, 31, - 12, 13, 14, 15})))); -} - -static __inline qword si_fesd(qword a) -{ - union { - double d[2]; - vec_double2 vd; - } out; - union { - float f[4]; - vec_float4 vf; - } in; - - in.vf = (vec_float4)(a); - out.d[0] = (double)(in.f[0]); - out.d[1] = (double)(in.f[2]); - return ((qword)(out.vd)); -} - -/* Gather - */ -static __inline qword si_gbb(qword a) -{ - vec_uchar16 bits; - vec_uint4 bytes; - - bits = vec_sl(vec_and((vec_uchar16)(a), vec_splat_u8(1)), ((vec_uchar16){7, 6, 5, 4, 3, 2, 1, 0, - 7, 6, 5, 4, 3, 2, 1, 0})); - bytes = (vec_uint4)vec_sum2s((vec_int4)(vec_sum4s(bits, ((vec_uint4){0}))), ((vec_int4){0})); - - return ((qword)(vec_perm(bytes, bytes, ((vec_uchar16){0, 0, 7,15, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0})))); -} - - -static __inline qword si_gbh(qword a) -{ - vec_ushort8 bits; - vec_uint4 bytes; - - bits = vec_sl(vec_and((vec_ushort8)(a), vec_splat_u16(1)), ((vec_ushort8){7, 6, 5, 4, 3, 2, 1, 0})); - - bytes = (vec_uint4)vec_sums((vec_int4)(vec_sum4s((vec_short8)(bits), (vec_int4){0})), (vec_int4){0}); - - return ((qword)(vec_sld(bytes, bytes, 12))); -} - -static __inline qword si_gb(qword a) -{ - vec_uint4 bits; - vec_uint4 bytes; - - bits = vec_sl(vec_and((vec_uint4)(a), vec_splat_u32(1)), ((vec_uint4){3, 2, 1, 0})); - bytes = (vec_uint4)vec_sums((vec_int4)(bits), ((vec_int4){0})); - return ((qword)(vec_sld(bytes, bytes, 12))); -} - - -/* Compare and halt - */ -static __inline void si_heq(qword a, qword b) -{ - union { - vector unsigned int v; - unsigned int i[4]; - } aa, bb; - - aa.v = (vector unsigned int)(a); - bb.v = (vector unsigned int)(b); - - if (aa.i[0] == bb.i[0]) { SPU_HALT_ACTION; }; -} - -static __inline void si_heqi(qword a, unsigned int b) -{ - union { - vector unsigned int v; - unsigned int i[4]; - } aa; - - aa.v = (vector unsigned int)(a); - - if (aa.i[0] == b) { SPU_HALT_ACTION; }; -} - -static __inline void si_hgt(qword a, qword b) -{ - union { - vector signed int v; - signed int i[4]; - } aa, bb; - - aa.v = (vector signed int)(a); - bb.v = (vector signed int)(b); - - if (aa.i[0] > bb.i[0]) { SPU_HALT_ACTION; }; -} - -static __inline void si_hgti(qword a, signed int b) -{ - union { - vector signed int v; - signed int i[4]; - } aa; - - aa.v = (vector signed int)(a); - - if (aa.i[0] > b) { SPU_HALT_ACTION; }; -} - -static __inline void si_hlgt(qword a, qword b) -{ - union { - vector unsigned int v; - unsigned int i[4]; - } aa, bb; - - aa.v = (vector unsigned int)(a); - bb.v = (vector unsigned int)(b); - - if (aa.i[0] > bb.i[0]) { SPU_HALT_ACTION; }; -} - -static __inline void si_hlgti(qword a, unsigned int b) -{ - union { - vector unsigned int v; - unsigned int i[4]; - } aa; - - aa.v = (vector unsigned int)(a); - - if (aa.i[0] > b) { SPU_HALT_ACTION; }; -} - - -/* Multiply and Add - */ -static __inline qword si_mpya(qword a, qword b, qword c) -{ - return ((qword)(vec_msum(vec_and((vec_short8)(a), - ((vec_short8){0, -1, 0, -1, 0, -1, 0, -1})), - (vec_short8)(b), (vec_int4)(c)))); -} - -static __inline qword si_fma(qword a, qword b, qword c) -{ - return ((qword)(vec_madd((vec_float4)(a), (vec_float4)(b), (vec_float4)(c)))); -} - -static __inline qword si_dfma(qword a, qword b, qword c) -{ - union { - vec_double2 v; - double d[2]; - } aa, bb, cc, dd; - - aa.v = (vec_double2)(a); - bb.v = (vec_double2)(b); - cc.v = (vec_double2)(c); - dd.d[0] = aa.d[0] * bb.d[0] + cc.d[0]; - dd.d[1] = aa.d[1] * bb.d[1] + cc.d[1]; - return ((qword)(dd.v)); -} - -/* Form Mask - */ -#define si_fsmbi(_a) si_fsmb(si_from_int(_a)) - -static __inline qword si_fsmb(qword a) -{ - vec_char16 mask; - vec_ushort8 in; - - in = (vec_ushort8)(a); - mask = (vec_char16)(vec_perm(in, in, ((vec_uchar16){2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3}))); - return ((qword)(vec_sra(vec_sl(mask, ((vec_uchar16){0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7})), - vec_splat_u8(7)))); -} - - -static __inline qword si_fsmh(qword a) -{ - vec_uchar16 in; - vec_short8 mask; - - in = (vec_uchar16)(a); - mask = (vec_short8)(vec_splat(in, 3)); - return ((qword)(vec_sra(vec_sl(mask, ((vec_ushort8){0, 1, 2, 3, 4, 5, 6, 7})), - vec_splat_u16(15)))); -} - -static __inline qword si_fsm(qword a) -{ - vec_uchar16 in; - vec_int4 mask; - - in = (vec_uchar16)(a); - mask = (vec_int4)(vec_splat(in, 3)); - return ((qword)(vec_sra(vec_sl(mask, ((vec_uint4){28, 29, 30, 31})), - ((vec_uint4){31,31,31,31})))); -} - -/* Move from/to registers - */ -#define si_fscrrd() ((qword)((vec_uint4){0})) -#define si_fscrwr(_a) - -#define si_mfspr(_reg) ((qword)((vec_uint4){0})) -#define si_mtspr(_reg, _a) - -/* Multiply High High Add - */ -static __inline qword si_mpyhha(qword a, qword b, qword c) -{ - return ((qword)(vec_add(vec_mule((vec_short8)(a), (vec_short8)(b)), (vec_int4)(c)))); -} - -static __inline qword si_mpyhhau(qword a, qword b, qword c) -{ - return ((qword)(vec_add(vec_mule((vec_ushort8)(a), (vec_ushort8)(b)), (vec_uint4)(c)))); -} - -/* Multiply Subtract - */ -static __inline qword si_fms(qword a, qword b, qword c) -{ - return ((qword)(vec_madd((vec_float4)(a), (vec_float4)(b), - vec_sub(((vec_float4){0.0f}), (vec_float4)(c))))); -} - -static __inline qword si_dfms(qword a, qword b, qword c) -{ - union { - vec_double2 v; - double d[2]; - } aa, bb, cc, dd; - - aa.v = (vec_double2)(a); - bb.v = (vec_double2)(b); - cc.v = (vec_double2)(c); - dd.d[0] = aa.d[0] * bb.d[0] - cc.d[0]; - dd.d[1] = aa.d[1] * bb.d[1] - cc.d[1]; - return ((qword)(dd.v)); -} - -/* Multiply - */ -static __inline qword si_fm(qword a, qword b) -{ - return ((qword)(vec_madd((vec_float4)(a), (vec_float4)(b), ((vec_float4){0.0f})))); -} - -static __inline qword si_dfm(qword a, qword b) -{ - union { - vec_double2 v; - double d[2]; - } aa, bb, dd; - - aa.v = (vec_double2)(a); - bb.v = (vec_double2)(b); - dd.d[0] = aa.d[0] * bb.d[0]; - dd.d[1] = aa.d[1] * bb.d[1]; - return ((qword)(dd.v)); -} - -/* Multiply High - */ -static __inline qword si_mpyh(qword a, qword b) -{ - vec_uint4 sixteen = (vec_uint4){16, 16, 16, 16}; - - return ((qword)(vec_sl(vec_mule((vec_short8)(a), (vec_short8)(vec_sl((vec_uint4)(b), sixteen))), sixteen))); -} - - -/* Multiply High High - */ -static __inline qword si_mpyhh(qword a, qword b) -{ - return ((qword)(vec_mule((vec_short8)(a), (vec_short8)(b)))); -} - -static __inline qword si_mpyhhu(qword a, qword b) -{ - return ((qword)(vec_mule((vec_ushort8)(a), (vec_ushort8)(b)))); -} - -/* Multiply Odd - */ -static __inline qword si_mpy(qword a, qword b) -{ - return ((qword)(vec_mulo((vec_short8)(a), (vec_short8)(b)))); -} - -static __inline qword si_mpyu(qword a, qword b) -{ - return ((qword)(vec_mulo((vec_ushort8)(a), (vec_ushort8)(b)))); -} - -static __inline qword si_mpyi(qword a, short b) -{ - return ((qword)(vec_mulo((vec_short8)(a), - vec_splat((vec_short8)(si_from_short(b)), 1)))); -} - -static __inline qword si_mpyui(qword a, unsigned short b) -{ - return ((qword)(vec_mulo((vec_ushort8)(a), - vec_splat((vec_ushort8)(si_from_ushort(b)), 1)))); -} - -/* Multiply and Shift Right - */ -static __inline qword si_mpys(qword a, qword b) -{ - return ((qword)(vec_sra(vec_mulo((vec_short8)(a), (vec_short8)(b)), ((vec_uint4){16,16,16,16})))); -} - -/* Nand - */ -static __inline qword si_nand(qword a, qword b) -{ - vec_uchar16 d; - - d = vec_and((vec_uchar16)(a), (vec_uchar16)(b)); - return ((qword)(vec_nor(d, d))); -} - -/* Negative Multiply Add - */ -static __inline qword si_dfnma(qword a, qword b, qword c) -{ - union { - vec_double2 v; - double d[2]; - } aa, bb, cc, dd; - - aa.v = (vec_double2)(a); - bb.v = (vec_double2)(b); - cc.v = (vec_double2)(c); - dd.d[0] = -cc.d[0] - aa.d[0] * bb.d[0]; - dd.d[1] = -cc.d[1] - aa.d[1] * bb.d[1]; - return ((qword)(dd.v)); -} - -/* Negative Multiply and Subtract - */ -static __inline qword si_fnms(qword a, qword b, qword c) -{ - return ((qword)(vec_nmsub((vec_float4)(a), (vec_float4)(b), (vec_float4)(c)))); -} - -static __inline qword si_dfnms(qword a, qword b, qword c) -{ - union { - vec_double2 v; - double d[2]; - } aa, bb, cc, dd; - - aa.v = (vec_double2)(a); - bb.v = (vec_double2)(b); - cc.v = (vec_double2)(c); - dd.d[0] = cc.d[0] - aa.d[0] * bb.d[0]; - dd.d[1] = cc.d[1] - aa.d[1] * bb.d[1]; - return ((qword)(dd.v)); -} - -/* Nor - */ -static __inline qword si_nor(qword a, qword b) -{ - return ((qword)(vec_nor((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -/* Or - */ -static __inline qword si_or(qword a, qword b) -{ - return ((qword)(vec_or((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -static __inline qword si_orbi(qword a, unsigned char b) -{ - return ((qword)(vec_or((vec_uchar16)(a), - vec_splat((vec_uchar16)(si_from_uchar(b)), 3)))); -} - -static __inline qword si_orhi(qword a, unsigned short b) -{ - return ((qword)(vec_or((vec_ushort8)(a), - vec_splat((vec_ushort8)(si_from_ushort(b)), 1)))); -} - -static __inline qword si_ori(qword a, unsigned int b) -{ - return ((qword)(vec_or((vec_uint4)(a), - vec_splat((vec_uint4)(si_from_uint(b)), 0)))); -} - -/* Or Complement - */ -static __inline qword si_orc(qword a, qword b) -{ - return ((qword)(vec_or((vec_uchar16)(a), vec_nor((vec_uchar16)(b), (vec_uchar16)(b))))); -} - - -/* Or Across - */ -static __inline qword si_orx(qword a) -{ - vec_uchar16 tmp; - tmp = (vec_uchar16)(a); - tmp = vec_or(tmp, vec_sld(tmp, tmp, 8)); - tmp = vec_or(tmp, vec_sld(tmp, tmp, 4)); - return ((qword)(vec_and(tmp, ((vec_uchar16){0xFF,0xFF,0xFF,0xFF, 0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00})))); -} - - -/* Estimates - */ -static __inline qword si_frest(qword a) -{ - return ((qword)(vec_re((vec_float4)(a)))); -} - -static __inline qword si_frsqest(qword a) -{ - return ((qword)(vec_rsqrte((vec_float4)(a)))); -} - -#define si_fi(_a, _d) (_d) - -/* Channel Read and Write - */ -#define si_rdch(_channel) ((qword)(vec_splat_u8(0))) /* not mappable */ -#define si_rchcnt(_channel) ((qword)(vec_splat_u8(0))) /* not mappable */ -#define si_wrch(_channel, _a) /* not mappable */ - -/* Rotate Left - */ -static __inline qword si_roth(qword a, qword b) -{ - return ((qword)(vec_rl((vec_ushort8)(a), (vec_ushort8)(b)))); -} - -static __inline qword si_rot(qword a, qword b) -{ - return ((qword)(vec_rl((vec_uint4)(a), (vec_uint4)(b)))); -} - -static __inline qword si_rothi(qword a, int b) -{ - return ((qword)(vec_rl((vec_ushort8)(a), - vec_splat((vec_ushort8)(si_from_int(b)), 1)))); -} - -static __inline qword si_roti(qword a, int b) -{ - return ((qword)(vec_rl((vec_uint4)(a), - vec_splat((vec_uint4)(si_from_int(b)), 0)))); -} - -/* Rotate Left with Mask - */ -static __inline qword si_rothm(qword a, qword b) -{ - vec_ushort8 neg_b; - vec_ushort8 mask; - - neg_b = (vec_ushort8)vec_sub(vec_splat_s16(0), (vec_short8)(b)); - mask = vec_sra(vec_sl(neg_b, vec_splat_u16(11)), vec_splat_u16(15)); - return ((qword)(vec_andc(vec_sr((vec_ushort8)(a), neg_b), mask))); -} - -static __inline qword si_rotm(qword a, qword b) -{ - vec_uint4 neg_b; - vec_uint4 mask; - - neg_b = (vec_uint4)vec_sub(vec_splat_s32(0), (vec_int4)(b)); - mask = vec_sra(vec_sl(neg_b, ((vec_uint4){26,26,26,26})), ((vec_uint4){31,31,31,31})); - return ((qword)(vec_andc(vec_sr((vec_uint4)(a), neg_b), mask))); -} - -static __inline qword si_rothmi(qword a, int b) -{ - vec_ushort8 neg_b; - vec_ushort8 mask; - - neg_b = vec_splat((vec_ushort8)(si_from_int(-b)), 1); - mask = vec_sra(vec_sl(neg_b, vec_splat_u16(11)), vec_splat_u16(15)); - return ((qword)(vec_andc(vec_sr((vec_ushort8)(a), neg_b), mask))); -} - -static __inline qword si_rotmi(qword a, int b) -{ - vec_uint4 neg_b; - vec_uint4 mask; - - neg_b = vec_splat((vec_uint4)(si_from_int(-b)), 0); - mask = vec_sra(vec_sl(neg_b, ((vec_uint4){26,26,26,26})), ((vec_uint4){31,31,31,31})); - return ((qword)(vec_andc(vec_sr((vec_uint4)(a), neg_b), mask))); -} - - -/* Rotate Left Algebraic with Mask - */ -static __inline qword si_rotmah(qword a, qword b) -{ - vec_ushort8 neg_b; - vec_ushort8 mask; - - neg_b = (vec_ushort8)vec_sub(vec_splat_s16(0), (vec_short8)(b)); - mask = vec_sra(vec_sl(neg_b, vec_splat_u16(11)), vec_splat_u16(15)); - return ((qword)(vec_sra((vec_short8)(a), (vec_ushort8)vec_or(neg_b, mask)))); -} - -static __inline qword si_rotma(qword a, qword b) -{ - vec_uint4 neg_b; - vec_uint4 mask; - - neg_b = (vec_uint4)vec_sub(vec_splat_s32(0), (vec_int4)(b)); - mask = vec_sra(vec_sl(neg_b, ((vec_uint4){26,26,26,26})), ((vec_uint4){31,31,31,31})); - return ((qword)(vec_sra((vec_int4)(a), (vec_uint4)vec_or(neg_b, mask)))); -} - - -static __inline qword si_rotmahi(qword a, int b) -{ - vec_ushort8 neg_b; - vec_ushort8 mask; - - neg_b = vec_splat((vec_ushort8)(si_from_int(-b)), 1); - mask = vec_sra(vec_sl(neg_b, vec_splat_u16(11)), vec_splat_u16(15)); - return ((qword)(vec_sra((vec_short8)(a), (vec_ushort8)vec_or(neg_b, mask)))); -} - -static __inline qword si_rotmai(qword a, int b) -{ - vec_uint4 neg_b; - vec_uint4 mask; - - neg_b = vec_splat((vec_uint4)(si_from_int(-b)), 0); - mask = vec_sra(vec_sl(neg_b, ((vec_uint4){26,26,26,26})), ((vec_uint4){31,31,31,31})); - return ((qword)(vec_sra((vec_int4)(a), (vec_uint4)vec_or(neg_b, mask)))); -} - - -/* Rotate Left Quadword by Bytes with Mask - */ -static __inline qword si_rotqmbyi(qword a, int count) -{ - union { - vec_uchar16 v; - int i[4]; - } x; - vec_uchar16 mask; - - count = 0 - count; - x.i[3] = count << 3; - mask = (count & 0x10) ? vec_splat_u8(0) : vec_splat_u8(-1); - - return ((qword)(vec_and(vec_sro((vec_uchar16)(a), x.v), mask))); -} - - -static __inline qword si_rotqmby(qword a, qword count) -{ - union { - vec_uchar16 v; - int i[4]; - } x; - int cnt; - vec_uchar16 mask; - - x.v = (vec_uchar16)(count); - x.i[0] = cnt = (0 - x.i[0]) << 3; - - x.v = vec_splat(x.v, 3); - mask = (cnt & 0x80) ? vec_splat_u8(0) : vec_splat_u8(-1); - - return ((qword)(vec_and(vec_sro((vec_uchar16)(a), x.v), mask))); -} - - -/* Rotate Left Quadword by Bytes - */ -static __inline qword si_rotqbyi(qword a, int count) -{ - union { - vec_uchar16 v; - int i[4]; - } left, right; - - count <<= 3; - left.i[3] = count; - right.i[3] = 0 - count; - return ((qword)(vec_or(vec_slo((vec_uchar16)(a), left.v), vec_sro((vec_uchar16)(a), right.v)))); -} - -static __inline qword si_rotqby(qword a, qword count) -{ - vec_uchar16 left, right; - - left = vec_sl(vec_splat((vec_uchar16)(count), 3), vec_splat_u8(3)); - right = vec_sub(vec_splat_u8(0), left); - return ((qword)(vec_or(vec_slo((vec_uchar16)(a), left), vec_sro((vec_uchar16)(a), right)))); -} - -/* Rotate Left Quadword by Bytes Bit Count - */ -static __inline qword si_rotqbybi(qword a, qword count) -{ - vec_uchar16 left, right; - - left = vec_splat((vec_uchar16)(count), 3); - right = vec_sub(vec_splat_u8(7), left); - return ((qword)(vec_or(vec_slo((vec_uchar16)(a), left), vec_sro((vec_uchar16)(a), right)))); -} - - -/* Rotate Left Quadword by Bytes Bit Count - */ -static __inline qword si_rotqbii(qword a, int count) -{ - vec_uchar16 x, y; - vec_uchar16 result; - - x = vec_splat((vec_uchar16)(si_from_int(count & 7)), 3); - y = (vec_uchar16)(vec_sr((vec_uint4)vec_sro((vec_uchar16)(a), ((vec_uchar16)((vec_uint4){0,0,0,120}))), - (vec_uint4)vec_sub(vec_splat_u8(8), x))); - result = vec_or(vec_sll((qword)(a), x), y); - return ((qword)(result)); -} - -static __inline qword si_rotqbi(qword a, qword count) -{ - vec_uchar16 x, y; - vec_uchar16 result; - - x = vec_and(vec_splat((vec_uchar16)(count), 3), vec_splat_u8(7)); - y = (vec_uchar16)(vec_sr((vec_uint4)vec_sro((vec_uchar16)(a), ((vec_uchar16)((vec_uint4){0,0,0,120}))), - (vec_uint4)vec_sub(vec_splat_u8(8), x))); - - result = vec_or(vec_sll((qword)(a), x), y); - return ((qword)(result)); -} - - -/* Rotate Left Quadword and Mask by Bits - */ -static __inline qword si_rotqmbii(qword a, int count) -{ - return ((qword)(vec_srl((vec_uchar16)(a), vec_splat((vec_uchar16)(si_from_int(0 - count)), 3)))); -} - -static __inline qword si_rotqmbi(qword a, qword count) -{ - return ((qword)(vec_srl((vec_uchar16)(a), vec_sub(vec_splat_u8(0), vec_splat((vec_uchar16)(count), 3))))); -} - - -/* Rotate Left Quadword and Mask by Bytes with Bit Count - */ -static __inline qword si_rotqmbybi(qword a, qword count) -{ - union { - vec_uchar16 v; - int i[4]; - } x; - int cnt; - vec_uchar16 mask; - - x.v = (vec_uchar16)(count); - x.i[0] = cnt = 0 - (x.i[0] & ~7); - x.v = vec_splat(x.v, 3); - mask = (cnt & 0x80) ? vec_splat_u8(0) : vec_splat_u8(-1); - - return ((qword)(vec_and(vec_sro((vec_uchar16)(a), x.v), mask))); -} - - - - -/* Round Double to Float - */ -static __inline qword si_frds(qword a) -{ - union { - vec_float4 v; - float f[4]; - } d; - union { - vec_double2 v; - double d[2]; - } in; - - in.v = (vec_double2)(a); - d.v = (vec_float4){0.0f}; - d.f[0] = (float)in.d[0]; - d.f[2] = (float)in.d[1]; - - return ((qword)(d.v)); -} - -/* Select Bits - */ -static __inline qword si_selb(qword a, qword b, qword c) -{ - return ((qword)(vec_sel((vec_uchar16)(a), (vec_uchar16)(b), (vec_uchar16)(c)))); -} - - -/* Shuffle Bytes - */ -static __inline qword si_shufb(qword a, qword b, qword pattern) -{ - vec_uchar16 pat; - - pat = vec_sel(((vec_uchar16){0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}), - vec_sr((vec_uchar16)(pattern), vec_splat_u8(3)), - vec_sra((vec_uchar16)(pattern), vec_splat_u8(7))); - return ((qword)(vec_perm(vec_perm(a, b, pattern), - ((vec_uchar16){0, 0, 0, 0, 0, 0, 0, 0, - 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80}), - pat))); -} - - -/* Shift Left - */ -static __inline qword si_shlh(qword a, qword b) -{ - vec_ushort8 mask; - - mask = (vec_ushort8)vec_sra(vec_sl((vec_ushort8)(b), vec_splat_u16(11)), vec_splat_u16(15)); - return ((qword)(vec_andc(vec_sl((vec_ushort8)(a), (vec_ushort8)(b)), mask))); -} - -static __inline qword si_shl(qword a, qword b) -{ - vec_uint4 mask; - - mask = (vec_uint4)vec_sra(vec_sl((vec_uint4)(b), ((vec_uint4){26,26,26,26})), ((vec_uint4){31,31,31,31})); - return ((qword)(vec_andc(vec_sl((vec_uint4)(a), (vec_uint4)(b)), mask))); -} - - -static __inline qword si_shlhi(qword a, unsigned int b) -{ - vec_ushort8 mask; - vec_ushort8 bv; - - bv = vec_splat((vec_ushort8)(si_from_int(b)), 1); - mask = (vec_ushort8)vec_sra(vec_sl(bv, vec_splat_u16(11)), vec_splat_u16(15)); - return ((qword)(vec_andc(vec_sl((vec_ushort8)(a), bv), mask))); -} - -static __inline qword si_shli(qword a, unsigned int b) -{ - vec_uint4 bv; - vec_uint4 mask; - - bv = vec_splat((vec_uint4)(si_from_uint(b)), 0); - mask = (vec_uint4)vec_sra(vec_sl(bv, ((vec_uint4){26,26,26,26})), ((vec_uint4){31,31,31,31})); - return ((qword)(vec_andc(vec_sl((vec_uint4)(a), bv), mask))); -} - - -/* Shift Left Quadword - */ -static __inline qword si_shlqbii(qword a, unsigned int count) -{ - vec_uchar16 x; - - x = vec_splat((vec_uchar16)(si_from_uint(count)), 3); - return ((qword)(vec_sll((vec_uchar16)(a), x))); -} - -static __inline qword si_shlqbi(qword a, qword count) -{ - vec_uchar16 x; - - x = vec_splat((vec_uchar16)(count), 3); - return ((qword)(vec_sll((vec_uchar16)(a), x))); -} - - -/* Shift Left Quadword by Bytes - */ -static __inline qword si_shlqbyi(qword a, unsigned int count) -{ - union { - vec_uchar16 v; - int i[4]; - } x; - vec_uchar16 mask; - - x.i[3] = count << 3; - mask = (count & 0x10) ? vec_splat_u8(0) : vec_splat_u8(-1); - return ((qword)(vec_and(vec_slo((vec_uchar16)(a), x.v), mask))); -} - -static __inline qword si_shlqby(qword a, qword count) -{ - union { - vec_uchar16 v; - unsigned int i[4]; - } x; - unsigned int cnt; - vec_uchar16 mask; - - x.v = vec_sl(vec_splat((vec_uchar16)(count), 3), vec_splat_u8(3)); - cnt = x.i[0]; - mask = (cnt & 0x80) ? vec_splat_u8(0) : vec_splat_u8(-1); - return ((qword)(vec_and(vec_slo((vec_uchar16)(a), x.v), mask))); -} - -/* Shift Left Quadword by Bytes with Bit Count - */ -static __inline qword si_shlqbybi(qword a, qword count) -{ - union { - vec_uchar16 v; - int i[4]; - } x; - unsigned int cnt; - vec_uchar16 mask; - - x.v = vec_splat((vec_uchar16)(count), 3); - cnt = x.i[0]; - mask = (cnt & 0x80) ? vec_splat_u8(0) : vec_splat_u8(-1); - return ((qword)(vec_and(vec_slo((vec_uchar16)(a), x.v), mask))); -} - - -/* Stop and Signal - */ -#define si_stop(_type) SPU_STOP_ACTION -#define si_stopd(a, b, c) SPU_STOP_ACTION - - -/* Subtract - */ -static __inline qword si_sfh(qword a, qword b) -{ - return ((qword)(vec_sub((vec_ushort8)(b), (vec_ushort8)(a)))); -} - -static __inline qword si_sf(qword a, qword b) -{ - return ((qword)(vec_sub((vec_uint4)(b), (vec_uint4)(a)))); -} - -static __inline qword si_fs(qword a, qword b) -{ - return ((qword)(vec_sub((vec_float4)(a), (vec_float4)(b)))); -} - -static __inline qword si_dfs(qword a, qword b) -{ - union { - vec_double2 v; - double d[2]; - } aa, bb, dd; - - aa.v = (vec_double2)(a); - bb.v = (vec_double2)(b); - dd.d[0] = aa.d[0] - bb.d[0]; - dd.d[1] = aa.d[1] - bb.d[1]; - return ((qword)(dd.v)); -} - -static __inline qword si_sfhi(qword a, short b) -{ - return ((qword)(vec_sub(vec_splat((vec_short8)(si_from_short(b)), 1), - (vec_short8)(a)))); -} - -static __inline qword si_sfi(qword a, int b) -{ - return ((qword)(vec_sub(vec_splat((vec_int4)(si_from_int(b)), 0), - (vec_int4)(a)))); -} - -/* Subtract word extended - */ -#define si_sfx(_a, _b, _c) ((qword)(vec_add(vec_add((vec_uint4)(_b), \ - vec_nor((vec_uint4)(_a), (vec_uint4)(_a))), \ - vec_and((vec_uint4)(_c), vec_splat_u32(1))))) - - -/* Sum Bytes into Shorts - */ -static __inline qword si_sumb(qword a, qword b) -{ - vec_uint4 zero = (vec_uint4){0}; - vec_ushort8 sum_a, sum_b; - - sum_a = (vec_ushort8)vec_sum4s((vec_uchar16)(a), zero); - sum_b = (vec_ushort8)vec_sum4s((vec_uchar16)(b), zero); - - return ((qword)(vec_perm(sum_a, sum_b, ((vec_uchar16){18, 19, 2, 3, 22, 23, 6, 7, - 26, 27, 10, 11, 30, 31, 14, 15})))); -} - -/* Exclusive OR - */ -static __inline qword si_xor(qword a, qword b) -{ - return ((qword)(vec_xor((vec_uchar16)(a), (vec_uchar16)(b)))); -} - -static __inline qword si_xorbi(qword a, unsigned char b) -{ - return ((qword)(vec_xor((vec_uchar16)(a), - vec_splat((vec_uchar16)(si_from_uchar(b)), 3)))); -} - -static __inline qword si_xorhi(qword a, unsigned short b) -{ - return ((qword)(vec_xor((vec_ushort8)(a), - vec_splat((vec_ushort8)(si_from_ushort(b)), 1)))); -} - -static __inline qword si_xori(qword a, unsigned int b) -{ - return ((qword)(vec_xor((vec_uint4)(a), - vec_splat((vec_uint4)(si_from_uint(b)), 0)))); -} - - -/* Generate Controls for Sub-Quadword Insertion - */ -static __inline qword si_cbd(qword a, int imm) -{ - union { - vec_uint4 v; - unsigned char c[16]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.c[(si_to_uint(a) + (unsigned int)(imm)) & 0xF] = 0x03; - return ((qword)(shmask.v)); -} - -static __inline qword si_cdd(qword a, int imm) -{ - union { - vec_uint4 v; - unsigned long long ll[2]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.ll[((si_to_uint(a) + (unsigned int)(imm)) >> 3) & 0x1] = 0x0001020304050607ULL; - return ((qword)(shmask.v)); -} - -static __inline qword si_chd(qword a, int imm) -{ - union { - vec_uint4 v; - unsigned short s[8]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.s[((si_to_uint(a) + (unsigned int)(imm)) >> 1) & 0x7] = 0x0203; - return ((qword)(shmask.v)); -} - -static __inline qword si_cwd(qword a, int imm) -{ - union { - vec_uint4 v; - unsigned int i[4]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.i[((si_to_uint(a) + (unsigned int)(imm)) >> 2) & 0x3] = 0x00010203; - return ((qword)(shmask.v)); -} - -static __inline qword si_cbx(qword a, qword b) -{ - union { - vec_uint4 v; - unsigned char c[16]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.c[si_to_uint((qword)(vec_add((vec_uint4)(a), (vec_uint4)(b)))) & 0xF] = 0x03; - return ((qword)(shmask.v)); -} - - -static __inline qword si_cdx(qword a, qword b) -{ - union { - vec_uint4 v; - unsigned long long ll[2]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.ll[(si_to_uint((qword)(vec_add((vec_uint4)(a), (vec_uint4)(b)))) >> 3) & 0x1] = 0x0001020304050607ULL; - return ((qword)(shmask.v)); -} - -static __inline qword si_chx(qword a, qword b) -{ - union { - vec_uint4 v; - unsigned short s[8]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.s[(si_to_uint((qword)(vec_add((vec_uint4)(a), (vec_uint4)(b)))) >> 1) & 0x7] = 0x0203; - return ((qword)(shmask.v)); -} - -static __inline qword si_cwx(qword a, qword b) -{ - union { - vec_uint4 v; - unsigned int i[4]; - } shmask; - - shmask.v = ((vec_uint4){0x10111213, 0x14151617, 0x18191A1B, 0x1C1D1E1F}); - shmask.i[(si_to_uint((qword)(vec_add((vec_uint4)(a), (vec_uint4)(b)))) >> 2) & 0x3] = 0x00010203; - return ((qword)(shmask.v)); -} - - -/* Constant Formation - */ -static __inline qword si_il(signed short imm) -{ - return ((qword)(vec_splat((vec_int4)(si_from_int((signed int)(imm))), 0))); -} - - -static __inline qword si_ila(unsigned int imm) -{ - return ((qword)(vec_splat((vec_uint4)(si_from_uint(imm)), 0))); -} - -static __inline qword si_ilh(signed short imm) -{ - return ((qword)(vec_splat((vec_short8)(si_from_short(imm)), 1))); -} - -static __inline qword si_ilhu(signed short imm) -{ - return ((qword)(vec_splat((vec_uint4)(si_from_uint((unsigned int)(imm) << 16)), 0))); -} - -static __inline qword si_iohl(qword a, unsigned short imm) -{ - return ((qword)(vec_or((vec_uint4)(a), vec_splat((vec_uint4)(si_from_uint((unsigned int)(imm))), 0)))); -} - -/* No Operation - */ -#define si_lnop() /* do nothing */ -#define si_nop() /* do nothing */ - - -/* Memory Load and Store - */ -static __inline qword si_lqa(unsigned int imm) -{ - return ((qword)(vec_ld(0, (vector unsigned char *)(imm)))); -} - -static __inline qword si_lqd(qword a, unsigned int imm) -{ - return ((qword)(vec_ld(si_to_uint(a) & ~0xF, (vector unsigned char *)(imm)))); -} - -static __inline qword si_lqr(unsigned int imm) -{ - return ((qword)(vec_ld(0, (vector unsigned char *)(imm)))); -} - -static __inline qword si_lqx(qword a, qword b) -{ - return ((qword)(vec_ld(si_to_uint((qword)(vec_add((vec_uint4)(a), (vec_uint4)(b)))), (vector unsigned char *)(0)))); -} - -static __inline void si_stqa(qword a, unsigned int imm) -{ - vec_st((vec_uchar16)(a), 0, (vector unsigned char *)(imm)); -} - -static __inline void si_stqd(qword a, qword b, unsigned int imm) -{ - vec_st((vec_uchar16)(a), si_to_uint(b) & ~0xF, (vector unsigned char *)(imm)); -} - -static __inline void si_stqr(qword a, unsigned int imm) -{ - vec_st((vec_uchar16)(a), 0, (vector unsigned char *)(imm)); -} - -static __inline void si_stqx(qword a, qword b, qword c) -{ - vec_st((vec_uchar16)(a), - si_to_uint((qword)(vec_add((vec_uint4)(b), (vec_uint4)(c)))), - (vector unsigned char *)(0)); -} - -#endif /* !__SPU__ */ -#endif /* !_SI2VMX_H_ */ - diff --git a/gcc-4.8.1/gcc/config/rs6000/singlefp.h b/gcc-4.8.1/gcc/config/rs6000/singlefp.h deleted file mode 100644 index a7f34f802..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/singlefp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Definitions for PowerPC single-precision floating point unit - such as Xilinx PowerPC 405/440 APU. - - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Contributed by Michael Eager (eager@eagercon.com) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - - -/* Undefine definitions from rs6000.h. */ -#undef TARGET_SINGLE_FLOAT -#undef TARGET_DOUBLE_FLOAT -#undef TARGET_SINGLE_FPU -#undef TARGET_SIMPLE_FPU -#undef UNITS_PER_FP_WORD - -/* FPU operations supported. - If TARGET_SINGLE_FPU set, processor supports single fp options. */ -#define TARGET_SINGLE_FLOAT (rs6000_single_float) -#define TARGET_DOUBLE_FLOAT (rs6000_double_float) -#define TARGET_SINGLE_FPU 1 -#define TARGET_SIMPLE_FPU (rs6000_simple_fpu) - -/* FP word width depends on single/double fp support. */ -#define UNITS_PER_FP_WORD ((TARGET_SOFT_FLOAT || TARGET_DOUBLE_FLOAT) ? 8 : 4) - diff --git a/gcc-4.8.1/gcc/config/rs6000/spe.h b/gcc-4.8.1/gcc/config/rs6000/spe.h deleted file mode 100644 index adde83092..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/spe.h +++ /dev/null @@ -1,1107 +0,0 @@ -/* PowerPC E500 user include file. - Copyright (C) 2002-2013 Free Software Foundation, Inc. - Contributed by Aldy Hernandez (aldyh@redhat.com). - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _SPE_H -#define _SPE_H - -#define __vector __attribute__((vector_size(8))) - -typedef int int32_t; -typedef unsigned uint32_t; -typedef short int16_t; -typedef unsigned short uint16_t; -typedef long long int64_t; -typedef unsigned long long uint64_t; - -typedef short __vector __ev64_s16__; -typedef unsigned short __vector __ev64_u16__; -typedef int __vector __ev64_s32__; -typedef unsigned __vector __ev64_u32__; -typedef long long __vector __ev64_s64__; -typedef unsigned long long __vector __ev64_u64__; -typedef float __vector __ev64_fs__; - -#define __v2si __ev64_opaque__ -#define __v2sf __ev64_fs__ - -#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 __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 __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 __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 __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 __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 __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 __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 __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 __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 __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 __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 __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 __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 -#define __ev_subfsmfaaw __ev_subfsmiaaw -#define __ev_subfssfaaw __ev_subfssiaaw - -/* Floating Point SIMD Instructions */ - -#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: */ - -#define __ev_mwhusfaaw __ev_mwhusiaaw -#define __ev_mwhumfaaw __ev_mwhumiaaw -#define __ev_mwhusfanw __ev_mwhusianw -#define __ev_mwhumfanw __ev_mwhumianw -#define __ev_mwhgumfaa __ev_mwhgumiaa -#define __ev_mwhgumfan __ev_mwhgumian - -#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) -{ - __ev64_opaque__ t; - - t = __ev_mwhssf (a, b); - return __ev_addssiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhssiaaw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmi (a, b); - return __ev_addssiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhsmfaaw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmf (a, b); - return __ev_addsmiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhsmiaaw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmi (a, b); - return __ev_addsmiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhusiaaw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhumi (a, b); - return __ev_addusiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhumiaaw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhumi (a, b); - return __ev_addumiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhssfanw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhssf (a, b); - return __ev_subfssiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhssianw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmi (a, b); - return __ev_subfssiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhsmfanw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmf (a, b); - return __ev_subfsmiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhsmianw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmi (a, b); - return __ev_subfsmiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhusianw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhumi (a, b); - return __ev_subfusiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhumianw (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhumi (a, b); - return __ev_subfumiaaw (t); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgssfaa (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhssf (a, b); - return __ev_mwsmiaa (t, ((__ev64_s32__){1, 1})); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgsmfaa (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmf (a, b); - return __ev_mwsmiaa (t, ((__ev64_s32__){1, 1})); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgsmiaa (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmi (a, b); - return __ev_mwsmiaa (t, ((__ev64_s32__){1, 1})); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgumiaa (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhumi (a, b); - return __ev_mwumiaa (t, ((__ev64_s32__){1, 1})); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgssfan (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhssf (a, b); - return __ev_mwsmian (t, ((__ev64_s32__){1, 1})); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgsmfan (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmf (a, b); - return __ev_mwsmian (t, ((__ev64_s32__){1, 1})); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgsmian (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhsmi (a, b); - return __ev_mwsmian (t, ((__ev64_s32__){1, 1})); -} - -static inline __ev64_opaque__ -__internal_ev_mwhgumian (__ev64_opaque__ a, __ev64_opaque__ b) -{ - __ev64_opaque__ t; - - t = __ev_mwhumi (a, b); - return __ev_mwumian (t, ((__ev64_s32__){1, 1})); -} - -/* END OF NOT SUPPORTED */ - -/* __ev_create* functions. */ - -#define __ev_create_ufix32_u32 __ev_create_u32 -#define __ev_create_sfix32_s32 __ev_create_s32 - -static inline __ev64_opaque__ -__ev_create_s16 (int16_t a, int16_t b, int16_t c, int16_t d) -{ - union - { - __ev64_opaque__ v; - int16_t i[4]; - } u; - - u.i[0] = a; - u.i[1] = b; - u.i[2] = c; - u.i[3] = d; - - return u.v; -} - -static inline __ev64_opaque__ -__ev_create_u16 (uint16_t a, uint16_t b, uint16_t c, uint16_t d) - -{ - union - { - __ev64_opaque__ v; - uint16_t i[4]; - } u; - - u.i[0] = a; - u.i[1] = b; - u.i[2] = c; - u.i[3] = d; - - return u.v; -} - -static inline __ev64_opaque__ -__ev_create_s32 (int32_t a, int32_t b) -{ - union - { - __ev64_opaque__ v; - int32_t i[2]; - } u; - - u.i[0] = a; - u.i[1] = b; - - return u.v; -} - -static inline __ev64_opaque__ -__ev_create_u32 (uint32_t a, uint32_t b) -{ - union - { - __ev64_opaque__ v; - uint32_t i[2]; - } u; - - u.i[0] = a; - u.i[1] = b; - - return u.v; -} - -static inline __ev64_opaque__ -__ev_create_fs (float a, float b) -{ - union - { - __ev64_opaque__ v; - float f[2]; - } u; - - u.f[0] = a; - u.f[1] = b; - - return u.v; -} - -static inline __ev64_opaque__ -__ev_create_sfix32_fs (float a, float b) -{ - __ev64_opaque__ ev; - - ev = (__ev64_opaque__) __ev_create_fs (a, b); - return (__ev64_opaque__) __builtin_spe_evfsctsf ((__v2sf) ev); -} - -static inline __ev64_opaque__ -__ev_create_ufix32_fs (float a, float b) -{ - __ev64_opaque__ ev; - - ev = (__ev64_opaque__) __ev_create_fs (a, b); - return (__ev64_opaque__) __builtin_spe_evfsctuf ((__v2sf) ev); -} - -static inline __ev64_opaque__ -__ev_create_s64 (int64_t a) -{ - union - { - __ev64_opaque__ v; - int64_t i; - } u; - - u.i = a; - return u.v; -} - -static inline __ev64_opaque__ -__ev_create_u64 (uint64_t a) -{ - union - { - __ev64_opaque__ v; - uint64_t i; - } u; - - u.i = a; - return u.v; -} - -static inline uint64_t -__ev_convert_u64 (__ev64_opaque__ a) -{ - return (uint64_t) a; -} - -static inline int64_t -__ev_convert_s64 (__ev64_opaque__ a) -{ - return (int64_t) a; -} - -/* __ev_get_* functions. */ - -#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) -{ - union - { - __ev64_opaque__ v; - uint32_t i[2]; - } u; - - u.v = a; - return u.i[pos]; -} - -static inline int32_t -__ev_get_s32_internal (__ev64_opaque__ a, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - int32_t i[2]; - } u; - - u.v = a; - return u.i[pos]; -} - -static inline float -__ev_get_fs_internal (__ev64_opaque__ a, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - float f[2]; - } u; - - u.v = a; - return u.f[pos]; -} - -static inline float -__ev_get_sfix32_fs_internal (__ev64_opaque__ a, uint32_t pos) -{ - __ev64_fs__ v; - - v = __builtin_spe_evfscfsf ((__v2sf) a); - return __ev_get_fs_internal ((__ev64_opaque__) v, pos); -} - -static inline float -__ev_get_ufix32_fs_internal (__ev64_opaque__ a, uint32_t pos) -{ - __ev64_fs__ v; - - v = __builtin_spe_evfscfuf ((__v2sf) a); - return __ev_get_fs_internal ((__ev64_opaque__) v, pos); -} - -static inline uint16_t -__ev_get_u16_internal (__ev64_opaque__ a, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - uint16_t i[4]; - } u; - - u.v = a; - return u.i[pos]; -} - -static inline int16_t -__ev_get_s16_internal (__ev64_opaque__ a, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - int16_t i[4]; - } u; - - u.v = a; - return u.i[pos]; -} - -/* __ev_set_* functions. */ - -#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 __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) -#define __ev_set_upper_s32(a, b) __ev_set_s32 (a, b, 0) -#define __ev_set_lower_s32(a, b) __ev_set_s32 (a, b, 1) -#define __ev_set_upper_fs(a, b) __ev_set_fs (a, b, 0) -#define __ev_set_lower_fs(a, b) __ev_set_fs (a, b, 1) -#define __ev_set_upper_ufix32_u32 __ev_set_upper_u32 -#define __ev_set_lower_ufix32_u32 __ev_set_lower_u32 -#define __ev_set_upper_sfix32_s32 __ev_set_upper_s32 -#define __ev_set_lower_sfix32_s32 __ev_set_lower_s32 -#define __ev_set_upper_sfix32_fs(a, b) __ev_set_sfix32_fs (a, b, 0) -#define __ev_set_lower_sfix32_fs(a, b) __ev_set_sfix32_fs (a, b, 1) -#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 __builtin_spe_evmra - -static inline __ev64_opaque__ -__ev_set_acc_u64 (uint64_t a) -{ - __ev64_opaque__ ev32; - ev32 = __ev_create_u64 (a); - __ev_mra (ev32); - return ev32; -} - -static inline __ev64_opaque__ -__ev_set_acc_s64 (int64_t a) -{ - __ev64_opaque__ ev32; - ev32 = __ev_create_s64 (a); - __ev_mra (ev32); - return ev32; -} - -static inline __ev64_opaque__ -__ev_set_u32_internal (__ev64_opaque__ a, uint32_t b, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - uint32_t i[2]; - } u; - - u.v = a; - u.i[pos] = b; - return u.v; -} - -static inline __ev64_opaque__ -__ev_set_s32_internal (__ev64_opaque__ a, int32_t b, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - int32_t i[2]; - } u; - - u.v = a; - u.i[pos] = b; - return u.v; -} - -static inline __ev64_opaque__ -__ev_set_fs_internal (__ev64_opaque__ a, float b, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - float f[2]; - } u; - - u.v = a; - u.f[pos] = b; - return u.v; -} - -static inline __ev64_opaque__ -__ev_set_sfix32_fs_internal (__ev64_opaque__ a, float b, uint32_t pos) -{ - __ev64_opaque__ v; - float other; - - /* Get other half. */ - other = __ev_get_fs_internal (a, pos ^ 1); - - /* Make an sfix32 with 'b'. */ - v = __ev_create_sfix32_fs (b, b); - - /* Set other half to what it used to be. */ - return __ev_set_fs_internal (v, other, pos ^ 1); -} - -static inline __ev64_opaque__ -__ev_set_ufix32_fs_internal (__ev64_opaque__ a, float b, uint32_t pos) -{ - __ev64_opaque__ v; - float other; - - /* Get other half. */ - other = __ev_get_fs_internal (a, pos ^ 1); - - /* Make an ufix32 with 'b'. */ - v = __ev_create_ufix32_fs (b, b); - - /* Set other half to what it used to be. */ - return __ev_set_fs_internal (v, other, pos ^ 1); -} - -static inline __ev64_opaque__ -__ev_set_u16_internal (__ev64_opaque__ a, uint16_t b, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - uint16_t i[4]; - } u; - - u.v = a; - u.i[pos] = b; - return u.v; -} - -static inline __ev64_opaque__ -__ev_set_s16_internal (__ev64_opaque__ a, int16_t b, uint32_t pos) -{ - union - { - __ev64_opaque__ v; - int16_t i[4]; - } u; - - u.v = a; - u.i[pos] = b; - return u.v; -} - -/* Predicates. */ - -#define __pred_all 0 -#define __pred_any 1 -#define __pred_upper 2 -#define __pred_lower 3 - -#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 -#define __SPEFSCR_FGH 0x20000000 -#define __SPEFSCR_FXH 0x10000000 -#define __SPEFSCR_FINVH 0x08000000 -#define __SPEFSCR_FDBZH 0x04000000 -#define __SPEFSCR_FUNFH 0x02000000 -#define __SPEFSCR_FOVFH 0x01000000 -/* 2 unused bits. */ -#define __SPEFSCR_FINXS 0x00200000 -#define __SPEFSCR_FINVS 0x00100000 -#define __SPEFSCR_FDBZS 0x00080000 -#define __SPEFSCR_FUNFS 0x00040000 -#define __SPEFSCR_FOVFS 0x00020000 -#define __SPEFSCR_MODE 0x00010000 -#define __SPEFSCR_SOV 0x00008000 -#define __SPEFSCR_OV 0x00004000 -#define __SPEFSCR_FG 0x00002000 -#define __SPEFSCR_FX 0x00001000 -#define __SPEFSCR_FINV 0x00000800 -#define __SPEFSCR_FDBZ 0x00000400 -#define __SPEFSCR_FUNF 0x00000200 -#define __SPEFSCR_FOVF 0x00000100 -/* 1 unused bit. */ -#define __SPEFSCR_FINXE 0x00000040 -#define __SPEFSCR_FINVE 0x00000020 -#define __SPEFSCR_FDBZE 0x00000010 -#define __SPEFSCR_FUNFE 0x00000008 -#define __SPEFSCR_FOVFE 0x00000004 -#define __SPEFSCR_FRMC 0x00000003 - -#define __ev_get_spefscr_sovh() (__builtin_spe_mfspefscr () & __SPEFSCR_SOVH) -#define __ev_get_spefscr_ovh() (__builtin_spe_mfspefscr () & __SPEFSCR_OVH) -#define __ev_get_spefscr_fgh() (__builtin_spe_mfspefscr () & __SPEFSCR_FGH) -#define __ev_get_spefscr_fxh() (__builtin_spe_mfspefscr () & __SPEFSCR_FXH) -#define __ev_get_spefscr_finvh() (__builtin_spe_mfspefscr () & __SPEFSCR_FINVH) -#define __ev_get_spefscr_fdbzh() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZH) -#define __ev_get_spefscr_funfh() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNFH) -#define __ev_get_spefscr_fovfh() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVFH) -#define __ev_get_spefscr_finxs() (__builtin_spe_mfspefscr () & __SPEFSCR_FINXS) -#define __ev_get_spefscr_finvs() (__builtin_spe_mfspefscr () & __SPEFSCR_FINVS) -#define __ev_get_spefscr_fdbzs() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZS) -#define __ev_get_spefscr_funfs() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNFS) -#define __ev_get_spefscr_fovfs() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVFS) -#define __ev_get_spefscr_mode() (__builtin_spe_mfspefscr () & __SPEFSCR_MODE) -#define __ev_get_spefscr_sov() (__builtin_spe_mfspefscr () & __SPEFSCR_SOV) -#define __ev_get_spefscr_ov() (__builtin_spe_mfspefscr () & __SPEFSCR_OV) -#define __ev_get_spefscr_fg() (__builtin_spe_mfspefscr () & __SPEFSCR_FG) -#define __ev_get_spefscr_fx() (__builtin_spe_mfspefscr () & __SPEFSCR_FX) -#define __ev_get_spefscr_finv() (__builtin_spe_mfspefscr () & __SPEFSCR_FINV) -#define __ev_get_spefscr_fdbz() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZ) -#define __ev_get_spefscr_funf() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNF) -#define __ev_get_spefscr_fovf() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVF) -#define __ev_get_spefscr_finxe() (__builtin_spe_mfspefscr () & __SPEFSCR_FINXE) -#define __ev_get_spefscr_finve() (__builtin_spe_mfspefscr () & __SPEFSCR_FINVE) -#define __ev_get_spefscr_fdbze() (__builtin_spe_mfspefscr () & __SPEFSCR_FDBZE) -#define __ev_get_spefscr_funfe() (__builtin_spe_mfspefscr () & __SPEFSCR_FUNFE) -#define __ev_get_spefscr_fovfe() (__builtin_spe_mfspefscr () & __SPEFSCR_FOVFE) -#define __ev_get_spefscr_frmc() (__builtin_spe_mfspefscr () & __SPEFSCR_FRMC) - -static inline void -__ev_clr_spefscr_field (int mask) -{ - int i; - - i = __builtin_spe_mfspefscr (); - i &= ~mask; - __builtin_spe_mtspefscr (i); -} - -#define __ev_clr_spefscr_sovh() __ev_clr_spefscr_field (__SPEFSCR_SOVH) -#define __ev_clr_spefscr_sov() __ev_clr_spefscr_field (__SPEFSCR_SOV) -#define __ev_clr_spefscr_finxs() __ev_clr_spefscr_field (__SPEFSCR_FINXS) -#define __ev_clr_spefscr_finvs() __ev_clr_spefscr_field (__SPEFSCR_FINVS) -#define __ev_clr_spefscr_fdbzs() __ev_clr_spefscr_field (__SPEFSCR_FDBZS) -#define __ev_clr_spefscr_funfs() __ev_clr_spefscr_field (__SPEFSCR_FUNFS) -#define __ev_clr_spefscr_fovfs() __ev_clr_spefscr_field (__SPEFSCR_FOVFS) - -/* Set rounding mode: - rnd = 0 (nearest) - rnd = 1 (zero) - rnd = 2 (+inf) - rnd = 3 (-inf). */ - -static inline void -__ev_set_spefscr_frmc (int rnd) -{ - int i; - - i = __builtin_spe_mfspefscr (); - i &= ~__SPEFSCR_FRMC; - i |= rnd; - __builtin_spe_mtspefscr (i); -} - -/* The SPE PIM says these are declared in <spe.h>, although they are - not provided by GCC: they must be taken from a separate - library. */ -extern short int atosfix16 (const char *); -extern int atosfix32 (const char *); -extern long long atosfix64 (const char *); - -extern unsigned short atoufix16 (const char *); -extern unsigned int atoufix32 (const char *); -extern unsigned long long atoufix64 (const char *); - -extern short int strtosfix16 (const char *, char **); -extern int strtosfix32 (const char *, char **); -extern long long strtosfix64 (const char *, char **); - -extern unsigned short int strtoufix16 (const char *, char **); -extern unsigned int strtoufix32 (const char *, char **); -extern unsigned long long strtoufix64 (const char *, char **); - -#endif /* _SPE_H */ diff --git a/gcc-4.8.1/gcc/config/rs6000/spe.md b/gcc-4.8.1/gcc/config/rs6000/spe.md deleted file mode 100644 index cec2b430b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/spe.md +++ /dev/null @@ -1,3223 +0,0 @@ -;; e500 SPE description -;; Copyright (C) 2002-2013 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 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_constants - [(CMPDFEQ_GPR 1006) - (TSTDFEQ_GPR 1007) - (CMPDFGT_GPR 1008) - (TSTDFGT_GPR 1009) - (CMPDFLT_GPR 1010) - (TSTDFLT_GPR 1011) - (CMPTFEQ_GPR 1012) - (TSTTFEQ_GPR 1013) - (CMPTFGT_GPR 1014) - (TSTTFGT_GPR 1015) - (CMPTFLT_GPR 1016) - (TSTTFLT_GPR 1017) - (E500_CR_IOR_COMPARE 1018) - ]) - -;; Modes using a 64-bit register. -(define_mode_iterator SPE64 [DF V4HI V2SF V1DI V2SI]) - -;; Likewise, but allow TFmode (two registers) as well. -(define_mode_iterator SPE64TF [DF V4HI V2SF V1DI V2SI TF]) - -;; DImode and TImode. -(define_mode_iterator DITI [DI TI]) - -(define_insn "*negsf2_gpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (neg:SF (match_operand:SF 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "efsneg %0,%1" - [(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" "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") - (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%r") - (match_operand:SF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "efsadd %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "*subsf3_gpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (minus:SF (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "efssub %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "*mulsf3_gpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%r") - (match_operand:SF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "efsmul %0,%1,%2" - [(set_attr "type" "fp")]) - -(define_insn "*divsf3_gpr" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (div:SF (match_operand:SF 1 "gpc_reg_operand" "r") - (match_operand:SF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "efsdiv %0,%1,%2" - [(set_attr "type" "vecfdiv")]) - -;; Floating point conversion instructions. - -(define_insn "spe_fixuns_truncdfsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdctuiz %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "spe_extendsfdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdcfs %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "spe_fixuns_truncsfsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (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_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" - "efsctsiz %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "spe_fix_truncdfsi2" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdctsiz %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "spe_floatunssisf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "efscfui %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "spe_floatunssidf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdcfui %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "spe_floatsisf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "efscfsi %0,%1" - [(set_attr "type" "fp")]) - -(define_insn "spe_floatsidf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdcfsi %0,%1" - [(set_attr "type" "fp")]) - -;; SPE SIMD instructions - -(define_insn "absv2si2" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (abs:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")))] - "TARGET_SPE" - "evabs %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evandc" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (not:V2SI (match_operand:V2SI 2 "gpc_reg_operand" "r"))))] - "TARGET_SPE" - "evandc %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "andv2si3" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")))] - "TARGET_SPE" - "evand %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -;; Vector compare instructions - -(define_insn "spe_evcmpeq" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")] 500))] - "TARGET_SPE" - "evcmpeq %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evcmpgts" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")] 501))] - "TARGET_SPE" - "evcmpgts %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evcmpgtu" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")] 502))] - "TARGET_SPE" - "evcmpgtu %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evcmplts" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")] 503))] - "TARGET_SPE" - "evcmplts %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evcmpltu" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")] 504))] - "TARGET_SPE" - "evcmpltu %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -;; Floating point vector compare instructions - -(define_insn "spe_evfscmpeq" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r")] 538)) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evfscmpeq %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evfscmpgt" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r")] 539)) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evfscmpgt %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evfscmplt" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r")] 540)) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evfscmplt %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evfststeq" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r")] 541))] - "TARGET_SPE" - "evfststeq %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evfststgt" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r")] 542))] - "TARGET_SPE" - "evfststgt %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evfststlt" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r")] 543))] - "TARGET_SPE" - "evfststlt %0,%1,%2" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -;; End of vector compare instructions - -(define_insn "spe_evcntlsw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")] 505))] - "TARGET_SPE" - "evcntlsw %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evcntlzw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")] 506))] - "TARGET_SPE" - "evcntlzw %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_eveqv" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (not:V2SI (xor:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r"))))] - "TARGET_SPE" - "eveqv %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evextsb" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")] 507))] - "TARGET_SPE" - "evextsb %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evextsh" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")] 508))] - "TARGET_SPE" - "evextsh %0,%1" - [(set_attr "type" "vecsimple") - (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") - (match_operand:QI 2 "immediate_operand" "i")))) - (unspec [(const_int 0)] 509)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlhhesplat %0,%2*2(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlhhesplatx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 510)] - "TARGET_SPE" - "evlhhesplatx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlhhossplat" - [(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)] 511)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlhhossplat %0,%2*2(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlhhossplatx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 512)] - "TARGET_SPE" - "evlhhossplatx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlhhousplat" - [(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)] 513)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlhhousplat %0,%2*2(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlhhousplatx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 514)] - "TARGET_SPE" - "evlhhousplatx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhsplat" - [(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)] 515)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlwhsplat %0,%2*4(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhsplatx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 516)] - "TARGET_SPE" - "evlwhsplatx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwwsplat" - [(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)] 517)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlwwsplat %0,%2*4(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwwsplatx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 518)] - "TARGET_SPE" - "evlwwsplatx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evmergehi" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (vec_select:V2SI - (vec_concat:V4SI - (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (parallel [(const_int 0) (const_int 2)])))] - "TARGET_SPE" - "evmergehi %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evmergehilo" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (vec_select:V2SI - (vec_concat:V4SI - (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (parallel [(const_int 0) (const_int 3)])))] - "TARGET_SPE" - "evmergehilo %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evmergelo" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (vec_select:V2SI - (vec_concat:V4SI - (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (parallel [(const_int 1) (const_int 3)])))] - "TARGET_SPE" - "evmergelo %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evmergelohi" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (vec_select:V2SI - (vec_concat:V4SI - (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (parallel [(const_int 1) (const_int 2)])))] - "TARGET_SPE" - "evmergelohi %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_expand "vec_perm_constv2si" - [(match_operand:V2SI 0 "gpc_reg_operand" "") - (match_operand:V2SI 1 "gpc_reg_operand" "") - (match_operand:V2SI 2 "gpc_reg_operand" "") - (match_operand:V2SI 3 "" "")] - "TARGET_SPE" -{ - if (rs6000_expand_vec_perm_const (operands)) - DONE; - else - FAIL; -}) - -(define_insn "spe_evnand" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (not:V2SI (and:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r"))))] - "TARGET_SPE" - "evnand %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "negv2si2" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (neg:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")))] - "TARGET_SPE" - "evneg %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evnor" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (not:V2SI (ior:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r"))))] - "TARGET_SPE" - "evnor %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evorc" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (ior:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (not:V2SI (match_operand:V2SI 2 "gpc_reg_operand" "r"))))] - "TARGET_SPE" - "evorc %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evor" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (ior:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")))] - "TARGET_SPE" - "evor %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evrlwi" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 519))] - "TARGET_SPE" - "evrlwi %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evrlw" - [(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")] 520))] - "TARGET_SPE" - "evrlw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evrndw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")] 521))] - "TARGET_SPE" - "evrndw %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evsel" - [(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") - (match_operand:CC 3 "cc_reg_operand" "y")] 522))] - "TARGET_SPE" - "evsel %0,%1,%2,%3" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evsel_fs" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r") - (match_operand:CC 3 "cc_reg_operand" "y")] 725))] - "TARGET_SPE" - "evsel %0,%1,%2,%3" - [(set_attr "type" "veccmp") - (set_attr "length" "4")]) - -(define_insn "spe_evslwi" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] - 523))] - "TARGET_SPE" - "evslwi %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evslw" - [(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")] 524))] - "TARGET_SPE" - "evslw %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evsrwis" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] - 525))] - "TARGET_SPE" - "evsrwis %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evsrwiu" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] - 526))] - "TARGET_SPE" - "evsrwiu %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evsrws" - [(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")] 527))] - "TARGET_SPE" - "evsrws %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evsrwu" - [(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")] 528))] - "TARGET_SPE" - "evsrwu %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -;; 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")))] - "TARGET_SPE" - "evxor %0,%1,%2" - [(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" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evfsadd" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r"))) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evfsadd %0,%1,%2" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfscfsf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 529))] - "TARGET_SPE" - "evfscfsf %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfscfsi" - [(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") - (set_attr "length" "4")]) - -(define_insn "spe_evfscfuf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 530))] - "TARGET_SPE" - "evfscfuf %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfscfui" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (unspec:V2SF [(match_operand:V2SI 1 "gpc_reg_operand" "r")] 701))] - "TARGET_SPE" - "evfscfui %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsctsf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 531))] - "TARGET_SPE" - "evfsctsf %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsctsi" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 532))] - "TARGET_SPE" - "evfsctsi %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsctsiz" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 533))] - "TARGET_SPE" - "evfsctsiz %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsctuf" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 534))] - "TARGET_SPE" - "evfsctuf %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsctui" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 535))] - "TARGET_SPE" - "evfsctui %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsctuiz" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 536))] - "TARGET_SPE" - "evfsctuiz %0,%1" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsdiv" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r"))) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evfsdiv %0,%1,%2" - [(set_attr "type" "vecfdiv") - (set_attr "length" "4")]) - -(define_insn "spe_evfsmul" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r"))) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evfsmul %0,%1,%2" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -(define_insn "spe_evfsnabs" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 537))] - "TARGET_SPE" - "evfsnabs %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evfsneg" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r")))] - "TARGET_SPE" - "evfsneg %0,%1" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evfssub" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r") - (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r") - (match_operand:V2SF 2 "gpc_reg_operand" "r"))) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evfssub %0,%1,%2" - [(set_attr "type" "vecfloat") - (set_attr "length" "4")]) - -;; SPE SIMD load instructions. - -;; 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. - -(define_insn "spe_evldd" - [(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)] 544)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evldd %0,%2*8(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlddx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 545)] - "TARGET_SPE" - "evlddx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evldh" - [(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)] 546)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evldh %0,%2*8(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evldhx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 547)] - "TARGET_SPE" - "evldhx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evldw" - [(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)] 548)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evldw %0,%2*8(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evldwx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 549)] - "TARGET_SPE" - "evldwx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhe" - [(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)] 550)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlwhe %0,%2*4(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhex" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 551)] - "TARGET_SPE" - "evlwhex %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhos" - [(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)] 552)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlwhos %0,%2*4(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhosx" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 553)] - "TARGET_SPE" - "evlwhosx %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhou" - [(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)] 554)] - "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31" - "evlwhou %0,%2*4(%1)" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_evlwhoux" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") - (match_operand:SI 2 "gpc_reg_operand" "r")))) - (unspec [(const_int 0)] 555)] - "TARGET_SPE" - "evlwhoux %0,%1,%2" - [(set_attr "type" "vecload") - (set_attr "length" "4")]) - -(define_insn "spe_brinc" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] 556))] - "TARGET_SPE" - "brinc %0,%1,%2" - [(set_attr "type" "brinc") - (set_attr "length" "4")]) - -(define_insn "spe_evmhegsmfaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 557)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhegsmfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhegsmfan" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 558)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhegsmfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhegsmiaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 559)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhegsmiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhegsmian" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 560)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhegsmian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhegumiaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 561)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhegumiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhegumian" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 562)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhegumian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmfaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 563)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhesmfaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmfanw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 564)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhesmfanw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmfa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhesmfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmf" - [(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")] 566))] - "TARGET_SPE" - "evmhesmf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 567)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhesmiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 568)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhesmianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhesmia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhesmi" - [(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")] 570))] - "TARGET_SPE" - "evmhesmi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhessfaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 571)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhessfaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhessfanw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 572)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhessfanw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhessfa" - [(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")] 573)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhessfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhessf" - [(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")] 574)) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evmhessf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhessiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 575)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhessiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhessianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 576)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhessianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmheumiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 577)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmheumiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmheumianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 578)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmheumianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmheumia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmheumia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmheumi" - [(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")] 580))] - "TARGET_SPE" - "evmheumi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmheusiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 581)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmheusiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmheusianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 582)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmheusianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhogsmfaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 583)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhogsmfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhogsmfan" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 584)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhogsmfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhogsmiaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 585)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhogsmiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhogsmian" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 586)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhogsmian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhogumiaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 587)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhogumiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhogumian" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 588)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhogumian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmfaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 589)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhosmfaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmfanw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 590)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhosmfanw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmfa" - [(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")] 591))] - "TARGET_SPE" - "evmhosmfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmf" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhosmf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 593)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhosmiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 594)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhosmianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhosmia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhosmi" - [(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")] 596))] - "TARGET_SPE" - "evmhosmi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhossfaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 597)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhossfaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhossfanw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 598)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhossfanw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhossfa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 599)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhossfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhossf" - [(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")] 600)) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evmhossf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhossiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 601)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhossiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhossianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 602)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhossianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhoumiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 603)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhoumiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhoumianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 604)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhoumianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhoumia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhoumia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhoumi" - [(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")] 606))] - "TARGET_SPE" - "evmhoumi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhousiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 607)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhousiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmhousianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 608)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmhousianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmmlssfa" - [(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")] 609))] - "TARGET_SPE" - "evmmlssfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmmlssf" - [(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")] 610))] - "TARGET_SPE" - "evmmlssf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmfa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhsmfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmf" - [(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")] 612))] - "TARGET_SPE" - "evmwhsmf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhsmia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmi" - [(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")] 614))] - "TARGET_SPE" - "evmwhsmi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhssfa" - [(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")] 615)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhssfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhusian" - [(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")] 626))] - "TARGET_SPE" - "evmwhusian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhssf" - [(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")] 628)) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evmwhssf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhumia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhumia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhumi" - [(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")] 630))] - "TARGET_SPE" - "evmwhumi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlsmiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 635)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlsmiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlsmianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 636)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlsmianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlssiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 641)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlssiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlssianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 642)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlssianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlumiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 643)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlumiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlumianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 644)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlumianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlumia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlumia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlumi" - [(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")] 646))] - "TARGET_SPE" - "evmwlumi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlusiaaw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 647)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlusiaaw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwlusianw" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 648)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwlusianw %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmfaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 649)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwsmfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmfan" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 650)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwsmfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmfa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwsmfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmf" - [(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")] 652))] - "TARGET_SPE" - "evmwsmf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmiaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 653)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwsmiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmian" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 654)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwsmian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwsmia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwsmi" - [(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")] 656))] - "TARGET_SPE" - "evmwsmi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwssfaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 657)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwssfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwssfan" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 658)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwssfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwssfa" - [(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")] 659)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwssfa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwssf" - [(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")] 660)) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evmwssf %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwumiaa" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 661)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwumiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwumian" - [(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") - (reg:V2SI SPE_ACC_REGNO)] 662)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwumian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwumia" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwumia %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwumi" - [(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")] 664))] - "TARGET_SPE" - "evmwumi %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "addv2si3" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (plus:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")))] - "TARGET_SPE" - "evaddw %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evaddusiaaw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (reg:V2SI SPE_ACC_REGNO)] 673)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evaddusiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evaddumiaaw" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evaddumiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evaddssiaaw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (reg:V2SI SPE_ACC_REGNO)] 675)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evaddssiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evaddsmiaaw" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evaddsmiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evaddiw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 677))] - "TARGET_SPE" - "evaddiw %0,%1,%2" - [(set_attr "type" "vecsimple") - (set_attr "length" "4")]) - -(define_insn "spe_evsubifw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 678))] - "TARGET_SPE" - "evsubifw %0,%2,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "subv2si3" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (minus:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r")))] - "TARGET_SPE" - "evsubfw %0,%2,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evsubfusiaaw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (reg:V2SI SPE_ACC_REGNO)] 679)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evsubfusiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evsubfumiaaw" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evsubfumiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evsubfssiaaw" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r") - (reg:V2SI SPE_ACC_REGNO)] 681)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evsubfssiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evsubfsmiaaw" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evsubfsmiaaw %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmra" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (match_operand:V2SI 1 "gpc_reg_operand" "r")) - (set (reg:V2SI SPE_ACC_REGNO) - (unspec:V2SI [(match_dup 1)] 726))] - "TARGET_SPE" - "evmra %0,%1" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "divv2si3" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (div:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r"))) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evdivws %0,%1,%2" - [(set_attr "type" "vecdiv") - (set_attr "length" "4")]) - -(define_insn "spe_evdivwu" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (udiv:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r") - (match_operand:V2SI 2 "gpc_reg_operand" "r"))) - (clobber (reg:SI SPEFSCR_REGNO))] - "TARGET_SPE" - "evdivwu %0,%1,%2" - [(set_attr "type" "vecdiv") - (set_attr "length" "4")]) - -(define_insn "spe_evsplatfi" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:QI 1 "immediate_operand" "i")] 684))] - "TARGET_SPE" - "evsplatfi %0,%1" - [(set_attr "type" "vecperm") - (set_attr "length" "4")]) - -(define_insn "spe_evsplati" - [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r") - (unspec:V2SI [(match_operand:QI 1 "immediate_operand" "i")] 685))] - "TARGET_SPE" - "evsplati %0,%1" - [(set_attr "type" "vecperm") - (set_attr "length" "4")]) - -(define_insn "spe_evstdd" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:QI 1 "immediate_operand" "i"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 686)] - "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31" - "evstdd %2,%1*8(%0)" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstddx" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:SI 1 "gpc_reg_operand" "r"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 687)] - "TARGET_SPE" - "evstddx %2,%0,%1" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstdh" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:QI 1 "immediate_operand" "i"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 688)] - "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31" - "evstdh %2,%1*8(%0)" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstdhx" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:SI 1 "gpc_reg_operand" "r"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 689)] - "TARGET_SPE" - "evstdhx %2,%0,%1" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstdw" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:QI 1 "immediate_operand" "i"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 690)] - "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31" - "evstdw %2,%1*8(%0)" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstdwx" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:SI 1 "gpc_reg_operand" "r"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 691)] - "TARGET_SPE" - "evstdwx %2,%0,%1" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwhe" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:QI 1 "immediate_operand" "i"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 692)] - "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31" - "evstwhe %2,%1*4(%0)" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwhex" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:SI 1 "gpc_reg_operand" "r"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 693)] - "TARGET_SPE" - "evstwhex %2,%0,%1" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwho" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:QI 1 "immediate_operand" "i"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 694)] - "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31" - "evstwho %2,%1*4(%0)" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwhox" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:SI 1 "gpc_reg_operand" "r"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 695)] - "TARGET_SPE" - "evstwhox %2,%0,%1" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwwe" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:QI 1 "immediate_operand" "i"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 696)] - "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31" - "evstwwe %2,%1*4(%0)" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwwex" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:SI 1 "gpc_reg_operand" "r"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 697)] - "TARGET_SPE" - "evstwwex %2,%0,%1" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwwo" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:QI 1 "immediate_operand" "i"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 698)] - "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31" - "evstwwo %2,%1*4(%0)" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -(define_insn "spe_evstwwox" - [(set (mem:V2SI (plus:SI (match_operand:SI 0 "gpc_reg_operand" "b") - (match_operand:SI 1 "gpc_reg_operand" "r"))) - (match_operand:V2SI 2 "gpc_reg_operand" "r")) - (unspec [(const_int 0)] 699)] - "TARGET_SPE" - "evstwwox %2,%0,%1" - [(set_attr "type" "vecstore") - (set_attr "length" "4")]) - -;; Double-precision floating point instructions. - -;; FIXME: Add o=r option. -(define_insn "*frob_<SPE64:mode>_<DITI:mode>" - [(set (match_operand:SPE64 0 "nonimmediate_operand" "=r,r") - (subreg:SPE64 (match_operand:DITI 1 "input_operand" "r,m") 0))] - "(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode) - || (TARGET_SPE && <SPE64:MODE>mode != DFmode)" - "@ - evmergelo %0,%1,%L1 - evldd%X1 %0,%y1") - -(define_insn "*frob_tf_ti" - [(set (match_operand:TF 0 "gpc_reg_operand" "=r") - (subreg:TF (match_operand:TI 1 "gpc_reg_operand" "r") 0))] - "TARGET_E500_DOUBLE" - "evmergelo %0,%1,%L1\;evmergelo %L0,%Y1,%Z1" - [(set_attr "length" "8")]) - -(define_insn "*frob_<mode>_di_2" - [(set (subreg:DI (match_operand:SPE64TF 0 "nonimmediate_operand" "+&r,r") 0) - (match_operand:DI 1 "input_operand" "r,m"))] - "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" - "@ - evmergelo %0,%1,%L1 - evldd%X1 %0,%y1") - -(define_insn "*frob_tf_di_8_2" - [(set (subreg:DI (match_operand:TF 0 "nonimmediate_operand" "+&r,r") 8) - (match_operand:DI 1 "input_operand" "r,m"))] - "TARGET_E500_DOUBLE" - "@ - evmergelo %L0,%1,%L1 - evldd%X1 %L0,%y1") - -(define_insn "*frob_di_<mode>" - [(set (match_operand:DI 0 "nonimmediate_operand" "=&r") - (subreg:DI (match_operand:SPE64TF 1 "input_operand" "r") 0))] - "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" - "evmergehi %0,%1,%1\;mr %L0,%1" - [(set_attr "length" "8")]) - -(define_insn "*frob_ti_tf" - [(set (match_operand:TI 0 "nonimmediate_operand" "=&r") - (subreg:TI (match_operand:TF 1 "input_operand" "r") 0))] - "TARGET_E500_DOUBLE" - "evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1" - [(set_attr "length" "16")]) - -(define_insn "*frob_<DITI:mode>_<SPE64:mode>_2" - [(set (subreg:SPE64 (match_operand:DITI 0 "register_operand" "+&r,r") 0) - (match_operand:SPE64 1 "input_operand" "r,m"))] - "(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode) - || (TARGET_SPE && <SPE64:MODE>mode != DFmode)" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - return \"evmergehi %0,%1,%1\;mr %L0,%1\"; - case 1: - /* If the address is not offsettable we need to load the whole - doubleword into a 64-bit register and then copy the high word - to form the correct output layout. */ - if (!offsettable_nonstrict_memref_p (operands[1])) - return \"evldd%X1 %L0,%y1\;evmergehi %0,%L0,%L0\"; - /* 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 \"lwz %L0,%L1\;lwz %0,%1\"; - else - return \"lwz%U1%X1 %0,%1\;lwz %L0,%L1\"; - } -}" - [(set_attr "length" "8,8")]) - -; As the above, but TImode at offset 8. -(define_insn "*frob_ti_<mode>_8_2" - [(set (subreg:SPE64 (match_operand:TI 0 "register_operand" "+&r,r") 8) - (match_operand:SPE64 1 "input_operand" "r,m"))] - "(TARGET_E500_DOUBLE && <MODE>mode == DFmode) - || (TARGET_SPE && <MODE>mode != DFmode)" - "* -{ - switch (which_alternative) - { - default: - gcc_unreachable (); - case 0: - return \"evmergehi %Y0,%1,%1\;mr %Z0,%1\"; - case 1: - if (!offsettable_nonstrict_memref_p (operands[1])) - return \"evldd%X1 %Z0,%y1\;evmergehi %Y0,%Z0,%Z0\"; - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands[1], 0)) - return \"lwz %Z0,%L1\;lwz %Y0,%1\"; - else - return \"lwz%U1%X1 %Y0,%1\;lwz %Z0,%L1\"; - } -}" - [(set_attr "length" "8,8")]) - -(define_insn "*frob_ti_tf_2" - [(set (subreg:TF (match_operand:TI 0 "gpc_reg_operand" "=&r") 0) - (match_operand:TF 1 "input_operand" "r"))] - "TARGET_E500_DOUBLE" - "evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1" - [(set_attr "length" "16")]) - -(define_insn "mov_si<mode>_e500_subreg0" - [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,&r") 0) - (match_operand:SI 1 "input_operand" "r,m"))] - "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" - "@ - evmergelo %0,%1,%0 - evmergelohi %0,%0,%0\;lwz%U1%X1 %0,%1\;evmergelohi %0,%0,%0" - [(set_attr "length" "4,12")]) - -(define_insn_and_split "*mov_si<mode>_e500_subreg0_elf_low" - [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 0) - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand 2 "" "")))] - "((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)) - && TARGET_ELF && !TARGET_64BIT && can_create_pseudo_p ()" - "#" - "&& 1" - [(pc)] -{ - rtx tmp = gen_reg_rtx (SImode); - emit_insn (gen_elf_low (tmp, operands[1], operands[2])); - emit_insn (gen_mov_si<mode>_e500_subreg0 (operands[0], tmp)); - DONE; -} - [(set_attr "length" "8")]) - -;; ??? Could use evstwwe for memory stores in some cases, depending on -;; the offset. -(define_insn "*mov_si<mode>_e500_subreg0_2" - [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") - (subreg:SI (match_operand:SPE64TF 1 "register_operand" "+r,&r") 0))] - "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" - "@ - evmergehi %0,%0,%1 - evmergelohi %1,%1,%1\;stw%U0%X0 %1,%0" - [(set_attr "length" "4,8")]) - -(define_insn "*mov_si<mode>_e500_subreg4" - [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,r") 4) - (match_operand:SI 1 "input_operand" "r,m"))] - "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" - "@ - mr %0,%1 - lwz%U1%X1 %0,%1") - -(define_insn "*mov_si<mode>_e500_subreg4_elf_low" - [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 4) - (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand 2 "" "")))] - "((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)) - && TARGET_ELF && !TARGET_64BIT" - "addic %0,%1,%K2") - -(define_insn "*mov_si<mode>_e500_subreg4_2" - [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") - (subreg:SI (match_operand:SPE64TF 1 "register_operand" "r,r") 4))] - "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode)) - || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)" - "@ - mr %0,%1 - stw%U0%X0 %1,%0") - -(define_insn "*mov_sitf_e500_subreg8" - [(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,&r") 8) - (match_operand:SI 1 "input_operand" "r,m"))] - "TARGET_E500_DOUBLE" - "@ - evmergelo %L0,%1,%L0 - evmergelohi %L0,%L0,%L0\;lwz%U1%X1 %L0,%1\;evmergelohi %L0,%L0,%L0" - [(set_attr "length" "4,12")]) - -(define_insn "*mov_sitf_e500_subreg8_2" - [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") - (subreg:SI (match_operand:TF 1 "register_operand" "+r,&r") 8))] - "TARGET_E500_DOUBLE" - "@ - evmergehi %0,%0,%L1 - evmergelohi %L1,%L1,%L1\;stw%U0%X0 %L1,%0" - [(set_attr "length" "4,8")]) - -(define_insn "*mov_sitf_e500_subreg12" - [(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,r") 12) - (match_operand:SI 1 "input_operand" "r,m"))] - "TARGET_E500_DOUBLE" - "@ - mr %L0,%1 - lwz%U1%X1 %L0,%1") - -(define_insn "*mov_sitf_e500_subreg12_2" - [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m") - (subreg:SI (match_operand:TF 1 "register_operand" "r,r") 12))] - "TARGET_E500_DOUBLE" - "@ - mr %0,%L1 - stw%U0%X0 %L1,%0") - -;; FIXME: Allow r=CONST0. -(define_insn "*movdf_e500_double" - [(set (match_operand:DF 0 "rs6000_nonimmediate_operand" "=r,r,m") - (match_operand:DF 1 "input_operand" "r,m,r"))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE - && (gpc_reg_operand (operands[0], DFmode) - || gpc_reg_operand (operands[1], DFmode))" - "* - { - switch (which_alternative) - { - case 0: - return \"evor %0,%1,%1\"; - case 1: - return \"evldd%X1 %0,%y1\"; - case 2: - return \"evstdd%X0 %1,%y0\"; - default: - gcc_unreachable (); - } - }" - [(set_attr "type" "*,vecload,vecstore") - (set_attr "length" "*,*,*")]) - -(define_insn "spe_truncdfsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efscfd %0,%1") - -(define_insn "spe_absdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (abs:DF (match_operand:DF 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdabs %0,%1") - -(define_insn "spe_nabsdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "r"))))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdnabs %0,%1") - -(define_insn "spe_negdf2" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (neg:DF (match_operand:DF 1 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdneg %0,%1") - -(define_insn "spe_adddf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (plus:DF (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdadd %0,%1,%2") - -(define_insn "spe_subdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (minus:DF (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdsub %0,%1,%2") - -(define_insn "spe_muldf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efdmul %0,%1,%2") - -(define_insn "spe_divdf3" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r") - (div:DF (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r")))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" - "efddiv %0,%1,%2") - -;; Double-precision floating point instructions for IBM long double. - -(define_insn_and_split "spe_trunctfdf2_internal1" - [(set (match_operand:DF 0 "gpc_reg_operand" "=r,?r") - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,r")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" - "@ - # - evor %0,%1,%1" - "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" - [(const_int 0)] -{ - emit_note (NOTE_INSN_DELETED); - DONE; -}) - -(define_insn_and_split "spe_trunctfsf2" - [(set (match_operand:SF 0 "gpc_reg_operand" "=r") - (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "r"))) - (clobber (match_scratch:DF 2 "=r"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" - "#" - "&& reload_completed" - [(set (match_dup 2) - (float_truncate:DF (match_dup 1))) - (set (match_dup 0) - (float_truncate:SF (match_dup 2)))] - "") - -(define_insn "spe_extenddftf2" - [(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=r,?r,r,o") - (float_extend:TF (match_operand:DF 1 "input_operand" "0,r,m,r"))) - (clobber (match_scratch:DF 2 "=X,X,X,&r"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" - "@ - evxor %L0,%L0,%L0 - evor %0,%1,%1\;evxor %L0,%L0,%L0 - evldd%X1 %0,%y1\;evxor %L0,%L0,%L0 - evstdd%X0 %1,%y0\;evxor %2,%2,%2\;evstdd %2,%Y0" - [(set_attr "length" "4,8,8,12")]) - -(define_expand "spe_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))])] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" -{ - operands[2] = gen_reg_rtx (DFmode); - operands[3] = gen_reg_rtx (SImode); - operands[4] = gen_reg_rtx (SImode); -}) - -; Like fix_trunc_helper, add with rounding towards 0. -(define_insn "spe_fix_trunctfsi2_internal" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (fix:SI (match_operand:TF 1 "gpc_reg_operand" "r"))) - (clobber (match_operand:DF 2 "gpc_reg_operand" "=r")) - (clobber (match_operand:SI 3 "gpc_reg_operand" "=&r")) - (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" - "mfspefscr %3\;rlwinm %4,%3,0,0,29\;ori %4,%4,1\;efdadd %2,%1,%L1\;mtspefscr %3\;efdctsiz %0, %2" - [(set_attr "length" "24")]) - -(define_insn "spe_negtf2_internal" - [(set (match_operand:TF 0 "gpc_reg_operand" "=r") - (neg:TF (match_operand:TF 1 "gpc_reg_operand" "r")))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" - "* -{ - if (REGNO (operands[0]) == REGNO (operands[1]) + 1) - return \"efdneg %L0,%L1\;efdneg %0,%1\"; - else - return \"efdneg %0,%1\;efdneg %L0,%L1\"; -}" - [(set_attr "length" "8")]) - -(define_expand "spe_abstf2_cmp" - [(set (match_operand:TF 0 "gpc_reg_operand" "=f") - (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) (unspec:CCFP [(compare:CCFP (match_dup 3) - (match_dup 5))] CMPDFEQ_GPR)) - (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)))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" - " -{ - 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); -}") - -(define_expand "spe_abstf2_tst" - [(set (match_operand:TF 0 "gpc_reg_operand" "=f") - (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) (unspec:CCFP [(compare:CCFP (match_dup 3) - (match_dup 5))] TSTDFEQ_GPR)) - (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)))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" - " -{ - 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); -}") - -;; Vector move instructions. - -(define_expand "movv2si" - [(set (match_operand:V2SI 0 "nonimmediate_operand" "") - (match_operand:V2SI 1 "any_operand" ""))] - "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,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: gcc_unreachable (); - } -}" - [(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" "") - (match_operand:V1DI 1 "any_operand" ""))] - "TARGET_SPE" - "{ rs6000_emit_move (operands[0], operands[1], V1DImode); DONE; }") - -(define_insn "*movv1di_internal" - [(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 - evxor %0,%0,%0" - [(set_attr "type" "vecload,vecstore,*,*") - (set_attr "length" "*,*,*,*")]) - -(define_expand "movv4hi" - [(set (match_operand:V4HI 0 "nonimmediate_operand" "") - (match_operand:V4HI 1 "any_operand" ""))] - "TARGET_SPE" - "{ rs6000_emit_move (operands[0], operands[1], V4HImode); DONE; }") - -(define_insn "*movv4hi_internal" - [(set (match_operand:V4HI 0 "nonimmediate_operand" "=m,r,r,r") - (match_operand:V4HI 1 "input_operand" "r,m,r,W"))] - "TARGET_SPE - && (gpc_reg_operand (operands[0], V4HImode) - || gpc_reg_operand (operands[1], V4HImode))" - "@ - evstdd%X0 %1,%y0 - evldd%X1 %0,%y1 - evor %0,%1,%1 - evxor %0,%0,%0" - [(set_attr "type" "vecload")]) - -(define_expand "movv2sf" - [(set (match_operand:V2SF 0 "nonimmediate_operand" "") - (match_operand:V2SF 1 "any_operand" ""))] - "TARGET_SPE || TARGET_PAIRED_FLOAT" - "{ rs6000_emit_move (operands[0], operands[1], V2SFmode); DONE; }") - -(define_insn "*movv2sf_internal" - [(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 - 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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhssfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhssmaa" - [(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")] 703)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhssmaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmfaa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhsmfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmiaa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhsmiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhusiaa" - [(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")] 706)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhusiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhumiaa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhumiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhssfan" - [(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")] 708)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhssfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhssian" - [(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")] 709)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhssian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmfan" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhsmfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhsmian" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhsmian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhumian" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhumian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgssfaa" - [(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")] 714)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgssfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgsmfaa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgsmfaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgsmiaa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgsmiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgumiaa" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgumiaa %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgssfan" - [(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")] 718)) - (clobber (reg:SI SPEFSCR_REGNO)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgssfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgsmfan" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgsmfan %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgsmian" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgsmian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_evmwhgumian" - [(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)) - (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))] - "TARGET_SPE" - "evmwhgumian %0,%1,%2" - [(set_attr "type" "veccomplex") - (set_attr "length" "4")]) - -(define_insn "spe_mtspefscr" - [(set (reg:SI SPEFSCR_REGNO) - (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] - 722))] - "TARGET_SPE" - "mtspefscr %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "spe_mfspefscr" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec_volatile:SI [(reg:SI SPEFSCR_REGNO)] 723))] - "TARGET_SPE" - "mfspefscr %0" - [(set_attr "type" "vecsimple")]) - -;; 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") - (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_finite_math_only && !flag_trapping_math)" - "efscmpeq %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "tstsfeq_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (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_finite_math_only && !flag_trapping_math" - "efststeq %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -(define_insn "cmpsfgt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (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_finite_math_only && !flag_trapping_math)" - "efscmpgt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "tstsfgt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (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_finite_math_only && !flag_trapping_math" - "efststgt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -(define_insn "cmpsflt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (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_finite_math_only && !flag_trapping_math)" - "efscmplt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "tstsflt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (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_finite_math_only && !flag_trapping_math" - "efststlt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -;; Same thing, but for double-precision. - -(define_insn "cmpdfeq_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - CMPDFEQ_GPR))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE - && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpeq %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "tstdfeq_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - TSTDFEQ_GPR))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE - && flag_finite_math_only && !flag_trapping_math" - "efdtsteq %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -(define_insn "cmpdfgt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - CMPDFGT_GPR))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE - && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpgt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "tstdfgt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - TSTDFGT_GPR))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE - && flag_finite_math_only && !flag_trapping_math" - "efdtstgt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -(define_insn "cmpdflt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - CMPDFLT_GPR))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE - && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmplt %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "tstdflt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "r") - (match_operand:DF 2 "gpc_reg_operand" "r"))] - TSTDFLT_GPR))] - "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE - && flag_finite_math_only && !flag_trapping_math" - "efdtstlt %0,%1,%2" - [(set_attr "type" "veccmpsimple")]) - -;; Same thing, but for IBM long double. - -(define_insn "cmptfeq_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r") - (match_operand:TF 2 "gpc_reg_operand" "r"))] - CMPTFEQ_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 - && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpeq %0,%L1,%L2" - [(set_attr "type" "veccmp") - (set_attr "length" "12")]) - -(define_insn "tsttfeq_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r") - (match_operand:TF 2 "gpc_reg_operand" "r"))] - TSTTFEQ_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 - && flag_finite_math_only && !flag_trapping_math" - "efdtsteq %0,%1,%2\;bng %0,$+8\;efdtsteq %0,%L1,%L2" - [(set_attr "type" "veccmpsimple") - (set_attr "length" "12")]) - -(define_insn "cmptfgt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r") - (match_operand:TF 2 "gpc_reg_operand" "r"))] - CMPTFGT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 - && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmpgt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpgt %0,%L1,%L2" - [(set_attr "type" "veccmp") - (set_attr "length" "20")]) - -(define_insn "tsttfgt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r") - (match_operand:TF 2 "gpc_reg_operand" "r"))] - TSTTFGT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 - && flag_finite_math_only && !flag_trapping_math" - "efdtstgt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstgt %0,%L1,%L2" - [(set_attr "type" "veccmpsimple") - (set_attr "length" "20")]) - -(define_insn "cmptflt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r") - (match_operand:TF 2 "gpc_reg_operand" "r"))] - CMPTFLT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 - && !(flag_finite_math_only && !flag_trapping_math)" - "efdcmplt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmplt %0,%L1,%L2" - [(set_attr "type" "veccmp") - (set_attr "length" "20")]) - -(define_insn "tsttflt_gpr" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP - [(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r") - (match_operand:TF 2 "gpc_reg_operand" "r"))] - TSTTFLT_GPR))] - "!TARGET_IEEEQUAD - && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128 - && flag_finite_math_only && !flag_trapping_math" - "efdtstlt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstlt %0,%L1,%L2" - [(set_attr "type" "veccmpsimple") - (set_attr "length" "20")]) - -;; Like cceq_ior_compare, but compare the GT bits. -(define_insn "e500_cr_ior_compare" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") - (unspec:CCFP [(match_operand 1 "cc_reg_operand" "y") - (match_operand 2 "cc_reg_operand" "y")] - E500_CR_IOR_COMPARE))] - "TARGET_HARD_FLOAT && !TARGET_FPRS" - "cror 4*%0+gt,4*%1+gt,4*%2+gt" - [(set_attr "type" "cr_logical")]) - -;; Out-of-line prologues and epilogues. -(define_insn "*save_gpregs_spe" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:V2SI 2 "memory_operand" "=m") - (match_operand:V2SI 3 "gpc_reg_operand" "r"))])] - "TARGET_SPE_ABI" - "bl %z1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*restore_gpregs_spe" - [(match_parallel 0 "any_parallel_operand" - [(clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:V2SI 2 "gpc_reg_operand" "=r") - (match_operand:V2SI 3 "memory_operand" "m"))])] - "TARGET_SPE_ABI" - "bl %z1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) - -(define_insn "*return_and_restore_gpregs_spe" - [(match_parallel 0 "any_parallel_operand" - [(return) - (clobber (reg:P 65)) - (use (match_operand:P 1 "symbol_ref_operand" "s")) - (use (reg:P 11)) - (set (match_operand:V2SI 2 "gpc_reg_operand" "=r") - (match_operand:V2SI 3 "memory_operand" "m"))])] - "TARGET_SPE_ABI" - "b %z1" - [(set_attr "type" "branch") - (set_attr "length" "4")]) diff --git a/gcc-4.8.1/gcc/config/rs6000/spu2vmx.h b/gcc-4.8.1/gcc/config/rs6000/spu2vmx.h deleted file mode 100644 index 04733e921..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/spu2vmx.h +++ /dev/null @@ -1,2415 +0,0 @@ -/* Cell SPU 2 VMX intrinsics header - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _SPU2VMX_H_ -#define _SPU2VMX_H_ 1 - -#ifdef __cplusplus - -#ifndef __SPU__ - -#include <si2vmx.h> - -/* spu_absd (absolute difference) - * ======== - */ -static __inline vec_uchar16 spu_absd(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_absdb((qword)(a), (qword)(b)))); - -} - - -/* spu_add - * ======= - */ -static __inline vec_uint4 spu_add(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_a((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_add(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_a((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_add(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_ah((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_add(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_ah((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_add(vec_uint4 a, unsigned int b) -{ - return ((vec_uint4)(si_ai((qword)(a), (int)(b)))); -} - -static __inline vec_int4 spu_add(vec_int4 a, int b) -{ - return ((vec_int4)(si_ai((qword)(a), b))); -} - -static __inline vec_ushort8 spu_add(vec_ushort8 a, unsigned short b) -{ - return ((vec_ushort8)(si_ahi((qword)(a), (short)(b)))); -} - -static __inline vec_short8 spu_add(vec_short8 a, short b) -{ - return ((vec_short8)(si_ahi((qword)(a), b))); -} - -static __inline vec_float4 spu_add(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_fa((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_add(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_dfa((qword)(a), (qword)(b)))); -} - - -/* spu_addx - * ======== - */ -static __inline vec_uint4 spu_addx(vec_uint4 a, vec_uint4 b, vec_uint4 c) -{ - return ((vec_uint4)(si_addx((qword)(a), (qword)(b), (qword)(c)))); -} - -static __inline vec_int4 spu_addx(vec_int4 a, vec_int4 b, vec_int4 c) -{ - return ((vec_int4)(si_addx((qword)(a), (qword)(b), (qword)(c)))); -} - - -/* spu_and - * ======= - */ -static __inline vec_uchar16 spu_and(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_char16 spu_and(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_and(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_and(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_and(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_and(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_float4 spu_and(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_ullong2 spu_and(vec_ullong2 a, vec_ullong2 b) -{ - return ((vec_ullong2)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_llong2 spu_and(vec_llong2 a, vec_llong2 b) -{ - return ((vec_llong2)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_and(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_and((qword)(a), (qword)(b)))); -} - -static __inline vec_uchar16 spu_and(vec_uchar16 a, unsigned char b) -{ - return ((vec_uchar16)(si_andbi((qword)(a), (signed char)(b)))); -} - - -static __inline vec_char16 spu_and(vec_char16 a, signed char b) -{ - return ((vec_char16)(si_andbi((qword)(a), b))); -} - -static __inline vec_ushort8 spu_and(vec_ushort8 a, unsigned short b) -{ - return ((vec_ushort8)(si_andhi((qword)(a), (signed short)(b)))); -} - -static __inline vec_short8 spu_and(vec_short8 a, signed short b) -{ - return ((vec_short8)(si_andhi((qword)(a), b))); -} - -static __inline vec_uint4 spu_and(vec_uint4 a, unsigned int b) -{ - return ((vec_uint4)(si_andi((qword)(a), (signed int)(b)))); -} - -static __inline vec_int4 spu_and(vec_int4 a, signed int b) -{ - return ((vec_int4)(si_andi((qword)(a), b))); -} - - -/* spu_andc - * ======== - */ -#define spu_andc(_a, _b) vec_andc(_a, _b) - - -/* spu_avg - * ======= - */ -#define spu_avg(_a, _b) vec_avg(_a, _b) - - -/* spu_bisled - * spu_bisled_d - * spu_bisled_e - * ============ - */ -#define spu_bisled(_func) /* not mappable */ -#define spu_bisled_d(_func) /* not mappable */ -#define spu_bisled_e(_func) /* not mappable */ - -/* spu_cmpabseq - * ============ - */ -static __inline vec_uint4 spu_cmpabseq(vec_float4 a, vec_float4 b) -{ - return ((vec_uint4)(si_fcmeq((qword)(a), (qword)(b)))); - -} - -static __inline vec_ullong2 spu_cmpabseq(vec_double2 a, vec_double2 b) -{ - return ((vec_ullong2)(si_dfcmeq((qword)(a), (qword)(b)))); -} - - -/* spu_cmpabsgt - * ============ - */ -static __inline vec_uint4 spu_cmpabsgt(vec_float4 a, vec_float4 b) -{ - return ((vec_uint4)(si_fcmgt((qword)(a), (qword)(b)))); -} - -static __inline vec_ullong2 spu_cmpabsgt(vec_double2 a, vec_double2 b) -{ - return ((vec_ullong2)(si_dfcmgt((qword)(a), (qword)(b)))); -} - - -/* spu_cmpeq - * ======== - */ -static __inline vec_uchar16 spu_cmpeq(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_ceqb((qword)(a), (qword)(b)))); -} - -static __inline vec_uchar16 spu_cmpeq(vec_char16 a, vec_char16 b) -{ - return ((vec_uchar16)(si_ceqb((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_cmpeq(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_ceqh((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_cmpeq(vec_short8 a, vec_short8 b) -{ - return ((vec_ushort8)(si_ceqh((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_cmpeq(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_ceq((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_cmpeq(vec_int4 a, vec_int4 b) -{ - return ((vec_uint4)(si_ceq((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_cmpeq(vec_float4 a, vec_float4 b) -{ - return ((vec_uint4)(si_fceq((qword)(a), (qword)(b)))); -} - -static __inline vec_uchar16 spu_cmpeq(vec_uchar16 a, unsigned char b) -{ - return ((vec_uchar16)(si_ceqbi((qword)(a), (signed char)(b)))); -} - -static __inline vec_uchar16 spu_cmpeq(vec_char16 a, signed char b) -{ - return ((vec_uchar16)(si_ceqbi((qword)(a), b))); -} - -static __inline vec_ushort8 spu_cmpeq(vec_ushort8 a, unsigned short b) -{ - return ((vec_ushort8)(si_ceqhi((qword)(a), (signed short)(b)))); -} - -static __inline vec_ushort8 spu_cmpeq(vec_short8 a, signed short b) -{ - return ((vec_ushort8)(si_ceqhi((qword)(a), b))); -} - -static __inline vec_uint4 spu_cmpeq(vec_uint4 a, unsigned int b) -{ - return ((vec_uint4)(si_ceqi((qword)(a), (signed int)(b)))); -} - -static __inline vec_uint4 spu_cmpeq(vec_int4 a, signed int b) -{ - return ((vec_uint4)(si_ceqi((qword)(a), b))); -} - -static __inline vec_ullong2 spu_cmpeq(vec_double2 a, vec_double2 b) -{ - return ((vec_ullong2)(si_dfceq((qword)(a), (qword)(b)))); -} - - -/* spu_cmpgt - * ======== - */ -static __inline vec_uchar16 spu_cmpgt(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_clgtb((qword)(a), (qword)(b)))); -} - -static __inline vec_uchar16 spu_cmpgt(vec_char16 a, vec_char16 b) -{ - return ((vec_uchar16)(si_cgtb((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_cmpgt(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_clgth((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_cmpgt(vec_short8 a, vec_short8 b) -{ - return ((vec_ushort8)(si_cgth((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_cmpgt(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_clgt((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_cmpgt(vec_int4 a, vec_int4 b) -{ - return ((vec_uint4)(si_cgt((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_cmpgt(vec_float4 a, vec_float4 b) -{ - return ((vec_uint4)(si_fcgt((qword)(a), (qword)(b)))); -} - -static __inline vec_uchar16 spu_cmpgt(vec_uchar16 a, unsigned char b) -{ - return ((vec_uchar16)(si_clgtbi((qword)(a), b))); -} - -static __inline vec_uchar16 spu_cmpgt(vec_char16 a, signed char b) -{ - return ((vec_uchar16)(si_cgtbi((qword)(a), b))); -} - -static __inline vec_ushort8 spu_cmpgt(vec_ushort8 a, unsigned short b) -{ - return ((vec_ushort8)(si_clgthi((qword)(a), b))); -} - -static __inline vec_ushort8 spu_cmpgt(vec_short8 a, signed short b) -{ - return ((vec_ushort8)(si_cgthi((qword)(a), b))); -} - -static __inline vec_uint4 spu_cmpgt(vec_uint4 a, unsigned int b) -{ - return ((vec_uint4)(si_clgti((qword)(a), b))); -} - -static __inline vec_uint4 spu_cmpgt(vec_int4 a, signed int b) -{ - return ((vec_uint4)(si_cgti((qword)(a), b))); -} - -static __inline vec_ullong2 spu_cmpgt(vec_double2 a, vec_double2 b) -{ - return ((vec_ullong2)(si_dfcgt((qword)(a), (qword)(b)))); -} - - -/* spu_cntb - * ======== - */ -static __inline vec_uchar16 spu_cntb(vec_uchar16 a) -{ - return ((vec_uchar16)(si_cntb((qword)(a)))); -} - - -static __inline vec_uchar16 spu_cntb(vec_char16 a) -{ - return ((vec_uchar16)(si_cntb((qword)(a)))); -} - -/* spu_cntlz - * ========= - */ -static __inline vec_uint4 spu_cntlz(vec_uint4 a) -{ - return ((vec_uint4)(si_clz((qword)(a)))); -} - -static __inline vec_uint4 spu_cntlz(vec_int4 a) -{ - return ((vec_uint4)(si_clz((qword)(a)))); -} - -static __inline vec_uint4 spu_cntlz(vec_float4 a) -{ - return ((vec_uint4)(si_clz((qword)(a)))); -} - -/* spu_testsv - * ========== - */ -static __inline vec_ullong2 spu_testsv(vec_double2 a, char b) -{ - return ((vec_ullong2)(si_dftsv((qword)(a), b))); -} - -/* spu_convtf - * ========== - */ -#define spu_convtf(_a, _b) (vec_ctf(_a, _b)) - -/* spu_convts - * ========== - */ -#define spu_convts(_a, _b) (vec_cts(_a, _b)) - -/* spu_convtu - * ========== - */ -#define spu_convtu(_a, _b) (vec_ctu(_a, _b)) - - -/* spu_dsync - * ======== - */ -#define spu_dsync() - -/* spu_eqv - * ======= - */ -static __inline vec_uchar16 spu_eqv(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_char16 spu_eqv(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_eqv(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_eqv(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_eqv(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_eqv(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_float4 spu_eqv(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_ullong2 spu_eqv(vec_ullong2 a, vec_ullong2 b) -{ - return ((vec_ullong2)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_llong2 spu_eqv(vec_llong2 a, vec_llong2 b) -{ - return ((vec_llong2)(si_eqv((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_eqv(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_eqv((qword)(a), (qword)(b)))); -} - -/* spu_extend - * ======== - */ -static __inline vec_short8 spu_extend(vec_char16 a) -{ - return ((vec_short8)(si_xsbh((qword)(a)))); -} - - -static __inline vec_int4 spu_extend(vec_short8 a) -{ - return ((vec_int4)(si_xshw((qword)(a)))); -} - -static __inline vec_llong2 spu_extend(vec_int4 a) -{ - return ((vec_llong2)(si_xswd((qword)(a)))); -} - - -static __inline vec_double2 spu_extend(vec_float4 a) -{ - return ((vec_double2)(si_fesd((qword)(a)))); -} - - -/* spu_extract - * ======== - */ -static __inline unsigned char spu_extract(vec_uchar16 a, int element) -{ - union { - vec_uchar16 v; - unsigned char c[16]; - } in; - - in.v = a; - return (in.c[element & 15]); -} - -static __inline signed char spu_extract(vec_char16 a, int element) -{ - union { - vec_char16 v; - signed char c[16]; - } in; - - in.v = a; - return (in.c[element & 15]); -} - -static __inline unsigned short spu_extract(vec_ushort8 a, int element) -{ - union { - vec_ushort8 v; - unsigned short s[8]; - } in; - - in.v = a; - return (in.s[element & 7]); -} - -static __inline signed short spu_extract(vec_short8 a, int element) -{ - union { - vec_short8 v; - signed short s[8]; - } in; - - in.v = a; - return (in.s[element & 7]); -} - -static __inline unsigned int spu_extract(vec_uint4 a, int element) -{ - union { - vec_uint4 v; - unsigned int i[4]; - } in; - - in.v = a; - return (in.i[element & 3]); -} - -static __inline signed int spu_extract(vec_int4 a, int element) -{ - union { - vec_int4 v; - signed int i[4]; - } in; - - in.v = a; - return (in.i[element & 3]); -} - -static __inline float spu_extract(vec_float4 a, int element) -{ - union { - vec_float4 v; - float f[4]; - } in; - - in.v = a; - return (in.f[element & 3]); -} - -static __inline unsigned long long spu_extract(vec_ullong2 a, int element) -{ - union { - vec_ullong2 v; - unsigned long long l[2]; - } in; - - in.v = a; - return (in.l[element & 1]); -} - -static __inline signed long long spu_extract(vec_llong2 a, int element) -{ - union { - vec_llong2 v; - signed long long l[2]; - } in; - - in.v = a; - return (in.l[element & 1]); -} - -static __inline double spu_extract(vec_double2 a, int element) -{ - union { - vec_double2 v; - double d[2]; - } in; - - in.v = a; - return (in.d[element & 1]); -} - -/* spu_gather - * ======== - */ -static __inline vec_uint4 spu_gather(vec_uchar16 a) -{ - return ((vec_uint4)(si_gbb((qword)(a)))); -} - - -static __inline vec_uint4 spu_gather(vec_char16 a) -{ - return ((vec_uint4)(si_gbb((qword)(a)))); -} - -static __inline vec_uint4 spu_gather(vec_ushort8 a) -{ - return ((vec_uint4)(si_gbh((qword)(a)))); -} - -static __inline vec_uint4 spu_gather(vec_short8 a) -{ - return ((vec_uint4)(si_gbh((qword)(a)))); -} - - -static __inline vec_uint4 spu_gather(vec_uint4 a) -{ - return ((vec_uint4)(si_gb((qword)(a)))); -} - -static __inline vec_uint4 spu_gather(vec_int4 a) -{ - return ((vec_uint4)(si_gb((qword)(a)))); -} - -static __inline vec_uint4 spu_gather(vec_float4 a) -{ - return ((vec_uint4)(si_gb((qword)(a)))); -} - -/* spu_genb - * ======== - */ -static __inline vec_uint4 spu_genb(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_bg((qword)(b), (qword)(a)))); -} - -static __inline vec_int4 spu_genb(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_bg((qword)(b), (qword)(a)))); -} - -/* spu_genbx - * ========= - */ -static __inline vec_uint4 spu_genbx(vec_uint4 a, vec_uint4 b, vec_uint4 c) -{ - return ((vec_uint4)(si_bgx((qword)(b), (qword)(a), (qword)(c)))); -} - -static __inline vec_int4 spu_genbx(vec_int4 a, vec_int4 b, vec_int4 c) -{ - return ((vec_int4)(si_bgx((qword)(b), (qword)(a), (qword)(c)))); -} - - -/* spu_genc - * ======== - */ -static __inline vec_uint4 spu_genc(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_cg((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_genc(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_cg((qword)(a), (qword)(b)))); -} - -/* spu_gencx - * ========= - */ -static __inline vec_uint4 spu_gencx(vec_uint4 a, vec_uint4 b, vec_uint4 c) -{ - return ((vec_uint4)(si_cgx((qword)(a), (qword)(b), (qword)(c)))); -} - -static __inline vec_int4 spu_gencx(vec_int4 a, vec_int4 b, vec_int4 c) -{ - return ((vec_int4)(si_cgx((qword)(a), (qword)(b), (qword)(c)))); -} - - -/* spu_hcmpeq - * ======== - */ -#define spu_hcmpeq(_a, _b) if (_a == _b) { SPU_HALT_ACTION; }; - - -/* spu_hcmpgt - * ======== - */ -#define spu_hcmpgt(_a, _b) if (_a > _b) { SPU_HALT_ACTION; }; - - -/* spu_idisable - * ============ - */ -#define spu_idisable() SPU_UNSUPPORTED_ACTION - - -/* spu_ienable - * =========== - */ -#define spu_ienable() SPU_UNSUPPORTED_ACTION - - -/* spu_insert - * ======== - */ -static __inline vec_uchar16 spu_insert(unsigned char a, vec_uchar16 b, int element) -{ - union { - vec_uchar16 v; - unsigned char c[16]; - } in; - - in.v = b; - in.c[element & 15] = a; - return (in.v); -} - -static __inline vec_char16 spu_insert(signed char a, vec_char16 b, int element) -{ - return ((vec_char16)spu_insert((unsigned char)(a), (vec_uchar16)(b), element)); -} - -static __inline vec_ushort8 spu_insert(unsigned short a, vec_ushort8 b, int element) -{ - union { - vec_ushort8 v; - unsigned short s[8]; - } in; - - in.v = b; - in.s[element & 7] = a; - return (in.v); -} - -static __inline vec_short8 spu_insert(signed short a, vec_short8 b, int element) -{ - return ((vec_short8)spu_insert((unsigned short)(a), (vec_ushort8)(b), element)); -} - -static __inline vec_uint4 spu_insert(unsigned int a, vec_uint4 b, int element) -{ - union { - vec_uint4 v; - unsigned int i[4]; - } in; - - in.v = b; - in.i[element & 3] = a; - return (in.v); -} - -static __inline vec_int4 spu_insert(signed int a, vec_int4 b, int element) -{ - return ((vec_int4)spu_insert((unsigned int)(a), (vec_uint4)(b), element)); -} - -static __inline vec_float4 spu_insert(float a, vec_float4 b, int element) -{ - union { - vec_float4 v; - float f[4]; - } in; - - in.v = b; - in.f[element & 3] = a; - return (in.v); -} - -static __inline vec_ullong2 spu_insert(unsigned long long a, vec_ullong2 b, int element) -{ - union { - vec_ullong2 v; - unsigned long long l[2]; - } in; - - in.v = b; - in.l[element & 1] = a; - return (in.v); -} - -static __inline vec_llong2 spu_insert(signed long long a, vec_llong2 b, int element) -{ - return ((vec_llong2)spu_insert((unsigned long long)(a), (vec_ullong2)(b), element)); -} - -static __inline vec_double2 spu_insert(double a, vec_double2 b, int element) -{ - union { - vec_double2 v; - double d[2]; - } in; - - in.v = b; - in.d[element & 1] = a; - return (in.v); -} - - -/* spu_madd - * ======== - */ -static __inline vec_int4 spu_madd(vec_short8 a, vec_short8 b, vec_int4 c) -{ - return ((vec_int4)(si_mpya((qword)(a), (qword)(b), (qword)(c)))); -} - -static __inline vec_float4 spu_madd(vec_float4 a, vec_float4 b, vec_float4 c) -{ - return ((vec_float4)(si_fma((qword)(a), (qword)(b), (qword)(c)))); -} - -static __inline vec_double2 spu_madd(vec_double2 a, vec_double2 b, vec_double2 c) -{ - return ((vec_double2)(si_dfma((qword)(a), (qword)(b), (qword)(c)))); -} - - -/* spu_maskb - * ======== - */ -#define spu_maskb(_a) (vec_uchar16)(si_fsmb(si_from_int((int)(_a)))) - -/* spu_maskh - * ======== - */ -#define spu_maskh(_a) (vec_ushort8)(si_fsmh(si_from_int((int)(_a)))) - - -/* spu_maskw - * ======== - */ -#define spu_maskw(_a) (vec_uint4)(si_fsm(si_from_int((int)(_a)))) - - -/* spu_mfcdma32 - * ======== - */ -#define spu_mfcdma32(_ls, _ea, _size, _tagid, _cmd) - - -/* spu_mfcdma64 - * ======== - */ -#define spu_mfcdma64(_ls, _eahi, _ealow, _size, _tagid, _cmd) - -/* spu_mfcstat - * ======== - */ -#define spu_mfcstat(_type) 0xFFFFFFFF - - - -/* spu_mffpscr - * =========== - */ -#define spu_mffpscr() (vec_uint4)(si_fscrrd()) - - -/* spu_mfspr - * ======== - */ - -#define spu_mfspr(_reg) si_to_uint(si_mfspr(_reg)) - - - -/* spu_mhhadd - * ========== - */ -static __inline vec_int4 spu_mhhadd(vec_short8 a, vec_short8 b, vec_int4 c) -{ - return ((vec_int4)(si_mpyhha((qword)(a), (qword)(b), (qword)(c)))); -} - - -static __inline vec_uint4 spu_mhhadd(vec_ushort8 a, vec_ushort8 b, vec_uint4 c) -{ - return ((vec_uint4)(si_mpyhhau((qword)(a), (qword)(b), (qword)(c)))); -} - - -/* spu_msub - * ======== - */ -static __inline vec_float4 spu_msub(vec_float4 a, vec_float4 b, vec_float4 c) -{ - return ((vec_float4)(si_fms((qword)(a), (qword)(b), (qword)(c)))); -} - -static __inline vec_double2 spu_msub(vec_double2 a, vec_double2 b, vec_double2 c) -{ - return ((vec_double2)(si_dfms((qword)(a), (qword)(b), (qword)(c)))); -} - - -/* spu_mtfpscr - * =========== - */ -#define spu_mtfpscr(_a) - - -/* spu_mtspr - * ======== - */ -#define spu_mtspr(_reg, _a) - - -/* spu_mul - * ======== - */ -static __inline vec_float4 spu_mul(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_fm((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_mul(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_dfm((qword)(a), (qword)(b)))); -} - - -/* spu_mulh - * ======== - */ -static __inline vec_int4 spu_mulh(vec_short8 a, vec_short8 b) -{ - return ((vec_int4)(si_mpyh((qword)(a), (qword)(b)))); -} - -/* spu_mule - * ========= - */ -#define spu_mule(_a, _b) vec_mule(_a, _b) - - - -/* spu_mulo - * ======== - */ -static __inline vec_int4 spu_mulo(vec_short8 a, vec_short8 b) -{ - return ((vec_int4)(si_mpy((qword)(a), (qword)(b)))); -} - - -static __inline vec_uint4 spu_mulo(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_uint4)(si_mpyu((qword)(a), (qword)(b)))); -} - - -static __inline vec_int4 spu_mulo(vec_short8 a, short b) -{ - return ((vec_int4)(si_mpyi((qword)(a), b))); -} - -static __inline vec_uint4 spu_mulo(vec_ushort8 a, unsigned short b) -{ - return ((vec_uint4)(si_mpyui((qword)(a), b))); -} - - -/* spu_mulsr - * ========= - */ -static __inline vec_int4 spu_mulsr(vec_short8 a, vec_short8 b) -{ - return ((vec_int4)(si_mpys((qword)(a), (qword)(b)))); -} - - -/* spu_nand - * ======== - */ -static __inline vec_uchar16 spu_nand(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_char16 spu_nand(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_nand(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_nand(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_nand(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_nand(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_float4 spu_nand(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_ullong2 spu_nand(vec_ullong2 a, vec_ullong2 b) -{ - return ((vec_ullong2)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_llong2 spu_nand(vec_llong2 a, vec_llong2 b) -{ - return ((vec_llong2)(si_nand((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_nand(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_nand((qword)(a), (qword)(b)))); -} - - -/* spu_nmadd - * ========= - */ -static __inline vec_double2 spu_nmadd(vec_double2 a, vec_double2 b, vec_double2 c) -{ - return ((vec_double2)(si_dfnma((qword)(a), (qword)(b), (qword)(c)))); -} - - -/* spu_nmsub - * ========= - */ -static __inline vec_float4 spu_nmsub(vec_float4 a, vec_float4 b, vec_float4 c) -{ - return ((vec_float4)(si_fnms((qword)(a), (qword)(b), (qword)(c)))); -} - -static __inline vec_double2 spu_nmsub(vec_double2 a, vec_double2 b, vec_double2 c) -{ - return ((vec_double2)(si_dfnms((qword)(a), (qword)(b), (qword)(c)))); -} - - -/* spu_nor - * ======= - */ -#define spu_nor(_a, _b) vec_nor(_a, _b) - - -/* spu_or - * ====== - */ -static __inline vec_uchar16 spu_or(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_char16 spu_or(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_or(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_or(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_or(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_or(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_float4 spu_or(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_ullong2 spu_or(vec_ullong2 a, vec_ullong2 b) -{ - return ((vec_ullong2)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_llong2 spu_or(vec_llong2 a, vec_llong2 b) -{ - return ((vec_llong2)(si_or((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_or(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_or((qword)(a), (qword)(b)))); -} - - -static __inline vec_uchar16 spu_or(vec_uchar16 a, unsigned char b) -{ - return ((vec_uchar16)(si_orbi((qword)(a), b))); -} - -static __inline vec_char16 spu_or(vec_char16 a, signed char b) -{ - return ((vec_char16)(si_orbi((qword)(a), (unsigned char)(b)))); -} - -static __inline vec_ushort8 spu_or(vec_ushort8 a, unsigned short b) -{ - return ((vec_ushort8)(si_orhi((qword)(a), b))); -} - -static __inline vec_short8 spu_or(vec_short8 a, signed short b) -{ - return ((vec_short8)(si_orhi((qword)(a), (unsigned short)(b)))); -} - -static __inline vec_uint4 spu_or(vec_uint4 a, unsigned int b) -{ - return ((vec_uint4)(si_ori((qword)(a), b))); -} - -static __inline vec_int4 spu_or(vec_int4 a, signed int b) -{ - return ((vec_int4)(si_ori((qword)(a), (unsigned int)(b)))); -} - - -/* spu_orc - * ======= - */ -#define spu_orc(_a, _b) vec_or(_a, vec_nor(_b, _b)) - - -/* spu_orx - * ======= - */ -static __inline vec_uint4 spu_orx(vec_uint4 a) -{ - return ((vec_uint4)(si_orx((qword)(a)))); -} - -static __inline vec_int4 spu_orx(vec_int4 a) -{ - return ((vec_int4)(si_orx((qword)(a)))); -} - - -/* spu_promote - * =========== - */ -static __inline vec_uchar16 spu_promote(unsigned char a, int element) -{ - union { - vec_uchar16 v; - unsigned char c[16]; - } in; - - in.c[element & 15] = a; - return (in.v); -} - -static __inline vec_char16 spu_promote(signed char a, int element) -{ - union { - vec_char16 v; - signed char c[16]; - } in; - - in.c[element & 15] = a; - return (in.v); -} - -static __inline vec_ushort8 spu_promote(unsigned short a, int element) -{ - union { - vec_ushort8 v; - unsigned short s[8]; - } in; - - in.s[element & 7] = a; - return (in.v); -} - -static __inline vec_short8 spu_promote(signed short a, int element) -{ - union { - vec_short8 v; - signed short s[8]; - } in; - - in.s[element & 7] = a; - return (in.v); -} - -static __inline vec_uint4 spu_promote(unsigned int a, int element) -{ - union { - vec_uint4 v; - unsigned int i[4]; - } in; - - in.i[element & 3] = a; - return (in.v); -} - -static __inline vec_int4 spu_promote(signed int a, int element) -{ - union { - vec_int4 v; - signed int i[4]; - } in; - - in.i[element & 3] = a; - return (in.v); -} - -static __inline vec_float4 spu_promote(float a, int element) -{ - union { - vec_float4 v; - float f[4]; - } in; - - in.f[element & 3] = a; - return (in.v); -} - -static __inline vec_ullong2 spu_promote(unsigned long long a, int element) -{ - union { - vec_ullong2 v; - unsigned long long l[2]; - } in; - - in.l[element & 1] = a; - return (in.v); -} - -static __inline vec_llong2 spu_promote(signed long long a, int element) -{ - union { - vec_llong2 v; - signed long long l[2]; - } in; - - in.l[element & 1] = a; - return (in.v); -} - -static __inline vec_double2 spu_promote(double a, int element) -{ - union { - vec_double2 v; - double d[2]; - } in; - - in.d[element & 1] = a; - return (in.v); -} - -/* spu_re - * ====== - */ -#define spu_re(_a) vec_re(_a) - - -/* spu_readch - * ========== - */ -#define spu_readch(_channel) 0 /* not mappable */ - - -/* spu_readchcnt - * ============= - */ -#define spu_readchcnt(_channel) 0 /* not mappable */ - - -/* spu_readchqw - * ============ - */ -#define spu_readchqw(_channel) __extension__ ({ vec_uint4 result = { 0, 0, 0, 0 }; result; }) - -/* spu_rl - * ====== - */ -static __inline vec_ushort8 spu_rl(vec_ushort8 a, vec_short8 b) -{ - return ((vec_ushort8)(si_roth((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_rl(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_roth((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_rl(vec_uint4 a, vec_int4 b) -{ - return ((vec_uint4)(si_rot((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_rl(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_rot((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_rl(vec_ushort8 a, int b) -{ - return ((vec_ushort8)(si_rothi((qword)(a), b))); -} - -static __inline vec_short8 spu_rl(vec_short8 a, int b) -{ - return ((vec_short8)(si_rothi((qword)(a), b))); -} - -static __inline vec_uint4 spu_rl(vec_uint4 a, int b) -{ - return ((vec_uint4)(si_roti((qword)(a), b))); -} - -static __inline vec_int4 spu_rl(vec_int4 a, int b) -{ - return ((vec_int4)(si_roti((qword)(a), b))); -} - - -/* spu_rlmask - * ========== - */ -static __inline vec_ushort8 spu_rlmask(vec_ushort8 a, vec_short8 b) -{ - return ((vec_ushort8)(si_rothm((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_rlmask(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_rothm((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_rlmask(vec_uint4 a, vec_int4 b) -{ - return ((vec_uint4)(si_rotm((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_rlmask(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_rotm((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_rlmask(vec_ushort8 a, int b) -{ - return ((vec_ushort8)(si_rothmi((qword)(a), b))); -} - -static __inline vec_short8 spu_rlmask(vec_short8 a, int b) -{ - return ((vec_short8)(si_rothmi((qword)(a), b))); -} - - -static __inline vec_uint4 spu_rlmask(vec_uint4 a, int b) -{ - return ((vec_uint4)(si_rotmi((qword)(a), b))); -} - -static __inline vec_int4 spu_rlmask(vec_int4 a, int b) -{ - return ((vec_int4)(si_rotmi((qword)(a), b))); -} - -/* spu_rlmaska - * =========== - */ -static __inline vec_short8 spu_rlmaska(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_rotmah((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_rlmaska(vec_ushort8 a, vec_short8 b) -{ - return ((vec_ushort8)(si_rotmah((qword)(a), (qword)(b)))); -} - - -static __inline vec_int4 spu_rlmaska(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_rotma((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_rlmaska(vec_uint4 a, vec_int4 b) -{ - return ((vec_uint4)(si_rotma((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_rlmaska(vec_ushort8 a, int b) -{ - return ((vec_ushort8)(si_rotmahi((qword)(a), b))); -} - -static __inline vec_short8 spu_rlmaska(vec_short8 a, int b) -{ - return ((vec_short8)(si_rotmahi((qword)(a), b))); -} - -static __inline vec_uint4 spu_rlmaska(vec_uint4 a, int b) -{ - return ((vec_uint4)(si_rotmai((qword)(a), b))); -} - -static __inline vec_int4 spu_rlmaska(vec_int4 a, int b) -{ - return ((vec_int4)(si_rotmai((qword)(a), b))); -} - - -/* spu_rlmaskqw - * ============ - */ -static __inline vec_uchar16 spu_rlmaskqw(vec_uchar16 a, int count) -{ - return ((vec_uchar16)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_char16 spu_rlmaskqw(vec_char16 a, int count) -{ - return ((vec_char16)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ushort8 spu_rlmaskqw(vec_ushort8 a, int count) -{ - return ((vec_ushort8)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_short8 spu_rlmaskqw(vec_short8 a, int count) -{ - return ((vec_short8)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_uint4 spu_rlmaskqw(vec_uint4 a, int count) -{ - return ((vec_uint4)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_int4 spu_rlmaskqw(vec_int4 a, int count) -{ - return ((vec_int4)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_float4 spu_rlmaskqw(vec_float4 a, int count) -{ - return ((vec_float4)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ullong2 spu_rlmaskqw(vec_ullong2 a, int count) -{ - return ((vec_ullong2)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_llong2 spu_rlmaskqw(vec_llong2 a, int count) -{ - return ((vec_llong2)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_double2 spu_rlmaskqw(vec_double2 a, int count) -{ - return ((vec_double2)(si_rotqmbi((qword)(a), si_from_int(count)))); -} - -/* spu_rlmaskqwbyte - * ================ - */ -static __inline vec_uchar16 spu_rlmaskqwbyte(vec_uchar16 a, int count) -{ - return ((vec_uchar16)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_char16 spu_rlmaskqwbyte(vec_char16 a, int count) -{ - return ((vec_char16)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_ushort8 spu_rlmaskqwbyte(vec_ushort8 a, int count) -{ - return ((vec_ushort8)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_short8 spu_rlmaskqwbyte(vec_short8 a, int count) -{ - return ((vec_short8)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_uint4 spu_rlmaskqwbyte(vec_uint4 a, int count) -{ - return ((vec_uint4)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_int4 spu_rlmaskqwbyte(vec_int4 a, int count) -{ - return ((vec_int4)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_float4 spu_rlmaskqwbyte(vec_float4 a, int count) -{ - return ((vec_float4)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_ullong2 spu_rlmaskqwbyte(vec_ullong2 a, int count) -{ - return ((vec_ullong2)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_llong2 spu_rlmaskqwbyte(vec_llong2 a, int count) -{ - return ((vec_llong2)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -static __inline vec_double2 spu_rlmaskqwbyte(vec_double2 a, int count) -{ - return ((vec_double2)(si_rotqmby((qword)(a), si_from_int(count)))); -} - -/* spu_rlmaskqwbytebc - * ================== - */ -static __inline vec_uchar16 spu_rlmaskqwbytebc(vec_uchar16 a, int count) -{ - return ((vec_uchar16)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_char16 spu_rlmaskqwbytebc(vec_char16 a, int count) -{ - return ((vec_char16)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ushort8 spu_rlmaskqwbytebc(vec_ushort8 a, int count) -{ - return ((vec_ushort8)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_short8 spu_rlmaskqwbytebc(vec_short8 a, int count) -{ - return ((vec_short8)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_uint4 spu_rlmaskqwbytebc(vec_uint4 a, int count) -{ - return ((vec_uint4)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_int4 spu_rlmaskqwbytebc(vec_int4 a, int count) -{ - return ((vec_int4)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_float4 spu_rlmaskqwbytebc(vec_float4 a, int count) -{ - return ((vec_float4)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ullong2 spu_rlmaskqwbytebc(vec_ullong2 a, int count) -{ - return ((vec_ullong2)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_llong2 spu_rlmaskqwbytebc(vec_llong2 a, int count) -{ - return ((vec_llong2)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_double2 spu_rlmaskqwbytebc(vec_double2 a, int count) -{ - return ((vec_double2)(si_rotqmbybi((qword)(a), si_from_int(count)))); -} - - -/* spu_rlqwbyte - * ============ - */ -static __inline vec_uchar16 spu_rlqwbyte(vec_uchar16 a, int count) -{ - return ((vec_uchar16)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_char16 spu_rlqwbyte(vec_char16 a, int count) -{ - return ((vec_char16)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_ushort8 spu_rlqwbyte(vec_ushort8 a, int count) -{ - return ((vec_ushort8)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_short8 spu_rlqwbyte(vec_short8 a, int count) -{ - return ((vec_short8)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_uint4 spu_rlqwbyte(vec_uint4 a, int count) -{ - return ((vec_uint4)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_int4 spu_rlqwbyte(vec_int4 a, int count) -{ - return ((vec_int4)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_float4 spu_rlqwbyte(vec_float4 a, int count) -{ - return ((vec_float4)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_ullong2 spu_rlqwbyte(vec_ullong2 a, int count) -{ - return ((vec_ullong2)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_llong2 spu_rlqwbyte(vec_llong2 a, int count) -{ - return ((vec_llong2)(si_rotqby((qword)(a), si_from_int(count)))); -} - -static __inline vec_double2 spu_rlqwbyte(vec_double2 a, int count) -{ - return ((vec_double2)(si_rotqby((qword)(a), si_from_int(count)))); -} - - -/* spu_rlqwbytebc - * ============== - */ -static __inline vec_uchar16 spu_rlqwbytebc(vec_uchar16 a, int count) -{ - return ((vec_uchar16)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_char16 spu_rlqwbytebc(vec_char16 a, int count) -{ - return ((vec_char16)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ushort8 spu_rlqwbytebc(vec_ushort8 a, int count) -{ - return ((vec_ushort8)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_short8 spu_rlqwbytebc(vec_short8 a, int count) -{ - return ((vec_short8)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_uint4 spu_rlqwbytebc(vec_uint4 a, int count) -{ - return ((vec_uint4)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_int4 spu_rlqwbytebc(vec_int4 a, int count) -{ - return ((vec_int4)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_float4 spu_rlqwbytebc(vec_float4 a, int count) -{ - return ((vec_float4)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ullong2 spu_rlqwbytebc(vec_ullong2 a, int count) -{ - return ((vec_ullong2)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_llong2 spu_rlqwbytebc(vec_llong2 a, int count) -{ - return ((vec_llong2)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -static __inline vec_double2 spu_rlqwbytebc(vec_double2 a, int count) -{ - return ((vec_double2)(si_rotqbybi((qword)(a), si_from_int(count)))); -} - -/* spu_rlqw - * ======== - */ -static __inline vec_uchar16 spu_rlqw(vec_uchar16 a, int count) -{ - return ((vec_uchar16)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_char16 spu_rlqw(vec_char16 a, int count) -{ - return ((vec_char16)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ushort8 spu_rlqw(vec_ushort8 a, int count) -{ - return ((vec_ushort8)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_short8 spu_rlqw(vec_short8 a, int count) -{ - return ((vec_short8)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_uint4 spu_rlqw(vec_uint4 a, int count) -{ - return ((vec_uint4)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_int4 spu_rlqw(vec_int4 a, int count) -{ - return ((vec_int4)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_float4 spu_rlqw(vec_float4 a, int count) -{ - return ((vec_float4)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_ullong2 spu_rlqw(vec_ullong2 a, int count) -{ - return ((vec_ullong2)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_llong2 spu_rlqw(vec_llong2 a, int count) -{ - return ((vec_llong2)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -static __inline vec_double2 spu_rlqw(vec_double2 a, int count) -{ - return ((vec_double2)(si_rotqbi((qword)(a), si_from_int(count)))); -} - -/* spu_roundtf - * =========== - */ -static __inline vec_float4 spu_roundtf(vec_double2 a) -{ - return ((vec_float4)(si_frds((qword)(a)))); -} - - -/* spu_rsqrte - * ========== - */ -#define spu_rsqrte(_a) vec_rsqrte(_a) - - -/* spu_sel - * ======= - */ -static __inline vec_uchar16 spu_sel(vec_uchar16 a, vec_uchar16 b, vec_uchar16 pattern) -{ - return ((vec_uchar16)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_char16 spu_sel(vec_char16 a, vec_char16 b, vec_uchar16 pattern) -{ - return ((vec_char16)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_ushort8 spu_sel(vec_ushort8 a, vec_ushort8 b, vec_ushort8 pattern) -{ - return ((vec_ushort8)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_short8 spu_sel(vec_short8 a, vec_short8 b, vec_ushort8 pattern) -{ - return ((vec_short8)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_uint4 spu_sel(vec_uint4 a, vec_uint4 b, vec_uint4 pattern) -{ - return ((vec_uint4)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_int4 spu_sel(vec_int4 a, vec_int4 b, vec_uint4 pattern) -{ - return ((vec_int4)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_float4 spu_sel(vec_float4 a, vec_float4 b, vec_uint4 pattern) -{ - return ((vec_float4)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_ullong2 spu_sel(vec_ullong2 a, vec_ullong2 b, vec_ullong2 pattern) -{ - return ((vec_ullong2)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_llong2 spu_sel(vec_llong2 a, vec_llong2 b, vec_ullong2 pattern) -{ - return ((vec_llong2)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_double2 spu_sel(vec_double2 a, vec_double2 b, vec_ullong2 pattern) -{ - return ((vec_double2)(si_selb((qword)(a), (qword)(b), (qword)(pattern)))); -} - - - -/* spu_shuffle - * =========== - */ -static __inline vec_uchar16 spu_shuffle(vec_uchar16 a, vec_uchar16 b, vec_uchar16 pattern) -{ - return ((vec_uchar16)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_char16 spu_shuffle(vec_char16 a, vec_char16 b, vec_uchar16 pattern) -{ - return ((vec_char16)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_ushort8 spu_shuffle(vec_ushort8 a, vec_ushort8 b, vec_uchar16 pattern) -{ - return ((vec_ushort8)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_short8 spu_shuffle(vec_short8 a, vec_short8 b, vec_uchar16 pattern) -{ - return ((vec_short8)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_uint4 spu_shuffle(vec_uint4 a, vec_uint4 b, vec_uchar16 pattern) -{ - return ((vec_uint4)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_int4 spu_shuffle(vec_int4 a, vec_int4 b, vec_uchar16 pattern) -{ - return ((vec_int4)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_float4 spu_shuffle(vec_float4 a, vec_float4 b, vec_uchar16 pattern) -{ - return ((vec_float4)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_ullong2 spu_shuffle(vec_ullong2 a, vec_ullong2 b, vec_uchar16 pattern) -{ - return ((vec_ullong2)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_llong2 spu_shuffle(vec_llong2 a, vec_llong2 b, vec_uchar16 pattern) -{ - return ((vec_llong2)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - -static __inline vec_double2 spu_shuffle(vec_double2 a, vec_double2 b, vec_uchar16 pattern) -{ - return ((vec_double2)(si_shufb((qword)(a), (qword)(b), (qword)(pattern)))); -} - - -/* spu_sl - * ====== - */ -static __inline vec_ushort8 spu_sl(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_shlh((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_sl(vec_short8 a, vec_ushort8 b) -{ - return ((vec_short8)(si_shlh((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_sl(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_shl((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_sl(vec_int4 a, vec_uint4 b) -{ - return ((vec_int4)(si_shl((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_sl(vec_ushort8 a, unsigned int b) -{ - return ((vec_ushort8)(si_shlhi((qword)(a), b))); -} - -static __inline vec_short8 spu_sl(vec_short8 a, unsigned int b) -{ - return ((vec_short8)(si_shlhi((qword)(a), b))); -} - -static __inline vec_uint4 spu_sl(vec_uint4 a, unsigned int b) -{ - return ((vec_uint4)(si_shli((qword)(a), b))); -} - -static __inline vec_int4 spu_sl(vec_int4 a, unsigned int b) -{ - return ((vec_int4)(si_shli((qword)(a), b))); -} - - -/* spu_slqw - * ======== - */ -static __inline vec_uchar16 spu_slqw(vec_uchar16 a, unsigned int count) -{ - return ((vec_uchar16)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_char16 spu_slqw(vec_char16 a, unsigned int count) -{ - return ((vec_char16)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_ushort8 spu_slqw(vec_ushort8 a, unsigned int count) -{ - return ((vec_ushort8)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_short8 spu_slqw(vec_short8 a, unsigned int count) -{ - return ((vec_short8)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_uint4 spu_slqw(vec_uint4 a, unsigned int count) -{ - return ((vec_uint4)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_int4 spu_slqw(vec_int4 a, unsigned int count) -{ - return ((vec_int4)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_float4 spu_slqw(vec_float4 a, unsigned int count) -{ - return ((vec_float4)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_ullong2 spu_slqw(vec_ullong2 a, unsigned int count) -{ - return ((vec_ullong2)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_llong2 spu_slqw(vec_llong2 a, unsigned int count) -{ - return ((vec_llong2)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_double2 spu_slqw(vec_double2 a, unsigned int count) -{ - return ((vec_double2)(si_shlqbi((qword)(a), si_from_uint(count)))); -} - -/* spu_slqwbyte - * ============ - */ -static __inline vec_uchar16 spu_slqwbyte(vec_uchar16 a, unsigned int count) -{ - return ((vec_uchar16)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_char16 spu_slqwbyte(vec_char16 a, unsigned int count) -{ - return ((vec_char16)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_ushort8 spu_slqwbyte(vec_ushort8 a, unsigned int count) -{ - return ((vec_ushort8)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_short8 spu_slqwbyte(vec_short8 a, unsigned int count) -{ - return ((vec_short8)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_uint4 spu_slqwbyte(vec_uint4 a, unsigned int count) -{ - return ((vec_uint4)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_int4 spu_slqwbyte(vec_int4 a, unsigned int count) -{ - return ((vec_int4)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_float4 spu_slqwbyte(vec_float4 a, unsigned int count) -{ - return ((vec_float4)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_ullong2 spu_slqwbyte(vec_ullong2 a, unsigned int count) -{ - return ((vec_ullong2)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_llong2 spu_slqwbyte(vec_llong2 a, unsigned int count) -{ - return ((vec_llong2)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -static __inline vec_double2 spu_slqwbyte(vec_double2 a, unsigned int count) -{ - return ((vec_double2)(si_shlqby((qword)(a), si_from_uint(count)))); -} - -/* spu_slqwbytebc - * ============== - */ -static __inline vec_uchar16 spu_slqwbytebc(vec_uchar16 a, unsigned int count) -{ - return ((vec_uchar16)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_char16 spu_slqwbytebc(vec_char16 a, unsigned int count) -{ - return ((vec_char16)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_ushort8 spu_slqwbytebc(vec_ushort8 a, unsigned int count) -{ - return ((vec_ushort8)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_short8 spu_slqwbytebc(vec_short8 a, unsigned int count) -{ - return ((vec_short8)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_uint4 spu_slqwbytebc(vec_uint4 a, unsigned int count) -{ - return ((vec_uint4)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_int4 spu_slqwbytebc(vec_int4 a, unsigned int count) -{ - return ((vec_int4)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_float4 spu_slqwbytebc(vec_float4 a, unsigned int count) -{ - return ((vec_float4)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_ullong2 spu_slqwbytebc(vec_ullong2 a, unsigned int count) -{ - return ((vec_ullong2)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_llong2 spu_slqwbytebc(vec_llong2 a, unsigned int count) -{ - return ((vec_llong2)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -static __inline vec_double2 spu_slqwbytebc(vec_double2 a, unsigned int count) -{ - return ((vec_double2)(si_shlqbybi((qword)(a), si_from_uint(count)))); -} - -/* spu_splats - * ========== - */ -static __inline vec_uchar16 spu_splats(unsigned char a) -{ - union { - vec_uchar16 v; - unsigned char c[16]; - } in; - - in.c[0] = a; - return (vec_splat(in.v, 0)); -} - -static __inline vec_char16 spu_splats(signed char a) -{ - return ((vec_char16)spu_splats((unsigned char)(a))); -} - -static __inline vec_ushort8 spu_splats(unsigned short a) -{ - union { - vec_ushort8 v; - unsigned short s[8]; - } in; - - in.s[0] = a; - return (vec_splat(in.v, 0)); -} - -static __inline vec_short8 spu_splats(signed short a) -{ - return ((vec_short8)spu_splats((unsigned short)(a))); -} - -static __inline vec_uint4 spu_splats(unsigned int a) -{ - union { - vec_uint4 v; - unsigned int i[4]; - } in; - - in.i[0] = a; - return (vec_splat(in.v, 0)); -} - -static __inline vec_int4 spu_splats(signed int a) -{ - return ((vec_int4)spu_splats((unsigned int)(a))); -} - -static __inline vec_float4 spu_splats(float a) -{ - union { - vec_float4 v; - float f[4]; - } in; - - in.f[0] = a; - return (vec_splat(in.v, 0)); -} - -static __inline vec_ullong2 spu_splats(unsigned long long a) -{ - union { - vec_ullong2 v; - unsigned long long l[2]; - } in; - - in.l[0] = a; - in.l[1] = a; - return (in.v); -} - -static __inline vec_llong2 spu_splats(signed long long a) -{ - return ((vec_llong2)spu_splats((unsigned long long)(a))); -} - -static __inline vec_double2 spu_splats(double a) -{ - union { - vec_double2 v; - double d[2]; - } in; - - in.d[0] = a; - in.d[1] = a; - return (in.v); -} - - -/* spu_stop - * ======== - */ -#define spu_stop(_type) si_stop(_type) - - -/* spu_sub - * ======= - */ -static __inline vec_ushort8 spu_sub(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_sfh((qword)(b), (qword)(a)))); -} - -static __inline vec_short8 spu_sub(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_sfh((qword)(b), (qword)(a)))); -} - -static __inline vec_uint4 spu_sub(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_sf((qword)(b), (qword)(a)))); -} - -static __inline vec_int4 spu_sub(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_sf((qword)(b), (qword)(a)))); -} - -static __inline vec_float4 spu_sub(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_fs((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_sub(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_dfs((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_sub(unsigned int a, vec_uint4 b) -{ - return ((vec_uint4)(si_sfi((qword)b, (int)a))); -} - -static __inline vec_int4 spu_sub(signed int a, vec_int4 b) -{ - return ((vec_int4)(si_sfi((qword)b, (int)a))); -} - -static __inline vec_ushort8 spu_sub(unsigned short a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_sfhi((qword)b, (short)a))); -} - -static __inline vec_short8 spu_sub(signed short a, vec_short8 b) -{ - return ((vec_short8)(si_sfhi((qword)b, (short)a))); -} - -/* spu_subx - * ======== - */ -static __inline vec_uint4 spu_subx(vec_uint4 a, vec_uint4 b, vec_uint4 c) -{ - return ((vec_uint4)(si_sfx((qword)(b), (qword)(a), (qword)(c)))); -} - -static __inline vec_int4 spu_subx(vec_int4 a, vec_int4 b, vec_int4 c) -{ - return ((vec_int4)(si_sfx((qword)(b), (qword)(a), (qword)(c)))); -} - -/* spu_sumb - * ======== - */ -static __inline vec_ushort8 spu_sumb(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_ushort8)(si_sumb((qword)(a), (qword)(b)))); -} - - -/* spu_sync - * spu_sync_c - * ======== - */ -#define spu_sync() /* do nothing */ - -#define spu_sync_c() /* do nothing */ - - -/* spu_writech - * =========== - */ -#define spu_writech(_channel, _a) /* not mappable */ - -/* spu_writechqw - * ============= - */ -#define spu_writechqw(_channel, _a) /* not mappable */ - - -/* spu_xor - * ======= - */ -static __inline vec_uchar16 spu_xor(vec_uchar16 a, vec_uchar16 b) -{ - return ((vec_uchar16)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_char16 spu_xor(vec_char16 a, vec_char16 b) -{ - return ((vec_char16)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_ushort8 spu_xor(vec_ushort8 a, vec_ushort8 b) -{ - return ((vec_ushort8)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_short8 spu_xor(vec_short8 a, vec_short8 b) -{ - return ((vec_short8)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_uint4 spu_xor(vec_uint4 a, vec_uint4 b) -{ - return ((vec_uint4)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_int4 spu_xor(vec_int4 a, vec_int4 b) -{ - return ((vec_int4)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_float4 spu_xor(vec_float4 a, vec_float4 b) -{ - return ((vec_float4)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_ullong2 spu_xor(vec_ullong2 a, vec_ullong2 b) -{ - return ((vec_ullong2)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_llong2 spu_xor(vec_llong2 a, vec_llong2 b) -{ - return ((vec_llong2)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_double2 spu_xor(vec_double2 a, vec_double2 b) -{ - return ((vec_double2)(si_xor((qword)(a), (qword)(b)))); -} - -static __inline vec_uchar16 spu_xor(vec_uchar16 a, unsigned char b) -{ - return ((vec_uchar16)(si_xorbi((qword)(a), b))); -} - -static __inline vec_char16 spu_xor(vec_char16 a, signed char b) -{ - return ((vec_char16)(si_xorbi((qword)(a), (unsigned char)(b)))); -} - -static __inline vec_ushort8 spu_xor(vec_ushort8 a, unsigned short b) -{ - return ((vec_ushort8)(si_xorhi((qword)(a), b))); -} - -static __inline vec_short8 spu_xor(vec_short8 a, signed short b) -{ - return ((vec_short8)(si_xorhi((qword)(a), (unsigned short)(b)))); -} - -static __inline vec_uint4 spu_xor(vec_uint4 a, unsigned int b) -{ - return ((vec_uint4)(si_xori((qword)(a), b))); -} - -static __inline vec_int4 spu_xor(vec_int4 a, signed int b) -{ - return ((vec_int4)(si_xori((qword)(a), (unsigned int)(b)))); -} - -#endif /* !__SPU__ */ -#endif /* __cplusplus */ -#endif /* !_SPU2VMX_H_ */ diff --git a/gcc-4.8.1/gcc/config/rs6000/sync.md b/gcc-4.8.1/gcc/config/rs6000/sync.md deleted file mode 100644 index 252e2690a..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/sync.md +++ /dev/null @@ -1,293 +0,0 @@ -;; Machine description for PowerPC synchronization instructions. -;; Copyright (C) 2005-2013 Free Software Foundation, Inc. -;; Contributed by Geoffrey Keating. - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -(define_mode_attr larx [(SI "lwarx") (DI "ldarx")]) -(define_mode_attr stcx [(SI "stwcx.") (DI "stdcx.")]) - -(define_code_iterator FETCHOP [plus minus ior xor and]) -(define_code_attr fetchop_name - [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")]) -(define_code_attr fetchop_pred - [(plus "add_operand") (minus "gpc_reg_operand") - (ior "logical_operand") (xor "logical_operand") (and "and_operand")]) - -(define_expand "mem_thread_fence" - [(match_operand:SI 0 "const_int_operand" "")] ;; model - "" -{ - enum memmodel model = (enum memmodel) INTVAL (operands[0]); - switch (model) - { - case MEMMODEL_RELAXED: - break; - case MEMMODEL_CONSUME: - case MEMMODEL_ACQUIRE: - case MEMMODEL_RELEASE: - case MEMMODEL_ACQ_REL: - emit_insn (gen_lwsync ()); - break; - case MEMMODEL_SEQ_CST: - emit_insn (gen_hwsync ()); - break; - default: - gcc_unreachable (); - } - DONE; -}) - -(define_expand "hwsync" - [(set (match_dup 0) - (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))] - "" -{ - operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); - MEM_VOLATILE_P (operands[0]) = 1; -}) - -(define_insn "*hwsync" - [(set (match_operand:BLK 0 "" "") - (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))] - "" - "sync" - [(set_attr "type" "sync")]) - -(define_expand "lwsync" - [(set (match_dup 0) - (unspec:BLK [(match_dup 0)] UNSPEC_LWSYNC))] - "" -{ - operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); - MEM_VOLATILE_P (operands[0]) = 1; -}) - -(define_insn "*lwsync" - [(set (match_operand:BLK 0 "" "") - (unspec:BLK [(match_dup 0)] UNSPEC_LWSYNC))] - "" -{ - /* Some AIX assemblers don't accept lwsync, so we use a .long. */ - if (TARGET_NO_LWSYNC) - return "sync"; - else if (TARGET_LWSYNC_INSTRUCTION) - return "lwsync"; - else - return ".long 0x7c2004ac"; -} - [(set_attr "type" "sync")]) - -(define_insn "isync" - [(unspec_volatile:BLK [(const_int 0)] UNSPECV_ISYNC)] - "" - "isync" - [(set_attr "type" "isync")]) - -;; The control dependency used for load dependency described -;; in B.2.3 of the Power ISA 2.06B. -(define_insn "loadsync_<mode>" - [(unspec_volatile:BLK [(match_operand:INT1 0 "register_operand" "r")] - UNSPECV_ISYNC) - (clobber (match_scratch:CC 1 "=y"))] - "" - "cmpw %1,%0,%0\;bne- %1,$+4\;isync" - [(set_attr "type" "isync") - (set_attr "length" "12")]) - -(define_expand "atomic_load<mode>" - [(set (match_operand:INT1 0 "register_operand" "") ;; output - (match_operand:INT1 1 "memory_operand" "")) ;; memory - (use (match_operand:SI 2 "const_int_operand" ""))] ;; model - "" -{ - enum memmodel model = (enum memmodel) INTVAL (operands[2]); - - if (model == MEMMODEL_SEQ_CST) - emit_insn (gen_hwsync ()); - - emit_move_insn (operands[0], operands[1]); - - switch (model) - { - case MEMMODEL_RELAXED: - break; - case MEMMODEL_CONSUME: - case MEMMODEL_ACQUIRE: - case MEMMODEL_SEQ_CST: - if (GET_MODE (operands[0]) == QImode) - emit_insn (gen_loadsync_qi (operands[0])); - else if (GET_MODE (operands[0]) == HImode) - emit_insn (gen_loadsync_hi (operands[0])); - else if (GET_MODE (operands[0]) == SImode) - emit_insn (gen_loadsync_si (operands[0])); - else if (GET_MODE (operands[0]) == DImode) - emit_insn (gen_loadsync_di (operands[0])); - else - gcc_unreachable (); - break; - default: - gcc_unreachable (); - } - DONE; -}) - -(define_expand "atomic_store<mode>" - [(set (match_operand:INT1 0 "memory_operand" "") ;; memory - (match_operand:INT1 1 "register_operand" "")) ;; input - (use (match_operand:SI 2 "const_int_operand" ""))] ;; model - "" -{ - enum memmodel model = (enum memmodel) INTVAL (operands[2]); - switch (model) - { - case MEMMODEL_RELAXED: - break; - case MEMMODEL_RELEASE: - emit_insn (gen_lwsync ()); - break; - case MEMMODEL_SEQ_CST: - emit_insn (gen_hwsync ()); - break; - default: - gcc_unreachable (); - } - emit_move_insn (operands[0], operands[1]); - DONE; -}) - -;; ??? Power ISA 2.06B says that there *is* a load-{byte,half}-and-reserve -;; opcode that is "phased-in". Not implemented as of Power7, so not yet used, -;; but let's prepare the macros anyway. - -(define_mode_iterator ATOMIC [SI (DI "TARGET_POWERPC64")]) - -(define_insn "load_locked<mode>" - [(set (match_operand:ATOMIC 0 "gpc_reg_operand" "=r") - (unspec_volatile:ATOMIC - [(match_operand:ATOMIC 1 "memory_operand" "Z")] UNSPECV_LL))] - "" - "<larx> %0,%y1" - [(set_attr "type" "load_l")]) - -(define_insn "store_conditional<mode>" - [(set (match_operand:CC 0 "cc_reg_operand" "=x") - (unspec_volatile:CC [(const_int 0)] UNSPECV_SC)) - (set (match_operand:ATOMIC 1 "memory_operand" "=Z") - (match_operand:ATOMIC 2 "gpc_reg_operand" "r"))] - "" - "<stcx> %2,%y1" - [(set_attr "type" "store_c")]) - -(define_expand "atomic_compare_and_swap<mode>" - [(match_operand:SI 0 "gpc_reg_operand" "") ;; bool out - (match_operand:INT1 1 "gpc_reg_operand" "") ;; val out - (match_operand:INT1 2 "memory_operand" "") ;; memory - (match_operand:INT1 3 "reg_or_short_operand" "") ;; expected - (match_operand:INT1 4 "gpc_reg_operand" "") ;; desired - (match_operand:SI 5 "const_int_operand" "") ;; is_weak - (match_operand:SI 6 "const_int_operand" "") ;; model succ - (match_operand:SI 7 "const_int_operand" "")] ;; model fail - "" -{ - rs6000_expand_atomic_compare_and_swap (operands); - DONE; -}) - -(define_expand "atomic_exchange<mode>" - [(match_operand:INT1 0 "gpc_reg_operand" "") ;; output - (match_operand:INT1 1 "memory_operand" "") ;; memory - (match_operand:INT1 2 "gpc_reg_operand" "") ;; input - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - rs6000_expand_atomic_exchange (operands); - DONE; -}) - -(define_expand "atomic_<fetchop_name><mode>" - [(match_operand:INT1 0 "memory_operand" "") ;; memory - (FETCHOP:INT1 (match_dup 0) - (match_operand:INT1 1 "<fetchop_pred>" "")) ;; operand - (match_operand:SI 2 "const_int_operand" "")] ;; model - "" -{ - rs6000_expand_atomic_op (<CODE>, operands[0], operands[1], - NULL_RTX, NULL_RTX, operands[2]); - DONE; -}) - -(define_expand "atomic_nand<mode>" - [(match_operand:INT1 0 "memory_operand" "") ;; memory - (match_operand:INT1 1 "gpc_reg_operand" "") ;; operand - (match_operand:SI 2 "const_int_operand" "")] ;; model - "" -{ - rs6000_expand_atomic_op (NOT, operands[0], operands[1], - NULL_RTX, NULL_RTX, operands[2]); - DONE; -}) - -(define_expand "atomic_fetch_<fetchop_name><mode>" - [(match_operand:INT1 0 "gpc_reg_operand" "") ;; output - (match_operand:INT1 1 "memory_operand" "") ;; memory - (FETCHOP:INT1 (match_dup 1) - (match_operand:INT1 2 "<fetchop_pred>" "")) ;; operand - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - rs6000_expand_atomic_op (<CODE>, operands[1], operands[2], - operands[0], NULL_RTX, operands[3]); - DONE; -}) - -(define_expand "atomic_fetch_nand<mode>" - [(match_operand:INT1 0 "gpc_reg_operand" "") ;; output - (match_operand:INT1 1 "memory_operand" "") ;; memory - (match_operand:INT1 2 "gpc_reg_operand" "") ;; operand - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - rs6000_expand_atomic_op (NOT, operands[1], operands[2], - operands[0], NULL_RTX, operands[3]); - DONE; -}) - -(define_expand "atomic_<fetchop_name>_fetch<mode>" - [(match_operand:INT1 0 "gpc_reg_operand" "") ;; output - (match_operand:INT1 1 "memory_operand" "") ;; memory - (FETCHOP:INT1 (match_dup 1) - (match_operand:INT1 2 "<fetchop_pred>" "")) ;; operand - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - rs6000_expand_atomic_op (<CODE>, operands[1], operands[2], - NULL_RTX, operands[0], operands[3]); - DONE; -}) - -(define_expand "atomic_nand_fetch<mode>" - [(match_operand:INT1 0 "gpc_reg_operand" "") ;; output - (match_operand:INT1 1 "memory_operand" "") ;; memory - (match_operand:INT1 2 "gpc_reg_operand" "") ;; operand - (match_operand:SI 3 "const_int_operand" "")] ;; model - "" -{ - rs6000_expand_atomic_op (NOT, operands[1], operands[2], - NULL_RTX, operands[0], operands[3]); - DONE; -}) diff --git a/gcc-4.8.1/gcc/config/rs6000/sysv4.h b/gcc-4.8.1/gcc/config/rs6000/sysv4.h deleted file mode 100644 index 54bdb210c..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/sysv4.h +++ /dev/null @@ -1,980 +0,0 @@ -/* Target definitions for GNU compiler for PowerPC running System V.4 - Copyright (C) 1995-2013 Free Software Foundation, Inc. - Contributed by Cygnus Support. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* Header files should be C++ aware in general. */ -#undef NO_IMPLICIT_EXTERN_C -#define NO_IMPLICIT_EXTERN_C - -/* Yes! We are ELF. */ -#define TARGET_OBJECT_FORMAT OBJECT_ELF - -/* Default ABI to compile code for. */ -#define DEFAULT_ABI rs6000_current_abi - -/* Default ABI to use. */ -#define RS6000_ABI_NAME "sysv" - -/* Override rs6000.h definition. */ -#undef ASM_DEFAULT_SPEC -#define ASM_DEFAULT_SPEC "-mppc" - -#define TARGET_TOC ((rs6000_isa_flags & OPTION_MASK_64BIT) \ - || ((rs6000_isa_flags \ - & (OPTION_MASK_RELOCATABLE \ - | OPTION_MASK_MINIMAL_TOC)) \ - && flag_pic > 1) \ - || DEFAULT_ABI == ABI_AIX) - -#define TARGET_BITFIELD_TYPE (! TARGET_NO_BITFIELD_TYPE) -#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN) -#define TARGET_PROTOTYPE target_prototype -#define TARGET_NO_PROTOTYPE (! TARGET_PROTOTYPE) -#define TARGET_NO_TOC (! TARGET_TOC) -#define TARGET_NO_EABI (! TARGET_EABI) -#define TARGET_REGNAMES rs6000_regnames - -#ifdef HAVE_AS_REL16 -#undef TARGET_SECURE_PLT -#define TARGET_SECURE_PLT secure_plt -#endif - -#define SDATA_DEFAULT_SIZE 8 - -/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to - get control in TARGET_OPTION_OVERRIDE. */ - -#define SUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if (!global_options_set.x_g_switch_value) \ - 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")) \ - { \ - rs6000_current_abi = ABI_V4; \ - rs6000_isa_flags &= ~ OPTION_MASK_EABI; \ - } \ - else if (!strcmp (rs6000_abi_name, "sysv-eabi") \ - || !strcmp (rs6000_abi_name, "eabi")) \ - { \ - rs6000_current_abi = ABI_V4; \ - rs6000_isa_flags |= OPTION_MASK_EABI; \ - } \ - else if (!strcmp (rs6000_abi_name, "aixdesc")) \ - rs6000_current_abi = ABI_AIX; \ - else if (!strcmp (rs6000_abi_name, "freebsd") \ - || !strcmp (rs6000_abi_name, "linux")) \ - { \ - if (TARGET_64BIT) \ - rs6000_current_abi = ABI_AIX; \ - else \ - 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; \ - rs6000_isa_flags |= (OPTION_MASK_LITTLE_ENDIAN | OPTION_MASK_EABI); \ - rs6000_isa_flags &= ~OPTION_MASK_STRICT_ALIGN; \ - TARGET_NO_BITFIELD_WORD = 1; \ - } \ - else \ - { \ - rs6000_current_abi = ABI_V4; \ - error ("bad value for -mcall-%s", rs6000_abi_name); \ - } \ - \ - if (rs6000_sdata_name) \ - { \ - if (!strcmp (rs6000_sdata_name, "none")) \ - rs6000_sdata = SDATA_NONE; \ - else if (!strcmp (rs6000_sdata_name, "data")) \ - rs6000_sdata = SDATA_DATA; \ - else if (!strcmp (rs6000_sdata_name, "default")) \ - rs6000_sdata = (TARGET_EABI) ? SDATA_EABI : SDATA_SYSV; \ - else if (!strcmp (rs6000_sdata_name, "sysv")) \ - rs6000_sdata = SDATA_SYSV; \ - else if (!strcmp (rs6000_sdata_name, "eabi")) \ - rs6000_sdata = SDATA_EABI; \ - else \ - error ("bad value for -msdata=%s", rs6000_sdata_name); \ - } \ - else if (DEFAULT_ABI == ABI_V4) \ - { \ - rs6000_sdata = SDATA_DATA; \ - rs6000_sdata_name = "data"; \ - } \ - else \ - { \ - rs6000_sdata = SDATA_NONE; \ - rs6000_sdata_name = "none"; \ - } \ - \ - if (TARGET_RELOCATABLE && \ - (rs6000_sdata == SDATA_EABI || rs6000_sdata == SDATA_SYSV)) \ - { \ - rs6000_sdata = SDATA_DATA; \ - error ("-mrelocatable and -msdata=%s are incompatible", \ - rs6000_sdata_name); \ - } \ - \ - 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", \ - (flag_pic > 1) ? "PIC" : "pic", \ - rs6000_sdata_name); \ - } \ - \ - if ((rs6000_sdata != SDATA_NONE && DEFAULT_ABI != ABI_V4) \ - || (rs6000_sdata == SDATA_EABI && !TARGET_EABI)) \ - { \ - rs6000_sdata = SDATA_NONE; \ - error ("-msdata=%s and -mcall-%s are incompatible", \ - rs6000_sdata_name, rs6000_abi_name); \ - } \ - \ - targetm.have_srodata_section = rs6000_sdata == SDATA_EABI; \ - \ - if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \ - { \ - rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; \ - error ("-mrelocatable and -mno-minimal-toc are incompatible"); \ - } \ - \ - if (TARGET_RELOCATABLE && rs6000_current_abi == ABI_AIX) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \ - error ("-mrelocatable and -mcall-%s are incompatible", \ - rs6000_abi_name); \ - } \ - \ - if (!TARGET_64BIT && flag_pic > 1 && rs6000_current_abi == ABI_AIX) \ - { \ - flag_pic = 0; \ - error ("-fPIC and -mcall-%s are incompatible", \ - rs6000_abi_name); \ - } \ - \ - if (rs6000_current_abi == ABI_AIX && TARGET_LITTLE_ENDIAN) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_LITTLE_ENDIAN; \ - error ("-mcall-aixdesc must be big endian"); \ - } \ - \ - if (TARGET_SECURE_PLT != secure_plt) \ - { \ - error ("-msecure-plt not supported by your assembler"); \ - } \ - \ - /* Treat -fPIC the same as -mrelocatable. */ \ - if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX) \ - { \ - rs6000_isa_flags |= OPTION_MASK_RELOCATABLE | OPTION_MASK_MINIMAL_TOC; \ - TARGET_NO_FP_IN_TOC = 1; \ - } \ - \ - else if (TARGET_RELOCATABLE) \ - if (!flag_pic) \ - flag_pic = 2; \ -} while (0) - -#ifndef RS6000_BI_ARCH -# define SUBSUBTARGET_OVERRIDE_OPTIONS \ -do { \ - if ((TARGET_DEFAULT ^ rs6000_isa_flags) & OPTION_MASK_64BIT) \ - error ("-m%s not supported in this configuration", \ - (rs6000_isa_flags & OPTION_MASK_64BIT) ? "64" : "32"); \ -} while (0) -#endif - -/* Override rs6000.h definition. */ -#undef TARGET_DEFAULT -#define TARGET_DEFAULT 0 - -/* Override rs6000.h definition. */ -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC750 - -#define FIXED_R2 1 -/* System V.4 uses register 13 as a pointer to the small data area, - so it is not available to the normal user. */ -#define FIXED_R13 1 - -/* Override default big endianism definitions in rs6000.h. */ -#undef BYTES_BIG_ENDIAN -#undef WORDS_BIG_ENDIAN -#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN) -#define WORDS_BIG_ENDIAN (TARGET_BIG_ENDIAN) - -/* Put jump tables in read-only memory, rather than in .text. */ -#define JUMP_TABLES_IN_TEXT_SECTION 0 - -/* Prefix and suffix to use to saving floating point. */ -#define SAVE_FP_PREFIX "_savefpr_" -#define SAVE_FP_SUFFIX "" - -/* Prefix and suffix to use to restoring floating point. */ -#define RESTORE_FP_PREFIX "_restfpr_" -#define RESTORE_FP_SUFFIX "" - -/* Type used for size_t, as a string used in a declaration. */ -#undef SIZE_TYPE -#define SIZE_TYPE "unsigned int" - -/* Type used for ptrdiff_t, as a string used in a declaration. */ -#define PTRDIFF_TYPE "int" - -#undef WCHAR_TYPE -#define WCHAR_TYPE "long int" - -#undef WCHAR_TYPE_SIZE -#define WCHAR_TYPE_SIZE 32 - -/* Make int foo : 8 not cause structures to be aligned to an int boundary. */ -/* Override elfos.h definition. */ -#undef PCC_BITFIELD_TYPE_MATTERS -#define PCC_BITFIELD_TYPE_MATTERS (TARGET_BITFIELD_TYPE) - -#undef BITFIELD_NBYTES_LIMITED -#define BITFIELD_NBYTES_LIMITED (TARGET_NO_BITFIELD_WORD) - -/* Define this macro to be the value 1 if instructions will fail to - work if given data not on the nominal alignment. If instructions - will merely go slower in that case, define this macro as 0. */ -#undef STRICT_ALIGNMENT -#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN) - -/* 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 - in bits). This macro must evaluate to a value equal to or larger - than STACK_BOUNDARY. - For the SYSV ABI and variants the alignment of the stack pointer - is usually controlled manually in rs6000.c. However, to maintain - alignment across alloca () in all circumstances, - PREFERRED_STACK_BOUNDARY needs to be set as well. - This has the additional advantage of allowing a bigger maximum - alignment of user objects on the stack. */ - -#undef PREFERRED_STACK_BOUNDARY -#define PREFERRED_STACK_BOUNDARY 128 - -/* Real stack boundary as mandated by the appropriate ABI. */ -#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. */ -#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ - ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \ - ? 128 : COMPUTED) - -#undef BIGGEST_FIELD_ALIGNMENT - -/* Use ELF style section commands. */ - -#define TEXT_SECTION_ASM_OP "\t.section\t\".text\"" - -#define DATA_SECTION_ASM_OP "\t.section\t\".data\"" - -#define BSS_SECTION_ASM_OP "\t.section\t\".bss\"" - -/* Override elfos.h definition. */ -#undef INIT_SECTION_ASM_OP -#define INIT_SECTION_ASM_OP "\t.section\t\".init\",\"ax\"" - -/* Override elfos.h definition. */ -#undef FINI_SECTION_ASM_OP -#define FINI_SECTION_ASM_OP "\t.section\t\".fini\",\"ax\"" - -#define TOC_SECTION_ASM_OP "\t.section\t\".got\",\"aw\"" - -/* Put PC relative got entries in .got2. */ -#define MINIMAL_TOC_SECTION_ASM_OP \ - (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\"" -#define SBSS_SECTION_ASM_OP "\t.section\t\".sbss\",\"aw\",@nobits" - -/* Override default elf definitions. */ -#define TARGET_ASM_INIT_SECTIONS rs6000_elf_asm_init_sections -#undef TARGET_ASM_RELOC_RW_MASK -#define TARGET_ASM_RELOC_RW_MASK rs6000_elf_reloc_rw_mask -#undef TARGET_ASM_SELECT_RTX_SECTION -#define TARGET_ASM_SELECT_RTX_SECTION rs6000_elf_select_rtx_section - -/* Return nonzero if this entry is to be written into the constant pool - in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST - containing one of them. If -mfp-in-toc (the default), we also do - this for floating-point constants. We actually can only do this - if the FP formats of the target and host machines are the same, but - we can't check that since not every file that uses these target macros - includes real.h. - - Unlike AIX, we don't key off of -mminimal-toc, but instead do not - allow floating point constants in the TOC if -mrelocatable. */ - -#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \ - (TARGET_TOC \ - && (GET_CODE (X) == SYMBOL_REF \ - || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ - || GET_CODE (X) == LABEL_REF \ - || (GET_CODE (X) == CONST_INT \ - && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \ - || (!TARGET_NO_FP_IN_TOC \ - && !TARGET_RELOCATABLE \ - && GET_CODE (X) == CONST_DOUBLE \ - && SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ - && BITS_PER_WORD == HOST_BITS_PER_INT))) - -/* These macros generate the special .type and .size directives which - are used to set the corresponding fields of the linker symbol table - entries in an ELF object file under SVR4. These macros also output - the starting labels for the relevant functions/objects. */ - -/* Write the extra assembler code needed to declare a function properly. - Some svr4 assemblers need to also have something extra said about the - function's return value. We allow for that here. */ - -/* Override elfos.h definition. */ -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ - 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. */ - -#define LOCAL_LABEL_PREFIX "." -#define USER_LABEL_PREFIX "" - -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - asm_fprintf (FILE, "%L%s", PREFIX) - -/* Globalizing directive for a label. */ -#define GLOBAL_ASM_OP "\t.globl " - -/* This says how to output assembler code to declare an - uninitialized internal linkage data object. Under SVR4, - the linker seems to want the alignment of data objects - to depend on their types. We do exactly that here. */ - -#define LOCAL_ASM_OP "\t.local\t" - -#define LCOMM_ASM_OP "\t.lcomm\t" - -/* Describe how to emit uninitialized local items. */ -#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \ -do { \ - if ((DECL) && rs6000_elf_in_small_data_p (DECL)) \ - { \ - switch_to_section (sbss_section); \ - ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ - ASM_OUTPUT_SKIP (FILE, SIZE); \ - if (!flag_inhibit_size_directive && (SIZE) > 0) \ - ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \ - } \ - else \ - { \ - fprintf (FILE, "%s", LCOMM_ASM_OP); \ - assemble_name ((FILE), (NAME)); \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \ - (SIZE), (ALIGN) / BITS_PER_UNIT); \ - } \ - ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \ -} while (0) - -/* Describe how to emit uninitialized external linkage items. */ -#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ -do { \ - ASM_OUTPUT_ALIGNED_DECL_LOCAL (FILE, DECL, 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. - - On the rs6000, we must keep the backchain up to date. In order - to simplify things, always allocate 16 bytes for a push (System V - wants to keep stack aligned to a 16 byte boundary). */ - -#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \ -do { \ - if (DEFAULT_ABI == ABI_V4) \ - asm_fprintf (FILE, \ - "\tstwu %s,-16(%s)\n\tstw %s,12(%s)\n", \ - reg_names[1], reg_names[1], reg_names[REGNO], \ - reg_names[1]); \ -} while (0) - -/* This is how to output an insn to pop a register from the stack. - It need not be very fast code. */ - -#define ASM_OUTPUT_REG_POP(FILE, REGNO) \ -do { \ - if (DEFAULT_ABI == ABI_V4) \ - asm_fprintf (FILE, \ - "\tlwz %s,12(%s)\n\taddic %s,%s,16\n", \ - reg_names[REGNO], reg_names[1], reg_names[1], \ - reg_names[1]); \ -} while (0) - -extern int fixuplabelno; - -/* Handle constructors specially for -mrelocatable. */ -#define TARGET_ASM_CONSTRUCTOR rs6000_elf_asm_out_constructor -#define TARGET_ASM_DESTRUCTOR rs6000_elf_asm_out_destructor - -/* This is the end of what might become sysv4.h. */ - -/* Use DWARF 2 debugging information by default. */ -#undef PREFERRED_DEBUGGING_TYPE -#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG - -/* Historically we have also supported stabs debugging. */ -#define DBX_DEBUGGING_INFO 1 - -#define TARGET_ENCODE_SECTION_INFO rs6000_elf_encode_section_info -#define TARGET_IN_SMALL_DATA_P rs6000_elf_in_small_data_p - -/* The ELF version doesn't encode [DS] or whatever at the end of symbols. */ - -#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ - assemble_name (FILE, NAME) - -/* We have to output the stabs for the function name *first*, before - outputting its label. */ - -#define DBX_FUNCTION_FIRST - -/* This is the end of what might become sysv4dbx.h. */ - -#define TARGET_OS_SYSV_CPP_BUILTINS() \ - do \ - { \ - if (rs6000_isa_flags_explicit \ - & OPTION_MASK_RELOCATABLE) \ - builtin_define ("_RELOCATABLE"); \ - } \ - while (0) - -#ifndef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define_std ("PPC"); \ - builtin_define_std ("unix"); \ - builtin_define ("__svr4__"); \ - builtin_assert ("system=unix"); \ - builtin_assert ("system=svr4"); \ - builtin_assert ("cpu=powerpc"); \ - builtin_assert ("machine=powerpc"); \ - TARGET_OS_SYSV_CPP_BUILTINS (); \ - } \ - while (0) -#endif - -#undef ASM_SPEC -#define ASM_SPEC "%(asm_cpu) \ -%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ -%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \ -%{memb|msdata=eabi: -memb} \ -%{mlittle|mlittle-endian:-mlittle; \ - mbig|mbig-endian :-mbig; \ - mcall-aixdesc | \ - mcall-freebsd | \ - mcall-netbsd | \ - mcall-openbsd | \ - mcall-linux :-mbig; \ - mcall-i960-old :-mlittle}" - -#define CC1_ENDIAN_BIG_SPEC "" - -#define CC1_ENDIAN_LITTLE_SPEC "\ -%{!mstrict-align: %{!mno-strict-align: \ - %{!mcall-i960-old: \ - -mstrict-align \ - } \ -}}" - -#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big)" - -#ifndef CC1_SECURE_PLT_DEFAULT_SPEC -#define CC1_SECURE_PLT_DEFAULT_SPEC "" -#endif - -/* Pass -G xxx to the compiler and set correct endian mode. */ -#define CC1_SPEC "%{G*} %(cc1_cpu) \ -%{mlittle|mlittle-endian: %(cc1_endian_little); \ - mbig |mbig-endian : %(cc1_endian_big); \ - mcall-aixdesc | \ - mcall-freebsd | \ - mcall-netbsd | \ - mcall-openbsd | \ - mcall-linux : -mbig %(cc1_endian_big); \ - mcall-i960-old : -mlittle %(cc1_endian_little); \ - : %(cc1_endian_default)} \ -%{meabi: %{!mcall-*: -mcall-sysv }} \ -%{!meabi: %{!mno-eabi: \ - %{mrelocatable: -meabi } \ - %{mcall-freebsd: -mno-eabi } \ - %{mcall-i960-old: -meabi } \ - %{mcall-linux: -mno-eabi } \ - %{mcall-netbsd: -mno-eabi } \ - %{mcall-openbsd: -mno-eabi }}} \ -%{msdata: -msdata=default} \ -%{mno-sdata: -msdata=none} \ -%{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \ -%{profile: -p}" - -/* 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) ; \ - mcall-freebsd: %(link_start_freebsd) ; \ - mcall-linux : %(link_start_linux) ; \ - mcall-netbsd : %(link_start_netbsd) ; \ - mcall-openbsd: %(link_start_openbsd) ; \ - : %(link_start_default) }" - -#define LINK_START_DEFAULT_SPEC "" - -#undef LINK_SPEC -#define LINK_SPEC "\ -%{h*} %{v:-V} %{!msdata=none:%{G*}} %{msdata=none:-G0} \ -%{R*} \ -%(link_shlib) \ -%{!T*: %(link_start) } \ -%(link_target) \ -%(link_os)" - -/* Shared libraries are not default. */ -#define LINK_SHLIB_SPEC "\ -%{!mshlib: %{!shared: %{!symbolic: -dn -Bstatic}}} \ -%{static: } \ -%{shared:-G -dy -z text } \ -%{symbolic:-Bsymbolic -G -dy -z text }" - -/* Override the default target of the linker. */ -#define LINK_TARGET_SPEC "\ -%{mlittle: --oformat elf32-powerpcle } %{mlittle-endian: --oformat elf32-powerpcle } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-i960-old: --oformat elf32-powerpcle} \ - }}}}" - -/* Any specific OS flags. */ -#define LINK_OS_SPEC "\ -%{mads : %(link_os_ads) ; \ - myellowknife : %(link_os_yellowknife) ; \ - mmvme : %(link_os_mvme) ; \ - msim : %(link_os_sim) ; \ - mcall-freebsd: %(link_os_freebsd) ; \ - mcall-linux : %(link_os_linux) ; \ - mcall-netbsd : %(link_os_netbsd) ; \ - mcall-openbsd: %(link_os_openbsd) ; \ - : %(link_os_default) }" - -#define LINK_OS_DEFAULT_SPEC "" - -#define DRIVER_SELF_SPECS "%{mfpu=none: %<mfpu=* \ - %<msingle-float %<mdouble-float}" - -/* Override rs6000.h definition. */ -#undef CPP_SPEC -#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ -%{mads : %(cpp_os_ads) ; \ - myellowknife : %(cpp_os_yellowknife) ; \ - mmvme : %(cpp_os_mvme) ; \ - msim : %(cpp_os_sim) ; \ - mcall-freebsd: %(cpp_os_freebsd) ; \ - mcall-linux : %(cpp_os_linux) ; \ - mcall-netbsd : %(cpp_os_netbsd) ; \ - mcall-openbsd: %(cpp_os_openbsd) ; \ - : %(cpp_os_default) }" - -#define CPP_OS_DEFAULT_SPEC "" - -#undef STARTFILE_SPEC -#define STARTFILE_SPEC "\ -%{mads : %(startfile_ads) ; \ - myellowknife : %(startfile_yellowknife) ; \ - mmvme : %(startfile_mvme) ; \ - msim : %(startfile_sim) ; \ - mcall-freebsd: %(startfile_freebsd) ; \ - mcall-linux : %(startfile_linux) ; \ - mcall-netbsd : %(startfile_netbsd) ; \ - mcall-openbsd: %(startfile_openbsd) ; \ - : %(startfile_default) }" - -#define STARTFILE_DEFAULT_SPEC "ecrti.o%s crtbegin.o%s" - -#undef LIB_SPEC -#define LIB_SPEC "\ -%{mads : %(lib_ads) ; \ - myellowknife : %(lib_yellowknife) ; \ - mmvme : %(lib_mvme) ; \ - msim : %(lib_sim) ; \ - mcall-freebsd: %(lib_freebsd) ; \ - mcall-linux : %(lib_linux) ; \ - mcall-netbsd : %(lib_netbsd) ; \ - mcall-openbsd: %(lib_openbsd) ; \ - : %(lib_default) }" - -#define LIB_DEFAULT_SPEC "-lc" - -#undef ENDFILE_SPEC -#define ENDFILE_SPEC "\ -%{mads : %(endfile_ads) ; \ - myellowknife : %(endfile_yellowknife) ; \ - mmvme : %(endfile_mvme) ; \ - msim : %(endfile_sim) ; \ - mcall-freebsd: %(endfile_freebsd) ; \ - mcall-linux : %(endfile_linux) ; \ - mcall-netbsd : %(endfile_netbsd) ; \ - mcall-openbsd: %(endfile_openbsd) ; \ - : %(crtsavres_default) %(endfile_default) }" - -#define CRTSAVRES_DEFAULT_SPEC "" - -#define ENDFILE_DEFAULT_SPEC "crtend.o%s ecrtn.o%s" - -/* Motorola ADS support. */ -#define LIB_ADS_SPEC "--start-group -lads -lc --end-group" - -#define STARTFILE_ADS_SPEC "ecrti.o%s crt0.o%s crtbegin.o%s" - -#define ENDFILE_ADS_SPEC "crtend.o%s ecrtn.o%s" - -#define LINK_START_ADS_SPEC "-T ads.ld%s" - -#define LINK_OS_ADS_SPEC "" - -#define CPP_OS_ADS_SPEC "" - -/* Motorola Yellowknife support. */ -#define LIB_YELLOWKNIFE_SPEC "--start-group -lyk -lc --end-group" - -#define STARTFILE_YELLOWKNIFE_SPEC "ecrti.o%s crt0.o%s crtbegin.o%s" - -#define ENDFILE_YELLOWKNIFE_SPEC "crtend.o%s ecrtn.o%s" - -#define LINK_START_YELLOWKNIFE_SPEC "-T yellowknife.ld%s" - -#define LINK_OS_YELLOWKNIFE_SPEC "" - -#define CPP_OS_YELLOWKNIFE_SPEC "" - -/* Motorola MVME support. */ -#define LIB_MVME_SPEC "--start-group -lmvme -lc --end-group" - -#define STARTFILE_MVME_SPEC "ecrti.o%s crt0.o%s crtbegin.o%s" - -#define ENDFILE_MVME_SPEC "crtend.o%s ecrtn.o%s" - -#define LINK_START_MVME_SPEC "-Ttext 0x40000" - -#define LINK_OS_MVME_SPEC "" - -#define CPP_OS_MVME_SPEC "" - -/* PowerPC simulator based on netbsd system calls support. */ -#define LIB_SIM_SPEC "--start-group -lsim -lc --end-group" - -#define STARTFILE_SIM_SPEC "ecrti.o%s sim-crt0.o%s crtbegin.o%s" - -#define ENDFILE_SIM_SPEC "crtend.o%s ecrtn.o%s" - -#define LINK_START_SIM_SPEC "" - -#define LINK_OS_SIM_SPEC "-m elf32ppcsim" - -#define CPP_OS_SIM_SPEC "" - -/* FreeBSD support. */ - -#define CPP_OS_FREEBSD_SPEC "\ - -D__PPC__ -D__ppc__ -D__PowerPC__ -D__powerpc__ \ - -Acpu=powerpc -Amachine=powerpc" - -#define STARTFILE_FREEBSD_SPEC FBSD_STARTFILE_SPEC -#define ENDFILE_FREEBSD_SPEC FBSD_ENDFILE_SPEC -#define LIB_FREEBSD_SPEC FBSD_LIB_SPEC -#define LINK_START_FREEBSD_SPEC "" - -#define LINK_OS_FREEBSD_SPEC "\ - %{p:%nconsider using '-pg' instead of '-p' with gprof(1)} \ - %{v:-V} \ - %{assert*} %{R*} %{rpath*} %{defsym*} \ - %{shared:-Bshareable %{h*} %{soname*}} \ - %{!shared: \ - %{!static: \ - %{rdynamic: -export-dynamic} \ - -dynamic-linker %(fbsd_dynamic_linker) } \ - %{static:-Bstatic}} \ - %{symbolic:-Bsymbolic}" - -/* GNU/Linux support. */ -#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \ -%{!mnewlib: %{pthread:-lpthread} %{shared:-lc} \ -%{!shared: %{profile:-lc_p} %{!profile:-lc}}}" - -#ifdef HAVE_LD_PIE -#define STARTFILE_LINUX_SPEC "\ -%{!shared: %{pg|p|profile: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|p|profile: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|pie:crtendS.o%s;:crtend.o%s} \ -%{mnewlib:ecrtn.o%s;:crtn.o%s}" - -#define LINK_START_LINUX_SPEC "" - -#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1" -#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" -#if DEFAULT_LIBC == LIBC_UCLIBC -#define CHOOSE_DYNAMIC_LINKER(G, U) "%{mglibc:" G ";:" U "}" -#elif !defined (DEFAULT_LIBC) || DEFAULT_LIBC == LIBC_GLIBC -#define CHOOSE_DYNAMIC_LINKER(G, U) "%{muclibc:" U ";:" G "}" -#else -#error "Unsupported DEFAULT_LIBC" -#endif -#define GNU_USER_DYNAMIC_LINKER \ - CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER) - -#define LINK_OS_LINUX_SPEC "-m elf32ppclinux %{!shared: %{!static: \ - %{rdynamic:-export-dynamic} \ - -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}" - -#if defined(HAVE_LD_EH_FRAME_HDR) -# define LINK_EH_SPEC "%{!static:--eh-frame-hdr} " -#endif - -#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=linux -Asystem=unix -Asystem=posix %{pthread:-D_REENTRANT}" - -/* NetBSD support. */ -#define LIB_NETBSD_SPEC "\ --lc" - -#define STARTFILE_NETBSD_SPEC "\ -ncrti.o%s crt0.o%s \ -%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" - -#define ENDFILE_NETBSD_SPEC "\ -%{!shared:crtend.o%s} %{shared:crtendS.o%s} \ -ncrtn.o%s" - -#define LINK_START_NETBSD_SPEC "\ -" - -#define LINK_OS_NETBSD_SPEC "\ -%{!shared: %{!static: \ - %{rdynamic:-export-dynamic} \ - -dynamic-linker /usr/libexec/ld.elf_so}}" - -#define CPP_OS_NETBSD_SPEC "\ --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 - -/* Define any extra SPECS that the compiler needs to generate. */ -/* Override rs6000.h definition. */ -#undef SUBTARGET_EXTRA_SPECS -#define SUBTARGET_EXTRA_SPECS \ - { "crtsavres_default", CRTSAVRES_DEFAULT_SPEC }, \ - { "lib_ads", LIB_ADS_SPEC }, \ - { "lib_yellowknife", LIB_YELLOWKNIFE_SPEC }, \ - { "lib_mvme", LIB_MVME_SPEC }, \ - { "lib_sim", LIB_SIM_SPEC }, \ - { "lib_freebsd", LIB_FREEBSD_SPEC }, \ - { "lib_linux", LIB_LINUX_SPEC }, \ - { "lib_netbsd", LIB_NETBSD_SPEC }, \ - { "lib_openbsd", LIB_OPENBSD_SPEC }, \ - { "lib_default", LIB_DEFAULT_SPEC }, \ - { "startfile_ads", STARTFILE_ADS_SPEC }, \ - { "startfile_yellowknife", STARTFILE_YELLOWKNIFE_SPEC }, \ - { "startfile_mvme", STARTFILE_MVME_SPEC }, \ - { "startfile_sim", STARTFILE_SIM_SPEC }, \ - { "startfile_freebsd", STARTFILE_FREEBSD_SPEC }, \ - { "startfile_linux", STARTFILE_LINUX_SPEC }, \ - { "startfile_netbsd", STARTFILE_NETBSD_SPEC }, \ - { "startfile_openbsd", STARTFILE_OPENBSD_SPEC }, \ - { "startfile_default", STARTFILE_DEFAULT_SPEC }, \ - { "endfile_ads", ENDFILE_ADS_SPEC }, \ - { "endfile_yellowknife", ENDFILE_YELLOWKNIFE_SPEC }, \ - { "endfile_mvme", ENDFILE_MVME_SPEC }, \ - { "endfile_sim", ENDFILE_SIM_SPEC }, \ - { "endfile_freebsd", ENDFILE_FREEBSD_SPEC }, \ - { "endfile_linux", ENDFILE_LINUX_SPEC }, \ - { "endfile_netbsd", ENDFILE_NETBSD_SPEC }, \ - { "endfile_openbsd", ENDFILE_OPENBSD_SPEC }, \ - { "endfile_default", ENDFILE_DEFAULT_SPEC }, \ - { "link_shlib", LINK_SHLIB_SPEC }, \ - { "link_target", LINK_TARGET_SPEC }, \ - { "link_start", LINK_START_SPEC }, \ - { "link_start_ads", LINK_START_ADS_SPEC }, \ - { "link_start_yellowknife", LINK_START_YELLOWKNIFE_SPEC }, \ - { "link_start_mvme", LINK_START_MVME_SPEC }, \ - { "link_start_sim", LINK_START_SIM_SPEC }, \ - { "link_start_freebsd", LINK_START_FREEBSD_SPEC }, \ - { "link_start_linux", LINK_START_LINUX_SPEC }, \ - { "link_start_netbsd", LINK_START_NETBSD_SPEC }, \ - { "link_start_openbsd", LINK_START_OPENBSD_SPEC }, \ - { "link_start_default", LINK_START_DEFAULT_SPEC }, \ - { "link_os", LINK_OS_SPEC }, \ - { "link_os_ads", LINK_OS_ADS_SPEC }, \ - { "link_os_yellowknife", LINK_OS_YELLOWKNIFE_SPEC }, \ - { "link_os_mvme", LINK_OS_MVME_SPEC }, \ - { "link_os_sim", LINK_OS_SIM_SPEC }, \ - { "link_os_freebsd", LINK_OS_FREEBSD_SPEC }, \ - { "link_os_linux", LINK_OS_LINUX_SPEC }, \ - { "link_os_netbsd", LINK_OS_NETBSD_SPEC }, \ - { "link_os_openbsd", LINK_OS_OPENBSD_SPEC }, \ - { "link_os_default", LINK_OS_DEFAULT_SPEC }, \ - { "cc1_endian_big", CC1_ENDIAN_BIG_SPEC }, \ - { "cc1_endian_little", CC1_ENDIAN_LITTLE_SPEC }, \ - { "cc1_endian_default", CC1_ENDIAN_DEFAULT_SPEC }, \ - { "cc1_secure_plt_default", CC1_SECURE_PLT_DEFAULT_SPEC }, \ - { "cpp_os_ads", CPP_OS_ADS_SPEC }, \ - { "cpp_os_yellowknife", CPP_OS_YELLOWKNIFE_SPEC }, \ - { "cpp_os_mvme", CPP_OS_MVME_SPEC }, \ - { "cpp_os_sim", CPP_OS_SIM_SPEC }, \ - { "cpp_os_freebsd", CPP_OS_FREEBSD_SPEC }, \ - { "cpp_os_linux", CPP_OS_LINUX_SPEC }, \ - { "cpp_os_netbsd", CPP_OS_NETBSD_SPEC }, \ - { "cpp_os_openbsd", CPP_OS_OPENBSD_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 - 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::. */ - -#define MULTILIB_DEFAULTS { "mbig", "mcall-sysv" } - -/* Define this macro if the code for function profiling should come - before the function prologue. Normally, the profiling code comes - after. */ -#define PROFILE_BEFORE_PROLOGUE 1 - -/* Function name to call to do profiling. */ -#define RS6000_MCOUNT "_mcount" - -/* 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. */ -#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \ - ((flag_pic || TARGET_RELOCATABLE) \ - ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \ - : DW_EH_PE_absptr) - -#define DOUBLE_INT_ASM_OP "\t.quad\t" - -/* Generate entries in .fixup for relocatable addresses. */ -#define RELOCATABLE_NEEDS_FIXUP 1 - -#define TARGET_ASM_FILE_END rs6000_elf_file_end - -#undef TARGET_ASAN_SHADOW_OFFSET -#define TARGET_ASAN_SHADOW_OFFSET rs6000_asan_shadow_offset - -/* This target uses the sysv4.opt file. */ -#define TARGET_USES_SYSV4_OPT 1 - -#undef DBX_REGISTER_NUMBER diff --git a/gcc-4.8.1/gcc/config/rs6000/sysv4.opt b/gcc-4.8.1/gcc/config/rs6000/sysv4.opt deleted file mode 100644 index 55b7a4333..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/sysv4.opt +++ /dev/null @@ -1,157 +0,0 @@ -; SYSV4 options for PPC port. -; -; Copyright (C) 2005-2013 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 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -; License for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -mcall- -Target RejectNegative Joined Var(rs6000_abi_name) -Select ABI calling convention - -msdata= -Target RejectNegative Joined Var(rs6000_sdata_name) -Select method for sdata handling - -mtls-size= -Target RejectNegative Joined Var(rs6000_tls_size) Enum(rs6000_tls_size) -Specify bit size of immediate TLS offsets - -Enum -Name(rs6000_tls_size) Type(int) - -EnumValue -Enum(rs6000_tls_size) String(16) Value(16) - -EnumValue -Enum(rs6000_tls_size) String(32) Value(32) - -EnumValue -Enum(rs6000_tls_size) String(64) Value(64) - -mbit-align -Target Report Var(TARGET_NO_BITFIELD_TYPE) Save -Align to the base type of the bit-field - -mstrict-align -Target Report Mask(STRICT_ALIGN) Var(rs6000_isa_flags) -Align to the base type of the bit-field -Don't assume that unaligned accesses are handled by the system - -mrelocatable -Target Report Mask(RELOCATABLE) Var(rs6000_isa_flags) -Produce code relocatable at runtime - -mrelocatable-lib -Target -Produce code relocatable at runtime - -mlittle-endian -Target Report RejectNegative Mask(LITTLE_ENDIAN) Var(rs6000_isa_flags) -Produce little endian code - -mlittle -Target Report RejectNegative Mask(LITTLE_ENDIAN) Var(rs6000_isa_flags) -Produce little endian code - -mbig-endian -Target Report RejectNegative InverseMask(LITTLE_ENDIAN) Var(rs6000_isa_flags) -Produce big endian code - -mbig -Target Report RejectNegative InverseMask(LITTLE_ENDIAN) Var(rs6000_isa_flags) -Produce big endian code - -;; FIXME: This does nothing. What should be done? -mno-toc -Target RejectNegative -no description yet - -mtoc -Target RejectNegative -no description yet - -mprototype -Target Var(target_prototype) Save -Assume all variable arg functions are prototyped - -;; FIXME: Does nothing. -mno-traceback -Target RejectNegative -no description yet - -meabi -Target Report Mask(EABI) Var(rs6000_isa_flags) -Use EABI - -mbit-word -Target Report Var(TARGET_NO_BITFIELD_WORD) Save -Allow bit-fields to cross word boundaries - -mregnames -Target Var(rs6000_regnames) Save -Use alternate register names - -;; This option does nothing and only exists because the compiler -;; driver passes all -m* options through. -msdata -Target -Use default method for sdata handling - -msim -Target RejectNegative -Link with libsim.a, libc.a and sim-crt0.o - -mads -Target RejectNegative -Link with libads.a, libc.a and crt0.o - -myellowknife -Target RejectNegative -Link with libyk.a, libc.a and crt0.o - -mmvme -Target RejectNegative -Link with libmvme.a, libc.a and crt0.o - -memb -Target RejectNegative -Set the PPC_EMB bit in the ELF flags header - -mshlib -Target RejectNegative -no description yet - -m64 -Target Report RejectNegative Negative(m32) Mask(64BIT) Var(rs6000_isa_flags) -Generate 64-bit code - -m32 -Target Report RejectNegative Negative(m64) InverseMask(64BIT) Var(rs6000_isa_flags) -Generate 32-bit code - -mnewlib -Target RejectNegative -no description yet - -msecure-plt -Target Report RejectNegative Var(secure_plt, 1) Save -Generate code to use a non-exec PLT and GOT - -mbss-plt -Target Report RejectNegative Var(secure_plt, 0) Save -Generate code for old exec BSS PLT diff --git a/gcc-4.8.1/gcc/config/rs6000/sysv4le.h b/gcc-4.8.1/gcc/config/rs6000/sysv4le.h deleted file mode 100644 index 40ab10a30..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/sysv4le.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Target definitions for GCC for a little endian PowerPC - running System V.4 - Copyright (C) 1995-2013 Free Software Foundation, Inc. - Contributed by Cygnus Support. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT MASK_LITTLE_ENDIAN - -#undef CC1_ENDIAN_DEFAULT_SPEC -#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_little)" - -#undef LINK_TARGET_SPEC -#define LINK_TARGET_SPEC "\ -%{mbig: --oformat elf32-powerpc } %{mbig-endian: --oformat elf32-powerpc } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-linux: --oformat elf32-powerpc} \ - }}}}" - -#undef MULTILIB_DEFAULTS -#define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" } diff --git a/gcc-4.8.1/gcc/config/rs6000/t-aix43 b/gcc-4.8.1/gcc/config/rs6000/t-aix43 deleted file mode 100644 index 1f4955cd2..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-aix43 +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 1998-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# Build the libraries for pthread and all of the -# different processor models - -MULTILIB_OPTIONS = pthread \ - mcpu=common/mcpu=powerpc/maix64 - -MULTILIB_DIRNAMES = pthread \ - common powerpc ppc64 - -MULTILIB_MATCHES = mcpu?powerpc=mcpu?power3 \ - mcpu?powerpc=mcpu?power4 \ - mcpu?powerpc=mcpu?powerpc \ - mcpu?powerpc=mcpu?rs64a \ - mcpu?powerpc=mcpu?601 \ - mcpu?powerpc=mcpu?602 \ - mcpu?powerpc=mcpu?603 \ - mcpu?powerpc=mcpu?603e \ - mcpu?powerpc=mcpu?604 \ - mcpu?powerpc=mcpu?604e \ - mcpu?powerpc=mcpu?620 \ - mcpu?powerpc=mcpu?630 diff --git a/gcc-4.8.1/gcc/config/rs6000/t-aix52 b/gcc-4.8.1/gcc/config/rs6000/t-aix52 deleted file mode 100644 index 2ce2fdd68..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-aix52 +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# Build the libraries for pthread and all of the -# different processor models - -MULTILIB_OPTIONS = pthread maix64 - -MULTILIB_DIRNAMES = pthread ppc64 - -MULTILIB_MATCHES = diff --git a/gcc-4.8.1/gcc/config/rs6000/t-darwin64 b/gcc-4.8.1/gcc/config/rs6000/t-darwin64 deleted file mode 100644 index b0a04c7d8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-darwin64 +++ /dev/null @@ -1,2 +0,0 @@ -MULTILIB_OPTIONS = m32 -MULTILIB_DIRNAMES = ppc diff --git a/gcc-4.8.1/gcc/config/rs6000/t-darwin8 b/gcc-4.8.1/gcc/config/rs6000/t-darwin8 deleted file mode 100644 index 2f3bb32f8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-darwin8 +++ /dev/null @@ -1,3 +0,0 @@ -# 64-bit libraries can only be built in Darwin 8.x or later. -MULTILIB_OPTIONS = m64 -MULTILIB_DIRNAMES = ppc64 diff --git a/gcc-4.8.1/gcc/config/rs6000/t-fprules b/gcc-4.8.1/gcc/config/rs6000/t-fprules deleted file mode 100644 index 2ae04da27..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-fprules +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -SOFT_FLOAT_CPUS = e300c2 401 403 405 440 464 476 ec603e 801 821 823 860 -MULTILIB_MATCHES_FLOAT = $(foreach cpu, $(SOFT_FLOAT_CPUS), msoft-float=mcpu?$(cpu)) - -# 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} diff --git a/gcc-4.8.1/gcc/config/rs6000/t-freebsd64 b/gcc-4.8.1/gcc/config/rs6000/t-freebsd64 deleted file mode 100644 index ef26892b8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-freebsd64 +++ /dev/null @@ -1,31 +0,0 @@ -#rs6000/t-freebsd64 - -# Copyright (C) 2012-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# On FreeBSD the 32-bit libraries are found under /usr/lib32. -# Set MULTILIB_OSDIRNAMES according to this. - -MULTILIB_OPTIONS = m32 msoft-float -MULTILIB_DIRNAMES = 32 nof -MULTILIB_EXTRA_OPTS = fPIC mstrict-align -MULTILIB_EXCEPTIONS = -MULTILIB_EXCLUSIONS = !m32/msoft-float -MULTILIB_OSDIRNAMES = ../lib32 -#MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) - diff --git a/gcc-4.8.1/gcc/config/rs6000/t-linux b/gcc-4.8.1/gcc/config/rs6000/t-linux deleted file mode 100644 index 017a293cd..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-linux +++ /dev/null @@ -1,9 +0,0 @@ -# do not define the multiarch name if configured for a soft-float cpu -# or soft-float. -ifeq (,$(filter $(with_cpu),$(SOFT_FLOAT_CPUS))$(findstring soft,$(with_float))) -ifneq (,$(findstring spe,$(target))) -MULTIARCH_DIRNAME = powerpc-linux-gnuspe$(if $(findstring rs6000/e500-double.h, $(tm_file_list)),,v1) -else -MULTIARCH_DIRNAME = powerpc-linux-gnu -endif -endif diff --git a/gcc-4.8.1/gcc/config/rs6000/t-linux64 b/gcc-4.8.1/gcc/config/rs6000/t-linux64 deleted file mode 100644 index 9175de2ff..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-linux64 +++ /dev/null @@ -1,32 +0,0 @@ -#rs6000/t-linux64 - -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# On Debian, Ubuntu and other derivative distributions, the 32bit libraries -# are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to -# /lib and /usr/lib, while other distributions install libraries into /lib64 -# and /usr/lib64. The LSB does not enforce the use of /lib64 and /usr/lib64, -# it doesn't tell anything about the 32bit libraries on those systems. Set -# MULTILIB_OSDIRNAMES according to what is found on the target. - -MULTILIB_OPTIONS = m64/m32 -MULTILIB_DIRNAMES = 64 32 -MULTILIB_EXTRA_OPTS = fPIC -MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:powerpc64-linux-gnu) -MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) diff --git a/gcc-4.8.1/gcc/config/rs6000/t-lynx b/gcc-4.8.1/gcc/config/rs6000/t-lynx deleted file mode 100644 index 98dc3cd28..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-lynx +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 2004-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -MULTILIB_OPTIONS += msoft-float -MULTILIB_DIRNAMES += soft-float - -MULTILIB_OPTIONS += maltivec -MULTILIB_DIRNAMES += altivec - -MULTILIB_EXCEPTIONS = *msoft-float/*maltivec* - -Local Variables: -mode: makefile -End: diff --git a/gcc-4.8.1/gcc/config/rs6000/t-netbsd b/gcc-4.8.1/gcc/config/rs6000/t-netbsd deleted file mode 100644 index 001257c07..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-netbsd +++ /dev/null @@ -1,36 +0,0 @@ -# Support for NetBSD PowerPC ELF targets (SVR4 ABI). -# -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# 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_OPTIONS = msoft-float -MULTILIB_DIRNAMES = soft-float -MULTILIB_EXTRA_OPTS = fPIC mstrict-align -MULTILIB_EXCEPTIONS = - -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} diff --git a/gcc-4.8.1/gcc/config/rs6000/t-ppccomm b/gcc-4.8.1/gcc/config/rs6000/t-ppccomm deleted file mode 100644 index a2274bc8b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-ppccomm +++ /dev/null @@ -1,23 +0,0 @@ -# Common support for PowerPC ELF targets (both EABI and SVR4). -# -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# Switch synonyms -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 diff --git a/gcc-4.8.1/gcc/config/rs6000/t-ppcendian b/gcc-4.8.1/gcc/config/rs6000/t-ppcendian deleted file mode 100644 index 051014c56..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-ppcendian +++ /dev/null @@ -1,30 +0,0 @@ -# Multilibs for powerpc embedded ELF targets with altivec. -# -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -MULTILIB_OPTIONS = msoft-float \ - mlittle/mbig - -MULTILIB_DIRNAMES = nof \ - le be - - -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \ - ${MULTILIB_MATCHES_ENDIAN} \ - ${MULTILIB_MATCHES_SYSV} diff --git a/gcc-4.8.1/gcc/config/rs6000/t-ppcgas b/gcc-4.8.1/gcc/config/rs6000/t-ppcgas deleted file mode 100644 index d1c219b1c..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-ppcgas +++ /dev/null @@ -1,32 +0,0 @@ -# Multilibs for powerpc embedded ELF targets. -# -# Copyright (C) 1995-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -MULTILIB_OPTIONS = msoft-float \ - mlittle/mbig \ - fleading-underscore - -MULTILIB_DIRNAMES = nof \ - le be \ - und - -MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align - -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \ - ${MULTILIB_MATCHES_ENDIAN} diff --git a/gcc-4.8.1/gcc/config/rs6000/t-ppcos b/gcc-4.8.1/gcc/config/rs6000/t-ppcos deleted file mode 100644 index 819863bea..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-ppcos +++ /dev/null @@ -1,8 +0,0 @@ -# Multilibs for a powerpc hosted ELF target (linux, SVR4) - -MULTILIB_OPTIONS = msoft-float -MULTILIB_DIRNAMES = nof -MULTILIB_EXTRA_OPTS = fPIC mstrict-align -MULTILIB_EXCEPTIONS = - -MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} diff --git a/gcc-4.8.1/gcc/config/rs6000/t-rs6000 b/gcc-4.8.1/gcc/config/rs6000/t-rs6000 deleted file mode 100644 index 52c183915..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-rs6000 +++ /dev/null @@ -1,75 +0,0 @@ -# General rules that all rs6000/ targets must have. -# -# Copyright (C) 1995-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -TM_H += $(srcdir)/config/rs6000/rs6000-builtin.def - -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 dbxout.h $(BASIC_BLOCK_H) toplev.h $(GGC_H) $(HASHTAB_H) \ - $(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h gt-rs6000.h \ - cfgloop.h $(OPTS_H) $(COMMON_TARGET_H) dumpfile.h \ - $(srcdir)/config/rs6000/rs6000-cpus.def - -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) - $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(srcdir)/config/rs6000/rs6000-c.c - -$(srcdir)/config/rs6000/rs6000-tables.opt: $(srcdir)/config/rs6000/genopt.sh \ - $(srcdir)/config/rs6000/rs6000-cpus.def - $(SHELL) $(srcdir)/config/rs6000/genopt.sh $(srcdir)/config/rs6000 > \ - $(srcdir)/config/rs6000/rs6000-tables.opt - -# The rs6000 backend doesn't cause warnings in these files. -insn-conditions.o-warn = - -MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \ - $(srcdir)/config/rs6000/mpc.md \ - $(srcdir)/config/rs6000/40x.md \ - $(srcdir)/config/rs6000/440.md \ - $(srcdir)/config/rs6000/601.md \ - $(srcdir)/config/rs6000/603.md \ - $(srcdir)/config/rs6000/6xx.md \ - $(srcdir)/config/rs6000/7xx.md \ - $(srcdir)/config/rs6000/7450.md \ - $(srcdir)/config/rs6000/8540.md \ - $(srcdir)/config/rs6000/e300c2c3.md \ - $(srcdir)/config/rs6000/e500mc.md \ - $(srcdir)/config/rs6000/power4.md \ - $(srcdir)/config/rs6000/power5.md \ - $(srcdir)/config/rs6000/power6.md \ - $(srcdir)/config/rs6000/power7.md \ - $(srcdir)/config/rs6000/cell.md \ - $(srcdir)/config/rs6000/xfpu.md \ - $(srcdir)/config/rs6000/a2.md \ - $(srcdir)/config/rs6000/predicates.md \ - $(srcdir)/config/rs6000/constraints.md \ - $(srcdir)/config/rs6000/darwin.md \ - $(srcdir)/config/rs6000/sync.md \ - $(srcdir)/config/rs6000/vector.md \ - $(srcdir)/config/rs6000/vsx.md \ - $(srcdir)/config/rs6000/altivec.md \ - $(srcdir)/config/rs6000/spe.md \ - $(srcdir)/config/rs6000/dfp.md \ - $(srcdir)/config/rs6000/paired.md diff --git a/gcc-4.8.1/gcc/config/rs6000/t-rtems b/gcc-4.8.1/gcc/config/rs6000/t-rtems deleted file mode 100644 index e840bbcc3..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-rtems +++ /dev/null @@ -1,88 +0,0 @@ -# Multilibs for powerpc RTEMS targets. -# -# Copyright (C) 2004-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -MULTILIB_OPTIONS = \ -mcpu=403/mcpu=505/mcpu=603e/mcpu=604/mcpu=860/mcpu=7400/mcpu=8540 \ -msoft-float/mfloat-gprs=double - -MULTILIB_DIRNAMES = \ -m403 m505 m603e m604 m860 m7400 m8540 \ -nof gprsdouble - -# MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} -MULTILIB_MATCHES = -MULTILIB_MATCHES += ${MULTILIB_MATCHES_ENDIAN} -MULTILIB_MATCHES += ${MULTILIB_MATCHES_SYSV} -# Map 405 to 403 -MULTILIB_MATCHES += mcpu?403=mcpu?405 -# Map 602, 603e, 603 to 603e -MULTILIB_MATCHES += mcpu?603e=mcpu?602 -MULTILIB_MATCHES += mcpu?603e=mcpu?603 -# Map 801, 821, 823 to 860 -MULTILIB_MATCHES += mcpu?860=mcpu?801 -MULTILIB_MATCHES += mcpu?860=mcpu?821 -MULTILIB_MATCHES += mcpu?860=mcpu?823 -# Map 7450 to 7400 -MULTILIB_MATCHES += mcpu?7400=mcpu?7450 - -# Map 750 to . -MULTILIB_MATCHES += mcpu?750= - -# Map 8548 to 8540 -MULTILIB_MATCHES += mcpu?8540=mcpu?8548 - -# Map -mcpu=8540 -mfloat-gprs=single to -mcpu=8540 -# (mfloat-gprs=single is implicit default) -MULTILIB_MATCHES += mcpu?8540=mcpu?8540/mfloat-gprs?single - -# Soft-float only, default implies msoft-float -# NOTE: Must match with MULTILIB_MATCHES_FLOAT and MULTILIB_MATCHES -MULTILIB_SOFTFLOAT_ONLY = \ -*mcpu=401/*msoft-float* \ -*mcpu=403/*msoft-float* \ -*mcpu=405/*msoft-float* \ -*mcpu=801/*msoft-float* \ -*mcpu=821/*msoft-float* \ -*mcpu=823/*msoft-float* \ -*mcpu=860/*msoft-float* - -# Hard-float only, take out msoft-float -MULTILIB_HARDFLOAT_ONLY = \ -*mcpu=505/*msoft-float* - -# Targets which do not support gprs -MULTILIB_NOGPRS = \ -mfloat-gprs=* \ -*mcpu=403/*mfloat-gprs=* \ -*mcpu=505/*mfloat-gprs=* \ -*mcpu=603e/*mfloat-gprs=* \ -*mcpu=604/*mfloat-gprs=* \ -*mcpu=860/*mfloat-gprs=* \ -*mcpu=7400/*mfloat-gprs=* - -MULTILIB_EXCEPTIONS = - -# Disallow -Dppc and -Dmpc without other options -MULTILIB_EXCEPTIONS += Dppc* Dmpc* - -MULTILIB_EXCEPTIONS += \ -${MULTILIB_SOFTFLOAT_ONLY} \ -${MULTILIB_HARDFLOAT_ONLY} \ -${MULTILIB_NOGPRS} diff --git a/gcc-4.8.1/gcc/config/rs6000/t-spe b/gcc-4.8.1/gcc/config/rs6000/t-spe deleted file mode 100644 index 8dd3bb96e..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-spe +++ /dev/null @@ -1,73 +0,0 @@ -# Multilibs for e500 -# -# Copyright (C) 2003-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# What we really want are these variants: -# -mcpu=7400 -# -mcpu=7400 -maltivec -mabi=altivec -# -mcpu=7400 -msoft-float -# -msoft-float -# -mno-spe -mabi=no-spe -mno-isel -# so we'll need to create exceptions later below. - -MULTILIB_OPTIONS = mcpu=7400 \ - maltivec \ - mabi=altivec \ - msoft-float \ - mno-spe \ - mabi=no-spe \ - mno-isel \ - mlittle - -MULTILIB_DIRNAMES = mpc7400 altivec abi-altivec \ - nof no-spe no-abi-spe no-isel le - -MULTILIB_EXCEPTIONS = maltivec mabi=altivec mno-spe mabi=no-spe mno-isel \ - maltivec/mabi=altivec \ - mcpu=7400/maltivec \ - mcpu=7400/mabi=altivec \ - *mcpu=7400/*mno-spe* \ - *mcpu=7400/*mabi=no-spe* \ - *mcpu=7400/*mno-isel* \ - *maltivec/*msoft-float* \ - *maltivec/*mno-spe* \ - *maltivec/*mabi=no-spe* \ - *maltivec/*mno-isel* \ - *mabi=altivec/*msoft-float* \ - *mabi=altivec/*mno-spe* \ - *mabi=altivec/*mabi=no-spe* \ - *mabi=altivec/*mno-isel* \ - *msoft-float/*mno-spe* \ - *msoft-float/*mabi=no-spe* \ - *msoft-float/*mno-isel* \ - mno-spe/mabi=no-spe \ - mno-spe/mno-isel \ - mabi=no-spe/mno-isel \ - mno-isel/mlittle \ - mabi=no-spe/mno-isel/mlittle \ - mno-spe/mlittle \ - mabi=spe/mlittle \ - mcpu=7400/mabi=altivec/mlittle \ - mcpu=7400/maltivec/mlittle \ - mabi=no-spe/mlittle \ - mno-spe/mno-isel/mlittle \ - mno-spe/mabi=no-spe/mlittle \ - mabi=altivec/mlittle \ - maltivec/mlittle \ - maltivec/mabi=altivec/mlittle diff --git a/gcc-4.8.1/gcc/config/rs6000/t-vxworks b/gcc-4.8.1/gcc/config/rs6000/t-vxworks deleted file mode 100644 index 1899dff6c..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-vxworks +++ /dev/null @@ -1,25 +0,0 @@ -# Multilibs for VxWorks. -# -# Copyright (C) 2002-2013 Free Software Foundation, Inc. -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# The base multilib is -mhard-float. -MULTILIB_OPTIONS = mrtp fPIC msoft-float -MULTILIB_DIRNAMES = -MULTILIB_MATCHES = fPIC=fpic -MULTILIB_EXCEPTIONS = fPIC* diff --git a/gcc-4.8.1/gcc/config/rs6000/t-vxworksae b/gcc-4.8.1/gcc/config/rs6000/t-vxworksae deleted file mode 100644 index 5f682627e..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-vxworksae +++ /dev/null @@ -1,5 +0,0 @@ -# Multilibs for VxWorks AE. - -MULTILIB_OPTIONS = mvthreads msoft-float -MULTILIB_MATCHES = -MULTILIB_EXCEPTIONS = diff --git a/gcc-4.8.1/gcc/config/rs6000/t-xilinx b/gcc-4.8.1/gcc/config/rs6000/t-xilinx deleted file mode 100644 index 2abb333d5..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/t-xilinx +++ /dev/null @@ -1,56 +0,0 @@ -# Multilibs for Xilinx powerpc embedded ELF targets. -# -# Copyright (C) 2009-2013 Free Software Foundation, Inc. -# Contributed by Michael Eager, eager@eagercon.com -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# Switch synonyms -MULTILIB_MATCHES = mfpu?sp_lite=msingle-float mfpu?dp_lite=mdouble-float mfpu?dp_lite=mhard-float mfpu?sp_lite=mfpu?sp_full mfpu?dp_lite=mfpu?dp_full - -MULTILIB_OPTIONS = mfpu=sp_lite/mfpu=dp_lite - -MULTILIB_DIRNAMES = single double - -# Multilibs for Xilinx powerpc embedded ELF targets. -# -# Copyright (C) 2009-2013 Free Software Foundation, Inc. -# Contributed by Michael Eager, eager@eagercon.com -# -# This file is part of GCC. -# -# GCC is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GCC is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GCC; see the file COPYING3. If not see -# <http://www.gnu.org/licenses/>. - -# Switch synonyms -MULTILIB_MATCHES = mfpu?sp_lite=msingle-float mfpu?dp_lite=mdouble-float mfpu?dp_lite=mhard-float mfpu?sp_lite=mfpu?sp_full mfpu?dp_lite=mfpu?dp_full - -MULTILIB_OPTIONS = mfpu=sp_lite/mfpu=dp_lite - -MULTILIB_DIRNAMES = single double - diff --git a/gcc-4.8.1/gcc/config/rs6000/titan.md b/gcc-4.8.1/gcc/config/rs6000/titan.md deleted file mode 100644 index 138b712b8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/titan.md +++ /dev/null @@ -1,169 +0,0 @@ -;; Pipeline description for the AppliedMicro Titan core. -;; Copyright (C) 2010-2013 Free Software Foundation, Inc. -;; Contributed by Theobroma Systems Design und Consulting GmbH -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. -;; -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; AppliedMicro Titan core complex - -(define_automaton "titan_core,titan_fpu,titan_fxu,titan_bpu,titan_lsu") -(define_cpu_unit "titan_issue_0,titan_issue_1" "titan_core") - -;; Some useful abbreviations. -(define_reservation "titan_issue" "titan_issue_0|titan_issue_1") - -;; === FXU scheduling === - -(define_cpu_unit "titan_fxu_sh,titan_fxu_wb" "titan_fxu") - -;; The 1-cycle adder executes add, addi, subf, neg, compare and trap -;; instructions. It provides its own, dedicated result-bus, so we -;; don't need the titan_fxu_wb reservation to complete. -(define_insn_reservation "titan_fxu_adder" 1 - (and (eq_attr "type" "cmp,fast_compare,trap") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fxu_sh") - -;; Keep the titan_imul and titan_mulhw (half-word) rules in order, to -;; ensure the proper match: the half-word instructions are tagged as -;; imul3 only, whereas regular multiplys will always carry a imul tag. - -(define_insn_reservation "titan_imul" 5 - (and (eq_attr "type" "imul,imul2,imul_compare") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fxu_sh,nothing*5,titan_fxu_wb") - -(define_insn_reservation "titan_mulhw" 4 - (and (eq_attr "type" "imul3") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fxu_sh,nothing*4,titan_fxu_wb") - -(define_bypass 2 "titan_mulhw" "titan_mulhw") - -(define_insn_reservation "titan_fxu_shift_and_rotate" 2 - (and (eq_attr "type" "insert_word,shift,var_shift_rotate,cntlz") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fxu_sh,nothing*2,titan_fxu_wb") - -;; We model the divider for the worst-case (i.e. a full 32-bit -;; divide). To model the bypass for byte-wise completion, a -;; define_bypass with a guard-function could be used... however, this -;; would be an optimization of doubtful value, as a large number of -;; divides will operate on 32-bit variables. - -;; To avoid an unmanagably large automata (generating the automata -;; would require well over 2GB in memory), we don't model the shared -;; result bus on this one. The divider-pipeline is thus modeled -;; through its latency and initial disptach bottlenecks (i.e. issue -;; slots and fxu scheduler availability) -(define_insn_reservation "titan_fxu_div" 34 - (and (eq_attr "type" "idiv") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fxu_sh") - -(define_insn_reservation "titan_fxu_alu" 1 - (and (eq_attr "type" "integer,exts") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fxu_sh,nothing,titan_fxu_wb") - -;; === BPU scheduling === - -(define_cpu_unit "titan_bpu_sh" "titan_bpu") - -(define_insn_reservation "titan_bpu" 2 - (and (eq_attr "type" "branch,jmpreg,cr_logical,delayed_cr") - (eq_attr "cpu" "titan")) - "titan_issue,titan_bpu_sh") - -;; === LSU scheduling === - -(define_cpu_unit "titan_lsu_sh" "titan_lsu") - -;; Loads. -(define_insn_reservation "titan_lsu_load" 3 - (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\ - load_l,sync") - (eq_attr "cpu" "titan")) - "titan_issue,titan_lsu_sh") - -(define_insn_reservation "titan_lsu_fpload" 12 - (and (eq_attr "type" "fpload,fpload_ux,fpload_u") - (eq_attr "cpu" "titan")) - "titan_issue,titan_lsu_sh") - -;; Note that the isync is not clearly placed within any execution -;; unit. We've made the assumption that it will be running out of the -;; LSU, as msync is also executed within the LSU. -(define_insn_reservation "titan_lsu_sync" 20 - (and (eq_attr "type" "sync") - (eq_attr "cpu" "titan")) - "titan_issue,titan_lsu_sh*20") - -;; Stores. -(define_insn_reservation "titan_lsu_store" 12 - (and (eq_attr "type" "store,store_ux,store_u,store_c") - (eq_attr "cpu" "titan")) - "titan_issue,titan_lsu_sh") - -(define_insn_reservation "titan_lsu_fpstore" 12 - (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u") - (eq_attr "cpu" "titan")) - "titan_issue,titan_lsu_sh") - -;; === FPU scheduling === - -;; In order to keep the automaton for the Titan FPU efficient and -;; maintainable, we've kept in as concise as possible and created a -;; mapping for the main "choke points" only instead of modelling the -;; overall flow of instructions through the FP-pipeline(s). - -;; The key elements modelled are: -;; * each FP-instruction takes up one of the two issue slots -;; * the FPU runs at half the core frequency -;; * divides are not pipelined (but execute in a separate unit) -;; * the FPU has a shared result bus for all its units - -(define_cpu_unit "titan_fp0,titan_fpdiv,titan_fpwb" "titan_fpu") - -(define_insn_reservation "titan_fp_div_double" 72 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fpdiv*72,titan_fpwb") - -(define_insn_reservation "titan_fp_div_single" 46 - (and (eq_attr "type" "sdiv") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fpdiv*46,titan_fpwb") - -(define_insn_reservation "titan_fp_single" 12 - (and (eq_attr "fp_type" "fp_addsub_s,fp_mul_s,fp_maddsub_s") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fp0*2,nothing*10,titan_fpwb") - -;; Make sure the "titan_fp" rule stays last, as it's a catch all for -;; double-precision and unclassified (e.g. fsel) FP-instructions -(define_insn_reservation "titan_fp" 10 - (and (eq_attr "type" "fpcompare,fp,dmul") - (eq_attr "cpu" "titan")) - "titan_issue,titan_fp0*2,nothing*8,titan_fpwb") - -;; Please note, that the non-pipelined FP-instructions "mcrfs", -;; "mtfsb0[.]", "mtfsb1[.]", "mtfsf[.]", "mtfsfi[.]" are not -;; accessible from regular language constructs (i.e. they are not used -;; by the code generator, except for special purpose sequences defined -;; in rs6000.md), no special provisions are made for these. - diff --git a/gcc-4.8.1/gcc/config/rs6000/vec_types.h b/gcc-4.8.1/gcc/config/rs6000/vec_types.h deleted file mode 100644 index 35534d3b9..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/vec_types.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Cell single token vector types - Copyright (C) 2007-2013 Free Software Foundation, Inc. - - This file is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your option) - any later version. - - This file is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -/* Single token vector data types for the PowerPC SIMD/Vector Multi-media - eXtension */ - -#ifndef _VEC_TYPES_H_ -#define _VEC_TYPES_H_ 1 - -#define qword __vector unsigned char - -#define vec_uchar16 __vector unsigned char -#define vec_char16 __vector signed char -#define vec_bchar16 __vector bool char - -#define vec_ushort8 __vector unsigned short -#define vec_short8 __vector signed short -#define vec_bshort8 __vector bool short - -#define vec_pixel8 __vector pixel - -#define vec_uint4 __vector unsigned int -#define vec_int4 __vector signed int -#define vec_bint4 __vector bool int - -#define vec_float4 __vector float - -#define vec_ullong2 __vector bool char -#define vec_llong2 __vector bool short - -#define vec_double2 __vector bool int - -#endif /* _VEC_TYPES_H_ */ diff --git a/gcc-4.8.1/gcc/config/rs6000/vector.md b/gcc-4.8.1/gcc/config/rs6000/vector.md deleted file mode 100644 index 5a6e1fb30..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/vector.md +++ /dev/null @@ -1,1221 +0,0 @@ -;; Expander definitions for vector support between altivec & vsx. No -;; instructions are in this file, this file provides the generic vector -;; expander, and the actual vector instructions will be in altivec.md and -;; vsx.md - -;; Copyright (C) 2009-2013 Free Software Foundation, Inc. -;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com> - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - - -;; Vector int modes -(define_mode_iterator VEC_I [V16QI V8HI V4SI]) - -;; Vector float modes -(define_mode_iterator VEC_F [V4SF V2DF]) - -;; Vector arithmetic modes -(define_mode_iterator VEC_A [V16QI V8HI V4SI V4SF V2DF]) - -;; Vector modes that need alginment via permutes -(define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF]) - -;; Vector logical modes -(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF TI]) - -;; Vector modes for moves. Don't do TImode here. -(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF]) - -;; Vector modes for types that don't need a realignment under VSX -(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF]) - -;; Vector comparison modes -(define_mode_iterator VEC_C [V16QI V8HI V4SI V4SF V2DF]) - -;; Vector init/extract modes -(define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF]) - -;; Vector modes for 64-bit base types -(define_mode_iterator VEC_64 [V2DI V2DF]) - -;; Vector reload iterator -(define_mode_iterator VEC_R [V16QI V8HI V4SI V2DI V4SF V2DF DF TI]) - -;; Base type from vector mode -(define_mode_attr VEC_base [(V16QI "QI") - (V8HI "HI") - (V4SI "SI") - (V2DI "DI") - (V4SF "SF") - (V2DF "DF") - (TI "TI")]) - -;; Same size integer type for floating point data -(define_mode_attr VEC_int [(V4SF "v4si") - (V2DF "v2di")]) - -(define_mode_attr VEC_INT [(V4SF "V4SI") - (V2DF "V2DI")]) - -;; constants for unspec -(define_c_enum "unspec" [UNSPEC_PREDICATE - UNSPEC_REDUC]) - -;; Vector reduction code iterators -(define_code_iterator VEC_reduc [plus smin smax]) - -(define_code_attr VEC_reduc_name [(plus "splus") - (smin "smin") - (smax "smax")]) - -(define_code_attr VEC_reduc_rtx [(plus "add") - (smin "smin") - (smax "smax")]) - - -;; Vector move instructions. -(define_expand "mov<mode>" - [(set (match_operand:VEC_M 0 "nonimmediate_operand" "") - (match_operand:VEC_M 1 "any_operand" ""))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - if (can_create_pseudo_p ()) - { - if (CONSTANT_P (operands[1]) - && !easy_vector_constant (operands[1], <MODE>mode)) - operands[1] = force_const_mem (<MODE>mode, operands[1]); - - else if (!vlogical_operand (operands[0], <MODE>mode) - && !vlogical_operand (operands[1], <MODE>mode)) - operands[1] = force_reg (<MODE>mode, operands[1]); - } -}) - -;; Generic vector floating point load/store instructions. These will match -;; insns defined in vsx.md or altivec.md depending on the switches. -(define_expand "vector_load_<mode>" - [(set (match_operand:VEC_M 0 "vfloat_operand" "") - (match_operand:VEC_M 1 "memory_operand" ""))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_store_<mode>" - [(set (match_operand:VEC_M 0 "memory_operand" "") - (match_operand:VEC_M 1 "vfloat_operand" ""))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -;; Splits if a GPR register was chosen for the move -(define_split - [(set (match_operand:VEC_L 0 "nonimmediate_operand" "") - (match_operand:VEC_L 1 "input_operand" ""))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode) - && reload_completed - && gpr_or_gpr_p (operands[0], operands[1])" - [(pc)] -{ - rs6000_split_multireg_move (operands[0], operands[1]); - DONE; -}) - -;; Vector floating point load/store instructions that uses the Altivec -;; instructions even if we are compiling for VSX, since the Altivec -;; instructions silently ignore the bottom 3 bits of the address, and VSX does -;; not. -(define_expand "vector_altivec_load_<mode>" - [(set (match_operand:VEC_M 0 "vfloat_operand" "") - (match_operand:VEC_M 1 "memory_operand" ""))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)); - - if (VECTOR_MEM_VSX_P (<MODE>mode)) - { - operands[1] = rs6000_address_for_altivec (operands[1]); - emit_insn (gen_altivec_lvx_<mode> (operands[0], operands[1])); - DONE; - } -}") - -(define_expand "vector_altivec_store_<mode>" - [(set (match_operand:VEC_M 0 "memory_operand" "") - (match_operand:VEC_M 1 "vfloat_operand" ""))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)); - - if (VECTOR_MEM_VSX_P (<MODE>mode)) - { - operands[0] = rs6000_address_for_altivec (operands[0]); - emit_insn (gen_altivec_stvx_<mode> (operands[0], operands[1])); - DONE; - } -}") - - - -;; Reload patterns for vector operations. We may need an additional base -;; register to convert the reg+offset addressing to reg+reg for vector -;; registers and reg+reg or (reg+reg)&(-16) addressing to just an index -;; register for gpr registers. -(define_expand "reload_<VEC_R:mode>_<P:mptrsize>_store" - [(parallel [(match_operand:VEC_R 0 "memory_operand" "m") - (match_operand:VEC_R 1 "gpc_reg_operand" "r") - (match_operand:P 2 "register_operand" "=&b")])] - "<P:tptrsize>" -{ - rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); - DONE; -}) - -(define_expand "reload_<VEC_R:mode>_<P:mptrsize>_load" - [(parallel [(match_operand:VEC_R 0 "gpc_reg_operand" "=&r") - (match_operand:VEC_R 1 "memory_operand" "m") - (match_operand:P 2 "register_operand" "=&b")])] - "<P:tptrsize>" -{ - rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); - DONE; -}) - -;; Reload sometimes tries to move the address to a GPR, and can generate -;; invalid RTL for addresses involving AND -16. Allow addresses involving -;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16. - -(define_insn_and_split "*vec_reload_and_plus_<mptrsize>" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") - (match_operand:P 2 "reg_or_cint_operand" "rI")) - (const_int -16)))] - "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)" - "#" - "&& reload_completed" - [(set (match_dup 0) - (plus:P (match_dup 1) - (match_dup 2))) - (parallel [(set (match_dup 0) - (and:P (match_dup 0) - (const_int -16))) - (clobber:CC (scratch:CC))])]) - -;; The normal ANDSI3/ANDDI3 won't match if reload decides to move an AND -16 -;; address to a register because there is no clobber of a (scratch), so we add -;; it here. -(define_insn_and_split "*vec_reload_and_reg_<mptrsize>" - [(set (match_operand:P 0 "gpc_reg_operand" "=b") - (and:P (match_operand:P 1 "gpc_reg_operand" "r") - (const_int -16)))] - "(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)" - "#" - "&& reload_completed" - [(parallel [(set (match_dup 0) - (and:P (match_dup 1) - (const_int -16))) - (clobber:CC (scratch:CC))])]) - -;; Generic floating point vector arithmetic support -(define_expand "add<mode>3" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "sub<mode>3" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "mul<mode>3" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_VSX_P (<MODE>mode) || VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2])); - DONE; - } -}) - -(define_expand "div<mode>3" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (div:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "") - -(define_expand "neg<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1])); - DONE; - } -}") - -(define_expand "abs<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1])); - DONE; - } -}") - -(define_expand "smin<mode>3" - [(set (match_operand:VEC_F 0 "register_operand" "") - (smin:VEC_F (match_operand:VEC_F 1 "register_operand" "") - (match_operand:VEC_F 2 "register_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "smax<mode>3" - [(set (match_operand:VEC_F 0 "register_operand" "") - (smax:VEC_F (match_operand:VEC_F 1 "register_operand" "") - (match_operand:VEC_F 2 "register_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - - -(define_expand "sqrt<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (sqrt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "") - -(define_expand "rsqrte<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] - UNSPEC_RSQRT))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "re<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "f")] - UNSPEC_FRES))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "ftrunc<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_ceil<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] - UNSPEC_FRIP))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_floor<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] - UNSPEC_FRIM))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_btrunc<mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_copysign<mode>3" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")] UNSPEC_COPYSIGN))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_copysign_v4sf3 (operands[0], operands[1], - operands[2])); - DONE; - } -}") - - -;; Vector comparisons -(define_expand "vcond<mode><mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (if_then_else:VEC_F - (match_operator 3 "comparison_operator" - [(match_operand:VEC_F 4 "vfloat_operand" "") - (match_operand:VEC_F 5 "vfloat_operand" "")]) - (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; -}") - -(define_expand "vcond<mode><mode>" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (if_then_else:VEC_I - (match_operator 3 "comparison_operator" - [(match_operand:VEC_I 4 "vint_operand" "") - (match_operand:VEC_I 5 "vint_operand" "")]) - (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - " -{ - if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; -}") - -(define_expand "vcondv4sfv4si" - [(set (match_operand:V4SF 0 "vfloat_operand" "") - (if_then_else:V4SF - (match_operator 3 "comparison_operator" - [(match_operand:V4SI 4 "vint_operand" "") - (match_operand:V4SI 5 "vint_operand" "")]) - (match_operand:V4SF 1 "vfloat_operand" "") - (match_operand:V4SF 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) - && VECTOR_UNIT_ALTIVEC_P (V4SImode)" - " -{ - if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; -}") - -(define_expand "vcondv4siv4sf" - [(set (match_operand:V4SI 0 "vint_operand" "") - (if_then_else:V4SI - (match_operator 3 "comparison_operator" - [(match_operand:V4SF 4 "vfloat_operand" "") - (match_operand:V4SF 5 "vfloat_operand" "")]) - (match_operand:V4SI 1 "vint_operand" "") - (match_operand:V4SI 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) - && VECTOR_UNIT_ALTIVEC_P (V4SImode)" - " -{ - if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; -}") - -(define_expand "vcondu<mode><mode>" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (if_then_else:VEC_I - (match_operator 3 "comparison_operator" - [(match_operand:VEC_I 4 "vint_operand" "") - (match_operand:VEC_I 5 "vint_operand" "")]) - (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - " -{ - if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; -}") - -(define_expand "vconduv4sfv4si" - [(set (match_operand:V4SF 0 "vfloat_operand" "") - (if_then_else:V4SF - (match_operator 3 "comparison_operator" - [(match_operand:V4SI 4 "vint_operand" "") - (match_operand:V4SI 5 "vint_operand" "")]) - (match_operand:V4SF 1 "vfloat_operand" "") - (match_operand:V4SF 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) - && VECTOR_UNIT_ALTIVEC_P (V4SImode)" - " -{ - if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], - operands[3], operands[4], operands[5])) - DONE; - else - FAIL; -}") - -(define_expand "vector_eq<mode>" - [(set (match_operand:VEC_C 0 "vlogical_operand" "") - (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") - (match_operand:VEC_C 2 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_gt<mode>" - [(set (match_operand:VEC_C 0 "vlogical_operand" "") - (gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") - (match_operand:VEC_C 2 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_ge<mode>" - [(set (match_operand:VEC_C 0 "vlogical_operand" "") - (ge:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") - (match_operand:VEC_C 2 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_gtu<mode>" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (gtu:VEC_I (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "") - -(define_expand "vector_geu<mode>" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (geu:VEC_I (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" - "") - -(define_insn_and_split "*vector_uneq<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (uneq:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "#" - "" - [(set (match_dup 3) - (gt:VEC_F (match_dup 1) - (match_dup 2))) - (set (match_dup 4) - (gt:VEC_F (match_dup 2) - (match_dup 1))) - (set (match_dup 0) - (not:VEC_F (ior:VEC_F (match_dup 3) - (match_dup 4))))] - " -{ - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); -}") - -(define_insn_and_split "*vector_ltgt<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (ltgt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "#" - "" - [(set (match_dup 3) - (gt:VEC_F (match_dup 1) - (match_dup 2))) - (set (match_dup 4) - (gt:VEC_F (match_dup 2) - (match_dup 1))) - (set (match_dup 0) - (ior:VEC_F (match_dup 3) - (match_dup 4)))] - " -{ - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); -}") - -(define_insn_and_split "*vector_ordered<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (ordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "#" - "" - [(set (match_dup 3) - (ge:VEC_F (match_dup 1) - (match_dup 2))) - (set (match_dup 4) - (ge:VEC_F (match_dup 2) - (match_dup 1))) - (set (match_dup 0) - (ior:VEC_F (match_dup 3) - (match_dup 4)))] - " -{ - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); -}") - -(define_insn_and_split "*vector_unordered<mode>" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (unordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "#" - "" - [(set (match_dup 3) - (ge:VEC_F (match_dup 1) - (match_dup 2))) - (set (match_dup 4) - (ge:VEC_F (match_dup 2) - (match_dup 1))) - (set (match_dup 0) - (not:VEC_F (ior:VEC_F (match_dup 3) - (match_dup 4))))] - " -{ - operands[3] = gen_reg_rtx (<MODE>mode); - operands[4] = gen_reg_rtx (<MODE>mode); -}") - -;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask -;; which is in the reverse order that we want -(define_expand "vector_select_<mode>" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (if_then_else:VEC_L - (ne:CC (match_operand:VEC_L 3 "vlogical_operand" "") - (match_dup 4)) - (match_operand:VEC_L 2 "vlogical_operand" "") - (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "operands[4] = CONST0_RTX (<MODE>mode);") - -(define_expand "vector_select_<mode>_uns" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (if_then_else:VEC_L - (ne:CCUNS (match_operand:VEC_L 3 "vlogical_operand" "") - (match_dup 4)) - (match_operand:VEC_L 2 "vlogical_operand" "") - (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "operands[4] = CONST0_RTX (<MODE>mode);") - -;; Expansions that compare vectors producing a vector result and a predicate, -;; setting CR6 to indicate a combined status -(define_expand "vector_eq_<mode>_p" - [(parallel - [(set (reg:CC 74) - (unspec:CC [(eq:CC (match_operand:VEC_A 1 "vlogical_operand" "") - (match_operand:VEC_A 2 "vlogical_operand" ""))] - UNSPEC_PREDICATE)) - (set (match_operand:VEC_A 0 "vlogical_operand" "") - (eq:VEC_A (match_dup 1) - (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_gt_<mode>_p" - [(parallel - [(set (reg:CC 74) - (unspec:CC [(gt:CC (match_operand:VEC_A 1 "vlogical_operand" "") - (match_operand:VEC_A 2 "vlogical_operand" ""))] - UNSPEC_PREDICATE)) - (set (match_operand:VEC_A 0 "vlogical_operand" "") - (gt:VEC_A (match_dup 1) - (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_ge_<mode>_p" - [(parallel - [(set (reg:CC 74) - (unspec:CC [(ge:CC (match_operand:VEC_F 1 "vfloat_operand" "") - (match_operand:VEC_F 2 "vfloat_operand" ""))] - UNSPEC_PREDICATE)) - (set (match_operand:VEC_F 0 "vfloat_operand" "") - (ge:VEC_F (match_dup 1) - (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "vector_gtu_<mode>_p" - [(parallel - [(set (reg:CC 74) - (unspec:CC [(gtu:CC (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" ""))] - UNSPEC_PREDICATE)) - (set (match_operand:VEC_I 0 "vlogical_operand" "") - (gtu:VEC_I (match_dup 1) - (match_dup 2)))])] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -;; AltiVec/VSX predicates. - -(define_expand "cr6_test_for_zero" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (reg:CC 74) - (const_int 0)))] - "TARGET_ALTIVEC || TARGET_VSX" - "") - -(define_expand "cr6_test_for_zero_reverse" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (reg:CC 74) - (const_int 0))) - (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC || TARGET_VSX" - "") - -(define_expand "cr6_test_for_lt" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (reg:CC 74) - (const_int 0)))] - "TARGET_ALTIVEC || TARGET_VSX" - "") - -(define_expand "cr6_test_for_lt_reverse" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (reg:CC 74) - (const_int 0))) - (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC || TARGET_VSX" - "") - - -;; Vector logical instructions -(define_expand "xor<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (xor:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "ior<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "and<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (and:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "one_cmpl<mode>2" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (not:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "nor<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (not:VEC_L (ior:VEC_L (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:VEC_L 2 "vlogical_operand" ""))))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -(define_expand "andc<mode>3" - [(set (match_operand:VEC_L 0 "vlogical_operand" "") - (and:VEC_L (not:VEC_L (match_operand:VEC_L 2 "vlogical_operand" "")) - (match_operand:VEC_L 1 "vlogical_operand" "")))] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" - "") - -;; Same size conversions -(define_expand "float<VEC_int><mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx)); - DONE; - } -}") - -(define_expand "floatuns<VEC_int><mode>2" - [(set (match_operand:VEC_F 0 "vfloat_operand" "") - (unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx)); - DONE; - } -}") - -(define_expand "fix_trunc<mode><VEC_int>2" - [(set (match_operand:<VEC_INT> 0 "vint_operand" "") - (fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx)); - DONE; - } -}") - -(define_expand "fixuns_trunc<mode><VEC_int>2" - [(set (match_operand:<VEC_INT> 0 "vint_operand" "") - (unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] - "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" - " -{ - if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) - { - emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx)); - DONE; - } -}") - - -;; Vector initialization, set, extract -(define_expand "vec_init<mode>" - [(match_operand:VEC_E 0 "vlogical_operand" "") - (match_operand:VEC_E 1 "" "")] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - rs6000_expand_vector_init (operands[0], operands[1]); - DONE; -}) - -(define_expand "vec_set<mode>" - [(match_operand:VEC_E 0 "vlogical_operand" "") - (match_operand:<VEC_base> 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2])); - DONE; -}) - -(define_expand "vec_extract<mode>" - [(match_operand:<VEC_base> 0 "register_operand" "") - (match_operand:VEC_E 1 "vlogical_operand" "") - (match_operand 2 "const_int_operand" "")] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - rs6000_expand_vector_extract (operands[0], operands[1], - INTVAL (operands[2])); - DONE; -}) - -;; Convert double word types to single word types -(define_expand "vec_pack_trunc_v2df" - [(match_operand:V4SF 0 "vfloat_operand" "") - (match_operand:V2DF 1 "vfloat_operand" "") - (match_operand:V2DF 2 "vfloat_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" -{ - rtx r1 = gen_reg_rtx (V4SFmode); - rtx r2 = gen_reg_rtx (V4SFmode); - - emit_insn (gen_vsx_xvcvdpsp (r1, operands[1])); - emit_insn (gen_vsx_xvcvdpsp (r2, operands[2])); - rs6000_expand_extract_even (operands[0], r1, r2); - DONE; -}) - -(define_expand "vec_pack_sfix_trunc_v2df" - [(match_operand:V4SI 0 "vint_operand" "") - (match_operand:V2DF 1 "vfloat_operand" "") - (match_operand:V2DF 2 "vfloat_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" -{ - rtx r1 = gen_reg_rtx (V4SImode); - rtx r2 = gen_reg_rtx (V4SImode); - - emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1])); - emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2])); - rs6000_expand_extract_even (operands[0], r1, r2); - DONE; -}) - -(define_expand "vec_pack_ufix_trunc_v2df" - [(match_operand:V4SI 0 "vint_operand" "") - (match_operand:V2DF 1 "vfloat_operand" "") - (match_operand:V2DF 2 "vfloat_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" -{ - rtx r1 = gen_reg_rtx (V4SImode); - rtx r2 = gen_reg_rtx (V4SImode); - - emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1])); - emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2])); - rs6000_expand_extract_even (operands[0], r1, r2); - DONE; -}) - -;; Convert single word types to double word -(define_expand "vec_unpacks_hi_v4sf" - [(match_operand:V2DF 0 "vfloat_operand" "") - (match_operand:V4SF 1 "vfloat_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" -{ - rtx reg = gen_reg_rtx (V4SFmode); - - rs6000_expand_interleave (reg, operands[1], operands[1], true); - emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); - DONE; -}) - -(define_expand "vec_unpacks_lo_v4sf" - [(match_operand:V2DF 0 "vfloat_operand" "") - (match_operand:V4SF 1 "vfloat_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" -{ - rtx reg = gen_reg_rtx (V4SFmode); - - rs6000_expand_interleave (reg, operands[1], operands[1], false); - emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); - DONE; -}) - -(define_expand "vec_unpacks_float_hi_v4si" - [(match_operand:V2DF 0 "vfloat_operand" "") - (match_operand:V4SI 1 "vint_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -{ - rtx reg = gen_reg_rtx (V4SImode); - - rs6000_expand_interleave (reg, operands[1], operands[1], true); - emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); - DONE; -}) - -(define_expand "vec_unpacks_float_lo_v4si" - [(match_operand:V2DF 0 "vfloat_operand" "") - (match_operand:V4SI 1 "vint_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -{ - rtx reg = gen_reg_rtx (V4SImode); - - rs6000_expand_interleave (reg, operands[1], operands[1], false); - emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); - DONE; -}) - -(define_expand "vec_unpacku_float_hi_v4si" - [(match_operand:V2DF 0 "vfloat_operand" "") - (match_operand:V4SI 1 "vint_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -{ - rtx reg = gen_reg_rtx (V4SImode); - - rs6000_expand_interleave (reg, operands[1], operands[1], true); - emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); - DONE; -}) - -(define_expand "vec_unpacku_float_lo_v4si" - [(match_operand:V2DF 0 "vfloat_operand" "") - (match_operand:V4SI 1 "vint_operand" "")] - "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" -{ - rtx reg = gen_reg_rtx (V4SImode); - - rs6000_expand_interleave (reg, operands[1], operands[1], false); - emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); - DONE; -}) - - -;; Align vector loads with a permute. -(define_expand "vec_realign_load_<mode>" - [(match_operand:VEC_K 0 "vlogical_operand" "") - (match_operand:VEC_K 1 "vlogical_operand" "") - (match_operand:VEC_K 2 "vlogical_operand" "") - (match_operand:V16QI 3 "vlogical_operand" "")] - "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" -{ - emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], operands[2], - operands[3])); - DONE; -}) - -;; Under VSX, vectors of 4/8 byte alignments do not need to be aligned -;; since the load already handles it. -(define_expand "movmisalign<mode>" - [(set (match_operand:VEC_N 0 "nonimmediate_operand" "") - (match_operand:VEC_N 1 "any_operand" ""))] - "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_ALLOW_MOVMISALIGN" - "") - - -;; Vector shift left in bits. Currently supported ony for shift -;; amounts that can be expressed as byte shifts (divisible by 8). -;; General shift amounts can be supported using vslo + vsl. We're -;; not expecting to see these yet (the vectorizer currently -;; generates only shifts divisible by byte_size). -(define_expand "vec_shl_<mode>" - [(match_operand:VEC_L 0 "vlogical_operand" "") - (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:QI 2 "reg_or_short_operand" "")] - "TARGET_ALTIVEC" - " -{ - rtx bitshift = operands[2]; - rtx shift; - rtx insn; - HOST_WIDE_INT bitshift_val; - HOST_WIDE_INT byteshift_val; - - if (! CONSTANT_P (bitshift)) - FAIL; - bitshift_val = INTVAL (bitshift); - if (bitshift_val & 0x7) - FAIL; - byteshift_val = bitshift_val >> 3; - if (TARGET_VSX && (byteshift_val & 0x3) == 0) - { - shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); - insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1], - shift); - } - else - { - shift = gen_rtx_CONST_INT (QImode, byteshift_val); - insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], - shift); - } - - emit_insn (insn); - DONE; -}") - -;; Vector shift right in bits. Currently supported ony for shift -;; amounts that can be expressed as byte shifts (divisible by 8). -;; General shift amounts can be supported using vsro + vsr. We're -;; not expecting to see these yet (the vectorizer currently -;; generates only shifts divisible by byte_size). -(define_expand "vec_shr_<mode>" - [(match_operand:VEC_L 0 "vlogical_operand" "") - (match_operand:VEC_L 1 "vlogical_operand" "") - (match_operand:QI 2 "reg_or_short_operand" "")] - "TARGET_ALTIVEC" - " -{ - rtx bitshift = operands[2]; - rtx shift; - rtx insn; - HOST_WIDE_INT bitshift_val; - HOST_WIDE_INT byteshift_val; - - if (! CONSTANT_P (bitshift)) - FAIL; - bitshift_val = INTVAL (bitshift); - if (bitshift_val & 0x7) - FAIL; - byteshift_val = 16 - (bitshift_val >> 3); - if (TARGET_VSX && (byteshift_val & 0x3) == 0) - { - shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); - insn = gen_vsx_xxsldwi_<mode> (operands[0], operands[1], operands[1], - shift); - } - else - { - shift = gen_rtx_CONST_INT (QImode, byteshift_val); - insn = gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1], - shift); - } - - emit_insn (insn); - DONE; -}") - -;; Expanders for rotate each element in a vector -(define_expand "vrotl<mode>3" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (rotate:VEC_I (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" - "") - -;; Expanders for arithmetic shift left on each vector element -(define_expand "vashl<mode>3" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" - "") - -;; Expanders for logical shift right on each vector element -(define_expand "vlshr<mode>3" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" - "") - -;; Expanders for arithmetic shift right on each vector element -(define_expand "vashr<mode>3" - [(set (match_operand:VEC_I 0 "vint_operand" "") - (ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "") - (match_operand:VEC_I 2 "vint_operand" "")))] - "TARGET_ALTIVEC" - "") - -;; Vector reduction expanders for VSX - -(define_expand "reduc_<VEC_reduc_name>_v2df" - [(parallel [(set (match_operand:V2DF 0 "vfloat_operand" "") - (VEC_reduc:V2DF - (vec_concat:V2DF - (vec_select:DF - (match_operand:V2DF 1 "vfloat_operand" "") - (parallel [(const_int 1)])) - (vec_select:DF - (match_dup 1) - (parallel [(const_int 0)]))) - (match_dup 1))) - (clobber (match_scratch:V2DF 2 ""))])] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "") - -; The (VEC_reduc:V4SF -; (op1) -; (unspec:V4SF [(const_int 0)] UNSPEC_REDUC)) -; -; is to allow us to use a code iterator, but not completely list all of the -; vector rotates, etc. to prevent canonicalization - -(define_expand "reduc_<VEC_reduc_name>_v4sf" - [(parallel [(set (match_operand:V4SF 0 "vfloat_operand" "") - (VEC_reduc:V4SF - (unspec:V4SF [(const_int 0)] UNSPEC_REDUC) - (match_operand:V4SF 1 "vfloat_operand" ""))) - (clobber (match_scratch:V4SF 2 "")) - (clobber (match_scratch:V4SF 3 ""))])] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "") - - -;;; Expanders for vector insn patterns shared between the SPE and TARGET_PAIRED systems. - -(define_expand "absv2sf2" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "") - (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))] - "TARGET_PAIRED_FLOAT || TARGET_SPE" - "") - -(define_expand "negv2sf2" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "") - (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))] - "TARGET_PAIRED_FLOAT || TARGET_SPE" - "") - -(define_expand "addv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "") - (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") - (match_operand:V2SF 2 "gpc_reg_operand" "")))] - "TARGET_PAIRED_FLOAT || TARGET_SPE" - " -{ - if (TARGET_SPE) - { - /* We need to make a note that we clobber SPEFSCR. */ - rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); - - XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_PLUS (V2SFmode, operands[1], operands[2])); - XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); - emit_insn (par); - DONE; - } -}") - -(define_expand "subv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "") - (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") - (match_operand:V2SF 2 "gpc_reg_operand" "")))] - "TARGET_PAIRED_FLOAT || TARGET_SPE" - " -{ - if (TARGET_SPE) - { - /* We need to make a note that we clobber SPEFSCR. */ - rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); - - XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_MINUS (V2SFmode, operands[1], operands[2])); - XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); - emit_insn (par); - DONE; - } -}") - -(define_expand "mulv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "") - (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") - (match_operand:V2SF 2 "gpc_reg_operand" "")))] - "TARGET_PAIRED_FLOAT || TARGET_SPE" - " -{ - if (TARGET_SPE) - { - /* We need to make a note that we clobber SPEFSCR. */ - rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); - - XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_MULT (V2SFmode, operands[1], operands[2])); - XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); - emit_insn (par); - DONE; - } -}") - -(define_expand "divv2sf3" - [(set (match_operand:V2SF 0 "gpc_reg_operand" "") - (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") - (match_operand:V2SF 2 "gpc_reg_operand" "")))] - "TARGET_PAIRED_FLOAT || TARGET_SPE" - " -{ - if (TARGET_SPE) - { - /* We need to make a note that we clobber SPEFSCR. */ - rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); - - XVECEXP (par, 0, 0) = gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_DIV (V2SFmode, operands[1], operands[2])); - XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); - emit_insn (par); - DONE; - } -}") diff --git a/gcc-4.8.1/gcc/config/rs6000/vsx.md b/gcc-4.8.1/gcc/config/rs6000/vsx.md deleted file mode 100644 index 3fafd9b27..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/vsx.md +++ /dev/null @@ -1,1485 +0,0 @@ -;; VSX patterns. -;; Copyright (C) 2009-2013 Free Software Foundation, Inc. -;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com> - -;; This file is part of GCC. - -;; GCC is free software; you can redistribute it and/or modify it -;; under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 3, or (at your -;; option) any later version. - -;; GCC is distributed in the hope that it will be useful, but WITHOUT -;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -;; License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;; Iterator for both scalar and vector floating point types supported by VSX -(define_mode_iterator VSX_B [DF V4SF V2DF]) - -;; Iterator for the 2 64-bit vector types -(define_mode_iterator VSX_D [V2DF V2DI]) - -;; Iterator for the 2 32-bit vector types -(define_mode_iterator VSX_W [V4SF V4SI]) - -;; Iterator for the DF types -(define_mode_iterator VSX_DF [V2DF DF]) - -;; Iterator for vector floating point types supported by VSX -(define_mode_iterator VSX_F [V4SF V2DF]) - -;; Iterator for logical types supported by VSX -(define_mode_iterator VSX_L [V16QI V8HI V4SI V2DI V4SF V2DF TI]) - -;; Iterator for memory move. Handle TImode specially to allow -;; it to use gprs as well as vsx registers. -(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF]) - -;; Map into the appropriate load/store name based on the type -(define_mode_attr VSm [(V16QI "vw4") - (V8HI "vw4") - (V4SI "vw4") - (V4SF "vw4") - (V2DF "vd2") - (V2DI "vd2") - (DF "d") - (TI "vw4")]) - -;; Map into the appropriate suffix based on the type -(define_mode_attr VSs [(V16QI "sp") - (V8HI "sp") - (V4SI "sp") - (V4SF "sp") - (V2DF "dp") - (V2DI "dp") - (DF "dp") - (SF "sp") - (TI "sp")]) - -;; Map the register class used -(define_mode_attr VSr [(V16QI "v") - (V8HI "v") - (V4SI "v") - (V4SF "wf") - (V2DI "wd") - (V2DF "wd") - (DF "ws") - (SF "d") - (TI "wd")]) - -;; Map the register class used for float<->int conversions -(define_mode_attr VSr2 [(V2DF "wd") - (V4SF "wf") - (DF "ws")]) - -(define_mode_attr VSr3 [(V2DF "wa") - (V4SF "wa") - (DF "ws")]) - -;; Map the register class for sp<->dp float conversions, destination -(define_mode_attr VSr4 [(SF "ws") - (DF "f") - (V2DF "wd") - (V4SF "v")]) - -;; Map the register class for sp<->dp float conversions, destination -(define_mode_attr VSr5 [(SF "ws") - (DF "f") - (V2DF "v") - (V4SF "wd")]) - -;; Same size integer type for floating point data -(define_mode_attr VSi [(V4SF "v4si") - (V2DF "v2di") - (DF "di")]) - -(define_mode_attr VSI [(V4SF "V4SI") - (V2DF "V2DI") - (DF "DI")]) - -;; Word size for same size conversion -(define_mode_attr VSc [(V4SF "w") - (V2DF "d") - (DF "d")]) - -;; Map into either s or v, depending on whether this is a scalar or vector -;; operation -(define_mode_attr VSv [(V16QI "v") - (V8HI "v") - (V4SI "v") - (V4SF "v") - (V2DI "v") - (V2DF "v") - (TI "v") - (DF "s")]) - -;; Appropriate type for add ops (and other simple FP ops) -(define_mode_attr VStype_simple [(V2DF "vecdouble") - (V4SF "vecfloat") - (DF "fp")]) - -(define_mode_attr VSfptype_simple [(V2DF "fp_addsub_d") - (V4SF "fp_addsub_s") - (DF "fp_addsub_d")]) - -;; Appropriate type for multiply ops -(define_mode_attr VStype_mul [(V2DF "vecdouble") - (V4SF "vecfloat") - (DF "dmul")]) - -(define_mode_attr VSfptype_mul [(V2DF "fp_mul_d") - (V4SF "fp_mul_s") - (DF "fp_mul_d")]) - -;; Appropriate type for divide ops. -(define_mode_attr VStype_div [(V2DF "vecdiv") - (V4SF "vecfdiv") - (DF "ddiv")]) - -(define_mode_attr VSfptype_div [(V2DF "fp_div_d") - (V4SF "fp_div_s") - (DF "fp_div_d")]) - -;; Appropriate type for sqrt ops. For now, just lump the vector sqrt with -;; the scalar sqrt -(define_mode_attr VStype_sqrt [(V2DF "dsqrt") - (V4SF "ssqrt") - (DF "dsqrt")]) - -(define_mode_attr VSfptype_sqrt [(V2DF "fp_sqrt_d") - (V4SF "fp_sqrt_s") - (DF "fp_sqrt_d")]) - -;; Iterator and modes for sp<->dp conversions -;; Because scalar SF values are represented internally as double, use the -;; V4SF type to represent this than SF. -(define_mode_iterator VSX_SPDP [DF V4SF V2DF]) - -(define_mode_attr VS_spdp_res [(DF "V4SF") - (V4SF "V2DF") - (V2DF "V4SF")]) - -(define_mode_attr VS_spdp_insn [(DF "xscvdpsp") - (V4SF "xvcvspdp") - (V2DF "xvcvdpsp")]) - -(define_mode_attr VS_spdp_type [(DF "fp") - (V4SF "vecdouble") - (V2DF "vecdouble")]) - -;; Map the scalar mode for a vector type -(define_mode_attr VS_scalar [(V2DF "DF") - (V2DI "DI") - (V4SF "SF") - (V4SI "SI") - (V8HI "HI") - (V16QI "QI")]) - -;; Map to a double-sized vector mode -(define_mode_attr VS_double [(V4SI "V8SI") - (V4SF "V8SF") - (V2DI "V4DI") - (V2DF "V4DF")]) - -;; Constants for creating unspecs -(define_c_enum "unspec" - [UNSPEC_VSX_CONCAT - UNSPEC_VSX_CVDPSXWS - UNSPEC_VSX_CVDPUXWS - UNSPEC_VSX_CVSPDP - UNSPEC_VSX_CVSXWDP - UNSPEC_VSX_CVUXWDP - UNSPEC_VSX_CVSXDSP - UNSPEC_VSX_CVUXDSP - UNSPEC_VSX_CVSPSXDS - UNSPEC_VSX_CVSPUXDS - UNSPEC_VSX_TDIV - UNSPEC_VSX_TSQRT - UNSPEC_VSX_SET - UNSPEC_VSX_ROUND_I - UNSPEC_VSX_ROUND_IC - UNSPEC_VSX_SLDWI - ]) - -;; VSX moves -(define_insn "*vsx_mov<mode>" - [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?wa,?wa,*Y,*r,*r,<VSr>,?wa,*r,v,wZ,v") - (match_operand:VSX_M 1 "input_operand" "<VSr>,Z,<VSr>,wa,Z,wa,r,Y,r,j,j,j,W,v,wZ"))] - "VECTOR_MEM_VSX_P (<MODE>mode) - && (register_operand (operands[0], <MODE>mode) - || register_operand (operands[1], <MODE>mode))" -{ - switch (which_alternative) - { - case 0: - case 3: - gcc_assert (MEM_P (operands[0]) - && GET_CODE (XEXP (operands[0], 0)) != PRE_INC - && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC - && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY); - return "stx<VSm>x %x1,%y0"; - - case 1: - case 4: - gcc_assert (MEM_P (operands[1]) - && GET_CODE (XEXP (operands[1], 0)) != PRE_INC - && GET_CODE (XEXP (operands[1], 0)) != PRE_DEC - && GET_CODE (XEXP (operands[1], 0)) != PRE_MODIFY); - return "lx<VSm>x %x0,%y1"; - - case 2: - case 5: - return "xxlor %x0,%x1,%x1"; - - case 6: - case 7: - case 8: - case 11: - return "#"; - - case 9: - case 10: - return "xxlxor %x0,%x0,%x0"; - - case 12: - return output_vec_const_move (operands); - - case 13: - gcc_assert (MEM_P (operands[0]) - && GET_CODE (XEXP (operands[0], 0)) != PRE_INC - && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC - && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY); - return "stvx %1,%y0"; - - case 14: - gcc_assert (MEM_P (operands[0]) - && GET_CODE (XEXP (operands[0], 0)) != PRE_INC - && GET_CODE (XEXP (operands[0], 0)) != PRE_DEC - && GET_CODE (XEXP (operands[0], 0)) != PRE_MODIFY); - return "lvx %0,%y1"; - - default: - gcc_unreachable (); - } -} - [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,*,*,*,vecsimple,vecsimple,*,*,vecstore,vecload")]) - -;; Unlike other VSX moves, allow the GPRs, since a normal use of TImode is for -;; unions. However for plain data movement, slightly favor the vector loads -(define_insn "*vsx_movti" - [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,?Y,?r,?r,wa,v,v,wZ") - (match_operand:TI 1 "input_operand" "wa,Z,wa,r,Y,r,j,W,wZ,v"))] - "VECTOR_MEM_VSX_P (TImode) - && (register_operand (operands[0], TImode) - || register_operand (operands[1], TImode))" -{ - switch (which_alternative) - { - case 0: - return "stxvd2x %x1,%y0"; - - case 1: - return "lxvd2x %x0,%y1"; - - case 2: - return "xxlor %x0,%x1,%x1"; - - case 3: - case 4: - case 5: - return "#"; - - case 6: - return "xxlxor %x0,%x0,%x0"; - - case 7: - return output_vec_const_move (operands); - - case 8: - return "stvx %1,%y0"; - - case 9: - return "lvx %0,%y1"; - - default: - gcc_unreachable (); - } -} - [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")]) - -;; Explicit load/store expanders for the builtin functions -(define_expand "vsx_load_<mode>" - [(set (match_operand:VSX_M 0 "vsx_register_operand" "") - (match_operand:VSX_M 1 "memory_operand" ""))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "") - -(define_expand "vsx_store_<mode>" - [(set (match_operand:VEC_M 0 "memory_operand" "") - (match_operand:VEC_M 1 "vsx_register_operand" ""))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "") - - -;; VSX scalar and vector floating point arithmetic instructions -(define_insn "*vsx_add<mode>3" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>add<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "*vsx_sub<mode>3" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (minus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>sub<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "*vsx_mul<mode>3" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (mult:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>mul<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_mul>") - (set_attr "fp_type" "<VSfptype_mul>")]) - -(define_insn "*vsx_div<mode>3" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (div:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>div<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_div>") - (set_attr "fp_type" "<VSfptype_div>")]) - -;; *tdiv* instruction returning the FG flag -(define_expand "vsx_tdiv<mode>3_fg" - [(set (match_dup 3) - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "") - (match_operand:VSX_B 2 "vsx_register_operand" "")] - UNSPEC_VSX_TDIV)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (gt:SI (match_dup 3) - (const_int 0)))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" -{ - operands[3] = gen_reg_rtx (CCFPmode); -}) - -;; *tdiv* instruction returning the FE flag -(define_expand "vsx_tdiv<mode>3_fe" - [(set (match_dup 3) - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "") - (match_operand:VSX_B 2 "vsx_register_operand" "")] - UNSPEC_VSX_TDIV)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (eq:SI (match_dup 3) - (const_int 0)))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" -{ - operands[3] = gen_reg_rtx (CCFPmode); -}) - -(define_insn "*vsx_tdiv<mode>3_internal" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x") - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_VSX_TDIV))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>tdiv<VSs> %0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_fre<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_FRES))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>re<VSs> %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "*vsx_neg<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (neg:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>neg<VSs> %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "*vsx_abs<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>abs<VSs> %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_nabs<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (neg:VSX_B - (abs:VSX_B - (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa"))))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>nabs<VSs> %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_smax<mode>3" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (smax:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>max<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "*vsx_smin<mode>3" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (smin:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>min<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -;; Special VSX version of smin/smax for single precision floating point. Since -;; both numbers are rounded to single precision, we can just use the DP version -;; of the instruction. - -(define_insn "*vsx_smaxsf3" - [(set (match_operand:SF 0 "vsx_register_operand" "=f") - (smax:SF (match_operand:SF 1 "vsx_register_operand" "f") - (match_operand:SF 2 "vsx_register_operand" "f")))] - "VECTOR_UNIT_VSX_P (DFmode)" - "xsmaxdp %x0,%x1,%x2" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_addsub_d")]) - -(define_insn "*vsx_sminsf3" - [(set (match_operand:SF 0 "vsx_register_operand" "=f") - (smin:SF (match_operand:SF 1 "vsx_register_operand" "f") - (match_operand:SF 2 "vsx_register_operand" "f")))] - "VECTOR_UNIT_VSX_P (DFmode)" - "xsmindp %x0,%x1,%x2" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_addsub_d")]) - -(define_insn "*vsx_sqrt<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>sqrt<VSs> %x0,%x1" - [(set_attr "type" "<VStype_sqrt>") - (set_attr "fp_type" "<VSfptype_sqrt>")]) - -(define_insn "*vsx_rsqrte<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_RSQRT))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>rsqrte<VSs> %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -;; *tsqrt* returning the fg flag -(define_expand "vsx_tsqrt<mode>2_fg" - [(set (match_dup 3) - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")] - UNSPEC_VSX_TSQRT)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (gt:SI (match_dup 3) - (const_int 0)))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" -{ - operands[3] = gen_reg_rtx (CCFPmode); -}) - -;; *tsqrt* returning the fe flag -(define_expand "vsx_tsqrt<mode>2_fe" - [(set (match_dup 3) - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")] - UNSPEC_VSX_TSQRT)) - (set (match_operand:SI 0 "gpc_reg_operand" "") - (eq:SI (match_dup 3) - (const_int 0)))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" -{ - operands[3] = gen_reg_rtx (CCFPmode); -}) - -(define_insn "*vsx_tsqrt<mode>2_internal" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x") - (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_VSX_TSQRT))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>tsqrt<VSs> %0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -;; Fused vector multiply/add instructions Support the classical DF versions of -;; fma, which allows the target to be a separate register from the 3 inputs. -;; Under VSX, the target must be either the addend or the first multiply. -;; Where we can, also do the same for the Altivec V4SF fmas. - -(define_insn "*vsx_fmadf4" - [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d") - (fma:DF - (match_operand:DF 1 "vsx_register_operand" "%ws,ws,wa,wa,d") - (match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d") - (match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d")))] - "VECTOR_UNIT_VSX_P (DFmode)" - "@ - xsmaddadp %x0,%x1,%x2 - xsmaddmdp %x0,%x1,%x3 - xsmaddadp %x0,%x1,%x2 - xsmaddmdp %x0,%x1,%x3 - fmadd %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_insn "*vsx_fmav4sf4" - [(set (match_operand:V4SF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,v") - (fma:V4SF - (match_operand:V4SF 1 "vsx_register_operand" "%ws,ws,wa,wa,v") - (match_operand:V4SF 2 "vsx_register_operand" "ws,0,wa,0,v") - (match_operand:V4SF 3 "vsx_register_operand" "0,ws,0,wa,v")))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "@ - xvmaddasp %x0,%x1,%x2 - xvmaddmsp %x0,%x1,%x3 - xvmaddasp %x0,%x1,%x2 - xvmaddmsp %x0,%x1,%x3 - vmaddfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - -(define_insn "*vsx_fmav2df4" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa") - (fma:V2DF - (match_operand:V2DF 1 "vsx_register_operand" "%ws,ws,wa,wa") - (match_operand:V2DF 2 "vsx_register_operand" "ws,0,wa,0") - (match_operand:V2DF 3 "vsx_register_operand" "0,ws,0,wa")))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "@ - xvmaddadp %x0,%x1,%x2 - xvmaddmdp %x0,%x1,%x3 - xvmaddadp %x0,%x1,%x2 - xvmaddmdp %x0,%x1,%x3" - [(set_attr "type" "vecdouble")]) - -(define_insn "*vsx_fmsdf4" - [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d") - (fma:DF - (match_operand:DF 1 "vsx_register_operand" "%ws,ws,wa,wa,d") - (match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d") - (neg:DF - (match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d"))))] - "VECTOR_UNIT_VSX_P (DFmode)" - "@ - xsmsubadp %x0,%x1,%x2 - xsmsubmdp %x0,%x1,%x3 - xsmsubadp %x0,%x1,%x2 - xsmsubmdp %x0,%x1,%x3 - fmsub %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_insn "*vsx_fms<mode>4" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") - (fma:VSX_F - (match_operand:VSX_F 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,wa,0") - (neg:VSX_F - (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "@ - x<VSv>msuba<VSs> %x0,%x1,%x2 - x<VSv>msubm<VSs> %x0,%x1,%x3 - x<VSv>msuba<VSs> %x0,%x1,%x2 - x<VSv>msubm<VSs> %x0,%x1,%x3" - [(set_attr "type" "<VStype_mul>")]) - -(define_insn "*vsx_nfmadf4" - [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d") - (neg:DF - (fma:DF - (match_operand:DF 1 "vsx_register_operand" "ws,ws,wa,wa,d") - (match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d") - (match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d"))))] - "VECTOR_UNIT_VSX_P (DFmode)" - "@ - xsnmaddadp %x0,%x1,%x2 - xsnmaddmdp %x0,%x1,%x3 - xsnmaddadp %x0,%x1,%x2 - xsnmaddmdp %x0,%x1,%x3 - fnmadd %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_insn "*vsx_nfma<mode>4" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") - (neg:VSX_F - (fma:VSX_F - (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,wa,0") - (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "@ - x<VSv>nmadda<VSs> %x0,%x1,%x2 - x<VSv>nmaddm<VSs> %x0,%x1,%x3 - x<VSv>nmadda<VSs> %x0,%x1,%x2 - x<VSv>nmaddm<VSs> %x0,%x1,%x3" - [(set_attr "type" "<VStype_mul>") - (set_attr "fp_type" "<VSfptype_mul>")]) - -(define_insn "*vsx_nfmsdf4" - [(set (match_operand:DF 0 "vsx_register_operand" "=ws,ws,?wa,?wa,d") - (neg:DF - (fma:DF - (match_operand:DF 1 "vsx_register_operand" "%ws,ws,wa,wa,d") - (match_operand:DF 2 "vsx_register_operand" "ws,0,wa,0,d") - (neg:DF - (match_operand:DF 3 "vsx_register_operand" "0,ws,0,wa,d")))))] - "VECTOR_UNIT_VSX_P (DFmode)" - "@ - xsnmsubadp %x0,%x1,%x2 - xsnmsubmdp %x0,%x1,%x3 - xsnmsubadp %x0,%x1,%x2 - xsnmsubmdp %x0,%x1,%x3 - fnmsub %0,%1,%2,%3" - [(set_attr "type" "fp") - (set_attr "fp_type" "fp_maddsub_d")]) - -(define_insn "*vsx_nfmsv4sf4" - [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,wf,?wa,?wa,v") - (neg:V4SF - (fma:V4SF - (match_operand:V4SF 1 "vsx_register_operand" "%wf,wf,wa,wa,v") - (match_operand:V4SF 2 "vsx_register_operand" "wf,0,wa,0,v") - (neg:V4SF - (match_operand:V4SF 3 "vsx_register_operand" "0,wf,0,wa,v")))))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "@ - xvnmsubasp %x0,%x1,%x2 - xvnmsubmsp %x0,%x1,%x3 - xvnmsubasp %x0,%x1,%x2 - xvnmsubmsp %x0,%x1,%x3 - vnmsubfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - -(define_insn "*vsx_nfmsv2df4" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,?wa,?wa") - (neg:V2DF - (fma:V2DF - (match_operand:V2DF 1 "vsx_register_operand" "%wd,wd,wa,wa") - (match_operand:V2DF 2 "vsx_register_operand" "wd,0,wa,0") - (neg:V2DF - (match_operand:V2DF 3 "vsx_register_operand" "0,wd,0,wa")))))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "@ - xvnmsubadp %x0,%x1,%x2 - xvnmsubmdp %x0,%x1,%x3 - xvnmsubadp %x0,%x1,%x2 - xvnmsubmdp %x0,%x1,%x3" - [(set_attr "type" "vecdouble")]) - -;; Vector conditional expressions (no scalar version for these instructions) -(define_insn "vsx_eq<mode>" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "xvcmpeq<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_gt<mode>" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "xvcmpgt<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "*vsx_ge<mode>" - [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "xvcmpge<VSs> %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -;; Floating point scalar compare -(define_insn "*vsx_cmpdf_internal1" - [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,?y") - (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "ws,wa") - (match_operand:DF 2 "gpc_reg_operand" "ws,wa")))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && VECTOR_UNIT_VSX_P (DFmode)" - "xscmpudp %0,%x1,%x2" - [(set_attr "type" "fpcompare")]) - -;; Compare vectors producing a vector result and a predicate, setting CR6 to -;; indicate a combined status -(define_insn "*vsx_eq_<mode>_p" - [(set (reg:CC 74) - (unspec:CC - [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] - UNSPEC_PREDICATE)) - (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (eq:VSX_F (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "xvcmpeq<VSs>. %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>")]) - -(define_insn "*vsx_gt_<mode>_p" - [(set (reg:CC 74) - (unspec:CC - [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] - UNSPEC_PREDICATE)) - (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (gt:VSX_F (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "xvcmpgt<VSs>. %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>")]) - -(define_insn "*vsx_ge_<mode>_p" - [(set (reg:CC 74) - (unspec:CC - [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?wa"))] - UNSPEC_PREDICATE)) - (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?wa") - (ge:VSX_F (match_dup 1) - (match_dup 2)))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "xvcmpge<VSs>. %x0,%x1,%x2" - [(set_attr "type" "<VStype_simple>")]) - -;; Vector select -(define_insn "*vsx_xxsel<mode>" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (if_then_else:VSX_L - (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_L 4 "zero_constant" "")) - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxsel %x0,%x3,%x2,%x1" - [(set_attr "type" "vecperm")]) - -(define_insn "*vsx_xxsel<mode>_uns" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (if_then_else:VSX_L - (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_L 4 "zero_constant" "")) - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxsel %x0,%x3,%x2,%x1" - [(set_attr "type" "vecperm")]) - -;; Copy sign -(define_insn "vsx_copysign<mode>3" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B - [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") - (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_COPYSIGN))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>cpsgn<VSs> %x0,%x2,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -;; For the conversions, limit the register class for the integer value to be -;; the fprs because we don't want to add the altivec registers to movdi/movsi. -;; For the unsigned tests, there isn't a generic double -> unsigned conversion -;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX. -;; Don't use vsx_register_operand here, use gpc_reg_operand to match rs6000.md. -(define_insn "vsx_float<VSi><mode>2" - [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?wa") - (float:VSX_B (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>cvsx<VSc><VSs> %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_floatuns<VSi><mode>2" - [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?wa") - (unsigned_float:VSX_B (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>cvux<VSc><VSs> %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_fix_trunc<mode><VSi>2" - [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>") - (fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>cv<VSs>sx<VSc>s %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_fixuns_trunc<mode><VSi>2" - [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>") - (unsigned_fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>cv<VSs>ux<VSc>s %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -;; Math rounding functions -(define_insn "vsx_x<VSv>r<VSs>i" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_VSX_ROUND_I))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>r<VSs>i %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_x<VSv>r<VSs>ic" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_VSX_ROUND_IC))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>r<VSs>ic %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_btrunc<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (fix:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>r<VSs>iz %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "*vsx_b2trunc<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_FRIZ))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>r<VSs>iz %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_floor<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_FRIM))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>r<VSs>im %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - -(define_insn "vsx_ceil<mode>2" - [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") - (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] - UNSPEC_FRIP))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "x<VSv>r<VSs>ip %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - - -;; VSX convert to/from double vector - -;; Convert between single and double precision -;; Don't use xscvspdp and xscvdpsp for scalar conversions, since the normal -;; scalar single precision instructions internally use the double format. -;; Prefer the altivec registers, since we likely will need to do a vperm -(define_insn "vsx_<VS_spdp_insn>" - [(set (match_operand:<VS_spdp_res> 0 "vsx_register_operand" "=<VSr4>,?wa") - (unspec:<VS_spdp_res> [(match_operand:VSX_SPDP 1 "vsx_register_operand" "<VSr5>,wa")] - UNSPEC_VSX_CVSPDP))] - "VECTOR_UNIT_VSX_P (<MODE>mode)" - "<VS_spdp_insn> %x0,%x1" - [(set_attr "type" "<VS_spdp_type>")]) - -;; xscvspdp, represent the scalar SF type as V4SF -(define_insn "vsx_xscvspdp" - [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?wa") - (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")] - UNSPEC_VSX_CVSPDP))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "xscvspdp %x0,%x1" - [(set_attr "type" "fp")]) - -;; xscvdpsp used for splat'ing a scalar to V4SF, knowing that the internal SF -;; format of scalars is actually DF. -(define_insn "vsx_xscvdpsp_scalar" - [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") - (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f")] - UNSPEC_VSX_CVSPDP))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "xscvdpsp %x0,%x1" - [(set_attr "type" "fp")]) - -;; Same as vsx_xscvspdp, but use SF as the type -(define_insn "vsx_xscvspdp_scalar2" - [(set (match_operand:SF 0 "vsx_register_operand" "=f") - (unspec:SF [(match_operand:V4SF 1 "vsx_register_operand" "wa")] - UNSPEC_VSX_CVSPDP))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "xscvspdp %x0,%x1" - [(set_attr "type" "fp")]) - -;; Convert from 64-bit to 32-bit types -;; Note, favor the Altivec registers since the usual use of these instructions -;; is in vector converts and we need to use the Altivec vperm instruction. - -(define_insn "vsx_xvcvdpsxws" - [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa") - (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")] - UNSPEC_VSX_CVDPSXWS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvdpsxws %x0,%x1" - [(set_attr "type" "vecdouble")]) - -(define_insn "vsx_xvcvdpuxws" - [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa") - (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")] - UNSPEC_VSX_CVDPUXWS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvdpuxws %x0,%x1" - [(set_attr "type" "vecdouble")]) - -(define_insn "vsx_xvcvsxdsp" - [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa") - (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")] - UNSPEC_VSX_CVSXDSP))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvsxdsp %x0,%x1" - [(set_attr "type" "vecfloat")]) - -(define_insn "vsx_xvcvuxdsp" - [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa") - (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")] - UNSPEC_VSX_CVUXDSP))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvuxwdp %x0,%x1" - [(set_attr "type" "vecdouble")]) - -;; Convert from 32-bit to 64-bit types -(define_insn "vsx_xvcvsxwdp" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") - (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")] - UNSPEC_VSX_CVSXWDP))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvsxwdp %x0,%x1" - [(set_attr "type" "vecdouble")]) - -(define_insn "vsx_xvcvuxwdp" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") - (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")] - UNSPEC_VSX_CVUXWDP))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvuxwdp %x0,%x1" - [(set_attr "type" "vecdouble")]) - -(define_insn "vsx_xvcvspsxds" - [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") - (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")] - UNSPEC_VSX_CVSPSXDS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvspsxds %x0,%x1" - [(set_attr "type" "vecdouble")]) - -(define_insn "vsx_xvcvspuxds" - [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") - (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")] - UNSPEC_VSX_CVSPUXDS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvspuxds %x0,%x1" - [(set_attr "type" "vecdouble")]) - -;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since -;; since the xsrdpiz instruction does not truncate the value if the floating -;; point value is < LONG_MIN or > LONG_MAX. -(define_insn "*vsx_float_fix_<mode>2" - [(set (match_operand:VSX_DF 0 "vsx_register_operand" "=<VSr>,?wa") - (float:VSX_DF - (fix:<VSI> - (match_operand:VSX_DF 1 "vsx_register_operand" "<VSr>,?wa"))))] - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT - && VECTOR_UNIT_VSX_P (<MODE>mode) && flag_unsafe_math_optimizations - && !flag_trapping_math && TARGET_FRIZ" - "x<VSv>r<VSs>iz %x0,%x1" - [(set_attr "type" "<VStype_simple>") - (set_attr "fp_type" "<VSfptype_simple>")]) - - -;; Logical and permute operations -(define_insn "*vsx_and<mode>3" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (and:VSX_L - (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxland %x0,%x1,%x2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*vsx_ior<mode>3" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (ior:VSX_L (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxlor %x0,%x1,%x2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*vsx_xor<mode>3" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (xor:VSX_L - (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxlxor %x0,%x1,%x2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*vsx_one_cmpl<mode>2" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (not:VSX_L - (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxlnor %x0,%x1,%x1" - [(set_attr "type" "vecsimple")]) - -(define_insn "*vsx_nor<mode>3" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (not:VSX_L - (ior:VSX_L - (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa") - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa"))))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxlnor %x0,%x1,%x2" - [(set_attr "type" "vecsimple")]) - -(define_insn "*vsx_andc<mode>3" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") - (and:VSX_L - (not:VSX_L - (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,?wa")) - (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,?wa")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxlandc %x0,%x1,%x2" - [(set_attr "type" "vecsimple")]) - - -;; Permute operations - -;; Build a V2DF/V2DI vector from two scalars -(define_insn "vsx_concat_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa") - (unspec:VSX_D - [(match_operand:<VS_scalar> 1 "vsx_register_operand" "ws,wa") - (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa")] - UNSPEC_VSX_CONCAT))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxpermdi %x0,%x1,%x2,0" - [(set_attr "type" "vecperm")]) - -;; Special purpose concat using xxpermdi to glue two single precision values -;; together, relying on the fact that internally scalar floats are represented -;; as doubles. This is used to initialize a V4SF vector with 4 floats -(define_insn "vsx_concat_v2sf" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa") - (unspec:V2DF - [(match_operand:SF 1 "vsx_register_operand" "f,f") - (match_operand:SF 2 "vsx_register_operand" "f,f")] - UNSPEC_VSX_CONCAT))] - "VECTOR_MEM_VSX_P (V2DFmode)" - "xxpermdi %x0,%x1,%x2,0" - [(set_attr "type" "vecperm")]) - -;; Set the element of a V2DI/VD2F mode -(define_insn "vsx_set_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?wa") - (unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wd,wa") - (match_operand:<VS_scalar> 2 "vsx_register_operand" "ws,wa") - (match_operand:QI 3 "u5bit_cint_operand" "i,i")] - UNSPEC_VSX_SET))] - "VECTOR_MEM_VSX_P (<MODE>mode)" -{ - if (INTVAL (operands[3]) == 0) - return \"xxpermdi %x0,%x2,%x1,1\"; - else if (INTVAL (operands[3]) == 1) - return \"xxpermdi %x0,%x1,%x2,0\"; - else - gcc_unreachable (); -} - [(set_attr "type" "vecperm")]) - -;; Extract a DF/DI element from V2DF/V2DI -(define_insn "vsx_extract_<mode>" - [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=ws,d,?wa") - (vec_select:<VS_scalar> (match_operand:VSX_D 1 "vsx_register_operand" "wd,wd,wa") - (parallel - [(match_operand:QI 2 "u5bit_cint_operand" "i,i,i")])))] - "VECTOR_MEM_VSX_P (<MODE>mode)" -{ - gcc_assert (UINTVAL (operands[2]) <= 1); - operands[3] = GEN_INT (INTVAL (operands[2]) << 1); - return \"xxpermdi %x0,%x1,%x1,%3\"; -} - [(set_attr "type" "vecperm")]) - -;; Optimize extracting element 0 from memory -(define_insn "*vsx_extract_<mode>_zero" - [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=ws,d,?wa") - (vec_select:<VS_scalar> - (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z") - (parallel [(const_int 0)])))] - "VECTOR_MEM_VSX_P (<MODE>mode) && WORDS_BIG_ENDIAN" - "lxsd%U1x %x0,%y1" - [(set_attr "type" "fpload") - (set_attr "length" "4")]) - -;; Extract a SF element from V4SF -(define_insn_and_split "vsx_extract_v4sf" - [(set (match_operand:SF 0 "vsx_register_operand" "=f,f") - (vec_select:SF - (match_operand:V4SF 1 "vsx_register_operand" "wa,wa") - (parallel [(match_operand:QI 2 "u5bit_cint_operand" "O,i")]))) - (clobber (match_scratch:V4SF 3 "=X,0"))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "@ - xscvspdp %x0,%x1 - #" - "" - [(const_int 0)] - " -{ - rtx op0 = operands[0]; - rtx op1 = operands[1]; - rtx op2 = operands[2]; - rtx op3 = operands[3]; - rtx tmp; - HOST_WIDE_INT ele = INTVAL (op2); - - if (ele == 0) - tmp = op1; - else - { - if (GET_CODE (op3) == SCRATCH) - op3 = gen_reg_rtx (V4SFmode); - emit_insn (gen_vsx_xxsldwi_v4sf (op3, op1, op1, op2)); - tmp = op3; - } - emit_insn (gen_vsx_xscvspdp_scalar2 (op0, tmp)); - DONE; -}" - [(set_attr "length" "4,8") - (set_attr "type" "fp")]) - -;; Expand the builtin form of xxpermdi to canonical rtl. -(define_expand "vsx_xxpermdi_<mode>" - [(match_operand:VSX_L 0 "vsx_register_operand" "") - (match_operand:VSX_L 1 "vsx_register_operand" "") - (match_operand:VSX_L 2 "vsx_register_operand" "") - (match_operand:QI 3 "u5bit_cint_operand" "")] - "VECTOR_MEM_VSX_P (<MODE>mode)" -{ - rtx target = operands[0]; - rtx op0 = operands[1]; - rtx op1 = operands[2]; - int mask = INTVAL (operands[3]); - rtx perm0 = GEN_INT ((mask >> 1) & 1); - rtx perm1 = GEN_INT ((mask & 1) + 2); - rtx (*gen) (rtx, rtx, rtx, rtx, rtx); - - if (<MODE>mode == V2DFmode) - gen = gen_vsx_xxpermdi2_v2df_1; - else - { - gen = gen_vsx_xxpermdi2_v2di_1; - if (<MODE>mode != V2DImode) - { - target = gen_lowpart (V2DImode, target); - op0 = gen_lowpart (V2DImode, target); - op1 = gen_lowpart (V2DImode, target); - } - } - emit_insn (gen (target, op0, op1, perm0, perm1)); - DONE; -}) - -(define_insn "vsx_xxpermdi2_<mode>_1" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd") - (vec_select:VSX_D - (vec_concat:<VS_double> - (match_operand:VSX_D 1 "vsx_register_operand" "wd") - (match_operand:VSX_D 2 "vsx_register_operand" "wd")) - (parallel [(match_operand 3 "const_0_to_1_operand" "") - (match_operand 4 "const_2_to_3_operand" "")])))] - "VECTOR_MEM_VSX_P (<MODE>mode)" -{ - int mask = (INTVAL (operands[3]) << 1) | (INTVAL (operands[4]) - 2); - operands[3] = GEN_INT (mask); - return "xxpermdi %x0,%x1,%x2,%3"; -} - [(set_attr "type" "vecperm")]) - -(define_expand "vec_perm_const<mode>" - [(match_operand:VSX_D 0 "vsx_register_operand" "") - (match_operand:VSX_D 1 "vsx_register_operand" "") - (match_operand:VSX_D 2 "vsx_register_operand" "") - (match_operand:V2DI 3 "" "")] - "VECTOR_MEM_VSX_P (<MODE>mode)" -{ - if (rs6000_expand_vec_perm_const (operands)) - DONE; - else - FAIL; -}) - -;; Expanders for builtins -(define_expand "vsx_mergel_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "") - (vec_select:VSX_D - (vec_concat:<VS_double> - (match_operand:VSX_D 1 "vsx_register_operand" "") - (match_operand:VSX_D 2 "vsx_register_operand" "")) - (parallel [(const_int 1) (const_int 3)])))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "") - -(define_expand "vsx_mergeh_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "") - (vec_select:VSX_D - (vec_concat:<VS_double> - (match_operand:VSX_D 1 "vsx_register_operand" "") - (match_operand:VSX_D 2 "vsx_register_operand" "")) - (parallel [(const_int 0) (const_int 2)])))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "") - -;; V2DF/V2DI splat -(define_insn "vsx_splat_<mode>" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,wd,wd,?wa,?wa,?wa") - (vec_duplicate:VSX_D - (match_operand:<VS_scalar> 1 "splat_input_operand" "ws,f,Z,wa,wa,Z")))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "@ - xxpermdi %x0,%x1,%x1,0 - xxpermdi %x0,%x1,%x1,0 - lxvdsx %x0,%y1 - xxpermdi %x0,%x1,%x1,0 - xxpermdi %x0,%x1,%x1,0 - lxvdsx %x0,%y1" - [(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")]) - -;; V4SF/V4SI splat -(define_insn "vsx_xxspltw_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") - (vec_duplicate:VSX_W - (vec_select:<VS_scalar> - (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") - (parallel - [(match_operand:QI 2 "u5bit_cint_operand" "i,i")]))))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxspltw %x0,%x1,%2" - [(set_attr "type" "vecperm")]) - -;; V4SF/V4SI interleave -(define_insn "vsx_xxmrghw_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") - (vec_select:VSX_W - (vec_concat:<VS_double> - (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") - (match_operand:VSX_W 2 "vsx_register_operand" "wf,wa")) - (parallel [(const_int 0) (const_int 4) - (const_int 1) (const_int 5)])))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxmrghw %x0,%x1,%x2" - [(set_attr "type" "vecperm")]) - -(define_insn "vsx_xxmrglw_<mode>" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?wa") - (vec_select:VSX_W - (vec_concat:<VS_double> - (match_operand:VSX_W 1 "vsx_register_operand" "wf,wa") - (match_operand:VSX_W 2 "vsx_register_operand" "wf,?wa")) - (parallel [(const_int 2) (const_int 6) - (const_int 3) (const_int 7)])))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxmrglw %x0,%x1,%x2" - [(set_attr "type" "vecperm")]) - -;; Shift left double by word immediate -(define_insn "vsx_xxsldwi_<mode>" - [(set (match_operand:VSX_L 0 "vsx_register_operand" "=wa") - (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "wa") - (match_operand:VSX_L 2 "vsx_register_operand" "wa") - (match_operand:QI 3 "u5bit_cint_operand" "i")] - UNSPEC_VSX_SLDWI))] - "VECTOR_MEM_VSX_P (<MODE>mode)" - "xxsldwi %x0,%x1,%x2,%3" - [(set_attr "type" "vecperm")]) - - -;; Vector reduction insns and splitters - -(define_insn_and_split "*vsx_reduc_<VEC_reduc_name>_v2df" - [(set (match_operand:V2DF 0 "vfloat_operand" "=&wd,&?wa,wd,?wa") - (VEC_reduc:V2DF - (vec_concat:V2DF - (vec_select:DF - (match_operand:V2DF 1 "vfloat_operand" "wd,wa,wd,wa") - (parallel [(const_int 1)])) - (vec_select:DF - (match_dup 1) - (parallel [(const_int 0)]))) - (match_dup 1))) - (clobber (match_scratch:V2DF 2 "=0,0,&wd,&wa"))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "#" - "" - [(const_int 0)] - " -{ - rtx tmp = (GET_CODE (operands[2]) == SCRATCH) - ? gen_reg_rtx (V2DFmode) - : operands[2]; - emit_insn (gen_vsx_xxsldwi_v2df (tmp, operands[1], operands[1], const2_rtx)); - emit_insn (gen_<VEC_reduc_rtx>v2df3 (operands[0], tmp, operands[1])); - DONE; -}" - [(set_attr "length" "8") - (set_attr "type" "veccomplex")]) - -(define_insn_and_split "*vsx_reduc_<VEC_reduc_name>_v4sf" - [(set (match_operand:V4SF 0 "vfloat_operand" "=wf,?wa") - (VEC_reduc:V4SF - (unspec:V4SF [(const_int 0)] UNSPEC_REDUC) - (match_operand:V4SF 1 "vfloat_operand" "wf,wa"))) - (clobber (match_scratch:V4SF 2 "=&wf,&wa")) - (clobber (match_scratch:V4SF 3 "=&wf,&wa"))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "#" - "" - [(const_int 0)] - " -{ - rtx op0 = operands[0]; - rtx op1 = operands[1]; - rtx tmp2, tmp3, tmp4; - - if (can_create_pseudo_p ()) - { - tmp2 = gen_reg_rtx (V4SFmode); - tmp3 = gen_reg_rtx (V4SFmode); - tmp4 = gen_reg_rtx (V4SFmode); - } - else - { - tmp2 = operands[2]; - tmp3 = operands[3]; - tmp4 = tmp2; - } - - emit_insn (gen_vsx_xxsldwi_v4sf (tmp2, op1, op1, const2_rtx)); - emit_insn (gen_<VEC_reduc_rtx>v4sf3 (tmp3, tmp2, op1)); - emit_insn (gen_vsx_xxsldwi_v4sf (tmp4, tmp3, tmp3, GEN_INT (3))); - emit_insn (gen_<VEC_reduc_rtx>v4sf3 (op0, tmp4, tmp3)); - DONE; -}" - [(set_attr "length" "16") - (set_attr "type" "veccomplex")]) - -;; Combiner patterns with the vector reduction patterns that knows we can get -;; to the top element of the V2DF array without doing an extract. - -(define_insn_and_split "*vsx_reduc_<VEC_reduc_name>_v2df_scalar" - [(set (match_operand:DF 0 "vfloat_operand" "=&ws,&?wa,ws,?wa") - (vec_select:DF - (VEC_reduc:V2DF - (vec_concat:V2DF - (vec_select:DF - (match_operand:V2DF 1 "vfloat_operand" "wd,wa,wd,wa") - (parallel [(const_int 1)])) - (vec_select:DF - (match_dup 1) - (parallel [(const_int 0)]))) - (match_dup 1)) - (parallel [(const_int 1)]))) - (clobber (match_scratch:DF 2 "=0,0,&wd,&wa"))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "#" - "" - [(const_int 0)] - " -{ - rtx hi = gen_highpart (DFmode, operands[1]); - rtx lo = (GET_CODE (operands[2]) == SCRATCH) - ? gen_reg_rtx (DFmode) - : operands[2]; - - emit_insn (gen_vsx_extract_v2df (lo, operands[1], const1_rtx)); - emit_insn (gen_<VEC_reduc_rtx>df3 (operands[0], hi, lo)); - DONE; -}" - [(set_attr "length" "8") - (set_attr "type" "veccomplex")]) - -(define_insn_and_split "*vsx_reduc_<VEC_reduc_name>_v4sf_scalar" - [(set (match_operand:SF 0 "vfloat_operand" "=f,?f") - (vec_select:SF - (VEC_reduc:V4SF - (unspec:V4SF [(const_int 0)] UNSPEC_REDUC) - (match_operand:V4SF 1 "vfloat_operand" "wf,wa")) - (parallel [(const_int 3)]))) - (clobber (match_scratch:V4SF 2 "=&wf,&wa")) - (clobber (match_scratch:V4SF 3 "=&wf,&wa")) - (clobber (match_scratch:V4SF 4 "=0,0"))] - "VECTOR_UNIT_VSX_P (V4SFmode)" - "#" - "" - [(const_int 0)] - " -{ - rtx op0 = operands[0]; - rtx op1 = operands[1]; - rtx tmp2, tmp3, tmp4, tmp5; - - if (can_create_pseudo_p ()) - { - tmp2 = gen_reg_rtx (V4SFmode); - tmp3 = gen_reg_rtx (V4SFmode); - tmp4 = gen_reg_rtx (V4SFmode); - tmp5 = gen_reg_rtx (V4SFmode); - } - else - { - tmp2 = operands[2]; - tmp3 = operands[3]; - tmp4 = tmp2; - tmp5 = operands[4]; - } - - emit_insn (gen_vsx_xxsldwi_v4sf (tmp2, op1, op1, const2_rtx)); - emit_insn (gen_<VEC_reduc_rtx>v4sf3 (tmp3, tmp2, op1)); - emit_insn (gen_vsx_xxsldwi_v4sf (tmp4, tmp3, tmp3, GEN_INT (3))); - emit_insn (gen_<VEC_reduc_rtx>v4sf3 (tmp5, tmp4, tmp3)); - emit_insn (gen_vsx_xscvspdp_scalar2 (op0, tmp5)); - DONE; -}" - [(set_attr "length" "20") - (set_attr "type" "veccomplex")]) diff --git a/gcc-4.8.1/gcc/config/rs6000/vxworks.h b/gcc-4.8.1/gcc/config/rs6000/vxworks.h deleted file mode 100644 index 427a05102..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/vxworks.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Definitions of target machine for GNU compiler. Vxworks PowerPC version. - Copyright (C) 1996-2013 Free Software Foundation, Inc. - Contributed by CodeSourcery, LLC. - -This file is part of GCC. - -GCC is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 3, or (at your option) any later -version. - -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -/* Note to future editors: VxWorks is mostly an EABI target. We do - not use rs6000/eabi.h because we would have to override most of - it anyway. However, if you change that file, consider making - analogous changes here too. */ - -/* CPP predefined macros. */ - -#undef TARGET_OS_CPP_BUILTINS -#define TARGET_OS_CPP_BUILTINS() \ - do \ - { \ - builtin_define ("__ppc"); \ - builtin_define ("__PPC__"); \ - builtin_define ("__EABI__"); \ - builtin_define ("__ELF__"); \ - if (!TARGET_SOFT_FLOAT) \ - builtin_define ("__hardfp"); \ - \ - /* C89 namespace violation! */ \ - builtin_define ("CPU_FAMILY=PPC"); \ - \ - VXWORKS_OS_CPP_BUILTINS (); \ - } \ - while (0) - -/* Only big endian PPC is supported by VxWorks. */ -#undef BYTES_BIG_ENDIAN -#define BYTES_BIG_ENDIAN 1 -#undef WORDS_BIG_ENDIAN -#define WORDS_BIG_ENDIAN 1 - -/* 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 */ - -/* FIXME: The only reason we allow no -mcpu switch at all is because - config-ml.in insists on a "." multilib. */ -#define CPP_SPEC \ -"%{!DCPU=*: \ - %{mcpu=403 : -DCPU=PPC403 ; \ - mcpu=405 : -DCPU=PPC405 ; \ - mcpu=440 : -DCPU=PPC440 ; \ - mcpu=464 : -DCPU=PPC464 ; \ - mcpu=476 : -DCPU=PPC476 ; \ - mcpu=603 : -DCPU=PPC603 ; \ - mcpu=604 : -DCPU=PPC604 ; \ - mcpu=860 : -DCPU=PPC860 ; \ - mcpu=8540: -DCPU=PPC85XX ; \ - : -DCPU=PPC604 }}" \ -VXWORKS_ADDITIONAL_CPP_SPEC - -#define CC1_SPEC \ -"%{G*} %{mno-sdata:-msdata=none} %{msdata:-msdata=default} \ - %{mlittle|mlittle-endian:-mstrict-align}" - -#define ASM_SPEC \ -"%(asm_cpu) \ - %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ - %{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} -mbig" - -#undef LIB_SPEC -#define LIB_SPEC VXWORKS_LIB_SPEC -#undef LINK_SPEC -#define LINK_SPEC VXWORKS_LINK_SPEC -#undef STARTFILE_SPEC -#define STARTFILE_SPEC VXWORKS_STARTFILE_SPEC -#undef ENDFILE_SPEC -#define ENDFILE_SPEC VXWORKS_ENDFILE_SPEC - -/* There is no default multilib. */ -#undef MULTILIB_DEFAULTS - -#undef TARGET_DEFAULT -#define TARGET_DEFAULT (MASK_EABI | MASK_STRICT_ALIGN) - -#undef PROCESSOR_DEFAULT -#define PROCESSOR_DEFAULT PROCESSOR_PPC604 - -/* Nor sdata, for kernel mode. We use this in - SUBSUBTARGET_INITIALIZE_OPTIONS, after rs6000_rtp has been initialized. */ -#undef SDATA_DEFAULT_SIZE -#define SDATA_DEFAULT_SIZE (TARGET_VXWORKS_RTP ? 8 : 0) - -/* Enforce 16bytes alignment for the stack pointer, to permit general - compliance with e.g. Altivec instructions requirements. Make sure - this isn't overruled by the EABI constraints. */ - -#undef STACK_BOUNDARY -#define STACK_BOUNDARY (16*BITS_PER_UNIT) - -#undef PREFERRED_STACK_BOUNDARY -#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY - -#undef ABI_STACK_BOUNDARY - -#undef SUBSUBTARGET_OVERRIDE_OPTIONS -#define SUBSUBTARGET_OVERRIDE_OPTIONS \ - do { \ - if (!global_options_set.x_g_switch_value) \ - g_switch_value = SDATA_DEFAULT_SIZE; \ - VXWORKS_OVERRIDE_OPTIONS; \ - } while (0) - -/* No _mcount profiling on VxWorks. */ -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE,LABELNO) VXWORKS_FUNCTION_PROFILER(FILE,LABELNO) diff --git a/gcc-4.8.1/gcc/config/rs6000/x-aix b/gcc-4.8.1/gcc/config/rs6000/x-aix deleted file mode 100644 index d40690f2d..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/x-aix +++ /dev/null @@ -1,6 +0,0 @@ -# genautomata requires more than 256MB of data -build/genautomata : override LDFLAGS += -Wl,-bmaxdata:0x20000000 - -# jc1 requires more than 256MB of data -$(COMPILERS) : override LDFLAGS += -Wl,-bmaxdata:0x40000000 - diff --git a/gcc-4.8.1/gcc/config/rs6000/x-darwin b/gcc-4.8.1/gcc/config/rs6000/x-darwin deleted file mode 100644 index 5672c698b..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/x-darwin +++ /dev/null @@ -1,5 +0,0 @@ -host-ppc-darwin.o : $(srcdir)/config/rs6000/host-darwin.c \ - $(CONFIG_H) $(SYSTEM_H) coretypes.h hosthooks.h $(HOSTHOOKS_DEF_H) toplev.h \ - config/host-darwin.h $(DIAGNOSTIC_H) - $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ - $(INCLUDES) $< -o $@ diff --git a/gcc-4.8.1/gcc/config/rs6000/x-darwin64 b/gcc-4.8.1/gcc/config/rs6000/x-darwin64 deleted file mode 100644 index 921d555ba..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/x-darwin64 +++ /dev/null @@ -1,5 +0,0 @@ -host-ppc64-darwin.o : $(srcdir)/config/rs6000/host-ppc64-darwin.c \ - $(CONFIG_H) $(SYSTEM_H) coretypes.h hosthooks.h $(HOSTHOOKS_DEF_H) toplev.h \ - config/host-darwin.h $(DIAGNOSTIC_H) - $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ - $(INCLUDES) $< -o $@ diff --git a/gcc-4.8.1/gcc/config/rs6000/x-linux-relax b/gcc-4.8.1/gcc/config/rs6000/x-linux-relax deleted file mode 100644 index 2743a94e4..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/x-linux-relax +++ /dev/null @@ -1,2 +0,0 @@ -# At -O0 cc1 etc. are too large and -Wl,--relax is needed -$(COMPILERS) : override LDFLAGS += -Wl,--relax diff --git a/gcc-4.8.1/gcc/config/rs6000/x-rs6000 b/gcc-4.8.1/gcc/config/rs6000/x-rs6000 deleted file mode 100644 index 9e31f24cd..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/x-rs6000 +++ /dev/null @@ -1,3 +0,0 @@ -driver-rs6000.o : $(srcdir)/config/rs6000/driver-rs6000.c \ - $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h - $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< diff --git a/gcc-4.8.1/gcc/config/rs6000/xcoff.h b/gcc-4.8.1/gcc/config/rs6000/xcoff.h deleted file mode 100644 index 512bcb547..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/xcoff.h +++ /dev/null @@ -1,362 +0,0 @@ -/* Definitions of target machine for GNU compiler, - for some generic XCOFF file format - Copyright (C) 2001-2013 Free Software Foundation, Inc. - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -#define TARGET_OBJECT_FORMAT OBJECT_XCOFF - -/* The RS/6000 uses the XCOFF format. */ -#define XCOFF_DEBUGGING_INFO 1 - -/* Define if the object format being used is COFF or a superset. */ -#define OBJECT_FORMAT_COFF - -/* Define the magic numbers that we recognize as COFF. - - AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects and AIX V5 adds - U64_TOCMAGIC (0767), but collect2.c does not include files in the - correct order to conditionally define the symbolic name in this macro. - - The AIX linker accepts import/export files as object files, - so accept "#!" (0x2321) magic number. */ -#define MY_ISCOFF(magic) \ - ((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \ - || (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0767 \ - || (magic) == 0x2321) - -/* We don't have GAS for the RS/6000 yet, so don't write out special - .stabs in cc1plus. */ - -#define FASCIST_ASSEMBLER - -/* We define this to prevent the name mangler from putting dollar signs into - function names. */ - -#define NO_DOLLAR_IN_LABEL - -/* We define this to 0 so that gcc will never accept a dollar sign in a - variable name. This is needed because the AIX assembler will not accept - dollar signs. */ - -#define DOLLARS_IN_IDENTIFIERS 0 - -/* AIX .align pseudo-op accept value from 0 to 12, corresponding to - log base 2 of the alignment in bytes; 12 = 4096 bytes = 32768 bits. */ - -#define MAX_OFILE_ALIGNMENT 32768 - -/* Default alignment factor for csect directives, chosen to honor - BIGGEST_ALIGNMENT. */ -#define XCOFF_CSECT_DEFAULT_ALIGNMENT_STR "4" - -/* Return nonzero if this entry is to be written into the constant - pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF - or a CONST containing one of them. If -mfp-in-toc (the default), - we also do this for floating-point constants. We actually can only - do this if the FP formats of the target and host machines are the - same, but we can't check that since not every file that uses these - target macros includes real.h. We also do this when we can write the - entry into the TOC and the entry is not larger than a TOC entry. */ - -#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \ - (TARGET_TOC \ - && (GET_CODE (X) == SYMBOL_REF \ - || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ - && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ - || GET_CODE (X) == LABEL_REF \ - || (GET_CODE (X) == CONST_INT \ - && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \ - || (GET_CODE (X) == CONST_DOUBLE \ - && (TARGET_MINIMAL_TOC \ - || (SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ - && ! TARGET_NO_FP_IN_TOC))))) - -#define TARGET_ASM_OUTPUT_ANCHOR rs6000_xcoff_asm_output_anchor -#define TARGET_ASM_GLOBALIZE_LABEL rs6000_xcoff_asm_globalize_label -#define TARGET_ASM_INIT_SECTIONS rs6000_xcoff_asm_init_sections -#define TARGET_ASM_RELOC_RW_MASK rs6000_xcoff_reloc_rw_mask -#define TARGET_ASM_NAMED_SECTION rs6000_xcoff_asm_named_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_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section -#define TARGET_STRIP_NAME_ENCODING rs6000_xcoff_strip_name_encoding -#define TARGET_SECTION_TYPE_FLAGS rs6000_xcoff_section_type_flags -#ifdef HAVE_AS_TLS -#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info -#endif - -/* FP save and restore routines. */ -#define SAVE_FP_PREFIX "._savef" -#define SAVE_FP_SUFFIX "" -#define RESTORE_FP_PREFIX "._restf" -#define RESTORE_FP_SUFFIX "" - -/* Function name to call to do profiling. */ -#undef RS6000_MCOUNT -#define RS6000_MCOUNT ".__mcount" - -/* This outputs NAME to FILE up to the first null or '['. */ - -#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ - assemble_name ((FILE), (*targetm.strip_name_encoding) (NAME)) - -/* This is how to output the definition of a user-level label named NAME, - such as the label on a static function or variable NAME. */ - -#define ASM_OUTPUT_LABEL(FILE,NAME) \ - do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0) - -/* This is how to output a command to make the user-level label named NAME - defined for reference from other files. */ - -/* Globalizing directive for a label. */ -#define GLOBAL_ASM_OP "\t.globl " - -#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 - output the function descriptor. - Dollar signs are converted to underscores. - - The csect for the function will have already been created when - text_section was selected. We do have to go back to that csect, however. - - 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) \ -{ char *buffer = (char *) alloca (strlen (NAME) + 1); \ - char *p; \ - int dollar_inside = 0; \ - strcpy (buffer, NAME); \ - p = strchr (buffer, '$'); \ - while (p) { \ - *p = '_'; \ - dollar_inside++; \ - p = strchr (p + 1, '$'); \ - } \ - if (TREE_PUBLIC (DECL)) \ - { \ - if (!RS6000_WEAK || !DECL_WEAK (decl)) \ - { \ - if (dollar_inside) { \ - fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \ - fprintf(FILE, "\t.rename %s,\"%s\"\n", buffer, NAME); \ - } \ - fputs ("\t.globl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, buffer); \ - putc ('\n', FILE); \ - } \ - } \ - else \ - { \ - if (dollar_inside) { \ - fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \ - fprintf(FILE, "\t.rename %s,\"%s\"\n", buffer, NAME); \ - } \ - fputs ("\t.lglobl .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, buffer); \ - putc ('\n', FILE); \ - } \ - fputs ("\t.csect ", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, buffer); \ - fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, buffer); \ - fputs (":\n", FILE); \ - fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, buffer); \ - fputs (", TOC[tc0], 0\n", FILE); \ - in_section = NULL; \ - switch_to_section (function_section (DECL)); \ - putc ('.', FILE); \ - RS6000_OUTPUT_BASENAME (FILE, buffer); \ - fputs (":\n", FILE); \ - if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (DECL)) \ - xcoffout_declare_function (FILE, DECL, buffer); \ -} - -/* Output a reference to SYM on FILE. */ - -#define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \ - rs6000_output_symbol_ref (FILE, SYM) - -/* This says how to output an external. - Dollar signs are converted to underscores. */ - -#undef ASM_OUTPUT_EXTERNAL -#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ -{ char *buffer = (char *) alloca (strlen (NAME) + 1); \ - char *p; \ - rtx _symref = XEXP (DECL_RTL (DECL), 0); \ - int dollar_inside = 0; \ - strcpy (buffer, NAME); \ - p = strchr (buffer, '$'); \ - while (p) { \ - *p = '_'; \ - dollar_inside++; \ - p = strchr (p + 1, '$'); \ - } \ - if (dollar_inside) { \ - fputs ("\t.extern .", FILE); \ - RS6000_OUTPUT_BASENAME (FILE, buffer); \ - putc ('\n', FILE); \ - fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \ - } \ - if ((TREE_CODE (DECL) == VAR_DECL \ - || TREE_CODE (DECL) == FUNCTION_DECL) \ - && (NAME)[strlen (NAME) - 1] != ']') \ - { \ - XSTR (_symref, 0) = concat (XSTR (_symref, 0), \ - (TREE_CODE (DECL) == FUNCTION_DECL \ - ? "[DS]" : "[RW]"), \ - NULL); \ - } \ -} - -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ - -#define ASM_OUTPUT_LABELREF(FILE,NAME) \ - asm_fprintf ((FILE), "%U%s", rs6000_xcoff_strip_dollar (NAME)); - -/* This is how to output an internal label prefix. rs6000.c uses this - when generating traceback tables. */ - -#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ - fprintf (FILE, "%s..", PREFIX) - -/* This is how to output a label for a jump table. Arguments are the same as - 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); (*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 - PREFIX is the class of label and NUM is the number within the class. - This is suitable for output with `assemble_name'. */ - -#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*%s..%u", rs6000_xcoff_strip_dollar (PREFIX), (unsigned) (NUM)) - -/* This is how to output an assembler line to define N characters starting - at P to FILE. */ - -#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N)) - -/* This is how to advance the location counter by SIZE bytes. */ - -#define SKIP_ASM_OP "\t.space " - -#define ASM_OUTPUT_SKIP(FILE,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. */ - -#define COMMON_ASM_OP "\t.comm " - -#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ - do { fputs (COMMON_ASM_OP, (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - if ((ALIGN) > 32) \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \ - floor_log2 ((ALIGN) / BITS_PER_UNIT)); \ - else if ((SIZE) > 4) \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",3\n", (SIZE)); \ - else \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \ - } while (0) - -/* This says how to output an assembler line - to define a local common symbol. - The assembler in AIX 6.1 and later supports an alignment argument. - For earlier releases of AIX, we try to maintain - alignment after preceding TOC section if it was aligned - for 64-bit mode. */ - -#define LOCAL_COMMON_ASM_OP "\t.lcomm " - -#if TARGET_AIX_VERSION >= 61 -#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ - do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - if ((ALIGN) > 32) \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s,%u\n", \ - (SIZE), xcoff_bss_section_name, \ - floor_log2 ((ALIGN) / BITS_PER_UNIT)); \ - else if ((SIZE) > 4) \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s,3\n", \ - (SIZE), xcoff_bss_section_name); \ - else \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s\n", \ - (SIZE), xcoff_bss_section_name); \ - } while (0) -#endif - -#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ - do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s\n", \ - (TARGET_32BIT ? (SIZE) : (ROUNDED)), \ - xcoff_bss_section_name); \ - } while (0) - -#ifdef HAVE_AS_TLS -#define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE) \ - do { fputs(COMMON_ASM_OP, (FILE)); \ - RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ - fprintf ((FILE), "[UL],"HOST_WIDE_INT_PRINT_UNSIGNED"\n", \ - (SIZE)); \ - } while (0) -#endif - -/* This is how we tell the assembler that two symbols have the same value. */ -#define SET_ASM_OP "\t.set " - -/* This is how we tell the assembler to equate two values. */ -#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ - do { fprintf ((FILE), "%s", SET_ASM_OP); \ - RS6000_OUTPUT_BASENAME (FILE, LABEL1); \ - fprintf (FILE, ","); \ - RS6000_OUTPUT_BASENAME (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ - } while (0) - -/* Used by rs6000_assemble_integer, among others. */ -#define DOUBLE_INT_ASM_OP "\t.llong\t" - -/* Output before instructions. */ -#define TEXT_SECTION_ASM_OP "\t.csect .text[PR]" - -/* Output before writable data. */ -#define DATA_SECTION_ASM_OP \ - "\t.csect .data[RW]," XCOFF_CSECT_DEFAULT_ALIGNMENT_STR - - -/* Define to prevent DWARF2 unwind info in the data section rather - than in the .eh_frame section. We do this because the AIX linker - would otherwise garbage collect these sections. */ -#define EH_FRAME_IN_DATA_SECTION 1 diff --git a/gcc-4.8.1/gcc/config/rs6000/xfpu.h b/gcc-4.8.1/gcc/config/rs6000/xfpu.h deleted file mode 100644 index 3bc7f21b8..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/xfpu.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Definitions for Xilinx PowerPC 405/440 APU. - - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Contributed by Michael Eager (eager@eagercon.com) - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - - -/* Undefine definitions from rs6000.h. */ -#undef TARGET_XILINX_FPU - -#define TARGET_XILINX_FPU (rs6000_xilinx_fpu) diff --git a/gcc-4.8.1/gcc/config/rs6000/xfpu.md b/gcc-4.8.1/gcc/config/rs6000/xfpu.md deleted file mode 100644 index 596575938..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/xfpu.md +++ /dev/null @@ -1,140 +0,0 @@ -;; Scheduling description for the Xilinx PowerPC 405 APU Floating Point Unit. -;; Copyright (C) 2008-2013 Free Software Foundation, Inc. -;; Contributed by Michael Eager (eager@eagercon.com). -;; -;; This file is part of GCC. -;; -;; GCC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. -;; -;; GCC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING3. If not see -;; <http://www.gnu.org/licenses/>. - -;;---------------------------------------------------- -;; Xilinx APU FPU Pipeline Description -;; -;; - attr 'type' and 'fp_type' should definitely -;; be cleaned up at some point in the future. -;; ddiv,sdiv,dmul,smul etc are quite confusing. -;; Should use consistent fp* attrs. 'fp_type' -;; should also go away, leaving us only with 'fp' -;; -;;---------------------------------------------------- - -;; ------------------------------------------------------------------------- -;; Latencies -;; Latest latency figures (all in FCB cycles). PowerPC to FPU frequency ratio -;; assumed to be 1/2. (most common deployment) -;; Add 2 PPC cycles for (register file access + wb) and 2 PPC cycles -;; for issue (from PPC) -;; SP DP -;; Loads: 4 6 -;; Stores: 1 2 (from availability of data) -;; Move/Abs/Neg: 1 1 -;; Add/Subtract: 5 7 -;; Multiply: 4 11 -;; Multiply-add: 10 19 -;; Convert (any): 4 6 -;; Divide/Sqrt: 27 56 -;; Compares: 1 2 -;; -;; bypasses needed for forwarding capability of the FPU. -;; Add this at some future time. -;; ------------------------------------------------------------------------- -(define_automaton "Xfpu") -(define_cpu_unit "Xfpu_issue,Xfpu_addsub,Xfpu_mul,Xfpu_div,Xfpu_sqrt" "Xfpu") - - -(define_insn_reservation "fp-default" 2 - (and (and - (eq_attr "type" "fp") - (eq_attr "fp_type" "fp_default")) - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2") - -(define_insn_reservation "fp-compare" 6 - (and (eq_attr "type" "fpcompare") ;; Inconsistent naming - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_addsub") - -(define_insn_reservation "fp-addsub-s" 14 - (and (and - (eq_attr "type" "fp") - (eq_attr "fp_type" "fp_addsub_s")) - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_addsub") - -(define_insn_reservation "fp-addsub-d" 18 - (and (and - (eq_attr "type" "fp") - (eq_attr "fp_type" "fp_addsub_d")) - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_addsub") - -(define_insn_reservation "fp-mul-s" 12 - (and (and - (eq_attr "type" "fp") - (eq_attr "fp_type" "fp_mul_s")) - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_mul") - -(define_insn_reservation "fp-mul-d" 16 ;; Actually 28. Long latencies are killing the automaton formation. Need to figure out why. - (and (and - (eq_attr "type" "fp") - (eq_attr "fp_type" "fp_mul_d")) - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_mul") - -(define_insn_reservation "fp-div-s" 24 ;; Actually 34 - (and (eq_attr "type" "sdiv") ;; Inconsistent attr naming - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_div*10") ;; Unpipelined - -(define_insn_reservation "fp-div-d" 34 ;; Actually 116 - (and (eq_attr "type" "ddiv") - (eq_attr "cpu" "ppc405")) ;; Inconsistent attr naming - "Xfpu_issue*2,Xfpu_div*10") ;; Unpipelined - -(define_insn_reservation "fp-maddsub-s" 24 - (and (and - (eq_attr "type" "fp") - (eq_attr "fp_type" "fp_maddsub_s")) - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_mul,nothing*7,Xfpu_addsub") - -(define_insn_reservation "fp-maddsub-d" 34 ;; Actually 42 - (and (and - (eq_attr "type" "dmul") ;; Inconsistent attr naming - (eq_attr "fp_type" "fp_maddsub_d")) - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_mul,nothing*7,Xfpu_addsub") - -(define_insn_reservation "fp-load" 10 ;; FIXME. Is double/single precision the same ? - (and (eq_attr "type" "fpload, fpload_ux, fpload_u") - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*10") - -(define_insn_reservation "fp-store" 4 - (and (eq_attr "type" "fpstore, fpstore_ux, fpstore_u") - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*4") - -(define_insn_reservation "fp-sqrt-s" 24 ;; Actually 56 - (and (eq_attr "type" "ssqrt") - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_sqrt*10") ;; Unpipelined - - -(define_insn_reservation "fp-sqrt-d" 34 ;; Actually 116 - (and (eq_attr "type" "dsqrt") - (eq_attr "cpu" "ppc405")) - "Xfpu_issue*2,Xfpu_sqrt*10") ;; Unpipelined - diff --git a/gcc-4.8.1/gcc/config/rs6000/xilinx.h b/gcc-4.8.1/gcc/config/rs6000/xilinx.h deleted file mode 100644 index 237c1b7af..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/xilinx.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Support for GCC on Xilinx embedded PowerPC systems - Copyright (C) 2008-2013 Free Software Foundation, Inc. - Contributed by Michael Eager, eager@eagercon.com - - This file is part of GCC. - - GCC is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GCC is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see - <http://www.gnu.org/licenses/>. */ - -/* Set defaults for Xilinx embedded target boards. */ - -#undef CPP_SPEC -#define CPP_SPEC "\ --mxilinx-fpu \ -%{mfpu=sp_lite: -DHAVE_XFPU_SP_LITE} \ -%{mfpu=sp_full: -DHAVE_XFPU_SP_FULL} \ -%{mfpu=dp_lite: -DHAVE_XFPU_DP_LITE} \ -%{mfpu=dp_full: -DHAVE_XFPU_DP_FULL} \ -%{mfpu=*: -DHAVE_XFPU}" - -#undef LIB_DEFAULT_SPEC -#define LIB_DEFAULT_SPEC "\ -%{!nostdlib: --start-group -lxil -lc -lm --end-group \ -%{mppcperflib: %{mfpu=*: -lppcstr405 -lgcc} \ -%{!mfpu=*: -lppcstr405 -lppcfp -lgcc}} \ -%{!mppcperflib: -lgcc}}" - -#undef STARTFILE_DEFAULT_SPEC -#define STARTFILE_DEFAULT_SPEC "\ -ecrti.o%s %{pg: %{!mno-clearbss: xil-pgcrt0.o%s} \ -%{mno-clearbss: xil-sim-pgcrt0.o%s}} \ -%{!pg: %{!mno-clearbss: xil-crt0.o%s} \ -%{mno-clearbss: xil-sim-crt0.o%s}} crtbegin.o%s" - -#undef LINK_START_DEFAULT_SPEC -#define LINK_START_DEFAULT_SPEC "-T xilinx.ld%s" diff --git a/gcc-4.8.1/gcc/config/rs6000/xilinx.opt b/gcc-4.8.1/gcc/config/rs6000/xilinx.opt deleted file mode 100644 index f3cd85356..000000000 --- a/gcc-4.8.1/gcc/config/rs6000/xilinx.opt +++ /dev/null @@ -1,32 +0,0 @@ -; Xilinx embedded PowerPC options. - -; Copyright (C) 2011-2013 Free Software Foundation, Inc. -; -; This file is part of GCC. -; -; GCC is free software; you can redistribute it and/or modify it under -; the terms of the GNU General Public License as published by the Free -; Software Foundation; either version 3, or (at your option) any later -; version. -; -; GCC is distributed in the hope that it will be useful, but WITHOUT ANY -; WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -; for more details. -; -; You should have received a copy of the GNU General Public License -; along with GCC; see the file COPYING3. If not see -; <http://www.gnu.org/licenses/>. - -; See the GCC internals manual (options.texi) for a description of -; this file's format. - -; Please try to keep this file in ASCII collating order. - -mno-clearbss -Target RejectNegative - -mppcperflib -Target RejectNegative - -; This comment is to ensure we retain the blank line above. |