ppc64/ppc64asm: fix objdump tests

In short, these tests create an object file from a list of opcodes,
and expect objdump to generate exactly as many decoded opcodes.

Unfortunately, objdump generates two opcode entries for each invalid
prefixed instruction, which causes the the testing code to deadlock
itself.

For example, objdump decodes an invalid form of paddi like:

    .long ...
    addi ...

instead of something like:

    .quadword ...

Work around this by examing the primary opcode of any entry which
objdump reports as ".long", and skip over the next word if the
primary opcode is "1" (the prefix opcode). The test skips over
".long" entries, so it will continue to work as expected.

Change-Id: I9dd0fda10683f666aace4140b63e81fc0fea2ad0
Reviewed-on: https://go-review.googlesource.com/c/arch/+/418857
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
diff --git a/ppc64/ppc64asm/ext_test.go b/ppc64/ppc64asm/ext_test.go
index f9242e1..806701b 100644
--- a/ppc64/ppc64asm/ext_test.go
+++ b/ppc64/ppc64asm/ext_test.go
@@ -40,7 +40,7 @@
 // from an external disassembler's output.
 type ExtInst struct {
 	addr uint32
-	enc  [4]byte
+	enc  [8]byte
 	nenc int
 	text string
 }
@@ -200,20 +200,25 @@
 	defer w.Flush()
 	size = 0
 	generate(func(x []byte) {
-		if len(x) > 4 {
-			x = x[:4]
+		if len(x) != 4 && len(x) != 8 {
+			panic(fmt.Sprintf("Unexpected instruction %v\n", x))
+		}
+		izeros := zeros
+		if len(x) == 4 {
+			// Only pad to 4 bytes for a 4 byte instruction word.
+			izeros = izeros[4:]
 		}
 		if debug {
-			fmt.Printf("%#x: %x%x\n", start+size, x, zeros[len(x):])
+			fmt.Printf("%#x: %x%x\n", start+size, x, izeros[len(x):])
 		}
 		w.Write(x)
-		w.Write(zeros[len(x):])
-		size += len(zeros)
+		w.Write(izeros[len(x):])
+		size += len(izeros)
 	})
 	return file, f, size, nil
 }
 
-var zeros = []byte{0, 0, 0, 0}
+var zeros = []byte{0, 0, 0, 0, 0, 0, 0, 0}
 
 // pad pads the code sequence with pops.
 func pad(enc []byte) []byte {
diff --git a/ppc64/ppc64asm/objdumpext_test.go b/ppc64/ppc64asm/objdumpext_test.go
index 37aa257..033f670 100644
--- a/ppc64/ppc64asm/objdumpext_test.go
+++ b/ppc64/ppc64asm/objdumpext_test.go
@@ -64,7 +64,7 @@
 		reading bool
 		next    uint32 = start
 		addr    uint32
-		encbuf  [4]byte
+		encbuf  [8]byte
 		enc     []byte
 		text    string
 	)
@@ -88,15 +88,19 @@
 				text = "error: unknown instruction"
 				enc = nil
 			}
-			if len(enc) == 4 {
-				// prints as word but we want to record bytes
-				enc[0], enc[3] = enc[3], enc[0]
-				enc[1], enc[2] = enc[2], enc[1]
+			// Prefixed instructions may not decode as expected if
+			// they are an invalid form. Some are tested in decode.txt.
+			// objdump treats these like two instructions.
+			//
+			// Look for primary opcode 1 and advance an exta 4 bytes if
+			// this failed to decode.
+			if strings.HasPrefix(text, ".long") && enc[0]>>2 == 1 {
+				next += 4
 			}
 			ext.Dec <- ExtInst{addr, encbuf, len(enc), text}
-			encbuf = [4]byte{}
+			encbuf = [8]byte{}
+			next += uint32(len(enc))
 			enc = nil
-			next += 4
 		}
 	}
 	var textangle = []byte("<.text>:")