/*
* Optimize return, load, and store primitives using macros
* Get rid of the negates and addition/subtraction
+ * 128 byte red-zone between stack and heap
*/
//---------------------------------------------------------------------
// x86_64 Preserved Registers:
// rbx, rsp, rbp, r12, r13, r14, r15
-.set PC, %rsi
-.set SP, %rsp
-.set FP, %rbp
-.set AC, %rax
-.set T1, %rbx
+.set PC, %rsi /* Program Counter */
+.set SP, %rsp /* Stack Pointer*/
+.set FP, %rbp /* Frame Pointer */
+.set AC, %rax /* Accumulator Register */
+.set T1, %rbx /* Temporary Register */
+.set HP, %r12 /* Heap Pointer */
+.set TP, %r13 /* Task Pointer */
// When calling C code PC and AC must be manually preserved!
+/* Task Representation as a C struct:
+ typedef struct Task {
+ uintptr_t PC; // Program Counter
+ uintptr_t SP; // Stack Pointer
+ uintptr_t FP; // Frame Pointer
+ uintptr_t AC; // Accumulator Register
+ uintptr_t T1; // Temporary Register
+ uintptr_t HP; // Heap Pointer
+ struct Task* next; // Next task in task list
+ uintptr_t mem[]; // Stack and Heap Memory
+ } Task;
+*/
+
//---------------------------------------------------------------------
// Value Tagging
//---------------------------------------------------------------------
popq %rdi
call _exit
-// Exit a function, returning to the caller BROKEN!!
+// Exit a function, returning to the caller
defcode OP_return
popq T1
lodsq
// Predicate Primitives
//---------------------------------------------------------------------
-
//---------------------------------------------------------------------
// Main Routine
//---------------------------------------------------------------------
leaq cold_start(%rip), PC
NEXT
+ .text
+ .global _task_start
+ .p2align 4, 0x90
+_task_start:
+ movq %rdi, TP
+ movq (TP), PC
+ movq 8(TP), SP
+ movq 16(TP), FP
+ movq 24(TP), AC
+ movq 32(TP), T1
+ movq 40(TP), HP
+ NEXT
+
+ .text
+ .global _task_yield
+ .p2align 4, 0x90
+_task_yield:
+ movq PC, (TP)
+ movq SP, 8(TP)
+ movq FP, 16(TP)
+ movq AC, 24(TP)
+ movq T1, 32(TP)
+ movq HP, 40(TP)
+ /* ...switch to next task here... */
+
// First instructions to execute by the interpreter
.data
.global cold_start