Commit f3caa118 by Andre Vieira Committed by Andre Vieira

[ARM] Implement support for ACLE Coprocessor MCRR and MRRC intrinsics

gcc/ChangeLog:
2017-01-06  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/arm/arm.md (<mcrr>): New.
	(<mrrc>): New.
	* config/arm/arm.c (arm_arch5te): New.
	(arm_option_override): Set arm_arch5te.
	(arm_coproc_builtin_available): Add support for mcrr, mcrr2, mrrc
	and mrrc2.
	* config/arm/arm-builtins.c (MCRR_QUALIFIERS): Define to...
	(arm_mcrr_qualifiers): ... this. New.
	(MRRC_QUALIFIERS): Define to...
	(arm_mrrc_qualifiers): ... this. New.
	* config/arm/arm_acle.h (__arm_mcrr, __arm_mcrr2, __arm_mrrc,
	__arm_mrrc2): New.
	* config/arm/arm_acle_builtins.def (mcrr, mcrr2, mrrc, mrrc2): New.
	* config/arm/iterators.md (MCRRI, mcrr, MCRR): New.
	(MRRCI, mrrc, MRRC): New.
	* config/arm/unspecs.md (VUNSPEC_MCRR, VUNSPEC_MCRR2, VUNSPEC_MRRC,
	VUNSPEC_MRRC2): New.

gcc/testsuite/ChangeLog:
2017-01-06  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* gcc.target/arm/acle/mcrr: New.
	* gcc.target/arm/acle/mcrr2: New.
	* gcc.target/arm/acle/mrrc: New.
	* gcc.target/arm/acle/mrrc2: New.

From-SVN: r244175
parent ecc9a25b
2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com> 2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
* config/arm/arm.md (<mcrr>): New.
(<mrrc>): New.
* config/arm/arm.c (arm_arch5te): New.
(arm_option_override): Set arm_arch5te.
(arm_coproc_builtin_available): Add support for mcrr, mcrr2, mrrc
and mrrc2.
* config/arm/arm-builtins.c (MCRR_QUALIFIERS): Define to...
(arm_mcrr_qualifiers): ... this. New.
(MRRC_QUALIFIERS): Define to...
(arm_mrrc_qualifiers): ... this. New.
* config/arm/arm_acle.h (__arm_mcrr, __arm_mcrr2, __arm_mrrc,
__arm_mrrc2): New.
* config/arm/arm_acle_builtins.def (mcrr, mcrr2, mrrc, mrrc2): New.
* config/arm/iterators.md (MCRRI, mcrr, MCRR): New.
(MRRCI, mrrc, MRRC): New.
* config/arm/unspecs.md (VUNSPEC_MCRR, VUNSPEC_MCRR2, VUNSPEC_MRRC,
VUNSPEC_MRRC2): New.
2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
* config/arm/arm.md (<mcr>): New. * config/arm/arm.md (<mcr>): New.
(<mrc>): New. (<mrc>): New.
* config/arm/arm.c (arm_coproc_builtin_available): Add * config/arm/arm.c (arm_coproc_builtin_available): Add
......
...@@ -217,6 +217,24 @@ arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS] ...@@ -217,6 +217,24 @@ arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
qualifier_unsigned_immediate, qualifier_unsigned_immediate }; qualifier_unsigned_immediate, qualifier_unsigned_immediate };
#define MRC_QUALIFIERS \ #define MRC_QUALIFIERS \
(arm_mrc_qualifiers) (arm_mrc_qualifiers)
/* void (unsigned immediate, unsigned immediate, T, unsigned immediate). */
static enum arm_type_qualifiers
arm_mcrr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_void, qualifier_unsigned_immediate,
qualifier_unsigned_immediate, qualifier_none,
qualifier_unsigned_immediate };
#define MCRR_QUALIFIERS \
(arm_mcrr_qualifiers)
/* T (unsigned immediate, unsigned immediate, unsigned immediate). */
static enum arm_type_qualifiers
arm_mrrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_none, qualifier_unsigned_immediate,
qualifier_unsigned_immediate, qualifier_unsigned_immediate };
#define MRRC_QUALIFIERS \
(arm_mrrc_qualifiers)
/* The first argument (return type) of a store should be void type, /* The first argument (return type) of a store should be void type,
which we represent with qualifier_void. Their first operand will be which we represent with qualifier_void. Their first operand will be
a DImode pointer to the location to store to, so we must use a DImode pointer to the location to store to, so we must use
......
...@@ -814,6 +814,9 @@ int arm_arch5 = 0; ...@@ -814,6 +814,9 @@ int arm_arch5 = 0;
/* Nonzero if this chip supports the ARM Architecture 5E extensions. */ /* Nonzero if this chip supports the ARM Architecture 5E extensions. */
int arm_arch5e = 0; int arm_arch5e = 0;
/* Nonzero if this chip supports the ARM Architecture 5TE extensions. */
int arm_arch5te = 0;
/* Nonzero if this chip supports the ARM Architecture 6 extensions. */ /* Nonzero if this chip supports the ARM Architecture 6 extensions. */
int arm_arch6 = 0; int arm_arch6 = 0;
...@@ -3372,6 +3375,8 @@ arm_option_override (void) ...@@ -3372,6 +3375,8 @@ arm_option_override (void)
arm_arch4t = arm_arch4 && bitmap_bit_p (arm_active_target.isa, isa_bit_thumb); arm_arch4t = arm_arch4 && bitmap_bit_p (arm_active_target.isa, isa_bit_thumb);
arm_arch5 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv5); arm_arch5 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv5);
arm_arch5e = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv5e); arm_arch5e = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv5e);
arm_arch5te = arm_arch5e
&& bitmap_bit_p (arm_active_target.isa, isa_bit_thumb);
arm_arch6 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv6); arm_arch6 = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv6);
arm_arch6k = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv6k); arm_arch6k = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv6k);
arm_arch_notm = bitmap_bit_p (arm_active_target.isa, isa_bit_notm); arm_arch_notm = bitmap_bit_p (arm_active_target.isa, isa_bit_notm);
...@@ -30925,6 +30930,18 @@ arm_coproc_builtin_available (enum unspecv builtin) ...@@ -30925,6 +30930,18 @@ arm_coproc_builtin_available (enum unspecv builtin)
if (arm_arch5) if (arm_arch5)
return true; return true;
break; break;
case VUNSPEC_MCRR:
case VUNSPEC_MRRC:
/* Only present in ARMv5TE, ARMv6 (but not ARMv6-M), ARMv7* and
ARMv8-{A,M}. */
if (arm_arch6 || arm_arch5te)
return true;
break;
case VUNSPEC_MCRR2:
case VUNSPEC_MRRC2:
if (arm_arch6)
return true;
break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
......
...@@ -12016,6 +12016,37 @@ ...@@ -12016,6 +12016,37 @@
[(set_attr "length" "4") [(set_attr "length" "4")
(set_attr "type" "coproc")]) (set_attr "type" "coproc")])
(define_insn "<mcrr>"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
(match_operand:SI 1 "immediate_operand" "n")
(match_operand:DI 2 "s_register_operand" "r")
(match_operand:SI 3 "immediate_operand" "n")] MCRRI)
(use (match_dup 2))]
"arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
{
arm_const_bounds (operands[0], 0, 16);
arm_const_bounds (operands[1], 0, 8);
arm_const_bounds (operands[3], 0, (1 << 5));
return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
}
[(set_attr "length" "4")
(set_attr "type" "coproc")])
(define_insn "<mrrc>"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(unspec_volatile [(match_operand:SI 1 "immediate_operand" "n")
(match_operand:SI 2 "immediate_operand" "n")
(match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
"arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
{
arm_const_bounds (operands[1], 0, 16);
arm_const_bounds (operands[2], 0, 8);
arm_const_bounds (operands[3], 0, (1 << 5));
return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
}
[(set_attr "length" "4")
(set_attr "type" "coproc")])
;; Vector bits common to IWMMXT and Neon ;; Vector bits common to IWMMXT and Neon
(include "vec-common.md") (include "vec-common.md")
;; Load the Intel Wireless Multimedia Extension patterns ;; Load the Intel Wireless Multimedia Extension patterns
......
...@@ -136,6 +136,40 @@ __arm_mrc2 (const unsigned int __coproc, const unsigned int __opc1, ...@@ -136,6 +136,40 @@ __arm_mrc2 (const unsigned int __coproc, const unsigned int __opc1,
{ {
return __builtin_arm_mrc2 (__coproc, __opc1, __CRn, __CRm, __opc2); return __builtin_arm_mrc2 (__coproc, __opc1, __CRn, __CRm, __opc2);
} }
#if __ARM_ARCH >= 6 || defined (__ARM_ARCH_5TE__)
__extension__ static __inline void __attribute__ ((__always_inline__))
__arm_mcrr (const unsigned int __coproc, const unsigned int __opc1,
uint64_t __value, const unsigned int __CRm)
{
return __builtin_arm_mcrr (__coproc, __opc1, __value, __CRm);
}
__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
__arm_mrrc (const unsigned int __coproc, const unsigned int __opc1,
const unsigned int __CRm)
{
return __builtin_arm_mrrc (__coproc, __opc1, __CRm);
}
#if __ARM_ARCH >= 6
__extension__ static __inline void __attribute__ ((__always_inline__))
__arm_mcrr2 (const unsigned int __coproc, const unsigned int __opc1,
uint64_t __value, const unsigned int __CRm)
{
return __builtin_arm_mcrr2 (__coproc, __opc1, __value, __CRm);
}
__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
__arm_mrrc2 (const unsigned int __coproc, const unsigned int __opc1,
const unsigned int __CRm)
{
return __builtin_arm_mrrc2 (__coproc, __opc1, __CRm);
}
#endif /* __ARM_ARCH >= 6. */
#endif /* __ARM_ARCH >= 6 || defined (__ARM_ARCH_5TE__). */
#endif /* __ARM_ARCH >= 5. */ #endif /* __ARM_ARCH >= 5. */
#endif /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */ #endif /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */
......
...@@ -38,3 +38,7 @@ VAR1 (MCR, mcr, void) ...@@ -38,3 +38,7 @@ VAR1 (MCR, mcr, void)
VAR1 (MCR, mcr2, void) VAR1 (MCR, mcr2, void)
VAR1 (MRC, mrc, si) VAR1 (MRC, mrc, si)
VAR1 (MRC, mrc2, si) VAR1 (MRC, mrc2, si)
VAR1 (MCRR, mcrr, void)
VAR1 (MCRR, mcrr2, void)
VAR1 (MRRC, mrrc, di)
VAR1 (MRRC, mrrc2, di)
...@@ -976,3 +976,15 @@ ...@@ -976,3 +976,15 @@
(define_int_attr mrc [(VUNSPEC_MRC "mrc") (VUNSPEC_MRC2 "mrc2")]) (define_int_attr mrc [(VUNSPEC_MRC "mrc") (VUNSPEC_MRC2 "mrc2")])
(define_int_attr MRC [(VUNSPEC_MRC "MRC") (VUNSPEC_MRC2 "MRC2")]) (define_int_attr MRC [(VUNSPEC_MRC "MRC") (VUNSPEC_MRC2 "MRC2")])
;; An iterator for the MCRR coprocessor instructions
(define_int_iterator MCRRI [VUNSPEC_MCRR VUNSPEC_MCRR2])
(define_int_attr mcrr [(VUNSPEC_MCRR "mcrr") (VUNSPEC_MCRR2 "mcrr2")])
(define_int_attr MCRR [(VUNSPEC_MCRR "MCRR") (VUNSPEC_MCRR2 "MCRR2")])
;; An iterator for the MRRC coprocessor instructions
(define_int_iterator MRRCI [VUNSPEC_MRRC VUNSPEC_MRRC2])
(define_int_attr mrrc [(VUNSPEC_MRRC "mrrc") (VUNSPEC_MRRC2 "mrrc2")])
(define_int_attr MRRC [(VUNSPEC_MRRC "MRRC") (VUNSPEC_MRRC2 "MRRC2")])
...@@ -164,6 +164,10 @@ ...@@ -164,6 +164,10 @@
VUNSPEC_MCR2 ; Represent the coprocessor mcr2 instruction. VUNSPEC_MCR2 ; Represent the coprocessor mcr2 instruction.
VUNSPEC_MRC ; Represent the coprocessor mrc instruction. VUNSPEC_MRC ; Represent the coprocessor mrc instruction.
VUNSPEC_MRC2 ; Represent the coprocessor mrc2 instruction. VUNSPEC_MRC2 ; Represent the coprocessor mrc2 instruction.
VUNSPEC_MCRR ; Represent the coprocessor mcrr instruction.
VUNSPEC_MCRR2 ; Represent the coprocessor mcrr2 instruction.
VUNSPEC_MRRC ; Represent the coprocessor mrrc instruction.
VUNSPEC_MRRC2 ; Represent the coprocessor mrrc2 instruction.
]) ])
;; Enumerators for NEON unspecs. ;; Enumerators for NEON unspecs.
......
2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com> 2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
* gcc.target/arm/acle/mcrr: New.
* gcc.target/arm/acle/mcrr2: New.
* gcc.target/arm/acle/mrrc: New.
* gcc.target/arm/acle/mrrc2: New.
2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
* gcc.target/arm/acle/mcr.c: New. * gcc.target/arm/acle/mcr.c: New.
* gcc.target/arm/acle/mrc.c: New. * gcc.target/arm/acle/mrc.c: New.
* gcc.target/arm/acle/mcr2.c: New. * gcc.target/arm/acle/mcr2.c: New.
......
/* Test the mcrr ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc3_ok } */
#include "arm_acle.h"
void test_mcrr (uint64_t a)
{
a += 77;
__arm_mcrr (10, 5, a, 3);
}
/* { dg-final { scan-assembler "add\[^\n\]*#77\n" } } */
/* { dg-final { scan-assembler "mcrr\tp10, #5, r\[r0-9\]*, r\[r0-9\]*, CR3\n" } } */
/* Test the mcrr2 ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc4_ok } */
#include "arm_acle.h"
void test_mcrr2 (uint64_t a)
{
a += 77;
__arm_mcrr2 (10, 5, a, 3);
}
/* { dg-final { scan-assembler "add\[^\n\]*#77\n" } } */
/* { dg-final { scan-assembler "mcrr2\tp10, #5, r\[r0-9\]*, r\[r0-9\]*, CR3\n" } } */
/* Test the mrrc ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc3_ok } */
#include "arm_acle.h"
uint64_t test_mrrc (void)
{
return __arm_mrrc (10, 5, 3);
}
/* { dg-final { scan-assembler "mrrc\tp10, #5, r\[r0-9\]*, r\[r0-9\]*, CR3\n" } } */
/* Test the mrrc2 ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc4_ok } */
#include "arm_acle.h"
uint64_t test_mrrc2 (void)
{
return __arm_mrrc2 (10, 5, 3);
}
/* { dg-final { scan-assembler "mrrc2\tp10, #5, r\[r0-9\]*, r\[r0-9\]*, CR3\n" } } */
...@@ -8279,7 +8279,7 @@ proc check_effective_target_arm_coproc2_ok { } { ...@@ -8279,7 +8279,7 @@ proc check_effective_target_arm_coproc2_ok { } {
# Return 1 if the target supports all coprocessor instructions checked by # Return 1 if the target supports all coprocessor instructions checked by
# check_effective_target_arm_coproc2_ok in addition the following: mcrr and # check_effective_target_arm_coproc2_ok in addition the following: mcrr and
mrrc. # mrrc.
proc check_effective_target_arm_coproc3_ok_nocache { } { proc check_effective_target_arm_coproc3_ok_nocache { } {
if { ![check_effective_target_arm_coproc2_ok] } { if { ![check_effective_target_arm_coproc2_ok] } {
return 0 return 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment