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