feat(arch): add the amd64 memory-operand mechanism to the extension layer
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
d1030a1788
commit
7d69dda874
3 files changed
+212
-3
No files matched your search
+39
-3
@@ -34,6 +34,7 @@ const (
|
||||
ExtKReg // opmask register K0-K7
|
||||
ExtR32 // 32-bit general register EAX-R15D
|
||||
ExtR64 // 64-bit general register RAX-R15
|
||||
ExtMem // base-relative memory operand, 4660(R8) style
|
||||
)
|
||||
|
||||
// String returns a short label for the kind.
|
||||
@@ -57,6 +58,8 @@ func (k ExtOperandKind) String() string {
|
||||
return "32-bit general register"
|
||||
case ExtR64:
|
||||
return "64-bit general register"
|
||||
case ExtMem:
|
||||
return "memory operand"
|
||||
default:
|
||||
return "operand"
|
||||
}
|
||||
@@ -153,10 +156,14 @@ func (q ExtQualifier) String() string {
|
||||
// from the parsed statement; Encode consumes them.
|
||||
type ExtOperand struct {
|
||||
Kind ExtOperandKind
|
||||
Reg int // register number (Z: 0..31, P: 0..15)
|
||||
// Reg is the register number (Z: 0..31, P: 0..15); under ExtMem it is
|
||||
// the base general register, 0..15.
|
||||
Reg int
|
||||
Arr ExtArrangement // element-size suffix; ExtArrNone when bare
|
||||
Qual ExtQualifier // predicate qualifier; ExtQualNone elsewhere
|
||||
Imm int64 // immediate value (ExtImm only)
|
||||
// Imm is the immediate value under ExtImm; under ExtMem it is the
|
||||
// signed displacement the base carries.
|
||||
Imm int64
|
||||
// Shift carries the LSL amount an immediate form shifts the constant by
|
||||
// before use (0 or 8 in the SVE add/subtract immediate class). HasShift
|
||||
// separates a spelled shift (validated as written) from an unshifted
|
||||
@@ -185,6 +192,14 @@ func ExtShiftedImmediate(v int64, shift int) ExtOperand {
|
||||
return ExtOperand{Kind: ExtImm, Imm: v, Shift: shift, HasShift: true}
|
||||
}
|
||||
|
||||
// ExtMemory builds a base-relative memory operand, 4660(R8) style: the base
|
||||
// is a 64-bit general register number, 0..15, and the displacement rides the
|
||||
// ModR/M disp8 or disp32 form the encoder picks. No index register and no
|
||||
// scale: the base-plus-displacement shape alone.
|
||||
func ExtMemory(base int, disp int64) ExtOperand {
|
||||
return ExtOperand{Kind: ExtMem, Reg: base, Imm: disp}
|
||||
}
|
||||
|
||||
// ExtField is one named field of the 32-bit encoding word: a bit offset from
|
||||
// the least significant end and the field's width.
|
||||
type ExtField struct {
|
||||
@@ -282,6 +297,13 @@ const (
|
||||
// where dest is an opmask register and the immediate's layout is named
|
||||
// by the entry's Imm8 kind.
|
||||
ExtFormAmdMask2Imm
|
||||
// ExtFormAmdMemVec is the memory-load form: VMOVSH X30, 4660(R8) shape,
|
||||
// the manual's xmm1, m16 lines that stand beside the register form.
|
||||
// Operands: mem, dest.
|
||||
ExtFormAmdMemVec
|
||||
// ExtFormAmdVecMem is the memory-store form: VMOVSH 4660(R9), X29
|
||||
// shape, the manual's m16, xmm1 lines. Operands: src, mem.
|
||||
ExtFormAmdVecMem
|
||||
)
|
||||
|
||||
// Arity returns the operand count the form takes.
|
||||
@@ -297,6 +319,8 @@ func (f ExtForm) Arity() int {
|
||||
return 2
|
||||
case ExtFormAmdVec3Imm, ExtFormAmdMask2Imm:
|
||||
return 4
|
||||
case ExtFormAmdMemVec, ExtFormAmdVecMem:
|
||||
return 2
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
@@ -350,6 +374,10 @@ func (f ExtForm) String() string {
|
||||
return "immediate, three vectors"
|
||||
case ExtFormAmdMask2Imm:
|
||||
return "immediate, two vectors into an opmask"
|
||||
case ExtFormAmdMemVec:
|
||||
return "memory into a vector"
|
||||
case ExtFormAmdVecMem:
|
||||
return "a vector into memory"
|
||||
default:
|
||||
return "unknown form"
|
||||
}
|
||||
@@ -431,6 +459,14 @@ type ExtInstr struct {
|
||||
// operand carries, ExtImm8None when the form takes none. The arm64
|
||||
// entries all carry the zero value.
|
||||
Imm8 ExtImm8Kind
|
||||
// Mem names the 1-based operand position that may carry a memory
|
||||
// operand beside the register the position normally takes: 2 on the
|
||||
// arithmetic whose second source the manual spells xmm3/m16, 1 on the
|
||||
// narrow BF16 convert whose source it spells m256/m512. Zero means
|
||||
// the form takes registers alone. The load and store shapes are forms
|
||||
// of their own, ExtFormAmdMemVec and ExtFormAmdVecMem, and need no
|
||||
// flag. The arm64 entries all carry the zero value.
|
||||
Mem int
|
||||
}
|
||||
|
||||
// Encode assembles the operands into the 4 little-endian bytes of the
|
||||
@@ -453,7 +489,7 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeSignedImmediate(ops)
|
||||
case ExtFormAmdVec3, ExtFormAmdVec2, ExtFormAmdVec2Half, ExtFormAmdMask2,
|
||||
ExtFormAmdVecGprVec, ExtFormAmdGprVec, ExtFormAmdVecGpr,
|
||||
ExtFormAmdVec3Imm, ExtFormAmdMask2Imm:
|
||||
ExtFormAmdVec3Imm, ExtFormAmdMask2Imm, ExtFormAmdMemVec, ExtFormAmdVecMem:
|
||||
return in.encodeAmd64(ops)
|
||||
default:
|
||||
return nil, fmt.Errorf("%s: unknown form %d", in.Name, in.Form)
|
||||
|
||||
Reference in new issue
Block a user