+2005-07-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * 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.
+
2005-07-26 J"orn Rennecke <joern.rennecke@st.com>
* emit-rtl.c (gen_lowpart_common): Compare size of MODE in bits
{ 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
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) \
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);
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
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. */
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,
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;
}
(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)
(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")])
\f
;; ::::::::::::::::::::
;; ::
else
FAIL;
}")
+\f
+;; 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")])
\f
;; ::::::::::::::::::::
;; ::