[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
This commit is contained in:
parent
3811581f8b
commit
ecc9a25b97
|
@ -1,3 +1,22 @@
|
|||
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.
|
||||
|
|
|
@ -197,6 +197,26 @@ arm_stc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
|
|||
#define 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,
|
||||
which we represent with qualifier_void. Their first operand will be
|
||||
a DImode pointer to the location to store to, so we must use
|
||||
|
|
|
@ -30908,6 +30908,8 @@ arm_coproc_builtin_available (enum unspecv builtin)
|
|||
case VUNSPEC_LDCL:
|
||||
case VUNSPEC_STC:
|
||||
case VUNSPEC_STCL:
|
||||
case VUNSPEC_MCR:
|
||||
case VUNSPEC_MRC:
|
||||
if (arm_arch4)
|
||||
return true;
|
||||
break;
|
||||
|
@ -30916,6 +30918,8 @@ arm_coproc_builtin_available (enum unspecv builtin)
|
|||
case VUNSPEC_LDC2L:
|
||||
case VUNSPEC_STC2:
|
||||
case VUNSPEC_STC2L:
|
||||
case VUNSPEC_MCR2:
|
||||
case VUNSPEC_MRC2:
|
||||
/* Only present in ARMv5*, ARMv6 (but not ARMv6-M), ARMv7* and
|
||||
ARMv8-{A,M}. */
|
||||
if (arm_arch5)
|
||||
|
|
|
@ -11977,6 +11977,45 @@
|
|||
(mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
|
||||
"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
|
||||
(include "vec-common.md")
|
||||
;; Load the Intel Wireless Multimedia Extension patterns
|
||||
|
|
|
@ -68,6 +68,22 @@ __arm_stcl (const unsigned int __coproc, const unsigned int __CRd,
|
|||
{
|
||||
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
|
||||
__extension__ static __inline void __attribute__ ((__always_inline__))
|
||||
__arm_cdp2 (const unsigned int __coproc, const unsigned int __opc1,
|
||||
|
@ -104,6 +120,22 @@ __arm_stc2l (const unsigned int __coproc, const unsigned int __CRd,
|
|||
{
|
||||
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 /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */
|
||||
|
||||
|
|
|
@ -34,3 +34,7 @@ VAR1 (STC, stc, void)
|
|||
VAR1 (STC, stc2, void)
|
||||
VAR1 (STC, stcl, 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 @@
|
|||
(VUNSPEC_STCL "stcl") (VUNSPEC_STC2L "stc2l")])
|
||||
(define_int_attr STC [(VUNSPEC_STC "STC") (VUNSPEC_STC2 "STC2")
|
||||
(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 @@
|
|||
VUNSPEC_STC2 ; Represent the coprocessor stc2 instruction.
|
||||
VUNSPEC_STCL ; Represent the coprocessor stcl 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.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
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.
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/* 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" } } */
|
|
@ -0,0 +1,16 @@
|
|||
/* 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" } } */
|
|
@ -0,0 +1,14 @@
|
|||
/* 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" } } */
|
|
@ -0,0 +1,14 @@
|
|||
/* 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" } } */
|
Loading…
Reference in New Issue