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:
parent
6f11f1f527
commit
f5895ebc97
|
@ -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) '()))]
|
||||
|
|
Loading…
Reference in New Issue
Block a user