From 8acf14351c818d956babe50e61711740f378c941 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Fri, 27 Jul 2018 22:21:43 -0500 Subject: [PATCH] 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 ): 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. --- gas/ChangeLog | 11 ++ gas/config/tc-ppc.c | 5 +- gas/messages.c | 18 +- gas/testsuite/gas/ppc/ppc.exp | 1 + gas/testsuite/gas/ppc/prefix-pcrel.d | 235 +++++++++++++++++++++++++++ gas/testsuite/gas/ppc/prefix-pcrel.s | 121 ++++++++++++++ opcodes/ChangeLog | 13 ++ opcodes/ppc-opc.c | 188 ++++++++++++++++++++- 8 files changed, 577 insertions(+), 15 deletions(-) create mode 100644 gas/testsuite/gas/ppc/prefix-pcrel.d create mode 100644 gas/testsuite/gas/ppc/prefix-pcrel.s diff --git a/gas/ChangeLog b/gas/ChangeLog index a747a9874fb..2d05746753f 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2019-05-24 Peter Bergner + Alan Modra + + * 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 Alan Modra diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 4abb5b8a31c..4026c722939 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -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) diff --git a/gas/messages.c b/gas/messages.c index 95471a6befa..b7d82f595dc 100644 --- a/gas/messages.c +++ b/gas/messages.c @@ -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 { diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp index 6be042bf26c..aa199d5e85e 100644 --- a/gas/testsuite/gas/ppc/ppc.exp +++ b/gas/testsuite/gas/ppc/ppc.exp @@ -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" diff --git a/gas/testsuite/gas/ppc/prefix-pcrel.d b/gas/testsuite/gas/ppc/prefix-pcrel.d new file mode 100644 index 00000000000..a0ca60fa548 --- /dev/null +++ b/gas/testsuite/gas/ppc/prefix-pcrel.d @@ -0,0 +1,235 @@ +#as: -mfuture +#objdump: -dr -Mfuture +#name: POWERXX pcrel tests + +.* + + +Disassembly of section \.text: + +0+00 : +.*: (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 diff --git a/gas/testsuite/gas/ppc/prefix-pcrel.s b/gas/testsuite/gas/ppc/prefix-pcrel.s new file mode 100644 index 00000000000..c3831d8a2c3 --- /dev/null +++ b/gas/testsuite/gas/ppc/prefix-pcrel.s @@ -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 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index e46e1fb4670..949b04f2a51 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,16 @@ +2019-05-24 Peter Bergner + Alan Modra + + * 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 ): 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 Alan Modra diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 7dc2d775d98..aa7184230f5 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -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 = -- 2.30.2