diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5cc90358c0a4b2adcc155a284b2b3e1908b49a5..e0d975a029b3be5a48be5509cecbb46ada2c29ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +2012-01-04 Andrew Pinski <apinski@cavium.com> + Adam Nemet <anemet@caviumnetworks.com> + + * config/mips/mips.md (size): Add SI and DI. + (SIZE): New mode attribute. + (U): New code attribute. + * config/mips/mips-dsp.md (mips_lbux): Use gen_mips_lbux_extsi. + (mips_lbux_<mode>): Delete. + (mips_l<SHORT:size><u>x_ext<GPR:mode>_<P:mode>): New pattern. + (mips_lhx): Use gen_mips_lhx_extsi. + (mips_lhx_<mode>): Delete. + (mips_lwx): Delete. + (mips_l<size>x): New expand. + (mips_lwx_<mode>): Delete. + (mips_l<GPR:size>x_<P:mode>): New pattern. + (*mips_lw<u>x_<P:mode>_ext): Likewise. + * config/mips/mips-ftypes.def: Add DI f(POINTER, SI) function type. + * config/mips/mips.c (mips_lx_address_p): New function. + (mips_rtx_costs <case MEM>): Call mips_lx_address_p. + (dsp64): New availability predicate. + (mips_builtins): Add an entry for __builtin_mips_ldx. + * config/mips/mips.h (ISA_HAS_LBX): New define. + (ISA_HAS_LBUX): Likewise. + (ISA_HAS_LHX): Likewise. + (ISA_HAS_LHUX): Likewise. + (ISA_HAS_LWX): Likewise. + (ISA_HAS_LWUX): Likewise. + (ISA_HAS_LDX): Likewise. + * doc/extend.texi (__builtin_mips_ldx): Document. + 2012-01-04 Tristan Gingold <gingold@adacore.com> * config/vms/xm-vms.h (HOST_LONG_FORMAT, HOST_PTR_PRINTF): Define diff --git a/gcc/config/mips/mips-dsp.md b/gcc/config/mips/mips-dsp.md index 0f73d08502ecca785f8c20efc732c44938bae2fe..1b60ad23c59c65a00bb389e114836bc002ded5ac 100644 --- a/gcc/config/mips/mips-dsp.md +++ b/gcc/config/mips/mips-dsp.md @@ -1,4 +1,5 @@ -;; Copyright (C) 2005, 2006, 2007, 2008, 2010 Free Software Foundation, Inc. +;; Copyright (C) 2005, 2006, 2007, 2008, 2010, 2011, 2012 +;; Free Software Foundation, Inc. ;; ;; This file is part of GCC. ;; @@ -1105,20 +1106,21 @@ "ISA_HAS_DSP" { operands[2] = convert_to_mode (Pmode, operands[2], false); - emit_insn (PMODE_INSN (gen_mips_lbux, + emit_insn (PMODE_INSN (gen_mips_lbux_extsi, (operands[0], operands[1], operands[2]))); DONE; }) -(define_insn "mips_lbux_<mode>" - [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extend:SI - (mem:QI (plus:P (match_operand:P 1 "register_operand" "d") - (match_operand:P 2 "register_operand" "d")))))] - "ISA_HAS_DSP" - "lbux\t%0,%2(%1)" +(define_insn "mips_l<SHORT:size><u>x_ext<GPR:mode>_<P:mode>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (any_extend:GPR + (mem:SHORT (plus:P (match_operand:P 1 "register_operand" "d") + (match_operand:P 2 "register_operand" "d")))))] + "ISA_HAS_L<SHORT:SIZE><U>X" + "l<SHORT:size><u>x\t%0,%2(%1)" [(set_attr "type" "load") - (set_attr "mode" "SI")]) + (set_attr "mode" "<GPR:MODE>") + (set_attr "length" "4")]) (define_expand "mips_lhx" [(match_operand:SI 0 "register_operand") @@ -1127,41 +1129,43 @@ "ISA_HAS_DSP" { operands[2] = convert_to_mode (Pmode, operands[2], false); - emit_insn (PMODE_INSN (gen_mips_lhx, + emit_insn (PMODE_INSN (gen_mips_lhx_extsi, (operands[0], operands[1], operands[2]))); DONE; }) -(define_insn "mips_lhx_<mode>" - [(set (match_operand:SI 0 "register_operand" "=d") - (sign_extend:SI - (mem:HI (plus:P (match_operand:P 1 "register_operand" "d") - (match_operand:P 2 "register_operand" "d")))))] - "ISA_HAS_DSP" - "lhx\t%0,%2(%1)" - [(set_attr "type" "load") - (set_attr "mode" "SI")]) - -(define_expand "mips_lwx" - [(match_operand:SI 0 "register_operand") +(define_expand "mips_l<size>x" + [(match_operand:GPR 0 "register_operand") (match_operand 1 "pmode_register_operand") (match_operand:SI 2 "register_operand")] "ISA_HAS_DSP" { operands[2] = convert_to_mode (Pmode, operands[2], false); - emit_insn (PMODE_INSN (gen_mips_lwx, + emit_insn (PMODE_INSN (gen_mips_l<size>x, (operands[0], operands[1], operands[2]))); DONE; }) -(define_insn "mips_lwx_<mode>" - [(set (match_operand:SI 0 "register_operand" "=d") - (mem:SI (plus:P (match_operand:P 1 "register_operand" "d") - (match_operand:P 2 "register_operand" "d"))))] - "ISA_HAS_DSP" - "lwx\t%0,%2(%1)" +(define_insn "mips_l<GPR:size>x_<P:mode>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (mem:GPR (plus:P (match_operand:P 1 "register_operand" "d") + (match_operand:P 2 "register_operand" "d"))))] + "ISA_HAS_L<GPR:SIZE>X" + "l<GPR:size>x\t%0,%2(%1)" [(set_attr "type" "load") - (set_attr "mode" "SI")]) + (set_attr "mode" "<GPR:MODE>") + (set_attr "length" "4")]) + +(define_insn "*mips_lw<u>x_<P:mode>_ext" + [(set (match_operand:DI 0 "register_operand" "=d") + (any_extend:DI + (mem:SI (plus:P (match_operand:P 1 "register_operand" "d") + (match_operand:P 2 "register_operand" "d")))))] + "ISA_HAS_LW<U>X && TARGET_64BIT" + "lw<u>x\t%0,%2(%1)" + [(set_attr "type" "load") + (set_attr "mode" "DI") + (set_attr "length" "4")]) ;; Table 2-8. MIPS DSP ASE Instructions: Branch ;; BPOSGE32 diff --git a/gcc/config/mips/mips-ftypes.def b/gcc/config/mips/mips-ftypes.def index 0357aa64935b3fd118d67bc88c25283b1815d1cf..cd1d1da7a961a660ce14cc00a27cc4888dddbaf2 100644 --- a/gcc/config/mips/mips-ftypes.def +++ b/gcc/config/mips/mips-ftypes.def @@ -1,5 +1,5 @@ /* Definitions of prototypes for MIPS built-in functions. -*- C -*- - Copyright (C) 2007, 2008 + Copyright (C) 2007, 2008, 2012 Free Software Foundation, Inc. This file is part of GCC. @@ -53,6 +53,7 @@ DEF_MIPS_FTYPE (4, (INT, V2SF, V2SF, V2SF, V2SF)) DEF_MIPS_FTYPE (2, (SI, DI, SI)) DEF_MIPS_FTYPE (2, (SI, POINTER, SI)) +DEF_MIPS_FTYPE (2, (DI, POINTER, SI)) DEF_MIPS_FTYPE (1, (SI, SI)) DEF_MIPS_FTYPE (2, (SI, SI, SI)) DEF_MIPS_FTYPE (3, (SI, SI, SI, SI)) diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 7b3b6852cc96156993740914165a9c7a9daa7fd6..33e238c7d3e29d73e5ca043f676da82acec2f55f 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -1,7 +1,7 @@ /* Subroutines used for MIPS code generation. Copyright (C) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, - 2011 + 2011, 2012 Free Software Foundation, Inc. Contributed by A. Lichnewsky, lich@inria.inria.fr. Changes by Michael Meissner, meissner@osf.org. @@ -2159,6 +2159,29 @@ mips_lwxs_address_p (rtx addr) } return false; } + +/* Return true if ADDR matches the pattern for the L{B,H,W,D}{,U}X load + indexed address instruction. Note that such addresses are + not considered legitimate in the TARGET_LEGITIMATE_ADDRESS_P + sense, because their use is so restricted. */ + +static bool +mips_lx_address_p (rtx addr, enum machine_mode mode) +{ + if (GET_CODE (addr) != PLUS + || !REG_P (XEXP (addr, 0)) + || !REG_P (XEXP (addr, 1))) + return false; + if (ISA_HAS_LBX && mode == QImode) + return true; + if (ISA_HAS_LHX && mode == HImode) + return true; + if (ISA_HAS_LWX && mode == SImode) + return true; + if (ISA_HAS_LDX && mode == DImode) + return true; + return false; +} /* Return true if a value at OFFSET bytes from base register BASE can be accessed using an unextended MIPS16 instruction. MODE is the mode of @@ -3547,7 +3570,8 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, return true; } /* Check for a scaled indexed address. */ - if (mips_lwxs_address_p (addr)) + if (mips_lwxs_address_p (addr) + || mips_lx_address_p (addr, mode)) { *total = COSTS_N_INSNS (2); return true; @@ -12720,6 +12744,7 @@ AVAIL_NON_MIPS16 (mips3d, TARGET_MIPS3D) AVAIL_NON_MIPS16 (dsp, TARGET_DSP) AVAIL_NON_MIPS16 (dspr2, TARGET_DSPR2) AVAIL_NON_MIPS16 (dsp_32, !TARGET_64BIT && TARGET_DSP) +AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP) AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2) AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_VECTORS) AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN) @@ -13046,6 +13071,9 @@ static const struct mips_builtin_description mips_builtins[] = { DIRECT_BUILTIN (mult, MIPS_DI_FTYPE_SI_SI, dsp_32), DIRECT_BUILTIN (multu, MIPS_DI_FTYPE_USI_USI, dsp_32), + /* Built-in functions for the DSP ASE (64-bit only). */ + DIRECT_BUILTIN (ldx, MIPS_DI_FTYPE_POINTER_SI, dsp_64), + /* The following are for the MIPS DSP ASE REV 2 (32-bit only). */ DIRECT_BUILTIN (dpa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32), DIRECT_BUILTIN (dps_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32), diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 23d40baf9a6e76624550ed77258bfb07bb3fe840..d07e241d0d615b9f800bfe1eec55df31fd0bb83c 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1,6 +1,7 @@ /* Definitions of target machine for GNU compiler. MIPS version. Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 + 2012 Free Software Foundation, Inc. Contributed by A. Lichnewsky (lich@inria.inria.fr). Changed by Michael Meissner (meissner@osf.org). @@ -996,6 +997,16 @@ struct mips_cpu_info { /* ISA has lwxs instruction (load w/scaled index address. */ #define ISA_HAS_LWXS (TARGET_SMARTMIPS && !TARGET_MIPS16) +/* ISA has lbx, lbux, lhx, lhx, lhux, lwx, lwux, or ldx instruction. */ +#define ISA_HAS_LBX (TARGET_OCTEON2) +#define ISA_HAS_LBUX (ISA_HAS_DSP || TARGET_OCTEON2) +#define ISA_HAS_LHX (ISA_HAS_DSP || TARGET_OCTEON2) +#define ISA_HAS_LHUX (TARGET_OCTEON2) +#define ISA_HAS_LWX (ISA_HAS_DSP || TARGET_OCTEON2) +#define ISA_HAS_LWUX (TARGET_OCTEON2 && TARGET_64BIT) +#define ISA_HAS_LDX ((ISA_HAS_DSP || TARGET_OCTEON2) \ + && TARGET_64BIT) + /* The DSP ASE is available. */ #define ISA_HAS_DSP (TARGET_DSP && !TARGET_MIPS16) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index c4cda064eff77d73e42b7a7bc019010985d28fd5..3be7dd4df16e0e04702bc10123f3c923556c60b4 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1,6 +1,7 @@ ;; Mips.md Machine Description for MIPS based processors ;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, -;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +;; 2011, 2012 ;; Free Software Foundation, Inc. ;; Contributed by A. Lichnewsky, lich@inria.inria.fr ;; Changes by Michael Meissner, meissner@osf.org @@ -668,9 +669,10 @@ (HA "") (SA "") (DA "D") (UHA "") (USA "") (UDA "D")]) -;; This attribute gives the length suffix for a sign- or zero-extension -;; instruction. -(define_mode_attr size [(QI "b") (HI "h")]) +;; This attribute gives the length suffix for a load or store instruction. +;; The same suffixes work for zero and sign extensions. +(define_mode_attr size [(QI "b") (HI "h") (SI "w") (DI "d")]) +(define_mode_attr SIZE [(QI "B") (HI "H") (SI "W") (DI "D")]) ;; This attributes gives the mode mask of a SHORT. (define_mode_attr mask [(QI "0x00ff") (HI "0xffff")]) @@ -790,6 +792,9 @@ (lt "") (ltu "u") (le "") (leu "u")]) +;; <U> is like <u> except uppercase. +(define_code_attr U [(sign_extend "") (zero_extend "U")]) + ;; <su> is like <u>, but the signed form expands to "s" rather than "". (define_code_attr su [(sign_extend "s") (zero_extend "u")]) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 124bdbaed977908627c62193642bea518321d693..53bfd1cfac47599573e517c3d0f8f6455e5a5859 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1,5 +1,5 @@ @c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001, -@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 +@c 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 @c Free Software Foundation, Inc. @c This is part of the GCC manual. @@ -10537,6 +10537,7 @@ i32 __builtin_mips_rddsp (imm0_63) i32 __builtin_mips_lbux (void *, i32) i32 __builtin_mips_lhx (void *, i32) i32 __builtin_mips_lwx (void *, i32) +a64 __builtin_mips_ldx (void *, i32) [MIPS64 only] i32 __builtin_mips_bposge32 (void) a64 __builtin_mips_madd (a64, i32, i32); a64 __builtin_mips_maddu (a64, ui32, ui32); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e17b43675defbdd8a728ecaa42f8cdc9d08a9e9d..576d6c517e8a0192ff6dd2b328c89a21c3cd6071 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2012-01-04 Andrew Pinski <apinski@cavium.com> + + * gcc.target/mips/mips64-dsp-ldx1.c: New test. + * gcc.target/mips/octeon2-lx-1.c: New test. + * gcc.target/mips/mips64-dsp-ldx.c: New test. + * gcc.target/mips/octeon2-lx-2.c: New test. + * gcc.target/mips/octeon2-lx-3.c: New test. + 2012-01-04 Patrick Marlier <patrick.marlier@gmail.com> PR other/51163 diff --git a/gcc/testsuite/gcc.target/mips/mips64-dsp-ldx.c b/gcc/testsuite/gcc.target/mips/mips64-dsp-ldx.c new file mode 100644 index 0000000000000000000000000000000000000000..d136676190291e27c95398e61dba396fc7b1f7fe --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/mips64-dsp-ldx.c @@ -0,0 +1,10 @@ +/* Test MIPS64 DSP instructions */ +/* { dg-do compile } */ +/* { dg-options "-mgp64 -mdsp -O" } */ + +/* { dg-final { scan-assembler "\tldx\t" } } */ + +NOMIPS16 signed long long test (signed long long *a, int index) +{ + return a[index]; +} diff --git a/gcc/testsuite/gcc.target/mips/mips64-dsp-ldx1.c b/gcc/testsuite/gcc.target/mips/mips64-dsp-ldx1.c new file mode 100644 index 0000000000000000000000000000000000000000..b7f3bc8f816e59136f60e31f1d9bb692127c6d03 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/mips64-dsp-ldx1.c @@ -0,0 +1,10 @@ +/* Test MIPS64 DSP instructions */ +/* { dg-do compile } */ +/* { dg-options "-mgp64 -mdsp" } */ + +/* { dg-final { scan-assembler "\tldx\t" } } */ + +NOMIPS16 signed long long test (signed long long *a, int index) +{ + return __builtin_mips_ldx (a, index); +} diff --git a/gcc/testsuite/gcc.target/mips/octeon2-lx-1.c b/gcc/testsuite/gcc.target/mips/octeon2-lx-1.c new file mode 100644 index 0000000000000000000000000000000000000000..2d8b0c6dcdd4268dd1870915f025b5c7a2f66980 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon2-lx-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=octeon2 -O -mgp64" } */ + +#define TEST(N, R, T) \ + T fll##N (T j, R *b, long long i) { return j + b[i]; } \ + T gll##N (T j, unsigned R *b, long long i) { return j + b[i]; } \ + T fi##N (T j, R *b, int i) { return j + b[i]; } \ + T gi##N (T j, unsigned R *b, int i) { return j + b[i]; } \ + +TEST (1, char, int) +TEST (2, char, long long) +/* { dg-final { scan-assembler-times "\tlbx\t" 4 } } */ +/* { dg-final { scan-assembler-times "\tlbux\t" 4 } } */ +TEST (3, short, int) +TEST (4, short, long long) +/* { dg-final { scan-assembler-times "\tlhx\t" 4 } } */ +/* { dg-final { scan-assembler-times "\tlhux\t" 4 } } */ +TEST (5, int, long long) +/* { dg-final { scan-assembler-times "\tlwx\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tlwux\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/mips/octeon2-lx-2.c b/gcc/testsuite/gcc.target/mips/octeon2-lx-2.c new file mode 100644 index 0000000000000000000000000000000000000000..521a71f961bbef7b4d315a4b181d2f09d3eb609a --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon2-lx-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=octeon2 -O -mgp64" } */ + +#define TEST(N, T) \ + T f##N (T *p, int i) { return p[i]; } \ + unsigned T g##N (unsigned T *p, int i) { return p[i]; } + +TEST (1, char) +/* { dg-final { scan-assembler-times "\tlbu?x\t" 2 } } */ +TEST (2, short) +/* { dg-final { scan-assembler-times "\tlhu?x\t" 2 } } */ +TEST (3, int) +/* { dg-final { scan-assembler-times "\tlwx\t" 2 } } */ +TEST (4, long long) +/* { dg-final { scan-assembler-times "\tldx\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/mips/octeon2-lx-3.c b/gcc/testsuite/gcc.target/mips/octeon2-lx-3.c new file mode 100644 index 0000000000000000000000000000000000000000..51d2e1031ccd86cb9073df976e6bdc7b3f11bae6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/octeon2-lx-3.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-march=octeon2 -O -mgp32" } */ + +#define TEST(N, T) \ + T f##N (T *p, int i) { return p[i]; } \ + unsigned T g##N (unsigned T *p, int i) { return p[i]; } + +TEST (1, char) +/* { dg-final { scan-assembler-times "\tlbu?x\t" 2 } } */ +TEST (2, short) +/* { dg-final { scan-assembler-times "\tlhu?x\t" 2 } } */ +TEST (3, int) +/* { dg-final { scan-assembler-times "\tlwx\t" 2 } } */