This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

patch: frv __builtin_{read,write}* implementation


Hi folks.

This patch implements the __builtin_read* and __builtin_write* builtins
for FRV.  They are just like loads and stores, but generate MEMBAR
instructions to flush I/O system (if I understand correctly).

I would have preferred the builtins to be named something like
__builtin_frv_read* or __builtin_frv_membar_read*, but the ucLinux and
the Linux kernel already call the builtins as implemented here.

Tested on ppc64-linux x frv-elf.

Committed.

	* 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.

Index: doc/extend.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/extend.texi,v
retrieving revision 1.257
diff -c -p -r1.257 extend.texi
*** doc/extend.texi	27 Jun 2005 12:17:35 -0000	1.257
--- doc/extend.texi	26 Jul 2005 15:28:44 -0000
*************** this attribute to work correctly.
*** 1879,1888 ****
  
  @item interrupt
  @cindex interrupt handler functions
! Use this attribute on the ARM, AVR, C4x, M32R/D and Xstormy16 ports to indicate
! that the specified function is an interrupt handler.  The compiler will
! generate function entry and exit sequences suitable for use in an
! interrupt handler when this attribute is present.
  
  Note, interrupt handlers for the Blackfin, m68k, H8/300, H8/300H, H8S, and
  SH processors can be specified via the @code{interrupt_handler} attribute.
--- 1879,1888 ----
  
  @item interrupt
  @cindex interrupt handler functions
! Use this attribute on the ARM, AVR, C4x, M32R/D, MS1, and Xstormy16
! ports to indicate that the specified function is an interrupt handler.
! The compiler will generate function entry and exit sequences suitable
! for use in an interrupt handler when this attribute is present.
  
  Note, interrupt handlers for the Blackfin, m68k, H8/300, H8/300H, H8S, and
  SH processors can be specified via the @code{interrupt_handler} attribute.
*************** here in tabular form.
*** 6020,6025 ****
--- 6020,6026 ----
  * Argument Types::
  * Directly-mapped Integer Functions::
  * Directly-mapped Media Functions::
+ * Raw read/write Functions::
  * Other Built-in Functions::
  @end menu
  
*************** The functions listed below map directly 
*** 6374,6379 ****
--- 6375,6401 ----
  @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
  
Index: testsuite/gcc.target/frv/all-builtin-read8.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-read8.c
diff -N testsuite/gcc.target/frv/all-builtin-read8.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-read8.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: testsuite/gcc.target/frv/all-builtin-read16.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-read16.c
diff -N testsuite/gcc.target/frv/all-builtin-read16.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-read16.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: testsuite/gcc.target/frv/all-builtin-read32.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-read32.c
diff -N testsuite/gcc.target/frv/all-builtin-read32.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-read32.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: testsuite/gcc.target/frv/all-builtin-read64.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-read64.c
diff -N testsuite/gcc.target/frv/all-builtin-read64.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-read64.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: testsuite/gcc.target/frv/all-builtin-write8.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-write8.c
diff -N testsuite/gcc.target/frv/all-builtin-write8.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-write8.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: testsuite/gcc.target/frv/all-builtin-write16.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-write16.c
diff -N testsuite/gcc.target/frv/all-builtin-write16.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-write16.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: testsuite/gcc.target/frv/all-builtin-write32.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-write32.c
diff -N testsuite/gcc.target/frv/all-builtin-write32.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-write32.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: testsuite/gcc.target/frv/all-builtin-write64.c
===================================================================
RCS file: testsuite/gcc.target/frv/all-builtin-write64.c
diff -N testsuite/gcc.target/frv/all-builtin-write64.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/frv/all-builtin-write64.c	26 Jul 2005 15:28:44 -0000
***************
*** 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" } } */
Index: config/frv/frv.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/frv/frv.c,v
retrieving revision 1.93
diff -c -p -r1.93 frv.c
*** config/frv/frv.c	28 Jun 2005 19:56:03 -0000	1.93
--- config/frv/frv.c	26 Jul 2005 15:28:48 -0000
*************** static struct builtin_description bdesc_
*** 7953,7958 ****
--- 7953,7987 ----
    { 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
*************** frv_init_builtins (void)
*** 7968,7973 ****
--- 7997,8004 ----
    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) \
*************** frv_init_builtins (void)
*** 8034,8039 ****
--- 8065,8076 ----
    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);
*************** frv_init_builtins (void)
*** 8139,8144 ****
--- 8176,8190 ----
    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
*************** frv_legitimize_argument (enum insn_code 
*** 8364,8369 ****
--- 8410,8427 ----
      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.  */
  
*************** frv_expand_voidaccop_builtin (enum insn_
*** 8612,8617 ****
--- 8670,8708 ----
    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,
*************** frv_expand_builtin (tree exp,
*** 8956,8961 ****
--- 9047,9060 ----
      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;
  }
  
Index: config/frv/frv.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/frv/frv.h,v
retrieving revision 1.67
diff -c -p -r1.67 frv.h
*** config/frv/frv.h	26 Jun 2005 05:18:31 -0000	1.67
--- config/frv/frv.h	26 Jul 2005 15:28:51 -0000
*************** enum frv_builtins
*** 2985,2991 ****
    FRV_BUILTIN_IACCreadl,
    FRV_BUILTIN_IACCsetll,
    FRV_BUILTIN_IACCsetl,
!   FRV_BUILTIN_SCAN
  };
  #define FRV_BUILTIN_FIRST_NONMEDIA FRV_BUILTIN_SMUL
  
--- 2985,2999 ----
    FRV_BUILTIN_IACCreadl,
    FRV_BUILTIN_IACCsetll,
    FRV_BUILTIN_IACCsetl,
!   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
  
Index: config/frv/frv.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/frv/frv.md,v
retrieving revision 1.37
diff -c -p -r1.37 frv.md
*** config/frv/frv.md	28 Jun 2005 19:56:04 -0000	1.37
--- config/frv/frv.md	26 Jul 2005 15:28:53 -0000
***************
*** 41,46 ****
--- 41,49 ----
     (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,92 ****
     (FDPIC_REG			15)
     ])
  
! 
  
  ;; ::::::::::::::::::::
  ;; ::
--- 89,97 ----
     (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,2168 ****
--- 2167,2211 ----
    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")])
  
  ;; ::::::::::::::::::::
  ;; ::


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]