PowerPC D-form prefixed loads and stores
authorPeter Bergner <bergner@linux.ibm.com>
Sat, 28 Jul 2018 03:21:43 +0000 (22:21 -0500)
committerAlan Modra <amodra@gmail.com>
Fri, 24 May 2019 00:57:49 +0000 (10:27 +0930)
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.

gas/ChangeLog
gas/config/tc-ppc.c
gas/messages.c
gas/testsuite/gas/ppc/ppc.exp
gas/testsuite/gas/ppc/prefix-pcrel.d [new file with mode: 0644]
gas/testsuite/gas/ppc/prefix-pcrel.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/ppc-opc.c

index a747a9874fb9cd5d1e55b548d440753a9e54fd75..2d05746753fbad9a0453232f11cb007be50f362b 100644 (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>
 
index 4abb5b8a31c5b73b4a0c4b2be183988342bec037..4026c722939dd992ddbff29fe169ba62feebb502 100644 (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)
index 95471a6befac89ef9bcef86e15e692e1fd008a50..b7d82f595dc7da38b5a301039b2b88c680b4babe 100644 (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
     {
index 6be042bf26ce6586aed279caa0cddec2b8353236..aa199d5e85ea7f3f10b85d0411f9b7395309b759 100644 (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"
diff --git a/gas/testsuite/gas/ppc/prefix-pcrel.d b/gas/testsuite/gas/ppc/prefix-pcrel.d
new file mode 100644 (file)
index 0000000..a0ca60f
--- /dev/null
@@ -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
diff --git a/gas/testsuite/gas/ppc/prefix-pcrel.s b/gas/testsuite/gas/ppc/prefix-pcrel.s
new file mode 100644 (file)
index 0000000..c3831d8
--- /dev/null
@@ -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
index e46e1fb4670b42baabf5136444e47d2836bebbf7..949b04f2a51d239801bcb4288892df4e1ba43232 100644 (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>
 
index 7dc2d775d9873777bb77d34b4e9a659e77dc315e..aa7184230f518e7307c6edbe80f765615294cd8a 100644 (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 =