fix(asm): size the arm64 logical-immediate materialisation exactly

Assisted-by: GLM 5.3
This commit is contained in:
petrbalvin committed 2026-10-07 13:49:49 +02:00
1 parent 4ccd3bb4c6
commit 4fc96decc4
2 files changed
+45 -4

No files matched your search

+11 -4
View File
@@ -313,22 +313,26 @@ func arm64InstrSize(instr *ast.Instr, fi arm64FrameInfo, pos int) int {
return arm64MovSize(mnem, ops, fi)
}
// The logical-immediate family: one word on the bitmask fast path (a
// real destination, or the flags-only TST spellings), two words for the
// materialisation the ZR destinations and the non-bitmask immediates
// take. Mirrors encodeARM64DPSR's decision exactly.
// real destination, or the flags-only TST spellings), otherwise the
// constant materialisation into REGTMP plus the register-form tail.
// Mirrors encodeARM64DPSR's decision exactly, the materialisation word
// count included: a MOVZ plus up to three MOVKs makes five words.
if len(ops) >= 2 && len(ops) <= 3 && isImmOperand(ops[0]) {
switch mnem {
case "AND", "ANDW", "ANDS", "ANDSW", "ORR", "ORRW", "EOR", "EORW",
"BIC", "BICW", "BICS", "BICSW", "ORN", "ORNW", "EON", "EONW",
"TST", "TSTW":
if v, ok := arm64ImmOperandValue(ops[0]); ok {
written := v
switch mnem {
case "BIC", "BICW", "BICS", "BICSW", "ORN", "ORNW", "EON", "EONW":
v = ^v
}
width := 64
mwMnem := "MOVD"
if strings.HasSuffix(mnem, "W") {
width = 32
mwMnem = "MOVW"
}
zrDest := false
if mnem != "TST" && mnem != "TSTW" {
@@ -337,7 +341,10 @@ func arm64InstrSize(instr *ast.Instr, fi arm64FrameInfo, pos int) int {
if _, _, _, bc := a64LogicalImm(v, width); bc && (mnem == "TST" || mnem == "TSTW" || !zrDest) {
return 4
}
return 8
if mw, err := encodeARM64LoadImm(27, written, mwMnem); err == nil {
return len(mw) + 4
}
return 4
}
}
}