feat(asm): encode the arm64 Q-width FP load and store
FMOVQ routes through the MOV load/store machinery in the plain, post-index, pre-index and static-symbol forms. The Q width carries its size in the opc field, so the store spelling is opc=10 and the access scales by sixteen; both come from helpers now instead of the size exponent. The static-symbol form takes the toolchain's twelve-byte ADRP + ADD + access fallback with the R_ADDRARM64 pair. The register-to-register and immediate forms stay rejected, matching the toolchain's own table. Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
a6bd9c1ebe
commit
daf7fad5b9
5 files changed
+161
-9
No files matched your search
+16
-1
@@ -1518,11 +1518,26 @@ var a64LoadTable = map[string]a64LSType{
|
||||
|
||||
// a64StoreOpc returns the store opc for a given load type: integer and FP
|
||||
// stores both encode opc=00 (the load's signedness bit sits in opc[1], which
|
||||
// the store form clears; FP registers are selected by V, not opc).
|
||||
// the store form clears; FP registers are selected by V, not opc). The one
|
||||
// exception is the 128-bit Q width, whose store is the opc=10 spelling: with
|
||||
// opc=00 the size field selects STR B instead (STR Qt is size=00, opc=10).
|
||||
func a64StoreOpc(t a64LSType) int {
|
||||
if t.size == 0 && t.V == 1 {
|
||||
return 2
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// a64LSScale returns the byte width an access's unsigned offset divides by.
|
||||
// The Q width carries its size in opc (the size field stays 0), yet scales
|
||||
// by 16 like any other 128-bit access, so the exponent alone does not answer.
|
||||
func a64LSScale(t a64LSType) int64 {
|
||||
if t.size == 0 && t.V == 1 {
|
||||
return 16
|
||||
}
|
||||
return int64(1) << uint(t.size)
|
||||
}
|
||||
|
||||
// arm64RegClass discriminates integer (R), floating-point (F) registers for
|
||||
// the MOV pseudo-instruction.
|
||||
type arm64RegClass int
|
||||
|
||||
Reference in new issue
Block a user