Commit 5437cde9 authored by isharipo's avatar isharipo Committed by Ilya Tocar

cmd/asm: enable AVX512

- Uncomment tests for AVX512 encoder
- Permit instruction suffixes for x86
- Permit limited reg list [reg-reg] syntax for x86 for multi-source ops
- EVEX encoding support in obj/x86 (Z-cases, asmevex, etc.)
- optabs and ytabs generated by x86avxgen (https://golang.org/cl/107216)

Note: suffix formatting implemented with updated CConv function.
Now arch asm backend should register formatting function by
calling RegisterOpSuffix.

Updates #22779

Change-Id: I076a167ee49582700e058c56ad74e6696710c8c8
Reviewed-on: https://go-review.googlesource.com/113315
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarCherry Zhang <cherryyz@google.com>
parent 8a85bce2
......@@ -13,6 +13,7 @@ import (
"cmd/asm/internal/flags"
"cmd/asm/internal/lex"
"cmd/internal/obj"
"cmd/internal/obj/x86"
"cmd/internal/objabi"
"cmd/internal/sys"
)
......@@ -38,6 +39,12 @@ func (p *Parser) append(prog *obj.Prog, cond string, doLabel bool) {
return
}
case sys.AMD64, sys.I386:
if err := x86.ParseSuffix(prog, cond); err != nil {
p.errorf("%v", err)
return
}
default:
p.errorf("unrecognized suffix .%q", cond)
return
......@@ -740,6 +747,12 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.To = a[4]
break
}
if p.arch.Family == sys.AMD64 {
prog.From = a[0]
prog.RestArgs = []obj.Addr{a[1], a[2], a[3]}
prog.To = a[4]
break
}
p.errorf("can't handle %s instruction with 5 operands", op)
return
case 6:
......
......@@ -97,10 +97,6 @@ var badExprTests = []badExprTest{
}
func TestBadExpr(t *testing.T) {
panicOnError = true
defer func() {
panicOnError = false
}()
for i, test := range badExprTests {
err := runBadTest(i, test, t)
if err == nil {
......@@ -119,13 +115,7 @@ func TestBadExpr(t *testing.T) {
func runBadTest(i int, test badExprTest, t *testing.T) (err error) {
p := NewParser(nil, nil, nil) // Expression evaluation uses none of these fields of the parser.
p.start(lex.Tokenize(test.input))
defer func() {
e := recover()
var ok bool
if err, ok = e.(error); e != nil && !ok {
t.Fatal(e)
}
}()
p.expr()
return nil
return tryParse(t, func() {
p.expr()
})
}
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package asm
import (
"cmd/asm/internal/lex"
"strings"
"testing"
)
type badInstTest struct {
input, error string
}
func TestAMD64BadInstParser(t *testing.T) {
testBadInstParser(t, "amd64", []badInstTest{
// Test AVX512 suffixes.
{"VADDPD.A X0, X1, X2", `unknown suffix "A"`},
{"VADDPD.A.A X0, X1, X2", `unknown suffix "A"; duplicate suffix "A"`},
{"VADDPD.A.A.A X0, X1, X2", `unknown suffix "A"; duplicate suffix "A"`},
{"VADDPD.A.B X0, X1, X2", `unknown suffix "A"; unknown suffix "B"`},
{"VADDPD.Z.A X0, X1, X2", `Z suffix should be the last; unknown suffix "A"`},
{"VADDPD.Z.Z X0, X1, X2", `Z suffix should be the last; duplicate suffix "Z"`},
{"VADDPD.SAE.BCST X0, X1, X2", `can't combine rounding/SAE and broadcast`},
{"VADDPD.BCST.SAE X0, X1, X2", `can't combine rounding/SAE and broadcast`},
{"VADDPD.BCST.Z.SAE X0, X1, X2", `Z suffix should be the last; can't combine rounding/SAE and broadcast`},
{"VADDPD.SAE.SAE X0, X1, X2", `duplicate suffix "SAE"`},
{"VADDPD.RZ_SAE.SAE X0, X1, X2", `bad suffix combination`},
})
}
func testBadInstParser(t *testing.T, goarch string, tests []badInstTest) {
for i, test := range tests {
arch, ctxt := setArch(goarch)
tokenizer := lex.NewTokenizer("", strings.NewReader(test.input+"\n"), nil)
parser := NewParser(ctxt, arch, tokenizer)
err := tryParse(t, func() {
parser.start(lex.Tokenize(test.input))
parser.line()
})
switch {
case err == nil:
t.Errorf("#%d: %q: want error %q; have none", i, test.input, test.error)
case !strings.Contains(err.Error(), test.error):
t.Errorf("#%d: %q: want error %q; have %q", i, test.input, test.error, err)
}
}
}
......@@ -5,6 +5,7 @@
package asm
import (
"strings"
"testing"
"cmd/asm/internal/arch"
......@@ -30,6 +31,45 @@ func newParser(goarch string) *Parser {
return NewParser(ctxt, architecture, nil)
}
// tryParse executes parse func in panicOnError=true context.
// parse is expected to call any parsing methods that may panic.
// Returns error gathered from recover; nil if no parse errors occured.
//
// For unexpected panics, calls t.Fatal.
func tryParse(t *testing.T, parse func()) (err error) {
panicOnError = true
defer func() {
panicOnError = false
e := recover()
var ok bool
if err, ok = e.(error); e != nil && !ok {
t.Fatal(e)
}
}()
parse()
return nil
}
func testBadOperandParser(t *testing.T, parser *Parser, tests []badOperandTest) {
for _, test := range tests {
err := tryParse(t, func() {
parser.start(lex.Tokenize(test.input))
addr := obj.Addr{}
parser.operand(&addr)
})
switch {
case err == nil:
t.Errorf("fail at %s: got no errors; expected %s\n", test.input, test.error)
case !strings.Contains(err.Error(), test.error):
t.Errorf("fail at %s: got %s; expected %s", test.input, err, test.error)
}
}
}
func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {
for _, test := range tests {
parser.start(lex.Tokenize(test.input))
......@@ -45,6 +85,7 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {
func TestAMD64OperandParser(t *testing.T) {
parser := newParser("amd64")
testOperandParser(t, parser, amd64OperandTests)
testBadOperandParser(t, parser, amd64BadOperandTests)
}
func Test386OperandParser(t *testing.T) {
......@@ -85,6 +126,10 @@ type operandTest struct {
input, output string
}
type badOperandTest struct {
input, error string
}
// Examples collected by scanning all the assembly in the standard repo.
var amd64OperandTests = []operandTest{
......@@ -202,9 +247,28 @@ var amd64OperandTests = []operandTest{
{"y+56(FP)", "y+56(FP)"},
{"·AddUint32(SB)", "\"\".AddUint32(SB)"},
{"·callReflect(SB)", "\"\".callReflect(SB)"},
{"[X0-X0]", "[X0-X0]"},
{"[ Z9 - Z12 ]", "[Z9-Z12]"},
{"[X0-AX]", "[X0-AX]"},
{"[AX-X0]", "[AX-X0]"},
{"[):[o-FP", ""}, // Issue 12469 - asm hung parsing the o-FP range on non ARM platforms.
}
var amd64BadOperandTests = []badOperandTest{
{"[", "register list: expected ']', found EOF"},
{"[4", "register list: bad low register in `[4`"},
{"[]", "register list: bad low register in `[]`"},
{"[f-x]", "register list: bad low register in `[f`"},
{"[r10-r13]", "register list: bad low register in `[r10`"},
{"[k3-k6]", "register list: bad low register in `[k3`"},
{"[X0]", "register list: expected '-' after `[X0`, found ']'"},
{"[X0-]", "register list: bad high register in `[X0-]`"},
{"[X0-x]", "register list: bad high register in `[X0-x`"},
{"[X0-X1-X2]", "register list: expected ']' after `[X0-X1`, found '-'"},
{"[X0,X3]", "register list: expected '-' after `[X0`, found ','"},
{"[X0,X1,X2,X3]", "register list: expected '-' after `[X0`, found ','"},
}
var x86OperandTests = []operandTest{
{"$(2.928932188134524e-01)", "$(0.29289321881345243)"},
{"$-1", "$-1"},
......
......@@ -19,6 +19,7 @@ import (
"cmd/asm/internal/flags"
"cmd/asm/internal/lex"
"cmd/internal/obj"
"cmd/internal/obj/x86"
"cmd/internal/src"
"cmd/internal/sys"
)
......@@ -134,12 +135,12 @@ func (p *Parser) line() bool {
for {
tok = p.lex.Next()
if len(operands) == 0 && len(items) == 0 {
if p.arch.InFamily(sys.ARM, sys.ARM64) && tok == '.' {
// ARM conditionals.
if p.arch.InFamily(sys.ARM, sys.ARM64, sys.AMD64, sys.I386) && tok == '.' {
// Suffixes: ARM conditionals or x86 modifiers.
tok = p.lex.Next()
str := p.lex.Text()
if tok != scanner.Ident {
p.errorf("ARM condition expected identifier, found %s", str)
p.errorf("instruction suffix expected identifier, found %s", str)
}
cond = cond + "." + str
continue
......@@ -827,8 +828,25 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
// registers, as in [R1,R3-R5] or [V1.S4, V2.S4, V3.S4, V4.S4].
// For ARM, only R0 through R15 may appear.
// For ARM64, V0 through V31 with arrangement may appear.
//
// For 386/AMD64 register list specifies 4VNNIW-style multi-source operand.
// For range of 4 elements, Intel manual uses "+3" notation, for example:
// VP4DPWSSDS zmm1{k1}{z}, zmm2+3, m128
// Given asm line:
// VP4DPWSSDS Z5, [Z10-Z13], (AX)
// zmm2 is Z10, and Z13 is the only valid value for it (Z10+3).
// Only simple ranges are accepted, like [Z0-Z3].
//
// The opening bracket has been consumed.
func (p *Parser) registerList(a *obj.Addr) {
if p.arch.InFamily(sys.I386, sys.AMD64) {
p.registerListX86(a)
} else {
p.registerListARM(a)
}
}
func (p *Parser) registerListARM(a *obj.Addr) {
// One range per loop.
var maxReg int
var bits uint16
......@@ -923,6 +941,39 @@ ListLoop:
}
}
func (p *Parser) registerListX86(a *obj.Addr) {
// Accept only [RegA-RegB] syntax.
// Don't use p.get() to provide better error messages.
loName := p.next().String()
lo, ok := p.arch.Register[loName]
if !ok {
if loName == "EOF" {
p.errorf("register list: expected ']', found EOF")
} else {
p.errorf("register list: bad low register in `[%s`", loName)
}
return
}
if tok := p.next().ScanToken; tok != '-' {
p.errorf("register list: expected '-' after `[%s`, found %s", loName, tok)
return
}
hiName := p.next().String()
hi, ok := p.arch.Register[hiName]
if !ok {
p.errorf("register list: bad high register in `[%s-%s`", loName, hiName)
return
}
if tok := p.next().ScanToken; tok != ']' {
p.errorf("register list: expected ']' after `[%s-%s`, found %s", loName, hiName, tok)
}
a.Type = obj.TYPE_REGLIST
a.Reg = lo
a.Offset = x86.EncodeRegisterRange(lo, hi)
}
// register number is ARM-specific. It returns the number of the specified register.
func (p *Parser) registerNumber(name string) uint16 {
if p.arch.Family == sys.ARM && name == "g" {
......
......@@ -23,6 +23,10 @@ TEXT errors(SB),$0
// No VSIB for legacy instructions.
MOVL (AX)(X0*1), AX // ERROR "invalid instruction"
MOVL (AX)(Y0*1), AX // ERROR "invalid instruction"
// VSIB/VM is invalid without vector index.
// TODO(quasilyte): improve error message (#21860).
// "invalid VSIB address (missing vector index)"
VPGATHERQQ Y2, (BP), Y1 // ERROR "invalid instruction"
// AVX2GATHER mask/index/dest #UD cases.
VPGATHERQQ Y2, (BP)(X2*2), Y2 // ERROR "mask, index, and destination registers should be distinct"
VPGATHERQQ Y2, (BP)(X2*2), Y7 // ERROR "mask, index, and destination registers should be distinct"
......@@ -70,4 +74,62 @@ TEXT errors(SB),$0
MOVQ (AX), DR3 // ERROR "invalid instruction"
MOVQ (AX), DR6 // ERROR "invalid instruction"
MOVQ (AX), DR7 // ERROR "invalid instruction"
// AVX512GATHER index/index #UD cases.
VPGATHERQQ (BP)(X2*2), K1, X2 // ERROR "index and destination registers should be distinct"
VPGATHERQQ (BP)(Y15*2), K1, Y15 // ERROR "index and destination registers should be distinct"
VPGATHERQQ (BP)(Z20*2), K1, Z20 // ERROR "index and destination registers should be distinct"
VPGATHERDQ (BP)(X2*2), K1, X2 // ERROR "index and destination registers should be distinct"
VPGATHERDQ (BP)(X15*2), K1, Y15 // ERROR "index and destination registers should be distinct"
VPGATHERDQ (BP)(Y20*2), K1, Z20 // ERROR "index and destination registers should be distinct"
// Instructions without EVEX variant can't use High-16 registers.
VADDSUBPD X20, X1, X2 // ERROR "invalid instruction"
VADDSUBPS X0, X20, X2 // ERROR "invalid instruction"
// Use of K0 for write mask (Yknot0).
// TODO(quasilyte): improve error message (#21860).
// "K0 can't be used for write mask"
VADDPD X0, X1, K0, X2 // ERROR "invalid instruction"
VADDPD Y0, Y1, K0, Y2 // ERROR "invalid instruction"
VADDPD Z0, Z1, K0, Z2 // ERROR "invalid instruction"
// VEX-encoded VSIB can't use High-16 registers as index (unlike EVEX).
// TODO(quasilyte): improve error message (#21860).
VPGATHERQQ X2, (BP)(X20*2), X3 // ERROR "invalid instruction"
VPGATHERQQ Y2, (BP)(Y20*2), Y3 // ERROR "invalid instruction"
// YzrMulti4 expects exactly 4 registers referenced by REG_LIST.
// TODO(quasilyte): improve error message (#21860).
V4FMADDPS (AX), [Z0-Z4], K1, Z7 // ERROR "invalid instruction"
V4FMADDPS (AX), [Z0-Z0], K1, Z7 // ERROR "invalid instruction"
// Invalid ranges in REG_LIST (low > high).
// TODO(quasilyte): improve error message (#21860).
V4FMADDPS (AX), [Z4-Z0], K1, Z7 // ERROR "invalid instruction"
V4FMADDPS (AX), [Z1-Z0], K1, Z7 // ERROR "invalid instruction"
// Mismatching registers in a range.
// TODO(quasilyte): improve error message (#21860).
V4FMADDPS (AX), [AX-Z3], K1, Z7 // ERROR "invalid instruction"
V4FMADDPS (AX), [Z0-AX], K1, Z7 // ERROR "invalid instruction"
// Usage of suffixes for non-EVEX instructions.
ADCB.Z $7, AL // ERROR "invalid instruction"
ADCB.RU_SAE $7, AL // ERROR "invalid instruction"
ADCB.RU_SAE.Z $7, AL // ERROR "invalid instruction"
// Usage of rounding with invalid operands.
VADDPD.RU_SAE X3, X2, K1, X1 // ERROR "unsupported rounding"
VADDPD.RD_SAE X3, X2, K1, X1 // ERROR "unsupported rounding"
VADDPD.RZ_SAE X3, X2, K1, X1 // ERROR "unsupported rounding"
VADDPD.RN_SAE X3, X2, K1, X1 // ERROR "unsupported rounding"
VADDPD.RU_SAE Y3, Y2, K1, Y1 // ERROR "unsupported rounding"
VADDPD.RD_SAE Y3, Y2, K1, Y1 // ERROR "unsupported rounding"
VADDPD.RZ_SAE Y3, Y2, K1, Y1 // ERROR "unsupported rounding"
VADDPD.RN_SAE Y3, Y2, K1, Y1 // ERROR "unsupported rounding"
// Unsupported SAE.
VMAXPD.SAE (AX), Z2, K1, Z1 // ERROR "illegal SAE with memory argument"
VADDPD.SAE X3, X2, K1, X1 // ERROR "unsupported SAE"
// Unsupported zeroing.
VFPCLASSPDX.Z $0, (AX), K2, K1 // ERROR "unsupported zeroing"
VFPCLASSPDY.Z $0, (AX), K2, K1 // ERROR "unsupported zeroing"
// Unsupported broadcast.
VFPCLASSSD.BCST $0, (AX), K2, K1 // ERROR "unsupported broadcast"
VFPCLASSSS.BCST $0, (AX), K2, K1 // ERROR "unsupported broadcast"
// Broadcast without memory operand.
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
RET
......@@ -3,28 +3,28 @@
#include "../../../../../../runtime/textflag.h"
TEXT asmtest_avx512_4vnniw(SB), NOSPLIT, $0
//TODO: VP4DPWSSD 7(SI)(DI*1), [Z2-Z5], K4, Z17 // 62e26f4c528c3e07000000
//TODO: VP4DPWSSD 15(DX)(BX*8), [Z2-Z5], K4, Z17 // 62e26f4c528cda0f000000
//TODO: VP4DPWSSD 7(SI)(DI*1), [Z12-Z15], K4, Z17 // 62e21f4c528c3e07000000
//TODO: VP4DPWSSD 15(DX)(BX*8), [Z12-Z15], K4, Z17 // 62e21f4c528cda0f000000
//TODO: VP4DPWSSD 7(SI)(DI*1), [Z22-Z25], K4, Z17 // 62e24f44528c3e07000000
//TODO: VP4DPWSSD 15(DX)(BX*8), [Z22-Z25], K4, Z17 // 62e24f44528cda0f000000
//TODO: VP4DPWSSD 7(SI)(DI*1), [Z2-Z5], K4, Z23 // 62e26f4c52bc3e07000000
//TODO: VP4DPWSSD 15(DX)(BX*8), [Z2-Z5], K4, Z23 // 62e26f4c52bcda0f000000
//TODO: VP4DPWSSD 7(SI)(DI*1), [Z12-Z15], K4, Z23 // 62e21f4c52bc3e07000000
//TODO: VP4DPWSSD 15(DX)(BX*8), [Z12-Z15], K4, Z23 // 62e21f4c52bcda0f000000
//TODO: VP4DPWSSD 7(SI)(DI*1), [Z22-Z25], K4, Z23 // 62e24f4452bc3e07000000
//TODO: VP4DPWSSD 15(DX)(BX*8), [Z22-Z25], K4, Z23 // 62e24f4452bcda0f000000
//TODO: VP4DPWSSDS -7(DI)(R8*1), [Z4-Z7], K1, Z31 // 62225f4953bc07f9ffffff
//TODO: VP4DPWSSDS (SP), [Z4-Z7], K1, Z31 // 62625f49533c24
//TODO: VP4DPWSSDS -7(DI)(R8*1), [Z14-Z17], K1, Z31 // 62220f4953bc07f9ffffff
//TODO: VP4DPWSSDS (SP), [Z14-Z17], K1, Z31 // 62620f49533c24
//TODO: VP4DPWSSDS -7(DI)(R8*1), [Z24-Z27], K1, Z31 // 62223f4153bc07f9ffffff
//TODO: VP4DPWSSDS (SP), [Z24-Z27], K1, Z31 // 62623f41533c24
//TODO: VP4DPWSSDS -7(DI)(R8*1), [Z4-Z7], K1, Z0 // 62b25f49538407f9ffffff
//TODO: VP4DPWSSDS (SP), [Z4-Z7], K1, Z0 // 62f25f49530424
//TODO: VP4DPWSSDS -7(DI)(R8*1), [Z14-Z17], K1, Z0 // 62b20f49538407f9ffffff
//TODO: VP4DPWSSDS (SP), [Z14-Z17], K1, Z0 // 62f20f49530424
//TODO: VP4DPWSSDS -7(DI)(R8*1), [Z24-Z27], K1, Z0 // 62b23f41538407f9ffffff
//TODO: VP4DPWSSDS (SP), [Z24-Z27], K1, Z0 // 62f23f41530424
VP4DPWSSD 7(SI)(DI*1), [Z2-Z5], K4, Z17 // 62e26f4c528c3e07000000
VP4DPWSSD 15(DX)(BX*8), [Z2-Z5], K4, Z17 // 62e26f4c528cda0f000000
VP4DPWSSD 7(SI)(DI*1), [Z12-Z15], K4, Z17 // 62e21f4c528c3e07000000
VP4DPWSSD 15(DX)(BX*8), [Z12-Z15], K4, Z17 // 62e21f4c528cda0f000000
VP4DPWSSD 7(SI)(DI*1), [Z22-Z25], K4, Z17 // 62e24f44528c3e07000000
VP4DPWSSD 15(DX)(BX*8), [Z22-Z25], K4, Z17 // 62e24f44528cda0f000000
VP4DPWSSD 7(SI)(DI*1), [Z2-Z5], K4, Z23 // 62e26f4c52bc3e07000000
VP4DPWSSD 15(DX)(BX*8), [Z2-Z5], K4, Z23 // 62e26f4c52bcda0f000000
VP4DPWSSD 7(SI)(DI*1), [Z12-Z15], K4, Z23 // 62e21f4c52bc3e07000000
VP4DPWSSD 15(DX)(BX*8), [Z12-Z15], K4, Z23 // 62e21f4c52bcda0f000000
VP4DPWSSD 7(SI)(DI*1), [Z22-Z25], K4, Z23 // 62e24f4452bc3e07000000
VP4DPWSSD 15(DX)(BX*8), [Z22-Z25], K4, Z23 // 62e24f4452bcda0f000000
VP4DPWSSDS -7(DI)(R8*1), [Z4-Z7], K1, Z31 // 62225f4953bc07f9ffffff
VP4DPWSSDS (SP), [Z4-Z7], K1, Z31 // 62625f49533c24
VP4DPWSSDS -7(DI)(R8*1), [Z14-Z17], K1, Z31 // 62220f4953bc07f9ffffff
VP4DPWSSDS (SP), [Z14-Z17], K1, Z31 // 62620f49533c24
VP4DPWSSDS -7(DI)(R8*1), [Z24-Z27], K1, Z31 // 62223f4153bc07f9ffffff
VP4DPWSSDS (SP), [Z24-Z27], K1, Z31 // 62623f41533c24
VP4DPWSSDS -7(DI)(R8*1), [Z4-Z7], K1, Z0 // 62b25f49538407f9ffffff
VP4DPWSSDS (SP), [Z4-Z7], K1, Z0 // 62f25f49530424
VP4DPWSSDS -7(DI)(R8*1), [Z14-Z17], K1, Z0 // 62b20f49538407f9ffffff
VP4DPWSSDS (SP), [Z14-Z17], K1, Z0 // 62f20f49530424
VP4DPWSSDS -7(DI)(R8*1), [Z24-Z27], K1, Z0 // 62b23f41538407f9ffffff
VP4DPWSSDS (SP), [Z24-Z27], K1, Z0 // 62f23f41530424
RET
......@@ -3,52 +3,52 @@
#include "../../../../../../runtime/textflag.h"
TEXT asmtest_avx512pf(SB), NOSPLIT, $0
//TODO: VGATHERPF0DPD K5, (R10)(Y29*8) // 6292fd45c60cea
//TODO: VGATHERPF0DPD K5, (SP)(Y4*2) // 62f2fd4dc60c64
//TODO: VGATHERPF0DPD K5, (DX)(Y10*4) // 62b2fd4dc60c92
//TODO: VGATHERPF0DPS K3, (BP)(Z10*2) // 62b27d4bc64c5500
//TODO: VGATHERPF0DPS K3, (R10)(Z29*8) // 62927d43c60cea
//TODO: VGATHERPF0DPS K3, (R14)(Z29*8) // 62927d43c60cee
//TODO: VGATHERPF0QPD K4, (DX)(Z10*4) // 62b2fd4cc70c92
//TODO: VGATHERPF0QPD K4, (AX)(Z4*1) // 62f2fd4cc70c20
//TODO: VGATHERPF0QPD K4, (SP)(Z4*2) // 62f2fd4cc70c64
//TODO: VGATHERPF0QPS K2, (BP)(Z10*2) // 62b27d4ac74c5500
//TODO: VGATHERPF0QPS K2, (R10)(Z29*8) // 62927d42c70cea
//TODO: VGATHERPF0QPS K2, (R14)(Z29*8) // 62927d42c70cee
//TODO: VGATHERPF1DPD K2, (R14)(Y29*8) // 6292fd42c614ee
//TODO: VGATHERPF1DPD K2, (AX)(Y4*1) // 62f2fd4ac61420
//TODO: VGATHERPF1DPD K2, (BP)(Y10*2) // 62b2fd4ac6545500
//TODO: VGATHERPF1DPS K3, (DX)(Z10*4) // 62b27d4bc61492
//TODO: VGATHERPF1DPS K3, (AX)(Z4*1) // 62f27d4bc61420
//TODO: VGATHERPF1DPS K3, (SP)(Z4*2) // 62f27d4bc61464
//TODO: VGATHERPF1QPD K3, (DX)(Z10*4) // 62b2fd4bc71492
//TODO: VGATHERPF1QPD K3, (AX)(Z4*1) // 62f2fd4bc71420
//TODO: VGATHERPF1QPD K3, (SP)(Z4*2) // 62f2fd4bc71464
//TODO: VGATHERPF1QPS K3, (BP)(Z10*2) // 62b27d4bc7545500
//TODO: VGATHERPF1QPS K3, (R10)(Z29*8) // 62927d43c714ea
//TODO: VGATHERPF1QPS K3, (R14)(Z29*8) // 62927d43c714ee
//TODO: VSCATTERPF0DPD K5, (R10)(Y29*8) // 6292fd45c62cea
//TODO: VSCATTERPF0DPD K5, (SP)(Y4*2) // 62f2fd4dc62c64
//TODO: VSCATTERPF0DPD K5, (DX)(Y10*4) // 62b2fd4dc62c92
//TODO: VSCATTERPF0DPS K3, (DX)(Z10*4) // 62b27d4bc62c92
//TODO: VSCATTERPF0DPS K3, (AX)(Z4*1) // 62f27d4bc62c20
//TODO: VSCATTERPF0DPS K3, (SP)(Z4*2) // 62f27d4bc62c64
//TODO: VSCATTERPF0QPD K4, (DX)(Z10*4) // 62b2fd4cc72c92
//TODO: VSCATTERPF0QPD K4, (AX)(Z4*1) // 62f2fd4cc72c20
//TODO: VSCATTERPF0QPD K4, (SP)(Z4*2) // 62f2fd4cc72c64
//TODO: VSCATTERPF0QPS K2, (BP)(Z10*2) // 62b27d4ac76c5500
//TODO: VSCATTERPF0QPS K2, (R10)(Z29*8) // 62927d42c72cea
//TODO: VSCATTERPF0QPS K2, (R14)(Z29*8) // 62927d42c72cee
//TODO: VSCATTERPF1DPD K2, (R14)(Y29*8) // 6292fd42c634ee
//TODO: VSCATTERPF1DPD K2, (AX)(Y4*1) // 62f2fd4ac63420
//TODO: VSCATTERPF1DPD K2, (BP)(Y10*2) // 62b2fd4ac6745500
//TODO: VSCATTERPF1DPS K3, (BP)(Z10*2) // 62b27d4bc6745500
//TODO: VSCATTERPF1DPS K3, (R10)(Z29*8) // 62927d43c634ea
//TODO: VSCATTERPF1DPS K3, (R14)(Z29*8) // 62927d43c634ee
//TODO: VSCATTERPF1QPD K3, (DX)(Z10*4) // 62b2fd4bc73492
//TODO: VSCATTERPF1QPD K3, (AX)(Z4*1) // 62f2fd4bc73420
//TODO: VSCATTERPF1QPD K3, (SP)(Z4*2) // 62f2fd4bc73464
//TODO: VSCATTERPF1QPS K3, (BP)(Z10*2) // 62b27d4bc7745500
//TODO: VSCATTERPF1QPS K3, (R10)(Z29*8) // 62927d43c734ea
//TODO: VSCATTERPF1QPS K3, (R14)(Z29*8) // 62927d43c734ee
VGATHERPF0DPD K5, (R10)(Y29*8) // 6292fd45c60cea
VGATHERPF0DPD K5, (SP)(Y4*2) // 62f2fd4dc60c64
VGATHERPF0DPD K5, (DX)(Y10*4) // 62b2fd4dc60c92
VGATHERPF0DPS K3, (BP)(Z10*2) // 62b27d4bc64c5500
VGATHERPF0DPS K3, (R10)(Z29*8) // 62927d43c60cea
VGATHERPF0DPS K3, (R14)(Z29*8) // 62927d43c60cee
VGATHERPF0QPD K4, (DX)(Z10*4) // 62b2fd4cc70c92
VGATHERPF0QPD K4, (AX)(Z4*1) // 62f2fd4cc70c20
VGATHERPF0QPD K4, (SP)(Z4*2) // 62f2fd4cc70c64
VGATHERPF0QPS K2, (BP)(Z10*2) // 62b27d4ac74c5500
VGATHERPF0QPS K2, (R10)(Z29*8) // 62927d42c70cea
VGATHERPF0QPS K2, (R14)(Z29*8) // 62927d42c70cee
VGATHERPF1DPD K2, (R14)(Y29*8) // 6292fd42c614ee
VGATHERPF1DPD K2, (AX)(Y4*1) // 62f2fd4ac61420
VGATHERPF1DPD K2, (BP)(Y10*2) // 62b2fd4ac6545500
VGATHERPF1DPS K3, (DX)(Z10*4) // 62b27d4bc61492
VGATHERPF1DPS K3, (AX)(Z4*1) // 62f27d4bc61420
VGATHERPF1DPS K3, (SP)(Z4*2) // 62f27d4bc61464
VGATHERPF1QPD K3, (DX)(Z10*4) // 62b2fd4bc71492
VGATHERPF1QPD K3, (AX)(Z4*1) // 62f2fd4bc71420
VGATHERPF1QPD K3, (SP)(Z4*2) // 62f2fd4bc71464
VGATHERPF1QPS K3, (BP)(Z10*2) // 62b27d4bc7545500
VGATHERPF1QPS K3, (R10)(Z29*8) // 62927d43c714ea
VGATHERPF1QPS K3, (R14)(Z29*8) // 62927d43c714ee
VSCATTERPF0DPD K5, (R10)(Y29*8) // 6292fd45c62cea
VSCATTERPF0DPD K5, (SP)(Y4*2) // 62f2fd4dc62c64
VSCATTERPF0DPD K5, (DX)(Y10*4) // 62b2fd4dc62c92
VSCATTERPF0DPS K3, (DX)(Z10*4) // 62b27d4bc62c92
VSCATTERPF0DPS K3, (AX)(Z4*1) // 62f27d4bc62c20
VSCATTERPF0DPS K3, (SP)(Z4*2) // 62f27d4bc62c64
VSCATTERPF0QPD K4, (DX)(Z10*4) // 62b2fd4cc72c92
VSCATTERPF0QPD K4, (AX)(Z4*1) // 62f2fd4cc72c20
VSCATTERPF0QPD K4, (SP)(Z4*2) // 62f2fd4cc72c64
VSCATTERPF0QPS K2, (BP)(Z10*2) // 62b27d4ac76c5500
VSCATTERPF0QPS K2, (R10)(Z29*8) // 62927d42c72cea
VSCATTERPF0QPS K2, (R14)(Z29*8) // 62927d42c72cee
VSCATTERPF1DPD K2, (R14)(Y29*8) // 6292fd42c634ee
VSCATTERPF1DPD K2, (AX)(Y4*1) // 62f2fd4ac63420
VSCATTERPF1DPD K2, (BP)(Y10*2) // 62b2fd4ac6745500
VSCATTERPF1DPS K3, (BP)(Z10*2) // 62b27d4bc6745500
VSCATTERPF1DPS K3, (R10)(Z29*8) // 62927d43c634ea
VSCATTERPF1DPS K3, (R14)(Z29*8) // 62927d43c634ee
VSCATTERPF1QPD K3, (DX)(Z10*4) // 62b2fd4bc73492
VSCATTERPF1QPD K3, (AX)(Z4*1) // 62f2fd4bc73420
VSCATTERPF1QPD K3, (SP)(Z4*2) // 62f2fd4bc73464
VSCATTERPF1QPS K3, (BP)(Z10*2) // 62b27d4bc7745500
VSCATTERPF1QPS K3, (R10)(Z29*8) // 62927d43c734ea
VSCATTERPF1QPS K3, (R14)(Z29*8) // 62927d43c734ee
RET
......@@ -39,6 +39,7 @@ func init() {
obj.RegisterRegister(obj.RBaseARM, MAXREG, rconv)
obj.RegisterOpcode(obj.ABaseARM, Anames)
obj.RegisterRegisterList(obj.RegListARMLo, obj.RegListARMHi, rlconv)
obj.RegisterOpSuffix("arm", obj.CConvARM)
}
func rconv(r int) string {
......
......@@ -58,6 +58,7 @@ func init() {
obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, rconv)
obj.RegisterOpcode(obj.ABaseARM64, Anames)
obj.RegisterRegisterList(obj.RegListARM64Lo, obj.RegListARM64Hi, rlconv)
obj.RegisterOpSuffix("arm64", obj.CConvARM)
}
func arrange(a int) string {
......
......@@ -138,13 +138,16 @@ import (
// offset = second register
//
// [reg, reg, reg-reg]
// Register list for ARM and ARM64.
// Register list for ARM, ARM64, 386/AMD64.
// Encoding:
// type = TYPE_REGLIST
// On ARM:
// offset = bit mask of registers in list; R0 is low bit.
// On ARM64:
// offset = register count (Q:size) | arrangement (opcode) | first register
// On 386/AMD64:
// reg = range low register
// offset = 2 packed registers + kind tag (see x86.EncodeRegisterRange)
//
// reg, reg
// Register pair for ARM.
......@@ -282,7 +285,7 @@ type Prog struct {
RegTo2 int16 // 2nd destination operand
Mark uint16 // bitmask of arch-specific items
Optab uint16 // arch-specific opcode index
Scond uint8 // condition bits for conditional instruction (e.g., on ARM)
Scond uint8 // bits that describe instruction suffixes (e.g. ARM conditions)
Back uint8 // for x86 back end: backwards branch state
Ft uint8 // for x86 back end: type index of Prog.From
Tt uint8 // for x86 back end: type index of Prog.To
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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