Chez Scheme arm32: avoid bouncing in label-address assignment

The A32 instruction set has an interesting encoding of immediate
values where a larger value sometimes fits in a smaller set of
instructions. That turns out to be a bad property for loading a return
address, because it means that the as label computations push code
further away, a contracting return-address calculation can pull code
back nearer, and this push-and-pull can keep the label allocator from
arriving at a fixpoint.

This became a bigger problem with 8834597c1f, which creates
return-label references that go backwards and where the offset can be
much larger than the normal, forward references.
This commit is contained in:
Matthew Flatt 2020-09-02 18:32:27 -06:00
parent 6f11f1f527
commit f5895ebc97

View File

@ -1674,6 +1674,12 @@
(bitwise-arithmetic-shift-left (logand n #xffffff) 8)
(bitwise-arithmetic-shift-right n 24)))))))))
;; A region of funky12 where there's no number that fits when a smaller number doesn't
(define connected-funky12
(lambda (n)
(and (fixnum? n) (#%$fxu< n #x100)
(funky12 n))))
(define shift-count?
(lambda (imm)
; can also allow 0 for lsl and 32 (represented as 0) for lsr, asr
@ -2186,11 +2192,11 @@
(let ([incr-offset (adjust-return-point-offset incr-offset l)])
(let ([disp (fx- next-addr (fx- offset incr-offset) 4)])
(cond
[(funky12 disp)
[(connected-funky12 disp)
(Trivit (dest)
; aka adr, encoding A1
(emit addi #f dest `(reg . ,%pc) disp '()))]
[(funky12 (- disp))
[(connected-funky12 (- disp))
(Trivit (dest)
; aka adr, encoding A2
(emit subi #f dest `(reg . ,%pc) (- disp) '()))]