From f23f8232fbfdbd7639f46257aa4e1c31bdd91f5f Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 29 May 2023 01:04:55 +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 | 16 ++++--- gas/testsuite/gas/ppc/svshape.s | 6 +++ opcodes/ppc-opc.c | 80 ++++++++++++++++++++++++++++++--- 3 files changed, 92 insertions(+), 10 deletions(-) diff --git a/gas/testsuite/gas/ppc/svshape.d b/gas/testsuite/gas/ppc/svshape.d index 8244741ed33..9cfd638c302 100644 --- a/gas/testsuite/gas/ppc/svshape.d +++ b/gas/testsuite/gas/ppc/svshape.d @@ -6,8 +6,14 @@ Disassembly of section \.text: 0+ <\.text>: -.*: (19 00 e0 5b|5b e0 00 19) svshape 32,1,1,0,0 -.*: (19 00 1f 58|58 1f 00 19) svshape 1,32,1,0,0 -.*: (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 +.*:\s+(19 00 e0 5b|5b e0 00 19)\s+svshape\s+32,1,1,0,0 +.*:\s+(19 00 1f 58|58 1f 00 19)\s+svshape\s+1,32,1,0,0 +.*:\s+(19 f8 00 58|58 00 f8 19)\s+svshape\s+1,1,32,0,0 +.*:\s+(99 07 00 58|58 00 07 99)\s+svshape\s+1,1,1,15,0 +.*:\s+(59 00 00 58|58 00 00 59)\s+svshape\s+1,1,1,0,1 +.*:\s+(19 04 c0 5b|5b c0 04 19)\s+svshape2\s+15,0,0,1,0,0 +.*:\s+(19 04 20 58|58 20 04 19)\s+svshape2\s+0,1,0,1,0,0 +.*:\s+(19 04 1f 58|58 1f 04 19)\s+svshape2\s+0,0,31,1,0,0 +.*:\s+(19 fc 00 58|58 00 fc 19)\s+svshape2\s+0,0,0,32,0,0 +.*:\s+(59 04 00 58|58 00 04 59)\s+svshape2\s+0,0,0,1,1,0 +.*:\s+(99 04 00 58|58 00 04 99)\s+svshape2\s+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 37f1aeb780c..8afd12faff9 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -2785,6 +2785,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. @@ -3188,6 +3249,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. */ @@ -3945,10 +4007,7 @@ const struct powerpc_operand powerpc_operands[] = #define yx ms { 0x1, 8, NULL, NULL, 0 }, -#define SVLcr ms + 1 - { 0x1, 5, NULL, NULL, 0 }, - -#define SVxd SVLcr + 1 +#define SVxd ms + 1 { 0x1f, 21, NULL, NULL, PPC_OPERAND_NONZERO }, #define SVyd SVxd + 1 @@ -3959,13 +4018,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 = ARRAY_SIZE (powerpc_operands); @@ -4864,6 +4926,13 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (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) \ @@ -6950,6 +7019,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