Hi Guys, I am applying the attached patch to the RX backend. It adds a new command line option -mno-allow-string-insns which stops the compiler from using any of the RX string instructions (SMOVF, SUNTIL, etc). These instructions are problematic because they are unsafe if used in the RX I/O address space; they work OK everywhere else though.
The patch adds a new set of multilibs for the option as well as a preprocessor define to identify whether the instructions are allowed. The binutils and newlib sources have already been updated to make use of this define. Cheers Nick gcc/ChangeLog 2015-04-15 Nick Clifton <ni...@redhat.com> * config/rx/rx.opt (mallow-string-insns): New option. * config/rx/rx.c (RX_BUILTIN_RMPA): Disable the use of this builtin if string instructions are denied. * config/rx/rx.h (TARGET_CPU_CPP_BUILTINS): Define __RX_ALLOW_STRING_INSNS__ or __RX_DISALLOW_STRING_INSNS__, as appropriate. (ASM_SPEC): Pass -mno-allow-string-insns on to the assembler. * config/rx/rx.md (movstr): Enable pattern only if string instructions are allowed. (rx_movstr, rx_strend, movmemsi, rx_movmem): Likewise. (cmpstrnsi, cmpstrsi, rx_cmpstrn, rmpa): Likewise. * config/rx/t-rx (MULTILIB_OPTIONS): Add mno-allow-string-insns. (MULTILIB_DIRNAMES): Add no-strings. * doc/invoke.texi: Document -mno-allow-string-insns. gcc/testsuite/ChangeLog 2015-04-15 Nick Clifton <ni...@redhat.com> * gcc.target/rx/builtins.c: Disable RMPA test if string instructions are not allowed.
Index: config/rx/rx.c =================================================================== --- config/rx/rx.c (revision 222113) +++ config/rx/rx.c (working copy) @@ -2620,7 +2620,12 @@ (op, gen_mvtachi, true); case RX_BUILTIN_MVTACLO: return rx_expand_void_builtin_1_arg (op, gen_mvtaclo, true); - case RX_BUILTIN_RMPA: emit_insn (gen_rmpa ()); return NULL_RTX; + case RX_BUILTIN_RMPA: + if (rx_allow_string_insns) + emit_insn (gen_rmpa ()); + else + error ("-mno-allow-string-insns forbids the generation of the RMPA instruction"); + return NULL_RTX; case RX_BUILTIN_MVFC: return rx_expand_builtin_mvfc (arg, target); case RX_BUILTIN_MVTC: return rx_expand_builtin_mvtc (exp); case RX_BUILTIN_MVTIPL: return rx_expand_builtin_mvtipl (op); Index: config/rx/rx.h =================================================================== --- config/rx/rx.h (revision 222113) +++ config/rx/rx.h (working copy) @@ -67,6 +67,11 @@ builtin_define ("__RX_GCC_ABI__"); \ else \ builtin_define ("__RX_ABI__"); \ + \ + if (rx_allow_string_insns) \ + builtin_define ("__RX_ALLOW_STRING_INSNS__"); \ + else \ + builtin_define ("__RX_DISALLOW_STRING_INSNS__");\ } \ while (0) @@ -97,6 +102,7 @@ %{msmall-data-limit*:-msmall-data-limit} \ %{mrelax:-relax} \ %{mpid} \ +%{mno-allow-string-insns} \ %{mint-register=*} \ %{mgcc-abi:-mgcc-abi} %{!mgcc-abi:-mrx-abi} \ %{mcpu=*} \ Index: config/rx/rx.md =================================================================== --- config/rx/rx.md (revision 222113) +++ config/rx/rx.md (working copy) @@ -2165,7 +2165,7 @@ (match_operand:BLK 2 "memory_operand")) ;; Source (use (match_operand:SI 0 "register_operand")) ;; Updated Dest ] - "" + "rx_allow_string_insns" { rtx addr1 = gen_rtx_REG (SImode, 1); rtx addr2 = gen_rtx_REG (SImode, 2); @@ -2192,7 +2192,7 @@ (clobber (reg:SI 1)) (clobber (reg:SI 2)) (clobber (reg:SI 3))] - "" + "rx_allow_string_insns" "smovu" [(set_attr "length" "2") (set_attr "timings" "1111")] ;; The timing is a guesstimate. @@ -2207,7 +2207,7 @@ (clobber (reg:SI 3)) (clobber (reg:CC CC_REG)) ] - "" + "rx_allow_string_insns" "mov\t%1, r1\n\tmov\t#0, r2\n\tsuntil.b\n\tmov\tr1, %0\n\tsub\t#1, %0" [(set_attr "length" "10") (set_attr "timings" "1111")] ;; The timing is a guesstimate. @@ -2221,7 +2221,7 @@ (match_operand 3 "immediate_operand") ;; Align (unspec_volatile:BLK [(reg:SI 1) (reg:SI 2) (reg:SI 3)] UNSPEC_MOVMEM)] )] - "" + "rx_allow_string_insns" { rtx addr1 = gen_rtx_REG (SImode, 1); rtx addr2 = gen_rtx_REG (SImode, 2); @@ -2263,7 +2263,7 @@ (clobber (reg:SI 1)) (clobber (reg:SI 2)) (clobber (reg:SI 3))] - "" + "rx_allow_string_insns" "smovf" [(set_attr "length" "2") (set_attr "timings" "1111")] ;; The timing is a guesstimate. @@ -2307,7 +2307,7 @@ UNSPEC_CMPSTRN)) (use (match_operand:SI 3 "register_operand")) ;; Max Length (match_operand:SI 4 "immediate_operand")] ;; Known Align - "" + "rx_allow_string_insns" { rtx str1 = gen_rtx_REG (SImode, 1); rtx str2 = gen_rtx_REG (SImode, 2); @@ -2328,7 +2328,7 @@ (match_operand:BLK 2 "memory_operand")] ;; String2 UNSPEC_CMPSTRN)) (match_operand:SI 3 "immediate_operand")] ;; Known Align - "" + "rx_allow_string_insns" { rtx str1 = gen_rtx_REG (SImode, 1); rtx str2 = gen_rtx_REG (SImode, 2); @@ -2353,7 +2353,7 @@ (clobber (reg:SI 2)) (clobber (reg:SI 3)) (clobber (reg:CC CC_REG))] - "" + "rx_allow_string_insns" "scmpu ; Perform the string comparison mov #-1, %0 ; Set up -1 result (which cannot be created ; by the SC insn) @@ -2471,7 +2471,7 @@ (clobber (reg:SI 1)) (clobber (reg:SI 2)) (clobber (reg:SI 3))] - "" + "rx_allow_string_insns" "rmpa" [(set_attr "length" "2") (set_attr "timings" "1010")] Index: config/rx/rx.opt =================================================================== --- config/rx/rx.opt (revision 222113) +++ config/rx/rx.opt (working copy) @@ -128,6 +128,8 @@ Target Report Var(rx_warn_multiple_fast_interrupts) Init(1) Warning Warn when multiple, different, fast interrupt handlers are in the compilation unit. +;--------------------------------------------------- + mgcc-abi Target RejectNegative Report Mask(GCC_ABI) Enable the use of the old, broken, ABI where all stacked function arguments are aligned to 32-bits. @@ -136,6 +138,14 @@ Target RejectNegative Report InverseMask(GCC_ABI) Enable the use the standard RX ABI where all stacked function arguments are naturally aligned. This is the default. +;--------------------------------------------------- + mlra Target Report Mask(ENABLE_LRA) Enable the use of the LRA register allocator. + +;--------------------------------------------------- + +mallow-string-insns +Target Report Var(rx_allow_string_insns) Init(1) +Enables or disables the use of the SMOVF, SMOVB, SMOVU, SUNTIL, SWHILE and RMPA instructions. Enabled by default. Index: config/rx/t-rx =================================================================== --- config/rx/t-rx (revision 222113) +++ config/rx/t-rx (working copy) @@ -20,7 +20,7 @@ # Enable multilibs: -MULTILIB_OPTIONS = m64bit-doubles nofpu mbig-endian-data mpid +MULTILIB_OPTIONS = m64bit-doubles mnofpu mbig-endian-data mpid MULTILIB_DIRNAMES = 64-bit-double no-fpu-libs big-endian-data pid # If necessary uncomment the next two lines to generate multilibs @@ -28,6 +28,9 @@ # MULTILIB_OPTIONS += mgcc-abi # MULTILIB_DIRNAMES += gcc-abi +MULTILIB_OPTIONS += mno-allow-string-insns +MULTILIB_DIRNAMES += no-strings + MULTILIB_MATCHES = nofpu=mnofpu nofpu=mcpu?rx200 nofpu=mcpu?rx100 MULTILIB_EXCEPTIONS = Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 222113) +++ doc/invoke.texi (working copy) @@ -940,6 +940,7 @@ -mmax-constant-size=@gol -mint-register=@gol -mpid@gol +-mallow-string-insns -mno-allow-string-insns@gol -mno-warn-multiple-fast-interrupts@gol -msave-acc-in-interrupts} @@ -20057,6 +20058,27 @@ issue a warning for each extra fast interrupt handler found, as the RX only supports one such interrupt. +@item -mallow-string-insns +@itemx -mno-allow-string-insns +@opindex mallow-string-insns +@opindex mno-allow-string-insns +Enables or disables the use of the string manipulation instructions +@code{SMOVF}, @code{SCMPU}, @code{SMOVB}, @code{SMOVU}, @code{SUNTIL} +@code{SWHILE} and also the @code{RMPA} instruction. These +instructions may prefetch data, which is not safe to do if accessing +an I/O register. (See section 12.2.7 of the RX62N Group User's Manual +for more information). + +The default is to allow these instructions, but it is not possible for +GCC to reliably detect all circumstances where a string instruction +might be used to access an I/O register, so their use cannot be +disabled automatically. Instead it is reliant upon the programmer to +use the @option{-mno-allow-string-insns} option if their program +accesses I/O space. + +When the instructions are enabled GCC defines the C preprocessor +symbol @code{__RX_ALLOW_STRING_INSNS__}, otherwise it defines the +symbol @code{__RX_DISALLOW_STRING_INSNS__}. @end table @emph{Note:} The generic GCC command-line option @option{-ffixed-@var{reg}} Index: testsuite/gcc.target/rx/builtins.c =================================================================== --- testsuite/gcc.target/rx/builtins.c (revision 222113) +++ testsuite/gcc.target/rx/builtins.c (working copy) @@ -137,8 +137,10 @@ __builtin_rx_wait (); } +#ifndef __RX_DISALLOW_STRING_INSNS__ void rmpa (int * multiplicand, int * multiplier, int num) { __builtin_rx_rmpa (); } +#endif