Commit 7bd1c210 authored by Keith Randall's avatar Keith Randall

cmd/vendor/arch/x86: pull new version from x repo

Copied by hand.

Update #17410
Update #19142
Fixes #19986

Change-Id: I21d16d254161c75466b31c670f3b2c8c463abd66
Reviewed-on: https://go-review.googlesource.com/41205
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 8aa31d5d
......@@ -84,6 +84,7 @@ const (
xArgImm16u // arg imm8 but record as unsigned
xArgM // arg m
xArgM128 // arg m128
xArgM256 // arg m256
xArgM1428byte // arg m14/28byte
xArgM16 // arg m16
xArgM16and16 // arg m16&16
......@@ -155,12 +156,14 @@ const (
xArgXmm1 // arg xmm1
xArgXmm2 // arg xmm2
xArgXmm2M128 // arg xmm2/m128
xArgYmm2M256 // arg ymm2/m256
xArgXmm2M16 // arg xmm2/m16
xArgXmm2M32 // arg xmm2/m32
xArgXmm2M64 // arg xmm2/m64
xArgXmmM128 // arg xmm/m128
xArgXmmM32 // arg xmm/m32
xArgXmmM64 // arg xmm/m64
xArgYmm1 // arg ymm1
xArgRmf16 // arg r/m16 but force mod=3
xArgRmf32 // arg r/m32 but force mod=3
xArgRmf64 // arg r/m64 but force mod=3
......@@ -258,6 +261,8 @@ func decode1(src []byte, mode int, gnuCompat bool) (Inst, error) {
rex Prefix // rex byte if present (or 0)
rexUsed Prefix // bits used in rex byte
rexIndex = -1 // index of rex byte
vex Prefix // use vex encoding
vexIndex = -1 // index of vex prefix
addrMode = mode // address mode (width in bits)
dataMode = mode // operand mode (width in bits)
......@@ -398,6 +403,33 @@ ReadPrefixes:
inst.Prefix[addrSizeIndex] |= PrefixIgnored
}
addrSizeIndex = pos
//Group 5 - Vex encoding
case 0xC5:
if pos == 0 && (mode == 64 || (mode == 32 && pos+1 < len(src) && src[pos+1]&0xc0 == 0xc0)) {
vex = p
vexIndex = pos
inst.Prefix[pos] = p
inst.Prefix[pos+1] = Prefix(src[pos+1])
pos += 1
continue
} else {
nprefix = pos
break ReadPrefixes
}
case 0xC4:
if pos == 0 && (mode == 64 || (mode == 32 && pos+2 < len(src) && src[pos+1]&0xc0 == 0xc0)) {
vex = p
vexIndex = pos
inst.Prefix[pos] = p
inst.Prefix[pos+1] = Prefix(src[pos+1])
inst.Prefix[pos+2] = Prefix(src[pos+2])
pos += 2
continue
} else {
nprefix = pos
break ReadPrefixes
}
}
if pos >= len(inst.Prefix) {
......@@ -408,7 +440,7 @@ ReadPrefixes:
}
// Read REX prefix.
if pos < len(src) && mode == 64 && Prefix(src[pos]).IsREX() {
if pos < len(src) && mode == 64 && Prefix(src[pos]).IsREX() && vex == 0 {
rex = Prefix(src[pos])
rexIndex = pos
if pos >= len(inst.Prefix) {
......@@ -514,11 +546,11 @@ Decode:
scale = sib >> 6
index = (sib >> 3) & 07
base = sib & 07
if rex&PrefixREXB != 0 {
if rex&PrefixREXB != 0 || vex == 0xC4 && inst.Prefix[vexIndex+1]&0x20 == 0 {
rexUsed |= PrefixREXB
base |= 8
}
if rex&PrefixREXX != 0 {
if rex&PrefixREXX != 0 || vex == 0xC4 && inst.Prefix[vexIndex+1]&0x40 == 0 {
rexUsed |= PrefixREXX
index |= 8
}
......@@ -779,6 +811,34 @@ Decode:
if rex&prefix == prefix {
ok = true
}
} else if prefix == 0xC5 || prefix == 0xC4 {
if vex == prefix {
ok = true
}
} else if vex != 0 && (prefix == 0x0F || prefix == 0x0F38 || prefix == 0x0F3A ||
prefix == 0x66 || prefix == 0xF2 || prefix == 0xF3) {
var vexM, vexP Prefix
if vex == 0xC5 {
vexM = 1 // 2 byte vex always implies 0F
vexP = inst.Prefix[vexIndex+1]
} else {
vexM = inst.Prefix[vexIndex+1]
vexP = inst.Prefix[vexIndex+2]
}
switch prefix {
case 0x66:
ok = vexP&3 == 1
case 0xF3:
ok = vexP&3 == 2
case 0xF2:
ok = vexP&3 == 3
case 0x0F:
ok = vexM&3 == 1
case 0x0F38:
ok = vexM&3 == 2
case 0x0F3A:
ok = vexM&3 == 3
}
} else {
if prefix == 0xF3 {
sawF3 = true
......@@ -993,6 +1053,7 @@ Decode:
case xArgM,
xArgM128,
xArgM256,
xArgM1428byte,
xArgM16,
xArgM16and16,
......@@ -1041,7 +1102,7 @@ Decode:
case xArgMoffs8, xArgMoffs16, xArgMoffs32, xArgMoffs64:
// TODO(rsc): Can address be 64 bits?
mem = Mem{Disp: immc}
mem = Mem{Disp: int64(immc)}
if segIndex >= 0 {
mem.Segment = prefixToSegment(inst.Prefix[segIndex])
inst.Prefix[segIndex] |= PrefixImplicit
......@@ -1054,6 +1115,15 @@ Decode:
}
narg++
case xArgYmm1:
base := baseReg[x]
index := Reg(regop)
if inst.Prefix[vexIndex+1]&0x80 == 0 {
index += 8
}
inst.Args[narg] = base + index
narg++
case xArgR8, xArgR16, xArgR32, xArgR64, xArgXmm, xArgXmm1, xArgDR0dashDR7:
base := baseReg[x]
index := Reg(regop)
......@@ -1115,10 +1185,10 @@ Decode:
}
inst.Args[narg] = base + index
narg++
case xArgRM8, xArgRM16, xArgRM32, xArgRM64, xArgR32M16, xArgR32M8, xArgR64M16,
xArgMmM32, xArgMmM64, xArgMm2M64,
xArgXmm2M16, xArgXmm2M32, xArgXmm2M64, xArgXmmM64, xArgXmmM128, xArgXmmM32, xArgXmm2M128:
xArgXmm2M16, xArgXmm2M32, xArgXmm2M64, xArgXmmM64, xArgXmmM128, xArgXmmM32, xArgXmm2M128,
xArgYmm2M256:
if haveMem {
inst.Args[narg] = mem
inst.MemBytes = int(memBytes[decodeOp(x)])
......@@ -1139,6 +1209,10 @@ Decode:
index -= 4
base = SPB
}
case xArgYmm2M256:
if vex == 0xC4 && inst.Prefix[vexIndex+1]&0x40 == 0x40 {
index += 8
}
}
inst.Args[narg] = base + index
}
......@@ -1522,8 +1596,10 @@ var baseReg = [...]Reg{
xArgSTi: F0,
xArgTR0dashTR7: TR0,
xArgXmm1: X0,
xArgYmm1: X0,
xArgXmm2: X0,
xArgXmm2M128: X0,
xArgYmm2M256: X0,
xArgXmm2M16: X0,
xArgXmm2M32: X0,
xArgXmm2M64: X0,
......@@ -1579,6 +1655,7 @@ var fixedArg = [...]Arg{
// by a memory argument of the given form.
var memBytes = [...]int8{
xArgM128: 128 / 8,
xArgM256: 256 / 8,
xArgM16: 16 / 8,
xArgM16and16: (16 + 16) / 8,
xArgM16colon16: (16 + 16) / 8,
......@@ -1607,6 +1684,7 @@ var memBytes = [...]int8{
xArgRM64: 64 / 8,
xArgRM8: 8 / 8,
xArgXmm2M128: 128 / 8,
xArgYmm2M256: 256 / 8,
xArgXmm2M16: 16 / 8,
xArgXmm2M32: 32 / 8,
xArgXmm2M64: 64 / 8,
......
......@@ -432,7 +432,7 @@ SuffixLoop:
}
}
for _, p := range inst.Prefix {
if p == 0 {
if p == 0 || p.IsVEX() {
break
}
if p&PrefixImplicit != 0 {
......@@ -530,6 +530,8 @@ func gnuArg(inst *Inst, x Arg, usedPrefixes *bool) string {
if x == DX {
return "(%dx)"
}
case VMOVDQA, VMOVDQU, VMOVNTDQA, VMOVNTDQ:
return strings.Replace(gccRegName[x], "xmm", "ymm", -1)
}
return gccRegName[x]
case Mem:
......
......@@ -77,6 +77,8 @@ const (
PrefixREXR Prefix = 0x04 // extension bit R (r field in modrm)
PrefixREXX Prefix = 0x02 // extension bit X (index field in sib)
PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
PrefixVEX2Bytes Prefix = 0xC5 // Short form of vex prefix
PrefixVEX3Bytes Prefix = 0xC4 // Long form of vex prefix
)
// IsREX reports whether p is a REX prefix byte.
......@@ -84,6 +86,10 @@ func (p Prefix) IsREX() bool {
return p&0xF0 == PrefixREX
}
func (p Prefix) IsVEX() bool {
return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes
}
func (p Prefix) String() string {
p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
if s := prefixNames[p]; s != "" {
......
......@@ -88,6 +88,13 @@ func IntelSyntax(inst Inst) string {
if p.IsREX() {
inst.Prefix[i] |= PrefixImplicit
}
if p.IsVEX() {
if p == PrefixVEX3Bytes {
inst.Prefix[i+2] |= PrefixImplicit
}
inst.Prefix[i] |= PrefixImplicit
inst.Prefix[i+1] |= PrefixImplicit
}
}
}
......@@ -353,6 +360,8 @@ func intelArg(inst *Inst, arg Arg) string {
prefix = "qword "
case 16:
prefix = "xmmword "
case 32:
prefix = "ymmword "
}
switch inst.Op {
case INVLPG:
......@@ -434,9 +443,14 @@ func intelArg(inst *Inst, arg Arg) string {
return fmt.Sprintf(".%+#x", int64(a))
case Reg:
if int(a) < len(intelReg) && intelReg[a] != "" {
switch inst.Op {
case VMOVDQA, VMOVDQU, VMOVNTDQA, VMOVNTDQ:
return strings.Replace(intelReg[a], "xmm", "ymm", -1)
default:
return intelReg[a]
}
}
}
return strings.ToLower(arg.String())
}
......
......@@ -29,20 +29,32 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
args = append(args, plan9Arg(&inst, pc, symname, a))
}
var rep string
var last Prefix
for _, p := range inst.Prefix {
if p == 0 || p.IsREX() {
if p == 0 || p.IsREX() || p.IsVEX() {
break
}
switch {
// Don't show prefixes implied by the instruction text.
case p&0xFF00 == PrefixImplicit:
continue
// Only REP and REPN are recognized repeaters. Plan 9 syntax
// treats them as separate opcodes.
case p&0xFF == PrefixREP:
rep = "REP; "
case p&0xFF == PrefixREPN:
rep = "REPNE; "
default:
last = p
}
}
prefix := ""
switch last & 0xFF {
case 0, 0x66, 0x67:
// ignore
case PrefixREPN:
prefix += "REPNE "
default:
prefix += last.String() + " "
}
......@@ -69,7 +81,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
op += " " + strings.Join(args, ", ")
}
return prefix + op
return rep + prefix + op
}
func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
......
......@@ -15,8 +15,8 @@
{
"canonical": "golang.org/x/arch/x86/x86asm",
"local": "golang.org/x/arch/x86/x86asm",
"revision": "ad6a463afcf9bd5b38c81fa9ba612dae11859d40",
"revisionTime": "2015-08-28T15:42:14Z"
"revision": "58ea1a195b1a354bcd572b7ef6bbbd264dc63732",
"revisionTime": "2017-02-16T08:17:04Z"
},
{
"canonical": "golang.org/x/arch/arm/armasm",
......
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