diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2016-09-21 16:51:43 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2016-09-21 16:51:43 +0100 |
commit | 01dbfe4c0e2b832c6b1076e8d373b162e2faa376 (patch) | |
tree | 2e7c402a08b6ba05bef7fb03c6c3be5ce33a3101 | |
parent | 72e9f31937f063ed6f5991a2b8c00068fa2dc8fc (diff) | |
download | fsf-binutils-gdb-01dbfe4c0e2b832c6b1076e8d373b162e2faa376.zip fsf-binutils-gdb-01dbfe4c0e2b832c6b1076e8d373b162e2faa376.tar.gz fsf-binutils-gdb-01dbfe4c0e2b832c6b1076e8d373b162e2faa376.tar.bz2 |
[AArch64][SVE 19/32] Refactor address-printing code
SVE adds addresses in which the base or offset are vector registers.
The addresses otherwise have the same kind of form as normal AArch64
addresses, including things like SXTW with or without a shift, UXTW
with or without a shift, and LSL.
This patch therefore refactors the address-printing code so that it
can cope with both scalar and vector registers.
opcodes/
* aarch64-opc.c (get_offset_int_reg_name): New function.
(print_immediate_offset_address): Likewise.
(print_register_offset_address): Take the base and offset
registers as parameters.
(aarch64_print_operand): Update caller accordingly. Use
print_immediate_offset_address.
-rw-r--r-- | opcodes/ChangeLog | 9 | ||||
-rw-r--r-- | opcodes/aarch64-opc.c | 92 |
2 files changed, 65 insertions, 36 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 8255182..eab6811 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,14 @@ 2016-09-21 Richard Sandiford <richard.sandiford@arm.com> + * aarch64-opc.c (get_offset_int_reg_name): New function. + (print_immediate_offset_address): Likewise. + (print_register_offset_address): Take the base and offset + registers as parameters. + (aarch64_print_operand): Update caller accordingly. Use + print_immediate_offset_address. + +2016-09-21 Richard Sandiford <richard.sandiford@arm.com> + * aarch64-opc.c (BANK): New macro. (R32, R64): Take a register number as argument (int_reg): Use BANK. diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index 3f9be62..7a73c7e 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -2189,6 +2189,27 @@ get_64bit_int_reg_name (int regno, int sp_reg_p) return int_reg[has_zr][1][regno]; } +/* Get the name of the integer offset register in OPND, using the shift type + to decide whether it's a word or doubleword. */ + +static inline const char * +get_offset_int_reg_name (const aarch64_opnd_info *opnd) +{ + switch (opnd->shifter.kind) + { + case AARCH64_MOD_UXTW: + case AARCH64_MOD_SXTW: + return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0); + + case AARCH64_MOD_LSL: + case AARCH64_MOD_SXTX: + return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0); + + default: + abort (); + } +} + /* Types for expanding an encoded 8-bit value to a floating-point value. */ typedef union @@ -2311,28 +2332,43 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd, } } +/* Print the register+immediate address in OPND to BUF, which has SIZE + characters. BASE is the name of the base register. */ + +static void +print_immediate_offset_address (char *buf, size_t size, + const aarch64_opnd_info *opnd, + const char *base) +{ + if (opnd->addr.writeback) + { + if (opnd->addr.preind) + snprintf (buf, size, "[%s,#%d]!", base, opnd->addr.offset.imm); + else + snprintf (buf, size, "[%s],#%d", base, opnd->addr.offset.imm); + } + else + { + if (opnd->addr.offset.imm) + snprintf (buf, size, "[%s,#%d]", base, opnd->addr.offset.imm); + else + snprintf (buf, size, "[%s]", base); + } +} + /* Produce the string representation of the register offset address operand - *OPND in the buffer pointed by BUF of size SIZE. */ + *OPND in the buffer pointed by BUF of size SIZE. BASE and OFFSET are + the names of the base and offset registers. */ static void print_register_offset_address (char *buf, size_t size, - const aarch64_opnd_info *opnd) + const aarch64_opnd_info *opnd, + const char *base, const char *offset) { char tb[16]; /* Temporary buffer. */ - bfd_boolean lsl_p = FALSE; /* Is LSL shift operator? */ - bfd_boolean wm_p = FALSE; /* Should Rm be Wm? */ bfd_boolean print_extend_p = TRUE; bfd_boolean print_amount_p = TRUE; const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name; - switch (opnd->shifter.kind) - { - case AARCH64_MOD_UXTW: wm_p = TRUE; break; - case AARCH64_MOD_LSL : lsl_p = TRUE; break; - case AARCH64_MOD_SXTW: wm_p = TRUE; break; - case AARCH64_MOD_SXTX: break; - default: assert (0); - } - if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B || !opnd->shifter.amount_present)) { @@ -2341,7 +2377,7 @@ print_register_offset_address (char *buf, size_t size, print_amount_p = FALSE; /* Likewise, no need to print the shift operator LSL in such a situation. */ - if (lsl_p) + if (opnd->shifter.kind == AARCH64_MOD_LSL) print_extend_p = FALSE; } @@ -2356,12 +2392,7 @@ print_register_offset_address (char *buf, size_t size, else tb[0] = '\0'; - snprintf (buf, size, "[%s,%s%s]", - get_64bit_int_reg_name (opnd->addr.base_regno, 1), - get_int_reg_name (opnd->addr.offset.regno, - wm_p ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X, - 0 /* sp_reg_p */), - tb); + snprintf (buf, size, "[%s,%s%s]", base, offset, tb); } /* Generate the string representation of the operand OPNDS[IDX] for OPCODE @@ -2668,27 +2699,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, break; case AARCH64_OPND_ADDR_REGOFF: - print_register_offset_address (buf, size, opnd); + print_register_offset_address + (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1), + get_offset_int_reg_name (opnd)); break; case AARCH64_OPND_ADDR_SIMM7: case AARCH64_OPND_ADDR_SIMM9: case AARCH64_OPND_ADDR_SIMM9_2: - name = get_64bit_int_reg_name (opnd->addr.base_regno, 1); - if (opnd->addr.writeback) - { - if (opnd->addr.preind) - snprintf (buf, size, "[%s,#%d]!", name, opnd->addr.offset.imm); - else - snprintf (buf, size, "[%s],#%d", name, opnd->addr.offset.imm); - } - else - { - if (opnd->addr.offset.imm) - snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm); - else - snprintf (buf, size, "[%s]", name); - } + print_immediate_offset_address + (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1)); break; case AARCH64_OPND_ADDR_UIMM12: |