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) { ...@@ -172,7 +172,7 @@ func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) {
} }
break break
} }
if inst.Op == 0 { if inst.Op == 0 && inst.Enc != 0 {
return inst, errUnknown return inst, errUnknown
} }
return inst, nil return inst, nil
......
...@@ -50,8 +50,8 @@ func TestDecode(t *testing.T) { ...@@ -50,8 +50,8 @@ func TestDecode(t *testing.T) {
switch syntax { switch syntax {
case "gnu": case "gnu":
out = GNUSyntax(inst) out = GNUSyntax(inst)
//case "plan9": case "plan9":
// out = GoSyntax(inst, 0, nil, nil) out = GoSyntax(inst, 0, nil)
default: default:
t.Errorf("unknown syntax %q", syntax) t.Errorf("unknown syntax %q", syntax)
continue continue
......
...@@ -14,8 +14,12 @@ import ( ...@@ -14,8 +14,12 @@ import (
// This form typically matches the syntax defined in the Power ISA Reference Manual. // This form typically matches the syntax defined in the Power ISA Reference Manual.
func GNUSyntax(inst Inst) string { func GNUSyntax(inst Inst) string {
var buf bytes.Buffer var buf bytes.Buffer
if inst.Op == 0 { // When there are all 0s, identify them as the disassembler
return "error: unkown instruction" // in binutils would.
if inst.Enc == 0 {
return ".long 0x0"
} else if inst.Op == 0 {
return "error: unknown instruction"
} }
buf.WriteString(inst.Op.String()) buf.WriteString(inst.Op.String())
sep := " " sep := " "
......
...@@ -49,11 +49,11 @@ func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool ...@@ -49,11 +49,11 @@ func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool
switch inst.Op { switch inst.Op {
case BC, BCA, BL, BLA, BCL, BCLA, TDI, TWI, TW, TD: case BC, BCA, BL, BLA, BCL, BCLA, TDI, TWI, TW, TD:
return true // TODO(minux): we lack the support for extended opcodes here 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 return true // TODO(minux): we lack the support for extended opcodes here
case DCBTST, DCBT: case DCBTST, DCBT:
return true // objdump uses the embedded argument order, we use the server argument order 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 return true
case VSPLTB, VSPLTH, VSPLTW: // objdump generates unreasonable result "vspltw v6,v19,4" for 10c49a8c, the last 4 should be 0. case VSPLTB, VSPLTH, VSPLTW: // objdump generates unreasonable result "vspltw v6,v19,4" for 10c49a8c, the last 4 should be 0.
return true return true
......
...@@ -19,7 +19,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin ...@@ -19,7 +19,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
if symname == nil { if symname == nil {
symname = func(uint64) (string, uint64) { return "", 0 } 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 "?" return "?"
} }
var args []string var args []string
...@@ -28,13 +30,27 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin ...@@ -28,13 +30,27 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
break break
} }
if s := plan9Arg(&inst, i, pc, a, symname); s != "" { 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 var op string
op = plan9OpMap[inst.Op] op = plan9OpMap[inst.Op]
if op == "" { if op == "" {
op = strings.ToUpper(inst.Op.String()) op = strings.ToUpper(inst.Op.String())
if op[len(op)-1] == '.' {
op = op[:len(op)-1] + "CC"
}
} }
// laid out the instruction // laid out the instruction
switch inst.Op { switch inst.Op {
...@@ -45,15 +61,60 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin ...@@ -45,15 +61,60 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
return fmt.Sprintf("%s %s", op, args[0]) return fmt.Sprintf("%s %s", op, args[0])
} }
args = append(args, 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 // store instructions always have the memory operand at the end, no need to reorder
case STB, STBU, STBX, STBUX, // indexed stores handled separately
STH, STHU, STHX, STHUX, case STB, STBU,
STW, STWU, STWX, STWUX, STH, STHU,
STD, STDU, STDX, STDUX, STW, STWU,
STQ, STD, STDU,
STHBRX, STWBRX: STQ:
return op + " " + strings.Join(args, ", ") 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 // branch instructions needs additional handling
case BCLR: case BCLR:
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional 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 ...@@ -62,11 +123,17 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
return op + " " + strings.Join(args, ", ") return op + " " + strings.Join(args, ", ")
case BC: case BC:
if int(inst.Args[0].(Imm))&0x1c == 12 { // jump on cond bit set 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]) 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 } 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 fmt.Sprintf("B%s %s", revCondMap[args[1]], args[2])
} }
return op + " " + strings.Join(args, ", ") return op + " " + strings.Join(args, ",")
case BCCTR: case BCCTR:
if int(inst.Args[0].(Imm))&20 == 20 { // unconditional if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
return "BR (CTR)" return "BR (CTR)"
...@@ -76,9 +143,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin ...@@ -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 if int(inst.Args[0].(Imm))&20 == 20 { // unconditional
return "BL (CTR)" return "BL (CTR)"
} }
return op + " " + strings.Join(args, ", ") return op + " " + strings.Join(args, ",")
case BCA, BCL, BCLA, BCLRL, BCTAR, BCTARL: 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) ...@@ -102,6 +169,10 @@ func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64)
} }
return strings.ToUpper(arg.String()) return strings.ToUpper(arg.String())
case CondReg: 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") { if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
return "" // don't show cr0 for cmp instructions return "" // don't show cr0 for cmp instructions
} else if arg >= CR0 { } else if arg >= CR0 {
...@@ -111,7 +182,7 @@ func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64) ...@@ -111,7 +182,7 @@ func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64)
if arg <= Cond0SO { if arg <= Cond0SO {
return bit 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: case Imm:
return fmt.Sprintf("$%d", arg) return fmt.Sprintf("$%d", arg)
case SpReg: case SpReg:
...@@ -148,25 +219,27 @@ var revCondMap = map[string]string{ ...@@ -148,25 +219,27 @@ var revCondMap = map[string]string{
// plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics. // plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics.
var plan9OpMap = map[Op]string{ var plan9OpMap = map[Op]string{
LWARX: "LWAR", STWCX_: "STWCCC", LWARX: "LWAR",
LDARX: "LDAR", STDCX_: "STDCCC", LDARX: "LDAR",
LHARX: "LHAR", STHCX_: "STHCCC", LHARX: "LHAR",
LBARX: "LBAR", STBCX_: "STBCCC", LBARX: "LBAR",
ADDI: "ADD", ADDI: "ADD",
ADD_: "ADDCC", SRADI: "SRAD",
LBZ: "MOVBZ", STB: "MOVB", SUBF: "SUB",
LBZU: "MOVBZU", STBU: "MOVBU", // TODO(minux): indexed forms are not handled LI: "MOVD",
LBZ: "MOVBZ", STB: "MOVB",
LBZU: "MOVBZU", STBU: "MOVBU",
LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH", LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH",
LHZU: "MOVHZU", STHU: "MOVHU", LHZU: "MOVHZU", STHU: "MOVHU",
LI: "MOVD",
LIS: "ADDIS",
LWZ: "MOVWZ", LWA: "MOVW", STW: "MOVW", LWZ: "MOVWZ", LWA: "MOVW", STW: "MOVW",
LWZU: "MOVWZU", STWU: "MOVWU", LWZU: "MOVWZU", STWU: "MOVWU",
LD: "MOVD", STD: "MOVD", LD: "MOVD", STD: "MOVD",
LDU: "MOVDU", STDU: "MOVDU", 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 MTSPR: "MOVD", MFSPR: "MOVD", // the width is ambiguous for SPRs
B: "BR", B: "BR",
BL: "CALL", BL: "CALL",
CMPLD: "CMPU", CMPLW: "CMPWU",
CMPD: "CMP", CMPW: "CMPW",
} }
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| gnu xoris r20,r11,24930
6d746162| plan9 XORIS R11,$24930,R20
4c040000| gnu mcrf cr0,cr1 4c040000| gnu mcrf cr0,cr1
88000017| gnu lbz r0,23(0) 88a70002| gnu lbz r5,2(r7)
4abaa88a| gnu ba 0xfebaa888 88a70002| plan9 MOVBZ 2(R7),R5
7d8fc2a6| gnu mfspr r12,783 00000000| plan9 WORD $0
00000000| gnu error: unknown instruction 00010000| plan9 error: unknown instruction
00000000| gnu .long 0x0
00002000| gnu error: unknown instruction
a1841e80| gnu lhz r12,7808(r4) a1841e80| gnu lhz r12,7808(r4)
a1841e80| plan9 MOVHZ 7808(R4),R12
42093d10| gnu bc 16,4*cr2+gt,.+0x3d10 42093d10| gnu bc 16,4*cr2+gt,.+0x3d10
e38d5b90| gnu lq r28,23440(r13) e38d5b90| gnu lq r28,23440(r13)
84127a20| gnu lwzu r0,31264(r18) 84127a20| gnu lwzu r0,31264(r18)
c61bb730| gnu lfsu f16,-18640(r27) 84127a20| plan9 MOVWZU 31264(R18),R0
0825f440| gnu tdi 1,r5,-3008 a8630000| gnu lha r3,0(r3)
a9a912c1| gnu lha r13,4801(r9) a8630000| plan9 MOVH 0(R3),R3
ebb24fd1| gnu ldu r29,20432(r18) ebb24fd1| gnu ldu r29,20432(r18)
ebb24fd1| plan9 MOVDU 20432(R18),R29
b1ce0612| gnu sth r14,1554(r14) b1ce0612| gnu sth r14,1554(r14)
f3c04322| gnu xvcvdpuxws vs30,vs40 b1ce0612| plan9 MOVH R14,1554(R14)
945c62a2| gnu stwu r2,25250(r28) 945c62a2| gnu stwu r2,25250(r28)
9c8156e3| gnu stbu r4,22243(r1)
f91b9c7a| gnu stq r8,-25480(r27) f91b9c7a| gnu stq r8,-25480(r27)
2c1c81b4| gnu cmpwi r28,-32332 2c030001| gnu cmpwi r3,1
f87b904d| gnu stdu r3,-28596(r27) 2c030001| plan9 CMPW R3,$1
eab3c832| gnu lwa r21,-14288(r19) e8610032| gnu lwa r3,48(r1)
e8610032| plan9 MOVW 48(R1),R3
4320336b| gnu bcla 25,lt,0x3368 4320336b| gnu bcla 25,lt,0x3368
7e40092e| gnu stwx r18,0,r1 7e40092e| gnu stwx r18,0,r1
7e40092e| plan9 MOVW R18,(R1)(0)
7c103c2c| gnu lwbrx r0,r16,r7 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 @@ ...@@ -116,8 +116,8 @@
}, },
{ {
"path": "golang.org/x/arch/ppc64/ppc64asm", "path": "golang.org/x/arch/ppc64/ppc64asm",
"revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6", "revision": "5a4828bb704534b8a2fa09c791c67d0fb372f472",
"revisionTime": "2018-04-06T10:28:20Z" "revisionTime": "2018-12-03T22:54:21Z"
}, },
{ {
"path": "golang.org/x/arch/x86/x86asm", "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