X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gas%2Fconfig%2Ftc-aarch64.c;h=b04605cb1aadce009d6454df3392936ee433f495;hb=250d07de5cf6efc81ed934c25292beb63c7e3129;hp=57a2b4e997ce235536b9ff9819b28b466e9ad669;hpb=c1229f84a41a6aba5b7df1f4261a9336347b068a;p=thirdparty%2Fbinutils-gdb.git diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 57a2b4e997c..b04605cb1aa 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -1,6 +1,6 @@ /* tc-aarch64.c -- Assemble for the AArch64 ISA - Copyright (C) 2009-2020 Free Software Foundation, Inc. + Copyright (C) 2009-2021 Free Software Foundation, Inc. Contributed by ARM Ltd. This file is part of GAS. @@ -247,12 +247,6 @@ set_fatal_syntax_error (const char *error) present. */ #define COND_ALWAYS 0x10 -typedef struct -{ - const char *template; - unsigned long value; -} asm_barrier_opt; - typedef struct { const char *template; @@ -3993,7 +3987,7 @@ static int parse_barrier (char **str) { char *p, *q; - const asm_barrier_opt *o; + const struct aarch64_name_value_pair *o; p = q = *str; while (ISALPHA (*q)) @@ -4042,6 +4036,29 @@ parse_barrier_psb (char **str, return 0; } +/* Parse an operand for CSR (CSRE instruction). */ + +static int +parse_csr_operand (char **str) +{ + char *p, *q; + + p = q = *str; + while (ISALPHA (*q)) + q++; + + /* Instruction has only one operand PDEC which encodes Rt field of the + operation to 0b11111. */ + if (strcasecmp(p, "pdec")) + { + set_syntax_error (_("CSR instruction accepts only PDEC")); + return PARSE_FAIL; + } + + *str = q; + return 0; +} + /* Parse an operand for BTI. Set *HINT_OPT to the hint-option record return 0 if successful. Otherwise return PARSE_FAIL. */ @@ -5259,6 +5276,7 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode, case AARCH64_OPND_Rm: case AARCH64_OPND_Rt: case AARCH64_OPND_Rt2: + case AARCH64_OPND_Rt_LS64: case AARCH64_OPND_Rt_SP: case AARCH64_OPND_Rs: case AARCH64_OPND_Ra: @@ -5628,10 +5646,26 @@ parse_operands (char *str, const aarch64_opcode *opcode) case AARCH64_OPND_Rt2: case AARCH64_OPND_Rs: case AARCH64_OPND_Ra: + case AARCH64_OPND_Rt_LS64: case AARCH64_OPND_Rt_SYS: case AARCH64_OPND_PAIRREG: case AARCH64_OPND_SVE_Rm: po_int_reg_or_fail (REG_TYPE_R_Z); + + /* In LS64 load/store instructions Rt register number must be even + and <=22. */ + if (operands[i] == AARCH64_OPND_Rt_LS64) + { + /* We've already checked if this is valid register. + This will check if register number (Rt) is not undefined for LS64 + instructions: + if Rt<4:3> == '11' || Rt<0> == '1' then UNDEFINED. */ + if ((info->reg.regno & 0x18) == 0x18 || (info->reg.regno & 0x01) == 0x01) + { + set_syntax_error (_("invalid Rt register number in 64-byte load/store")); + goto failure; + } + } break; case AARCH64_OPND_Rd_SP: @@ -6692,12 +6726,53 @@ parse_operands (char *str, const aarch64_opcode *opcode) backtrack_pos = 0; goto failure; } + if (val != PARSE_FAIL + && operands[i] == AARCH64_OPND_BARRIER) + { + /* Regular barriers accept options CRm (C0-C15). + DSB nXS barrier variant accepts values > 15. */ + if (val < 0 || val > 15) + { + set_syntax_error (_("the specified option is not accepted in DSB")); + goto failure; + } + } /* This is an extension to accept a 0..15 immediate. */ if (val == PARSE_FAIL) po_imm_or_fail (0, 15); info->barrier = aarch64_barrier_options + val; break; + case AARCH64_OPND_BARRIER_DSB_NXS: + val = parse_barrier (&str); + if (val != PARSE_FAIL) + { + /* DSB nXS barrier variant accept only