• 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

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

Log Message

[AArch64][SVE 22/32] Add qualifiers for merging and zeroing predication

This patch adds qualifiers to represent /z and /m suffixes on
predicate registers.

include/opcode/
* aarch64.h (AARCH64_OPND_QLF_P_Z): New aarch64_opnd_qualifier.
(AARCH64_OPND_QLF_P_M): Likewise.

opcodes/
* aarch64-opc.c (aarch64_opnd_qualifiers): Add entries for
AARCH64_OPND_QLF_P_[ZM].
(aarch64_print_operand): Print /z and /m where appropriate.

gas/
* config/tc-aarch64.c (vector_el_type): Add NT_zero and NT_merge.
(parse_vector_type_for_operand): Assert that the skipped character
is a '.'.
(parse_predication_for_operand): New function.
(parse_typed_reg): Parse /z and /m suffixes for predicate registers.
(vectype_to_qualifier): Handle NT_zero and NT_merge.

Change-Id: I0e1463f446feeb2051ee9e4c832bbb31318ff05d

Change Summary

差異

--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -83,7 +83,9 @@ enum vector_el_type
8383 NT_h,
8484 NT_s,
8585 NT_d,
86- NT_q
86+ NT_q,
87+ NT_zero,
88+ NT_merge
8789 };
8890
8991 /* Bits for DEFINED field in vector_type_el. */
@@ -780,6 +782,7 @@ parse_vector_type_for_operand (aarch64_reg_type reg_type,
780782 enum vector_el_type type;
781783
782784 /* skip '.' */
785+ gas_assert (*ptr == '.');
783786 ptr++;
784787
785788 if (reg_type == REG_TYPE_ZN || reg_type == REG_TYPE_PN || !ISDIGIT (*ptr))
@@ -846,6 +849,38 @@ elt_size:
846849 return TRUE;
847850 }
848851
852+/* *STR contains an SVE zero/merge predication suffix. Parse it into
853+ *PARSED_TYPE and point *STR at the end of the suffix. */
854+
855+static bfd_boolean
856+parse_predication_for_operand (struct vector_type_el *parsed_type, char **str)
857+{
858+ char *ptr = *str;
859+
860+ /* Skip '/'. */
861+ gas_assert (*ptr == '/');
862+ ptr++;
863+ switch (TOLOWER (*ptr))
864+ {
865+ case 'z':
866+ parsed_type->type = NT_zero;
867+ break;
868+ case 'm':
869+ parsed_type->type = NT_merge;
870+ break;
871+ default:
872+ if (*ptr != '\0' && *ptr != ',')
873+ first_error_fmt (_("unexpected character `%c' in predication type"),
874+ *ptr);
875+ else
876+ first_error (_("missing predication type"));
877+ return FALSE;
878+ }
879+ parsed_type->width = 0;
880+ *str = ptr + 1;
881+ return TRUE;
882+}
883+
849884 /* Parse a register of the type TYPE.
850885
851886 Return PARSE_FAIL if the string pointed by *CCP is not a valid register
@@ -890,10 +925,18 @@ parse_typed_reg (char **ccp, aarch64_reg_type type, aarch64_reg_type *rtype,
890925 type = reg->type;
891926
892927 if ((type == REG_TYPE_VN || type == REG_TYPE_ZN || type == REG_TYPE_PN)
893- && *str == '.')
928+ && (*str == '.' || (type == REG_TYPE_PN && *str == '/')))
894929 {
895- if (!parse_vector_type_for_operand (type, &parsetype, &str))
896- return PARSE_FAIL;
930+ if (*str == '.')
931+ {
932+ if (!parse_vector_type_for_operand (type, &parsetype, &str))
933+ return PARSE_FAIL;
934+ }
935+ else
936+ {
937+ if (!parse_predication_for_operand (&parsetype, &str))
938+ return PARSE_FAIL;
939+ }
897940
898941 /* Register if of the form Vn.[bhsdq]. */
899942 is_typed_vecreg = TRUE;
@@ -4706,6 +4749,11 @@ vectype_to_qualifier (const struct vector_type_el *vectype)
47064749 if (!vectype->defined || vectype->type == NT_invtype)
47074750 goto vectype_conversion_fail;
47084751
4752+ if (vectype->type == NT_zero)
4753+ return AARCH64_OPND_QLF_P_Z;
4754+ if (vectype->type == NT_merge)
4755+ return AARCH64_OPND_QLF_P_M;
4756+
47094757 gas_assert (vectype->type >= NT_b && vectype->type <= NT_q);
47104758
47114759 if (vectype->defined & (NTA_HASINDEX | NTA_HASVARWIDTH))
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -315,6 +315,9 @@ enum aarch64_opnd_qualifier
315315 AARCH64_OPND_QLF_V_2D,
316316 AARCH64_OPND_QLF_V_1Q,
317317
318+ AARCH64_OPND_QLF_P_Z,
319+ AARCH64_OPND_QLF_P_M,
320+
318321 /* Constraint on value. */
319322 AARCH64_OPND_QLF_imm_0_7,
320323 AARCH64_OPND_QLF_imm_0_15,
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -603,6 +603,9 @@ struct operand_qualifier_data aarch64_opnd_qualifiers[] =
603603 {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
604604 {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
605605
606+ {0, 0, 0, "z", OQK_OPD_VARIANT},
607+ {0, 0, 0, "m", OQK_OPD_VARIANT},
608+
606609 /* Qualifiers constraining the value range.
607610 First 3 fields:
608611 Lower bound, higher bound, unused. */
@@ -2623,6 +2626,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
26232626 case AARCH64_OPND_SVE_Pt:
26242627 if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
26252628 snprintf (buf, size, "p%d", opnd->reg.regno);
2629+ else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
2630+ || opnd->qualifier == AARCH64_OPND_QLF_P_M)
2631+ snprintf (buf, size, "p%d/%s", opnd->reg.regno,
2632+ aarch64_get_qualifier_name (opnd->qualifier));
26262633 else
26272634 snprintf (buf, size, "p%d.%s", opnd->reg.regno,
26282635 aarch64_get_qualifier_name (opnd->qualifier));