Tidy up compiler utility return addresses.
authorTaylor R Campbell <campbell@mumble.net>
Sat, 5 Jan 2019 03:36:51 +0000 (03:36 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Tue, 13 Aug 2019 14:37:03 +0000 (14:37 +0000)
commitf53af07f681dd908ef7464aa0890395c3617dc2e
tree287214e4cba685c0287a21ba30950445035f4506
parent31163e25df96787629821c16ce3548b7bd6f0047
Tidy up compiler utility return addresses.

Use compiled returns for the ones that are likely to return to Scheme
like lookups and assignments, and compiled entries for the ones that
are likely to return to microcode like interrupts.

Architectures on which compiled entries and compiled returns have the
same format will see no difference: compiled code passes in an
untagged return address either way.

On amd64, where compiled entries and compiled returns are different:

- For hooks that act like leaf subroutines and never return to
  microcode, use plain CALL/RET in pairs.

- For hooks that are subroutines likely to return to Scheme
  immediately but might return to microcode in screw cases, use

        (CALL ,hook)                    ; Invoke hook with untagged ret addr...
        (JMP (@PCR ,continuation))      ; ...which jumps to formatted entry.
        (WORD ...)
        (BLOCK-OFFSET ,continuation)
        (QUAD U 0)
       (LABEL ,continuation)
        ...                             ; continuation instructions

  For the non-screw cases this keeps CALL/RET paired.

- For hooks that always defer to microcode, namely to handle
  interrupts, use

        (LEA Q (R ,rbx) (@PCR ,continuation))
        (JMP ,hook)

  Here it doesn't really whether the CALL/RET is paired because we're
  going to wreck the return address branch prediction stack no matter
  what, but it is convenient to have the entry address rather than
  the return address in the compiled utility.
src/compiler/machines/x86-64/lapgen.scm
src/compiler/machines/x86-64/rules3.scm
src/compiler/machines/x86-64/rules4.scm
src/microcode/cmpauxmd/x86-64.m4
src/microcode/cmpint.c