diff options
author | Yury Khrustalev <yury.khrustalev@arm.com> | 2024-02-21 12:52:23 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2024-03-18 16:54:06 +0000 |
commit | 4792a423d264cfb6dbb656ea97b1c84d1b4e55b6 (patch) | |
tree | b9ed74a4a37b8e8881e533325a9fa8777949532c /gas/config | |
parent | ee0fa6627079ebd16843d9d3fb4e24a5af545ded (diff) | |
download | binutils-4792a423d264cfb6dbb656ea97b1c84d1b4e55b6.zip binutils-4792a423d264cfb6dbb656ea97b1c84d1b4e55b6.tar.gz binutils-4792a423d264cfb6dbb656ea97b1c84d1b4e55b6.tar.bz2 |
aarch64: Add support for (M)ADDPT and (M)SUBPT instructions
The following instructions are added in this patch:
- ADDPT and SUBPT - Add/Subtract checked pointer
- MADDPT and MSUBPT - Multiply Add/Subtract checked pointer
These instructions are part of Checked Pointer Arithmetic extension.
This patch adds assembler and disassembler support for these instructions
with relevant checks. Tests are included as well.
A new flag "+cpa" added to documentation. This flag enables CPA extension.
Regression tested on the aarch64-none-linux-gnu target and no regressions
have been found.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-aarch64.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 4380de3..d6dab86 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -3748,6 +3748,41 @@ parse_shifter_operand (char **str, aarch64_opnd_info *operand, return parse_shifter_operand_imm (str, operand, mode); } +static bool +parse_reg_lsl_shifter_operand (char **str, aarch64_opnd_info *operand) +{ + aarch64_opnd_qualifier_t qualifier; + const reg_entry *reg = aarch64_reg_parse_32_64 (str, &qualifier); + + if (reg) + { + if (!aarch64_check_reg_type (reg, REG_TYPE_R_ZR)) + { + set_expected_reg_error (REG_TYPE_R_ZR, reg, 0); + return false; + } + + operand->reg.regno = reg->number; + operand->qualifier = qualifier; + + /* Accept optional LSL shift operation on register. */ + if (!skip_past_comma (str)) + return true; + + if (!parse_shift (str, operand, SHIFTED_LSL)) + return false; + + return true; + } + else + { + set_syntax_error + (_("integer register expected in the shifted operand " + "register")); + return false; + } +} + /* Return TRUE on success; return FALSE otherwise. */ static bool @@ -6593,6 +6628,17 @@ parse_operands (char *str, const aarch64_opcode *opcode) } break; + case AARCH64_OPND_Rm_LSL: + po_misc_or_fail (parse_reg_lsl_shifter_operand (&str, info)); + if (!info->shifter.operator_present) + { + /* Default to LSL #0 if not present. */ + gas_assert (info->shifter.kind == AARCH64_MOD_NONE); + info->shifter.kind = AARCH64_MOD_LSL; + info->shifter.amount = 0; + } + break; + case AARCH64_OPND_Fd: case AARCH64_OPND_Fn: case AARCH64_OPND_Fm: @@ -10429,6 +10475,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = { {"sme2p1", AARCH64_FEATURE (SME2p1), AARCH64_FEATURE (SME2)}, {"sve2p1", AARCH64_FEATURE (SVE2p1), AARCH64_FEATURE (SVE2)}, {"rcpc3", AARCH64_FEATURE (RCPC3), AARCH64_FEATURE (RCPC2)}, + {"cpa", AARCH64_FEATURE (CPA), AARCH64_NO_FEATURES}, {NULL, AARCH64_NO_FEATURES, AARCH64_NO_FEATURES}, }; |