diff options
author | Przemyslaw Wirkus <przemyslaw.wirkus@arm.com> | 2020-11-09 11:09:12 +0000 |
---|---|---|
committer | Przemyslaw Wirkus <przemyslaw.wirkus@arm.com> | 2020-11-09 11:19:44 +0000 |
commit | 8edca81ece5df534c1cdd1f8362e7b5b9b090cfa (patch) | |
tree | 7e07cdc4b08f84ca60406cc67afd31eaa71c8bf3 /opcodes/aarch64-tbl.h | |
parent | a76bf0e55d84e8529a337cad278814ba2e30d3af (diff) | |
download | binutils-gdb-8edca81ece5df534c1cdd1f8362e7b5b9b090cfa.tar.gz |
aarch64: Limit Rt register number for LS64 load/store instructions
Atomic 64-byte load/store instructions limit Rt register number to
values matching below condition (register <Xt> number must be even
and <= 22):
if Rt<4:3> == '11' || Rt<0> == '1' then UNDEFINED;
This patch adds check if Rt fulfills above requirement.
For more details regarding atomic 64-byte load/store instruction for
Armv8.7 please refer to Arm A64 Instruction set documentation for
Armv8-A architecture profile, see document page 157 for load
instruction, and pages 414-418 for store instructions of [0].
[0]: https://developer.arm.com/docs/ddi0596/i
Diffstat (limited to 'opcodes/aarch64-tbl.h')
-rw-r--r-- | opcodes/aarch64-tbl.h | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h index f86dde55644..a54b9683919 100644 --- a/opcodes/aarch64-tbl.h +++ b/opcodes/aarch64-tbl.h @@ -3646,10 +3646,10 @@ struct aarch64_opcode aarch64_opcode_table[] = CORE_INSN ("ldrsw", 0x98000000, 0xff000000, loadlit, OP_LDRSW_LIT, OP2 (Rt, ADDR_PCREL19), QL_X_PCREL, 0), CORE_INSN ("prfm", 0xd8000000, 0xff000000, loadlit, OP_PRFM_LIT, OP2 (PRFOP, ADDR_PCREL19), QL_PRFM_PCREL, 0), /* Atomic 64-byte load/store in Armv8.7. */ - _LS64_INSN ("ld64b", 0xf83fd000, 0xfffffc00, ldstexcl, OP2 (Rt, ADDR_SIMPLE), QL_X1NIL, 0), - _LS64_INSN ("st64b", 0xf83f9000, 0xfffffc00, ldstexcl, OP2 (Rt, ADDR_SIMPLE), QL_X1NIL, 0), - _LS64_INSN ("st64bv", 0xf820b000, 0xffe0fc00, ldstexcl, OP3 (Rs, Rt, ADDR_SIMPLE), QL_X2NIL, 0), - _LS64_INSN ("st64bv0", 0xf820a000, 0xffe0fc00, ldstexcl, OP3 (Rs, Rt, ADDR_SIMPLE), QL_X2NIL, 0), + _LS64_INSN ("ld64b", 0xf83fd000, 0xfffffc00, ldstexcl, OP2 (Rt_LS64, ADDR_SIMPLE), QL_X1NIL, 0), + _LS64_INSN ("st64b", 0xf83f9000, 0xfffffc00, ldstexcl, OP2 (Rt_LS64, ADDR_SIMPLE), QL_X1NIL, 0), + _LS64_INSN ("st64bv", 0xf820b000, 0xffe0fc00, ldstexcl, OP3 (Rs, Rt_LS64, ADDR_SIMPLE), QL_X2NIL, 0), + _LS64_INSN ("st64bv0", 0xf820a000, 0xffe0fc00, ldstexcl, OP3 (Rs, Rt_LS64, ADDR_SIMPLE), QL_X2NIL, 0), /* Logical (immediate). */ CORE_INSN ("and", 0x12000000, 0x7f800000, log_imm, 0, OP3 (Rd_SP, Rn, LIMM), QL_R2NIL, F_HAS_ALIAS | F_SF), CORE_INSN ("bic", 0x12000000, 0x7f800000, log_imm, OP_BIC, OP3 (Rd_SP, Rn, LIMM), QL_R2NIL, F_ALIAS | F_PSEUDO | F_SF), @@ -5181,6 +5181,7 @@ struct aarch64_opcode aarch64_opcode_table[] = Y(INT_REG, regno, "Rm", 0, F(FLD_Rm), "an integer register") \ Y(INT_REG, regno, "Rt", 0, F(FLD_Rt), "an integer register") \ Y(INT_REG, regno, "Rt2", 0, F(FLD_Rt2), "an integer register") \ + Y(INT_REG, regno, "Rt_LS64", 0, F(FLD_Rt), "an integer register") \ Y(INT_REG, regno, "Rt_SP", OPD_F_MAYBE_SP, F(FLD_Rt), \ "an integer or stack pointer register") \ Y(INT_REG, regno, "Rs", 0, F(FLD_Rs), "an integer register") \ |