This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [AArch64][SVE 20/32] Add support for tied operands


On 23/08/16 10:18, Richard Sandiford wrote:
> SVE has some instructions in which the same register appears twice
> in the assembly string, once as an input and once as an output.
> This patch adds a general mechanism for that.
> 
> The patch needs to add new information to the instruction entries.
> One option would have been to extend the flags field of the opcode
> to 64 bits (since we already rely on 64-bit integers being available
> on the host).  However, the *_INSN macros mean that it's easy to add
> new information as top-level fields without affecting the existing
> table entries too much.  Going for that option seemed to give slightly
> neater code.
> 
> OK to install?
> 
> Thanks,
> Richard
> 
> 
> include/opcode/
> 	* aarch64.h (aarch64_opcode): Add a tied_operand field.
> 	(AARCH64_OPDE_UNTIED_OPERAND): New aarch64_operand_error_kind.
> 
> opcodes/
> 	* aarch64-tbl.h (CORE_INSN, __FP_INSN, SIMD_INSN, CRYP_INSN)
> 	(_CRC_INSN, _LSE_INSN, _LOR_INSN, RDMA_INSN, FP16_INSN, SF16_INSN)
> 	(V8_2_INSN, aarch64_opcode_table): Initialize tied_operand field.
> 	* aarch64-opc.c (aarch64_match_operands_constraint): Check for
> 	tied operands.
> 
> gas/
> 	* config/tc-aarch64.c (output_operand_error_record): Handle
> 	AARCH64_OPDE_UNTIED_OPERAND.

OK.

R.

> 
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index 9591704..37f7d26 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -4419,6 +4419,11 @@ output_operand_error_record (const operand_error_record *record, char *str)
>  	}
>        break;
>  
> +    case AARCH64_OPDE_UNTIED_OPERAND:
> +      as_bad (_("operand %d must be the same register as operand 1 -- `%s'"),
> +	      detail->index + 1, str);
> +      break;
> +
>      case AARCH64_OPDE_OUT_OF_RANGE:
>        if (detail->data[0] != detail->data[1])
>  	as_bad (_("%s out of range %d to %d at operand %d -- `%s'"),
> diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
> index 24a2ddb..d39f10d 100644
> --- a/include/opcode/aarch64.h
> +++ b/include/opcode/aarch64.h
> @@ -539,6 +539,10 @@ struct aarch64_opcode
>    /* Flags providing information about this instruction */
>    uint32_t flags;
>  
> +  /* If nonzero, this operand and operand 0 are both registers and
> +     are required to have the same register number.  */
> +  unsigned char tied_operand;
> +
>    /* If non-NULL, a function to verify that a given instruction is valid.  */
>    bfd_boolean (* verifier) (const struct aarch64_opcode *, const aarch64_insn);
>  };
> @@ -872,6 +876,10 @@ typedef struct aarch64_inst aarch64_inst;
>       No syntax error, but the operands are not a valid combination, e.g.
>       FMOV D0,S0
>  
> +   AARCH64_OPDE_UNTIED_OPERAND
> +     The asm failed to use the same register for a destination operand
> +     and a tied source operand.
> +
>     AARCH64_OPDE_OUT_OF_RANGE
>       Error about some immediate value out of a valid range.
>  
> @@ -908,6 +916,7 @@ enum aarch64_operand_error_kind
>    AARCH64_OPDE_SYNTAX_ERROR,
>    AARCH64_OPDE_FATAL_SYNTAX_ERROR,
>    AARCH64_OPDE_INVALID_VARIANT,
> +  AARCH64_OPDE_UNTIED_OPERAND,
>    AARCH64_OPDE_OUT_OF_RANGE,
>    AARCH64_OPDE_UNALIGNED,
>    AARCH64_OPDE_REG_LIST,
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index 7a73c7e..30501fc 100644
> --- a/opcodes/aarch64-opc.c
> +++ b/opcodes/aarch64-opc.c
> @@ -2058,6 +2058,23 @@ aarch64_match_operands_constraint (aarch64_inst *inst,
>  
>    DEBUG_TRACE ("enter");
>  
> +  /* Check for cases where a source register needs to be the same as the
> +     destination register.  Do this before matching qualifiers since if
> +     an instruction has both invalid tying and invalid qualifiers,
> +     the error about qualifiers would suggest several alternative
> +     instructions that also have invalid tying.  */
> +  i = inst->opcode->tied_operand;
> +  if (i > 0 && (inst->operands[0].reg.regno != inst->operands[i].reg.regno))
> +    {
> +      if (mismatch_detail)
> +	{
> +	  mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
> +	  mismatch_detail->index = i;
> +	  mismatch_detail->error = NULL;
> +	}
> +      return 0;
> +    }
> +
>    /* Match operands' qualifier.
>       *INST has already had qualifier establish for some, if not all, of
>       its operands; we need to find out whether these established
> diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
> index 9a831e4..8f1c9b2 100644
> --- a/opcodes/aarch64-tbl.h
> +++ b/opcodes/aarch64-tbl.h
> @@ -1393,27 +1393,27 @@ static const aarch64_feature_set aarch64_feature_stat_profile =
>  #define ARMV8_2		&aarch64_feature_v8_2
>  
>  #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, NULL }
>  #define __FP_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, OP, FP, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, OP, FP, OPS, QUALS, FLAGS, 0, NULL }
>  #define SIMD_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, OP, SIMD, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, OP, SIMD, OPS, QUALS, FLAGS, 0, NULL }
>  #define CRYP_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, 0, CRYPTO, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, 0, CRYPTO, OPS, QUALS, FLAGS, 0, NULL }
>  #define _CRC_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, 0, CRC, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, 0, CRC, OPS, QUALS, FLAGS, 0, NULL }
>  #define _LSE_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, 0, LSE, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, 0, LSE, OPS, QUALS, FLAGS, 0, NULL }
>  #define _LOR_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, 0, LOR, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, 0, LOR, OPS, QUALS, FLAGS, 0, NULL }
>  #define RDMA_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, 0, RDMA, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, 0, RDMA, OPS, QUALS, FLAGS, 0, NULL }
>  #define FF16_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, 0, FP_F16, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, 0, FP_F16, OPS, QUALS, FLAGS, 0, NULL }
>  #define SF16_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS)		\
> -  { NAME, OPCODE, MASK, CLASS, 0, SIMD_F16, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, 0, SIMD_F16, OPS, QUALS, FLAGS, 0, NULL }
>  #define V8_2_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
> -  { NAME, OPCODE, MASK, CLASS, OP, ARMV8_2, OPS, QUALS, FLAGS, NULL }
> +  { NAME, OPCODE, MASK, CLASS, OP, ARMV8_2, OPS, QUALS, FLAGS, 0, NULL }
>  
>  struct aarch64_opcode aarch64_opcode_table[] =
>  {
> @@ -2389,13 +2389,13 @@ struct aarch64_opcode aarch64_opcode_table[] =
>    CORE_INSN ("ldp", 0x29400000, 0x7ec00000, ldstpair_off, 0, OP3 (Rt, Rt2, ADDR_SIMM7), QL_LDST_PAIR_R, F_SF),
>    CORE_INSN ("stp", 0x2d000000, 0x3fc00000, ldstpair_off, 0, OP3 (Ft, Ft2, ADDR_SIMM7), QL_LDST_PAIR_FP, 0),
>    CORE_INSN ("ldp", 0x2d400000, 0x3fc00000, ldstpair_off, 0, OP3 (Ft, Ft2, ADDR_SIMM7), QL_LDST_PAIR_FP, 0),
> -  {"ldpsw", 0x69400000, 0xffc00000, ldstpair_off, 0, CORE, OP3 (Rt, Rt2, ADDR_SIMM7), QL_LDST_PAIR_X32, 0, VERIFIER (ldpsw)},
> +  {"ldpsw", 0x69400000, 0xffc00000, ldstpair_off, 0, CORE, OP3 (Rt, Rt2, ADDR_SIMM7), QL_LDST_PAIR_X32, 0, 0, VERIFIER (ldpsw)},
>    /* Load/store register pair (indexed).  */
>    CORE_INSN ("stp", 0x28800000, 0x7ec00000, ldstpair_indexed, 0, OP3 (Rt, Rt2, ADDR_SIMM7), QL_LDST_PAIR_R, F_SF),
>    CORE_INSN ("ldp", 0x28c00000, 0x7ec00000, ldstpair_indexed, 0, OP3 (Rt, Rt2, ADDR_SIMM7), QL_LDST_PAIR_R, F_SF),
>    CORE_INSN ("stp", 0x2c800000, 0x3ec00000, ldstpair_indexed, 0, OP3 (Ft, Ft2, ADDR_SIMM7), QL_LDST_PAIR_FP, 0),
>    CORE_INSN ("ldp", 0x2cc00000, 0x3ec00000, ldstpair_indexed, 0, OP3 (Ft, Ft2, ADDR_SIMM7), QL_LDST_PAIR_FP, 0),
> -  {"ldpsw", 0x68c00000, 0xfec00000, ldstpair_indexed, 0, CORE, OP3 (Rt, Rt2, ADDR_SIMM7), QL_LDST_PAIR_X32, 0, VERIFIER (ldpsw)},
> +  {"ldpsw", 0x68c00000, 0xfec00000, ldstpair_indexed, 0, CORE, OP3 (Rt, Rt2, ADDR_SIMM7), QL_LDST_PAIR_X32, 0, 0, VERIFIER (ldpsw)},
>    /* Load register (literal).  */
>    CORE_INSN ("ldr",   0x18000000, 0xbf000000, loadlit, OP_LDR_LIT,   OP2 (Rt, ADDR_PCREL19),    QL_R_PCREL, F_GPRSIZE_IN_Q),
>    CORE_INSN ("ldr",   0x1c000000, 0x3f000000, loadlit, OP_LDRV_LIT,  OP2 (Ft, ADDR_PCREL19),    QL_FP_PCREL, 0),
> @@ -2613,8 +2613,8 @@ struct aarch64_opcode aarch64_opcode_table[] =
>    CORE_INSN ("wfi", 0xd503207f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
>    CORE_INSN ("sev", 0xd503209f, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
>    CORE_INSN ("sevl",0xd50320bf, 0xffffffff, ic_system, 0, OP0 (), {}, F_ALIAS),
> -  {"esb", 0xd503221f, 0xffffffff, ic_system, 0, RAS, OP0 (), {}, F_ALIAS, NULL},
> -  {"psb", 0xd503223f, 0xffffffff, ic_system, 0, STAT_PROFILE, OP1 (BARRIER_PSB), {}, F_ALIAS, NULL},
> +  {"esb", 0xd503221f, 0xffffffff, ic_system, 0, RAS, OP0 (), {}, F_ALIAS, 0, NULL},
> +  {"psb", 0xd503223f, 0xffffffff, ic_system, 0, STAT_PROFILE, OP1 (BARRIER_PSB), {}, F_ALIAS, 0, NULL},
>    CORE_INSN ("clrex", 0xd503305f, 0xfffff0ff, ic_system, 0, OP1 (UIMM4), {}, F_OPD0_OPT | F_DEFAULT (0xF)),
>    CORE_INSN ("dsb", 0xd503309f, 0xfffff0ff, ic_system, 0, OP1 (BARRIER), {}, 0),
>    CORE_INSN ("dmb", 0xd50330bf, 0xfffff0ff, ic_system, 0, OP1 (BARRIER), {}, 0),
> @@ -2648,7 +2648,7 @@ struct aarch64_opcode aarch64_opcode_table[] =
>    CORE_INSN ("bgt", 0x5400000c, 0xff00001f, condbranch, 0, OP1 (ADDR_PCREL19), QL_PCREL_NIL, F_ALIAS | F_PSEUDO),
>    CORE_INSN ("ble", 0x5400000d, 0xff00001f, condbranch, 0, OP1 (ADDR_PCREL19), QL_PCREL_NIL, F_ALIAS | F_PSEUDO),
>  
> -  {0, 0, 0, 0, 0, 0, {}, {}, 0, NULL},
> +  {0, 0, 0, 0, 0, 0, {}, {}, 0, 0, NULL},
>  };
>  
>  #ifdef AARCH64_OPERANDS
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]