Skip to content

Source: moonlive_lower.h

moonlive_lower

IR to machine bytes: the one lowering, written once for every backend.

Walking the IR is not a per-target algorithm, so the walk lives here and each backend supplies its assembler.

More info

What core decides

Which register holds a value, which frame slot it spills to, when a host argument is reloaded, and how an inline op expands. All of it identically for every target, because what differs per target is how an instruction is encoded, and that already lives behind the assembler.

The assembler contract

Each backend supplies a constructor, the label and frame calls, the move, arithmetic, shift, load and store forms, the branches, the two call forms, and a spill-slot bound. The branches are the fused forms, compare-and-branch as one call. arm64 has no such instruction and spells each as two inside its own assembler.

Include order

A backend includes its own assembler header before this one. Reg and Label are declared per assembler, each register file being a different size, so this header names them without declaring them. That is also why it is a template rather than a compiled unit, there being no single Reg to compile against.