Commit 1f5a0e8c authored by fanzha02's avatar fanzha02 Committed by Brad Fitzpatrick

cmd/vendor/golang.org/x/arch: pull updates from x repo

Vendor from golang.org/x/arch repo.  Pull in commits that update
arm64, arm, ppc64 and x86 directories (the latest commit 9111c30).

Change-Id: I2b4b3ea9662e69bcf0eeee9c6aba0118175524df
Reviewed-on: https://go-review.googlesource.com/107695
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent c2a53b1b
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"encoding/hex" "encoding/hex"
"flag" "flag"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"math/rand" "math/rand"
...@@ -196,7 +197,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, ...@@ -196,7 +197,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name() file = f.Name()
f.Seek(start, 0) f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f) w := bufio.NewWriter(f)
defer w.Flush() defer w.Flush()
size = 0 size = 0
......
...@@ -192,7 +192,7 @@ func parseContinuation(line []byte, enc []byte) []byte { ...@@ -192,7 +192,7 @@ func parseContinuation(line []byte, enc []byte) []byte {
// describing a text segment that starts at start // describing a text segment that starts at start
// and extends for size bytes. // and extends for size bytes.
func writeELF32(f *os.File, size int) error { func writeELF32(f *os.File, size int) error {
f.Seek(0, 0) f.Seek(0, io.SeekStart)
var hdr elf.Header32 var hdr elf.Header32
var prog elf.Prog32 var prog elf.Prog32
var sect elf.Section32 var sect elf.Section32
......
...@@ -96,34 +96,24 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -96,34 +96,24 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
// Move addressing mode into opcode suffix. // Move addressing mode into opcode suffix.
suffix := "" suffix := ""
switch inst.Op &^ 15 { switch inst.Op &^ 15 {
case LDR_EQ, LDRB_EQ, LDRSB_EQ, LDRH_EQ, LDRSH_EQ, STR_EQ, STRB_EQ, STRH_EQ, VLDR_EQ, VSTR_EQ: case PLD, PLI, PLD_W:
mem, _ := inst.Args[1].(Mem) if mem, ok := inst.Args[0].(Mem); ok {
switch mem.Mode { args[0], suffix = memOpTrans(mem)
case AddrOffset, AddrLDM: } else {
// no suffix panic(fmt.Sprintf("illegal instruction: %v", inst))
case AddrPreIndex, AddrLDM_WB:
suffix = ".W"
case AddrPostIndex:
suffix = ".P"
} }
off := "" case LDR_EQ, LDRB_EQ, LDRSB_EQ, LDRH_EQ, LDRSH_EQ, STR_EQ, STRB_EQ, STRH_EQ, VLDR_EQ, VSTR_EQ, LDREX_EQ, LDREXH_EQ, LDREXB_EQ:
if mem.Offset != 0 { if mem, ok := inst.Args[1].(Mem); ok {
off = fmt.Sprintf("%#x", mem.Offset) args[1], suffix = memOpTrans(mem)
} else {
panic(fmt.Sprintf("illegal instruction: %v", inst))
} }
base := fmt.Sprintf("(R%d)", int(mem.Base)) case SWP_EQ, SWP_B_EQ, STREX_EQ, STREXB_EQ, STREXH_EQ:
index := "" if mem, ok := inst.Args[2].(Mem); ok {
if mem.Sign != 0 { args[2], suffix = memOpTrans(mem)
sign := "" } else {
if mem.Sign < 0 { panic(fmt.Sprintf("illegal instruction: %v", inst))
suffix += ".U"
}
shift := ""
if mem.Count != 0 {
shift = fmt.Sprintf("%s%d", plan9Shift[mem.Shift], mem.Count)
}
index = fmt.Sprintf("(%sR%d%s)", sign, int(mem.Index), shift)
} }
args[1] = off + base + index
} }
// Reverse args, placing dest last. // Reverse args, placing dest last.
...@@ -135,35 +125,35 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -135,35 +125,35 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
case SMLAWT_EQ, SMLAWB_EQ, MLA_EQ, MLA_S_EQ, MLS_EQ, SMMLA_EQ, SMMLS_EQ, SMLABB_EQ, SMLATB_EQ, SMLABT_EQ, SMLATT_EQ, SMLAD_EQ, SMLAD_X_EQ, SMLSD_EQ, SMLSD_X_EQ: case SMLAWT_EQ, SMLAWB_EQ, MLA_EQ, MLA_S_EQ, MLS_EQ, SMMLA_EQ, SMMLS_EQ, SMLABB_EQ, SMLATB_EQ, SMLABT_EQ, SMLATT_EQ, SMLAD_EQ, SMLAD_X_EQ, SMLSD_EQ, SMLSD_X_EQ:
args = []string{args[1], args[2], args[0], args[3]} args = []string{args[1], args[2], args[0], args[3]}
} }
// For STREX like instructions, the memory operands comes first.
switch inst.Op &^ 15 {
case STREX_EQ, STREXB_EQ, STREXH_EQ, SWP_EQ, SWP_B_EQ:
args = []string{args[1], args[0], args[2]}
}
// special process for FP instructions
op, args = fpTrans(&inst, op, args)
// LDR/STR like instructions -> MOV like
switch inst.Op &^ 15 { switch inst.Op &^ 15 {
case MOV_EQ: case MOV_EQ:
op = "MOVW" + op[3:] op = "MOVW" + op[3:]
case LDR_EQ, MSR_EQ, MRS_EQ:
case LDR_EQ:
op = "MOVW" + op[3:] + suffix op = "MOVW" + op[3:] + suffix
case LDRB_EQ: case VMRS_EQ, VMSR_EQ:
op = "MOVW" + op[4:] + suffix
case LDRB_EQ, UXTB_EQ:
op = "MOVBU" + op[4:] + suffix op = "MOVBU" + op[4:] + suffix
case LDRSB_EQ: case LDRSB_EQ:
op = "MOVBS" + op[5:] + suffix op = "MOVBS" + op[5:] + suffix
case LDRH_EQ: case SXTB_EQ:
op = "MOVBS" + op[4:] + suffix
case LDRH_EQ, UXTH_EQ:
op = "MOVHU" + op[4:] + suffix op = "MOVHU" + op[4:] + suffix
case LDRSH_EQ: case LDRSH_EQ:
op = "MOVHS" + op[5:] + suffix op = "MOVHS" + op[5:] + suffix
case VLDR_EQ: case SXTH_EQ:
switch { op = "MOVHS" + op[4:] + suffix
case strings.HasPrefix(args[1], "D"): // VLDR.F64
op = "MOVD" + op[4:] + suffix
args[1] = "F" + args[1][1:] // Dx -> Fx
case strings.HasPrefix(args[1], "S"): // VLDR.F32
op = "MOVF" + op[4:] + suffix
if inst.Args[0].(Reg)&1 == 0 { // Sx -> Fy, y = x/2, if x is even
args[1] = fmt.Sprintf("F%d", (inst.Args[0].(Reg)-S0)/2)
}
default:
panic(fmt.Sprintf("wrong FP register: %v", inst))
}
case STR_EQ: case STR_EQ:
op = "MOVW" + op[3:] + suffix op = "MOVW" + op[3:] + suffix
args[0], args[1] = args[1], args[0] args[0], args[1] = args[1], args[0]
...@@ -174,19 +164,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -174,19 +164,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
op = "MOVH" + op[4:] + suffix op = "MOVH" + op[4:] + suffix
args[0], args[1] = args[1], args[0] args[0], args[1] = args[1], args[0]
case VSTR_EQ: case VSTR_EQ:
switch {
case strings.HasPrefix(args[1], "D"): // VSTR.F64
op = "MOVD" + op[4:] + suffix
args[1] = "F" + args[1][1:] // Dx -> Fx
case strings.HasPrefix(args[1], "S"): // VSTR.F32
op = "MOVF" + op[4:] + suffix
if inst.Args[0].(Reg)&1 == 0 { // Sx -> Fy, y = x/2, if x is even
args[1] = fmt.Sprintf("F%d", (inst.Args[0].(Reg)-S0)/2)
}
default:
panic(fmt.Sprintf("wrong FP register: %v", inst))
}
args[0], args[1] = args[1], args[0] args[0], args[1] = args[1], args[0]
default:
op = op + suffix
} }
if args != nil { if args != nil {
...@@ -266,3 +246,153 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg ...@@ -266,3 +246,153 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
} }
return strings.ToUpper(arg.String()) return strings.ToUpper(arg.String())
} }
// convert memory operand from GNU syntax to Plan 9 syntax, for example,
// [r5] -> (R5)
// [r6, #4080] -> 0xff0(R6)
// [r2, r0, ror #1] -> (R2)(R0@>1)
// inst [r2, -r0, ror #1] -> INST.U (R2)(R0@>1)
// input:
// a memory operand
// return values:
// corresponding memory operand in Plan 9 syntax
// .W/.P/.U suffix
func memOpTrans(mem Mem) (string, string) {
suffix := ""
switch mem.Mode {
case AddrOffset, AddrLDM:
// no suffix
case AddrPreIndex, AddrLDM_WB:
suffix = ".W"
case AddrPostIndex:
suffix = ".P"
}
off := ""
if mem.Offset != 0 {
off = fmt.Sprintf("%#x", mem.Offset)
}
base := fmt.Sprintf("(R%d)", int(mem.Base))
index := ""
if mem.Sign != 0 {
sign := ""
if mem.Sign < 0 {
suffix += ".U"
}
shift := ""
if mem.Count != 0 {
shift = fmt.Sprintf("%s%d", plan9Shift[mem.Shift], mem.Count)
}
index = fmt.Sprintf("(%sR%d%s)", sign, int(mem.Index), shift)
}
return off + base + index, suffix
}
type goFPInfo struct {
op Op
transArgs []int // indexes of arguments which need transformation
gnuName string // instruction name in GNU syntax
goName string // instruction name in Plan 9 syntax
}
var fpInst []goFPInfo = []goFPInfo{
{VADD_EQ_F32, []int{2, 1, 0}, "VADD", "ADDF"},
{VADD_EQ_F64, []int{2, 1, 0}, "VADD", "ADDD"},
{VSUB_EQ_F32, []int{2, 1, 0}, "VSUB", "SUBF"},
{VSUB_EQ_F64, []int{2, 1, 0}, "VSUB", "SUBD"},
{VMUL_EQ_F32, []int{2, 1, 0}, "VMUL", "MULF"},
{VMUL_EQ_F64, []int{2, 1, 0}, "VMUL", "MULD"},
{VNMUL_EQ_F32, []int{2, 1, 0}, "VNMUL", "NMULF"},
{VNMUL_EQ_F64, []int{2, 1, 0}, "VNMUL", "NMULD"},
{VMLA_EQ_F32, []int{2, 1, 0}, "VMLA", "MULAF"},
{VMLA_EQ_F64, []int{2, 1, 0}, "VMLA", "MULAD"},
{VMLS_EQ_F32, []int{2, 1, 0}, "VMLS", "MULSF"},
{VMLS_EQ_F64, []int{2, 1, 0}, "VMLS", "MULSD"},
{VNMLA_EQ_F32, []int{2, 1, 0}, "VNMLA", "NMULAF"},
{VNMLA_EQ_F64, []int{2, 1, 0}, "VNMLA", "NMULAD"},
{VNMLS_EQ_F32, []int{2, 1, 0}, "VNMLS", "NMULSF"},
{VNMLS_EQ_F64, []int{2, 1, 0}, "VNMLS", "NMULSD"},
{VDIV_EQ_F32, []int{2, 1, 0}, "VDIV", "DIVF"},
{VDIV_EQ_F64, []int{2, 1, 0}, "VDIV", "DIVD"},
{VNEG_EQ_F32, []int{1, 0}, "VNEG", "NEGF"},
{VNEG_EQ_F64, []int{1, 0}, "VNEG", "NEGD"},
{VABS_EQ_F32, []int{1, 0}, "VABS", "ABSF"},
{VABS_EQ_F64, []int{1, 0}, "VABS", "ABSD"},
{VSQRT_EQ_F32, []int{1, 0}, "VSQRT", "SQRTF"},
{VSQRT_EQ_F64, []int{1, 0}, "VSQRT", "SQRTD"},
{VCMP_EQ_F32, []int{1, 0}, "VCMP", "CMPF"},
{VCMP_EQ_F64, []int{1, 0}, "VCMP", "CMPD"},
{VCMP_E_EQ_F32, []int{1, 0}, "VCMP.E", "CMPF"},
{VCMP_E_EQ_F64, []int{1, 0}, "VCMP.E", "CMPD"},
{VLDR_EQ, []int{1}, "VLDR", "MOV"},
{VSTR_EQ, []int{1}, "VSTR", "MOV"},
{VMOV_EQ_F32, []int{1, 0}, "VMOV", "MOVF"},
{VMOV_EQ_F64, []int{1, 0}, "VMOV", "MOVD"},
{VMOV_EQ_32, []int{1, 0}, "VMOV", "MOVW"},
{VMOV_EQ, []int{1, 0}, "VMOV", "MOVW"},
{VCVT_EQ_F64_F32, []int{1, 0}, "VCVT", "MOVFD"},
{VCVT_EQ_F32_F64, []int{1, 0}, "VCVT", "MOVDF"},
{VCVT_EQ_F32_U32, []int{1, 0}, "VCVT", "MOVWF.U"},
{VCVT_EQ_F32_S32, []int{1, 0}, "VCVT", "MOVWF"},
{VCVT_EQ_S32_F32, []int{1, 0}, "VCVT", "MOVFW"},
{VCVT_EQ_U32_F32, []int{1, 0}, "VCVT", "MOVFW.U"},
{VCVT_EQ_F64_U32, []int{1, 0}, "VCVT", "MOVWD.U"},
{VCVT_EQ_F64_S32, []int{1, 0}, "VCVT", "MOVWD"},
{VCVT_EQ_S32_F64, []int{1, 0}, "VCVT", "MOVDW"},
{VCVT_EQ_U32_F64, []int{1, 0}, "VCVT", "MOVDW.U"},
}
// convert FP instructions from GNU syntax to Plan 9 syntax, for example,
// vadd.f32 s0, s3, s4 -> ADDF F0, S3, F2
// vsub.f64 d0, d2, d4 -> SUBD F0, F2, F4
// vldr s2, [r11] -> MOVF (R11), F1
// inputs: instruction name and arguments in GNU syntax
// return values: corresponding instruction name and arguments in Plan 9 syntax
func fpTrans(inst *Inst, op string, args []string) (string, []string) {
for _, fp := range fpInst {
if inst.Op&^15 == fp.op {
// remove gnu syntax suffixes
op = strings.Replace(op, ".F32", "", -1)
op = strings.Replace(op, ".F64", "", -1)
op = strings.Replace(op, ".S32", "", -1)
op = strings.Replace(op, ".U32", "", -1)
op = strings.Replace(op, ".32", "", -1)
// compose op name
if fp.op == VLDR_EQ || fp.op == VSTR_EQ {
switch {
case strings.HasPrefix(args[fp.transArgs[0]], "D"):
op = "MOVD" + op[len(fp.gnuName):]
case strings.HasPrefix(args[fp.transArgs[0]], "S"):
op = "MOVF" + op[len(fp.gnuName):]
default:
panic(fmt.Sprintf("wrong FP register: %v", inst))
}
} else {
op = fp.goName + op[len(fp.gnuName):]
}
// transform registers
for ix, ri := range fp.transArgs {
switch {
case strings.HasSuffix(args[ri], "[1]"): // MOVW Rx, Dy[1]
break
case strings.HasSuffix(args[ri], "[0]"): // Dx[0] -> Fx
args[ri] = strings.Replace(args[ri], "[0]", "", -1)
fallthrough
case strings.HasPrefix(args[ri], "D"): // Dx -> Fx
args[ri] = "F" + args[ri][1:]
case strings.HasPrefix(args[ri], "S"):
if inst.Args[ix].(Reg)&1 == 0 { // Sx -> Fy, y = x/2, if x is even
args[ri] = fmt.Sprintf("F%d", (inst.Args[ix].(Reg)-S0)/2)
}
case strings.HasPrefix(args[ri], "$"): // CMPF/CMPD $0, Fx
break
case strings.HasPrefix(args[ri], "R"): // MOVW Rx, Dy[1]
break
default:
panic(fmt.Sprintf("wrong FP register: %v", inst))
}
}
break
}
}
return op, args
}
...@@ -944,44 +944,46 @@ b12fbfe6| 1 plan9 REV16 R1, R2 ...@@ -944,44 +944,46 @@ b12fbfe6| 1 plan9 REV16 R1, R2
b12fffe6| 1 plan9 REVSH R1, R2 b12fffe6| 1 plan9 REVSH R1, R2
312fffe6| 1 plan9 RBIT R1, R2 312fffe6| 1 plan9 RBIT R1, R2
112f6fe1| 1 plan9 CLZ R1, R2 112f6fe1| 1 plan9 CLZ R1, R2
f0ffd6f5| 1 gnu pld [r6, #4080] f0ffd6f5| 1 plan9 PLD 0xff0(R6)
f0ff59f5| 1 gnu pld [r9, #-4080] f0ff59f5| 1 plan9 PLD -0xff0(R9)
f0ff96f5| 1 gnu pldw [r6, #4080] f0ff96f5| 1 plan9 PLD.W 0xff0(R6)
f0ff19f5| 1 gnu pldw [r9, #-4080] f0ff19f5| 1 plan9 PLD.W -0xff0(R9)
f0ffdff5| 1 gnu pld [pc, #4080] f0ffdff5| 1 plan9 PLD 0xff0(R15)
f0ff5ff5| 1 gnu pld [pc, #-4080] f0ff5ff5| 1 plan9 PLD -0xff0(R15)
00f0d2f7| 1 gnu pld [r2, r0] 00f0d2f7| 1 plan9 PLD (R2)(R0)
00f052f7| 1 gnu pld [r2, -r0] 00f052f7| 1 plan9 PLD.U (R2)(R0)
00f092f7| 1 gnu pldw [r2, r0] 00f092f7| 1 plan9 PLD.W (R2)(R0)
00f012f7| 1 gnu pldw [r2, -r0] 00f012f7| 1 plan9 PLD.W.U (R2)(R0)
80f0d2f7| 1 gnu pld [r2, r0, lsl #1] 80f0d2f7| 1 plan9 PLD (R2)(R0<<1)
80f052f7| 1 gnu pld [r2, -r0, lsl #1] 80f052f7| 1 plan9 PLD.U (R2)(R0<<1)
a0f0d2f7| 1 gnu pld [r2, r0, lsr #1] a0f0d2f7| 1 plan9 PLD (R2)(R0>>1)
a0f052f7| 1 gnu pld [r2, -r0, lsr #1] a0f052f7| 1 plan9 PLD.U (R2)(R0>>1)
c0f0d2f7| 1 gnu pld [r2, r0, asr #1] c0f0d2f7| 1 plan9 PLD (R2)(R0->1)
c0f052f7| 1 gnu pld [r2, -r0, asr #1] c0f052f7| 1 plan9 PLD.U (R2)(R0->1)
e0f0d2f7| 1 gnu pld [r2, r0, ror #1] e0f0d2f7| 1 plan9 PLD (R2)(R0@>1)
e0f052f7| 1 gnu pld [r2, -r0, ror #1] e0f052f7| 1 plan9 PLD.U (R2)(R0@>1)
80f092f7| 1 gnu pldw [r2, r0, lsl #1] 80f092f7| 1 plan9 PLD.W (R2)(R0<<1)
80f012f7| 1 gnu pldw [r2, -r0, lsl #1] 80f012f7| 1 plan9 PLD.W.U (R2)(R0<<1)
a0f092f7| 1 gnu pldw [r2, r0, lsr #1] a0f092f7| 1 plan9 PLD.W (R2)(R0>>1)
a0f012f7| 1 gnu pldw [r2, -r0, lsr #1] a0f012f7| 1 plan9 PLD.W.U (R2)(R0>>1)
c0f092f7| 1 gnu pldw [r2, r0, asr #1] c0f092f7| 1 plan9 PLD.W (R2)(R0->1)
c0f012f7| 1 gnu pldw [r2, -r0, asr #1] c0f012f7| 1 plan9 PLD.W.U (R2)(R0->1)
e0f092f7| 1 gnu pldw [r2, r0, ror #1] e0f092f7| 1 plan9 PLD.W (R2)(R0@>1)
e0f012f7| 1 gnu pldw [r2, -r0, ror #1] e0f012f7| 1 plan9 PLD.W.U (R2)(R0@>1)
f0ffd2f4| 1 gnu pli [r2, #4080] f0ffd2f4| 1 plan9 PLI 0xff0(R2)
f0ff52f4| 1 gnu pli [r2, #-4080] f0ff52f4| 1 plan9 PLI -0xff0(R2)
82f0d3f6| 1 gnu pli [r3, r2, lsl #1] 00f0d2f6| 1 plan9 PLI (R2)(R0)
82f053f6| 1 gnu pli [r3, -r2, lsl #1] 00f052f6| 1 plan9 PLI.U (R2)(R0)
a2f0d3f6| 1 gnu pli [r3, r2, lsr #1] 82f0d3f6| 1 plan9 PLI (R3)(R2<<1)
a2f053f6| 1 gnu pli [r3, -r2, lsr #1] 82f053f6| 1 plan9 PLI.U (R3)(R2<<1)
c2f0d3f6| 1 gnu pli [r3, r2, asr #1] a2f0d3f6| 1 plan9 PLI (R3)(R2>>1)
c2f053f6| 1 gnu pli [r3, -r2, asr #1] a2f053f6| 1 plan9 PLI.U (R3)(R2>>1)
e2f0d3f6| 1 gnu pli [r3, r2, ror #1] c2f0d3f6| 1 plan9 PLI (R3)(R2->1)
e2f053f6| 1 gnu pli [r3, -r2, ror #1] c2f053f6| 1 plan9 PLI.U (R3)(R2->1)
939007e1| 1 gnu swp r9, r3, [r7] e2f0d3f6| 1 plan9 PLI (R3)(R2@>1)
948042e1| 1 gnu swpb r8, r4, [r2] e2f053f6| 1 plan9 PLI.U (R3)(R2@>1)
939007e1| 1 plan9 SWP R3, (R7), R9
948042e1| 1 plan9 SWP.B R4, (R2), R8
000000ef| 1 plan9 SVC $0 000000ef| 1 plan9 SVC $0
ffff00ef| 1 plan9 SVC $65535 ffff00ef| 1 plan9 SVC $65535
ff10e0e3| 1 plan9 MVN $255, R1 ff10e0e3| 1 plan9 MVN $255, R1
...@@ -1061,15 +1063,15 @@ aaaa4a03| 1 plan9 MOVT.EQ $43690, R10 ...@@ -1061,15 +1063,15 @@ aaaa4a03| 1 plan9 MOVT.EQ $43690, R10
201012e5| 1 plan9 MOVW -0x20(R2), R1 201012e5| 1 plan9 MOVW -0x20(R2), R1
201012e4| 1 plan9 MOVW.P -0x20(R2), R1 201012e4| 1 plan9 MOVW.P -0x20(R2), R1
201032e5| 1 plan9 MOVW.W -0x20(R2), R1 201032e5| 1 plan9 MOVW.W -0x20(R2), R1
00100fe1| 1 plan9 MRS APSR, R1 00100fe1| 1 plan9 MOVW APSR, R1
fef02ce3| 1 plan9 MSR $254, APSR fef02ce3| 1 plan9 MOVW $254, APSR
fff42ce3| 1 plan9 MSR $4278190080, APSR fff42ce3| 1 plan9 MOVW $4278190080, APSR
05f02c01| 1 plan9 MSR.EQ R5, APSR 05f02c01| 1 plan9 MOVW.EQ R5, APSR
09f02c11| 1 plan9 MSR.NE R9, APSR 09f02c11| 1 plan9 MOVW.NE R9, APSR
109af1ee| 1 plan9 VMRS FPSCR, R9 109af10e| 1 plan9 MOVW.EQ FPSCR, R9
10aaf1ee| 1 plan9 VMRS FPSCR, R10 10aaf1ee| 1 plan9 MOVW FPSCR, R10
109ae1ee| 1 plan9 VMSR R9, FPSCR 109ae11e| 1 plan9 MOVW.NE R9, FPSCR
10aae1ee| 1 plan9 VMSR R10, FPSCR 10aae1ee| 1 plan9 MOVW R10, FPSCR
202e91e7| 1 plan9 MOVW (R1)(R0>>28), R2 202e91e7| 1 plan9 MOVW (R1)(R0>>28), R2
002e91e7| 1 plan9 MOVW (R1)(R0<<28), R2 002e91e7| 1 plan9 MOVW (R1)(R0<<28), R2
402e91e7| 1 plan9 MOVW (R1)(R0->28), R2 402e91e7| 1 plan9 MOVW (R1)(R0->28), R2
...@@ -1200,68 +1202,110 @@ b48259e0| 1 plan9 MOVHU.P -0x24(R9), R8 ...@@ -1200,68 +1202,110 @@ b48259e0| 1 plan9 MOVHU.P -0x24(R9), R8
f48259e1| 1 plan9 MOVHS -0x24(R9), R8 f48259e1| 1 plan9 MOVHS -0x24(R9), R8
f48279e1| 1 plan9 MOVHS.W -0x24(R9), R8 f48279e1| 1 plan9 MOVHS.W -0x24(R9), R8
f48259e0| 1 plan9 MOVHS.P -0x24(R9), R8 f48259e0| 1 plan9 MOVHS.P -0x24(R9), R8
002a31ee| 1 plan9 VADD.F32 S0, S2, S4 002a310e| 1 plan9 ADDF.EQ F0, F1, F2
202a31ee| 1 plan9 VADD.F32 S1, S2, S4 202a310e| 1 plan9 ADDF.EQ S1, F1, F2
802a31ee| 1 plan9 VADD.F32 S0, S3, S4 802a31ee| 1 plan9 ADDF F0, S3, F2
002a71ee| 1 plan9 VADD.F32 S0, S2, S5 002a71ee| 1 plan9 ADDF F0, F1, S5
035b340e| 1 plan9 VADD.EQ.F64 D3, D4, D5 035b340e| 1 plan9 ADDD.EQ F3, F4, F5
002a321e| 1 plan9 VADD.NE.F32 S0, S4, S4 002a321e| 1 plan9 ADDF.NE F0, F2, F2
035b35ee| 1 plan9 VADD.F64 D3, D5, D5 035b35ee| 1 plan9 ADDD F3, F5, F5
402a31ee| 1 plan9 VSUB.F32 S0, S2, S4 402a31ee| 1 plan9 SUBF F0, F1, F2
602a31ee| 1 plan9 VSUB.F32 S1, S2, S4 602a31ee| 1 plan9 SUBF S1, F1, F2
c02a31ee| 1 plan9 VSUB.F32 S0, S3, S4 c02a31ee| 1 plan9 SUBF F0, S3, F2
402a71ee| 1 plan9 VSUB.F32 S0, S2, S5 402a71ee| 1 plan9 SUBF F0, F1, S5
435b340e| 1 plan9 VSUB.EQ.F64 D3, D4, D5 435b340e| 1 plan9 SUBD.EQ F3, F4, F5
402a321e| 1 plan9 VSUB.NE.F32 S0, S4, S4 402a321e| 1 plan9 SUBF.NE F0, F2, F2
435b35ee| 1 plan9 VSUB.F64 D3, D5, D5 435b35ee| 1 plan9 SUBD F3, F5, F5
002a21ee| 1 plan9 VMUL.F32 S0, S2, S4 002a21ee| 1 plan9 MULF F0, F1, F2
202a21ee| 1 plan9 VMUL.F32 S1, S2, S4 202a21ee| 1 plan9 MULF S1, F1, F2
802a21ee| 1 plan9 VMUL.F32 S0, S3, S4 802a21ee| 1 plan9 MULF F0, S3, F2
002a61ee| 1 plan9 VMUL.F32 S0, S2, S5 002a61ee| 1 plan9 MULF F0, F1, S5
035b240e| 1 plan9 VMUL.EQ.F64 D3, D4, D5 035b240e| 1 plan9 MULD.EQ F3, F4, F5
002a221e| 1 plan9 VMUL.NE.F32 S0, S4, S4 002a221e| 1 plan9 MULF.NE F0, F2, F2
035b25ee| 1 plan9 VMUL.F64 D3, D5, D5 035b25ee| 1 plan9 MULD F3, F5, F5
002a81ee| 1 plan9 VDIV.F32 S0, S2, S4 402a21ee| 1 plan9 NMULF F0, F1, F2
202a81ee| 1 plan9 VDIV.F32 S1, S2, S4 602a21ee| 1 plan9 NMULF S1, F1, F2
802a81ee| 1 plan9 VDIV.F32 S0, S3, S4 c02a21ee| 1 plan9 NMULF F0, S3, F2
002ac1ee| 1 plan9 VDIV.F32 S0, S2, S5 402a61ee| 1 plan9 NMULF F0, F1, S5
035b840e| 1 plan9 VDIV.EQ.F64 D3, D4, D5 435b240e| 1 plan9 NMULD.EQ F3, F4, F5
002a821e| 1 plan9 VDIV.NE.F32 S0, S4, S4 402a221e| 1 plan9 NMULF.NE F0, F2, F2
035b85ee| 1 plan9 VDIV.F64 D3, D5, D5 435b25ee| 1 plan9 NMULD F3, F5, F5
401ab1ee| 1 plan9 VNEG.F32 S0, S2 002a01ee| 1 plan9 MULAF F0, F1, F2
601ab1ee| 1 plan9 VNEG.F32 S1, S2 202a01ee| 1 plan9 MULAF S1, F1, F2
401af1ee| 1 plan9 VNEG.F32 S0, S3 802a01ee| 1 plan9 MULAF F0, S3, F2
445bb1ee| 1 plan9 VNEG.F64 D4, D5 002a41ee| 1 plan9 MULAF F0, F1, S5
c01ab0ee| 1 plan9 VABS.F32 S0, S2 035b040e| 1 plan9 MULAD.EQ F3, F4, F5
e01ab0ee| 1 plan9 VABS.F32 S1, S2 002a021e| 1 plan9 MULAF.NE F0, F2, F2
c01af0ee| 1 plan9 VABS.F32 S0, S3 035b05ee| 1 plan9 MULAD F3, F5, F5
c45bb0ee| 1 plan9 VABS.F64 D4, D5 402a01ee| 1 plan9 MULSF F0, F1, F2
c01ab1ee| 1 plan9 VSQRT.F32 S0, S2 602a01ee| 1 plan9 MULSF S1, F1, F2
e01ab1ee| 1 plan9 VSQRT.F32 S1, S2 c02a01ee| 1 plan9 MULSF F0, S3, F2
c01af1ee| 1 plan9 VSQRT.F32 S0, S3 402a41ee| 1 plan9 MULSF F0, F1, S5
c45bb1ee| 1 plan9 VSQRT.F64 D4, D5 435b040e| 1 plan9 MULSD.EQ F3, F4, F5
c01ab7ee| 1 gnu vcvt.f64.f32 d1, s0 402a021e| 1 plan9 MULSF.NE F0, F2, F2
c45bb7ee| 1 gnu vcvt.f32.f64 s10, d4 435b05ee| 1 plan9 MULSD F3, F5, F5
9f9f98e1| 1 gnu ldrex r9, [r8] 002a11ee| 1 plan9 NMULSF F0, F1, F2
9f9fd8e1| 1 gnu ldrexb r9, [r8] 202a11ee| 1 plan9 NMULSF S1, F1, F2
9f9ff8e1| 1 gnu ldrexh r9, [r8] 802a11ee| 1 plan9 NMULSF F0, S3, F2
002a51ee| 1 plan9 NMULSF F0, F1, S5
035b140e| 1 plan9 NMULSD.EQ F3, F4, F5
002a121e| 1 plan9 NMULSF.NE F0, F2, F2
035b15ee| 1 plan9 NMULSD F3, F5, F5
402a11ee| 1 plan9 NMULAF F0, F1, F2
602a11ee| 1 plan9 NMULAF S1, F1, F2
c02a11ee| 1 plan9 NMULAF F0, S3, F2
402a51ee| 1 plan9 NMULAF F0, F1, S5
435b140e| 1 plan9 NMULAD.EQ F3, F4, F5
402a121e| 1 plan9 NMULAF.NE F0, F2, F2
435b15ee| 1 plan9 NMULAD F3, F5, F5
002a81ee| 1 plan9 DIVF F0, F1, F2
202a81ee| 1 plan9 DIVF S1, F1, F2
802a81ee| 1 plan9 DIVF F0, S3, F2
002ac1ee| 1 plan9 DIVF F0, F1, S5
035b840e| 1 plan9 DIVD.EQ F3, F4, F5
002a821e| 1 plan9 DIVF.NE F0, F2, F2
035b85ee| 1 plan9 DIVD F3, F5, F5
401ab1ee| 1 plan9 NEGF F0, F1
601ab1ee| 1 plan9 NEGF S1, F1
401af1ee| 1 plan9 NEGF F0, S3
445bb1ee| 1 plan9 NEGD F4, F5
c01ab0ee| 1 plan9 ABSF F0, F1
e01ab0ee| 1 plan9 ABSF S1, F1
c01af0ee| 1 plan9 ABSF F0, S3
c45bb0ee| 1 plan9 ABSD F4, F5
c01ab1ee| 1 plan9 SQRTF F0, F1
e01ab1ee| 1 plan9 SQRTF S1, F1
c01af1ee| 1 plan9 SQRTF F0, S3
c45bb1ee| 1 plan9 SQRTD F4, F5
c01ab7ee| 1 plan9 MOVFD F0, F1
c45bb7ee| 1 plan9 MOVDF F4, F5
c89ab4ee| 1 plan9 CMPF F8, F9
c45bb42e| 1 plan9 CMPD.CS F4, F5
c07ab56e| 1 plan9 CMPF.VS $0, F7
c06bb5ee| 1 plan9 CMPD $0, F6
9f9f98e1| 1 plan9 LDREX (R8), R9
9f9fd8e1| 1 plan9 LDREXB (R8), R9
9f9ff8e1| 1 plan9 LDREXH (R8), R9
9fcfbbe1| 1 gnu ldrexd ip, [fp] 9fcfbbe1| 1 gnu ldrexd ip, [fp]
935f84e1| 1 gnu strex r5, r3, [r4] 935f84e1| 1 plan9 STREX R3, (R4), R5
935fc4e1| 1 gnu strexb r5, r3, [r4] 935fc4e1| 1 plan9 STREXB R3, (R4), R5
935fe4e1| 1 gnu strexh r5, r3, [r4] 935fe4e1| 1 plan9 STREXH R3, (R4), R5
98afa9e1| 1 gnu strexd sl, r8, [r9] 98afa9e1| 1 gnu strexd sl, r8, [r9]
104b08ee| 1 gnu vmov.32 d8[0], r4 104b08ee| 1 plan9 MOVW R4, F8
108b14ee| 1 gnu vmov.32 r8, d4[0] 108b14ee| 1 plan9 MOVW F4, R8
445ab0ee| 1 gnu vmov.f32 s10, s8 104a080e| 1 plan9 MOVW.EQ R4, F8
467bb0ee| 1 gnu vmov.f64 d7, d6 104a181e| 1 plan9 MOVW.NE F8, R4
c68abdee| 1 gnu vcvt.s32.f32 s16, s12 904a181e| 1 plan9 MOVW.NE S17, R4
c68abcee| 1 gnu vcvt.u32.f32 s16, s12 445ab0ee| 1 plan9 MOVF F4, F5
c68bbdee| 1 gnu vcvt.s32.f64 s16, d6 467bb0ee| 1 plan9 MOVD F6, F7
c68bbcee| 1 gnu vcvt.u32.f64 s16, d6 c68abdee| 1 plan9 MOVFW F6, F8
c68ab8ee| 1 gnu vcvt.f32.s32 s16, s12 c68abcee| 1 plan9 MOVFW.U F6, F8
468ab8ee| 1 gnu vcvt.f32.u32 s16, s12 c68bbdee| 1 plan9 MOVDW F6, F8
c68bb8ee| 1 gnu vcvt.f64.s32 d8, s12 c68bbcee| 1 plan9 MOVDW.U F6, F8
468bb8ee| 1 gnu vcvt.f64.u32 d8, s12 c68ab8ee| 1 plan9 MOVWF F6, F8
468ab8ee| 1 plan9 MOVWF.U F6, F8
c68bb8ee| 1 plan9 MOVWD F6, F8
468bb8ee| 1 plan9 MOVWD.U F6, F8
000000ea| 1 plan9 B 0x8 000000ea| 1 plan9 B 0x8
feffffea| 1 plan9 B 0x0 feffffea| 1 plan9 B 0x0
fcffffea| 1 plan9 B 0xfffffff8 fcffffea| 1 plan9 B 0xfffffff8
...@@ -1446,34 +1490,34 @@ b310a2e0| 1 gnu strht r1, [r2], r3 ...@@ -1446,34 +1490,34 @@ b310a2e0| 1 gnu strht r1, [r2], r3
b640ade0| 1 gnu strht r4, [sp], r6 b640ade0| 1 gnu strht r4, [sp], r6
b31022e0| 1 gnu strht r1, [r2], -r3 b31022e0| 1 gnu strht r1, [r2], -r3
b6402de0| 1 gnu strht r4, [sp], -r6 b6402de0| 1 gnu strht r4, [sp], -r6
00f020e3| 1 gnu nop 00f020e3| 1 plan9 NOP
445ab0ee| 1 gnu vmov.f32 s10, s8 445ab0ee| 1 plan9 MOVF F4, F5
645af0ee| 1 gnu vmov.f32 s11, s9 645af0ee| 1 plan9 MOVF S9, S11
467bb0ee| 1 gnu vmov.f64 d7, d6 467bb0ee| 1 plan9 MOVD F6, F7
104b08ee| 1 gnu vmov.32 d8[0], r4 104b08ee| 1 plan9 MOVW R4, F8
104b28ee| 1 gnu vmov.32 d8[1], r4 104b28ee| 1 plan9 MOVW R4, D8[1]
108b14ee| 1 gnu vmov.32 r8, d4[0] 108b14ee| 1 plan9 MOVW F4, R8
108b34ee| 1 gnu vmov.32 r8, d4[1] 108b34ee| 1 plan9 MOVW D4[1], R8
c68abdee| 1 gnu vcvt.s32.f32 s16, s12 c68abdee| 1 plan9 MOVFW F6, F8
e68afdee| 1 gnu vcvt.s32.f32 s17, s13 e68afdee| 1 plan9 MOVFW S13, S17
c68abcee| 1 gnu vcvt.u32.f32 s16, s12 c68abcee| 1 plan9 MOVFW.U F6, F8
e68afcee| 1 gnu vcvt.u32.f32 s17, s13 e68afcee| 1 plan9 MOVFW.U S13, S17
c68bbdee| 1 gnu vcvt.s32.f64 s16, d6 c68bbdee| 1 plan9 MOVDW F6, F8
c68bfdee| 1 gnu vcvt.s32.f64 s17, d6 c68bfdee| 1 plan9 MOVDW F6, S17
c68bbcee| 1 gnu vcvt.u32.f64 s16, d6 c68bbcee| 1 plan9 MOVDW.U F6, F8
c68bfcee| 1 gnu vcvt.u32.f64 s17, d6 c68bfcee| 1 plan9 MOVDW.U F6, S17
c68ab8ee| 1 gnu vcvt.f32.s32 s16, s12 c68ab8ee| 1 plan9 MOVWF F6, F8
e68af8ee| 1 gnu vcvt.f32.s32 s17, s13 e68af8ee| 1 plan9 MOVWF S13, S17
468ab8ee| 1 gnu vcvt.f32.u32 s16, s12 468ab8ee| 1 plan9 MOVWF.U F6, F8
668af8ee| 1 gnu vcvt.f32.u32 s17, s13 668af8ee| 1 plan9 MOVWF.U S13, S17
c68bb8ee| 1 gnu vcvt.f64.s32 d8, s12 c68bb8ee| 1 plan9 MOVWD F6, F8
e68bb8ee| 1 gnu vcvt.f64.s32 d8, s13 e68bb8ee| 1 plan9 MOVWD S13, F8
468bb8ee| 1 gnu vcvt.f64.u32 d8, s12 468bb8ee| 1 plan9 MOVWD.U F6, F8
668bb8ee| 1 gnu vcvt.f64.u32 d8, s13 668bb8ee| 1 plan9 MOVWD.U S13, F8
c01ab7ee| 1 gnu vcvt.f64.f32 d1, s0 c01ab7ee| 1 plan9 MOVFD F0, F1
e01ab7ee| 1 gnu vcvt.f64.f32 d1, s1 e01ab7ee| 1 plan9 MOVFD S1, F1
c45bb7ee| 1 gnu vcvt.f32.f64 s10, d4 c45bb7ee| 1 plan9 MOVDF F4, F5
c65bf7ee| 1 gnu vcvt.f32.f64 s11, d6 c65bf7ee| 1 plan9 MOVDF F6, S11
102083e6| 1 gnu pkhbt r2, r3, r0 102083e6| 1 gnu pkhbt r2, r3, r0
102283e6| 1 gnu pkhbt r2, r3, r0, lsl #4 102283e6| 1 gnu pkhbt r2, r3, r0, lsl #4
502083e6| 1 gnu pkhtb r2, r3, r0, asr #32 502083e6| 1 gnu pkhtb r2, r3, r0, asr #32
...@@ -1525,8 +1569,8 @@ f92f73e6| 1 gnu uhsub8 r2, r3, r9 ...@@ -1525,8 +1569,8 @@ f92f73e6| 1 gnu uhsub8 r2, r3, r9
532f34e6| 1 gnu shsax r2, r4, r3 532f34e6| 1 gnu shsax r2, r4, r3
332f74e6| 1 gnu uhasx r2, r4, r3 332f74e6| 1 gnu uhasx r2, r4, r3
532f74e6| 1 gnu uhsax r2, r4, r3 532f74e6| 1 gnu uhsax r2, r4, r3
dc51afe7| 1 gnu sbfx r5, ip, #3, #16 dc51afe7| 1 plan9 SBFX $16, $3, R12, R5
dc51efe7| 1 gnu ubfx r5, ip, #3, #16 dc51efe7| 1 plan9 UBFX $16, $3, R12, R5
b12f88e6| 1 gnu sel r2, r8, r1 b12f88e6| 1 gnu sel r2, r8, r1
000201f1| 1 gnu setend be 000201f1| 1 gnu setend be
000001f1| 1 gnu setend le 000001f1| 1 gnu setend le
...@@ -1537,18 +1581,18 @@ b12f88e6| 1 gnu sel r2, r8, r1 ...@@ -1537,18 +1581,18 @@ b12f88e6| 1 gnu sel r2, r8, r1
1155eae6| 1 gnu usat r5, #10, r1, lsl #10 1155eae6| 1 gnu usat r5, #10, r1, lsl #10
5155eae6| 1 gnu usat r5, #10, r1, asr #10 5155eae6| 1 gnu usat r5, #10, r1, asr #10
335feae6| 1 gnu usat16 r5, #10, r3 335feae6| 1 gnu usat16 r5, #10, r3
7788a9e6| 1 gnu sxtab r8, r9, r7, ror #16 7788a9e6| 1 plan9 SXTAB R7@>$16, R9, R8
778889e6| 1 gnu sxtab16 r8, r9, r7, ror #16 778889e6| 1 plan9 SXTAB16 R7@>$16, R9, R8
7788b9e6| 1 gnu sxtah r8, r9, r7, ror #16 7788b9e6| 1 plan9 SXTAH R7@>$16, R9, R8
7784afe6| 1 gnu sxtb r8, r7, ror #8 7784afe6| 1 plan9 MOVBS R7@>$8, R8
778c8fe6| 1 gnu sxtb16 r8, r7, ror #24 778c8fe6| 1 plan9 SXTB16 R7@>$24, R8
7780bfe6| 1 gnu sxth r8, r7 7780bf16| 1 plan9 MOVHS.NE R7, R8
7788e9e6| 1 gnu uxtab r8, r9, r7, ror #16 7788e906| 1 plan9 UXTAB.EQ R7@>$16, R9, R8
7788c9e6| 1 gnu uxtab16 r8, r9, r7, ror #16 7788c9e6| 1 plan9 UXTAB16 R7@>$16, R9, R8
7788f9e6| 1 gnu uxtah r8, r9, r7, ror #16 7788f9e6| 1 plan9 UXTAH R7@>$16, R9, R8
7784efe6| 1 gnu uxtb r8, r7, ror #8 7784efe6| 1 plan9 MOVBU R7@>$8, R8
778ccfe6| 1 gnu uxtb16 r8, r7, ror #24 778ccfe6| 1 plan9 UXTB16 R7@>$24, R8
7780ffe6| 1 gnu uxth r8, r7 7780ffe6| 1 plan9 MOVHU R7, R8
11f288e7| 1 gnu usad8 r8, r1, r2 11f288e7| 1 gnu usad8 r8, r1, r2
112388e7| 1 gnu usada8 r8, r1, r3, r2 112388e7| 1 gnu usada8 r8, r1, r3, r2
02f020e3| 1 gnu wfe 02f020e3| 1 gnu wfe
......
...@@ -7,12 +7,14 @@ package arm64asm ...@@ -7,12 +7,14 @@ package arm64asm
import ( import (
"encoding/hex" "encoding/hex"
"io/ioutil" "io/ioutil"
"path/filepath"
"strings" "strings"
"testing" "testing"
) )
func TestDecode(t *testing.T) { func testDecode(t *testing.T, syntax string) {
data, err := ioutil.ReadFile("testdata/cases.txt") input := filepath.Join("testdata", syntax+"cases.txt")
data, err := ioutil.ReadFile(input)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -25,7 +27,7 @@ func TestDecode(t *testing.T) { ...@@ -25,7 +27,7 @@ func TestDecode(t *testing.T) {
if line == "" || strings.HasPrefix(line, "#") { if line == "" || strings.HasPrefix(line, "#") {
continue continue
} }
f := strings.SplitN(line, "\t", 3) f := strings.SplitN(line, "\t", 2)
i := strings.Index(f[0], "|") i := strings.Index(f[0], "|")
if i < 0 { if i < 0 {
t.Errorf("parsing %q: missing | separator", f[0]) t.Errorf("parsing %q: missing | separator", f[0])
...@@ -39,7 +41,7 @@ func TestDecode(t *testing.T) { ...@@ -39,7 +41,7 @@ func TestDecode(t *testing.T) {
t.Errorf("parsing %q: %v", f[0], err) t.Errorf("parsing %q: %v", f[0], err)
continue continue
} }
syntax, asm := f[1], f[2] asm := f[1]
inst, decodeErr := Decode(code) inst, decodeErr := Decode(code)
if decodeErr != nil && decodeErr != errUnknown { if decodeErr != nil && decodeErr != errUnknown {
// Some rarely used system instructions are not supported // Some rarely used system instructions are not supported
...@@ -71,8 +73,16 @@ func TestDecode(t *testing.T) { ...@@ -71,8 +73,16 @@ func TestDecode(t *testing.T) {
if strings.Replace(out, " ", "", -1) != strings.Replace(asm, " ", "", -1) && !hasPrefix(asm, Todo...) { if strings.Replace(out, " ", "", -1) != strings.Replace(asm, " ", "", -1) && !hasPrefix(asm, Todo...) {
// Exclude MSR since GNU objdump result is incorrect. eg. 0xd504431f msr s0_4_c4_c3_0, xzr // Exclude MSR since GNU objdump result is incorrect. eg. 0xd504431f msr s0_4_c4_c3_0, xzr
if !strings.HasSuffix(asm, " nv") && !strings.HasPrefix(asm, "msr") { if !strings.HasSuffix(asm, " nv") && !strings.HasPrefix(asm, "msr") {
t.Errorf("Decode(%s) [%s] = %s, want %s", f[0], syntax, out, asm) t.Errorf("Decode(%s) [%s] = %s, want %s", strings.Trim(f[0], "|"), syntax, out, asm)
} }
} }
} }
} }
func TestDecodeGNUSyntax(t *testing.T) {
testDecode(t, "gnu")
}
func TestDecodeGoSyntax(t *testing.T) {
testDecode(t, "plan9")
}
...@@ -14,11 +14,13 @@ import ( ...@@ -14,11 +14,13 @@ import (
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"math/rand" "math/rand"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
...@@ -220,7 +222,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, ...@@ -220,7 +222,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name() file = f.Name()
f.Seek(start, 0) f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f) w := bufio.NewWriter(f)
defer w.Flush() defer w.Flush()
size = 0 size = 0
...@@ -565,9 +567,10 @@ func hexCases(t *testing.T, encoded string) func(func([]byte)) { ...@@ -565,9 +567,10 @@ func hexCases(t *testing.T, encoded string) func(func([]byte)) {
// testdataCases generates the test cases recorded in testdata/cases.txt. // testdataCases generates the test cases recorded in testdata/cases.txt.
// It only uses the inputs; it ignores the answers recorded in that file. // It only uses the inputs; it ignores the answers recorded in that file.
func testdataCases(t *testing.T) func(func([]byte)) { func testdataCases(t *testing.T, syntax string) func(func([]byte)) {
var codes [][]byte var codes [][]byte
data, err := ioutil.ReadFile("testdata/cases.txt") input := filepath.Join("testdata", syntax+"cases.txt")
data, err := ioutil.ReadFile(input)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
...@@ -536,8 +536,13 @@ type MemExtend struct { ...@@ -536,8 +536,13 @@ type MemExtend struct {
Base RegSP Base RegSP
Index Reg Index Reg
Extend ExtShift Extend ExtShift
// Amount indicates the index shift amount (but also see ShiftMustBeZero field below).
Amount uint8 Amount uint8
Absent bool // ShiftMustBeZero is set to true when the shift amount must be 0, even if the
// Amount field is not 0. In GNU syntax, a #0 shift amount is printed if Amount
// is not 0 but ShiftMustBeZero is true; #0 is not printed if Amount is 0 and
// ShiftMustBeZero is true. Both cases represent shift by 0 bit.
ShiftMustBeZero bool
} }
func (MemExtend) isArg() {} func (MemExtend) isArg() {}
...@@ -545,7 +550,7 @@ func (MemExtend) isArg() {} ...@@ -545,7 +550,7 @@ func (MemExtend) isArg() {}
func (m MemExtend) String() string { func (m MemExtend) String() string {
Rbase := m.Base.String() Rbase := m.Base.String()
RIndex := m.Index.String() RIndex := m.Index.String()
if m.Absent { if m.ShiftMustBeZero {
if m.Amount != 0 { if m.Amount != 0 {
return fmt.Sprintf("[%s,%s,%s #0]", Rbase, RIndex, m.Extend.String()) return fmt.Sprintf("[%s,%s,%s #0]", Rbase, RIndex, m.Extend.String())
} else { } else {
......
...@@ -9,10 +9,15 @@ import ( ...@@ -9,10 +9,15 @@ import (
"testing" "testing"
) )
func TestObjdumpARM64Testdata(t *testing.T) { testObjdumpARM64(t, testdataCases(t)) } func TestObjdumpARM64TestDecodeGNUSyntaxdata(t *testing.T) {
func TestObjdumpARM64Manual(t *testing.T) { testObjdumpARM64(t, hexCases(t, objdumpManualTests)) } testObjdumpARM64(t, testdataCases(t, "gnu"))
func TestObjdumpARM64Cond(t *testing.T) { testObjdumpARM64(t, condCases(t)) } }
func TestObjdumpARM64(t *testing.T) { testObjdumpARM64(t, JSONCases(t)) } func TestObjdumpARM64TestDecodeGoSyntaxdata(t *testing.T) {
testObjdumpARM64(t, testdataCases(t, "plan9"))
}
func TestObjdumpARM64Manual(t *testing.T) { testObjdumpARM64(t, hexCases(t, objdumpManualTests)) }
func TestObjdumpARM64Cond(t *testing.T) { testObjdumpARM64(t, condCases(t)) }
func TestObjdumpARM64(t *testing.T) { testObjdumpARM64(t, JSONCases(t)) }
// objdumpManualTests holds test cases that will be run by TestObjdumpARMManual. // objdumpManualTests holds test cases that will be run by TestObjdumpARMManual.
// If you are debugging a few cases that turned up in a longer run, it can be useful // If you are debugging a few cases that turned up in a longer run, it can be useful
......
...@@ -232,7 +232,7 @@ func parseContinuation(line []byte, enc []byte) []byte { ...@@ -232,7 +232,7 @@ func parseContinuation(line []byte, enc []byte) []byte {
// writeELF64 writes an ELF64 header to the file, describing a text // writeELF64 writes an ELF64 header to the file, describing a text
// segment that starts at start (0x8000) and extends for size bytes. // segment that starts at start (0x8000) and extends for size bytes.
func writeELF64(f *os.File, size int) error { func writeELF64(f *os.File, size int) error {
f.Seek(0, 0) f.Seek(0, io.SeekStart)
var hdr elf.Header64 var hdr elf.Header64
var prog elf.Prog64 var prog elf.Prog64
var sect elf.Section64 var sect elf.Section64
......
...@@ -53,7 +53,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -53,7 +53,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
// Move addressing mode into opcode suffix. // Move addressing mode into opcode suffix.
suffix := "" suffix := ""
switch inst.Op { switch inst.Op {
case LDR, LDRB, LDRH, LDRSB, LDRSH, LDRSW, STR, STRB, STRH, STUR, STURB, STURH, LD1: case LDR, LDRB, LDRH, LDRSB, LDRSH, LDRSW, STR, STRB, STRH, STUR, STURB, STURH, LD1, ST1:
switch mem := inst.Args[1].(type) { switch mem := inst.Args[1].(type) {
case MemImmediate: case MemImmediate:
switch mem.Mode { switch mem.Mode {
...@@ -114,6 +114,8 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -114,6 +114,8 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
rno = int(a) rno = int(a)
case RegisterWithArrangementAndIndex: case RegisterWithArrangementAndIndex:
op = "VMOV" op = "VMOV"
case RegisterWithArrangement:
op = "VMOV"
} }
if rno >= 0 && rno <= int(WZR) { if rno >= 0 && rno <= int(WZR) {
op = "MOVW" op = "MOVW"
...@@ -133,6 +135,12 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -133,6 +135,12 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
} }
if rno <= uint16(WZR) { if rno <= uint16(WZR) {
op = "MOVWU" + suffix op = "MOVWU" + suffix
} else if rno >= uint16(S0) && rno <= uint16(S31) {
op = "FMOVS" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(D0) && rno <= uint16(D31) {
op = "FMOVD" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else { } else {
op = "MOVD" + suffix op = "MOVD" + suffix
} }
...@@ -173,6 +181,12 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -173,6 +181,12 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
} }
if rno <= uint16(WZR) { if rno <= uint16(WZR) {
op = "MOVW" + suffix op = "MOVW" + suffix
} else if rno >= uint16(S0) && rno <= uint16(S31) {
op = "FMOVS" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(D0) && rno <= uint16(D31) {
op = "FMOVD" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else { } else {
op = "MOVD" + suffix op = "MOVD" + suffix
} }
...@@ -230,6 +244,15 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -230,6 +244,15 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
} }
args[1], args[2], args[3] = args[3], args[1], args[2] args[1], args[2], args[3] = args[3], args[1], args[2]
case LDAXP, LDXP:
if r, ok := inst.Args[0].(Reg); ok {
rno := uint16(r)
if rno <= uint16(WZR) {
op += "W"
}
}
fallthrough
case STP, LDP: case STP, LDP:
args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1]) args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1])
args[1] = args[2] args[1] = args[2]
...@@ -239,8 +262,21 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -239,8 +262,21 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
} else if op == "LDP" { } else if op == "LDP" {
op = op + suffix op = op + suffix
return op + " " + args[1] + ", " + args[0] return op + " " + args[1] + ", " + args[0]
} else if op == "LDAXP" || op == "LDXP" || op == "LDAXPW" || op == "LDXPW" {
return op + " " + args[1] + ", " + args[0]
} }
case STLXP, STXP:
if r, ok := inst.Args[1].(Reg); ok {
rno := uint16(r)
if rno <= uint16(WZR) {
op += "W"
}
}
args[1] = fmt.Sprintf("(%s, %s)", args[1], args[2])
args[2] = args[3]
return op + " " + args[1] + ", " + args[2] + ", " + args[0]
case FCCMP, FCCMPE: case FCCMP, FCCMPE:
args[0], args[1] = args[1], args[0] args[0], args[1] = args[1], args[0]
fallthrough fallthrough
...@@ -251,7 +287,10 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -251,7 +287,10 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
} }
fallthrough fallthrough
case FADD, FSUB, FMUL, FNMUL, FDIV, FMAX, FMIN, FMAXNM, FMINNM, FCSEL: case FADD, FSUB, FMUL, FNMUL, FDIV, FMAX, FMIN, FMAXNM, FMINNM, FCSEL, FMADD, FMSUB, FNMADD, FNMSUB:
if strings.HasSuffix(op, "MADD") || strings.HasSuffix(op, "MSUB") {
args[2], args[3] = args[3], args[2]
}
if r, ok := inst.Args[0].(Reg); ok { if r, ok := inst.Args[0].(Reg); ok {
rno := uint16(r) rno := uint16(r)
if rno >= uint16(S0) && rno <= uint16(S31) { if rno >= uint16(S0) && rno <= uint16(S31) {
...@@ -337,6 +376,19 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -337,6 +376,19 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
addr := int64(inst.Args[1].(PCRel)) addr := int64(inst.Args[1].(PCRel))
args[1] = fmt.Sprintf("%d(PC)", addr) args[1] = fmt.Sprintf("%d(PC)", addr)
case MSR:
args[0] = inst.Args[0].String()
case ST1:
op = fmt.Sprintf("V%s", op) + suffix
args[0], args[1] = args[1], args[0]
case LD1:
op = fmt.Sprintf("V%s", op) + suffix
case UMOV:
op = "VMOV"
default: default:
index := sort.SearchStrings(noSuffixOpSet, op) index := sort.SearchStrings(noSuffixOpSet, op)
if !(index < len(noSuffixOpSet) && noSuffixOpSet[index] == op) { if !(index < len(noSuffixOpSet) && noSuffixOpSet[index] == op) {
...@@ -350,6 +402,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -350,6 +402,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
op = fmt.Sprintf("V%s", op) op = fmt.Sprintf("V%s", op)
} }
if rno >= int(B0) && rno <= int(Q31) && !strings.HasPrefix(op, "F") {
op = fmt.Sprintf("V%s", op)
}
if rno >= 0 && rno <= int(WZR) { if rno >= 0 && rno <= int(WZR) {
// Add "w" to opcode suffix. // Add "w" to opcode suffix.
op += "W" op += "W"
...@@ -381,6 +436,10 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text ...@@ -381,6 +436,10 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
// No need add "W" to opcode suffix. // No need add "W" to opcode suffix.
// Opcode must be inserted in ascending order. // Opcode must be inserted in ascending order.
var noSuffixOpSet = strings.Fields(` var noSuffixOpSet = strings.Fields(`
AESD
AESE
AESIMC
AESMC
CRC32B CRC32B
CRC32CB CRC32CB
CRC32CH CRC32CH
...@@ -393,8 +452,19 @@ LDARB ...@@ -393,8 +452,19 @@ LDARB
LDARH LDARH
LDAXRB LDAXRB
LDAXRH LDAXRH
LDTRH
LDXRB LDXRB
LDXRH LDXRH
SHA1C
SHA1H
SHA1M
SHA1P
SHA1SU0
SHA1SU1
SHA256H
SHA256H2
SHA256SU0
SHA256SU1
`) `)
func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string { func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
...@@ -423,9 +493,14 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg ...@@ -423,9 +493,14 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
regno := uint16(a) & 31 regno := uint16(a) & 31
if regenum >= uint16(B0) && regenum <= uint16(D31) { if regenum >= uint16(B0) && regenum <= uint16(D31) {
// FP registers are the same ones as SIMD registers if strings.HasPrefix(inst.Op.String(), "F") || strings.HasSuffix(inst.Op.String(), "CVTF") {
// Print Fn for scalar variant to align with assembler (e.g., FCVT) // FP registers are the same ones as SIMD registers
return fmt.Sprintf("F%d", regno) // Print Fn for scalar variant to align with assembler (e.g., FCVT, SCVTF, UCVTF, etc.)
return fmt.Sprintf("F%d", regno)
} else {
return fmt.Sprintf("V%d", regno)
}
} else if regenum >= uint16(Q0) && regenum <= uint16(Q31) { } else if regenum >= uint16(Q0) && regenum <= uint16(Q31) {
// Print Vn to align with assembler (e.g., SHA256H) // Print Vn to align with assembler (e.g., SHA256H)
return fmt.Sprintf("V%d", regno) return fmt.Sprintf("V%d", regno)
...@@ -503,7 +578,6 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg ...@@ -503,7 +578,6 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
case MemExtend: case MemExtend:
base := "" base := ""
index := "" index := ""
extend := ""
indexreg := "" indexreg := ""
regno := uint16(a.Base) & 31 regno := uint16(a.Base) & 31
if regno == 31 { if regno == 31 {
...@@ -517,15 +591,28 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg ...@@ -517,15 +591,28 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
} else { } else {
indexreg = fmt.Sprintf("R%d", regno) indexreg = fmt.Sprintf("R%d", regno)
} }
if a.Extend == lsl { if a.Extend == lsl {
if a.Amount != 0 { // a.Amount indicates the index shift amount, encoded in "S" field.
extend = fmt.Sprintf("<<%d", a.Amount) // a.ShiftMustBeZero is set true when the index shift amount must be 0,
// even if the a.Amount field is not 0.
// When a.ShiftMustBeZero is ture, GNU syntax prints #0 shift amount if
// "S" equals to 1, or does not print #0 shift amount if "S" equals to 0.
// Go syntax should never print a zero index shift amount.
if a.Amount != 0 && !a.ShiftMustBeZero {
index = fmt.Sprintf("(%s<<%d)", indexreg, a.Amount)
} else {
index = fmt.Sprintf("(%s)", indexreg)
} }
} else { } else {
extend = "unimplemented!" if a.Amount != 0 && !a.ShiftMustBeZero {
index = fmt.Sprintf("(%s.%s<<%d)", indexreg, a.Extend.String(), a.Amount)
} else {
index = fmt.Sprintf("(%s.%s)", indexreg, a.Extend.String())
}
} }
index = indexreg + extend
return index + base return base + index
case Cond: case Cond:
switch arg.String() { switch arg.String() {
...@@ -592,7 +679,7 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg ...@@ -592,7 +679,7 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
result := a.r.String() result := a.r.String()
arrange := a.a.String() arrange := a.a.String()
result += arrange result += arrange
if a.cnt > 0 { if a.cnt > 1 {
result = "[" + result result = "[" + result
for i := 1; i < int(a.cnt); i++ { for i := 1; i < int(a.cnt); i++ {
cur := V0 + Reg((uint16(a.r)-uint16(V0)+uint16(i))&31) cur := V0 + Reg((uint16(a.r)-uint16(V0)+uint16(i))&31)
...@@ -605,6 +692,10 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg ...@@ -605,6 +692,10 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
case Systemreg: case Systemreg:
return fmt.Sprintf("$%d", uint32(a.op0&1)<<14|uint32(a.op1&7)<<11|uint32(a.cn&15)<<7|uint32(a.cm&15)<<3|uint32(a.op2)&7) return fmt.Sprintf("$%d", uint32(a.op0&1)<<14|uint32(a.op1&7)<<11|uint32(a.cn&15)<<7|uint32(a.cm&15)<<3|uint32(a.op2)&7)
case Imm_prfop:
if strings.Contains(a.String(), "#") {
return fmt.Sprintf("$%d", a)
}
} }
return strings.ToUpper(arg.String()) return strings.ToUpper(arg.String())
......
go test command: go test command:
cd ..; go test -run 'ObjdumpARM64Cond' -v -timeout 10h -long 2>&1 | tee log cd ..; go test -run 'ObjdumpARM64Cond' -v -timeout 10h -long 2>&1 | tee log
cd ..; go test -run 'ObjdumpARM64Testdata' -v -timeout 10h -long 2>&1 | tee -a log cd ..; go test -run 'ObjdumpARM64TestGUNSyntaxdata' -v -timeout 10h -long 2>&1 | tee -a log
cd ..; go test -run 'ObjdumpARM64TestGoSyntaxdata' -v -timeout 10h -long 2>&1 | tee -a log
cd ..; go test -run 'ObjdumpARM64' -v -timeout 10h -long 2>&1 | tee -a log cd ..; go test -run 'ObjdumpARM64' -v -timeout 10h -long 2>&1 | tee -a log
cd ..; go test -run 'ObjdumpARM64Manual' -v -timeout 10h -long 2>&1 | tee -a log cd ..; go test -run 'ObjdumpARM64Manual' -v -timeout 10h -long 2>&1 | tee -a log
cd ..; go test -run 'TestDecode' cd ..; go test -run 'TestDecodeGNUSyntax'
cd ..; go test -run 'TestDecodeGoSyntax'
cd ..; go test -run '.*' cd ..; go test -run '.*'
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"encoding/hex" "encoding/hex"
"flag" "flag"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"math/rand" "math/rand"
...@@ -194,7 +195,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, ...@@ -194,7 +195,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name() file = f.Name()
f.Seek(start, 0) f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f) w := bufio.NewWriter(f)
defer w.Flush() defer w.Flush()
size = 0 size = 0
......
...@@ -188,7 +188,7 @@ func parseContinuation(line []byte, enc []byte) []byte { ...@@ -188,7 +188,7 @@ func parseContinuation(line []byte, enc []byte) []byte {
// describing a text segment that starts at start // describing a text segment that starts at start
// and extends for size bytes. // and extends for size bytes.
func writeELF64(f *os.File, size int) error { func writeELF64(f *os.File, size int) error {
f.Seek(0, 0) f.Seek(0, io.SeekStart)
var hdr elf.Header64 var hdr elf.Header64
var prog elf.Prog64 var prog elf.Prog64
var sect elf.Section64 var sect elf.Section64
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"encoding/hex" "encoding/hex"
"flag" "flag"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"math/rand" "math/rand"
...@@ -194,7 +195,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, ...@@ -194,7 +195,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name() file = f.Name()
f.Seek(start, 0) f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f) w := bufio.NewWriter(f)
defer w.Flush() defer w.Flush()
size = 0 size = 0
......
...@@ -176,7 +176,7 @@ func parseContinuation(line []byte, enc []byte) []byte { ...@@ -176,7 +176,7 @@ func parseContinuation(line []byte, enc []byte) []byte {
// describing a text segment that starts at start // describing a text segment that starts at start
// and extends for size bytes. // and extends for size bytes.
func writeELF32(f *os.File, size int) error { func writeELF32(f *os.File, size int) error {
f.Seek(0, 0) f.Seek(0, io.SeekStart)
var hdr elf.Header32 var hdr elf.Header32
var prog elf.Prog32 var prog elf.Prog32
var sect elf.Section32 var sect elf.Section32
...@@ -246,7 +246,7 @@ func writeELF32(f *os.File, size int) error { ...@@ -246,7 +246,7 @@ func writeELF32(f *os.File, size int) error {
// describing a text segment that starts at start // describing a text segment that starts at start
// and extends for size bytes. // and extends for size bytes.
func writeELF64(f *os.File, size int) error { func writeELF64(f *os.File, size int) error {
f.Seek(0, 0) f.Seek(0, io.SeekStart)
var hdr elf.Header64 var hdr elf.Header64
var prog elf.Prog64 var prog elf.Prog64
var sect elf.Section64 var sect elf.Section64
......
...@@ -15,26 +15,26 @@ ...@@ -15,26 +15,26 @@
{ {
"canonical": "golang.org/x/arch/x86/x86asm", "canonical": "golang.org/x/arch/x86/x86asm",
"local": "golang.org/x/arch/x86/x86asm", "local": "golang.org/x/arch/x86/x86asm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2", "revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6",
"revisionTime": "2017-12-26T02:13:20Z" "revisionTime": "2018-04-06T10:28:20Z"
}, },
{ {
"canonical": "golang.org/x/arch/arm/armasm", "canonical": "golang.org/x/arch/arm/armasm",
"local": "golang.org/x/arch/arm/armasm", "local": "golang.org/x/arch/arm/armasm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2", "revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6",
"revisionTime": "2017-12-26T02:13:20Z" "revisionTime": "2018-04-06T10:28:20Z"
}, },
{ {
"canonical": "golang.org/x/arch/ppc64/ppc64asm", "canonical": "golang.org/x/arch/ppc64/ppc64asm",
"local": "golang.org/x/arch/ppc64/ppc64asm", "local": "golang.org/x/arch/ppc64/ppc64asm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2", "revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6",
"revisionTime": "2017-12-26T02:13:20Z" "revisionTime": "2018-04-06T10:28:20Z"
}, },
{ {
"canonical": "golang.org/x/arch/arm64/arm6464asm", "canonical": "golang.org/x/arch/arm64/arm6464asm",
"local": "golang.org/x/arch/arm64/arm64asm", "local": "golang.org/x/arch/arm64/arm64asm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2", "revision": "9111c30535f37e70dcaf5956d34b03233f90f3b6",
"revisionTime": "2017-12-26T02:13:20Z" "revisionTime": "2018-03-13T04:07:09Z"
} }
] ]
} }
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