Commit ecc9a25b by Andre Vieira Committed by Andre Vieira

[ARM] Implement support for ACLE Coprocessor MCR and MRC intrinsics

gcc/ChangeLog:
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
	support for mcr, mrc, mcr2 and mrc2.
	* config/arm/arm-builtins.c (MCR_QUALIFIERS): Define to...
	(arm_mcr_qualifiers): ... this. New.
	(MRC_QUALIFIERS): Define to ...
	(arm_mrc_qualifiers): ... this. New.
	(MCR_QUALIFIERS): Define to ...
	(arm_mcr_qualifiers): ... this. New.
	* config/arm/arm_acle.h (__arm_mcr, __arm_mrc, __arm_mcr2,
	__arm_mrc2): New.
	* config/arm/arm_acle_builtins.def (mcr, mcr2, mrc, mrc2): New.
	* config/arm/iterators.md (MCRI, mcr, MCR, MRCI, mrc, MRC): New.
	* config/arm/unspecs.md (VUNSPEC_MCR, VUNSPEC_MCR2, VUNSPEC_MRC,
	VUNSPEC_MRC2): New.

gcc/testsuite/ChangeLog:
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.
	* gcc.target/arm/acle/mrc2.c: New.

From-SVN: r244174
parent 3811581f
2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com> 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
support for mcr, mrc, mcr2 and mrc2.
* config/arm/arm-builtins.c (MCR_QUALIFIERS): Define to...
(arm_mcr_qualifiers): ... this. New.
(MRC_QUALIFIERS): Define to ...
(arm_mrc_qualifiers): ... this. New.
(MCR_QUALIFIERS): Define to ...
(arm_mcr_qualifiers): ... this. New.
* config/arm/arm_acle.h (__arm_mcr, __arm_mrc, __arm_mcr2,
__arm_mrc2): New.
* config/arm/arm_acle_builtins.def (mcr, mcr2, mrc, mrc2): New.
* config/arm/iterators.md (MCRI, mcr, MCR, MRCI, mrc, MRC): New.
* config/arm/unspecs.md (VUNSPEC_MCR, VUNSPEC_MCR2, VUNSPEC_MRC,
VUNSPEC_MRC2): New.
2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
* config/arm/arm.md (*ldc): New. * config/arm/arm.md (*ldc): New.
(*stc): New. (*stc): New.
(<ldc>): New. (<ldc>): New.
......
...@@ -197,6 +197,26 @@ arm_stc_qualifiers[SIMD_MAX_BUILTIN_ARGS] ...@@ -197,6 +197,26 @@ arm_stc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
#define STC_QUALIFIERS \ #define STC_QUALIFIERS \
(arm_stc_qualifiers) (arm_stc_qualifiers)
/* void (unsigned immediate, unsigned immediate, T, unsigned immediate,
unsigned immediate, unsigned immediate). */
static enum arm_type_qualifiers
arm_mcr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_void, qualifier_unsigned_immediate,
qualifier_unsigned_immediate, qualifier_none,
qualifier_unsigned_immediate, qualifier_unsigned_immediate,
qualifier_unsigned_immediate };
#define MCR_QUALIFIERS \
(arm_mcr_qualifiers)
/* T (unsigned immediate, unsigned immediate, unsigned immediate,
unsigned immediate, unsigned immediate). */
static enum arm_type_qualifiers
arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
= { qualifier_none, qualifier_unsigned_immediate,
qualifier_unsigned_immediate, qualifier_unsigned_immediate,
qualifier_unsigned_immediate, qualifier_unsigned_immediate };
#define MRC_QUALIFIERS \
(arm_mrc_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
......
...@@ -30908,6 +30908,8 @@ arm_coproc_builtin_available (enum unspecv builtin) ...@@ -30908,6 +30908,8 @@ arm_coproc_builtin_available (enum unspecv builtin)
case VUNSPEC_LDCL: case VUNSPEC_LDCL:
case VUNSPEC_STC: case VUNSPEC_STC:
case VUNSPEC_STCL: case VUNSPEC_STCL:
case VUNSPEC_MCR:
case VUNSPEC_MRC:
if (arm_arch4) if (arm_arch4)
return true; return true;
break; break;
...@@ -30916,6 +30918,8 @@ arm_coproc_builtin_available (enum unspecv builtin) ...@@ -30916,6 +30918,8 @@ arm_coproc_builtin_available (enum unspecv builtin)
case VUNSPEC_LDC2L: case VUNSPEC_LDC2L:
case VUNSPEC_STC2: case VUNSPEC_STC2:
case VUNSPEC_STC2L: case VUNSPEC_STC2L:
case VUNSPEC_MCR2:
case VUNSPEC_MRC2:
/* Only present in ARMv5*, ARMv6 (but not ARMv6-M), ARMv7* and /* Only present in ARMv5*, ARMv6 (but not ARMv6-M), ARMv7* and
ARMv8-{A,M}. */ ARMv8-{A,M}. */
if (arm_arch5) if (arm_arch5)
......
...@@ -11977,6 +11977,45 @@ ...@@ -11977,6 +11977,45 @@
(mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)] (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
"arm_coproc_builtin_available (VUNSPEC_<STC>)") "arm_coproc_builtin_available (VUNSPEC_<STC>)")
(define_insn "<mcr>"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
(match_operand:SI 1 "immediate_operand" "n")
(match_operand:SI 2 "s_register_operand" "r")
(match_operand:SI 3 "immediate_operand" "n")
(match_operand:SI 4 "immediate_operand" "n")
(match_operand:SI 5 "immediate_operand" "n")] MCRI)
(use (match_dup 2))]
"arm_coproc_builtin_available (VUNSPEC_<MCR>)"
{
arm_const_bounds (operands[0], 0, 16);
arm_const_bounds (operands[1], 0, 8);
arm_const_bounds (operands[3], 0, (1 << 5));
arm_const_bounds (operands[4], 0, (1 << 5));
arm_const_bounds (operands[5], 0, 8);
return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
}
[(set_attr "length" "4")
(set_attr "type" "coproc")])
(define_insn "<mrc>"
[(set (match_operand:SI 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")
(match_operand:SI 4 "immediate_operand" "n")
(match_operand:SI 5 "immediate_operand" "n")] MRCI))]
"arm_coproc_builtin_available (VUNSPEC_<MRC>)"
{
arm_const_bounds (operands[1], 0, 16);
arm_const_bounds (operands[2], 0, 8);
arm_const_bounds (operands[3], 0, (1 << 5));
arm_const_bounds (operands[4], 0, (1 << 5));
arm_const_bounds (operands[5], 0, 8);
return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
}
[(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
......
...@@ -68,6 +68,22 @@ __arm_stcl (const unsigned int __coproc, const unsigned int __CRd, ...@@ -68,6 +68,22 @@ __arm_stcl (const unsigned int __coproc, const unsigned int __CRd,
{ {
return __builtin_arm_stcl (__coproc, __CRd, __p); return __builtin_arm_stcl (__coproc, __CRd, __p);
} }
__extension__ static __inline void __attribute__ ((__always_inline__))
__arm_mcr (const unsigned int __coproc, const unsigned int __opc1,
uint32_t __value, const unsigned int __CRn, const unsigned int __CRm,
const unsigned int __opc2)
{
return __builtin_arm_mcr (__coproc, __opc1, __value, __CRn, __CRm, __opc2);
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
__arm_mrc (const unsigned int __coproc, const unsigned int __opc1,
const unsigned int __CRn, const unsigned int __CRm,
const unsigned int __opc2)
{
return __builtin_arm_mrc (__coproc, __opc1, __CRn, __CRm, __opc2);
}
#if __ARM_ARCH >= 5 #if __ARM_ARCH >= 5
__extension__ static __inline void __attribute__ ((__always_inline__)) __extension__ static __inline void __attribute__ ((__always_inline__))
__arm_cdp2 (const unsigned int __coproc, const unsigned int __opc1, __arm_cdp2 (const unsigned int __coproc, const unsigned int __opc1,
...@@ -104,6 +120,22 @@ __arm_stc2l (const unsigned int __coproc, const unsigned int __CRd, ...@@ -104,6 +120,22 @@ __arm_stc2l (const unsigned int __coproc, const unsigned int __CRd,
{ {
return __builtin_arm_stc2l (__coproc, __CRd, __p); return __builtin_arm_stc2l (__coproc, __CRd, __p);
} }
__extension__ static __inline void __attribute__ ((__always_inline__))
__arm_mcr2 (const unsigned int __coproc, const unsigned int __opc1,
uint32_t __value, const unsigned int __CRn,
const unsigned int __CRm, const unsigned int __opc2)
{
return __builtin_arm_mcr2 (__coproc, __opc1, __value, __CRn, __CRm, __opc2);
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
__arm_mrc2 (const unsigned int __coproc, const unsigned int __opc1,
const unsigned int __CRn, const unsigned int __CRm,
const unsigned int __opc2)
{
return __builtin_arm_mrc2 (__coproc, __opc1, __CRn, __CRm, __opc2);
}
#endif /* __ARM_ARCH >= 5. */ #endif /* __ARM_ARCH >= 5. */
#endif /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */ #endif /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */
......
...@@ -34,3 +34,7 @@ VAR1 (STC, stc, void) ...@@ -34,3 +34,7 @@ VAR1 (STC, stc, void)
VAR1 (STC, stc2, void) VAR1 (STC, stc2, void)
VAR1 (STC, stcl, void) VAR1 (STC, stcl, void)
VAR1 (STC, stc2l, void) VAR1 (STC, stc2l, void)
VAR1 (MCR, mcr, void)
VAR1 (MCR, mcr2, void)
VAR1 (MRC, mrc, si)
VAR1 (MRC, mrc2, si)
...@@ -964,3 +964,15 @@ ...@@ -964,3 +964,15 @@
(VUNSPEC_STCL "stcl") (VUNSPEC_STC2L "stc2l")]) (VUNSPEC_STCL "stcl") (VUNSPEC_STC2L "stc2l")])
(define_int_attr STC [(VUNSPEC_STC "STC") (VUNSPEC_STC2 "STC2") (define_int_attr STC [(VUNSPEC_STC "STC") (VUNSPEC_STC2 "STC2")
(VUNSPEC_STCL "STCL") (VUNSPEC_STC2L "STC2L")]) (VUNSPEC_STCL "STCL") (VUNSPEC_STC2L "STC2L")])
;; An iterator for the MCR coprocessor instructions
(define_int_iterator MCRI [VUNSPEC_MCR VUNSPEC_MCR2])
(define_int_attr mcr [(VUNSPEC_MCR "mcr") (VUNSPEC_MCR2 "mcr2")])
(define_int_attr MCR [(VUNSPEC_MCR "MCR") (VUNSPEC_MCR2 "MCR2")])
;; An iterator for the MRC coprocessor instructions
(define_int_iterator MRCI [VUNSPEC_MRC VUNSPEC_MRC2])
(define_int_attr mrc [(VUNSPEC_MRC "mrc") (VUNSPEC_MRC2 "mrc2")])
(define_int_attr MRC [(VUNSPEC_MRC "MRC") (VUNSPEC_MRC2 "MRC2")])
...@@ -160,6 +160,10 @@ ...@@ -160,6 +160,10 @@
VUNSPEC_STC2 ; Represent the coprocessor stc2 instruction. VUNSPEC_STC2 ; Represent the coprocessor stc2 instruction.
VUNSPEC_STCL ; Represent the coprocessor stcl instruction. VUNSPEC_STCL ; Represent the coprocessor stcl instruction.
VUNSPEC_STC2L ; Represent the coprocessor stc2l instruction. VUNSPEC_STC2L ; Represent the coprocessor stc2l instruction.
VUNSPEC_MCR ; Represent the coprocessor mcr instruction.
VUNSPEC_MCR2 ; Represent the coprocessor mcr2 instruction.
VUNSPEC_MRC ; Represent the coprocessor mrc instruction.
VUNSPEC_MRC2 ; Represent the coprocessor mrc2 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/mcr.c: New.
* gcc.target/arm/acle/mrc.c: New.
* gcc.target/arm/acle/mcr2.c: New.
* gcc.target/arm/acle/mrc2.c: New.
2017-01-06 Andre Vieira <andre.simoesdiasvieira@arm.com>
* gcc.target/arm/acle/ldc: New. * gcc.target/arm/acle/ldc: New.
* gcc.target/arm/acle/ldc2: New. * gcc.target/arm/acle/ldc2: New.
* gcc.target/arm/acle/ldcl: New. * gcc.target/arm/acle/ldcl: New.
......
/* Test the mcr ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc1_ok } */
#include "arm_acle.h"
void test_mcr (uint32_t a)
{
a += 77;
__arm_mcr (10, 5, a, 3, 4, 7);
}
/* { dg-final { scan-assembler "add\[^\n\]*#77\n" } } */
/* { dg-final { scan-assembler "mcr\tp10, #5, r\[r0-9\]*, CR3, CR4, #7\n" } } */
/* Test the mcr2 ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc2_ok } */
#include "arm_acle.h"
void test_mcr2 (uint32_t a)
{
a += 77;
__arm_mcr2 (10, 5, a, 3, 4, 7);
}
/* { dg-final { scan-assembler "add\[^\n\]*#77\n" } } */
/* { dg-final { scan-assembler "mcr2\tp10, #5, r\[r0-9\]*, CR3, CR4, #7\n" } } */
/* Test the mrc ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc1_ok } */
#include "arm_acle.h"
uint32_t test_mrc (void)
{
return __arm_mrc (10, 0, 0, 15, 3);
}
/* { dg-final { scan-assembler "mrc\tp10, #0, r\[r0-9\]*, CR0, CR15, #3\n" } } */
/* Test the mrc2 ACLE intrinsic. */
/* { dg-do assemble } */
/* { dg-options "-save-temps" } */
/* { dg-require-effective-target arm_coproc2_ok } */
#include "arm_acle.h"
uint32_t test_mrc2 (void)
{
return __arm_mrc2 (10, 0, 0, 15, 3);
}
/* { dg-final { scan-assembler "mrc2\tp10, #0, r\[r0-9\]*, CR0, CR15, #3\n" } } */
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