feat(arch): add the amd64 extended-instruction layer with BF16 and VP2INTERSECT
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
2d803e38d8
commit
28bea95128
6 files changed
+803
-8
No files matched your search
+82
-1
@@ -6,7 +6,8 @@
|
||||
// golden vectors from the Arm Architecture Reference Manual rather than
|
||||
// against the toolchain. It sits beside the generated tables, never inside
|
||||
// them: arch/arm64_gen.go stays untouched, and Extensions returns the layer
|
||||
// per architecture so a later amd64 table attaches through the same door.
|
||||
// per architecture; the amd64 side of the layer lives in amd64_ext.go and
|
||||
// attaches through the same door.
|
||||
//
|
||||
// The first entry is the arm64 SVE and SVE2 integer add/subtract/multiply
|
||||
// family (twenty-three forms over four word shapes). The encodings are
|
||||
@@ -26,6 +27,13 @@ const (
|
||||
ExtZReg ExtOperandKind = iota // scalable vector register Z0-Z31
|
||||
ExtPReg // predicate register P0-P15
|
||||
ExtImm // immediate
|
||||
// The amd64 layer's register kinds.
|
||||
ExtXMM // 128-bit vector register XMM0-XMM31
|
||||
ExtYMM // 256-bit vector register YMM0-YMM31
|
||||
ExtZMM // 512-bit vector register ZMM0-ZMM31
|
||||
ExtKReg // opmask register K0-K7
|
||||
ExtR32 // 32-bit general register EAX-R15D
|
||||
ExtR64 // 64-bit general register RAX-R15
|
||||
)
|
||||
|
||||
// String returns a short label for the kind.
|
||||
@@ -37,6 +45,18 @@ func (k ExtOperandKind) String() string {
|
||||
return "predicate register"
|
||||
case ExtImm:
|
||||
return "immediate"
|
||||
case ExtXMM:
|
||||
return "XMM register"
|
||||
case ExtYMM:
|
||||
return "YMM register"
|
||||
case ExtZMM:
|
||||
return "ZMM register"
|
||||
case ExtKReg:
|
||||
return "opmask register"
|
||||
case ExtR32:
|
||||
return "32-bit general register"
|
||||
case ExtR64:
|
||||
return "64-bit general register"
|
||||
default:
|
||||
return "operand"
|
||||
}
|
||||
@@ -225,6 +245,33 @@ const (
|
||||
// multiply (immediate) class: MUL $-128, Z0.B computes Z0 = Z0 * -128.
|
||||
// Operands: simm8, Zdn. No shift exists in this class.
|
||||
ExtFormSignedImmediate
|
||||
// The amd64 layer's operand shapes, sources first, destination last.
|
||||
// The vector register class an entry takes comes from the encoding
|
||||
// template (the L'L field names it), not from the form.
|
||||
// ExtFormAmdVec3 is the EVEX non-destructive three-vector form:
|
||||
// VCVTNE2PS2BF16 Z6, Z5, Z4. Operands: src1, src2, dest.
|
||||
ExtFormAmdVec3
|
||||
// ExtFormAmdVec2 is the two-vector form: VPOPCNTD Z1, Z2, VCOMISH X1, X2.
|
||||
// Operands: src, dest.
|
||||
ExtFormAmdVec2
|
||||
// ExtFormAmdVec2Half is the two-vector form whose destination is the
|
||||
// half-width companion of the source, equal at 128 bits: VCVTNEPS2BF16
|
||||
// Y6, Z5. Operands: src, dest.
|
||||
ExtFormAmdVec2Half
|
||||
// ExtFormAmdMask2 is the form with an opmask destination and two vector
|
||||
// sources: VP2INTERSECTD K0, Z2, Z1. Operands: src1, src2, dest.
|
||||
ExtFormAmdMask2
|
||||
// ExtFormAmdVecGprVec is the three-operand conversion with a
|
||||
// general-register source: VCVTSI2SH X1, X2, EAX. Operands: src1, gpr,
|
||||
// dest.
|
||||
ExtFormAmdVecGprVec
|
||||
// ExtFormAmdGprVec is the two-operand form with a general-register
|
||||
// source and a vector destination: VMOVW X1, EAX and VCVTSH2SI EAX, X1.
|
||||
// Operands: gpr, dest.
|
||||
ExtFormAmdGprVec
|
||||
// ExtFormAmdVecGpr is the two-operand form with a vector source and a
|
||||
// general-register destination: VMOVW EAX, X1. Operands: src, dest.
|
||||
ExtFormAmdVecGpr
|
||||
)
|
||||
|
||||
// Arity returns the operand count the form takes.
|
||||
@@ -234,6 +281,10 @@ func (f ExtForm) Arity() int {
|
||||
return 3
|
||||
case ExtFormImmediate, ExtFormSignedImmediate:
|
||||
return 2
|
||||
case ExtFormAmdVec3, ExtFormAmdMask2, ExtFormAmdVecGprVec:
|
||||
return 3
|
||||
case ExtFormAmdVec2, ExtFormAmdVec2Half, ExtFormAmdGprVec, ExtFormAmdVecGpr:
|
||||
return 2
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
@@ -250,6 +301,9 @@ func (f ExtForm) Kinds() []ExtOperandKind {
|
||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtZReg}
|
||||
case ExtFormImmediate, ExtFormSignedImmediate:
|
||||
return []ExtOperandKind{ExtImm, ExtZReg}
|
||||
// The amd64 forms return no kinds: the exact vector class depends on the
|
||||
// entry's encoding template (its L'L field), which the form alone cannot
|
||||
// name, and the encode paths diagnose the class themselves.
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
@@ -266,6 +320,20 @@ func (f ExtForm) String() string {
|
||||
return "unsigned immediate"
|
||||
case ExtFormSignedImmediate:
|
||||
return "signed immediate"
|
||||
case ExtFormAmdVec3:
|
||||
return "three vectors"
|
||||
case ExtFormAmdVec2:
|
||||
return "two vectors"
|
||||
case ExtFormAmdVec2Half:
|
||||
return "two vectors, half-width destination"
|
||||
case ExtFormAmdMask2:
|
||||
return "two vectors into an opmask"
|
||||
case ExtFormAmdVecGprVec:
|
||||
return "vector, general register, vector"
|
||||
case ExtFormAmdGprVec:
|
||||
return "general register, vector"
|
||||
case ExtFormAmdVecGpr:
|
||||
return "vector, general register"
|
||||
default:
|
||||
return "unknown form"
|
||||
}
|
||||
@@ -296,6 +364,14 @@ type ExtInstr struct {
|
||||
Size ExtField // element-size field the arrangement fills
|
||||
Feature ExtFeature // sve or sve2
|
||||
Ref string // the ARM ARM entry the encoding comes from
|
||||
// Bytes is the amd64 encoding template: the EVEX prefix, opcode and
|
||||
// ModR/M byte of one form, with every register-derived bit zero. The
|
||||
// vector length and the general-register width an entry encodes are read
|
||||
// back out of it at encode time.
|
||||
Bytes []byte
|
||||
// Wig records that the entry ignores the W bit in its general-register
|
||||
// position, so both 32-bit and 64-bit registers encode.
|
||||
Wig bool
|
||||
}
|
||||
|
||||
// Encode assembles the operands into the 4 little-endian bytes of the
|
||||
@@ -316,6 +392,9 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeImmediate(ops)
|
||||
case ExtFormSignedImmediate:
|
||||
return in.encodeSignedImmediate(ops)
|
||||
case ExtFormAmdVec3, ExtFormAmdVec2, ExtFormAmdVec2Half, ExtFormAmdMask2,
|
||||
ExtFormAmdVecGprVec, ExtFormAmdGprVec, ExtFormAmdVecGpr:
|
||||
return in.encodeAmd64(ops)
|
||||
default:
|
||||
return nil, fmt.Errorf("%s: unknown form %d", in.Name, in.Form)
|
||||
}
|
||||
@@ -616,6 +695,8 @@ var arm64Extensions = []ExtInstr{
|
||||
// it simply offers no instruction where none is registered.
|
||||
func Extensions(a Arch) []ExtInstr {
|
||||
switch a {
|
||||
case AMD64:
|
||||
return amd64Extensions
|
||||
case ARM64:
|
||||
return arm64Extensions
|
||||
default:
|
||||
|
||||
Reference in new issue
Block a user