aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/frv
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2005-07-26 15:41:49 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2005-07-26 15:41:49 +0000
commitc14ff86e9ca385d8e62bbecac8ebd439171e5ced (patch)
treec953489e8663c24a0dc08d181832b0f04316ac9a /gcc/config/frv
parentdb48745242e25f3b9b414cd9e01986fe2205ccc1 (diff)
downloadgcc-c14ff86e9ca385d8e62bbecac8ebd439171e5ced.zip
gcc-c14ff86e9ca385d8e62bbecac8ebd439171e5ced.tar.gz
gcc-c14ff86e9ca385d8e62bbecac8ebd439171e5ced.tar.bz2
extend.texi (Raw read/write Functions): New section.
* doc/extend.texi (Raw read/write Functions): New section. * testsuite/gcc.target/frv/all-builtin-read8.c: New. * testsuite/gcc.target/frv/all-builtin-read16.c: New. * testsuite/gcc.target/frv/all-builtin-read32.c: New. * testsuite/gcc.target/frv/all-builtin-read64.c: New. * testsuite/gcc.target/frv/all-builtin-write8.c: New. * testsuite/gcc.target/frv/all-builtin-write16.c: New. * testsuite/gcc.target/frv/all-builtin-write32.c: New. * testsuite/gcc.target/frv/all-builtin-write64.c: New. * config/frv/frv.c: Add bdesc_loads global. Add bdesc_stores global. (frv_init_builtins): Add support for __builtin_{read/write}*. (frv_volatile_memref): New. (frv_expand_load_builtin): New. (frv_expand_store_builtin): New. * config/frv/frv.h (frv_builtins): Add FRV_BUILTIN_SCAN, FRV_BUILTIN_READ8, FRV_BUILTIN_READ16, FRV_BUILTIN_READ32, FRV_BUILTIN_READ64, FRV_BUILTIN_WRITE8, FRV_BUILTIN_WRITE16, FRV_BUILTIN_WRITE32, FRV_BUILTIN_WRITE64. * config/frv/frv.md (unspecs): Add UNSPEC_BUILTIN_LOAD, UNSPEC_BUILTIN_STORE, UNSPEC_OPTIONAL_MEMBAR. (builtin_read_<mode>): New. (builtin_write_<mode>): New. (builtin_write64): New. (optional_membar_<mode>): New. From-SVN: r102388
Diffstat (limited to 'gcc/config/frv')
-rw-r--r--gcc/config/frv/frv.c99
-rw-r--r--gcc/config/frv/frv.h10
-rw-r--r--gcc/config/frv/frv.md45
3 files changed, 152 insertions, 2 deletions
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 9b94bd3..756ae63 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -7953,6 +7953,35 @@ static struct builtin_description bdesc_voidacc[] =
{ CODE_FOR_mdasaccs, "__MDASACCS", FRV_BUILTIN_MDASACCS, 0, 0 }
};
+/* Intrinsics that load a value and then issue a MEMBAR.
+ The FLAGS field is the icode for the membar. */
+
+static struct builtin_description bdesc_loads[] =
+{
+ { CODE_FOR_builtin_read_qi, "__builtin_read8", FRV_BUILTIN_READ8, 0,
+ CODE_FOR_optional_membar_qi },
+ { CODE_FOR_builtin_read_hi, "__builtin_read16", FRV_BUILTIN_READ16, 0,
+ CODE_FOR_optional_membar_hi },
+ { CODE_FOR_builtin_read_si, "__builtin_read32", FRV_BUILTIN_READ32, 0,
+ CODE_FOR_optional_membar_si },
+ { CODE_FOR_builtin_read_di, "__builtin_read64", FRV_BUILTIN_READ64, 0,
+ CODE_FOR_optional_membar_di }
+};
+
+/* Likewise stores. */
+
+static struct builtin_description bdesc_stores[] =
+{
+ { CODE_FOR_builtin_write_qi, "__builtin_write8", FRV_BUILTIN_WRITE8, 0,
+ CODE_FOR_optional_membar_qi },
+ { CODE_FOR_builtin_write_hi, "__builtin_write16", FRV_BUILTIN_WRITE16, 0,
+ CODE_FOR_optional_membar_hi },
+ { CODE_FOR_builtin_write_si, "__builtin_write32", FRV_BUILTIN_WRITE32, 0,
+ CODE_FOR_optional_membar_si },
+ { CODE_FOR_builtin_write64, "__builtin_write64", FRV_BUILTIN_WRITE64, 0,
+ CODE_FOR_optional_membar_di }
+};
+
/* Initialize media builtins. */
static void
@@ -7968,6 +7997,8 @@ frv_init_builtins (void)
tree sword2 = long_long_integer_type_node;
tree uword2 = long_long_unsigned_type_node;
tree uword4 = build_pointer_type (uword1);
+ tree vptr = build_pointer_type (build_type_variant (void_type_node, 0, 1));
+ tree ubyte = unsigned_char_type_node;
tree iacc = integer_type_node;
#define UNARY(RET, T1) \
@@ -8034,6 +8065,12 @@ frv_init_builtins (void)
tree sw2_ftype_iacc = UNARY (sword2, iacc);
tree sw1_ftype_iacc = UNARY (sword1, iacc);
tree void_ftype_ptr = UNARY (voidt, const_ptr_type_node);
+ tree uw1_ftype_vptr = UNARY (uword1, vptr);
+ tree uw2_ftype_vptr = UNARY (uword2, vptr);
+ tree void_ftype_vptr_ub = BINARY (voidt, vptr, ubyte);
+ tree void_ftype_vptr_uh = BINARY (voidt, vptr, uhalf);
+ tree void_ftype_vptr_uw1 = BINARY (voidt, vptr, uword1);
+ tree void_ftype_vptr_uw2 = BINARY (voidt, vptr, uword2);
def_builtin ("__MAND", uw1_ftype_uw1_uw1, FRV_BUILTIN_MAND);
def_builtin ("__MOR", uw1_ftype_uw1_uw1, FRV_BUILTIN_MOR);
@@ -8139,6 +8176,15 @@ frv_init_builtins (void)
def_builtin ("__IACCsetl", void_ftype_iacc_sw1, FRV_BUILTIN_IACCsetl);
def_builtin ("__data_prefetch0", void_ftype_ptr, FRV_BUILTIN_PREFETCH0);
def_builtin ("__data_prefetch", void_ftype_ptr, FRV_BUILTIN_PREFETCH);
+ def_builtin ("__builtin_read8", uw1_ftype_vptr, FRV_BUILTIN_READ8);
+ def_builtin ("__builtin_read16", uw1_ftype_vptr, FRV_BUILTIN_READ16);
+ def_builtin ("__builtin_read32", uw1_ftype_vptr, FRV_BUILTIN_READ32);
+ def_builtin ("__builtin_read64", uw2_ftype_vptr, FRV_BUILTIN_READ64);
+
+ def_builtin ("__builtin_write8", void_ftype_vptr_ub, FRV_BUILTIN_WRITE8);
+ def_builtin ("__builtin_write16", void_ftype_vptr_uh, FRV_BUILTIN_WRITE16);
+ def_builtin ("__builtin_write32", void_ftype_vptr_uw1, FRV_BUILTIN_WRITE32);
+ def_builtin ("__builtin_write64", void_ftype_vptr_uw2, FRV_BUILTIN_WRITE64);
#undef UNARY
#undef BINARY
@@ -8364,6 +8410,18 @@ frv_legitimize_argument (enum insn_code icode, int opnum, rtx arg)
return copy_to_mode_reg (mode, arg);
}
+/* Return a volatile memory reference of mode MODE whose address is ARG. */
+
+static rtx
+frv_volatile_memref (enum machine_mode mode, rtx arg)
+{
+ rtx mem;
+
+ mem = gen_rtx_MEM (mode, memory_address (mode, arg));
+ MEM_VOLATILE_P (mem) = 1;
+ return mem;
+}
+
/* Expand builtins that take a single, constant argument. At the moment,
only MHDSETS falls into this category. */
@@ -8612,6 +8670,39 @@ frv_expand_voidaccop_builtin (enum insn_code icode, tree arglist)
return NULL_RTX;
}
+/* Expand a __builtin_read* function. ICODE is the instruction code for
+ the load and MEMBAR_ICODE is the instruction code of the "membar". */
+
+static rtx
+frv_expand_load_builtin (enum insn_code icode, enum insn_code membar_icode,
+ tree arglist, rtx target)
+{
+ rtx op0 = frv_read_argument (& arglist);
+
+ target = frv_legitimize_target (icode, target);
+ op0 = frv_volatile_memref (insn_data[membar_icode].operand[0].mode, op0);
+ emit_insn (GEN_FCN (icode) (target, op0));
+ emit_insn (GEN_FCN (membar_icode) (copy_rtx (op0)));
+ return target;
+}
+
+/* Likewise __builtin_write* functions, with ICODE being the instruction
+ code of the store. */
+
+static rtx
+frv_expand_store_builtin (enum insn_code icode, enum insn_code membar_icode,
+ tree arglist)
+{
+ rtx op0 = frv_read_argument (& arglist);
+ rtx op1 = frv_read_argument (& arglist);
+
+ op0 = frv_volatile_memref (insn_data[membar_icode].operand[0].mode, op0);
+ op1 = frv_legitimize_argument (icode, 1, op1);
+ emit_insn (GEN_FCN (icode) (op0, op1));
+ emit_insn (GEN_FCN (membar_icode) (copy_rtx (op0)));
+ return NULL_RTX;
+}
+
/* Expand the MDPACKH builtin. It takes four unsigned short arguments and
each argument forms one word of the two double-word input registers.
ARGLIST is a TREE_LIST of the arguments and TARGET, if nonnull,
@@ -8956,6 +9047,14 @@ frv_expand_builtin (tree exp,
if (d->code == fcode)
return frv_expand_prefetches (d->icode, arglist);
+ for (i = 0, d = bdesc_loads; i < ARRAY_SIZE (bdesc_loads); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_load_builtin (d->icode, d->flag, arglist, target);
+
+ for (i = 0, d = bdesc_stores; i < ARRAY_SIZE (bdesc_stores); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_store_builtin (d->icode, d->flag, arglist);
+
return 0;
}
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index b33805c..41c11c4 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -2985,7 +2985,15 @@ enum frv_builtins
FRV_BUILTIN_IACCreadl,
FRV_BUILTIN_IACCsetll,
FRV_BUILTIN_IACCsetl,
- FRV_BUILTIN_SCAN
+ FRV_BUILTIN_SCAN,
+ FRV_BUILTIN_READ8,
+ FRV_BUILTIN_READ16,
+ FRV_BUILTIN_READ32,
+ FRV_BUILTIN_READ64,
+ FRV_BUILTIN_WRITE8,
+ FRV_BUILTIN_WRITE16,
+ FRV_BUILTIN_WRITE32,
+ FRV_BUILTIN_WRITE64
};
#define FRV_BUILTIN_FIRST_NONMEDIA FRV_BUILTIN_SMUL
diff --git a/gcc/config/frv/frv.md b/gcc/config/frv/frv.md
index b8c37c5..5b744bb 100644
--- a/gcc/config/frv/frv.md
+++ b/gcc/config/frv/frv.md
@@ -41,6 +41,9 @@
(UNSPEC_EH_RETURN_EPILOGUE 6)
(UNSPEC_GOT 7)
(UNSPEC_LDD 8)
+ (UNSPEC_BUILTIN_LOAD 9)
+ (UNSPEC_BUILTIN_STORE 10)
+ (UNSPEC_OPTIONAL_MEMBAR 11)
(UNSPEC_GETTLSOFF 200)
(UNSPEC_TLS_LOAD_GOTTLSOFF12 201)
@@ -86,7 +89,9 @@
(FDPIC_REG 15)
])
-
+(define_mode_macro IMODE [QI HI SI DI])
+(define_mode_attr IMODEsuffix [(QI "b") (HI "h") (SI "") (DI "d")])
+(define_mode_attr BREADsuffix [(QI "ub") (HI "uh") (SI "") (DI "d")])
;; ::::::::::::::::::::
;; ::
@@ -2162,7 +2167,45 @@
else
FAIL;
}")
+
+;; The load part of a __builtin_read* function.
+;; Use UNSPECs to distinguish these patterns from normal moves.
+(define_insn "builtin_read_<mode>"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extend:SI (unspec:IMODE
+ [(match_operand:IMODE 1 "memory_operand" "m")]
+ UNSPEC_BUILTIN_LOAD)))]
+ ""
+ "ld<BREADsuffix>%I1%U1 %M1,%0"
+ [(set_attr "length" "4")
+ (set_attr "type" "gload")])
+
+;; The store part of a __builtin_write* function.
+(define_insn "builtin_write_<mode>"
+ [(set (match_operand:IMODE 0 "memory_operand" "=m")
+ (unspec:IMODE [(match_operand:IMODE 1 "reg_or_0_operand" "dO")]
+ UNSPEC_BUILTIN_STORE))]
+ ""
+ "st<IMODEsuffix>%I0%U0 %z1, %M0"
+ [(set_attr "length" "4")
+ (set_attr "type" "gstore")])
+;; This one has a different predicate for operand 1.
+(define_insn "builtin_write64"
+ [(set (match_operand:DI 0 "memory_operand" "=m")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "d")]
+ UNSPEC_BUILTIN_STORE))]
+ ""
+ "std%I0%U0 %z1, %M0"
+ [(set_attr "length" "4")
+ (set_attr "type" "gstore")])
+
+(define_insn "optional_membar_<mode>"
+ [(set (match_operand:IMODE 0 "memory_operand" "=m")
+ (unspec:IMODE [(const_int 0)] UNSPEC_OPTIONAL_MEMBAR))]
+ ""
+ "membar"
+ [(set_attr "length" "4")])
;; ::::::::::::::::::::
;; ::