... | ... | @@ -64,14 +64,28 @@ data CmmExpr |
|
|
```
|
|
|
|
|
|
|
|
|
An `Area` represents space on the stack; it may use either the `RegSlot` constructor to represent a single stack slot for a register or the `CallArea` constructor to represent parameters passed to/from a function call/return. In a young `CallArea`, the `BlockId` is the label of the function call's continuation, and it passes parameters to the call. Each `Area` grows down, with offset 0 pointing to the old end of the `Area`. The old call area is the initial state of the stack on entry to the function (the overflow parameters and the return address) as well as any arguments that will be passed to a tail call. Note that `RegSlot` areas are very small (since they only need to store a single register), while `CallArea` are contiguous chunks of arguments.
|
|
|
An `Area` represents space on the stack; it may use either the `RegSlot` constructor to represent a single stack slot for a register or the `CallArea` constructor to represent parameters passed to/from a function call/return. In a young `CallArea`, the `BlockId` is the label of the function call's continuation, and it passes parameters to the call.
|
|
|
|
|
|
**Area layout and addressing**
|
|
|
|
|
|
- Each `Area` grows down, towards lower machine addresses.
|
|
|
- *Offsets* are always-positive byte displacements within an `Area`.
|
|
|
- The low-offset end is also called the "old end" of the area, the high-offset end is also called the "young end".
|
|
|
- Notice that the low-offset (old) end has higher machine addresses.
|
|
|
- Offset 0 (if we allowed it) would address the byte one *beyond* the high-address end of the `Area`.
|
|
|
- Larger offsets (from the beginning of the `Area`) correspond to lower machine addresses.
|
|
|
- Hence, to address a 4-byte object at the old end of `Area` a, we use the offset +4, thus `(CmmStackSlot a 4)`.
|
|
|
|
|
|
|
|
|
The `Old` call area is the initial state of the stack on entry to the function (the overflow parameters and the return address) as well as any arguments that will be passed to a tail call. (SLPJ believes that:) On entry to the function, register `Sp` contains the address of the youngest (lowest-address, highest offset) byte in the `Old` area.
|
|
|
|
|
|
|
|
|
Note that `RegSlot` areas are very small (since they only need to store a single register), while `CallArea` are contiguous chunks of arguments.
|
|
|
|
|
|
|
|
|
To name a specific location on the stack, we represent its address with a new kind of `CmmExpr`: the `CmmStackSlot`.
|
|
|
A `CmmStackSlot` is just an integer offset into an `Area`.
|
|
|
|
|
|
To address a 4-byte object at the old end of the `Area`, we use the offset 4.
|
|
|
|
|
|
|
|
|
Notice that a `CmmStackSlot` is an *address*, so we can say
|
|
|
|
... | ... | |