Commit 162de6b5 authored by Lynn Boger's avatar Lynn Boger

cmd/vendor: update to golang.org/x/arch@5a4828b

This updates master to fix the ppc64 objdump. There were many cases where
the Go objdump was generating opcodes that didn't exist in the Go assembler,
or generated operands in the wrong order. The goal is to generate a Go
objdump that is acceptable to the Go assembler, or as close as possible.

An additional change will be needed for the Go objdump tool to make
use of this.

Change-Id: Ie8d2d534e13b9a64852c99b4b864a9c08ed7e036
Reviewed-on: https://go-review.googlesource.com/c/152517Reviewed-by: 's avatarCarlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Reviewed-by: 's avatarCherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent cd47e894
......@@ -172,7 +172,7 @@ func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) {
}
break
}
if inst.Op == 0 {
if inst.Op == 0 && inst.Enc != 0 {
return inst, errUnknown
}
return inst, nil
......
......@@ -50,8 +50,8 @@ func TestDecode(t *testing.T) {
switch syntax {
case "gnu":
out = GNUSyntax(inst)
//case "plan9":
// out = GoSyntax(inst, 0, nil, nil)
case "plan9":
out = GoSyntax(inst, 0, nil)
default:
t.Errorf("unknown syntax %q", syntax)
continue
......
......@@ -14,8 +14,12 @@ import (
// This form typically matches the syntax defined in the Power ISA Reference Manual.
func GNUSyntax(inst Inst) string {
var buf bytes.Buffer
if inst.Op == 0 {
return "error: unkown instruction"
// When there are all 0s, identify them as the disassembler
// in binutils would.
if inst.Enc == 0 {
return ".long 0x0"
} else if inst.Op == 0 {
return "error: unknown instruction"
}
buf.WriteString(inst.Op.String())
sep := " "
......
......@@ -49,11 +49,11 @@ func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool
switch inst.Op {
case BC, BCA, BL, BLA, BCL, BCLA, TDI, TWI, TW, TD:
return true // TODO(minux): we lack the support for extended opcodes here
case RLWNM, RLWNM_, RLDICL, RLDICL_, RLWINM, RLWINM_, RLDCL, RLDCL_:
case RLWNM, RLWNMCC, RLDICL, RLDICLCC, RLWINM, RLWINMCC, RLDCL, RLDCLCC:
return true // TODO(minux): we lack the support for extended opcodes here
case DCBTST, DCBT:
return true // objdump uses the embedded argument order, we use the server argument order
case MTFSF, MTFSF_: // objdump doesn't show the last two arguments
case MTFSF, MTFSFCC: // objdump doesn't show the last two arguments
return true
case VSPLTB, VSPLTH, VSPLTW: // objdump generates unreasonable result "vspltw v6,v19,4" for 10c49a8c, the last 4 should be 0.
return true
......
......@@ -19,7 +19,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
if symname == nil {
symname = func(uint64) (string, uint64) { return "", 0 }
}
if inst.Op == 0 {
if inst.Op == 0 && inst.Enc == 0 {
return "WORD $0"
} else if inst.Op == 0 {
return "?"
}
var args []string
......@@ -28,13 +30,27 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
break
}
if s := plan9Arg(&inst, i, pc, a, symname); s != "" {
args = append(args, s)
// In the case for some BC instructions, a CondReg arg has
// both the CR and the branch condition encoded in its value.
// plan9Arg will return a string with the string representation
// of these values separated by a blank that will be treated
// as 2 args from this point on.
if strings.IndexByte(s, ' ') > 0 {
t := strings.Split(s, " ")
args = append(args, t[0])
args = append(args, t[1])
} else {
args = append(args, s)
}
}
}
var op string
op = plan9OpMap[inst.Op]
if op == "" {
op = strings.ToUpper(inst.Op.String())
if op[len(op)-1] == '.' {
op = op[:len(op)-1] + "CC"
}
}
// laid out the instruction
switch inst.Op {
......@@ -45,15 +61,60 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
return fmt.Sprintf("%s %s", op, args[0])
}
args = append(args, args[0])
return op + " " + strings.Join(args[1:], ", ")
return op + " " + strings.Join(args[1:], ",")
case SYNC:
if args[0] == "$1" {
return "LWSYNC"
}
return "HWSYNC"
case ISEL:
return "ISEL " + args[3] + "," + args[1] + "," + args[2] + "," + args[0]
// store instructions always have the memory operand at the end, no need to reorder
case STB, STBU, STBX, STBUX,
STH, STHU, STHX, STHUX,
STW, STWU, STWX, STWUX,
STD, STDU, STDX, STDUX,
STQ,
STHBRX, STWBRX:
return op + " " + strings.Join(args, ", ")
// indexed stores handled separately
case STB, STBU,
STH, STHU,
STW, STWU,
STD, STDU,
STQ:
return op + " " + strings.Join(args, ",")
case CMPD, CMPDI, CMPLD, CMPLDI, CMPW, CMPWI, CMPLW, CMPLWI:
if len(args) == 2 {
return op + " " + args[0] + "," + args[1]
} else if len(args) == 3 {
return op + " " + args[0] + "," + args[1] + "," + args[2]
}
return op + " " + args[0] + " ??"
case LIS:
return "ADDIS $0," + args[1] + "," + args[0]
// store instructions with index registers
case STBX, STBUX, STHX, STHUX, STWX, STWUX, STDX, STDUX,
STHBRX, STWBRX, STDBRX, STSWX, STFSX, STFSUX, STFDX, STFDUX, STFIWX, STFDPX:
return "MOV" + op[2:len(op)-1] + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")"
case STDCXCC, STWCXCC, STHCXCC, STBCXCC:
return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")"
case STXVD2X, STXVW4X:
return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")"
// load instructions with index registers
case LBZX, LBZUX, LHZX, LHZUX, LWZX, LWZUX, LDX, LDUX,
LHBRX, LWBRX, LDBRX, LSWX, LFSX, LFSUX, LFDX, LFDUX, LFIWAX, LFIWZX:
return "MOV" + op[1:len(op)-1] + " (" + args[2] + ")(" + args[1] + ")," + args[0]
case LDARX, LWARX, LHARX, LBARX:
return op + " (" + args[2] + ")(" + args[1] + ")," + args[0]
case LXVD2X, LXVW4X:
return op + " (" + args[2] + ")(" + args[1] + ")," + args[0]
case DCBT, DCBTST, DCBZ, DCBST:
return op + " (" + args[1] + ")"
// branch instructions needs additional handling
case BCLR:
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
......@@ -62,11 +123,17 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
return op + " " + strings.Join(args, ", ")
case BC:
if int(inst.Args[0].(Imm))&0x1c == 12 { // jump on cond bit set
if len(args) == 4 {
return fmt.Sprintf("B%s %s,%s", args[1], args[2], args[3])
}
return fmt.Sprintf("B%s %s", args[1], args[2])
} else if int(inst.Args[0].(Imm))&0x1c == 4 && revCondMap[args[1]] != "" { // jump on cond bit not set
if len(args) == 4 {
return fmt.Sprintf("B%s %s,%s", revCondMap[args[1]], args[2], args[3])
}
return fmt.Sprintf("B%s %s", revCondMap[args[1]], args[2])
}
return op + " " + strings.Join(args, ", ")
return op + " " + strings.Join(args, ",")
case BCCTR:
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
return "BR (CTR)"
......@@ -76,9 +143,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
return "BL (CTR)"
}
return op + " " + strings.Join(args, ", ")
return op + " " + strings.Join(args, ",")
case BCA, BCL, BCLA, BCLRL, BCTAR, BCTARL:
return op + " " + strings.Join(args, ", ")
return op + " " + strings.Join(args, ",")
}
}
......@@ -102,6 +169,10 @@ func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64)
}
return strings.ToUpper(arg.String())
case CondReg:
// This op is left as its numerical value, not mapped onto CR + condition
if inst.Op == ISEL {
return fmt.Sprintf("$%d", (arg - Cond0LT))
}
if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
return "" // don't show cr0 for cmp instructions
} else if arg >= CR0 {
......@@ -111,7 +182,7 @@ func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64)
if arg <= Cond0SO {
return bit
}
return fmt.Sprintf("4*CR%d+%s", int(arg-Cond0LT)/4, bit)
return fmt.Sprintf("%s CR%d", bit, int(arg-Cond0LT)/4)
case Imm:
return fmt.Sprintf("$%d", arg)
case SpReg:
......@@ -148,25 +219,27 @@ var revCondMap = map[string]string{
// plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics.
var plan9OpMap = map[Op]string{
LWARX: "LWAR", STWCX_: "STWCCC",
LDARX: "LDAR", STDCX_: "STDCCC",
LHARX: "LHAR", STHCX_: "STHCCC",
LBARX: "LBAR", STBCX_: "STBCCC",
ADDI: "ADD",
ADD_: "ADDCC",
LBZ: "MOVBZ", STB: "MOVB",
LBZU: "MOVBZU", STBU: "MOVBU", // TODO(minux): indexed forms are not handled
LWARX: "LWAR",
LDARX: "LDAR",
LHARX: "LHAR",
LBARX: "LBAR",
ADDI: "ADD",
SRADI: "SRAD",
SUBF: "SUB",
LI: "MOVD",
LBZ: "MOVBZ", STB: "MOVB",
LBZU: "MOVBZU", STBU: "MOVBU",
LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH",
LHZU: "MOVHZU", STHU: "MOVHU",
LI: "MOVD",
LIS: "ADDIS",
LWZ: "MOVWZ", LWA: "MOVW", STW: "MOVW",
LWZU: "MOVWZU", STWU: "MOVWU",
LD: "MOVD", STD: "MOVD",
LDU: "MOVDU", STDU: "MOVDU",
CMPD: "CMP", CMPDI: "CMP",
CMPW: "CMPW", CMPWI: "CMPW",
CMPLD: "CMPU", CMPLDI: "CMPU",
CMPLW: "CMPWU", CMPLWI: "CMPWU",
MTSPR: "MOVD", MFSPR: "MOVD", // the width is ambiguous for SPRs
B: "BR",
BL: "CALL",
CMPLD: "CMPU", CMPLW: "CMPWU",
CMPD: "CMP", CMPW: "CMPW",
B: "BR",
BL: "CALL",
}
This source diff could not be displayed because it is too large. You can view the blob instead.
6d746162| gnu xoris r20,r11,24930
6d746162| plan9 XORIS R11,$24930,R20
4c040000| gnu mcrf cr0,cr1
88000017| gnu lbz r0,23(0)
4abaa88a| gnu ba 0xfebaa888
7d8fc2a6| gnu mfspr r12,783
00000000| gnu error: unknown instruction
88a70002| gnu lbz r5,2(r7)
88a70002| plan9 MOVBZ 2(R7),R5
00000000| plan9 WORD $0
00010000| plan9 error: unknown instruction
00000000| gnu .long 0x0
00002000| gnu error: unknown instruction
a1841e80| gnu lhz r12,7808(r4)
a1841e80| plan9 MOVHZ 7808(R4),R12
42093d10| gnu bc 16,4*cr2+gt,.+0x3d10
e38d5b90| gnu lq r28,23440(r13)
84127a20| gnu lwzu r0,31264(r18)
c61bb730| gnu lfsu f16,-18640(r27)
0825f440| gnu tdi 1,r5,-3008
a9a912c1| gnu lha r13,4801(r9)
84127a20| plan9 MOVWZU 31264(R18),R0
a8630000| gnu lha r3,0(r3)
a8630000| plan9 MOVH 0(R3),R3
ebb24fd1| gnu ldu r29,20432(r18)
ebb24fd1| plan9 MOVDU 20432(R18),R29
b1ce0612| gnu sth r14,1554(r14)
f3c04322| gnu xvcvdpuxws vs30,vs40
b1ce0612| plan9 MOVH R14,1554(R14)
945c62a2| gnu stwu r2,25250(r28)
9c8156e3| gnu stbu r4,22243(r1)
f91b9c7a| gnu stq r8,-25480(r27)
2c1c81b4| gnu cmpwi r28,-32332
f87b904d| gnu stdu r3,-28596(r27)
eab3c832| gnu lwa r21,-14288(r19)
2c030001| gnu cmpwi r3,1
2c030001| plan9 CMPW R3,$1
e8610032| gnu lwa r3,48(r1)
e8610032| plan9 MOVW 48(R1),R3
4320336b| gnu bcla 25,lt,0x3368
7e40092e| gnu stwx r18,0,r1
7e40092e| plan9 MOVW R18,(R1)(0)
7c103c2c| gnu lwbrx r0,r16,r7
7c103c2c| plan9 MOVWBR (R7)(R16),R0
7c441d28| gnu stdbrx r2,r4,r3
7c441d28| plan9 MOVDBR R2,(R3)(R4)
3d220001| gnu addis r9,r2,1
3d220001| plan9 ADDIS R2,$1,R9
7ce628ae| gnu lbzx r7,r6,r5
7ce628ae| plan9 MOVBZ (R5)(R6),R7
7c0e1e99| gnu lxvd2x vs32,r14,r3
7c0e1e99| plan9 LXVD2X (R3)(R14),VS32
7c00422c| gnu dcbt r0,r8,0
7c00422c| plan9 DCBT (R8)
7fab3040| gnu cmpld cr7,r11,r6
7fab3040| plan9 CMPU CR7,R11,R6
2c030001| gnu cmpwi r3,1
2c030001| plan9 CMPW R3,$1
7c2b4840| gnu cmpld r11,r9
7c2b4840| plan9 CMPU R11,R9
7c6521ad| gnu stdcx. r3,r5,r4
7c6521ad| plan9 STDCXCC R3,(R4)(R5)
fbe1ffd1| gnu stdu r31,-48(r1)
fbe1ffd1| plan9 MOVDU R31,-48(R1)
7c941f19| gnu stxvw4x vs36,r20,r3
7c941f19| plan9 STXVW4X VS36,(R3)(R20)
7c6520a8| gnu ldarx r3,r5,r4
7c6520a8| plan9 LDAR (R4)(R5),R3
......@@ -116,8 +116,8 @@
},
{
"path": "golang.org/x/arch/ppc64/ppc64asm",
"revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6",
"revisionTime": "2018-04-06T10:28:20Z"
"revision": "5a4828bb704534b8a2fa09c791c67d0fb372f472",
"revisionTime": "2018-12-03T22:54:21Z"
},
{
"path": "golang.org/x/arch/x86/x86asm",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment