aarch64: [SME] Add MOV and MOVA instructions
This patch is adding new MOV (alias) and MOVA SME instruction. gas/ChangeLog: * config/tc-aarch64.c (enum sme_hv_slice): new enum. (struct reloc_entry): Added ZAH and ZAV registers. (parse_sme_immediate): Immediate parser. (parse_sme_za_hv_tiles_operand): ZA tile parser. (parse_sme_za_hv_tiles_operand_index): Index parser. (parse_operands): Added ZA tile parser calls. (REGNUMS): New macro. Regs with suffix. (REGSET16S): New macro. 16 regs with suffix. * testsuite/gas/aarch64/sme-2-illegal.d: New test. * testsuite/gas/aarch64/sme-2-illegal.l: New test. * testsuite/gas/aarch64/sme-2-illegal.s: New test. * testsuite/gas/aarch64/sme-2.d: New test. * testsuite/gas/aarch64/sme-2.s: New test. * testsuite/gas/aarch64/sme-2a.d: New test. * testsuite/gas/aarch64/sme-2a.s: New test. * testsuite/gas/aarch64/sme-3-illegal.d: New test. * testsuite/gas/aarch64/sme-3-illegal.l: New test. * testsuite/gas/aarch64/sme-3-illegal.s: New test. * testsuite/gas/aarch64/sme-3.d: New test. * testsuite/gas/aarch64/sme-3.s: New test. * testsuite/gas/aarch64/sme-3a.d: New test. * testsuite/gas/aarch64/sme-3a.s: New test. include/ChangeLog: * opcode/aarch64.h (enum aarch64_opnd): New enums AARCH64_OPND_SME_ZA_HV_idx_src and AARCH64_OPND_SME_ZA_HV_idx_dest. (struct aarch64_opnd_info): New ZA tile vector struct. opcodes/ChangeLog: * aarch64-asm.c (aarch64_ins_sme_za_hv_tiles): New inserter. * aarch64-asm.h (AARCH64_DECL_OPD_INSERTER): New inserter ins_sme_za_hv_tiles. * aarch64-dis.c (aarch64_ext_sme_za_hv_tiles): New extractor. * aarch64-dis.h (AARCH64_DECL_OPD_EXTRACTOR): New extractor ext_sme_za_hv_tiles. * aarch64-opc.c (aarch64_print_operand): Handle SME_ZA_HV_idx_src and SME_ZA_HV_idx_dest. * aarch64-opc.h (enum aarch64_field_kind): New enums FLD_SME_size_10, FLD_SME_Q, FLD_SME_V and FLD_SME_Rv. (struct aarch64_operand): Increase fields size to 5. * aarch64-tbl.h (OP_SME_BHSDQ_PM_BHSDQ): New qualifiers aarch64-asm-2.c: Regenerate. aarch64-dis-2.c: Regenerate. aarch64-opc-2.c: Regenerate.
This commit is contained in:
parent
971eda7341
commit
7bb5f07c8a
26 changed files with 962 additions and 186 deletions
|
@ -99,6 +99,17 @@ enum vector_el_type
|
|||
NT_merge
|
||||
};
|
||||
|
||||
/* SME horizontal or vertical slice indicator, encoded in "V".
|
||||
Values:
|
||||
0 - Horizontal
|
||||
1 - vertical
|
||||
*/
|
||||
enum sme_hv_slice
|
||||
{
|
||||
HV_horizontal = 0,
|
||||
HV_vertical = 1
|
||||
};
|
||||
|
||||
/* Bits for DEFINED field in vector_type_el. */
|
||||
#define NTA_HASTYPE 1
|
||||
#define NTA_HASINDEX 2
|
||||
|
@ -279,6 +290,8 @@ struct reloc_entry
|
|||
BASIC_REG_TYPE(ZN) /* z[0-31] */ \
|
||||
BASIC_REG_TYPE(PN) /* p[0-15] */ \
|
||||
BASIC_REG_TYPE(ZA) /* za[0-15] */ \
|
||||
BASIC_REG_TYPE(ZAH) /* za[0-15]h */ \
|
||||
BASIC_REG_TYPE(ZAV) /* za[0-15]v */ \
|
||||
/* Typecheck: any 64-bit int reg (inc SP exc XZR). */ \
|
||||
MULTI_REG_TYPE(R64_SP, REG_TYPE(R_64) | REG_TYPE(SP_64)) \
|
||||
/* Typecheck: same, plus SVE registers. */ \
|
||||
|
@ -4276,6 +4289,178 @@ parse_sme_zada_operand (char **str, aarch64_opnd_qualifier_t *qualifier)
|
|||
return regno;
|
||||
}
|
||||
|
||||
/* Parse STR for unsigned, immediate (1-2 digits) in format:
|
||||
|
||||
#<imm>
|
||||
<imm>
|
||||
|
||||
Function return TRUE if immediate was found, or FALSE.
|
||||
*/
|
||||
static bool
|
||||
parse_sme_immediate (char **str, int64_t *imm)
|
||||
{
|
||||
int64_t val;
|
||||
if (! parse_constant_immediate (str, &val, REG_TYPE_R_N))
|
||||
return false;
|
||||
|
||||
*imm = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Parse index with vector select register and immediate:
|
||||
|
||||
[<Wv>, <imm>]
|
||||
[<Wv>, #<imm>]
|
||||
where <Wv> is in W12-W15 range and # is optional for immediate.
|
||||
|
||||
Function performs extra check for mandatory immediate value if REQUIRE_IMM
|
||||
is set to true.
|
||||
|
||||
On success function returns TRUE and populated VECTOR_SELECT_REGISTER and
|
||||
IMM output.
|
||||
*/
|
||||
static bool
|
||||
parse_sme_za_hv_tiles_operand_index (char **str,
|
||||
int *vector_select_register,
|
||||
int64_t *imm)
|
||||
{
|
||||
const reg_entry *reg;
|
||||
|
||||
if (!skip_past_char (str, '['))
|
||||
{
|
||||
set_syntax_error (_("expected '['"));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Vector select register W12-W15 encoded in the 2-bit Rv field. */
|
||||
reg = parse_reg (str);
|
||||
if (reg == NULL || reg->type != REG_TYPE_R_32
|
||||
|| reg->number < 12 || reg->number > 15)
|
||||
{
|
||||
set_syntax_error (_("expected vector select register W12-W15"));
|
||||
return false;
|
||||
}
|
||||
*vector_select_register = reg->number;
|
||||
|
||||
if (!skip_past_char (str, ',')) /* Optional index offset immediate. */
|
||||
{
|
||||
set_syntax_error (_("expected ','"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_sme_immediate (str, imm))
|
||||
{
|
||||
set_syntax_error (_("index offset immediate expected"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!skip_past_char (str, ']'))
|
||||
{
|
||||
set_syntax_error (_("expected ']'"));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Parse SME ZA horizontal or vertical vector access to tiles.
|
||||
Function extracts from STR to SLICE_INDICATOR <HV> horizontal (0) or
|
||||
vertical (1) ZA tile vector orientation. VECTOR_SELECT_REGISTER
|
||||
contains <Wv> select register and corresponding optional IMMEDIATE.
|
||||
In addition QUALIFIER is extracted.
|
||||
|
||||
Field format examples:
|
||||
|
||||
ZA0<HV>.B[<Wv>, #<imm>]
|
||||
<ZAn><HV>.H[<Wv>, #<imm>]
|
||||
<ZAn><HV>.S[<Wv>, #<imm>]
|
||||
<ZAn><HV>.D[<Wv>, #<imm>]
|
||||
<ZAn><HV>.Q[<Wv>, #<imm>]
|
||||
|
||||
Function returns <ZAda> register number or PARSE_FAIL.
|
||||
*/
|
||||
static int
|
||||
parse_sme_za_hv_tiles_operand (char **str,
|
||||
enum sme_hv_slice *slice_indicator,
|
||||
int *vector_select_register,
|
||||
int *imm,
|
||||
aarch64_opnd_qualifier_t *qualifier)
|
||||
{
|
||||
char *qh, *qv;
|
||||
int regno;
|
||||
int regno_limit;
|
||||
int64_t imm_limit;
|
||||
int64_t imm_value;
|
||||
const reg_entry *reg;
|
||||
|
||||
qh = qv = *str;
|
||||
if ((reg = parse_reg_with_qual (&qh, REG_TYPE_ZAH, qualifier)) != NULL)
|
||||
{
|
||||
*slice_indicator = HV_horizontal;
|
||||
*str = qh;
|
||||
}
|
||||
else if ((reg = parse_reg_with_qual (&qv, REG_TYPE_ZAV, qualifier)) != NULL)
|
||||
{
|
||||
*slice_indicator = HV_vertical;
|
||||
*str = qv;
|
||||
}
|
||||
else
|
||||
return PARSE_FAIL;
|
||||
regno = reg->number;
|
||||
|
||||
switch (*qualifier)
|
||||
{
|
||||
case AARCH64_OPND_QLF_S_B:
|
||||
regno_limit = 0;
|
||||
imm_limit = 15;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_H:
|
||||
regno_limit = 1;
|
||||
imm_limit = 7;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_S:
|
||||
regno_limit = 3;
|
||||
imm_limit = 3;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_D:
|
||||
regno_limit = 7;
|
||||
imm_limit = 1;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_Q:
|
||||
regno_limit = 15;
|
||||
imm_limit = 0;
|
||||
break;
|
||||
default:
|
||||
set_syntax_error (_("invalid ZA tile element size, allowed b, h, s, d and q"));
|
||||
return PARSE_FAIL;
|
||||
}
|
||||
|
||||
/* Check if destination register ZA tile vector is in range for given
|
||||
instruction variant. */
|
||||
if (regno < 0 || regno > regno_limit)
|
||||
{
|
||||
set_syntax_error (_("ZA tile vector out of range"));
|
||||
return PARSE_FAIL;
|
||||
}
|
||||
|
||||
if (!parse_sme_za_hv_tiles_operand_index (str, vector_select_register,
|
||||
&imm_value))
|
||||
return PARSE_FAIL;
|
||||
|
||||
/* Check if optional index offset is in the range for instruction
|
||||
variant. */
|
||||
if (imm_value < 0 || imm_value > imm_limit)
|
||||
{
|
||||
set_syntax_error (_("index offset out of range"));
|
||||
return PARSE_FAIL;
|
||||
}
|
||||
|
||||
*imm = imm_value;
|
||||
|
||||
return regno;
|
||||
}
|
||||
|
||||
|
||||
/* Parse a system register or a PSTATE field name for an MSR/MRS instruction.
|
||||
Returns the encoding for the option, or PARSE_FAIL.
|
||||
|
||||
|
@ -6989,6 +7174,26 @@ parse_operands (char *str, const aarch64_opcode *opcode)
|
|||
info->qualifier = qualifier;
|
||||
break;
|
||||
|
||||
case AARCH64_OPND_SME_ZA_HV_idx_src:
|
||||
case AARCH64_OPND_SME_ZA_HV_idx_dest:
|
||||
{
|
||||
enum sme_hv_slice vector_indicator;
|
||||
int vector_select_register;
|
||||
int imm;
|
||||
val = parse_sme_za_hv_tiles_operand (&str, &vector_indicator,
|
||||
&vector_select_register,
|
||||
&imm,
|
||||
&qualifier);
|
||||
if (val == PARSE_FAIL)
|
||||
goto failure;
|
||||
info->za_tile_vector.regno = val;
|
||||
info->za_tile_vector.index.regno = vector_select_register;
|
||||
info->za_tile_vector.index.imm = imm;
|
||||
info->za_tile_vector.v = vector_indicator;
|
||||
info->qualifier = qualifier;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
as_fatal (_("unhandled operand code %d"), operands[i]);
|
||||
}
|
||||
|
@ -7533,11 +7738,17 @@ aarch64_canonicalize_symbol_name (char *name)
|
|||
#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, true }
|
||||
#define REGDEF_ALIAS(s, n, t) { #s, n, REG_TYPE_##t, false}
|
||||
#define REGNUM(p,n,t) REGDEF(p##n, n, t)
|
||||
#define REGNUMS(p,n,s,t) REGDEF(p##n##s, n, t)
|
||||
#define REGSET16(p,t) \
|
||||
REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
|
||||
REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
|
||||
REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
|
||||
REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
|
||||
#define REGSET16S(p,s,t) \
|
||||
REGNUMS(p, 0,s,t), REGNUMS(p, 1,s,t), REGNUMS(p, 2,s,t), REGNUMS(p, 3,s,t), \
|
||||
REGNUMS(p, 4,s,t), REGNUMS(p, 5,s,t), REGNUMS(p, 6,s,t), REGNUMS(p, 7,s,t), \
|
||||
REGNUMS(p, 8,s,t), REGNUMS(p, 9,s,t), REGNUMS(p,10,s,t), REGNUMS(p,11,s,t), \
|
||||
REGNUMS(p,12,s,t), REGNUMS(p,13,s,t), REGNUMS(p,14,s,t), REGNUMS(p,15,s,t)
|
||||
#define REGSET31(p,t) \
|
||||
REGSET16(p, t), \
|
||||
REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
|
||||
|
@ -7588,7 +7799,13 @@ static const reg_entry reg_names[] = {
|
|||
REGSET16 (p, PN), REGSET16 (P, PN),
|
||||
|
||||
/* SME ZA tile registers. */
|
||||
REGSET16 (za, ZA), REGSET16 (ZA, ZA)
|
||||
REGSET16 (za, ZA), REGSET16 (ZA, ZA),
|
||||
|
||||
/* SME ZA tile registers (horizontal slice). */
|
||||
REGSET16S (za, h, ZAH), REGSET16S (ZA, H, ZAH),
|
||||
|
||||
/* SME ZA tile registers (vertical slice). */
|
||||
REGSET16S (za, v, ZAV), REGSET16S (ZA, V, ZAV)
|
||||
};
|
||||
|
||||
#undef REGDEF
|
||||
|
|
3
gas/testsuite/gas/aarch64/sme-2-illegal.d
Normal file
3
gas/testsuite/gas/aarch64/sme-2-illegal.d
Normal file
|
@ -0,0 +1,3 @@
|
|||
#as: -march=armv8-a+sme
|
||||
#source: sme-2-illegal.s
|
||||
#error_output: sme-2-illegal.l
|
27
gas/testsuite/gas/aarch64/sme-2-illegal.l
Normal file
27
gas/testsuite/gas/aarch64/sme-2-illegal.l
Normal file
|
@ -0,0 +1,27 @@
|
|||
[^:]*: Assembler messages:
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.b,p0/m,za1h\.b\[w12,#0\]'
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.h,p0/m,za2h\.h\[w12,#0\]'
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.s,p0/m,za4h\.s\[w12,#0\]'
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 3 -- `mova z0\.d,p0/m,za8h\.d\[w12,#0\]'
|
||||
[^:]*:[0-9]+: Error: operand 3 must be an SME horizontal or vertical vector access register -- `mova z0\.q,p0/m,za16h.q\[w12\]'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.b,p7/m,za0v\.b\[w15,#16\]'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.h,p7/m,za1v\.h\[w15,#8\]'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.s,p7/m,za3v\.s\[w15,#4\]'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.d,p7/m,za7v\.d\[w15,#2\]'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 3 -- `mova z31\.q,p7/m,za15v\.q\[w15,#1\]'
|
||||
[^:]*:[0-9]+: Error: expected ',' at operand 3 -- `mova z31\.q,p7/m,za15v\.q\[w15\]'
|
||||
[^:]*:[0-9]+: Error: expected '\[' at operand 3 -- `mova z0\.b,p0/m,za0v.b'
|
||||
[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z31\.b,p7/m,za0v\.b\[15,w15\]'
|
||||
[^:]*:[0-9]+: Error: expected ',' at operand 3 -- `mova z0\.h,p0/m,za0v\.h\[w12\. 0\]'
|
||||
[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.s,p0/m,za0v\.s\[x12,0]'
|
||||
[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.d,p0/m,za0v\.d\[w21,0\]'
|
||||
[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[s12\]'
|
||||
[^:]*:[0-9]+: Error: expected vector select register W12-W15 at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[d12\]'
|
||||
[^:]*:[0-9]+: Error: index offset immediate expected at operand 3 -- `mova z0.q,p0/m,za0v\.q\[w12,\]'
|
||||
[^:]*:[0-9]+: Error: expected ',' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12\.\]'
|
||||
[^:]*:[0-9]+: Error: index offset immediate expected at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,abc\]'
|
||||
[^:]*:[0-9]+: Error: index offset immediate expected at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#abc\]'
|
||||
[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,1a\]'
|
||||
[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a\]'
|
||||
[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,1a2\]'
|
||||
[^:]*:[0-9]+: Error: expected '\]' at operand 3 -- `mova z0\.q,p0/m,za0v\.q\[w12,#1a2\]'
|
32
gas/testsuite/gas/aarch64/sme-2-illegal.s
Normal file
32
gas/testsuite/gas/aarch64/sme-2-illegal.s
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* Scalable Matrix Extension (SME). */
|
||||
|
||||
/* MOVA (tile to vector) variant. */
|
||||
mova z0.b, p0/m, za1h.b[w12, #0]
|
||||
mova z0.h, p0/m, za2h.h[w12, #0]
|
||||
mova z0.s, p0/m, za4h.s[w12, #0]
|
||||
mova z0.d, p0/m, za8h.d[w12, #0]
|
||||
mova z0.q, p0/m, za16h.q[w12]
|
||||
|
||||
mova z31.b, p7/m, za0v.b[w15, #16]
|
||||
mova z31.h, p7/m, za1v.h[w15, #8]
|
||||
mova z31.s, p7/m, za3v.s[w15, #4]
|
||||
mova z31.d, p7/m, za7v.d[w15, #2]
|
||||
mova z31.q, p7/m, za15v.q[w15, #1]
|
||||
mova z31.q, p7/m, za15v.q[w15]
|
||||
|
||||
/* Syntax issues. */
|
||||
mova z0.b, p0/m, za0v.b
|
||||
mova z31.b, p7/m, za0v.b[15, w15]
|
||||
mova z0.h, p0/m, za0v.h[w12. 0]
|
||||
mova z0.s, p0/m, za0v.s[x12, 0]
|
||||
mova z0.d, p0/m, za0v.d[w21, 0]
|
||||
mova z0.q, p0/m, za0v.q[s12]
|
||||
mova z0.q, p0/m, za0v.q[d12]
|
||||
mova z0.q, p0/m, za0v.q[w12,]
|
||||
mova z0.q, p0/m, za0v.q[w12.]
|
||||
mova z0.q, p0/m, za0v.q[w12, abc]
|
||||
mova z0.q, p0/m, za0v.q[w12, #abc]
|
||||
mova z0.q, p0/m, za0v.q[w12, 1a]
|
||||
mova z0.q, p0/m, za0v.q[w12, #1a]
|
||||
mova z0.q, p0/m, za0v.q[w12, 1a2]
|
||||
mova z0.q, p0/m, za0v.q[w12, #1a2]
|
43
gas/testsuite/gas/aarch64/sme-2.d
Normal file
43
gas/testsuite/gas/aarch64/sme-2.d
Normal file
|
@ -0,0 +1,43 @@
|
|||
#name: SME extension, MOVA (tile to vector)
|
||||
#as: -march=armv8-a+sme
|
||||
#objdump: -dr
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+ <.*>:
|
||||
0: c0028000 mov z0.b, p0/m, za0v.b\[w12, 0\]
|
||||
4: c0428000 mov z0.h, p0/m, za0v.h\[w12, 0\]
|
||||
8: c0828000 mov z0.s, p0/m, za0v.s\[w12, 0\]
|
||||
c: c0c28000 mov z0.d, p0/m, za0v.d\[w12, 0\]
|
||||
10: c0c38000 mov z0.q, p0/m, za0v.q\[w12, 0\]
|
||||
14: c002fdff mov z31.b, p7/m, za0v.b\[w15, 15\]
|
||||
18: c042fdff mov z31.h, p7/m, za1v.h\[w15, 7\]
|
||||
1c: c082fdff mov z31.s, p7/m, za3v.s\[w15, 3\]
|
||||
20: c0c2fdff mov z31.d, p7/m, za7v.d\[w15, 1\]
|
||||
24: c0c3fdff mov z31.q, p7/m, za15v.q\[w15, 0\]
|
||||
28: c0020000 mov z0.b, p0/m, za0h.b\[w12, 0\]
|
||||
2c: c0420000 mov z0.h, p0/m, za0h.h\[w12, 0\]
|
||||
30: c0820000 mov z0.s, p0/m, za0h.s\[w12, 0\]
|
||||
34: c0c20000 mov z0.d, p0/m, za0h.d\[w12, 0\]
|
||||
38: c0c30000 mov z0.q, p0/m, za0h.q\[w12, 0\]
|
||||
3c: c0027dff mov z31.b, p7/m, za0h.b\[w15, 15\]
|
||||
40: c0427dff mov z31.h, p7/m, za1h.h\[w15, 7\]
|
||||
44: c0827dff mov z31.s, p7/m, za3h.s\[w15, 3\]
|
||||
48: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
|
||||
4c: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
|
||||
50: c0027dff mov z31.b, p7/m, za0h.b\[w15, 15\]
|
||||
54: c0427dff mov z31.h, p7/m, za1h.h\[w15, 7\]
|
||||
58: c0827dff mov z31.s, p7/m, za3h.s\[w15, 3\]
|
||||
5c: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
|
||||
60: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
|
||||
64: c0027dff mov z31.b, p7/m, za0h.b\[w15, 15\]
|
||||
68: c0427dff mov z31.h, p7/m, za1h.h\[w15, 7\]
|
||||
6c: c0827dff mov z31.s, p7/m, za3h.s\[w15, 3\]
|
||||
70: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
|
||||
74: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
|
||||
78: c0c27dff mov z31.d, p7/m, za7h.d\[w15, 1\]
|
||||
7c: c0c37dff mov z31.q, p7/m, za15h.q\[w15, 0\]
|
||||
80: c002a400 mov z0.b, p1/m, za0v.b\[w13, 0\]
|
||||
84: c002a4e0 mov z0.b, p1/m, za0v.b\[w13, 7\]
|
52
gas/testsuite/gas/aarch64/sme-2.s
Normal file
52
gas/testsuite/gas/aarch64/sme-2.s
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* Scalable Matrix Extension (SME). */
|
||||
|
||||
/* MOVA (tile to vector) variant. */
|
||||
mova z0.b, p0/m, za0v.b[w12, 0]
|
||||
mova z0.h, p0/m, za0v.h[w12, 0]
|
||||
mova z0.s, p0/m, za0v.s[w12, 0]
|
||||
mova z0.d, p0/m, za0v.d[w12, 0]
|
||||
mova z0.q, p0/m, za0v.q[w12, 0]
|
||||
|
||||
mova z31.b, p7/m, za0v.b[w15, 15]
|
||||
mova z31.h, p7/m, za1v.h[w15, 7]
|
||||
mova z31.s, p7/m, za3v.s[w15, 3]
|
||||
mova z31.d, p7/m, za7v.d[w15, 1]
|
||||
mova z31.q, p7/m, za15v.q[w15, 0]
|
||||
|
||||
mova z0.b, p0/m, za0h.b[w12, 0]
|
||||
mova z0.h, p0/m, za0h.h[w12, 0]
|
||||
mova z0.s, p0/m, za0h.s[w12, 0]
|
||||
mova z0.d, p0/m, za0h.d[w12, 0]
|
||||
mova z0.q, p0/m, za0h.q[w12, 0]
|
||||
|
||||
mova z31.b, p7/m, za0h.b[w15, 15]
|
||||
mova z31.h, p7/m, za1h.h[w15, 7]
|
||||
mova z31.s, p7/m, za3h.s[w15, 3]
|
||||
mova z31.d, p7/m, za7h.d[w15, 1]
|
||||
mova z31.q, p7/m, za15h.q[w15, 0]
|
||||
|
||||
/* Parser checks. */
|
||||
mova z31.b , p7/m , za0h.b [ w15 , 15 ]
|
||||
mova z31.h , p7/m , za1h.h [ w15 , 7 ]
|
||||
mova z31.s , p7/m , za3h.s [ w15 , 3 ]
|
||||
mova z31.d , p7/m , za7h.d [ w15 , 1 ]
|
||||
mova z31.q , p7/m , za15h.q [ w15 , #0 ]
|
||||
mova z31.b , p7/m , za0h.b [ w15 , #15 ]
|
||||
mova z31.h , p7/m , za1h.h [ w15 , #7 ]
|
||||
mova z31.s , p7/m , za3h.s [ w15 , #3 ]
|
||||
mova z31.d , p7/m , za7h.d [ w15 , #1 ]
|
||||
mova z31.q , p7/m , za15h.q [ w15, #0 ]
|
||||
|
||||
/* Register aliases. */
|
||||
foo .req w15
|
||||
bar .req za7h
|
||||
baz .req z31
|
||||
|
||||
mova z31.d , p7/m , bar.d [ foo , #1 ]
|
||||
mova baz.q , p7/m , za15h.q [ foo , #0 ]
|
||||
|
||||
/* Named immediate. */
|
||||
val_zero = 0
|
||||
val_seven = 7
|
||||
mova z0.b, p1/m, za0v.b[w13, #val_zero]
|
||||
mova z0.b, p1/m, za0v.b[w13, #val_seven]
|
29
gas/testsuite/gas/aarch64/sme-2a.d
Normal file
29
gas/testsuite/gas/aarch64/sme-2a.d
Normal file
|
@ -0,0 +1,29 @@
|
|||
#name: SME extension, MOV (tile to vector)
|
||||
#as: -march=armv8-a+sme
|
||||
#objdump: -dr
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+ <.*>:
|
||||
0: c0028000 mov z0\.b, p0/m, za0v\.b\[w12, 0\]
|
||||
4: c0428000 mov z0\.h, p0/m, za0v\.h\[w12, 0\]
|
||||
8: c0828000 mov z0\.s, p0/m, za0v\.s\[w12, 0\]
|
||||
c: c0c28000 mov z0\.d, p0/m, za0v\.d\[w12, 0\]
|
||||
10: c0c38000 mov z0\.q, p0/m, za0v\.q\[w12, 0\]
|
||||
14: c002fdff mov z31\.b, p7/m, za0v\.b\[w15, 15\]
|
||||
18: c042fdff mov z31\.h, p7/m, za1v\.h\[w15, 7\]
|
||||
1c: c082fdff mov z31\.s, p7/m, za3v\.s\[w15, 3\]
|
||||
20: c0c2fdff mov z31\.d, p7/m, za7v\.d\[w15, 1\]
|
||||
24: c0c3fdff mov z31\.q, p7/m, za15v\.q\[w15, 0\]
|
||||
28: c0020000 mov z0\.b, p0/m, za0h\.b\[w12, 0\]
|
||||
2c: c0420000 mov z0\.h, p0/m, za0h\.h\[w12, 0\]
|
||||
30: c0820000 mov z0\.s, p0/m, za0h\.s\[w12, 0\]
|
||||
34: c0c20000 mov z0\.d, p0/m, za0h\.d\[w12, 0\]
|
||||
38: c0c30000 mov z0\.q, p0/m, za0h\.q\[w12, 0\]
|
||||
3c: c0027dff mov z31\.b, p7/m, za0h\.b\[w15, 15\]
|
||||
40: c0427dff mov z31\.h, p7/m, za1h\.h\[w15, 7\]
|
||||
44: c0827dff mov z31\.s, p7/m, za3h\.s\[w15, 3\]
|
||||
48: c0c27dff mov z31\.d, p7/m, za7h\.d\[w15, 1\]
|
||||
4c: c0c37dff mov z31\.q, p7/m, za15h\.q\[w15, 0\]
|
26
gas/testsuite/gas/aarch64/sme-2a.s
Normal file
26
gas/testsuite/gas/aarch64/sme-2a.s
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Scalable Matrix Extension (SME). */
|
||||
|
||||
/* MOV alias (tile to vector) variant. */
|
||||
mov z0.b, p0/m, za0v.b[w12, 0]
|
||||
mov z0.h, p0/m, za0v.h[w12, 0]
|
||||
mov z0.s, p0/m, za0v.s[w12, 0]
|
||||
mov z0.d, p0/m, za0v.d[w12, 0]
|
||||
mov z0.q, p0/m, za0v.q[w12, 0]
|
||||
|
||||
mov z31.b, p7/m, za0v.b[w15, 15]
|
||||
mov z31.h, p7/m, za1v.h[w15, 7]
|
||||
mov z31.s, p7/m, za3v.s[w15, 3]
|
||||
mov z31.d, p7/m, za7v.d[w15, 1]
|
||||
mov z31.q, p7/m, za15v.q[w15, 0]
|
||||
|
||||
mov z0.b, p0/m, za0h.b[w12, 0]
|
||||
mov z0.h, p0/m, za0h.h[w12, 0]
|
||||
mov z0.s, p0/m, za0h.s[w12, 0]
|
||||
mov z0.d, p0/m, za0h.d[w12, 0]
|
||||
mov z0.q, p0/m, za0h.q[w12, 0]
|
||||
|
||||
mov z31.b, p7/m, za0h.b[w15, 15]
|
||||
mov z31.h, p7/m, za1h.h[w15, 7]
|
||||
mov z31.s, p7/m, za3h.s[w15, 3]
|
||||
mov z31.d, p7/m, za7h.d[w15, 1]
|
||||
mov z31.q, p7/m, za15h.q[w15, 0]
|
3
gas/testsuite/gas/aarch64/sme-3-illegal.d
Normal file
3
gas/testsuite/gas/aarch64/sme-3-illegal.d
Normal file
|
@ -0,0 +1,3 @@
|
|||
#as: -march=armv8-a+sme
|
||||
#source: sme-3-illegal.s
|
||||
#error_output: sme-3-illegal.l
|
11
gas/testsuite/gas/aarch64/sme-3-illegal.l
Normal file
11
gas/testsuite/gas/aarch64/sme-3-illegal.l
Normal file
|
@ -0,0 +1,11 @@
|
|||
[^:]*: Assembler messages:
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za1v\.b\[w12,#0\],p0/m,z0.b'
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za2v\.h\[w12,#0\],p0/m,z0.h'
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za4v\.s\[w12,#0\],p0/m,z0.s'
|
||||
[^:]*:[0-9]+: Error: ZA tile vector out of range at operand 1 -- `mova za8v\.d\[w12,#0\],p0/m,z0.d'
|
||||
[^:]*:[0-9]+: Error: operand 1 must be an SME horizontal or vertical vector access register -- `mova za16v\.q\[w12\],p0/m,z0.q'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za0v\.b\[w15,#16\],p7/m,z31.b'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za1v\.h\[w15,#8\],p7/m,z31.h'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za3v\.s\[w15,#4\],p7/m,z31.s'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za7v\.d\[w15,#2\],p7/m,z31.d'
|
||||
[^:]*:[0-9]+: Error: index offset out of range at operand 1 -- `mova za15v\.q\[w15,#1\],p7/m,z31.q'
|
14
gas/testsuite/gas/aarch64/sme-3-illegal.s
Normal file
14
gas/testsuite/gas/aarch64/sme-3-illegal.s
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* Scalable Matrix Extension (SME). */
|
||||
|
||||
/* MOVA (vector to tile) variant. */
|
||||
mova za1v.b[w12, #0], p0/m, z0.b
|
||||
mova za2v.h[w12, #0], p0/m, z0.h
|
||||
mova za4v.s[w12, #0], p0/m, z0.s
|
||||
mova za8v.d[w12, #0], p0/m, z0.d
|
||||
mova za16v.q[w12], p0/m, z0.q
|
||||
|
||||
mova za0v.b[w15, #16], p7/m, z31.b
|
||||
mova za1v.h[w15, #8], p7/m, z31.h
|
||||
mova za3v.s[w15, #4], p7/m, z31.s
|
||||
mova za7v.d[w15, #2], p7/m, z31.d
|
||||
mova za15v.q[w15, #1], p7/m, z31.q
|
31
gas/testsuite/gas/aarch64/sme-3.d
Normal file
31
gas/testsuite/gas/aarch64/sme-3.d
Normal file
|
@ -0,0 +1,31 @@
|
|||
#name: SME extension, MOVA (vector to tile)
|
||||
#as: -march=armv8-a+sme
|
||||
#objdump: -dr
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+ <.*>:
|
||||
0: c0008000 mov za0v\.b\[w12, 0\], p0/m, z0\.b
|
||||
4: c0408000 mov za0v\.h\[w12, 0\], p0/m, z0\.h
|
||||
8: c0808000 mov za0v\.s\[w12, 0\], p0/m, z0\.s
|
||||
c: c0c08000 mov za0v\.d\[w12, 0\], p0/m, z0\.d
|
||||
10: c0c18000 mov za0v\.q\[w12, 0\], p0/m, z0\.q
|
||||
14: c000ffef mov za0v\.b\[w15, 15\], p7/m, z31\.b
|
||||
18: c040ffef mov za1v\.h\[w15, 7\], p7/m, z31\.h
|
||||
1c: c080ffef mov za3v\.s\[w15, 3\], p7/m, z31\.s
|
||||
20: c0c0ffef mov za7v\.d\[w15, 1\], p7/m, z31\.d
|
||||
24: c0c1ffef mov za15v\.q\[w15, 0\], p7/m, z31\.q
|
||||
28: c0000000 mov za0h\.b\[w12, 0\], p0/m, z0\.b
|
||||
2c: c0400000 mov za0h\.h\[w12, 0\], p0/m, z0\.h
|
||||
30: c0800000 mov za0h\.s\[w12, 0\], p0/m, z0\.s
|
||||
34: c0c00000 mov za0h\.d\[w12, 0\], p0/m, z0\.d
|
||||
38: c0c10000 mov za0h\.q\[w12, 0\], p0/m, z0\.q
|
||||
3c: c0007fef mov za0h\.b\[w15, 15\], p7/m, z31\.b
|
||||
40: c0407fef mov za1h\.h\[w15, 7\], p7/m, z31\.h
|
||||
44: c0807fef mov za3h\.s\[w15, 3\], p7/m, z31\.s
|
||||
48: c0c07fef mov za7h\.d\[w15, 1\], p7/m, z31\.d
|
||||
4c: c0c17fef mov za15h\.q\[w15, 0\], p7/m, z31\.q
|
||||
50: c0008000 mov za0v\.b\[w12, 0\], p0/m, z0\.b
|
||||
54: c0c17fef mov za15h\.q\[w15, 0\], p7/m, z31\.q
|
31
gas/testsuite/gas/aarch64/sme-3.s
Normal file
31
gas/testsuite/gas/aarch64/sme-3.s
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* Scalable Matrix Extension (SME). */
|
||||
|
||||
/* MOVA (vector to tile) variant. */
|
||||
mova za0v.b[w12, 0], p0/m, z0.b
|
||||
mova za0v.h[w12, 0], p0/m, z0.h
|
||||
mova za0v.s[w12, 0], p0/m, z0.s
|
||||
mova za0v.d[w12, 0], p0/m, z0.d
|
||||
mova za0v.q[w12, 0], p0/m, z0.q
|
||||
|
||||
mova za0v.b[w15, 15], p7/m, z31.b
|
||||
mova za1v.h[w15, 7], p7/m, z31.h
|
||||
mova za3v.s[w15, 3], p7/m, z31.s
|
||||
mova za7v.d[w15, 1], p7/m, z31.d
|
||||
mova za15v.q[w15, 0], p7/m, z31.q
|
||||
|
||||
mova za0h.b[w12, 0], p0/m, z0.b
|
||||
mova za0h.h[w12, 0], p0/m, z0.h
|
||||
mova za0h.s[w12, 0], p0/m, z0.s
|
||||
mova za0h.d[w12, 0], p0/m, z0.d
|
||||
mova za0h.q[w12, 0], p0/m, z0.q
|
||||
|
||||
mova za0h.b[w15, 15], p7/m, z31.b
|
||||
mova za1h.h[w15, 7], p7/m, z31.h
|
||||
mova za3h.s[w15, 3], p7/m, z31.s
|
||||
mova za7h.d[w15, 1], p7/m, z31.d
|
||||
mova za15h.q[w15, 0], p7/m, z31.q
|
||||
|
||||
foo .req w12
|
||||
bar .req w15
|
||||
mova za0v.b[foo, 0], p0/m, z0.b
|
||||
mova za15h.q[bar, 0], p7/m, z31.q
|
29
gas/testsuite/gas/aarch64/sme-3a.d
Normal file
29
gas/testsuite/gas/aarch64/sme-3a.d
Normal file
|
@ -0,0 +1,29 @@
|
|||
#name: SME extension, MOV (vector to tile)
|
||||
#as: -march=armv8-a+sme
|
||||
#objdump: -dr
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+ <.*>:
|
||||
0: c0008000 mov za0v\.b\[w12, 0\], p0/m, z0\.b
|
||||
4: c0408000 mov za0v\.h\[w12, 0\], p0/m, z0\.h
|
||||
8: c0808000 mov za0v\.s\[w12, 0\], p0/m, z0\.s
|
||||
c: c0c08000 mov za0v\.d\[w12, 0\], p0/m, z0\.d
|
||||
10: c0c18000 mov za0v\.q\[w12, 0\], p0/m, z0\.q
|
||||
14: c000ffef mov za0v\.b\[w15, 15\], p7/m, z31\.b
|
||||
18: c040ffef mov za1v\.h\[w15, 7\], p7/m, z31\.h
|
||||
1c: c080ffef mov za3v\.s\[w15, 3\], p7/m, z31\.s
|
||||
20: c0c0ffef mov za7v\.d\[w15, 1\], p7/m, z31\.d
|
||||
24: c0c1ffef mov za15v\.q\[w15, 0\], p7/m, z31\.q
|
||||
28: c0000000 mov za0h\.b\[w12, 0\], p0/m, z0\.b
|
||||
2c: c0400000 mov za0h\.h\[w12, 0\], p0/m, z0\.h
|
||||
30: c0800000 mov za0h\.s\[w12, 0\], p0/m, z0\.s
|
||||
34: c0c00000 mov za0h\.d\[w12, 0\], p0/m, z0\.d
|
||||
38: c0c10000 mov za0h\.q\[w12, 0\], p0/m, z0\.q
|
||||
3c: c0007fef mov za0h\.b\[w15, 15\], p7/m, z31\.b
|
||||
40: c0407fef mov za1h\.h\[w15, 7\], p7/m, z31\.h
|
||||
44: c0807fef mov za3h\.s\[w15, 3\], p7/m, z31\.s
|
||||
48: c0c07fef mov za7h\.d\[w15, 1\], p7/m, z31\.d
|
||||
4c: c0c17fef mov za15h\.q\[w15, 0\], p7/m, z31\.q
|
26
gas/testsuite/gas/aarch64/sme-3a.s
Normal file
26
gas/testsuite/gas/aarch64/sme-3a.s
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Scalable Matrix Extension (SME). */
|
||||
|
||||
/* MOV alias (vector to tile) variant. */
|
||||
mov za0v.b[w12, 0], p0/m, z0.b
|
||||
mov za0v.h[w12, 0], p0/m, z0.h
|
||||
mov za0v.s[w12, 0], p0/m, z0.s
|
||||
mov za0v.d[w12, 0], p0/m, z0.d
|
||||
mov za0v.q[w12, 0], p0/m, z0.q
|
||||
|
||||
mov za0v.b[w15, 15], p7/m, z31.b
|
||||
mov za1v.h[w15, 7], p7/m, z31.h
|
||||
mov za3v.s[w15, 3], p7/m, z31.s
|
||||
mov za7v.d[w15, 1], p7/m, z31.d
|
||||
mov za15v.q[w15, 0], p7/m, z31.q
|
||||
|
||||
mov za0h.b[w12, 0], p0/m, z0.b
|
||||
mov za0h.h[w12, 0], p0/m, z0.h
|
||||
mov za0h.s[w12, 0], p0/m, z0.s
|
||||
mov za0h.d[w12, 0], p0/m, z0.d
|
||||
mov za0h.q[w12, 0], p0/m, z0.q
|
||||
|
||||
mov za0h.b[w15, 15], p7/m, z31.b
|
||||
mov za1h.h[w15, 7], p7/m, z31.h
|
||||
mov za3h.s[w15, 3], p7/m, z31.s
|
||||
mov za7h.d[w15, 1], p7/m, z31.d
|
||||
mov za15h.q[w15, 0], p7/m, z31.q
|
|
@ -447,6 +447,8 @@ enum aarch64_opnd
|
|||
AARCH64_OPND_SVE_ZtxN, /* SVE vector register list in Zt. */
|
||||
AARCH64_OPND_SME_ZAda_2b, /* SME <ZAda>.S, 2-bits. */
|
||||
AARCH64_OPND_SME_ZAda_3b, /* SME <ZAda>.D, 3-bits. */
|
||||
AARCH64_OPND_SME_ZA_HV_idx_src, /* SME source ZA tile vector. */
|
||||
AARCH64_OPND_SME_ZA_HV_idx_dest, /* SME destination ZA tile vector. */
|
||||
AARCH64_OPND_SME_Pm, /* SME scalable predicate register, bits [15:13]. */
|
||||
AARCH64_OPND_TME_UIMM16, /* TME unsigned 16-bit immediate. */
|
||||
AARCH64_OPND_SM3_IMM2, /* SM3 encodes lane in bits [13, 14]. */
|
||||
|
@ -1114,6 +1116,18 @@ struct aarch64_opnd_info
|
|||
uint32_t flags;
|
||||
} sysreg;
|
||||
|
||||
/* ZA tile vector, e.g. <ZAn><HV>.D[<Wv>{, <imm>}] */
|
||||
struct
|
||||
{
|
||||
int regno; /* <ZAn> */
|
||||
struct
|
||||
{
|
||||
int regno; /* <Wv> */
|
||||
int imm; /* <imm> */
|
||||
} index;
|
||||
unsigned v : 1; /* <HV> horizontal or vertical vector indicator. */
|
||||
} za_tile_vector;
|
||||
|
||||
const aarch64_cond *cond;
|
||||
/* The encoding of the PSTATE field. */
|
||||
aarch64_insn pstatefield;
|
||||
|
|
|
@ -663,7 +663,7 @@ aarch64_insert_operand (const aarch64_operand *self,
|
|||
case 207:
|
||||
case 209:
|
||||
case 210:
|
||||
case 211:
|
||||
case 213:
|
||||
return aarch64_ins_regno (self, info, code, inst, errors);
|
||||
case 15:
|
||||
return aarch64_ins_reg_extended (self, info, code, inst, errors);
|
||||
|
@ -675,7 +675,7 @@ aarch64_insert_operand (const aarch64_operand *self,
|
|||
case 33:
|
||||
case 34:
|
||||
case 35:
|
||||
case 213:
|
||||
case 215:
|
||||
return aarch64_ins_reglane (self, info, code, inst, errors);
|
||||
case 36:
|
||||
return aarch64_ins_reglist (self, info, code, inst, errors);
|
||||
|
@ -720,7 +720,7 @@ aarch64_insert_operand (const aarch64_operand *self,
|
|||
case 187:
|
||||
case 188:
|
||||
case 189:
|
||||
case 212:
|
||||
case 214:
|
||||
return aarch64_ins_imm (self, info, code, inst, errors);
|
||||
case 44:
|
||||
case 45:
|
||||
|
@ -879,6 +879,9 @@ aarch64_insert_operand (const aarch64_operand *self,
|
|||
case 206:
|
||||
case 208:
|
||||
return aarch64_ins_sve_reglist (self, info, code, inst, errors);
|
||||
case 211:
|
||||
case 212:
|
||||
return aarch64_ins_sme_za_hv_tiles (self, info, code, inst, errors);
|
||||
default: assert (0); abort ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1325,6 +1325,61 @@ aarch64_ins_sve_float_zero_one (const aarch64_operand *self,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Encode in SME instruction such as MOVA ZA tile vector register number,
|
||||
vector indicator, vector selector and immediate. */
|
||||
bool
|
||||
aarch64_ins_sme_za_hv_tiles (const aarch64_operand *self,
|
||||
const aarch64_opnd_info *info,
|
||||
aarch64_insn *code,
|
||||
const aarch64_inst *inst ATTRIBUTE_UNUSED,
|
||||
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int fld_size;
|
||||
int fld_q;
|
||||
int fld_v = info->za_tile_vector.v;
|
||||
int fld_rv = info->za_tile_vector.index.regno - 12;
|
||||
int fld_zan_imm = info->za_tile_vector.index.imm;
|
||||
int regno = info->za_tile_vector.regno;
|
||||
|
||||
switch (info->qualifier)
|
||||
{
|
||||
case AARCH64_OPND_QLF_S_B:
|
||||
fld_size = 0;
|
||||
fld_q = 0;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_H:
|
||||
fld_size = 1;
|
||||
fld_q = 0;
|
||||
fld_zan_imm |= regno << 3;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_S:
|
||||
fld_size = 2;
|
||||
fld_q = 0;
|
||||
fld_zan_imm |= regno << 2;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_D:
|
||||
fld_size = 3;
|
||||
fld_q = 0;
|
||||
fld_zan_imm |= regno << 1;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_Q:
|
||||
fld_size = 3;
|
||||
fld_q = 1;
|
||||
fld_zan_imm = regno;
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
insert_field (self->fields[0], code, fld_size, 0);
|
||||
insert_field (self->fields[1], code, fld_q, 0);
|
||||
insert_field (self->fields[2], code, fld_v, 0);
|
||||
insert_field (self->fields[3], code, fld_rv, 0);
|
||||
insert_field (self->fields[4], code, fld_zan_imm, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Miscellaneous encoding functions. */
|
||||
|
||||
/* Encode size[0], i.e. bit 22, for
|
||||
|
|
|
@ -98,6 +98,7 @@ AARCH64_DECL_OPD_INSERTER (ins_sve_reglist);
|
|||
AARCH64_DECL_OPD_INSERTER (ins_sve_scale);
|
||||
AARCH64_DECL_OPD_INSERTER (ins_sve_shlimm);
|
||||
AARCH64_DECL_OPD_INSERTER (ins_sve_shrimm);
|
||||
AARCH64_DECL_OPD_INSERTER (ins_sme_za_hv_tiles);
|
||||
AARCH64_DECL_OPD_INSERTER (ins_imm_rotate1);
|
||||
AARCH64_DECL_OPD_INSERTER (ins_imm_rotate2);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1748,6 +1748,64 @@ aarch64_ext_sve_float_zero_one (const aarch64_operand *self,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Decode ZA tile vector, vector indicator, vector selector, qualifier and
|
||||
immediate on numerous SME instruction fields such as MOVA. */
|
||||
bool
|
||||
aarch64_ext_sme_za_hv_tiles (const aarch64_operand *self,
|
||||
aarch64_opnd_info *info, aarch64_insn code,
|
||||
const aarch64_inst *inst ATTRIBUTE_UNUSED,
|
||||
aarch64_operand_error *errors ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int fld_size = extract_field (self->fields[0], code, 0);
|
||||
int fld_q = extract_field (self->fields[1], code, 0);
|
||||
int fld_v = extract_field (self->fields[2], code, 0);
|
||||
int fld_rv = extract_field (self->fields[3], code, 0);
|
||||
int fld_zan_imm = extract_field (self->fields[4], code, 0);
|
||||
|
||||
/* Deduce qualifier encoded in size and Q fields. */
|
||||
if (fld_size == 0)
|
||||
info->qualifier = AARCH64_OPND_QLF_S_B;
|
||||
else if (fld_size == 1)
|
||||
info->qualifier = AARCH64_OPND_QLF_S_H;
|
||||
else if (fld_size == 2)
|
||||
info->qualifier = AARCH64_OPND_QLF_S_S;
|
||||
else if (fld_size == 3 && fld_q == 0)
|
||||
info->qualifier = AARCH64_OPND_QLF_S_D;
|
||||
else if (fld_size == 3 && fld_q == 1)
|
||||
info->qualifier = AARCH64_OPND_QLF_S_Q;
|
||||
|
||||
info->za_tile_vector.index.regno = fld_rv + 12;
|
||||
info->za_tile_vector.v = fld_v;
|
||||
|
||||
switch (info->qualifier)
|
||||
{
|
||||
case AARCH64_OPND_QLF_S_B:
|
||||
info->za_tile_vector.regno = 0;
|
||||
info->za_tile_vector.index.imm = fld_zan_imm;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_H:
|
||||
info->za_tile_vector.regno = fld_zan_imm >> 3;
|
||||
info->za_tile_vector.index.imm = fld_zan_imm & 0x07;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_S:
|
||||
info->za_tile_vector.regno = fld_zan_imm >> 2;
|
||||
info->za_tile_vector.index.imm = fld_zan_imm & 0x03;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_D:
|
||||
info->za_tile_vector.regno = fld_zan_imm >> 1;
|
||||
info->za_tile_vector.index.imm = fld_zan_imm & 0x01;
|
||||
break;
|
||||
case AARCH64_OPND_QLF_S_Q:
|
||||
info->za_tile_vector.regno = fld_zan_imm;
|
||||
info->za_tile_vector.index.imm = 0;
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
|
||||
array specifies which field to use for Zn. MM is encoded in the
|
||||
concatenation of imm5 and SVE_tszh, with imm5 being the less
|
||||
|
|
|
@ -122,6 +122,7 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_sve_reglist);
|
|||
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_scale);
|
||||
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shlimm);
|
||||
AARCH64_DECL_OPD_EXTRACTOR (ext_sve_shrimm);
|
||||
AARCH64_DECL_OPD_EXTRACTOR (ext_sme_za_hv_tiles);
|
||||
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate1);
|
||||
AARCH64_DECL_OPD_EXTRACTOR (ext_imm_rotate2);
|
||||
|
||||
|
|
|
@ -235,6 +235,8 @@ const struct aarch64_operand aarch64_operands[] =
|
|||
{AARCH64_OPND_CLASS_SVE_REG, "SVE_ZtxN", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Zt}, "a list of SVE vector registers"},
|
||||
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZAda_2b", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_ZAda_2b}, "an SME ZA tile ZA0-ZA3"},
|
||||
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZAda_3b", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_ZAda_3b}, "an SME ZA tile ZA0-ZA7"},
|
||||
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_src", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_5}, "an SME horizontal or vertical vector access register"},
|
||||
{AARCH64_OPND_CLASS_SVE_REG, "SME_ZA_HV_idx_dest", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2}, "an SME horizontal or vertical vector access register"},
|
||||
{AARCH64_OPND_CLASS_PRED_REG, "SME_Pm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SME_Pm}, "an SVE predicate register"},
|
||||
{AARCH64_OPND_CLASS_IMMEDIATE, "TME_UIMM16", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_imm16}, "a 16-bit unsigned immediate for TME tcancel"},
|
||||
{AARCH64_OPND_CLASS_SIMD_ELEMENT, "SM3_IMM2", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SM3_imm2}, "an indexed SM3 vector immediate"},
|
||||
|
|
|
@ -242,6 +242,7 @@ const aarch64_field fields[] =
|
|||
{ 11, 4 }, /* imm4: in advsimd ext and advsimd ins instructions. */
|
||||
{ 0, 4 }, /* imm4_2: in rmif instructions. */
|
||||
{ 10, 4 }, /* imm4_3: in adddg/subg instructions. */
|
||||
{ 5, 4 }, /* imm4_5: in SME instructions. */
|
||||
{ 16, 5 }, /* imm5: in conditional compare (immediate) instructions. */
|
||||
{ 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */
|
||||
{ 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */
|
||||
|
@ -323,6 +324,10 @@ const aarch64_field fields[] =
|
|||
{ 22, 1 }, /* SVE_xs_22: UXTW/SXTW select (bit 22). */
|
||||
{ 0, 2 }, /* SME ZAda tile ZA0-ZA3. */
|
||||
{ 0, 3 }, /* SME ZAda tile ZA0-ZA7. */
|
||||
{ 22, 2 }, /* SME_size_10: size<1>, size<0> class field, [23:22]. */
|
||||
{ 16, 1 }, /* SME_Q: Q class bit, bit 16. */
|
||||
{ 15, 1 }, /* SME_V: (horizontal / vertical tiles), bit 15. */
|
||||
{ 13, 2 }, /* SME_Rv: vector select register W12-W15, bits [14:13]. */
|
||||
{ 13, 3 }, /* SME Pm second source scalable predicate register P0-P7. */
|
||||
{ 11, 2 }, /* rotate1: FCMLA immediate rotate. */
|
||||
{ 13, 2 }, /* rotate2: Indexed element FCMLA immediate rotate. */
|
||||
|
@ -3355,6 +3360,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
|
|||
aarch64_get_qualifier_name (opnd->qualifier));
|
||||
break;
|
||||
|
||||
case AARCH64_OPND_SME_ZA_HV_idx_src:
|
||||
case AARCH64_OPND_SME_ZA_HV_idx_dest:
|
||||
snprintf (buf, size, "za%d%c.%s[w%d, %d]",
|
||||
opnd->za_tile_vector.regno,
|
||||
opnd->za_tile_vector.v == 1 ? 'v' : 'h',
|
||||
aarch64_get_qualifier_name (opnd->qualifier),
|
||||
opnd->za_tile_vector.index.regno,
|
||||
opnd->za_tile_vector.index.imm);
|
||||
break;
|
||||
|
||||
case AARCH64_OPND_CRn:
|
||||
case AARCH64_OPND_CRm:
|
||||
snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
|
||||
|
|
|
@ -71,6 +71,7 @@ enum aarch64_field_kind
|
|||
FLD_imm4,
|
||||
FLD_imm4_2,
|
||||
FLD_imm4_3,
|
||||
FLD_imm4_5,
|
||||
FLD_imm5,
|
||||
FLD_imm7,
|
||||
FLD_imm8,
|
||||
|
@ -152,6 +153,10 @@ enum aarch64_field_kind
|
|||
FLD_SVE_xs_22,
|
||||
FLD_SME_ZAda_2b,
|
||||
FLD_SME_ZAda_3b,
|
||||
FLD_SME_size_10,
|
||||
FLD_SME_Q,
|
||||
FLD_SME_V,
|
||||
FLD_SME_Rv,
|
||||
FLD_SME_Pm,
|
||||
FLD_rotate1,
|
||||
FLD_rotate2,
|
||||
|
@ -186,7 +191,7 @@ struct aarch64_operand
|
|||
|
||||
/* The associated instruction bit-fields; no operand has more than 4
|
||||
bit-fields */
|
||||
enum aarch64_field_kind fields[4];
|
||||
enum aarch64_field_kind fields[5];
|
||||
|
||||
/* Brief description */
|
||||
const char *desc;
|
||||
|
|
|
@ -2203,6 +2203,14 @@
|
|||
{ \
|
||||
QLF5(S_D,P_M,P_M,S_H,S_H) \
|
||||
}
|
||||
#define OP_SME_BHSDQ_PM_BHSDQ \
|
||||
{ \
|
||||
QLF3(S_B,P_M,S_B), \
|
||||
QLF3(S_H,P_M,S_H), \
|
||||
QLF3(S_S,P_M,S_S), \
|
||||
QLF3(S_D,P_M,S_D), \
|
||||
QLF3(S_Q,P_M,S_Q) \
|
||||
}
|
||||
|
||||
/* e.g. UDOT <Vd>.2S, <Vn>.8B, <Vm>.8B. */
|
||||
#define QL_V3DOT \
|
||||
|
@ -5123,6 +5131,11 @@ const struct aarch64_opcode aarch64_opcode_table[] =
|
|||
SME_INSN ("usmops", 0xa1800010, 0xffe0001c, sme_misc, 0, OP5 (SME_ZAda_2b, SVE_Pg3, SME_Pm, SVE_Zn, SVE_Zm_16), OP_SME_ZADA_S_PM_PM_B_B, 0, 0),
|
||||
SME_I64_INSN ("usmops", 0xa1c00010, 0xffe00018, sme_misc, 0, OP5 (SME_ZAda_3b, SVE_Pg3, SME_Pm, SVE_Zn, SVE_Zm_16), OP_SME_ZADA_D_PM_PM_H_H, 0, 0),
|
||||
|
||||
SME_INSN ("mov", 0xc0020000, 0xff3e0200, sme_misc, 0, OP3 (SVE_Zd, SVE_Pg3, SME_ZA_HV_idx_src), OP_SME_BHSDQ_PM_BHSDQ, 0, 0),
|
||||
SME_INSN ("mov", 0xc0000000, 0xff3e0010, sme_misc, 0, OP3 (SME_ZA_HV_idx_dest, SVE_Pg3, SVE_Zn), OP_SME_BHSDQ_PM_BHSDQ, 0, 0),
|
||||
SME_INSN ("mova", 0xc0020000, 0xff3e0200, sme_misc, 0, OP3 (SVE_Zd, SVE_Pg3, SME_ZA_HV_idx_src), OP_SME_BHSDQ_PM_BHSDQ, 0, 0),
|
||||
SME_INSN ("mova", 0xc0000000, 0xff3e0010, sme_misc, 0, OP3 (SME_ZA_HV_idx_dest, SVE_Pg3, SVE_Zn), OP_SME_BHSDQ_PM_BHSDQ, 0, 0),
|
||||
|
||||
/* SIMD Dot Product (optional in v8.2-A). */
|
||||
DOT_INSN ("udot", 0x2e009400, 0xbf20fc00, dotproduct, OP3 (Vd, Vn, Vm), QL_V3DOT, F_SIZEQ),
|
||||
DOT_INSN ("sdot", 0xe009400, 0xbf20fc00, dotproduct, OP3 (Vd, Vn, Vm), QL_V3DOT, F_SIZEQ),
|
||||
|
@ -5694,6 +5707,12 @@ const struct aarch64_opcode aarch64_opcode_table[] =
|
|||
"an SME ZA tile ZA0-ZA3") \
|
||||
Y(SVE_REG, regno, "SME_ZAda_3b", 0, F(FLD_SME_ZAda_3b), \
|
||||
"an SME ZA tile ZA0-ZA7") \
|
||||
Y(SVE_REG, sme_za_hv_tiles, "SME_ZA_HV_idx_src", 0, \
|
||||
F(FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_5),\
|
||||
"an SME horizontal or vertical vector access register") \
|
||||
Y(SVE_REG, sme_za_hv_tiles, "SME_ZA_HV_idx_dest", 0, \
|
||||
F(FLD_SME_size_10,FLD_SME_Q,FLD_SME_V,FLD_SME_Rv,FLD_imm4_2),\
|
||||
"an SME horizontal or vertical vector access register") \
|
||||
Y(PRED_REG, regno, "SME_Pm", 0, F(FLD_SME_Pm), \
|
||||
"an SVE predicate register") \
|
||||
Y(IMMEDIATE, imm, "TME_UIMM16", 0, F(FLD_imm16), \
|
||||
|
|
Loading…
Add table
Reference in a new issue