[PATCH 3/6] Arm64: check tied operand specifier in aarch64-gen

Jan Beulich jbeulich@suse.com
Thu Mar 21 07:38:18 GMT 2024


On 20.03.2024 17:51, Richard Earnshaw (lists) wrote:
> On 23/02/2024 11:29, Jan Beulich wrote:
>> Make sure that field actually matches the specified operands. Don't
>> follow existing F_PSEUDO checking in using assertions, though. Print
>> meaingful error messages, thus - while not having a line number
>> available - at least providing some indication of where things are
>> wrong.
>>
>> Fix SVE2.1's extq accordingly, but don't extend the testsuite there:
>> There are further issues with its operands (SVE_Zm_imm4 doesn't look to
>> be correct to use there, as that describes an indexed vector register,
>> while here a separate vector register and immediate operand are to be
>> specified).
>>
>> --- a/opcodes/aarch64-gen.c
>> +++ b/opcodes/aarch64-gen.c
>> @@ -129,6 +129,7 @@ read_table (const struct aarch64_opcode*
>>    const struct aarch64_opcode *ent = table;
>>    opcode_node **new_ent;
>>    unsigned int index = initialize_index (table);
>> +  unsigned int errors = 0;
>>  
>>    if (!ent->name)
>>      return;
>> @@ -140,6 +141,8 @@ read_table (const struct aarch64_opcode*
>>  
>>    do
>>      {
>> +      bool match = false;
>> +
>>        /* F_PSEUDO needs to be used together with F_ALIAS to indicate an alias
>>  	 opcode is a programmer friendly pseudo instruction available only in
>>  	 the assembly code (thus will not show up in the disassembly).  */
>> @@ -150,12 +153,45 @@ read_table (const struct aarch64_opcode*
>>  	  index++;
>>  	  continue;
>>  	}
>> +
>> +      /* Check tied_operand against operands[].  */
>> +      for (unsigned int i = 1; i < ARRAY_SIZE (ent->operands); ++i)
>> +	{
>> +	  if (ent->operands[i] == AARCH64_OPND_NIL)
>> +	    break;
>> +
>> +	  if (ent->operands[i] != ent->operands[0])
>> +	    continue;
>> +	  match = true;
>> +
>> +	  if (i != ent->tied_operand)
>> +	    {
>> +	      fprintf (stderr, "%s: operands 1 and %u match, but tied=%u\n",
>> +		       ent->name, i + 1, ent->tied_operand);
>> +	      ++errors;
>> +	    }
> 
> I'm not sure I follow this.  It looks like you're testing that if one operand is tied to operand 0, then no other operand may overlap that, eg that
> 
> 	extq z3.b, z3.b, z3.b, #5
> 
> is an illegal instruction.  But I don't see anything in the instruction description that prohibits that.  While it may not be sensible, it's not obvious to me that it's prohibited.

No, that's no what is being tested. Here we're looking at operand types, i.e.
for extq with

SVE2p1_INSN("extq",0x05602400, 0xfff0fc00, sve_misc, 0, OP3 (SVE_Zd, SVE_Zd, SVE_Zm_imm4), OP_SVE_BBB, 0, 1),

the type of the first two operands is the same, while that of the 3rd is
different. Actual register types / numbers don't come into play here.

Jan


More information about the Binutils mailing list