feat(asm): add the wider EVEX set and the rounding, SAE and broadcast suffixes
Assisted-by: Qwen 3.8 Max Preview
This commit is contained in:
+21
-14
@@ -51,16 +51,17 @@ func (e *enc) encode(mnem string, ops []Operand) error {
|
||||
|
||||
// VEX (AVX/AVX2) and EVEX (AVX-512) instructions: the trailing
|
||||
// B/W/L/Q/D is part of the mnemonic, not a size suffix, so dispatch
|
||||
// before splitSize. A ".Z" suffix requests EVEX zeroing.
|
||||
base, zeroing, err := stripEvexSuffix(upper)
|
||||
// before splitSize. EVEX suffixes (.Z, .SAE, rounding, .BCST) split
|
||||
// off the mnemonic too.
|
||||
base, sfx, err := parseEvexSuffix(upper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isVex(base) || isEvex(base) || base == "KMOVW" {
|
||||
return e.encodeVec(base, ops, zeroing)
|
||||
if isVex(base) || isEvex(base) || isKOp(base) || base == "KMOVW" || base == "KMOVQ" {
|
||||
return e.encodeVec(base, ops, sfx)
|
||||
}
|
||||
if zeroing {
|
||||
return fmt.Errorf("%s: the .Z suffix requires an EVEX instruction", mnem)
|
||||
if sfx.any() {
|
||||
return fmt.Errorf("%s: the suffix requires an EVEX instruction", mnem)
|
||||
}
|
||||
|
||||
// CMOVcc and SETcc carry the condition in the mnemonic (CMOVLGT, SETNE).
|
||||
@@ -128,20 +129,26 @@ func splitSize(upper string) (base string, size int) {
|
||||
// its own direction-dependent opcodes; KTESTW is always VEX; everything else
|
||||
// takes EVEX when an operand demands it (a ZMM or K register, or an
|
||||
// EVEX-only mnemonic) and VEX otherwise.
|
||||
func (e *enc) encodeVec(upper string, ops []Operand, zeroing bool) error {
|
||||
if upper == "KMOVW" {
|
||||
if zeroing {
|
||||
return fmt.Errorf("KMOVW takes no .Z suffix")
|
||||
func (e *enc) encodeVec(upper string, ops []Operand, sfx evexSuffix) error {
|
||||
if upper == "KMOVW" || upper == "KMOVQ" {
|
||||
if sfx.any() {
|
||||
return fmt.Errorf("%s takes no EVEX suffixes", upper)
|
||||
}
|
||||
return e.encodeKmovw(ops)
|
||||
return e.encodeKmov(upper, ops)
|
||||
}
|
||||
if upper == "KTESTW" || !evexRequired(upper, ops) {
|
||||
if zeroing {
|
||||
if isKOp(upper) {
|
||||
if sfx.any() {
|
||||
return fmt.Errorf("%s takes no EVEX suffixes", upper)
|
||||
}
|
||||
return e.encodeKOp(upper, ops)
|
||||
}
|
||||
if upper == "KTESTW" || (!evexRequired(upper, ops) && !sfx.evexOnly()) {
|
||||
if sfx.any() {
|
||||
return fmt.Errorf("%s: the .Z suffix requires an EVEX instruction", upper)
|
||||
}
|
||||
return e.encodeVex(upper, ops)
|
||||
}
|
||||
return e.encodeEvex(upper, ops, zeroing)
|
||||
return e.encodeEvex(upper, ops, sfx)
|
||||
}
|
||||
|
||||
// --- instruction components -------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user