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 (
"encoding/hex"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
......@@ -196,7 +197,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name()
f.Seek(start, 0)
f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f)
defer w.Flush()
size = 0
......
......@@ -192,7 +192,7 @@ func parseContinuation(line []byte, enc []byte) []byte {
// describing a text segment that starts at start
// and extends for size bytes.
func writeELF32(f *os.File, size int) error {
f.Seek(0, 0)
f.Seek(0, io.SeekStart)
var hdr elf.Header32
var prog elf.Prog32
var sect elf.Section32
......
......@@ -96,34 +96,24 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
// Move addressing mode into opcode suffix.
suffix := ""
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:
mem, _ := inst.Args[1].(Mem)
switch mem.Mode {
case AddrOffset, AddrLDM:
// no suffix
case AddrPreIndex, AddrLDM_WB:
suffix = ".W"
case AddrPostIndex:
suffix = ".P"
case PLD, PLI, PLD_W:
if mem, ok := inst.Args[0].(Mem); ok {
args[0], suffix = memOpTrans(mem)
} else {
panic(fmt.Sprintf("illegal instruction: %v", inst))
}
off := ""
if mem.Offset != 0 {
off = fmt.Sprintf("%#x", mem.Offset)
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, ok := inst.Args[1].(Mem); ok {
args[1], suffix = memOpTrans(mem)
} else {
panic(fmt.Sprintf("illegal instruction: %v", inst))
}
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)
case SWP_EQ, SWP_B_EQ, STREX_EQ, STREXB_EQ, STREXH_EQ:
if mem, ok := inst.Args[2].(Mem); ok {
args[2], suffix = memOpTrans(mem)
} else {
panic(fmt.Sprintf("illegal instruction: %v", inst))
}
args[1] = off + base + index
}
// Reverse args, placing dest last.
......@@ -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:
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 {
case MOV_EQ:
op = "MOVW" + op[3:]
case LDR_EQ:
case LDR_EQ, MSR_EQ, MRS_EQ:
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
case LDRSB_EQ:
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
case LDRSH_EQ:
op = "MOVHS" + op[5:] + suffix
case VLDR_EQ:
switch {
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 SXTH_EQ:
op = "MOVHS" + op[4:] + suffix
case STR_EQ:
op = "MOVW" + op[3:] + suffix
args[0], args[1] = args[1], args[0]
......@@ -174,19 +164,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
op = "MOVH" + op[4:] + suffix
args[0], args[1] = args[1], args[0]
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]
default:
op = op + suffix
}
if args != nil {
......@@ -266,3 +246,153 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
}
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
b12fffe6| 1 plan9 REVSH R1, R2
312fffe6| 1 plan9 RBIT R1, R2
112f6fe1| 1 plan9 CLZ R1, R2
f0ffd6f5| 1 gnu pld [r6, #4080]
f0ff59f5| 1 gnu pld [r9, #-4080]
f0ff96f5| 1 gnu pldw [r6, #4080]
f0ff19f5| 1 gnu pldw [r9, #-4080]
f0ffdff5| 1 gnu pld [pc, #4080]
f0ff5ff5| 1 gnu pld [pc, #-4080]
00f0d2f7| 1 gnu pld [r2, r0]
00f052f7| 1 gnu pld [r2, -r0]
00f092f7| 1 gnu pldw [r2, r0]
00f012f7| 1 gnu pldw [r2, -r0]
80f0d2f7| 1 gnu pld [r2, r0, lsl #1]
80f052f7| 1 gnu pld [r2, -r0, lsl #1]
a0f0d2f7| 1 gnu pld [r2, r0, lsr #1]
a0f052f7| 1 gnu pld [r2, -r0, lsr #1]
c0f0d2f7| 1 gnu pld [r2, r0, asr #1]
c0f052f7| 1 gnu pld [r2, -r0, asr #1]
e0f0d2f7| 1 gnu pld [r2, r0, ror #1]
e0f052f7| 1 gnu pld [r2, -r0, ror #1]
80f092f7| 1 gnu pldw [r2, r0, lsl #1]
80f012f7| 1 gnu pldw [r2, -r0, lsl #1]
a0f092f7| 1 gnu pldw [r2, r0, lsr #1]
a0f012f7| 1 gnu pldw [r2, -r0, lsr #1]
c0f092f7| 1 gnu pldw [r2, r0, asr #1]
c0f012f7| 1 gnu pldw [r2, -r0, asr #1]
e0f092f7| 1 gnu pldw [r2, r0, ror #1]
e0f012f7| 1 gnu pldw [r2, -r0, ror #1]
f0ffd2f4| 1 gnu pli [r2, #4080]
f0ff52f4| 1 gnu pli [r2, #-4080]
82f0d3f6| 1 gnu pli [r3, r2, lsl #1]
82f053f6| 1 gnu pli [r3, -r2, lsl #1]
a2f0d3f6| 1 gnu pli [r3, r2, lsr #1]
a2f053f6| 1 gnu pli [r3, -r2, lsr #1]
c2f0d3f6| 1 gnu pli [r3, r2, asr #1]
c2f053f6| 1 gnu pli [r3, -r2, asr #1]
e2f0d3f6| 1 gnu pli [r3, r2, ror #1]
e2f053f6| 1 gnu pli [r3, -r2, ror #1]
939007e1| 1 gnu swp r9, r3, [r7]
948042e1| 1 gnu swpb r8, r4, [r2]
f0ffd6f5| 1 plan9 PLD 0xff0(R6)
f0ff59f5| 1 plan9 PLD -0xff0(R9)
f0ff96f5| 1 plan9 PLD.W 0xff0(R6)
f0ff19f5| 1 plan9 PLD.W -0xff0(R9)
f0ffdff5| 1 plan9 PLD 0xff0(R15)
f0ff5ff5| 1 plan9 PLD -0xff0(R15)
00f0d2f7| 1 plan9 PLD (R2)(R0)
00f052f7| 1 plan9 PLD.U (R2)(R0)
00f092f7| 1 plan9 PLD.W (R2)(R0)
00f012f7| 1 plan9 PLD.W.U (R2)(R0)
80f0d2f7| 1 plan9 PLD (R2)(R0<<1)
80f052f7| 1 plan9 PLD.U (R2)(R0<<1)
a0f0d2f7| 1 plan9 PLD (R2)(R0>>1)
a0f052f7| 1 plan9 PLD.U (R2)(R0>>1)
c0f0d2f7| 1 plan9 PLD (R2)(R0->1)
c0f052f7| 1 plan9 PLD.U (R2)(R0->1)
e0f0d2f7| 1 plan9 PLD (R2)(R0@>1)
e0f052f7| 1 plan9 PLD.U (R2)(R0@>1)
80f092f7| 1 plan9 PLD.W (R2)(R0<<1)
80f012f7| 1 plan9 PLD.W.U (R2)(R0<<1)
a0f092f7| 1 plan9 PLD.W (R2)(R0>>1)
a0f012f7| 1 plan9 PLD.W.U (R2)(R0>>1)
c0f092f7| 1 plan9 PLD.W (R2)(R0->1)
c0f012f7| 1 plan9 PLD.W.U (R2)(R0->1)
e0f092f7| 1 plan9 PLD.W (R2)(R0@>1)
e0f012f7| 1 plan9 PLD.W.U (R2)(R0@>1)
f0ffd2f4| 1 plan9 PLI 0xff0(R2)
f0ff52f4| 1 plan9 PLI -0xff0(R2)
00f0d2f6| 1 plan9 PLI (R2)(R0)
00f052f6| 1 plan9 PLI.U (R2)(R0)
82f0d3f6| 1 plan9 PLI (R3)(R2<<1)
82f053f6| 1 plan9 PLI.U (R3)(R2<<1)
a2f0d3f6| 1 plan9 PLI (R3)(R2>>1)
a2f053f6| 1 plan9 PLI.U (R3)(R2>>1)
c2f0d3f6| 1 plan9 PLI (R3)(R2->1)
c2f053f6| 1 plan9 PLI.U (R3)(R2->1)
e2f0d3f6| 1 plan9 PLI (R3)(R2@>1)
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
ffff00ef| 1 plan9 SVC $65535
ff10e0e3| 1 plan9 MVN $255, R1
......@@ -1061,15 +1063,15 @@ aaaa4a03| 1 plan9 MOVT.EQ $43690, R10
201012e5| 1 plan9 MOVW -0x20(R2), R1
201012e4| 1 plan9 MOVW.P -0x20(R2), R1
201032e5| 1 plan9 MOVW.W -0x20(R2), R1
00100fe1| 1 plan9 MRS APSR, R1
fef02ce3| 1 plan9 MSR $254, APSR
fff42ce3| 1 plan9 MSR $4278190080, APSR
05f02c01| 1 plan9 MSR.EQ R5, APSR
09f02c11| 1 plan9 MSR.NE R9, APSR
109af1ee| 1 plan9 VMRS FPSCR, R9
10aaf1ee| 1 plan9 VMRS FPSCR, R10
109ae1ee| 1 plan9 VMSR R9, FPSCR
10aae1ee| 1 plan9 VMSR R10, FPSCR
00100fe1| 1 plan9 MOVW APSR, R1
fef02ce3| 1 plan9 MOVW $254, APSR
fff42ce3| 1 plan9 MOVW $4278190080, APSR
05f02c01| 1 plan9 MOVW.EQ R5, APSR
09f02c11| 1 plan9 MOVW.NE R9, APSR
109af10e| 1 plan9 MOVW.EQ FPSCR, R9
10aaf1ee| 1 plan9 MOVW FPSCR, R10
109ae11e| 1 plan9 MOVW.NE R9, FPSCR
10aae1ee| 1 plan9 MOVW R10, FPSCR
202e91e7| 1 plan9 MOVW (R1)(R0>>28), R2
002e91e7| 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
f48259e1| 1 plan9 MOVHS -0x24(R9), R8
f48279e1| 1 plan9 MOVHS.W -0x24(R9), R8
f48259e0| 1 plan9 MOVHS.P -0x24(R9), R8
002a31ee| 1 plan9 VADD.F32 S0, S2, S4
202a31ee| 1 plan9 VADD.F32 S1, S2, S4
802a31ee| 1 plan9 VADD.F32 S0, S3, S4
002a71ee| 1 plan9 VADD.F32 S0, S2, S5
035b340e| 1 plan9 VADD.EQ.F64 D3, D4, D5
002a321e| 1 plan9 VADD.NE.F32 S0, S4, S4
035b35ee| 1 plan9 VADD.F64 D3, D5, D5
402a31ee| 1 plan9 VSUB.F32 S0, S2, S4
602a31ee| 1 plan9 VSUB.F32 S1, S2, S4
c02a31ee| 1 plan9 VSUB.F32 S0, S3, S4
402a71ee| 1 plan9 VSUB.F32 S0, S2, S5
435b340e| 1 plan9 VSUB.EQ.F64 D3, D4, D5
402a321e| 1 plan9 VSUB.NE.F32 S0, S4, S4
435b35ee| 1 plan9 VSUB.F64 D3, D5, D5
002a21ee| 1 plan9 VMUL.F32 S0, S2, S4
202a21ee| 1 plan9 VMUL.F32 S1, S2, S4
802a21ee| 1 plan9 VMUL.F32 S0, S3, S4
002a61ee| 1 plan9 VMUL.F32 S0, S2, S5
035b240e| 1 plan9 VMUL.EQ.F64 D3, D4, D5
002a221e| 1 plan9 VMUL.NE.F32 S0, S4, S4
035b25ee| 1 plan9 VMUL.F64 D3, D5, D5
002a81ee| 1 plan9 VDIV.F32 S0, S2, S4
202a81ee| 1 plan9 VDIV.F32 S1, S2, S4
802a81ee| 1 plan9 VDIV.F32 S0, S3, S4
002ac1ee| 1 plan9 VDIV.F32 S0, S2, S5
035b840e| 1 plan9 VDIV.EQ.F64 D3, D4, D5
002a821e| 1 plan9 VDIV.NE.F32 S0, S4, S4
035b85ee| 1 plan9 VDIV.F64 D3, D5, D5
401ab1ee| 1 plan9 VNEG.F32 S0, S2
601ab1ee| 1 plan9 VNEG.F32 S1, S2
401af1ee| 1 plan9 VNEG.F32 S0, S3
445bb1ee| 1 plan9 VNEG.F64 D4, D5
c01ab0ee| 1 plan9 VABS.F32 S0, S2
e01ab0ee| 1 plan9 VABS.F32 S1, S2
c01af0ee| 1 plan9 VABS.F32 S0, S3
c45bb0ee| 1 plan9 VABS.F64 D4, D5
c01ab1ee| 1 plan9 VSQRT.F32 S0, S2
e01ab1ee| 1 plan9 VSQRT.F32 S1, S2
c01af1ee| 1 plan9 VSQRT.F32 S0, S3
c45bb1ee| 1 plan9 VSQRT.F64 D4, D5
c01ab7ee| 1 gnu vcvt.f64.f32 d1, s0
c45bb7ee| 1 gnu vcvt.f32.f64 s10, d4
9f9f98e1| 1 gnu ldrex r9, [r8]
9f9fd8e1| 1 gnu ldrexb r9, [r8]
9f9ff8e1| 1 gnu ldrexh r9, [r8]
002a310e| 1 plan9 ADDF.EQ F0, F1, F2
202a310e| 1 plan9 ADDF.EQ S1, F1, F2
802a31ee| 1 plan9 ADDF F0, S3, F2
002a71ee| 1 plan9 ADDF F0, F1, S5
035b340e| 1 plan9 ADDD.EQ F3, F4, F5
002a321e| 1 plan9 ADDF.NE F0, F2, F2
035b35ee| 1 plan9 ADDD F3, F5, F5
402a31ee| 1 plan9 SUBF F0, F1, F2
602a31ee| 1 plan9 SUBF S1, F1, F2
c02a31ee| 1 plan9 SUBF F0, S3, F2
402a71ee| 1 plan9 SUBF F0, F1, S5
435b340e| 1 plan9 SUBD.EQ F3, F4, F5
402a321e| 1 plan9 SUBF.NE F0, F2, F2
435b35ee| 1 plan9 SUBD F3, F5, F5
002a21ee| 1 plan9 MULF F0, F1, F2
202a21ee| 1 plan9 MULF S1, F1, F2
802a21ee| 1 plan9 MULF F0, S3, F2
002a61ee| 1 plan9 MULF F0, F1, S5
035b240e| 1 plan9 MULD.EQ F3, F4, F5
002a221e| 1 plan9 MULF.NE F0, F2, F2
035b25ee| 1 plan9 MULD F3, F5, F5
402a21ee| 1 plan9 NMULF F0, F1, F2
602a21ee| 1 plan9 NMULF S1, F1, F2
c02a21ee| 1 plan9 NMULF F0, S3, F2
402a61ee| 1 plan9 NMULF F0, F1, S5
435b240e| 1 plan9 NMULD.EQ F3, F4, F5
402a221e| 1 plan9 NMULF.NE F0, F2, F2
435b25ee| 1 plan9 NMULD F3, F5, F5
002a01ee| 1 plan9 MULAF F0, F1, F2
202a01ee| 1 plan9 MULAF S1, F1, F2
802a01ee| 1 plan9 MULAF F0, S3, F2
002a41ee| 1 plan9 MULAF F0, F1, S5
035b040e| 1 plan9 MULAD.EQ F3, F4, F5
002a021e| 1 plan9 MULAF.NE F0, F2, F2
035b05ee| 1 plan9 MULAD F3, F5, F5
402a01ee| 1 plan9 MULSF F0, F1, F2
602a01ee| 1 plan9 MULSF S1, F1, F2
c02a01ee| 1 plan9 MULSF F0, S3, F2
402a41ee| 1 plan9 MULSF F0, F1, S5
435b040e| 1 plan9 MULSD.EQ F3, F4, F5
402a021e| 1 plan9 MULSF.NE F0, F2, F2
435b05ee| 1 plan9 MULSD F3, F5, F5
002a11ee| 1 plan9 NMULSF F0, F1, F2
202a11ee| 1 plan9 NMULSF S1, F1, F2
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]
935f84e1| 1 gnu strex r5, r3, [r4]
935fc4e1| 1 gnu strexb r5, r3, [r4]
935fe4e1| 1 gnu strexh r5, r3, [r4]
935f84e1| 1 plan9 STREX R3, (R4), R5
935fc4e1| 1 plan9 STREXB R3, (R4), R5
935fe4e1| 1 plan9 STREXH R3, (R4), R5
98afa9e1| 1 gnu strexd sl, r8, [r9]
104b08ee| 1 gnu vmov.32 d8[0], r4
108b14ee| 1 gnu vmov.32 r8, d4[0]
445ab0ee| 1 gnu vmov.f32 s10, s8
467bb0ee| 1 gnu vmov.f64 d7, d6
c68abdee| 1 gnu vcvt.s32.f32 s16, s12
c68abcee| 1 gnu vcvt.u32.f32 s16, s12
c68bbdee| 1 gnu vcvt.s32.f64 s16, d6
c68bbcee| 1 gnu vcvt.u32.f64 s16, d6
c68ab8ee| 1 gnu vcvt.f32.s32 s16, s12
468ab8ee| 1 gnu vcvt.f32.u32 s16, s12
c68bb8ee| 1 gnu vcvt.f64.s32 d8, s12
468bb8ee| 1 gnu vcvt.f64.u32 d8, s12
104b08ee| 1 plan9 MOVW R4, F8
108b14ee| 1 plan9 MOVW F4, R8
104a080e| 1 plan9 MOVW.EQ R4, F8
104a181e| 1 plan9 MOVW.NE F8, R4
904a181e| 1 plan9 MOVW.NE S17, R4
445ab0ee| 1 plan9 MOVF F4, F5
467bb0ee| 1 plan9 MOVD F6, F7
c68abdee| 1 plan9 MOVFW F6, F8
c68abcee| 1 plan9 MOVFW.U F6, F8
c68bbdee| 1 plan9 MOVDW F6, F8
c68bbcee| 1 plan9 MOVDW.U F6, F8
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
feffffea| 1 plan9 B 0x0
fcffffea| 1 plan9 B 0xfffffff8
......@@ -1446,34 +1490,34 @@ b310a2e0| 1 gnu strht r1, [r2], r3
b640ade0| 1 gnu strht r4, [sp], r6
b31022e0| 1 gnu strht r1, [r2], -r3
b6402de0| 1 gnu strht r4, [sp], -r6
00f020e3| 1 gnu nop
445ab0ee| 1 gnu vmov.f32 s10, s8
645af0ee| 1 gnu vmov.f32 s11, s9
467bb0ee| 1 gnu vmov.f64 d7, d6
104b08ee| 1 gnu vmov.32 d8[0], r4
104b28ee| 1 gnu vmov.32 d8[1], r4
108b14ee| 1 gnu vmov.32 r8, d4[0]
108b34ee| 1 gnu vmov.32 r8, d4[1]
c68abdee| 1 gnu vcvt.s32.f32 s16, s12
e68afdee| 1 gnu vcvt.s32.f32 s17, s13
c68abcee| 1 gnu vcvt.u32.f32 s16, s12
e68afcee| 1 gnu vcvt.u32.f32 s17, s13
c68bbdee| 1 gnu vcvt.s32.f64 s16, d6
c68bfdee| 1 gnu vcvt.s32.f64 s17, d6
c68bbcee| 1 gnu vcvt.u32.f64 s16, d6
c68bfcee| 1 gnu vcvt.u32.f64 s17, d6
c68ab8ee| 1 gnu vcvt.f32.s32 s16, s12
e68af8ee| 1 gnu vcvt.f32.s32 s17, s13
468ab8ee| 1 gnu vcvt.f32.u32 s16, s12
668af8ee| 1 gnu vcvt.f32.u32 s17, s13
c68bb8ee| 1 gnu vcvt.f64.s32 d8, s12
e68bb8ee| 1 gnu vcvt.f64.s32 d8, s13
468bb8ee| 1 gnu vcvt.f64.u32 d8, s12
668bb8ee| 1 gnu vcvt.f64.u32 d8, s13
c01ab7ee| 1 gnu vcvt.f64.f32 d1, s0
e01ab7ee| 1 gnu vcvt.f64.f32 d1, s1
c45bb7ee| 1 gnu vcvt.f32.f64 s10, d4
c65bf7ee| 1 gnu vcvt.f32.f64 s11, d6
00f020e3| 1 plan9 NOP
445ab0ee| 1 plan9 MOVF F4, F5
645af0ee| 1 plan9 MOVF S9, S11
467bb0ee| 1 plan9 MOVD F6, F7
104b08ee| 1 plan9 MOVW R4, F8
104b28ee| 1 plan9 MOVW R4, D8[1]
108b14ee| 1 plan9 MOVW F4, R8
108b34ee| 1 plan9 MOVW D4[1], R8
c68abdee| 1 plan9 MOVFW F6, F8
e68afdee| 1 plan9 MOVFW S13, S17
c68abcee| 1 plan9 MOVFW.U F6, F8
e68afcee| 1 plan9 MOVFW.U S13, S17
c68bbdee| 1 plan9 MOVDW F6, F8
c68bfdee| 1 plan9 MOVDW F6, S17
c68bbcee| 1 plan9 MOVDW.U F6, F8
c68bfcee| 1 plan9 MOVDW.U F6, S17
c68ab8ee| 1 plan9 MOVWF F6, F8
e68af8ee| 1 plan9 MOVWF S13, S17
468ab8ee| 1 plan9 MOVWF.U F6, F8
668af8ee| 1 plan9 MOVWF.U S13, S17
c68bb8ee| 1 plan9 MOVWD F6, F8
e68bb8ee| 1 plan9 MOVWD S13, F8
468bb8ee| 1 plan9 MOVWD.U F6, F8
668bb8ee| 1 plan9 MOVWD.U S13, F8
c01ab7ee| 1 plan9 MOVFD F0, F1
e01ab7ee| 1 plan9 MOVFD S1, F1
c45bb7ee| 1 plan9 MOVDF F4, F5
c65bf7ee| 1 plan9 MOVDF F6, S11
102083e6| 1 gnu pkhbt r2, r3, r0
102283e6| 1 gnu pkhbt r2, r3, r0, lsl #4
502083e6| 1 gnu pkhtb r2, r3, r0, asr #32
......@@ -1525,8 +1569,8 @@ f92f73e6| 1 gnu uhsub8 r2, r3, r9
532f34e6| 1 gnu shsax r2, r4, r3
332f74e6| 1 gnu uhasx r2, r4, r3
532f74e6| 1 gnu uhsax r2, r4, r3
dc51afe7| 1 gnu sbfx r5, ip, #3, #16
dc51efe7| 1 gnu ubfx r5, ip, #3, #16
dc51afe7| 1 plan9 SBFX $16, $3, R12, R5
dc51efe7| 1 plan9 UBFX $16, $3, R12, R5
b12f88e6| 1 gnu sel r2, r8, r1
000201f1| 1 gnu setend be
000001f1| 1 gnu setend le
......@@ -1537,18 +1581,18 @@ b12f88e6| 1 gnu sel r2, r8, r1
1155eae6| 1 gnu usat r5, #10, r1, lsl #10
5155eae6| 1 gnu usat r5, #10, r1, asr #10
335feae6| 1 gnu usat16 r5, #10, r3
7788a9e6| 1 gnu sxtab r8, r9, r7, ror #16
778889e6| 1 gnu sxtab16 r8, r9, r7, ror #16
7788b9e6| 1 gnu sxtah r8, r9, r7, ror #16
7784afe6| 1 gnu sxtb r8, r7, ror #8
778c8fe6| 1 gnu sxtb16 r8, r7, ror #24
7780bfe6| 1 gnu sxth r8, r7
7788e9e6| 1 gnu uxtab r8, r9, r7, ror #16
7788c9e6| 1 gnu uxtab16 r8, r9, r7, ror #16
7788f9e6| 1 gnu uxtah r8, r9, r7, ror #16
7784efe6| 1 gnu uxtb r8, r7, ror #8
778ccfe6| 1 gnu uxtb16 r8, r7, ror #24
7780ffe6| 1 gnu uxth r8, r7
7788a9e6| 1 plan9 SXTAB R7@>$16, R9, R8
778889e6| 1 plan9 SXTAB16 R7@>$16, R9, R8
7788b9e6| 1 plan9 SXTAH R7@>$16, R9, R8
7784afe6| 1 plan9 MOVBS R7@>$8, R8
778c8fe6| 1 plan9 SXTB16 R7@>$24, R8
7780bf16| 1 plan9 MOVHS.NE R7, R8
7788e906| 1 plan9 UXTAB.EQ R7@>$16, R9, R8
7788c9e6| 1 plan9 UXTAB16 R7@>$16, R9, R8
7788f9e6| 1 plan9 UXTAH R7@>$16, R9, R8
7784efe6| 1 plan9 MOVBU R7@>$8, R8
778ccfe6| 1 plan9 UXTB16 R7@>$24, R8
7780ffe6| 1 plan9 MOVHU R7, R8
11f288e7| 1 gnu usad8 r8, r1, r2
112388e7| 1 gnu usada8 r8, r1, r3, r2
02f020e3| 1 gnu wfe
......
......@@ -7,12 +7,14 @@ package arm64asm
import (
"encoding/hex"
"io/ioutil"
"path/filepath"
"strings"
"testing"
)
func TestDecode(t *testing.T) {
data, err := ioutil.ReadFile("testdata/cases.txt")
func testDecode(t *testing.T, syntax string) {
input := filepath.Join("testdata", syntax+"cases.txt")
data, err := ioutil.ReadFile(input)
if err != nil {
t.Fatal(err)
}
......@@ -25,7 +27,7 @@ func TestDecode(t *testing.T) {
if line == "" || strings.HasPrefix(line, "#") {
continue
}
f := strings.SplitN(line, "\t", 3)
f := strings.SplitN(line, "\t", 2)
i := strings.Index(f[0], "|")
if i < 0 {
t.Errorf("parsing %q: missing | separator", f[0])
......@@ -39,7 +41,7 @@ func TestDecode(t *testing.T) {
t.Errorf("parsing %q: %v", f[0], err)
continue
}
syntax, asm := f[1], f[2]
asm := f[1]
inst, decodeErr := Decode(code)
if decodeErr != nil && decodeErr != errUnknown {
// Some rarely used system instructions are not supported
......@@ -71,8 +73,16 @@ func TestDecode(t *testing.T) {
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
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 (
"encoding/json"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
......@@ -220,7 +222,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name()
f.Seek(start, 0)
f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f)
defer w.Flush()
size = 0
......@@ -565,9 +567,10 @@ func hexCases(t *testing.T, encoded string) func(func([]byte)) {
// testdataCases generates the test cases recorded in testdata/cases.txt.
// 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
data, err := ioutil.ReadFile("testdata/cases.txt")
input := filepath.Join("testdata", syntax+"cases.txt")
data, err := ioutil.ReadFile(input)
if err != nil {
t.Fatal(err)
}
......
......@@ -536,8 +536,13 @@ type MemExtend struct {
Base RegSP
Index Reg
Extend ExtShift
// Amount indicates the index shift amount (but also see ShiftMustBeZero field below).
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() {}
......@@ -545,7 +550,7 @@ func (MemExtend) isArg() {}
func (m MemExtend) String() string {
Rbase := m.Base.String()
RIndex := m.Index.String()
if m.Absent {
if m.ShiftMustBeZero {
if m.Amount != 0 {
return fmt.Sprintf("[%s,%s,%s #0]", Rbase, RIndex, m.Extend.String())
} else {
......
......@@ -9,10 +9,15 @@ import (
"testing"
)
func TestObjdumpARM64Testdata(t *testing.T) { testObjdumpARM64(t, testdataCases(t)) }
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)) }
func TestObjdumpARM64TestDecodeGNUSyntaxdata(t *testing.T) {
testObjdumpARM64(t, testdataCases(t, "gnu"))
}
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.
// 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 {
// writeELF64 writes an ELF64 header to the file, describing a text
// segment that starts at start (0x8000) and extends for size bytes.
func writeELF64(f *os.File, size int) error {
f.Seek(0, 0)
f.Seek(0, io.SeekStart)
var hdr elf.Header64
var prog elf.Prog64
var sect elf.Section64
......
......@@ -53,7 +53,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
// Move addressing mode into opcode suffix.
suffix := ""
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) {
case MemImmediate:
switch mem.Mode {
......@@ -114,6 +114,8 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
rno = int(a)
case RegisterWithArrangementAndIndex:
op = "VMOV"
case RegisterWithArrangement:
op = "VMOV"
}
if rno >= 0 && rno <= int(WZR) {
op = "MOVW"
......@@ -133,6 +135,12 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
}
if rno <= uint16(WZR) {
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 {
op = "MOVD" + suffix
}
......@@ -173,6 +181,12 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
}
if rno <= uint16(WZR) {
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 {
op = "MOVD" + suffix
}
......@@ -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]
case LDAXP, LDXP:
if r, ok := inst.Args[0].(Reg); ok {
rno := uint16(r)
if rno <= uint16(WZR) {
op += "W"
}
}
fallthrough
case STP, LDP:
args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1])
args[1] = args[2]
......@@ -239,8 +262,21 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
} else if op == "LDP" {
op = op + suffix
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:
args[0], args[1] = args[1], args[0]
fallthrough
......@@ -251,7 +287,10 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
}
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 {
rno := uint16(r)
if rno >= uint16(S0) && rno <= uint16(S31) {
......@@ -337,6 +376,19 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
addr := int64(inst.Args[1].(PCRel))
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:
index := sort.SearchStrings(noSuffixOpSet, op)
if !(index < len(noSuffixOpSet) && noSuffixOpSet[index] == op) {
......@@ -350,6 +402,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
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) {
// Add "w" to opcode suffix.
op += "W"
......@@ -381,6 +436,10 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
// No need add "W" to opcode suffix.
// Opcode must be inserted in ascending order.
var noSuffixOpSet = strings.Fields(`
AESD
AESE
AESIMC
AESMC
CRC32B
CRC32CB
CRC32CH
......@@ -393,8 +452,19 @@ LDARB
LDARH
LDAXRB
LDAXRH
LDTRH
LDXRB
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 {
......@@ -423,9 +493,14 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
regno := uint16(a) & 31
if regenum >= uint16(B0) && regenum <= uint16(D31) {
// FP registers are the same ones as SIMD registers
// Print Fn for scalar variant to align with assembler (e.g., FCVT)
return fmt.Sprintf("F%d", regno)
if strings.HasPrefix(inst.Op.String(), "F") || strings.HasSuffix(inst.Op.String(), "CVTF") {
// FP registers are the same ones as SIMD registers
// 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) {
// Print Vn to align with assembler (e.g., SHA256H)
return fmt.Sprintf("V%d", regno)
......@@ -503,7 +578,6 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
case MemExtend:
base := ""
index := ""
extend := ""
indexreg := ""
regno := uint16(a.Base) & 31
if regno == 31 {
......@@ -517,15 +591,28 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
} else {
indexreg = fmt.Sprintf("R%d", regno)
}
if a.Extend == lsl {
if a.Amount != 0 {
extend = fmt.Sprintf("<<%d", a.Amount)
// a.Amount indicates the index shift amount, encoded in "S" field.
// 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 {
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:
switch arg.String() {
......@@ -592,7 +679,7 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
result := a.r.String()
arrange := a.a.String()
result += arrange
if a.cnt > 0 {
if a.cnt > 1 {
result = "[" + result
for i := 1; i < int(a.cnt); i++ {
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
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)
case Imm_prfop:
if strings.Contains(a.String(), "#") {
return fmt.Sprintf("$%d", a)
}
}
return strings.ToUpper(arg.String())
......
go test command:
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 '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 '.*'
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 (
"encoding/hex"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
......@@ -194,7 +195,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name()
f.Seek(start, 0)
f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f)
defer w.Flush()
size = 0
......
......@@ -188,7 +188,7 @@ func parseContinuation(line []byte, enc []byte) []byte {
// describing a text segment that starts at start
// and extends for size bytes.
func writeELF64(f *os.File, size int) error {
f.Seek(0, 0)
f.Seek(0, io.SeekStart)
var hdr elf.Header64
var prog elf.Prog64
var sect elf.Section64
......
......@@ -12,6 +12,7 @@ import (
"encoding/hex"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
......@@ -194,7 +195,7 @@ func writeInst(generate func(func([]byte))) (file string, f *os.File, size int,
file = f.Name()
f.Seek(start, 0)
f.Seek(start, io.SeekStart)
w := bufio.NewWriter(f)
defer w.Flush()
size = 0
......
......@@ -176,7 +176,7 @@ func parseContinuation(line []byte, enc []byte) []byte {
// describing a text segment that starts at start
// and extends for size bytes.
func writeELF32(f *os.File, size int) error {
f.Seek(0, 0)
f.Seek(0, io.SeekStart)
var hdr elf.Header32
var prog elf.Prog32
var sect elf.Section32
......@@ -246,7 +246,7 @@ func writeELF32(f *os.File, size int) error {
// describing a text segment that starts at start
// and extends for size bytes.
func writeELF64(f *os.File, size int) error {
f.Seek(0, 0)
f.Seek(0, io.SeekStart)
var hdr elf.Header64
var prog elf.Prog64
var sect elf.Section64
......
......@@ -15,26 +15,26 @@
{
"canonical": "golang.org/x/arch/x86/x86asm",
"local": "golang.org/x/arch/x86/x86asm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2",
"revisionTime": "2017-12-26T02:13:20Z"
"revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6",
"revisionTime": "2018-04-06T10:28:20Z"
},
{
"canonical": "golang.org/x/arch/arm/armasm",
"local": "golang.org/x/arch/arm/armasm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2",
"revisionTime": "2017-12-26T02:13:20Z"
"revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6",
"revisionTime": "2018-04-06T10:28:20Z"
},
{
"canonical": "golang.org/x/arch/ppc64/ppc64asm",
"local": "golang.org/x/arch/ppc64/ppc64asm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2",
"revisionTime": "2017-12-26T02:13:20Z"
"revision": "5099b4b992f2813e39cfe2623c6f638718bd0fc6",
"revisionTime": "2018-04-06T10:28:20Z"
},
{
"canonical": "golang.org/x/arch/arm64/arm6464asm",
"local": "golang.org/x/arch/arm64/arm64asm",
"revision": "98fd8d9907002617e6000a77c0740a72947ca1c2",
"revisionTime": "2017-12-26T02:13:20Z"
"revision": "9111c30535f37e70dcaf5956d34b03233f90f3b6",
"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