aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndre Vieira <andre.simoesdiasvieira@arm.com>2017-01-06 17:49:12 +0000
committerAndre Vieira <avieira@gcc.gnu.org>2017-01-06 17:49:12 +0000
commitf3caa1182415bafbd565341c0c64f4e36811f8a8 (patch)
tree4d45643fda25f7067abfeacf4ed9b7683cd5232b /gcc
parentecc9a25b9775a6b099ce50d8bc4fd05c6d1d6ffc (diff)
downloadgcc-f3caa1182415bafbd565341c0c64f4e36811f8a8.zip
gcc-f3caa1182415bafbd565341c0c64f4e36811f8a8.tar.gz
gcc-f3caa1182415bafbd565341c0c64f4e36811f8a8.tar.bz2
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/arm/arm-builtins.c18
-rw-r--r--gcc/config/arm/arm.c17
-rw-r--r--gcc/config/arm/arm.md31
-rw-r--r--gcc/config/arm/arm_acle.h34
-rw-r--r--gcc/config/arm/arm_acle_builtins.def4
-rw-r--r--gcc/config/arm/iterators.md12
-rw-r--r--gcc/config/arm/unspecs.md4
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/arm/acle/mcrr.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/acle/mcrr2.c16
-rw-r--r--gcc/testsuite/gcc.target/arm/acle/mrrc.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/acle/mrrc2.c14
-rw-r--r--gcc/testsuite/lib/target-supports.exp2
14 files changed, 208 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c860f36..5f4577d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,25 @@
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.
(<mrc>): New.
* config/arm/arm.c (arm_coproc_builtin_available): Add
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 1a983b2..689219c 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -217,6 +217,24 @@ arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
qualifier_unsigned_immediate, qualifier_unsigned_immediate };
#define 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,
which we represent with qualifier_void. Their first operand will be
a DImode pointer to the location to store to, so we must use
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index e376ab3..ccdf1ab 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -814,6 +814,9 @@ int arm_arch5 = 0;
/* Nonzero if this chip supports the ARM Architecture 5E extensions. */
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. */
int arm_arch6 = 0;
@@ -3372,6 +3375,8 @@ arm_option_override (void)
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_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_arch6k = bitmap_bit_p (arm_active_target.isa, isa_bit_ARMv6k);
arm_arch_notm = bitmap_bit_p (arm_active_target.isa, isa_bit_notm);
@@ -30925,6 +30930,18 @@ arm_coproc_builtin_available (enum unspecv builtin)
if (arm_arch5)
return true;
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:
gcc_unreachable ();
}
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 15926f1..446fb22 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -12016,6 +12016,37 @@
[(set_attr "length" "4")
(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
(include "vec-common.md")
;; Load the Intel Wireless Multimedia Extension patterns
diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h
index a218547..972e28e 100644
--- a/gcc/config/arm/arm_acle.h
+++ b/gcc/config/arm/arm_acle.h
@@ -136,6 +136,40 @@ __arm_mrc2 (const unsigned int __coproc, const unsigned int __opc1,
{
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 /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */
diff --git a/gcc/config/arm/arm_acle_builtins.def b/gcc/config/arm/arm_acle_builtins.def
index d258f8a..bd1f662 100644
--- a/gcc/config/arm/arm_acle_builtins.def
+++ b/gcc/config/arm/arm_acle_builtins.def
@@ -38,3 +38,7 @@ VAR1 (MCR, mcr, void)
VAR1 (MCR, mcr2, void)
VAR1 (MRC, mrc, si)
VAR1 (MRC, mrc2, si)
+VAR1 (MCRR, mcrr, void)
+VAR1 (MCRR, mcrr2, void)
+VAR1 (MRRC, mrrc, di)
+VAR1 (MRRC, mrrc2, di)
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index d34a705..e2e5886 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -976,3 +976,15 @@
(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")])
diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md
index 6bde96e..99cfa41 100644
--- a/gcc/config/arm/unspecs.md
+++ b/gcc/config/arm/unspecs.md
@@ -164,6 +164,10 @@
VUNSPEC_MCR2 ; Represent the coprocessor mcr2 instruction.
VUNSPEC_MRC ; Represent the coprocessor mrc 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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index cd61f81..213f434 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
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/mrc.c: New.
* gcc.target/arm/acle/mcr2.c: New.
diff --git a/gcc/testsuite/gcc.target/arm/acle/mcrr.c b/gcc/testsuite/gcc.target/arm/acle/mcrr.c
new file mode 100644
index 0000000..dcc223c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/mcrr.c
@@ -0,0 +1,16 @@
+/* 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" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/mcrr2.c b/gcc/testsuite/gcc.target/arm/acle/mcrr2.c
new file mode 100644
index 0000000..10f2014
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/mcrr2.c
@@ -0,0 +1,16 @@
+/* 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" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/mrrc.c b/gcc/testsuite/gcc.target/arm/acle/mrrc.c
new file mode 100644
index 0000000..28c3b8e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/mrrc.c
@@ -0,0 +1,14 @@
+/* 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" } } */
diff --git a/gcc/testsuite/gcc.target/arm/acle/mrrc2.c b/gcc/testsuite/gcc.target/arm/acle/mrrc2.c
new file mode 100644
index 0000000..5b7aab0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/mrrc2.c
@@ -0,0 +1,14 @@
+/* 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" } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 342304d..b88d13c 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -8279,7 +8279,7 @@ proc check_effective_target_arm_coproc2_ok { } {
# Return 1 if the target supports all coprocessor instructions checked by
# check_effective_target_arm_coproc2_ok in addition the following: mcrr and
-mrrc.
+# mrrc.
proc check_effective_target_arm_coproc3_ok_nocache { } {
if { ![check_effective_target_arm_coproc2_ok] } {
return 0