Re: [PATCH 5/6][ARM] Implement support for ACLE Coprocessor MCR and MRC intrinsics
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
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
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
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