Re: [PATCH 5/6][ARM] Implement support for ACLE Coprocessor MCR and MRC intrinsics

2017-01-06 Thread Kyrill Tkachov


On 06/01/17 14:18, Andre Vieira (lists) wrote:

On 05/01/17 11:08, Kyrill Tkachov wrote:

On 09/11/16 10:12, Andre Vieira (lists) wrote:

Hi,

This patch implements support for the ARM ACLE Coprocessor MCR and MRC
intrinsics. See below a table mapping the intrinsics to their respective
instructions:

+---+---+

| Intrinsic signature   |
Instruction pattern   |
+---+---+

|void __arm_mcr(coproc, opc1, uint32_t value, CRn, CRm, opc2)   |
MCR coproc, opc1, Rt, CRn, CRm, opc2  |
+---+---+

|void __arm_mcr2(coproc, opc1, uint32_t value, CRn, CRm, opc2)  |
MCR2 coproc, opc1, Rt, CRn, CRm, opc2 |
+---+---+

|uint32_t __arm_mrc(coproc, opc1, CRn, CRm, opc2)   |
MRC coproc, opc1, Rt, CRn, CRm, opc2  |
+---+---+

|uint32_t __arm_mrc2(coproc, opc1, CRn, CRm, opc2)  |
MRC2 coproc, opc1, Rt, CRn, CRm, opc2 |
+---+---+

Note that any untyped variable in the intrinsic signature is required to
be a compiler-time constant and has the type 'unsigned int'.  We do some
boundary checks for coproc:[0-15], opc1[0-7] CR*:[0-31],opc2:[0-7].  If
either of these requirements are not met a diagnostic is issued.

Is this OK for trunk?

Regards,
Andre

gcc/ChangeLog:
2016-11-09  Andre Vieira  

* config/arm/arm.md (): New.
(): 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/ChangeLog:
2016-11-09  Andre Vieira  

* 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.

+(define_insn ""
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
+ (match_operand:SI 1 "immediate_operand")
+ (match_operand:SI 2 "s_register_operand")
+ (match_operand:SI 3 "immediate_operand")
+ (match_operand:SI 4 "immediate_operand")
+ (match_operand:SI 5 "immediate_operand")] MCRI)
+   (use (match_dup 2))]
+  "arm_coproc_builtin_available (VUNSPEC_)"
+{
+  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 "\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
+}
+  [(set_attr "length" "4")
+   (set_attr "type" "coproc")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "s_register_operand")
+(unspec_volatile [(match_operand:SI 1 "immediate_operand")
+  (match_operand:SI 2 "immediate_operand")
+  (match_operand:SI 3 "immediate_operand")
+  (match_operand:SI 4 "immediate_operand")
+  (match_operand:SI 5 "immediate_operand")] MRCI))]
+  "arm_coproc_builtin_available (VUNSPEC_)"
+{
+  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 "\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
+}
+  [(set_attr "length" "4")
+   (set_attr "type" "coproc")])

Same as the previous patch, these operands need constraints.
The MRC ones in particular need a '=' in their constraint string.

Hi,

Reworked comments and rebased.

Is this OK for trunk?


Ok.
Thanks,
Kyrill


Regards,
Andre

gcc/ChangeLog:
2017-01-xx  Andre Vieira  

   * config/arm/arm.md (): New.
   (): 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/a

Re: [PATCH 5/6][ARM] Implement support for ACLE Coprocessor MCR and MRC intrinsics

2017-01-06 Thread Andre Vieira (lists)
On 05/01/17 11:08, Kyrill Tkachov wrote:
> 
> On 09/11/16 10:12, Andre Vieira (lists) wrote:
>> Hi,
>>
>> This patch implements support for the ARM ACLE Coprocessor MCR and MRC
>> intrinsics. See below a table mapping the intrinsics to their respective
>> instructions:
>>
>> +---+---+
>>
>> | Intrinsic signature   |
>> Instruction pattern   |
>> +---+---+
>>
>> |void __arm_mcr(coproc, opc1, uint32_t value, CRn, CRm, opc2)   |
>> MCR coproc, opc1, Rt, CRn, CRm, opc2  |
>> +---+---+
>>
>> |void __arm_mcr2(coproc, opc1, uint32_t value, CRn, CRm, opc2)  |
>> MCR2 coproc, opc1, Rt, CRn, CRm, opc2 |
>> +---+---+
>>
>> |uint32_t __arm_mrc(coproc, opc1, CRn, CRm, opc2)   |
>> MRC coproc, opc1, Rt, CRn, CRm, opc2  |
>> +---+---+
>>
>> |uint32_t __arm_mrc2(coproc, opc1, CRn, CRm, opc2)  |
>> MRC2 coproc, opc1, Rt, CRn, CRm, opc2 |
>> +---+---+
>>
>> Note that any untyped variable in the intrinsic signature is required to
>> be a compiler-time constant and has the type 'unsigned int'.  We do some
>> boundary checks for coproc:[0-15], opc1[0-7] CR*:[0-31],opc2:[0-7].  If
>> either of these requirements are not met a diagnostic is issued.
>>
>> Is this OK for trunk?
>>
>> Regards,
>> Andre
>>
>> gcc/ChangeLog:
>> 2016-11-09  Andre Vieira  
>>
>>* config/arm/arm.md (): New.
>>(): 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/ChangeLog:
>> 2016-11-09  Andre Vieira  
>>
>>* 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.
> 
> +(define_insn ""
> +  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
> + (match_operand:SI 1 "immediate_operand")
> + (match_operand:SI 2 "s_register_operand")
> + (match_operand:SI 3 "immediate_operand")
> + (match_operand:SI 4 "immediate_operand")
> + (match_operand:SI 5 "immediate_operand")] MCRI)
> +   (use (match_dup 2))]
> +  "arm_coproc_builtin_available (VUNSPEC_)"
> +{
> +  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 "\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
> +}
> +  [(set_attr "length" "4")
> +   (set_attr "type" "coproc")])
> +
> +(define_insn ""
> +  [(set (match_operand:SI 0 "s_register_operand")
> +(unspec_volatile [(match_operand:SI 1 "immediate_operand")
> +  (match_operand:SI 2 "immediate_operand")
> +  (match_operand:SI 3 "immediate_operand")
> +  (match_operand:SI 4 "immediate_operand")
> +  (match_operand:SI 5 "immediate_operand")] MRCI))]
> +  "arm_coproc_builtin_available (VUNSPEC_)"
> +{
> +  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 "\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
> +}
> +  [(set_attr "length" "4")
> +   (set_attr "type" "coproc")])
> 
> Same as the previous patch, these operands need constraints.
> The MRC ones in particular need a '=' in their constraint string.
Hi,

Reworked comments and rebased.

Is this OK for trunk?

Regards,
Andre

gcc/ChangeLog:
2017-01-xx  Andre Vieira  

  * config/arm/arm.md (): New.
  (): 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. N

Re: [PATCH 5/6][ARM] Implement support for ACLE Coprocessor MCR and MRC intrinsics

2017-01-05 Thread Kyrill Tkachov


On 09/11/16 10:12, Andre Vieira (lists) wrote:

Hi,

This patch implements support for the ARM ACLE Coprocessor MCR and MRC
intrinsics. See below a table mapping the intrinsics to their respective
instructions:

+---+---+
| Intrinsic signature   |
Instruction pattern   |
+---+---+
|void __arm_mcr(coproc, opc1, uint32_t value, CRn, CRm, opc2)   |
MCR coproc, opc1, Rt, CRn, CRm, opc2  |
+---+---+
|void __arm_mcr2(coproc, opc1, uint32_t value, CRn, CRm, opc2)  |
MCR2 coproc, opc1, Rt, CRn, CRm, opc2 |
+---+---+
|uint32_t __arm_mrc(coproc, opc1, CRn, CRm, opc2)   |
MRC coproc, opc1, Rt, CRn, CRm, opc2  |
+---+---+
|uint32_t __arm_mrc2(coproc, opc1, CRn, CRm, opc2)  |
MRC2 coproc, opc1, Rt, CRn, CRm, opc2 |
+---+---+
Note that any untyped variable in the intrinsic signature is required to
be a compiler-time constant and has the type 'unsigned int'.  We do some
boundary checks for coproc:[0-15], opc1[0-7] CR*:[0-31],opc2:[0-7].  If
either of these requirements are not met a diagnostic is issued.

Is this OK for trunk?

Regards,
Andre

gcc/ChangeLog:
2016-11-09  Andre Vieira  

   * config/arm/arm.md (): New.
   (): 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/ChangeLog:
2016-11-09  Andre Vieira  

   * 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.


+(define_insn ""
+  [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
+(match_operand:SI 1 "immediate_operand")
+(match_operand:SI 2 "s_register_operand")
+(match_operand:SI 3 "immediate_operand")
+(match_operand:SI 4 "immediate_operand")
+(match_operand:SI 5 "immediate_operand")] MCRI)
+   (use (match_dup 2))]
+  "arm_coproc_builtin_available (VUNSPEC_)"
+{
+  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 "\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
+}
+  [(set_attr "length" "4")
+   (set_attr "type" "coproc")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "s_register_operand")
+   (unspec_volatile [(match_operand:SI 1 "immediate_operand")
+ (match_operand:SI 2 "immediate_operand")
+ (match_operand:SI 3 "immediate_operand")
+ (match_operand:SI 4 "immediate_operand")
+ (match_operand:SI 5 "immediate_operand")] MRCI))]
+  "arm_coproc_builtin_available (VUNSPEC_)"
+{
+  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 "\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
+}
+  [(set_attr "length" "4")
+   (set_attr "type" "coproc")])

Same as the previous patch, these operands need constraints.
The MRC ones in particular need a '=' in their constraint string.


[PATCH 5/6][ARM] Implement support for ACLE Coprocessor MCR and MRC intrinsics

2016-11-09 Thread Andre Vieira (lists)
Hi,

This patch implements support for the ARM ACLE Coprocessor MCR and MRC
intrinsics. See below a table mapping the intrinsics to their respective
instructions:

+---+---+
| Intrinsic signature   |
Instruction pattern   |
+---+---+
|void __arm_mcr(coproc, opc1, uint32_t value, CRn, CRm, opc2)   |
MCR coproc, opc1, Rt, CRn, CRm, opc2  |
+---+---+
|void __arm_mcr2(coproc, opc1, uint32_t value, CRn, CRm, opc2)  |
MCR2 coproc, opc1, Rt, CRn, CRm, opc2 |
+---+---+
|uint32_t __arm_mrc(coproc, opc1, CRn, CRm, opc2)   |
MRC coproc, opc1, Rt, CRn, CRm, opc2  |
+---+---+
|uint32_t __arm_mrc2(coproc, opc1, CRn, CRm, opc2)  |
MRC2 coproc, opc1, Rt, CRn, CRm, opc2 |
+---+---+
Note that any untyped variable in the intrinsic signature is required to
be a compiler-time constant and has the type 'unsigned int'.  We do some
boundary checks for coproc:[0-15], opc1[0-7] CR*:[0-31],opc2:[0-7].  If
either of these requirements are not met a diagnostic is issued.

Is this OK for trunk?

Regards,
Andre

gcc/ChangeLog:
2016-11-09  Andre Vieira  

  * config/arm/arm.md (): New.
  (): 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/ChangeLog:
2016-11-09  Andre Vieira  

  * 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.
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 
e6e58cd6a656732e37c6bca23ad980eea522a710..44f255356dcc3ea6b8f554ba96f99fd7856bf6a1
 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -196,6 +196,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
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 
d3191abee163d5fbf753fb5072be50fdb2b4c785..25439a343e8540c5fca5cbe19e8b76e2fdb97a73
 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -30803,6 +30803,8 @@ bool 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;
@@ -30811,6 +30813,8 @@ bool 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)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 
45cdd576fa5b7f26e2d1cfa2c86a8c876