From f5895ebc971b44c3107f5ce581332520d24c8f71 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 2 Sep 2020 18:32:27 -0600 Subject: [PATCH] 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. --- racket/src/ChezScheme/s/arm32.ss | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/racket/src/ChezScheme/s/arm32.ss b/racket/src/ChezScheme/s/arm32.ss index c7ec4bf61c..dcc36d1811 100644 --- a/racket/src/ChezScheme/s/arm32.ss +++ b/racket/src/ChezScheme/s/arm32.ss @@ -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) '()))]