This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
dev:crosscompiler:backend_ppc:code_generator [2015/12/16 12:03] – [Stackframe] ursgraf | dev:crosscompiler:backend_ppc:code_generator [2022/12/20 15:52] (current) – [Accessing the Hardware] ursgraf | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Code Generator ====== | + | ====== Code Generator |
All results of all SSA instructions have an assigned register. Now, each SSA instruction can be translated into one or a sequence of machine instructions. In order to do this, we must define the stackframe, which is used when calling a method. | All results of all SSA instructions have an assigned register. Now, each SSA instruction can be translated into one or a sequence of machine instructions. In order to do this, we must define the stackframe, which is used when calling a method. | ||
===== Stackframe ===== | ===== Stackframe ===== | ||
We use a stack pointer (R1) but no frame pointer. | We use a stack pointer (R1) but no frame pointer. | ||
- | [{{ .:stackframe.png? | + | [{{ .:stackframeppc.png? |
Explanation: | Explanation: | ||
LR is saved onto the stack first. Side note: This could be optimized, if method is a leaf method LR can stay unsaved. CTR, CR and XER need not to be saved. All of them might be used but they are never used across method calls. Considering the GPR's and FPR's, all nonvolatile register, which are used within this method, must be saved on the stack. Important: volatile FPR's must be saved as well if '' | LR is saved onto the stack first. Side note: This could be optimized, if method is a leaf method LR can stay unsaved. CTR, CR and XER need not to be saved. All of them might be used but they are never used across method calls. Considering the GPR's and FPR's, all nonvolatile register, which are used within this method, must be saved on the stack. Important: volatile FPR's must be saved as well if '' | ||
- | The field //local variables// is only used if the number of registers does not suffice. When dealing with FPR's some temprary | + | The field //local variables// is only used if the number of registers does not suffice. When dealing with FPR's some temporary |
- | Padding ensures that the stack frame is always a multiple of 16 bytes (quad-word aligned). \\ The field // | + | Padding ensures that the stack frame is always a multiple of 16 bytes (quad-word aligned). \\ The field // |
The stack pointer always points to the top of the actual frame. At the top the stack pointer of the caller has to be stored. When creating a new frame the relocation of the pointer and storing of its previous value must be atomic. This is achieved with the instruction //stwu//. When leaving the method in the epilogue a simple instruction //addi// suffices, since the compiler knows the size of the frame. The back chain pointer is used for the debugger, for exceptions and for the garbage collection. | The stack pointer always points to the top of the actual frame. At the top the stack pointer of the caller has to be stored. When creating a new frame the relocation of the pointer and storing of its previous value must be atomic. This is achieved with the instruction //stwu//. When leaving the method in the epilogue a simple instruction //addi// suffices, since the compiler knows the size of the frame. The back chain pointer is used for the debugger, for exceptions and for the garbage collection. | ||
\\ | \\ | ||
Line 33: | Line 33: | ||
* Addresses of class variables | * Addresses of class variables | ||
* Addresses of constants (floats, strings, type descriptors) | * Addresses of constants (floats, strings, type descriptors) | ||
- | Such addresses must be loaded with the aid of an auxilliary | + | Such addresses must be loaded with the aid of an auxiliary |
===== Accessing the Hardware ===== | ===== Accessing the Hardware ===== | ||
- | Java does not allow direct access and manipulation of absolute memory locations. Nevertheless this is essential for embedded programming. We therefore include this possibility by the use a special | + | Java does not allow direct access and manipulation of absolute memory locations. Nevertheless this is essential for embedded programming. We therefore include this possibility by using a special class //org.deepjava.unsafe.ppc.US.java// (US stand for unsafe). Wenn methods of this class are used the code generator has to insert machine code directly. |
===== Low Level Classes ===== | ===== Low Level Classes ===== | ||
Line 48: | Line 48: | ||
* Delegation of interface methods: address of this method inserted into the type descriptor by the linker | * Delegation of interface methods: address of this method inserted into the type descriptor by the linker | ||
* Exception handling: call to this methods inserted by the code generator | * Exception handling: call to this methods inserted by the code generator | ||
+ | |||
+ | ==== Practical Implementation of Searching the Correct Interface Method ==== | ||
+ | // | ||
+ | R10 holds the necessary information for the delegate method. The first two bytes are the ID of the sought-after interface, tho last to bytes contain the method offset. Loading of R10 should happen after parameter copying as R10 might be used there. | ||
+ | |||
+ |