• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

修訂136982a0a15e6c33d915cd9d48e6928bf8dab45b (tree)
時間2016-08-23 17:41:03
作者Richard Sandiford <richard.sandiford@arm....>
CommiterRichard Sandiford

Log Message

[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.

Change-Id: Ib975218f68fd866a50184d82ed3ea9bc792bbf02

Change Summary

差異

--- 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)
21892189 return int_reg[has_zr][1][regno];
21902190 }
21912191
2192+/* Get the name of the integer offset register in OPND, using the shift type
2193+ to decide whether it's a word or doubleword. */
2194+
2195+static inline const char *
2196+get_offset_int_reg_name (const aarch64_opnd_info *opnd)
2197+{
2198+ switch (opnd->shifter.kind)
2199+ {
2200+ case AARCH64_MOD_UXTW:
2201+ case AARCH64_MOD_SXTW:
2202+ return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
2203+
2204+ case AARCH64_MOD_LSL:
2205+ case AARCH64_MOD_SXTX:
2206+ return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
2207+
2208+ default:
2209+ abort ();
2210+ }
2211+}
2212+
21922213 /* Types for expanding an encoded 8-bit value to a floating-point value. */
21932214
21942215 typedef union
@@ -2311,28 +2332,43 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
23112332 }
23122333 }
23132334
2335+/* Print the register+immediate address in OPND to BUF, which has SIZE
2336+ characters. BASE is the name of the base register. */
2337+
2338+static void
2339+print_immediate_offset_address (char *buf, size_t size,
2340+ const aarch64_opnd_info *opnd,
2341+ const char *base)
2342+{
2343+ if (opnd->addr.writeback)
2344+ {
2345+ if (opnd->addr.preind)
2346+ snprintf (buf, size, "[%s,#%d]!", base, opnd->addr.offset.imm);
2347+ else
2348+ snprintf (buf, size, "[%s],#%d", base, opnd->addr.offset.imm);
2349+ }
2350+ else
2351+ {
2352+ if (opnd->addr.offset.imm)
2353+ snprintf (buf, size, "[%s,#%d]", base, opnd->addr.offset.imm);
2354+ else
2355+ snprintf (buf, size, "[%s]", base);
2356+ }
2357+}
2358+
23142359 /* Produce the string representation of the register offset address operand
2315- *OPND in the buffer pointed by BUF of size SIZE. */
2360+ *OPND in the buffer pointed by BUF of size SIZE. BASE and OFFSET are
2361+ the names of the base and offset registers. */
23162362 static void
23172363 print_register_offset_address (char *buf, size_t size,
2318- const aarch64_opnd_info *opnd)
2364+ const aarch64_opnd_info *opnd,
2365+ const char *base, const char *offset)
23192366 {
23202367 char tb[16]; /* Temporary buffer. */
2321- bfd_boolean lsl_p = FALSE; /* Is LSL shift operator? */
2322- bfd_boolean wm_p = FALSE; /* Should Rm be Wm? */
23232368 bfd_boolean print_extend_p = TRUE;
23242369 bfd_boolean print_amount_p = TRUE;
23252370 const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
23262371
2327- switch (opnd->shifter.kind)
2328- {
2329- case AARCH64_MOD_UXTW: wm_p = TRUE; break;
2330- case AARCH64_MOD_LSL : lsl_p = TRUE; break;
2331- case AARCH64_MOD_SXTW: wm_p = TRUE; break;
2332- case AARCH64_MOD_SXTX: break;
2333- default: assert (0);
2334- }
2335-
23362372 if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
23372373 || !opnd->shifter.amount_present))
23382374 {
@@ -2341,7 +2377,7 @@ print_register_offset_address (char *buf, size_t size,
23412377 print_amount_p = FALSE;
23422378 /* Likewise, no need to print the shift operator LSL in such a
23432379 situation. */
2344- if (lsl_p)
2380+ if (opnd->shifter.kind == AARCH64_MOD_LSL)
23452381 print_extend_p = FALSE;
23462382 }
23472383
@@ -2356,12 +2392,7 @@ print_register_offset_address (char *buf, size_t size,
23562392 else
23572393 tb[0] = '\0';
23582394
2359- snprintf (buf, size, "[%s,%s%s]",
2360- get_64bit_int_reg_name (opnd->addr.base_regno, 1),
2361- get_int_reg_name (opnd->addr.offset.regno,
2362- wm_p ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X,
2363- 0 /* sp_reg_p */),
2364- tb);
2395+ snprintf (buf, size, "[%s,%s%s]", base, offset, tb);
23652396 }
23662397
23672398 /* 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,
26682699 break;
26692700
26702701 case AARCH64_OPND_ADDR_REGOFF:
2671- print_register_offset_address (buf, size, opnd);
2702+ print_register_offset_address
2703+ (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
2704+ get_offset_int_reg_name (opnd));
26722705 break;
26732706
26742707 case AARCH64_OPND_ADDR_SIMM7:
26752708 case AARCH64_OPND_ADDR_SIMM9:
26762709 case AARCH64_OPND_ADDR_SIMM9_2:
2677- name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2678- if (opnd->addr.writeback)
2679- {
2680- if (opnd->addr.preind)
2681- snprintf (buf, size, "[%s,#%d]!", name, opnd->addr.offset.imm);
2682- else
2683- snprintf (buf, size, "[%s],#%d", name, opnd->addr.offset.imm);
2684- }
2685- else
2686- {
2687- if (opnd->addr.offset.imm)
2688- snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
2689- else
2690- snprintf (buf, size, "[%s]", name);
2691- }
2710+ print_immediate_offset_address
2711+ (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1));
26922712 break;
26932713
26942714 case AARCH64_OPND_ADDR_UIMM12: