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
This commit is contained in:
Aldy Hernandez 2005-07-26 15:41:49 +00:00 committed by Aldy Hernandez
parent db48745242
commit c14ff86e9c
13 changed files with 295 additions and 2 deletions

View File

@ -1,3 +1,31 @@
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

View File

@ -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;
}

View File

@ -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

View File

@ -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")])
;; ::::::::::::::::::::
;; ::

View File

@ -6044,6 +6044,7 @@ here in tabular form.
* Argument Types::
* Directly-mapped Integer Functions::
* Directly-mapped Media Functions::
* Raw read/write Functions::
* Other Built-in Functions::
@end menu
@ -6398,6 +6399,27 @@ The functions listed below map directly to FR-V M-type instructions.
@tab @code{MXOR @var{a},@var{b},@var{c}}
@end multitable
@node Raw read/write Functions
@subsubsection Raw read/write Functions
This sections describes built-in functions related to read and write
instructions to access memory. These functions generate
@code{membar} instructions to flush the I/O load and stores where
appropriate, as described in Fujitsu's manual described above.
@table @code
@item unsigned char __builtin_read8 (void *@var{data})
@item unsigned short __builtin_read16 (void *@var{data})
@item unsigned long __builtin_read32 (void *@var{data})
@item unsigned long long __builtin_read64 (void *@var{data})
@item void __builtin_write8 (void *@var{data}, unsigned char @var{datum})
@item void __builtin_write16 (void *@var{data}, unsigned short @var{datum})
@item void __builtin_write32 (void *@var{data}, unsigned long @var{datum})
@item void __builtin_write64 (void *@var{data}, unsigned long long @var{datum})
@end table
@node Other Built-in Functions
@subsubsection Other Built-in Functions

View File

@ -0,0 +1,11 @@
/* { dg-do compile } */
unsigned short z;
void foo (void *x)
{
z = __builtin_read16 (x);
}
/* { dg-final { scan-assembler "lduh" } } */
/* { dg-final { scan-assembler "membar" } } */

View File

@ -0,0 +1,12 @@
/* { dg-do compile } */
/* { dg-options "-O" } */
unsigned long z;
void foo (void *x)
{
z = __builtin_read32 (x);
}
/* { dg-final { scan-assembler "ld " } } */
/* { dg-final { scan-assembler "membar" } } */

View File

@ -0,0 +1,11 @@
/* { dg-do compile } */
unsigned long long z;
void foo (void *x)
{
z = __builtin_read64 (x);
}
/* { dg-final { scan-assembler "ldd" } } */
/* { dg-final { scan-assembler "membar" } } */

View File

@ -0,0 +1,11 @@
/* { dg-do compile } */
unsigned char z;
void foo (void *x)
{
z = __builtin_read8 (x);
}
/* { dg-final { scan-assembler "ldub" } } */
/* { dg-final { scan-assembler "membar" } } */

View File

@ -0,0 +1,12 @@
/* { dg-do compile } */
unsigned short *addr;
unsigned short datum;
void foo ()
{
__builtin_write16 (addr, datum);
}
/* { dg-final { scan-assembler "sth" } } */
/* { dg-final { scan-assembler "membar" } } */

View File

@ -0,0 +1,12 @@
/* { dg-do compile } */
unsigned long *addr;
unsigned long datum;
void foo ()
{
__builtin_write32 (addr, datum);
}
/* { dg-final { scan-assembler "st " } } */
/* { dg-final { scan-assembler "membar" } } */

View File

@ -0,0 +1,12 @@
/* { dg-do compile } */
unsigned long long *addr;
unsigned long long datum;
void foo ()
{
__builtin_write64 (addr, datum);
}
/* { dg-final { scan-assembler "std " } } */
/* { dg-final { scan-assembler "membar" } } */

View File

@ -0,0 +1,12 @@
/* { dg-do compile } */
unsigned char *addr;
unsigned char datum;
void foo ()
{
__builtin_write8 (addr, datum);
}
/* { dg-final { scan-assembler "stb" } } */
/* { dg-final { scan-assembler "membar" } } */