Hi,

The following patch adds a new builtin function for rx ( __builtin_rx_bset)
to make it possible for the user to use BSET whenever necessary.
Please note this builtin function is dedicated only for the variant 32 bit
variant of BSET (when destination is a register). 
For the 8 bit variant (when destination is a memory location) another
builtin function is necessary.

The patch contains also a test case which I added in
testsuite/gcc.target/rx.

The patch also modifies extend.texi as necessary.

Regression test is OK, tested with the following command:
make -k check-gcc RUNTESTFLAGS=--target_board=rx-sim

Please find below the changelog entries and patch.

Best Regards,
Sebastian

--- ChangeLog
2018-10-23  Sebastian Perta  <sebastian.pe...@renesas.com>

        * config/rx/rx.c (RX_BUILTIN_BSET): New enum.
        * config/rx/rx.c (rx_init_builtins): Added new builtin for BSET.
        * config/rx/rx.c (rx_expand_builtin_bit_manip): New function.
        * config/rx/rx.c (rx_expand_builtin): Added new case for BSET.
        * doc/extend.texi (RX Built-in Functions): Added declaration for
        __builtin_rx_bset.

testsuite/ChangeLog
2018-10-23  Sebastian Perta  <sebastian.pe...@renesas.com>

        * gcc.target/rx/testbset.c: New test.





Index: config/rx/rx.c
===================================================================
--- config/rx/rx.c      (revision 265425)
+++ config/rx/rx.c      (working copy)
@@ -2374,6 +2374,7 @@
   RX_BUILTIN_ROUND,
   RX_BUILTIN_SETPSW,
   RX_BUILTIN_WAIT,
+  RX_BUILTIN_BSET,
   RX_BUILTIN_max
 };
 
@@ -2440,6 +2441,7 @@
   ADD_RX_BUILTIN1 (ROUND,   "round",   intSI, float);
   ADD_RX_BUILTIN1 (REVW,    "revw",    intSI, intSI);
   ADD_RX_BUILTIN0 (WAIT,    "wait",    void);
+  ADD_RX_BUILTIN2 (BSET,    "bset",    intSI, intSI, intSI);
 }
 
 /* Return the RX builtin for CODE.  */
@@ -2576,6 +2578,26 @@
   return target;
 }
 
+static rtx
+rx_expand_builtin_bit_manip(tree exp, rtx target, rtx (* gen_func)(rtx,
rtx, rtx))
+{
+  rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
+  rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
+
+  if (! REG_P (arg1))
+    arg1 = force_reg (SImode, arg1);
+
+  if (! REG_P (arg2))
+    arg2 = force_reg (SImode, arg2);
+
+  if (target == NULL_RTX || ! REG_P (target))
+     target = gen_reg_rtx (SImode);
+
+  emit_insn(gen_func(target, arg2, arg1));
+
+  return target;
+}
+
 static int
 valid_psw_flag (rtx op, const char *which)
 {
@@ -2653,6 +2675,7 @@
     case RX_BUILTIN_REVW:    return rx_expand_int_builtin_1_arg
        (op, target, gen_revw, false);
     case RX_BUILTIN_WAIT:    emit_insn (gen_wait ()); return NULL_RTX;
+       case RX_BUILTIN_BSET:   return rx_expand_builtin_bit_manip(exp,
target, gen_bitset);
 
     default:
       internal_error ("bad builtin code");
Index: doc/extend.texi
===================================================================
--- doc/extend.texi     (revision 265425)
+++ doc/extend.texi     (working copy)
@@ -19635,6 +19635,10 @@
 Generates the @code{wait} machine instruction.
 @end deftypefn
 
+@deftypefn {Built-in Function}  int __builtin_rx_bset (int, int)
+Generates the @code{bset} machine instruction.
+@end deftypefn
+
 @node S/390 System z Built-in Functions
 @subsection S/390 System z Built-in Functions
 @deftypefn {Built-in Function} int __builtin_tbegin (void*)
Index: testsuite/ChangeLog
Index: testsuite/gcc.target/rx/testbset.c
===================================================================
--- testsuite/gcc.target/rx/testbset.c  (nonexistent)
+++ testsuite/gcc.target/rx/testbset.c  (working copy)
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+
+#include <stdlib.h>
+
+int f1(int a, int b) __attribute((noinline));
+int f1(int a, int b)
+{
+       return __builtin_rx_bset (a, b);
+}
+
+int f2(int a) __attribute((noinline));
+int f2(int a)
+{
+       return __builtin_rx_bset (a, 1);
+}
+
+int x, y;
+
+int f3() __attribute((noinline));
+int f3()
+{
+       return __builtin_rx_bset (x, 4);
+}
+
+int f4() __attribute((noinline));
+int f4()
+{
+       return __builtin_rx_bset (x, y);
+}
+
+void f5() __attribute((noinline));
+void f5()
+{
+       x = __builtin_rx_bset (x, 6);
+}
+
+int main()
+{
+       if(f1(0xF, 8) != 0x10F)
+               abort();
+       if(f2(0xC) != 0xE)
+               abort();
+       x = 0xF;
+       if(f3() != 0x1F)
+               abort();
+       y = 5;
+       if(f4() != 0x2F)
+               abort();
+       f5();
+       if(x != 0x4F)
+               abort();
+       exit(0);
+}

Reply via email to