x64 backend: fix to_amode with constant address (no registers). (#4239)

If an address expression is given to `to_amode` that is completely
constant (no registers at all), then it will produce an `Amode` that has
the resulting constant as an offset, and `(invalid_reg)` as the base.
This is a side-effect of the way we build up the amode step-by-step --
we're waiting to see a register and plug it into the base field. If we
never get a reg though, we need to generate a constant zero into a
register and use that as the base. This PR adds a `finalize_amode`
helper to do just that.

Fixes #4234.
This commit is contained in:
Chris Fallin
2022-06-07 11:40:10 -07:00
committed by GitHub
parent 0b4448a423
commit 54acd8b3e2
2 changed files with 33 additions and 1 deletions

View File

@@ -981,7 +981,16 @@
;; Finally, define the toplevel `to_amode`.
(rule (to_amode flags base offset)
(amode_add (amode_initial flags offset) base))
(amode_finalize (amode_add (amode_initial flags offset) base)))
;; If an amode has no registers at all and only offsets (a constant
;; value), we need to "finalize" it by sticking in a zero'd reg in
;; place of the (invalid_reg) produced by (amode_initial).
(decl amode_finalize (Amode) Amode)
(rule 1 (amode_finalize (Amode.ImmReg off (invalid_reg) flags))
(Amode.ImmReg off (imm $I64 0) flags))
(rule 0 (amode_finalize amode)
amode)
;; Offsetting an Amode. Used when we need to do consecutive
;; loads/stores to adjacent addresses.