This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[AArch64][PATCH 1/2] Add ARMv8.2 instructions BFC and REV64.
- From: Matthew Wahab <matthew dot wahab at foss dot arm dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Tue, 24 Nov 2015 11:17:38 +0000
- Subject: [AArch64][PATCH 1/2] Add ARMv8.2 instructions BFC and REV64.
- Authentication-results: sourceware.org; auth=none
Hello,
ARMv8.2 adds two new instructions: BFC as an alias for BFM and REV64 as
an alias for REV. This patch set adds support for these to binutils,
enabled when the -march=armv8.2-a is given. It depends on the support
for an instruction being its preferred form which was added in
https://sourceware.org/ml/binutils/2015-11/msg00220.html.
This patch adds the alias BFC <Rd>, #<imm>, #<width> as the preferred
form for BFM when the source is a zero register and the conditions for
using the BFI form are met (in other words, BFC is the preferred form
for BFI <Rd>, <Rs>, #<imm>, #<width> when the <Rs> is a zero register).
Tested the series for aarch64-none-linux-gnu with cross-compiled
check-binutils and check-gas.
Ok for trunk?
Matthew
gas/testsuite/
2015-11-24 Matthew Wahab <matthew.wahab@arm.com>
* gas/aarch64/alias-2.d: New.
* gas/aarch64/alias-2.s: New.
include/opcode/
2015-11-24 Matthew Wahab <matthew.wahab@arm.com>
* aarch64.h (aarch64_op): Add OP_BFC.
opcodes/
2015-11-24 Matthew Wahab <matthew.wahab@arm.com>
* aarch64-asm-2.c: Regenerate.
* aarch64-asm.c (convert_bfc_to_bfm): New.
(convert_to_real): Add case for OP_BFC.
* aarch64-dis-2.c: Regenerate.
* aarch64-dis.c: (convert_bfm_to_bfc): New.
(convert_to_alias): Add case for OP_BFC.
* aarch64-opc-2.c: Regenerate.
* aarch64-opc.c (operand_general_constraint_met_p): Weaken assert
to allow width operand in three-operand instructions.
* aarch64-tbl.h (QL_BF1): New.
(aarch64_feature_v8_2): New.
(ARMV8_2): New.
(aarch64_opcode_table): Add "bfc".
>From d3ea06d6caf3e2ec6b1b0f89cff479dfdce1051c Mon Sep 17 00:00:00 2001
From: Matthew Wahab <matthew.wahab@arm.com>
Date: Wed, 16 Sep 2015 10:50:24 +0100
Subject: [PATCH 1/2] [AArch64] Add ARMv8.2 instructions BFC and REV64.
---
gas/testsuite/gas/aarch64/alias-2.d | 98 ++++
gas/testsuite/gas/aarch64/alias-2.s | 31 +
include/opcode/aarch64.h | 1 +
opcodes/aarch64-asm-2.c | 571 +++++++++---------
opcodes/aarch64-asm.c | 34 ++
opcodes/aarch64-dis-2.c | 1097 ++++++++++++++++++-----------------
opcodes/aarch64-dis.c | 41 ++
opcodes/aarch64-opc-2.c | 55 +-
opcodes/aarch64-opc.c | 2 +-
opcodes/aarch64-tbl.h | 12 +
10 files changed, 1081 insertions(+), 861 deletions(-)
create mode 100644 gas/testsuite/gas/aarch64/alias-2.d
create mode 100644 gas/testsuite/gas/aarch64/alias-2.s
diff --git a/gas/testsuite/gas/aarch64/alias-2.d b/gas/testsuite/gas/aarch64/alias-2.d
new file mode 100644
index 0000000..92ed58f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/alias-2.d
@@ -0,0 +1,98 @@
+#objdump: -dr
+#as: -march=armv8.2-a
+
+.*: file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+ [0-9a-f]+: b34107e0 bfxil x0, xzr, #1, #1
+ [0-9a-f]+: b3410420 bfxil x0, x1, #1, #1
+ [0-9a-f]+: b341043f bfxil xzr, x1, #1, #1
+ [0-9a-f]+: b34107ff bfxil xzr, xzr, #1, #1
+ [0-9a-f]+: b34123e0 bfxil x0, xzr, #1, #8
+ [0-9a-f]+: b3412020 bfxil x0, x1, #1, #8
+ [0-9a-f]+: b341203f bfxil xzr, x1, #1, #8
+ [0-9a-f]+: b34123ff bfxil xzr, xzr, #1, #8
+ [0-9a-f]+: b3413fe0 bfxil x0, xzr, #1, #15
+ [0-9a-f]+: b3413c20 bfxil x0, x1, #1, #15
+ [0-9a-f]+: b3413c3f bfxil xzr, x1, #1, #15
+ [0-9a-f]+: b3413fff bfxil xzr, xzr, #1, #15
+ [0-9a-f]+: b35007e0 bfc x0, #48, #2
+ [0-9a-f]+: b3500420 bfi x0, x1, #48, #2
+ [0-9a-f]+: b350043f bfi xzr, x1, #48, #2
+ [0-9a-f]+: b35007ff bfc xzr, #48, #2
+ [0-9a-f]+: b35023e0 bfc x0, #48, #9
+ [0-9a-f]+: b3502020 bfi x0, x1, #48, #9
+ [0-9a-f]+: b350203f bfi xzr, x1, #48, #9
+ [0-9a-f]+: b35023ff bfc xzr, #48, #9
+ [0-9a-f]+: b3503fe0 bfc x0, #48, #16
+ [0-9a-f]+: b3503c20 bfi x0, x1, #48, #16
+ [0-9a-f]+: b3503c3f bfi xzr, x1, #48, #16
+ [0-9a-f]+: b3503fff bfc xzr, #48, #16
+ [0-9a-f]+: b35f07e0 bfc x0, #33, #2
+ [0-9a-f]+: b35f0420 bfi x0, x1, #33, #2
+ [0-9a-f]+: b35f043f bfi xzr, x1, #33, #2
+ [0-9a-f]+: b35f07ff bfc xzr, #33, #2
+ [0-9a-f]+: b35f23e0 bfc x0, #33, #9
+ [0-9a-f]+: b35f2020 bfi x0, x1, #33, #9
+ [0-9a-f]+: b35f203f bfi xzr, x1, #33, #9
+ [0-9a-f]+: b35f23ff bfc xzr, #33, #9
+ [0-9a-f]+: b35f3fe0 bfc x0, #33, #16
+ [0-9a-f]+: b35f3c20 bfi x0, x1, #33, #16
+ [0-9a-f]+: b35f3c3f bfi xzr, x1, #33, #16
+ [0-9a-f]+: b35f3fff bfc xzr, #33, #16
+ [0-9a-f]+: b37f03e0 bfc x0, #1, #1
+ [0-9a-f]+: b37f0020 bfi x0, x1, #1, #1
+ [0-9a-f]+: b37f003f bfi xzr, x1, #1, #1
+ [0-9a-f]+: b37f03ff bfc xzr, #1, #1
+ [0-9a-f]+: b37f1fe0 bfc x0, #1, #8
+ [0-9a-f]+: b37f1c20 bfi x0, x1, #1, #8
+ [0-9a-f]+: b37f1c3f bfi xzr, x1, #1, #8
+ [0-9a-f]+: b37f1fff bfc xzr, #1, #8
+ [0-9a-f]+: b37f3be0 bfc x0, #1, #15
+ [0-9a-f]+: b37f3820 bfi x0, x1, #1, #15
+ [0-9a-f]+: b37f383f bfi xzr, x1, #1, #15
+ [0-9a-f]+: b37f3bff bfc xzr, #1, #15
+ [0-9a-f]+: b37003e0 bfc x0, #16, #1
+ [0-9a-f]+: b3700020 bfi x0, x1, #16, #1
+ [0-9a-f]+: b370003f bfi xzr, x1, #16, #1
+ [0-9a-f]+: b37003ff bfc xzr, #16, #1
+ [0-9a-f]+: b3701fe0 bfc x0, #16, #8
+ [0-9a-f]+: b3701c20 bfi x0, x1, #16, #8
+ [0-9a-f]+: b3701c3f bfi xzr, x1, #16, #8
+ [0-9a-f]+: b3701fff bfc xzr, #16, #8
+ [0-9a-f]+: b3703be0 bfc x0, #16, #15
+ [0-9a-f]+: b3703820 bfi x0, x1, #16, #15
+ [0-9a-f]+: b370383f bfi xzr, x1, #16, #15
+ [0-9a-f]+: b3703bff bfc xzr, #16, #15
+ [0-9a-f]+: b36103e0 bfc x0, #31, #1
+ [0-9a-f]+: b3610020 bfi x0, x1, #31, #1
+ [0-9a-f]+: b361003f bfi xzr, x1, #31, #1
+ [0-9a-f]+: b36103ff bfc xzr, #31, #1
+ [0-9a-f]+: b3611fe0 bfc x0, #31, #8
+ [0-9a-f]+: b3611c20 bfi x0, x1, #31, #8
+ [0-9a-f]+: b3611c3f bfi xzr, x1, #31, #8
+ [0-9a-f]+: b3611fff bfc xzr, #31, #8
+ [0-9a-f]+: b3613be0 bfc x0, #31, #15
+ [0-9a-f]+: b3613820 bfi x0, x1, #31, #15
+ [0-9a-f]+: b361383f bfi xzr, x1, #31, #15
+ [0-9a-f]+: b3613bff bfc xzr, #31, #15
+ [0-9a-f]+: b34003e0 bfxil x0, xzr, #0, #1
+ [0-9a-f]+: b36103ff bfc xzr, #31, #1
+ [0-9a-f]+: b3401fe0 bfxil x0, xzr, #0, #8
+ [0-9a-f]+: b3611fff bfc xzr, #31, #8
+ [0-9a-f]+: b3403be0 bfxil x0, xzr, #0, #15
+ [0-9a-f]+: b3613bff bfc xzr, #31, #15
+ [0-9a-f]+: b34003e0 bfxil x0, xzr, #0, #1
+ [0-9a-f]+: b36103ff bfc xzr, #31, #1
+ [0-9a-f]+: b3401fe0 bfxil x0, xzr, #0, #8
+ [0-9a-f]+: b3611fff bfc xzr, #31, #8
+ [0-9a-f]+: b3403be0 bfxil x0, xzr, #0, #15
+ [0-9a-f]+: b3613bff bfc xzr, #31, #15
+ [0-9a-f]+: b34003e0 bfxil x0, xzr, #0, #1
+ [0-9a-f]+: b36103ff bfc xzr, #31, #1
+ [0-9a-f]+: b3401fe0 bfxil x0, xzr, #0, #8
+ [0-9a-f]+: b3611fff bfc xzr, #31, #8
+ [0-9a-f]+: b3403be0 bfxil x0, xzr, #0, #15
+ [0-9a-f]+: b3613bff bfc xzr, #31, #15
diff --git a/gas/testsuite/gas/aarch64/alias-2.s b/gas/testsuite/gas/aarch64/alias-2.s
new file mode 100644
index 0000000..d952c97
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/alias-2.s
@@ -0,0 +1,31 @@
+/* alias-2.s Test file for ARMv8.2 AArch64 instructions aliases or disassembly
+ preference. */
+
+ /* <bfm> [Xd|xzr], [xzr|<Xr>], <imm>, <width> */
+ .macro bfm_inst op imm width
+ \op x0, xzr, #\imm, #\width
+ \op x0, x1, #\imm, #\width
+ \op xzr, x1, #\imm, #\width
+ \op xzr, xzr, #\imm, #\width
+ .endm
+
+ /* bfc [Xd|xzr], <imm>, <width> */
+ .macro bfc_inst imm width
+ bfc x0, #\imm, #\width
+ bfc xzr, #\imm, #\width
+ .endm
+
+.text
+ .irp op, bfm, bfi
+ .irp imm, 1, 16, 31
+ .irp width, 1, 8, 15
+ bfm_inst \op, \imm, \width
+ .endr
+ .endr
+ .endr
+
+ .irp imm, 1, 16, 31
+ .irp width, 1, 8, 15
+ bfc_inst \imm, \width
+ .endr
+ .endr
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 9addf40..996ed85 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -436,6 +436,7 @@ enum aarch64_op
OP_SBFX,
OP_SBFIZ,
OP_BFI,
+ OP_BFC, /* ARMv8.2. */
OP_UBFIZ,
OP_UXTB,
OP_UXTH,
diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c
index 8989fa8..83f8a8e 100644
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 9689440..ef64501 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -1039,6 +1039,37 @@ convert_bfi_to_bfm (aarch64_inst *inst)
}
/* The instruction written:
+ BFC <Xd>, #<lsb>, #<width>
+ is equivalent to:
+ BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
+
+static void
+convert_bfc_to_bfm (aarch64_inst *inst)
+{
+ int64_t lsb, width;
+
+ /* Insert XZR. */
+ copy_operand_info (inst, 3, 2);
+ copy_operand_info (inst, 2, 1);
+ copy_operand_info (inst, 2, 0);
+ inst->operands[1].reg.regno = 0x1f;
+
+ /* Convert the immedate operand. */
+ lsb = inst->operands[2].imm.value;
+ width = inst->operands[3].imm.value;
+ if (inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31)
+ {
+ inst->operands[2].imm.value = (32 - lsb) & 0x1f;
+ inst->operands[3].imm.value = width - 1;
+ }
+ else
+ {
+ inst->operands[2].imm.value = (64 - lsb) & 0x3f;
+ inst->operands[3].imm.value = width - 1;
+ }
+}
+
+/* The instruction written:
LSL <Xd>, <Xn>, #<shift>
is equivalent to:
UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
@@ -1171,6 +1202,9 @@ convert_to_real (aarch64_inst *inst, const aarch64_opcode *real)
case OP_UBFIZ:
convert_bfi_to_bfm (inst);
break;
+ case OP_BFC:
+ convert_bfc_to_bfm (inst);
+ break;
case OP_MOV_V:
convert_mov_to_orr (inst);
break;
diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c
index d83bae0..f46f737 100644
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index d744c25..efa1074 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -1601,6 +1601,45 @@ convert_bfm_to_bfi (aarch64_inst *inst)
}
/* The instruction written:
+ BFC <Xd>, #<lsb>, #<width>
+ is equivalent to:
+ BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
+
+static int
+convert_bfm_to_bfc (aarch64_inst *inst)
+{
+ int64_t immr, imms, val;
+
+ /* Should have been assured by the base opcode value. */
+ assert (inst->operands[1].reg.regno == 0x1f);
+
+ immr = inst->operands[2].imm.value;
+ imms = inst->operands[3].imm.value;
+ val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
+ if (imms < immr)
+ {
+ /* Drop XZR from the second operand. */
+ copy_operand_info (inst, 1, 2);
+ copy_operand_info (inst, 2, 3);
+ inst->operands[3].type = AARCH64_OPND_NIL;
+
+ /* Recalculate the immediates. */
+ inst->operands[1].imm.value = (val - immr) & (val - 1);
+ inst->operands[2].imm.value = imms + 1;
+
+ /* The two opcodes have different qualifiers for the operands; reset to
+ help the checking. */
+ reset_operand_qualifier (inst, 1);
+ reset_operand_qualifier (inst, 2);
+ reset_operand_qualifier (inst, 3);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* The instruction written:
LSL <Xd>, <Xn>, #<shift>
is equivalent to:
UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
@@ -1759,6 +1798,8 @@ convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
case OP_BFI:
case OP_UBFIZ:
return convert_bfm_to_bfi (inst);
+ case OP_BFC:
+ return convert_bfm_to_bfc (inst);
case OP_MOV_V:
return convert_orr_to_mov (inst);
case OP_MOV_IMM_WIDE:
diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
index 20b8ae8..485a3f5 100644
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 9323217..9d1aa56 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1659,7 +1659,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
break;
case AARCH64_OPND_WIDTH:
- assert (idx == 3 && opnds[idx-1].type == AARCH64_OPND_IMM
+ assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
&& opnds[0].type == AARCH64_OPND_Rd);
size = get_upper_bound (qualifier);
if (opnd->imm.value + opnds[idx-1].imm.value > size)
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 86bc029..ddfc577 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -236,6 +236,13 @@
QLF4(X,X,imm_0_63,imm_0_63), \
}
+/* e.g. BFC <Wd>, #<immr>, #<imms>. */
+#define QL_BF1 \
+{ \
+ QLF3 (W, imm_0_31, imm_1_32), \
+ QLF3 (X, imm_0_63, imm_1_64), \
+}
+
/* e.g. UBFIZ <Wd>, <Wn>, #<lsb>, #<width>. */
#define QL_BF2 \
{ \
@@ -1226,6 +1233,8 @@ static const aarch64_feature_set aarch64_feature_lor =
AARCH64_FEATURE (AARCH64_FEATURE_LOR, 0);
static const aarch64_feature_set aarch64_feature_rdma =
AARCH64_FEATURE (AARCH64_FEATURE_RDMA, 0);
+static const aarch64_feature_set aarch64_feature_v8_2 =
+ AARCH64_FEATURE (AARCH64_FEATURE_V8_2, 0);
#define CORE &aarch64_feature_v8
#define FP &aarch64_feature_fp
@@ -1235,6 +1244,7 @@ static const aarch64_feature_set aarch64_feature_rdma =
#define LSE &aarch64_feature_lse
#define LOR &aarch64_feature_lor
#define RDMA &aarch64_feature_rdma
+#define ARMV8_2 &aarch64_feature_v8_2
struct aarch64_opcode aarch64_opcode_table[] =
{
@@ -1777,6 +1787,8 @@ struct aarch64_opcode aarch64_opcode_table[] =
{"asr", 0x13000000, 0x7f800000, bitfield, OP_ASR_IMM, CORE, OP3 (Rd, Rn, IMM), QL_SHIFT, F_ALIAS | F_P2 | F_CONV},
{"bfm", 0x33000000, 0x7f800000, bitfield, 0, CORE, OP4 (Rd, Rn, IMMR, IMMS), QL_BF, F_HAS_ALIAS | F_SF | F_N},
{"bfi", 0x33000000, 0x7f800000, bitfield, OP_BFI, CORE, OP4 (Rd, Rn, IMM, WIDTH), QL_BF2, F_ALIAS | F_P1 | F_CONV},
+ {"bfc", 0x330003e0, 0x7f8003e0, bitfield, OP_BFC, ARMV8_2,
+ OP3 (Rd, IMM, WIDTH), QL_BF1, F_ALIAS | F_P2 | F_CONV},
{"bfxil", 0x33000000, 0x7f800000, bitfield, OP_BFXIL, CORE, OP4 (Rd, Rn, IMM, WIDTH), QL_BF2, F_ALIAS | F_P1 | F_CONV},
{"ubfm", 0x53000000, 0x7f800000, bitfield, 0, CORE, OP4 (Rd, Rn, IMMR, IMMS), QL_BF, F_HAS_ALIAS | F_SF | F_N},
{"ubfiz", 0x53000000, 0x7f800000, bitfield, OP_UBFIZ, CORE, OP4 (Rd, Rn, IMM, WIDTH), QL_BF2, F_ALIAS | F_P1 | F_CONV},
--
2.1.4