PowerPC D-form prefixed loads and stores

opcodes/
	* ppc-opc.c (insert_d34, extract_d34, insert_nsi34, extract_nsi34),
	(insert_pcrel, extract_pcrel, extract_pcrel0): New functions.
	(extract_esync, extract_raq, extract_tbr, extract_sxl): Comment.
	(powerpc_operands <D34, SI34, NSI34, PRA0, PRAQ, PCREL, PCREL0,
	XTOP>): Define and add entries.
	(P8LS, PMLS, P_D_MASK, P_DRAPCREL_MASK): Define.
	(prefix_opcodes): Add pli, paddi, pla, psubi, plwz, plbz, pstw,
	pstb, plhz, plha, psth, plfs, plfd, pstfs, pstfd, plq, plxsd,
	plxssp, pld, plwa, pstxsd, pstxssp, pstxv, pstd, and pstq.
gas/
	* config/tc-ppc.c (ppc_insert_operand): Only sign extend fields that
	are 32-bits or smaller.
	* messages.c (as_internal_value_out_of_range): Do not truncate
	variables and use BFD_VMA_FMT to print them.
	* testsuite/gas/ppc/prefix-pcrel.s,
	* testsuite/gas/ppc/prefix-pcrel.d: New test.
	* testsuite/gas/ppc/ppc.exp: Run it.
This commit is contained in:
Peter Bergner 2018-07-27 22:21:43 -05:00 committed by Alan Modra
parent dd7efa7915
commit 8acf14351c
8 changed files with 577 additions and 15 deletions

View File

@ -1,3 +1,14 @@
2019-05-24 Peter Bergner <bergner@linux.ibm.com>
Alan Modra <amodra@gmail.com>
* config/tc-ppc.c (ppc_insert_operand): Only sign extend fields that
are 32-bits or smaller.
* messages.c (as_internal_value_out_of_range): Do not truncate
variables and use BFD_VMA_FMT to print them.
* testsuite/gas/ppc/prefix-pcrel.s,
* testsuite/gas/ppc/prefix-pcrel.d: New test.
* testsuite/gas/ppc/ppc.exp: Run it.
2019-05-24 Peter Bergner <bergner@linux.ibm.com>
Alan Modra <amodra@gmail.com>

View File

@ -1987,8 +1987,10 @@ ppc_insert_operand (uint64_t insn,
hand but only up to 32 bits. This shouldn't really be valid,
but, to permit this code to assemble on a 64-bit host, we
sign extend the 32-bit value to 64 bits if so doing makes the
value valid. */
value valid. We only do this for operands that are 32-bits or
smaller. */
if (val > max
&& (operand->bitm & ~0xffffffffULL) == 0
&& (val - (1LL << 32)) >= min
&& (val - (1LL << 32)) <= max
&& ((val - (1LL << 32)) & (right - 1)) == 0)
@ -1997,6 +1999,7 @@ ppc_insert_operand (uint64_t insn,
/* Similarly, people write expressions like ~(1<<15), and expect
this to be OK for a 32-bit unsigned value. */
else if (val < min
&& (operand->bitm & ~0xffffffffULL) == 0
&& (val + (1LL << 32)) >= min
&& (val + (1LL << 32)) <= max
&& ((val + (1LL << 32)) & (right - 1)) == 0)

View File

@ -397,13 +397,12 @@ as_internal_value_out_of_range (const char *prefix,
abort ();
/* xgettext:c-format */
err = _("%s out of domain (%d is not a multiple of %d)");
err = _("%s out of domain (%" BFD_VMA_FMT "d is not a multiple of %" \
BFD_VMA_FMT "d)");
if (bad)
as_bad_where (file, line, err,
prefix, (int) val, (int) right);
as_bad_where (file, line, err, prefix, val, right);
else
as_warn_where (file, line, err,
prefix, (int) val, (int) right);
as_warn_where (file, line, err, prefix, val, right);
return;
}
@ -415,14 +414,13 @@ as_internal_value_out_of_range (const char *prefix,
&& max > HEX_MIN_THRESHOLD)
{
/* xgettext:c-format */
err = _("%s out of range (%d is not between %d and %d)");
err = _("%s out of range (%" BFD_VMA_FMT "d is not between %" \
BFD_VMA_FMT "d and %" BFD_VMA_FMT "d)");
if (bad)
as_bad_where (file, line, err,
prefix, (int) val, (int) min, (int) max);
as_bad_where (file, line, err, prefix, val, min, max);
else
as_warn_where (file, line, err,
prefix, (int) val, (int) min, (int) max);
as_warn_where (file, line, err, prefix, val, min, max);
}
else
{

View File

@ -115,3 +115,4 @@ run_dump_test "vsx3"
run_dump_test "htm"
run_dump_test "titan"
run_dump_test "prefix-align"
run_dump_test "prefix-pcrel"

View File

@ -0,0 +1,235 @@
#as: -mfuture
#objdump: -dr -Mfuture
#name: POWERXX pcrel tests
.*
Disassembly of section \.text:
0+00 <prefix>:
.*: (06 00 00 00|00 00 00 06) paddi r10,r9,0
.*: (39 49 00 00|00 00 49 39)
.*: (06 00 00 00|00 00 00 06) paddi r10,r9,0
.*: (39 49 00 00|00 00 49 39)
.*: (06 00 00 00|00 00 00 06) paddi r10,r9,0
.*: (39 49 00 00|00 00 49 39)
.*: (06 03 ff ff|ff ff 03 06) paddi r11,r9,-32769
.*: (39 69 7f ff|ff 7f 69 39)
.*: (06 03 ff ff|ff ff 03 06) paddi r11,r9,-32769
.*: (39 69 7f ff|ff 7f 69 39)
.*: (06 03 ff ff|ff ff 03 06) paddi r11,r9,-32769
.*: (39 69 7f ff|ff 7f 69 39)
.*: (06 01 ff ff|ff ff 01 06) paddi r12,r9,8589934591
.*: (39 89 ff ff|ff ff 89 39)
.*: (06 01 ff ff|ff ff 01 06) paddi r12,r9,8589934591
.*: (39 89 ff ff|ff ff 89 39)
.*: (06 01 ff ff|ff ff 01 06) paddi r12,r9,8589934591
.*: (39 89 ff ff|ff ff 89 39)
.*: (06 01 ff ff|ff ff 01 06) paddi r12,r9,8589934591
.*: (39 89 ff ff|ff ff 89 39)
.*: (06 01 ff ff|ff ff 01 06) paddi r12,r9,8589934591
.*: (39 89 ff ff|ff ff 89 39)
.*: (06 02 00 00|00 00 02 06) paddi r13,r9,-8589934592
.*: (39 a9 00 00|00 00 a9 39)
.*: (06 02 00 00|00 00 02 06) paddi r13,r9,-8589934592
.*: (39 a9 00 00|00 00 a9 39)
.*: (06 02 00 00|00 00 02 06) paddi r13,r9,-8589934592
.*: (39 a9 00 00|00 00 a9 39)
.*: (06 02 00 00|00 00 02 06) paddi r13,r9,-8589934592
.*: (39 a9 00 00|00 00 a9 39)
.*: (06 02 00 00|00 00 02 06) paddi r13,r9,-8589934592
.*: (39 a9 00 00|00 00 a9 39)
.*: (06 10 00 00|00 00 10 06) pla r14,0
.*: (39 c0 00 00|00 00 c0 39)
.*: (06 10 00 00|00 00 10 06) pla r14,0
.*: (39 c0 00 00|00 00 c0 39)
.*: (06 13 ff ff|ff ff 13 06) pla r15,-32769
.*: (39 e0 7f ff|ff 7f e0 39)
.*: (06 13 ff ff|ff ff 13 06) pla r15,-32769
.*: (39 e0 7f ff|ff 7f e0 39)
.*: (06 13 ff ff|ff ff 13 06) pla r15,-32769
.*: (39 e0 7f ff|ff 7f e0 39)
.*: (06 11 ff ff|ff ff 11 06) pla r16,8589934591
.*: (3a 00 ff ff|ff ff 00 3a)
.*: (06 11 ff ff|ff ff 11 06) pla r16,8589934591
.*: (3a 00 ff ff|ff ff 00 3a)
.*: (06 11 ff ff|ff ff 11 06) pla r16,8589934591
.*: (3a 00 ff ff|ff ff 00 3a)
.*: (06 12 00 00|00 00 12 06) pla r17,-8589934592
.*: (3a 20 00 00|00 00 20 3a)
.*: (06 12 00 00|00 00 12 06) pla r17,-8589934592
.*: (3a 20 00 00|00 00 20 3a)
.*: (06 12 00 00|00 00 12 06) pla r17,-8589934592
.*: (3a 20 00 00|00 00 20 3a)
.*: (06 00 00 00|00 00 00 06) pli r20,13
.*: (3a 80 00 0d|0d 00 80 3a)
.*: (06 00 00 00|00 00 00 06) pli r20,13
.*: (3a 80 00 0d|0d 00 80 3a)
.*: (06 00 00 00|00 00 00 06) pli r20,13
.*: (3a 80 00 0d|0d 00 80 3a)
.*: (06 00 00 00|00 00 00 06) pli r20,13
.*: (3a 80 00 0d|0d 00 80 3a)
.*: (06 03 ff ff|ff ff 03 06) pli r21,-32769
.*: (3a a0 7f ff|ff 7f a0 3a)
.*: (06 03 ff ff|ff ff 03 06) pli r21,-32769
.*: (3a a0 7f ff|ff 7f a0 3a)
.*: (06 03 ff ff|ff ff 03 06) pli r21,-32769
.*: (3a a0 7f ff|ff 7f a0 3a)
.*: (06 01 ff ff|ff ff 01 06) pli r22,8589934591
.*: (3a c0 ff ff|ff ff c0 3a)
.*: (06 01 ff ff|ff ff 01 06) pli r22,8589934591
.*: (3a c0 ff ff|ff ff c0 3a)
.*: (06 01 ff ff|ff ff 01 06) pli r22,8589934591
.*: (3a c0 ff ff|ff ff c0 3a)
.*: (06 01 ff ff|ff ff 01 06) pli r22,8589934591
.*: (3a c0 ff ff|ff ff c0 3a)
.*: (06 01 ff ff|ff ff 01 06) pli r22,8589934591
.*: (3a c0 ff ff|ff ff c0 3a)
.*: (06 01 ff ff|ff ff 01 06) pli r22,8589934591
.*: (3a c0 ff ff|ff ff c0 3a)
.*: (06 02 00 00|00 00 02 06) pli r23,-8589934592
.*: (3a e0 00 00|00 00 e0 3a)
.*: (06 02 00 00|00 00 02 06) pli r23,-8589934592
.*: (3a e0 00 00|00 00 e0 3a)
.*: (06 02 00 00|00 00 02 06) pli r23,-8589934592
.*: (3a e0 00 00|00 00 e0 3a)
.*: (06 02 00 00|00 00 02 06) pli r23,-8589934592
.*: (3a e0 00 00|00 00 e0 3a)
.*: (06 02 00 00|00 00 02 06) pli r23,-8589934592
.*: (3a e0 00 00|00 00 e0 3a)
.*: (06 02 00 00|00 00 02 06) pli r23,-8589934592
.*: (3a e0 00 00|00 00 e0 3a)
.*: (06 00 00 00|00 00 00 06) plbz r3,0\(r1\)
.*: (88 61 00 00|00 00 61 88)
.*: (06 00 00 00|00 00 00 06) plbz r3,0\(r1\)
.*: (88 61 00 00|00 00 61 88)
.*: (06 03 ff ff|ff ff 03 06) plbz r3,-32769\(r1\)
.*: (88 61 7f ff|ff 7f 61 88)
.*: (06 03 ff ff|ff ff 03 06) plbz r3,-32769\(r1\)
.*: (88 61 7f ff|ff 7f 61 88)
.*: (06 01 ff ff|ff ff 01 06) plbz r3,8589934591\(r1\)
.*: (88 61 ff ff|ff ff 61 88)
.*: (06 01 ff ff|ff ff 01 06) plbz r3,8589934591\(r1\)
.*: (88 61 ff ff|ff ff 61 88)
.*: (06 02 00 00|00 00 02 06) plbz r3,-8589934592\(r1\)
.*: (88 61 00 00|00 00 61 88)
.*: (06 02 00 00|00 00 02 06) plbz r3,-8589934592\(r1\)
.*: (88 61 00 00|00 00 61 88)
.*: (06 00 00 00|00 00 00 06) plbz r3,0\(0\)
.*: (88 60 00 00|00 00 60 88)
.*: (06 10 00 00|00 00 10 06) plbz r4,0
.*: (88 80 00 00|00 00 80 88)
.*: (06 10 00 00|00 00 10 06) plbz r4,0
.*: (88 80 00 00|00 00 80 88)
.*: (06 03 ff ff|ff ff 03 06) plbz r3,-32769\(0\)
.*: (88 60 7f ff|ff 7f 60 88)
.*: (06 13 ff ff|ff ff 13 06) plbz r4,-32769
.*: (88 80 7f ff|ff 7f 80 88)
.*: (06 13 ff ff|ff ff 13 06) plbz r4,-32769
.*: (88 80 7f ff|ff 7f 80 88)
.*: (06 01 ff ff|ff ff 01 06) plbz r3,8589934591\(0\)
.*: (88 60 ff ff|ff ff 60 88)
.*: (06 11 ff ff|ff ff 11 06) plbz r4,8589934591
.*: (88 80 ff ff|ff ff 80 88)
.*: (06 11 ff ff|ff ff 11 06) plbz r4,8589934591
.*: (88 80 ff ff|ff ff 80 88)
.*: (06 02 00 00|00 00 02 06) plbz r3,-8589934592\(0\)
.*: (88 60 00 00|00 00 60 88)
.*: (06 12 00 00|00 00 12 06) plbz r4,-8589934592
.*: (88 80 00 00|00 00 80 88)
.*: (06 12 00 00|00 00 12 06) plbz r4,-8589934592
.*: (88 80 00 00|00 00 80 88)
.*: (06 00 00 00|00 00 00 06) plhz r5,4\(r10\)
.*: (a0 aa 00 04|04 00 aa a0)
.*: (06 10 00 00|00 00 10 06) plhz r5,4
.*: (a0 a0 00 04|04 00 a0 a0)
.*: (06 00 00 00|00 00 00 06) plha r6,8\(r10\)
.*: (a8 ca 00 08|08 00 ca a8)
.*: (06 10 00 00|00 00 10 06) plha r6,8
.*: (a8 c0 00 08|08 00 c0 a8)
.*: (06 00 00 00|00 00 00 06) plwz r7,12\(r10\)
.*: (80 ea 00 0c|0c 00 ea 80)
.*: (06 10 00 00|00 00 10 06) plwz r7,12
.*: (80 e0 00 0c|0c 00 e0 80)
.*: (04 00 00 00|00 00 00 04) plwa r8,16\(r10\)
.*: (a5 0a 00 10|10 00 0a a5)
.*: (04 10 00 00|00 00 10 04) plwa r8,16
.*: (a5 00 00 10|10 00 00 a5)
.*: (04 00 00 00|00 00 00 04) pld r9,20\(r10\)
.*: (e5 2a 00 14|14 00 2a e5)
.*: (04 10 00 00|00 00 10 04) pld r9,20
.*: (e5 20 00 14|14 00 20 e5)
.*: (06 00 00 00|00 00 00 06) plfs f10,24\(r10\)
.*: (c1 4a 00 18|18 00 4a c1)
.*: (06 10 00 00|00 00 10 06) plfs f10,24
.*: (c1 40 00 18|18 00 40 c1)
.*: (06 00 00 00|00 00 00 06) plfd f11,28\(r10\)
.*: (c9 6a 00 1c|1c 00 6a c9)
.*: (06 10 00 00|00 00 10 06) plfd f11,28
.*: (c9 60 00 1c|1c 00 60 c9)
.*: (04 00 00 00|00 00 00 04) plxsd v13,36\(r10\)
.*: (a9 aa 00 24|24 00 aa a9)
.*: (04 10 00 00|00 00 10 04) plxsd v13,36
.*: (a9 a0 00 24|24 00 a0 a9)
.*: (04 00 00 00|00 00 00 04) plxssp v14,40\(r10\)
.*: (ad ca 00 28|28 00 ca ad)
.*: (04 10 00 00|00 00 10 04) plxssp v14,40
.*: (ad c0 00 28|28 00 c0 ad)
.*: (04 00 00 00|00 00 00 04) plq r16,48\(r10\)
.*: (e2 0a 00 30|30 00 0a e2)
.*: (04 10 00 00|00 00 10 04) plq r16,48
.*: (e2 00 00 30|30 00 00 e2)
.*: (04 00 00 00|00 00 00 04) plxv vs17,64\(r10\)
.*: (ca 2a 00 40|40 00 2a ca)
.*: (04 10 00 00|00 00 10 04) plxv vs17,64
.*: (ca 20 00 40|40 00 20 ca)
.*: (04 00 00 00|00 00 00 04) plxv vs34,64\(r10\)
.*: (cc 4a 00 40|40 00 4a cc)
.*: (04 10 00 00|00 00 10 04) plxv vs34,64
.*: (cc 40 00 40|40 00 40 cc)
.*: (06 00 00 00|00 00 00 06) pstb r3,52\(r11\)
.*: (98 6b 00 34|34 00 6b 98)
.*: (06 10 00 00|00 00 10 06) pstb r3,52
.*: (98 60 00 34|34 00 60 98)
.*: (06 00 00 00|00 00 00 06) psth r4,56\(r11\)
.*: (b0 8b 00 38|38 00 8b b0)
.*: (06 10 00 00|00 00 10 06) psth r4,56
.*: (b0 80 00 38|38 00 80 b0)
.*: (06 00 00 00|00 00 00 06) pstw r5,60\(r11\)
.*: (90 ab 00 3c|3c 00 ab 90)
.*: (06 10 00 00|00 00 10 06) pstw r5,60
.*: (90 a0 00 3c|3c 00 a0 90)
.*: (06 00 00 00|00 00 00 06) pstfs f6,64\(r11\)
.*: (d0 cb 00 40|40 00 cb d0)
.*: (06 10 00 00|00 00 10 06) pstfs f6,64
.*: (d0 c0 00 40|40 00 c0 d0)
.*: (06 00 00 00|00 00 00 06) pstfd f7,68\(r11\)
.*: (d8 eb 00 44|44 00 eb d8)
.*: (06 10 00 00|00 00 10 06) pstfd f7,68
.*: (d8 e0 00 44|44 00 e0 d8)
.*: (04 00 00 00|00 00 00 04) pstxsd v9,76\(r11\)
.*: (b9 2b 00 4c|4c 00 2b b9)
.*: (04 10 00 00|00 00 10 04) pstxsd v9,76
.*: (b9 20 00 4c|4c 00 20 b9)
.*: (04 00 00 00|00 00 00 04) pstxssp v10,80\(r11\)
.*: (bd 4b 00 50|50 00 4b bd)
.*: (04 10 00 00|00 00 10 04) pstxssp v10,80
.*: (bd 40 00 50|50 00 40 bd)
.*: (04 00 00 00|00 00 00 04) pstd r11,84\(r11\)
.*: (f5 6b 00 54|54 00 6b f5)
.*: (04 10 00 00|00 00 10 04) pstd r11,84
.*: (f5 60 00 54|54 00 60 f5)
.*: (04 00 00 00|00 00 00 04) pstq r12,88\(r11\)
.*: (f1 8b 00 58|58 00 8b f1)
.*: (04 10 00 00|00 00 10 04) pstq r12,88
.*: (f1 80 00 58|58 00 80 f1)
.*: (04 00 00 00|00 00 00 04) pstxv vs13,96\(r11\)
.*: (d9 ab 00 60|60 00 ab d9)
.*: (04 10 00 00|00 00 10 04) pstxv vs13,96
.*: (d9 a0 00 60|60 00 a0 d9)
.*: (04 00 00 00|00 00 00 04) pstxv vs63,96\(r11\)
.*: (df eb 00 60|60 00 eb df)
.*: (04 10 00 00|00 00 10 04) pstxv vs63,96
.*: (df e0 00 60|60 00 e0 df)
#pass

View File

@ -0,0 +1,121 @@
.text
prefix:
# The following should all disassemble to: paddi rX,rY,disp
pla 10,0(9)
paddi 10,9,0
paddi 10,9,0,0
pla 11,~(1<<15)(9)
paddi 11,9,~(1<<15)
paddi 11,9,~(1<<15),0
pla 12,8589934591(9)
psubi 12,9,-8589934591
psubi 12,9,-8589934591,0
paddi 12,9,8589934591
paddi 12,9,8589934591,0
pla 13,-8589934592(9)
psubi 13,9,8589934592
psubi 13,9,8589934592,0
paddi 13,9,-8589934592
paddi 13,9,-8589934592,0
# The following should all disassemble to: pla rX,disp
pla 14,0
paddi 14,0,0,1
pla 15,~(1<<15)
psubi 15,0,-(~(1<<15)),1
paddi 15,0,~(1<<15),1
pla 16,8589934591
psubi 16,0,-8589934591,1
paddi 16,0,8589934591,1
pla 17,-8589934592
psubi 17,0,8589934592,1
paddi 17,0,-8589934592,1
# The following should all disassemble to: pli rX,immed
pli 20,13
pla 20,13(0)
psubi 20,0,-13
paddi 20,0,13
pli 21,~(1<<15)
pla 21,~(1<<15)(0)
paddi 21,0,~(1<<15)
pli 22,8589934591
pla 22,8589934591(0)
psubi 22,0,-8589934591
psubi 22,0,-8589934591,0
paddi 22,0,8589934591
paddi 22,0,8589934591,0
pli 23,-8589934592
pla 23,-8589934592(0)
psubi 23,0,8589934592
psubi 23,0,8589934592,0
paddi 23,0,-8589934592
paddi 23,0,-8589934592,0
# Tests of prefix loads and stores
plbz 3,0(1)
plbz 3,0(1),0
plbz 3,~(1<<15)(1)
plbz 3,~(1<<15)(1),0
plbz 3,8589934591(1)
plbz 3,8589934591(1),0
plbz 3,-8589934592(1)
plbz 3,-8589934592(1),0
plbz 3,0(0)
plbz 4,0(0),1
plbz 4,0
plbz 3,~(1<<15)(0)
plbz 4,~(1<<15)(0),1
plbz 4,~(1<<15)
plbz 3,8589934591(0)
plbz 4,8589934591(0),1
plbz 4,8589934591
plbz 3,-8589934592(0)
plbz 4,-8589934592(0),1
plbz 4,-8589934592
plhz 5,4(10),0
plhz 5,4(0),1
plha 6,8(10),0
plha 6,8(0),1
plwz 7,12(10),0
plwz 7,12(0),1
plwa 8,16(10),0
plwa 8,16(0),1
pld 9,20(10),0
pld 9,20(0),1
plfs 10,24(10),0
plfs 10,24(0),1
plfd 11,28(10),0
plfd 11,28(0),1
plxsd 13,36(10),0
plxsd 13,36(0),1
plxssp 14,40(10),0
plxssp 14,40(0),1
plq 16,48(10),0
plq 16,48(0),1
plxv 17,64(10),0
plxv 17,64(0),1
plxv 34,64(10),0
plxv 34,64(0),1
pstb 3,52(11),0
pstb 3,52(0),1
psth 4,56(11),0
psth 4,56(0),1
pstw 5,60(11),0
pstw 5,60(0),1
pstfs 6,64(11),0
pstfs 6,64(0),1
pstfd 7,68(11),0
pstfd 7,68(0),1
pstxsd 9,76(11),0
pstxsd 9,76(0),1
pstxssp 10,80(11),0
pstxssp 10,80(0),1
pstd 11,84(11),0
pstd 11,84(0),1
pstq 12,88(11),0
pstq 12,88(0),1
pstxv 13,96(11),0
pstxv 13,96(0),1
pstxv 63,96(11),0
pstxv 63,96(0),1

View File

@ -1,3 +1,16 @@
2019-05-24 Peter Bergner <bergner@linux.ibm.com>
Alan Modra <amodra@gmail.com>
* ppc-opc.c (insert_d34, extract_d34, insert_nsi34, extract_nsi34),
(insert_pcrel, extract_pcrel, extract_pcrel0): New functions.
(extract_esync, extract_raq, extract_tbr, extract_sxl): Comment.
(powerpc_operands <D34, SI34, NSI34, PRA0, PRAQ, PCREL, PCREL0,
XTOP>): Define and add entries.
(P8LS, PMLS, P_D_MASK, P_DRAPCREL_MASK): Define.
(prefix_opcodes): Add pli, paddi, pla, psubi, plwz, plbz, pstw,
pstb, plhz, plha, psth, plfs, plfd, pstfs, pstfd, plq, plxsd,
plxssp, pld, plwa, pstxsd, pstxssp, pstxv, pstd, and pstq.
2019-05-24 Peter Bergner <bergner@linux.ibm.com>
Alan Modra <amodra@gmail.com>

View File

@ -596,6 +596,106 @@ extract_dxdn (uint64_t insn,
return -extract_dxd (insn, dialect, invalid);
}
/* The D field in a 64-bit D form prefix instruction when the field is split
into separate D0 and D1 fields. */
static uint64_t
insert_d34 (uint64_t insn,
int64_t value,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
const char **errmsg ATTRIBUTE_UNUSED)
{
return insn | ((value & 0x3ffff0000ULL) << 16) | (value & 0xffff);
}
static int64_t
extract_d34 (uint64_t insn,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
int *invalid ATTRIBUTE_UNUSED)
{
int64_t mask = 1ULL << 33;
int64_t value = ((insn >> 16) & 0x3ffff0000ULL) | (insn & 0xffff);
value = (value ^ mask) - mask;
return value;
}
/* The NSI34 field in an 8-byte D form prefix instruction. This is the same
as the SI34 field, only negated. The extraction function always marks it
as invalid, since we never want to recognize an instruction which uses
a field of this type. */
static uint64_t
insert_nsi34 (uint64_t insn,
int64_t value,
ppc_cpu_t dialect,
const char **errmsg)
{
return insert_d34 (insn, -value, dialect, errmsg);
}
static int64_t
extract_nsi34 (uint64_t insn,
ppc_cpu_t dialect,
int *invalid)
{
int64_t value = extract_d34 (insn, dialect, invalid);
*invalid = 1;
return -value;
}
/* The R field in an 8-byte prefix instruction when there are restrictions
between R's value and the RA value (ie, they cannot both be non zero). */
static uint64_t
insert_pcrel (uint64_t insn,
int64_t value,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
const char **errmsg)
{
value &= 0x1;
int64_t ra = (insn >> 16) & 0x1f;
if (ra != 0 && value != 0)
*errmsg = _("invalid R operand");
return insn | (value << 52);
}
static int64_t
extract_pcrel (uint64_t insn,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
int *invalid)
{
/* If called with *invalid < 0 to return the value for missing
operands, *invalid will be the negative count of missing operands
including this one. Return a default value of 1 if the PRA0/PRAQ
operand was also omitted (ie. *invalid is -2). Return a default
value of 0 if the PRA0/PRAQ operand was not omitted
(ie. *invalid is -1). */
if (*invalid < 0)
return ~ *invalid & 1;
int64_t ra = (insn >> 16) & 0x1f;
int64_t pcrel = (insn >> 52) & 0x1;
if (ra != 0 && pcrel != 0)
*invalid = 1;
return pcrel;
}
/* Variant of extract_pcrel that sets invalid for R bit set. The idea
is to disassemble "paddi rt,0,offset,1" as "pla rt,offset". */
static int64_t
extract_pcrel0 (uint64_t insn,
ppc_cpu_t dialect,
int *invalid)
{
int64_t pcrel = extract_pcrel (insn, dialect, invalid);
if (pcrel)
*invalid = 1;
return pcrel;
}
/* FXM mask in mfcr and mtcrf instructions. */
static uint64_t
@ -758,6 +858,7 @@ extract_esync (uint64_t insn,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
int *invalid)
{
/* Missing optional operands have a value of zero. */
if (*invalid < 0)
return 0;
@ -1013,6 +1114,7 @@ extract_raq (uint64_t insn,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
int *invalid)
{
/* Missing optional operands have a value of zero. */
if (*invalid < 0)
return 0;
@ -1338,6 +1440,7 @@ extract_tbr (uint64_t insn,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
int *invalid)
{
/* Missing optional operands have a value of 268. */
if (*invalid < 0)
return 268;
@ -1810,6 +1913,7 @@ extract_sxl (uint64_t insn,
ppc_cpu_t dialect ATTRIBUTE_UNUSED,
int *invalid)
{
/* Missing optional operands have a value of one. */
if (*invalid < 0)
return 1;
return (insn >> 11) & 0x1;
@ -2039,9 +2143,26 @@ const struct powerpc_operand powerpc_operands[] =
{ 0xfffc, 0, NULL, NULL,
PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS },
/* The D field in an 8-byte D form prefix instruction. This is a displacement
off a register, and implies that the next operand is a register in
parentheses. */
#define D34 DS + 1
{ 0x3ffffffff, PPC_OPSHIFT_INV, insert_d34, extract_d34,
PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
/* The SI field in an 8-byte D form prefix instruction. */
#define SI34 D34 + 1
{ 0x3ffffffff, PPC_OPSHIFT_INV, insert_d34, extract_d34, PPC_OPERAND_SIGNED },
/* The NSI field in an 8-byte D form prefix instruction. This is the
same as the SI34 field, only negated. */
#define NSI34 SI34 + 1
{ 0x3ffffffff, PPC_OPSHIFT_INV, insert_nsi34, extract_nsi34,
PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
/* The DUIS or BHRBE fields in a XFX form instruction, 10 bits
unsigned imediate */
#define DUIS DS + 1
#define DUIS NSI34 + 1
#define BHRBE DUIS
{ 0x3ff, 11, NULL, NULL, 0 },
@ -2217,16 +2338,33 @@ const struct powerpc_operand powerpc_operands[] =
#define RA0 RA + 1
{ 0x1f, 16, NULL, NULL, PPC_OPERAND_GPR_0 },
/* Similar to above, but optional. */
#define PRA0 RA0 + 1
{ 0x1f, 16, NULL, NULL, PPC_OPERAND_GPR_0 | PPC_OPERAND_OPTIONAL },
/* The RA field in the DQ form lq or an lswx instruction, which have
special value restrictions. */
#define RAQ RA0 + 1
#define RAQ PRA0 + 1
#define RAX RAQ
{ 0x1f, 16, insert_raq, extract_raq, PPC_OPERAND_GPR_0 },
/* Similar to above, but optional. */
#define PRAQ RAQ + 1
{ 0x1f, 16, insert_raq, extract_raq,
PPC_OPERAND_GPR_0 | PPC_OPERAND_OPTIONAL },
/* The R field in an 8-byte D, DS, DQ or X form prefix instruction. */
#define PCREL PRAQ + 1
#define PCREL_MASK (1ULL << 52)
{ 0x1, 52, insert_pcrel, extract_pcrel, PPC_OPERAND_OPTIONAL },
#define PCREL0 PCREL + 1
{ 0x1, 52, insert_pcrel, extract_pcrel0, PPC_OPERAND_OPTIONAL },
/* The RA field in a D or X form instruction which is an updating
load, which means that the RA field may not be zero and may not
equal the RT field. */
#define RAL RAQ + 1
#define RAL PCREL0 + 1
{ 0x1f, 16, insert_ral, extract_ral, PPC_OPERAND_GPR_0 },
/* The RA field in an lmw instruction, which has special value
@ -2651,8 +2789,12 @@ const struct powerpc_operand powerpc_operands[] =
#define XTQ6 XSQ6
{ 0x3f, PPC_OPSHIFT_INV, insert_xtq6, extract_xtq6, PPC_OPERAND_VSR },
/* The XT field in a plxv instruction. Runs into the OP field. */
#define XTOP XSQ6 + 1
{ 0x3f, 21, NULL, NULL, PPC_OPERAND_VSR },
/* The XA field in an XX3 form instruction. This is split. */
#define XA6 XTQ6 + 1
#define XA6 XTOP + 1
{ 0x3f, PPC_OPSHIFT_INV, insert_xa6, extract_xa6, PPC_OPERAND_VSR },
/* The XB field in an XX2 or XX3 form instruction. This is split. */
@ -2730,9 +2872,21 @@ const unsigned int num_powerpc_operands = (sizeof (powerpc_operands)
#define SUFFIX_MASK ((1ULL << 32) - 1)
#define PREFIX_MASK (SUFFIX_MASK << 32)
/* Prefix insn, eight byte load/store form 8LS. */
#define P8LS (PREFIX_OP | PREFIX_FORM (0))
/* Prefix insn, modified load/store form MLS. */
#define PMLS (PREFIX_OP | PREFIX_FORM (2))
/* Prefix insn, modified register to register form MRR. */
#define PMRR (PREFIX_OP | PREFIX_FORM (3))
/* An 8-byte D form prefix instruction. */
#define P_D_MASK (((-1ULL << 50) & ~PCREL_MASK) | OP_MASK)
/* The same as P_D_MASK, but with the RA and PCREL fields specified. */
#define P_DRAPCREL_MASK (P_D_MASK | PCREL_MASK | RA_MASK)
/* The main opcode combined with a trap code in the TO field of a D
form instruction. Used for extended mnemonics for the trap
instructions. */
@ -7815,6 +7969,32 @@ const unsigned int powerpc_num_opcodes =
const struct powerpc_opcode prefix_opcodes[] = {
{"pnop", PMRR, PREFIX_MASK, POWERXX, 0, {0}},
{"pli", PMLS|OP(14), P_DRAPCREL_MASK, POWERXX, 0, {RT, SI34}},
{"paddi", PMLS|OP(14), P_D_MASK, POWERXX, 0, {RT, RA0, SI34, PCREL0}},
{"psubi", PMLS|OP(14), P_D_MASK, POWERXX, 0, {RT, RA0, NSI34, PCREL0}},
{"pla", PMLS|OP(14), P_D_MASK, POWERXX, 0, {RT, D34, PRA0, PCREL}},
{"plwz", PMLS|OP(32), P_D_MASK, POWERXX, 0, {RT, D34, PRA0, PCREL}},
{"plbz", PMLS|OP(34), P_D_MASK, POWERXX, 0, {RT, D34, PRA0, PCREL}},
{"pstw", PMLS|OP(36), P_D_MASK, POWERXX, 0, {RS, D34, PRA0, PCREL}},
{"pstb", PMLS|OP(38), P_D_MASK, POWERXX, 0, {RS, D34, PRA0, PCREL}},
{"plhz", PMLS|OP(40), P_D_MASK, POWERXX, 0, {RT, D34, PRA0, PCREL}},
{"plwa", P8LS|OP(41), P_D_MASK, POWERXX, 0, {RT, D34, PRA0, PCREL}},
{"plxsd", P8LS|OP(42), P_D_MASK, POWERXX, 0, {VD, D34, PRA0, PCREL}},
{"plha", PMLS|OP(42), P_D_MASK, POWERXX, 0, {RT, D34, PRA0, PCREL}},
{"plxssp", P8LS|OP(43), P_D_MASK, POWERXX, 0, {VD, D34, PRA0, PCREL}},
{"psth", PMLS|OP(44), P_D_MASK, POWERXX, 0, {RS, D34, PRA0, PCREL}},
{"pstxsd", P8LS|OP(46), P_D_MASK, POWERXX, 0, {VS, D34, PRA0, PCREL}},
{"pstxssp", P8LS|OP(47), P_D_MASK, POWERXX, 0, {VS, D34, PRA0, PCREL}},
{"plfs", PMLS|OP(48), P_D_MASK, POWERXX, 0, {FRT, D34, PRA0, PCREL}},
{"plxv", P8LS|OP(50), P_D_MASK&~OP(1), POWERXX, 0, {XTOP, D34, PRA0, PCREL}},
{"plfd", PMLS|OP(50), P_D_MASK, POWERXX, 0, {FRT, D34, PRA0, PCREL}},
{"pstfs", PMLS|OP(52), P_D_MASK, POWERXX, 0, {FRS, D34, PRA0, PCREL}},
{"pstxv", P8LS|OP(54), P_D_MASK&~OP(1), POWERXX, 0, {XTOP, D34, PRA0, PCREL}},
{"pstfd", PMLS|OP(54), P_D_MASK, POWERXX, 0, {FRS, D34, PRA0, PCREL}},
{"plq", P8LS|OP(56), P_D_MASK, POWERXX, 0, {RTQ, D34, PRAQ, PCREL}},
{"pld", P8LS|OP(57), P_D_MASK, POWERXX, 0, {RT, D34, PRA0, PCREL}},
{"pstq", P8LS|OP(60), P_D_MASK, POWERXX, 0, {RSQ, D34, PRA0, PCREL}},
{"pstd", P8LS|OP(61), P_D_MASK, POWERXX, 0, {RS, D34, PRA0, PCREL}},
};
const unsigned int prefix_num_opcodes =