summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/testsuite/gas/ppc/ppc.exp2
-rw-r--r--gas/testsuite/gas/ppc/rop-checks.d3
-rw-r--r--gas/testsuite/gas/ppc/rop-checks.l17
-rw-r--r--gas/testsuite/gas/ppc/rop-checks.s18
-rw-r--r--gas/testsuite/gas/ppc/rop.d27
-rw-r--r--gas/testsuite/gas/ppc/rop.s21
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/ppc-opc.c46
9 files changed, 148 insertions, 1 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index a2cdedaee93..cb38110d417 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,12 @@
+2021-01-08 Peter Bergner <bergner@linux.ibm.com>
+
+ * testsuite/gas/ppc/rop-checks.d,
+ * testsuite/gas/ppc/rop-checks.l,
+ * testsuite/gas/ppc/rop-checks.s,
+ * testsuite/gas/ppc/rop.d,
+ * testsuite/gas/ppc/rop.s: New tests.
+ * testsuite/gas/ppc/ppc.exp: Run them.
+
2021-01-09 Alan Modra <amodra@gmail.com>
* configure: Regenerate.
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index bec31513357..6f61ad09f41 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -146,5 +146,7 @@ run_dump_test "stringop"
run_dump_test "xvtlsbb"
run_dump_test "rightmost"
run_dump_test "scalarquad"
+run_dump_test "rop"
+run_dump_test "rop-checks"
run_dump_test "dcbt"
diff --git a/gas/testsuite/gas/ppc/rop-checks.d b/gas/testsuite/gas/ppc/rop-checks.d
new file mode 100644
index 00000000000..b7ef25eed21
--- /dev/null
+++ b/gas/testsuite/gas/ppc/rop-checks.d
@@ -0,0 +1,3 @@
+#as: -mpower10
+#name: Test Return-Oriented Programming checks
+#error_output: rop-checks.l
diff --git a/gas/testsuite/gas/ppc/rop-checks.l b/gas/testsuite/gas/ppc/rop-checks.l
new file mode 100644
index 00000000000..83ffbee8ee8
--- /dev/null
+++ b/gas/testsuite/gas/ppc/rop-checks.l
@@ -0,0 +1,17 @@
+[^:]*: Assembler messages:
+[^:]*:3: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:4: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:5: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:6: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:7: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:8: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:9: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:10: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:11: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:12: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:13: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:14: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:15: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:16: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:17: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
+[^:]*:18: Error: invalid offset: must be in the range \[-512, -8\] and be a multiple of 8
diff --git a/gas/testsuite/gas/ppc/rop-checks.s b/gas/testsuite/gas/ppc/rop-checks.s
new file mode 100644
index 00000000000..83ca35a819c
--- /dev/null
+++ b/gas/testsuite/gas/ppc/rop-checks.s
@@ -0,0 +1,18 @@
+ .text
+_start:
+ hashst 20,8(1)
+ hashst 21,0(1)
+ hashst 22,-12(1)
+ hashst 23,-520(1)
+ hashchk 20,8(1)
+ hashchk 21,0(1)
+ hashchk 22,-12(1)
+ hashchk 23,-520(1)
+ hashstp 20,8(1)
+ hashstp 21,0(1)
+ hashstp 22,-12(1)
+ hashstp 23,-520(1)
+ hashchkp 20,8(1)
+ hashchkp 21,0(1)
+ hashchkp 22,-12(1)
+ hashchkp 23,-520(1)
diff --git a/gas/testsuite/gas/ppc/rop.d b/gas/testsuite/gas/ppc/rop.d
new file mode 100644
index 00000000000..2671dd6bbd5
--- /dev/null
+++ b/gas/testsuite/gas/ppc/rop.d
@@ -0,0 +1,27 @@
+#as: -mpower8
+#objdump: -d -Mpower8
+#name: Return-Oriented Programming tests
+
+.*
+
+
+Disassembly of section \.text:
+
+0+0 <_start>:
+.*: (7f e1 a5 a5|a5 a5 e1 7f) hashst r20,-8\(r1\)
+.*: (7f c1 ad a5|a5 ad c1 7f) hashst r21,-16\(r1\)
+.*: (7c 01 b5 a5|a5 b5 01 7c) hashst r22,-256\(r1\)
+.*: (7c 01 bd a4|a4 bd 01 7c) hashst r23,-512\(r1\)
+.*: (7f e1 a5 e5|e5 a5 e1 7f) hashchk r20,-8\(r1\)
+.*: (7f c1 ad e5|e5 ad c1 7f) hashchk r21,-16\(r1\)
+.*: (7c 01 b5 e5|e5 b5 01 7c) hashchk r22,-256\(r1\)
+.*: (7c 01 bd e4|e4 bd 01 7c) hashchk r23,-512\(r1\)
+.*: (7f e1 a5 25|25 a5 e1 7f) hashstp r20,-8\(r1\)
+.*: (7f c1 ad 25|25 ad c1 7f) hashstp r21,-16\(r1\)
+.*: (7c 01 b5 25|25 b5 01 7c) hashstp r22,-256\(r1\)
+.*: (7c 01 bd 24|24 bd 01 7c) hashstp r23,-512\(r1\)
+.*: (7f e1 a5 65|65 a5 e1 7f) hashchkp r20,-8\(r1\)
+.*: (7f c1 ad 65|65 ad c1 7f) hashchkp r21,-16\(r1\)
+.*: (7c 01 b5 65|65 b5 01 7c) hashchkp r22,-256\(r1\)
+.*: (7c 01 bd 64|64 bd 01 7c) hashchkp r23,-512\(r1\)
+#pass
diff --git a/gas/testsuite/gas/ppc/rop.s b/gas/testsuite/gas/ppc/rop.s
new file mode 100644
index 00000000000..22e45f49aa9
--- /dev/null
+++ b/gas/testsuite/gas/ppc/rop.s
@@ -0,0 +1,21 @@
+# These instructions are new in POWER10, but enabled for POWER8 and
+# later cpus. On POWER8 and POWER9, these instructions behave as
+# nop's.
+ .text
+_start:
+ hashst 20,-8(1)
+ hashst 21,-16(1)
+ hashst 22,-256(1)
+ hashst 23,-512(1)
+ hashchk 20,-8(1)
+ hashchk 21,-16(1)
+ hashchk 22,-256(1)
+ hashchk 23,-512(1)
+ hashstp 20,-8(1)
+ hashstp 21,-16(1)
+ hashstp 22,-256(1)
+ hashstp 23,-512(1)
+ hashchkp 20,-8(1)
+ hashchkp 21,-16(1)
+ hashchkp 22,-256(1)
+ hashchkp 23,-512(1)
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 205c0ad6c37..6b48181d887 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,9 @@
+2021-01-08 Peter Bergner <bergner@linux.ibm.com>
+
+ * ppc-opc.c (insert_dw, (extract_dw): New functions.
+ (DW, (XRC_MASK): Define.
+ (powerpc_opcodes) <hashchk, hashchkp, hashst, haststp>: New mnemonics.
+
2021-01-09 Alan Modra <amodra@gmail.com>
* configure: Regenerate.
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index dcff56205d4..bbbadffad8f 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -558,6 +558,34 @@ extract_dcmxs (uint64_t insn,
return (insn & 0x40) | ((insn << 3) & 0x20) | ((insn >> 16) & 0x1f);
}
+/* The DW field in a X form instruction when the field is split
+ into separate D and DX fields. */
+
+static uint64_t
+insert_dw (uint64_t insn,
+ int64_t value,
+ ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ /* DW offsets must be in the range [-512, -8] and be a multiple of 8. */
+ if (value < -512
+ || value > -8
+ || (value & 0x7) != 0)
+ *errmsg = _("invalid offset: must be in the range [-512, -8] "
+ "and be a multiple of 8");
+
+ return insn | ((value & 0xf8) << 18) | ((value >> 8) & 1);
+}
+
+static int64_t
+extract_dw (uint64_t insn,
+ ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+ int *invalid ATTRIBUTE_UNUSED)
+{
+ int64_t dw = ((insn & 1) << 8) | ((insn >> 18) & 0xf8);
+ return dw - 512;
+}
+
/* The D field in a DX form instruction when the field is split
into separate D0, D1 and D2 fields. */
@@ -2497,8 +2525,13 @@ const struct powerpc_operand powerpc_operands[] =
#define BHRBE DUIS
{ 0x3ff, 11, NULL, NULL, 0 },
+ /* The split DW field in a X form instruction. */
+#define DW DUIS + 1
+ { -1, PPC_OPSHIFT_INV, insert_dw, extract_dw,
+ PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED},
+
/* The split D field in a DX form instruction. */
-#define DXD DUIS + 1
+#define DXD DW + 1
{ 0xffff, PPC_OPSHIFT_INV, insert_dxd, extract_dxd,
PPC_OPERAND_SIGNED | PPC_OPERAND_SIGNOPT},
@@ -3750,6 +3783,9 @@ const unsigned int num_powerpc_operands = (sizeof (powerpc_operands)
/* The mask for an X form instruction with the BF bits specified. */
#define XBF_MASK (X_MASK | (3 << 21))
+/* An X form instruction without the RC field specified. */
+#define XRC_MASK XRC (0x3f, 0x3ff, 0)
+
/* An X form wait instruction with everything filled in except the WC
field. */
#define XWC_MASK (XRC (0x3f, 0x3ff, 1) | (7 << 23) | RA_MASK | RB_MASK)
@@ -7656,6 +7692,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"addeo.", XO(31,138,1,1), XO_MASK, PPCCOM, 0, {RT, RA, RB}},
{"aeo.", XO(31,138,1,1), XO_MASK, PWRCOM, 0, {RT, RA, RB}},
+{"hashstp", X(31,658), XRC_MASK, POWER8, 0, {RB, DW, RA0}},
+
{"mfsrin", X(31,659), XRA_MASK, PPC, NON32, {RT, RB}},
{"stdbrx", X(31,660), X_MASK, CELL|POWER7|PPCA2, 0, {RS, RA0, RB}},
@@ -7685,6 +7723,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"tendall.", XRC(31,686,1)|(1<<25), XRTRARB_MASK, PPCHTM, 0, {0}},
{"tend.", XRC(31,686,1), XRTARARB_MASK, PPCHTM, 0, {HTM_A}},
+{"hashchkp", X(31,690), XRC_MASK, POWER8, 0, {RB, DW, RA0}},
+
{"stbcx.", XRC(31,694,1), X_MASK, POWER8|E6500, 0, {RS, RA0, RB}},
{"stfsux", X(31,695), X_MASK, COM, PPCEFS, {FRS, RAS, RB}},
@@ -7715,6 +7755,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"addzeo.", XO(31,202,1,1), XORB_MASK, PPCCOM, 0, {RT, RA}},
{"azeo.", XO(31,202,1,1), XORB_MASK, PWRCOM, 0, {RT, RA}},
+{"hashst", X(31,722), XRC_MASK, POWER8, 0, {RB, DW, RA0}},
+
{"stswi", X(31,725), X_MASK, PPCCOM, E500|E500MC, {RS, RA0, NB}},
{"stsi", X(31,725), X_MASK, PWRCOM, 0, {RS, RA0, NB}},
@@ -7761,6 +7803,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"tresume.", XRCL(31,750,1,1), XRTRARB_MASK,PPCHTM, 0, {0}},
{"tsr.", XRC(31,750,1), XRTLRARB_MASK,PPCHTM, 0, {L}},
+{"hashchk", X(31,754), XRC_MASK, POWER8, 0, {RB, DW, RA0}},
+
{"darn", X(31,755), XLRAND_MASK, POWER9, 0, {RT, LRAND}},
{"dcba", X(31,758), XRT_MASK, PPC405|PPC7450|BOOKE|PPCA2|PPC476, 0, {RA0, RB}},