From aff5912c6f01b8a97ea8f107e12c7d10c869bb5d Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Thu, 8 Sep 2022 20:38:29 +0300 Subject: [PATCH] ppc/svp64: support svshape2 instruction https://libre-soc.org/openpower/sv/ https://libre-soc.org/openpower/sv/remap/#svshape https://libre-soc.org/openpower/sv/remap/#svshape2 https://libre-soc.org/openpower/isa/simplev/ --- gas/testsuite/gas/ppc/svshape.d | 6 +++ gas/testsuite/gas/ppc/svshape.s | 6 +++ opcodes/ppc-opc.c | 75 ++++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/gas/testsuite/gas/ppc/svshape.d b/gas/testsuite/gas/ppc/svshape.d index 8244741ed33..29bc42960af 100644 --- a/gas/testsuite/gas/ppc/svshape.d +++ b/gas/testsuite/gas/ppc/svshape.d @@ -11,3 +11,9 @@ Disassembly of section \.text: .*: (19 f8 00 58|58 00 f8 19) svshape 1,1,32,0,0 .*: (99 07 00 58|58 00 07 99) svshape 1,1,1,15,0 .*: (59 00 00 58|58 00 00 59) svshape 1,1,1,0,1 +.*: (19 04 c0 5b|5b c0 04 19) svshape2 15,0,0,1,0,0 +.*: (19 04 20 58|58 20 04 19) svshape2 0,1,0,1,0,0 +.*: (19 04 1f 58|58 1f 04 19) svshape2 0,0,31,1,0,0 +.*: (19 fc 00 58|58 00 fc 19) svshape2 0,0,0,32,0,0 +.*: (59 04 00 58|58 00 04 59) svshape2 0,0,0,1,1,0 +.*: (99 04 00 58|58 00 04 99) svshape2 0,0,0,1,0,1 diff --git a/gas/testsuite/gas/ppc/svshape.s b/gas/testsuite/gas/ppc/svshape.s index c83373ba372..39d4579a200 100644 --- a/gas/testsuite/gas/ppc/svshape.s +++ b/gas/testsuite/gas/ppc/svshape.s @@ -3,3 +3,9 @@ svshape 1,32,1,0,0 svshape 1,1,32,0,0 svshape 1,1,1,15,0 svshape 1,1,1,0,1 +svshape2 15,0,0,1,0,0 +svshape2 0,1,0,1,0,0 +svshape2 0,0,31,1,0,0 +svshape2 0,0,0,32,0,0 +svshape2 0,0,0,1,1,0 +svshape2 0,0,0,1,0,1 diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 25c96ba87b7..e9d3c7b1f4c 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -2719,6 +2719,67 @@ extract_thds (uint64_t insn, return value; } + +static uint64_t +insert_SVrm (uint64_t insn, + int64_t value, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + const char **errmsg) +{ + /* + * 0b1000 and 0b1001 values are reserved for svshape2. + * svshape is SVM-form; svshape2 is SVM2-form. + * + * svshape XO: + * 0000-011001 + * 0001-011001 + * 0010-011001 + * 0011-011001 + * 0100-011001 + * 0101-011001 + * 0110-011001 + * 0111-011001 + * 1010-011001 + * 1011-011001 + * 1100-011001 + * 1101-011001 + * 1110-011001 + * 1111-011001 + * + * svshape2 XO: + * 100--011001 + * + * # 1.6.35 SVM-FORM + * |0 |6 |11 |16 |21 |25 |26 |31 | + * | PO | SVxd | SVyd | SVzd | SVrm |vf | XO | + * + * # 1.6.35.1 SVM2-FORM + * |0 |6 |10|11 |16 |21 |24|25 |26 |31 | + * | PO | offs |yx| rmm | SVd |XO |mm|sk | XO | + */ + if ((value == 8) || (value == 9)) + *errmsg = _("invalid SVrm value"); + + return insn | ((value & 0xf) << 7); +} + +static int64_t +extract_SVrm (uint64_t insn, + ppc_cpu_t dialect ATTRIBUTE_UNUSED, + int *invalid) +{ + int64_t value = (insn >> 7) & 0xf; + + /* + * We should never meet the condition below in practice. + * svshape2 opcode and mask should always be matched first. + */ + if ((value == 8) || (value == 9)) + *invalid = 1; + + return value; +} + /* The operands table. @@ -3110,6 +3171,7 @@ const struct powerpc_operand powerpc_operands[] = /* The L field in a D or X form instruction. */ #define L IMM20 + 1 +#define yx10 L { 0x1, 21, NULL, NULL, 0 }, /* The optional L field in tlbie and tlbiel instructions. */ @@ -3864,13 +3926,16 @@ const struct powerpc_operand powerpc_operands[] = { 0x1f, 11, NULL, NULL, PPC_OPERAND_NONZERO }, #define SVrm SVzd + 1 - { 0xf, 7, NULL, NULL, 0 }, + { 0xf, 7, insert_SVrm, extract_SVrm, 0 }, #define mi1 SVrm + 1 { 0x3, 17, NULL, NULL, 0 }, #define mi2 mi1 + 1 { 0x3, 15, NULL, NULL, 0 }, + +#define SVo mi2 + 1 + { 0xf, 22, NULL, NULL, 0 }, }; const unsigned int num_powerpc_operands = (sizeof (powerpc_operands) @@ -4759,6 +4824,13 @@ const unsigned int num_powerpc_operands = (sizeof (powerpc_operands) | (((uint64_t)(xop)) & 0x3f)) #define SVM_MASK SVM (0x3f, 0x3f) +/* An SVM2 form instruction. */ +#define SVM2(op, xop) \ + (OP (op) \ + | (((((uint64_t)(xop)) >> 6) & 0x7) << 8) \ + | (((uint64_t)(xop)) & 0x3f)) +#define SVM2_MASK SVM2 (0x3f, 0x1ff) + /* An SVRM form instruction. */ #define SVRM(op, xop) \ (OP (op) \ @@ -6844,6 +6916,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { {"svstep", SVL(22,19,0), SVL_MASK, SVP64, PPCVLE, {RT, SVi, vf}}, {"svstep.", SVL(22,19,1), SVL_MASK, SVP64, PPCVLE, {RT, SVi, vf}}, +{"svshape2", SVM2(22,281), SVM2_MASK, SVP64, PPCVLE, {SVo, yx10, rmm, SVd, sk, mm}}, {"svshape", SVM(22,25), SVM_MASK, SVP64, PPCVLE, {SVxd, SVyd, SVzd, SVrm, vf}}, {"setvl", SVL(22,27,0), SVL_MASK, SVP64, PPCVLE, {RT, RA, SVi, vf, vs, ms}}, -- 2.30.2