commit bb2521efa29d3f3746ac04f148516f4f145d3402
parent 98221f3153817e479d4baf6deea9e07d5f5ebd9e
Author: erai <erai@omiltem.net>
Date: Fri, 31 Jan 2025 02:51:02 +0000
remove the manual compiler
Diffstat:
M | as.om | | | 513 | ------------------------------------------------------------------------------- |
M | cc1.om | | | 436 | +------------------------------------------------------------------------------ |
M | ir.om | | | 195 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- |
3 files changed, 193 insertions(+), 951 deletions(-)
diff --git a/as.om b/as.om
@@ -435,519 +435,6 @@ func add_symbol(c: *assembler, name: *byte, l: *label) {
c.symbols = s;
}
-func emit_restorer(c: *assembler) {
- as_modri(c, OP_MOVI, R_RAX, 15);
- as_op(c, OP_SYSCALL);
-}
-
-func emit_ptr(c: *assembler, l: *label) {
- reserve(c, 16);
- as_modrm(c, OP_LEA, R_RAX, R_RIP, 0, 0, 128);
- addfixup(c, l);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_jmp(c: *assembler, l: *label) {
- as_jmp(c, OP_JMP, l);
-}
-
-func emit_num(c: *assembler, x: int) {
- as_opri64(c, OP_MOVABS, R_RDX, x);
- as_opr(c, OP_PUSHR, R_RDX);
-}
-
-func emit_blob(c: *assembler, s: *byte, n: int) {
- var a: *label;
- var b: *label;
- var i: int;
-
- a = mklabel(c);
- b = mklabel(c);
-
- as_jmp(c, OP_JMP, b);
-
- fixup_label(c, a);
-
- i = 0;
- loop {
- if i == n {
- break;
- }
- as_emit(c, s[i] as int);
- i = i + 1;
- }
- as_emit(c, 0);
-
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
-
- fixup_label(c, b);
- emit_ptr(c, a);
-}
-
-func emit_str(c: *assembler, s: *byte) {
- var a: *label;
- var b: *label;
- var i: int;
-
- a = mklabel(c);
- b = mklabel(c);
-
- as_jmp(c, OP_JMP, b);
-
- fixup_label(c, a);
-
- i = 0;
- loop {
- if (!s[i]) {
- break;
- }
- as_emit(c, s[i] as int);
- i = i + 1;
- }
- as_emit(c, 0);
-
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
- as_op(c, OP_NOP);
-
- fixup_label(c, b);
- emit_ptr(c, a);
-}
-
-func emit_pop(c: *assembler, n: int) {
- as_modri(c, OP_ADDI, R_RSP, n << 3);
-}
-
-func emit_kstart(c: *assembler) {
- var hang: *label;
- var do_iret: *label;
- var do_ret: *label;
- var done: *label;
-
- c.bits32 = 1;
-
- hang = mklabel(c);
- do_iret = mklabel(c);
- do_ret = mklabel(c);
- done = mklabel(c);
-
- // Check for valid multiboot magic
- as_modri(c, OP_MOVI, R_RDX, 0x2badb002);
- as_modrr(c, OP_CMPRM, R_RAX, R_RDX);
- as_jmp(c, OP_JCC + CC_NE, hang);
-
- // Setup an early stack
- as_modri(c, OP_MOVI, R_RSP, 0x00300000); // FIXME bss
-
- // Align stack to page
- as_modri(c, OP_ANDI, R_RSP, -0x1000);
-
- // pt3 -> 1g
- as_modri(c, OP_SUBI, R_RSP, 0x1000);
- as_modri(c, OP_MOVI, R_RAX, 0x83);
- as_modri(c, OP_MOVI, R_RDX, 0);
- as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 0);
- as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 4);
- as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 510 * 8 + 0);
- as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 510 * 8 + 4);
-
- // pt4 -> pt3
- as_modrr(c, OP_MOVE, R_RAX, R_RSP);
- as_modri(c, OP_SUBI, R_RSP, 0x1000);
- as_modri(c, OP_ORI, R_RAX, 3);
- as_modri(c, OP_MOVI, R_RDX, 0);
- as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 0);
- as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 4);
- as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 511 * 8 + 0);
- as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 511 * 8 + 4);
-
- // Load page table pt4
- as_modrr(c, OP_WRCRR, R_CR3, R_RSP);
-
- // Allocate space for the gdt
- as_modri(c, OP_SUBI, R_RSP, 64);
- as_modrr(c, OP_MOVE, R_RBP, R_RSP);
-
- // Null Segment
- as_modri(c, OP_MOVI, R_RAX, 0x00000000);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 8);
- as_modri(c, OP_MOVI, R_RAX, 0x00000000);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 12);
-
- // Kernel code segment
- as_modri(c, OP_MOVI, R_RAX, 0x00000000);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 16);
- as_modri(c, OP_MOVI, R_RAX, 0x00209800);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 20);
-
- // Kernel data segment
- as_modri(c, OP_MOVI, R_RAX, 0x00000000);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 24);
- as_modri(c, OP_MOVI, R_RAX, 0x00009200);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 28);
-
- // Load gdt
- as_modri(c, OP_MOVI, R_RAX, 23);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 0);
- as_modrm(c, OP_LEA, R_RAX, R_RBP, 0, 0, 8);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 2);
- as_modm(c, OP_LGDTM, R_RBP, 0, 0, 0);
-
- // Load null lldt
- as_modri(c, OP_MOVI, R_RAX, 0);
- as_modr(c, OP_LLDTM, R_RAX);
-
- // Load null idt
- as_modm(c, OP_LIDTM, R_RBP, 0, 0, 8);
-
- // Enable pae
- as_modri(c, OP_MOVI, R_RAX, 0xa0);
- as_modrr(c, OP_WRCRR, R_CR4, R_RAX);
-
- // Enable long mode
- as_modri(c, OP_MOVI, R_RCX, (-1 << 32) + (0xc0 << 24) + 0x000080);
- as_op(c, OP_RDMSR);
- as_modri(c, OP_ORI, R_RAX, 0x100);
- as_op(c, OP_WRMSR);
-
- // Enable paging
- as_modrr(c, OP_RDCRR, R_CR0, R_RAX);
- as_modri(c, OP_ORI, R_RAX, (-0x80000000) | 0x0001);
- as_modrr(c, OP_WRCRR, R_CR0, R_RAX);
-
- // flags
- as_modri(c, OP_MOVI, R_RAX, 0);
- as_opr(c, OP_PUSHR, R_RAX);
- // cs
- as_modri(c, OP_MOVI, R_RAX, 8);
- as_opr(c, OP_PUSHR, R_RAX);
- // pointer
- as_jmp(c, OP_CALL, do_iret);
-
- c.bits32 = 0;
-
- // Jump to top half
- as_jmp(c, OP_CALL, do_ret);
-
- // Reload the gdt in the top half
- as_modri(c, OP_ORI, R_RBP, -0x80000000);
- as_modri(c, OP_MOVI, R_RAX, 23);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 0);
- as_modrm(c, OP_LEA, R_RAX, R_RBP, 0, 0, 8);
- as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 2);
- as_modm(c, OP_LGDTM, R_RBP, 0, 0, 0);
-
- // Reload segments
- as_modri(c, OP_MOVI, R_RAX, 16);
- as_modrr(c, OP_WRSR, R_ES, R_RAX);
- as_modrr(c, OP_WRSR, R_DS, R_RAX);
- as_modrr(c, OP_WRSR, R_FS, R_RAX);
- as_modrr(c, OP_WRSR, R_GS, R_RAX);
- as_modrr(c, OP_WRSR, R_SS, R_RAX);
- as_modrr(c, OP_MOVE, R_RSP, R_RSP);
-
- // Reload stack in the top half
- as_modri(c, OP_ORI, R_RSP, -0x80000000);
-
- // Kill the lower mapping
- as_modri(c, OP_MOVI, R_RAX, 0);
- as_modrm(c, OP_LEA, R_RDI, R_RBP, 0, 0, 64);
- as_modrm(c, OP_STORE, R_RAX, R_RDI, 0, 0, 4096);
- as_modrm(c, OP_STORE, R_RAX, R_RDI, 0, 0, 0);
- as_modri(c, OP_ANDI, R_RDI, 0x7fffffff);
- as_modrr(c, OP_WRCRR, R_CR3, R_RDI);
-
- // Setup a call frame for _kstart
- as_jmp(c, OP_JMP, done);
-
- // hlt forever
- fixup_label(c, hang);
- as_op(c, OP_CLI);
- as_op(c, OP_HLT);
- as_jmp(c, OP_JMP, hang);
-
- // iret to long mode
- fixup_label(c, do_iret);
- as_op(c, OP_IRET);
-
- // ret to top half
- fixup_label(c, do_ret);
- as_opr(c, OP_POPR, R_RAX);
- as_modri(c, OP_ORI, R_RAX, -0x80000000);
- as_opr(c, OP_PUSHR, R_RAX);
- as_op(c, OP_RET);
-
- // Setup a call frame for _kstart
- fixup_label(c, done);
- as_modrr(c, OP_XORRM, R_RBP, R_RBP);
- as_opr(c, OP_PUSHR, R_RBX);
- as_modrr(c, OP_MOVE, R_RDI, R_RBX);
- as_opr(c, OP_PUSHR, R_RBP);
-}
-
-func emit_preamble(c: *assembler, n: int, pragma: int) {
- var i: int;
- if (pragma == 1) {
- as_modrr(c, OP_XORRM, R_RBP, R_RBP);
- as_modrm(c, OP_LOAD, R_RDI, R_RSP, 0, 0, 0);
- as_modrm(c, OP_LEA, R_RSI, R_RSP, 0, 0, 8);
- as_modrm(c, OP_LEA, R_RDX, R_RSI, R_RDI, 8, 8);
- as_opr(c, OP_PUSHR, R_RDX);
- as_opr(c, OP_PUSHR, R_RSI);
- as_opr(c, OP_PUSHR, R_RDI);
- as_opr(c, OP_PUSHR, R_RBP);
- } else if (pragma > 1) {
- emit_kstart(c);
- }
- as_opr(c, OP_PUSHR, R_RBP);
- as_modrr(c, OP_MOVE, R_RBP, R_RSP);
- i = 0;
- loop {
- if (i >= n) {
- break;
- }
- emit_num(c, 0);
- i = i + 8;
- }
-}
-
-func emit_store(c: *assembler, t: *type) {
- as_opr(c, OP_POPR, R_RDI);
- as_opr(c, OP_POPR, R_RAX);
- if (t.kind == TY_BYTE) {
- as_modrm(c, OP_STOREB, R_RAX, R_RDI, 0, 0, 0);
- } else if (type_isprim(t)) {
- as_modrm(c, OP_STORE, R_RAX, R_RDI, 0, 0, 0);
- } else {
- die("invalid store");
- }
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_load(c: *assembler, t: *type) {
- as_opr(c, OP_POPR, R_RDI);
- if (t.kind == TY_BYTE) {
- as_modrr(c, OP_XORRM, R_RAX, R_RAX);
- as_modrm(c, OP_LOADB, R_RAX, R_RDI, 0, 0, 0);
- } else if (type_isprim(t)) {
- as_modrm(c, OP_LOAD, R_RAX, R_RDI, 0, 0, 0);
- } else {
- die("invalid load");
- }
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_jz(c: *assembler, l: *label) {
- as_opr(c, OP_POPR, R_RAX);
- as_modrr(c, OP_TESTRM, R_RAX, R_RAX);
- as_jmp(c, OP_JCC + CC_E, l);
-}
-
-func emit_lea(c: *assembler, offset: int) {
- as_modrm(c, OP_LEA, R_RAX, R_RBP, 0, 0, offset);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_and(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RDX);
- as_modrr(c, OP_ANDRM, R_RAX, R_RDX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_or(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RDX);
- as_modrr(c, OP_ORRM, R_RAX, R_RDX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_xor(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RDX);
- as_modrr(c, OP_XORRM, R_RAX, R_RDX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_add(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RDX);
- as_modrr(c, OP_ADDRM, R_RAX, R_RDX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_ud(c: *assembler) {
- as_op(c, OP_UD2);
-}
-
-func emit_ret(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_modrr(c, OP_MOVE, R_RSP, R_RBP);
- as_opr(c, OP_POPR, R_RBP);
- as_op(c, OP_RET);
-}
-
-func emit_call(c: *assembler, n: int) {
- as_opr(c, OP_POPR, R_RAX);
- as_modr(c, OP_ICALLM, R_RAX);
- emit_pop(c, n);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_lcall(c: *assembler, l: *label, n: int) {
- as_jmp(c, OP_CALL, l);
- emit_pop(c, n);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_gt(c: *assembler) {
- as_opr(c, OP_POPR, R_RDX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RAX, R_RAX);
- as_modrr(c, OP_CMPRM, R_RDX, R_RCX);
- as_modrr(c, OP_SETCC + CC_G, 0, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_lt(c: *assembler) {
- as_opr(c, OP_POPR, R_RDX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RAX, R_RAX);
- as_modrr(c, OP_CMPRM, R_RDX, R_RCX);
- as_modrr(c, OP_SETCC + CC_L, 0, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_ge(c: *assembler) {
- as_opr(c, OP_POPR, R_RDX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RAX, R_RAX);
- as_modrr(c, OP_CMPRM, R_RDX, R_RCX);
- as_modrr(c, OP_SETCC + CC_GE, 0, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_le(c: *assembler) {
- as_opr(c, OP_POPR, R_RDX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RAX, R_RAX);
- as_modrr(c, OP_CMPRM, R_RDX, R_RCX);
- as_modrr(c, OP_SETCC + CC_LE, 0, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_eq(c: *assembler) {
- as_opr(c, OP_POPR, R_RDX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RAX, R_RAX);
- as_modrr(c, OP_CMPRM, R_RDX, R_RCX);
- as_modrr(c, OP_SETCC + CC_E, 0, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_ne(c: *assembler) {
- as_opr(c, OP_POPR, R_RDX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RAX, R_RAX);
- as_modrr(c, OP_CMPRM, R_RDX, R_RCX);
- as_modrr(c, OP_SETCC + CC_NE, 0, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_sub(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RDX);
- as_modrr(c, OP_SUBRM, R_RAX, R_RDX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_mul(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RCX);
- as_modr(c, OP_IMULM, R_RCX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_div(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RDX, R_RDX);
- as_modrr(c, OP_TESTRM, R_RAX, R_RAX);
- as_modrr(c, OP_SETCC + CC_S, 0, R_RDX);
- as_modr(c, OP_NEGM, R_RDX);
- as_modr(c, OP_IDIVM, R_RCX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_mod(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RCX);
- as_modrr(c, OP_XORRM, R_RDX, R_RDX);
- as_modrr(c, OP_TESTRM, R_RAX, R_RAX);
- as_modrr(c, OP_SETCC + CC_S, 0, R_RDX);
- as_modr(c, OP_NEGM, R_RDX);
- as_modr(c, OP_IDIVM, R_RCX);
- as_opr(c, OP_PUSHR, R_RDX);
-}
-
-func emit_lsh(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RCX);
- as_modr(c, OP_SHLM, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_rsh(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_opr(c, OP_POPR, R_RCX);
- as_modr(c, OP_SHRM, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_not(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_modr(c, OP_NOTM, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_neg(c: *assembler) {
- as_opr(c, OP_POPR, R_RAX);
- as_modr(c, OP_NEGM, R_RAX);
- as_opr(c, OP_PUSHR, R_RAX);
-}
-
-func emit_align(c: *assembler, n: int, b: int) {
- var pad: int;
-
- pad = c.at & (n - 1);
-
- if pad == 0 {
- return;
- }
-
- loop {
- if pad == n {
- break;
- }
-
- as_emit(c, b);
-
- pad = pad + 1;
- }
-}
-
func emit_strtab_str(c: *assembler, s: *byte): int {
var i: int;
diff --git a/cc1.om b/cc1.om
@@ -1299,283 +1299,6 @@ func gather_include(c: *compiler, filename: *byte, slen: *int): *byte {
return blob;
}
-func compile_include(c: *compiler, n: *node) {
- var blob: *byte;
- var len: int;
-
- if n.b.a.kind != N_STR {
- die("non literal include");
- }
-
- blob = gather_include(c, n.b.a.s, &len);
-
- as_opr(c.s, OP_POPR, R_RAX);
- as_opr(c.s, OP_POPR, R_RDI);
- as_opri64(c.s, OP_MOVABS, R_RAX, len);
- as_modrm(c.s, OP_STORE, R_RAX, R_RDI, 0, 0, 0);
- emit_blob(c.s, blob, len);
-
- free(c.a, blob);
-}
-
-// Translate an expression
-func compile_expr(c: *compiler, d: *decl, n: *node, rhs: int) {
- var no: *label;
- var out: *label;
- var v: *decl;
- var kind: int;
-
- update_place(c, n);
-
- kind = n.kind;
- if (kind == N_STR) {
- emit_str(c.s, n.s);
- } else if (kind == N_NIL) {
- emit_num(c.s, 0);
- } else if (kind == N_NUM) {
- emit_num(c.s, n.n);
- } else if (kind == N_CHAR) {
- emit_num(c.s, n.n);
- } else if (kind == N_EXPRLIST) {
- if (n.b) {
- compile_expr(c, d, n.b, 1);
- }
-
- compile_expr(c, d, n.a, 1);
- } else if (kind == N_CALL) {
- if (n.b) {
- compile_expr(c, d, n.b, 1);
- }
-
- if (n.a.kind == N_IDENT) {
- v = find(c, n.a.s, nil, 0);
- if (v && v.enum_defined) {
- cdie(c, "type error");
- }
-
- v = find(c, d.name, n.a.s, 0);
- if (v && v.var_defined) {
- emit_lea(c.s, v.var_offset);
- emit_load(c.s, n.a.t);
- emit_call(c.s, count_args(c, n.a.t.arg));
- } else if !strcmp(n.a.s, "_include") {
- v = find(c, n.a.s, nil, 0);
- compile_include(c, n);
- } else {
- v = find(c, n.a.s, nil, 0);
- emit_lcall(c.s, v.func_label, count_args(c, n.a.t.arg));
- }
- } else {
- compile_expr(c, d, n.a, 1);
- emit_call(c.s, count_args(c, n.a.t.arg));
- }
-
- if (n.b) {
- unify(c, n.a.t.arg, n.b.t);
- } else {
- unify(c, n.a.t.arg, nil);
- }
- } else if (kind == N_DOT) {
- compile_expr(c, d, n.a, 0);
-
- if (n.a.t.kind == TY_PTR) {
- v = find(c, n.a.t.val.st.name, n.b.s, 0);
- emit_load(c.s, n.a.t);
- } else {
- v = find(c, n.a.t.st.name, n.b.s, 0);
- }
-
- emit_num(c.s, v.member_offset);
- emit_add(c.s);
-
- if (rhs) {
- emit_load(c.s, n.t);
- }
- } else if (kind == N_IDENT) {
- v = find(c, n.s, nil, 0);
- if (v && v.enum_defined) {
- emit_num(c.s, v.enum_value);
- return;
- }
-
- v = find(c, d.name, n.s, 0);
- if (v && v.var_defined) {
- emit_lea(c.s, v.var_offset);
- if (rhs) {
- emit_load(c.s, n.t);
- }
- return;
- }
-
- v = find(c, n.s, nil, 0);
- if (v && v.func_defined) {
- emit_ptr(c.s, v.func_label);
- return;
- }
- } else if (kind == N_ASSIGN) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 0);
-
- emit_store(c.s, n.t);
- } else if (kind == N_SIZEOF) {
- if (n.a.t.kind == TY_BYTE) {
- emit_num(c.s, 1);
- } else {
- emit_num(c.s, type_sizeof(c, n.a.t));
- }
- } else if (kind == N_REF) {
- compile_expr(c, d, n.a, 0);
- } else if (kind == N_DEREF) {
- compile_expr(c, d, n.a, 1);
-
- if (rhs) {
- emit_load(c.s, n.t);
- }
- } else if (kind == N_INDEX) {
- compile_expr(c, d, n.a, 1);
- compile_expr(c, d, n.b, 1);
-
- if (n.t.kind == TY_BYTE) {
- emit_num(c.s, 1);
- } else {
- emit_num(c.s, type_sizeof(c, n.t));
- }
-
- emit_mul(c.s);
- emit_add(c.s);
-
- if (rhs) {
- emit_load(c.s, n.t);
- }
- } else if (kind == N_LT) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_lt(c.s);
- } else if (kind == N_GT) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_gt(c.s);
- } else if (kind == N_LE) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_le(c.s);
- } else if (kind == N_GE) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_ge(c.s);
- } else if (kind == N_EQ) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_eq(c.s);
- } else if (kind == N_NE) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_ne(c.s);
- } else if (kind == N_BNOT) {
- no = mklabel(c.s);
- out = mklabel(c.s);
-
- compile_expr(c, d, n.a, 1);
-
- emit_jz(c.s, no);
- emit_num(c.s, 0);
- emit_jmp(c.s, out);
- fixup_label(c.s, no);
- emit_num(c.s, 1);
- fixup_label(c.s, out);
- } else if (kind == N_BOR) {
- no = mklabel(c.s);
- out = mklabel(c.s);
-
- compile_expr(c, d, n.a, 1);
- emit_jz(c.s, no);
- emit_num(c.s, 1);
- emit_jmp(c.s, out);
-
- fixup_label(c.s, no);
- no = mklabel(c.s);
-
- compile_expr(c, d, n.b, 1);
- emit_jz(c.s, no);
- emit_num(c.s, 1);
- emit_jmp(c.s, out);
-
- fixup_label(c.s, no);
- emit_num(c.s, 0);
-
- fixup_label(c.s, out);
- } else if (kind == N_BAND) {
- no = mklabel(c.s);
- out = mklabel(c.s);
-
- compile_expr(c, d, n.a, 1);
- emit_jz(c.s, no);
-
- compile_expr(c, d, n.b, 1);
- emit_jz(c.s, no);
-
- emit_num(c.s, 1);
- emit_jmp(c.s, out);
-
- fixup_label(c.s, no);
- emit_num(c.s, 0);
-
- fixup_label(c.s, out);
- } else if (kind == N_POS) {
- compile_expr(c, d, n.a, 1);
- } else if (kind == N_NEG) {
- compile_expr(c, d, n.a, 1);
- emit_neg(c.s);
- } else if (kind == N_NOT) {
- compile_expr(c, d, n.a, 1);
- emit_not(c.s);
- } else if (kind == N_ADD) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_add(c.s);
- } else if (kind == N_SUB) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_sub(c.s);
- } else if (kind == N_MUL) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_mul(c.s);
- } else if (kind == N_DIV) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_div(c.s);
- } else if (kind == N_MOD) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_mod(c.s);
- } else if (kind == N_LSH) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_lsh(c.s);
- } else if (kind == N_RSH) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_rsh(c.s);
- } else if (kind == N_AND) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_and(c.s);
- } else if (kind == N_OR) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_or(c.s);
- } else if (kind == N_XOR) {
- compile_expr(c, d, n.b, 1);
- compile_expr(c, d, n.a, 1);
- emit_xor(c.s);
- } else if (kind == N_CAST) {
- compile_expr(c, d, n.a, 1);
- } else {
- cdie(c, "not an expression");
- }
-}
-
func call_check(c: *compiler, n: *node): int {
var result: int;
var ret: int;
@@ -1646,92 +1369,6 @@ func update_place(c: *compiler, n: *node) {
c.s.lineno = n.lineno;
}
-// Compile a statement
-func compile_stmt(c: *compiler, d: *decl, n: *node, top: *label, out: *label) {
- var no: *label;
- var ifout: *label;
- var v: *decl;
- var kind: int;
-
- if (!n) {
- return;
- }
-
- update_place(c, n);
-
- kind = n.kind;
- if (kind == N_CONDLIST) {
- ifout = mklabel(c.s);
- no = nil;
- loop {
- if (no) {
- fixup_label(c.s, no);
- }
-
- if (!n) {
- break;
- }
-
- no = mklabel(c.s);
-
- if (n.a.a) {
- compile_expr(c, d, n.a.a, 1);
- emit_jz(c.s, no);
- }
-
- compile_stmt(c, d, n.a.b, top, out);
- emit_jmp(c.s, ifout);
-
- n = n.b;
- }
- fixup_label(c.s, ifout);
- } else if (kind == N_STMTLIST) {
- loop {
- if (!n) {
- break;
- }
- compile_stmt(c, d, n.a, top, out);
- n = n.b;
- }
- } else if (kind == N_LOOP) {
- top = mklabel(c.s);
- out = mklabel(c.s);
- fixup_label(c.s, top);
- compile_stmt(c, d, n.a, top, out);
- emit_jmp(c.s, top);
- fixup_label(c.s, out);
- } else if (kind == N_BREAK) {
- if (!out) {
- cdie(c, "break outside loop");
- }
- emit_jmp(c.s, out);
- } else if (kind == N_CONTINUE) {
- if (!top) {
- cdie(c, "continue outside loop");
- }
- emit_jmp(c.s, top);
- } else if (kind == N_RETURN) {
- if (n.a) {
- compile_expr(c, d, n.a, 1);
- } else {
- emit_num(c.s, 0);
- }
- emit_ret(c.s);
- } else if (kind == N_LABEL) {
- v = find(c, d.name, n.a.s, 0);
- fixup_label(c.s, v.goto_label);
- } else if (kind == N_GOTO) {
- v = find(c, d.name, n.a.s, 0);
- if (!v || !v.goto_defined) {
- cdie(c, "label not defined");
- }
- emit_jmp(c.s, v.goto_label);
- } else if (kind != N_VARDECL) {
- compile_expr(c, d, n, 1);
- emit_pop(c.s, 1);
- }
-}
-
func emit_ssr(c: *compiler) {
var d: *decl;
var v: *decl;
@@ -1987,8 +1624,8 @@ func emit_builtin(c: *compiler) {
if (d.func_defined && !d.func_label.fixed) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
- as_op(c.s, OP_UD2);
- emit_restorer(c.s);
+ as_modri(c.s, OP_MOVI, R_RAX, 15);
+ as_op(c.s, OP_SYSCALL);
}
d = find(c, "_include", nil, 1);
@@ -2010,7 +1647,6 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDI, R_RBP, 0, 0, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RDI, 0, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDI, R_RBP, 0, 0, 24);
@@ -2029,7 +1665,6 @@ func emit_builtin(c: *compiler) {
as_modrm(c.s, OP_LOAD, R_RDI, R_RBP, 0, 0, 40);
as_modrm(c.s, OP_STORE, R_RBX, R_RDI, 0, 0, 0);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "inb", nil, 1);
@@ -2037,11 +1672,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDX, R_RBP, 0, 0, 16);
as_op(c.s, OP_IN);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "outb", nil, 1);
@@ -2049,12 +1682,10 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDX, R_RBP, 0, 0, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
as_op(c.s, OP_OUT);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "inw", nil, 1);
@@ -2062,12 +1693,10 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDX, R_RBP, 0, 0, 16);
as_emit(c.s, OP_OS);
as_op(c.s, OP_IND);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "outw", nil, 1);
@@ -2075,13 +1704,11 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDX, R_RBP, 0, 0, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
as_emit(c.s, OP_OS);
as_op(c.s, OP_OUTD);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "ind", nil, 1);
@@ -2089,11 +1716,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDX, R_RBP, 0, 0, 16);
as_op(c.s, OP_IND);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "outd", nil, 1);
@@ -2101,12 +1726,10 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDX, R_RBP, 0, 0, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
as_op(c.s, OP_OUTD);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "rdmsr", nil, 1);
@@ -2114,14 +1737,12 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RCX, R_RBP, 0, 0, 16);
as_op(c.s, OP_RDMSR);
as_modri(c.s, OP_MOVI, R_RCX, 32);
as_modr(c.s, OP_SHLM, R_RDX);
as_modrr(c.s, OP_ORRM, R_RAX, R_RDX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "wrmsr", nil, 1);
@@ -2129,7 +1750,6 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
as_modrr(c.s, OP_MOVE, R_RDX, R_RAX);
as_modri(c.s, OP_MOVI, R_RCX, 32);
@@ -2137,7 +1757,6 @@ func emit_builtin(c: *compiler) {
as_modrm(c.s, OP_LOAD, R_RCX, R_RBP, 0, 0, 16);
as_op(c.s, OP_WRMSR);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "rdcr0", nil, 1);
@@ -2145,10 +1764,8 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrr(c.s, OP_RDCRR, R_CR0, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "wrcr0", nil, 1);
@@ -2156,11 +1773,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RCX, R_RBP, 0, 0, 16);
as_modrr(c.s, OP_WRCRR, R_CR0, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "rdcr2", nil, 1);
@@ -2168,10 +1783,8 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrr(c.s, OP_RDCRR, R_CR2, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "wrcr2", nil, 1);
@@ -2179,11 +1792,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RCX, R_RBP, 0, 0, 16);
as_modrr(c.s, OP_WRCRR, R_CR2, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "rdcr3", nil, 1);
@@ -2191,10 +1802,8 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrr(c.s, OP_RDCRR, R_CR3, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "wrcr3", nil, 1);
@@ -2202,11 +1811,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RCX, R_RBP, 0, 0, 16);
as_modrr(c.s, OP_WRCRR, R_CR3, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "rdcr4", nil, 1);
@@ -2214,10 +1821,8 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrr(c.s, OP_RDCRR, R_CR4, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "wrcr4", nil, 1);
@@ -2225,11 +1830,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RCX, R_RBP, 0, 0, 16);
as_modrr(c.s, OP_WRCRR, R_CR4, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "lgdt", nil, 1);
@@ -2237,7 +1840,6 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modri(c.s, OP_SUBI, R_RSP, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
as_modri(c.s, OP_SUBI, R_RAX, 1);
@@ -2247,7 +1849,6 @@ func emit_builtin(c: *compiler) {
as_modm(c.s, OP_LGDTM, R_RSP, 0, 0, 0);
as_modri(c.s, OP_ADDI, R_RSP, 16);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "lidt", nil, 1);
@@ -2255,7 +1856,6 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modri(c.s, OP_SUBI, R_RSP, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
as_modri(c.s, OP_SUBI, R_RAX, 1);
@@ -2265,7 +1865,6 @@ func emit_builtin(c: *compiler) {
as_modm(c.s, OP_LIDTM, R_RSP, 0, 0, 0);
as_modri(c.s, OP_ADDI, R_RSP, 16);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "lldt", nil, 1);
@@ -2273,11 +1872,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 16);
as_modr(c.s, OP_LLDTM, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "ltr", nil, 1);
@@ -2285,11 +1882,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 16);
as_modr(c.s, OP_LTRM, R_RAX);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "lseg", nil, 1);
@@ -2297,7 +1892,6 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
// es ds fs gs
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
as_modrr(c.s, OP_WRSR, R_ES, R_RAX);
@@ -2326,7 +1920,6 @@ func emit_builtin(c: *compiler) {
as_emit(c.s, 0);
as_op(c.s, OP_IRETQ);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "hlt", nil, 1);
@@ -2334,10 +1927,8 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_op(c.s, OP_HLT);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "cli", nil, 1);
@@ -2345,10 +1936,8 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_op(c.s, OP_CLI);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "sti", nil, 1);
@@ -2356,10 +1945,8 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_op(c.s, OP_STI);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "rdflags", nil, 1);
@@ -2367,9 +1954,7 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_op(c.s, OP_PUSHF);
- emit_ret(c.s);
}
d = find(c, "wrflags", nil, 1);
@@ -2377,12 +1962,10 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_op(c.s, OP_PUSHF);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 16);
as_opr(c.s, OP_PUSHR, R_RAX);
as_op(c.s, OP_POPF);
- emit_ret(c.s);
}
d = find(c, "wbinvld", nil, 1);
@@ -2390,11 +1973,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 16);
as_modm(c.s, OP_WBINVD, R_RAX, 0, 0, 0);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "invlpg", nil, 1);
@@ -2402,11 +1983,9 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 16);
as_modm(c.s, OP_INVLPGM, R_RAX, 0, 0, 0);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "_ssr0", nil, 1);
@@ -2430,12 +2009,10 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RSI, R_RBP, 0, 0, 16);
as_emit(c.s, OP_GS);
as_modrm(c.s, OP_LOAD, R_RAX, R_RSI, 0, 0, 0);
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "_r32", nil, 1);
@@ -2443,13 +2020,11 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RSI, R_RBP, 0, 0, 16);
c.s.bits32 = 1;
as_modrm(c.s, OP_LOAD, R_RAX, R_RSI, 0, 0, 0);
c.s.bits32 = 0;
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "_w32", nil, 1);
@@ -2457,14 +2032,12 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDI, R_RBP, 0, 0, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
c.s.bits32 = 1;
as_modrm(c.s, OP_STORE, R_RAX, R_RDI, 0, 0, 0);
c.s.bits32 = 0;
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "_r16", nil, 1);
@@ -2472,14 +2045,12 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RSI, R_RBP, 0, 0, 16);
as_modrr(c.s, OP_XORRM, R_RAX, R_RAX);
c.s.bits32 = 1;
as_modrm(c.s, OP_LOAD16, R_RAX, R_RDI, 0, 0, 0);
c.s.bits32 = 0;
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "_w16", nil, 1);
@@ -2487,14 +2058,12 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_op(c.s, OP_UD2);
- emit_preamble(c.s, 0, 0);
as_modrm(c.s, OP_LOAD, R_RDI, R_RBP, 0, 0, 16);
as_modrm(c.s, OP_LOAD, R_RAX, R_RBP, 0, 0, 24);
c.s.bits32 = 1;
as_modrm(c.s, OP_STORE16, R_RAX, R_RDI, 0, 0, 0);
c.s.bits32 = 0;
as_opr(c.s, OP_PUSHR, R_RAX);
- emit_ret(c.s);
}
d = find(c, "_rdrand", nil, 1);
@@ -2502,7 +2071,6 @@ func emit_builtin(c: *compiler) {
fixup_label(c.s, d.func_label);
add_symbol(c.s, d.name, d.func_label);
as_modr(c.s, OP_RDRAND, R_RAX);
- emit_ret(c.s);
}
d = find(c, "taskswitch", nil, 1);
diff --git a/ir.om b/ir.om
@@ -1374,6 +1374,192 @@ func irshow(out: *file, b: *irblock) {
irreset(b);
}
+func emit_kstart(c: *assembler) {
+ var hang: *label;
+ var do_iret: *label;
+ var do_ret: *label;
+ var done: *label;
+
+ c.bits32 = 1;
+
+ hang = mklabel(c);
+ do_iret = mklabel(c);
+ do_ret = mklabel(c);
+ done = mklabel(c);
+
+ // Check for valid multiboot magic
+ as_modri(c, OP_MOVI, R_RDX, 0x2badb002);
+ as_modrr(c, OP_CMPRM, R_RAX, R_RDX);
+ as_jmp(c, OP_JCC + CC_NE, hang);
+
+ // Setup an early stack
+ as_modri(c, OP_MOVI, R_RSP, 0x00300000); // FIXME bss
+
+ // Align stack to page
+ as_modri(c, OP_ANDI, R_RSP, -0x1000);
+
+ // pt3 -> 1g
+ as_modri(c, OP_SUBI, R_RSP, 0x1000);
+ as_modri(c, OP_MOVI, R_RAX, 0x83);
+ as_modri(c, OP_MOVI, R_RDX, 0);
+ as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 0);
+ as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 4);
+ as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 510 * 8 + 0);
+ as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 510 * 8 + 4);
+
+ // pt4 -> pt3
+ as_modrr(c, OP_MOVE, R_RAX, R_RSP);
+ as_modri(c, OP_SUBI, R_RSP, 0x1000);
+ as_modri(c, OP_ORI, R_RAX, 3);
+ as_modri(c, OP_MOVI, R_RDX, 0);
+ as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 0);
+ as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 4);
+ as_modrm(c, OP_STORE, R_RAX, R_RSP, 0, 0, 511 * 8 + 0);
+ as_modrm(c, OP_STORE, R_RDX, R_RSP, 0, 0, 511 * 8 + 4);
+
+ // Load page table pt4
+ as_modrr(c, OP_WRCRR, R_CR3, R_RSP);
+
+ // Allocate space for the gdt
+ as_modri(c, OP_SUBI, R_RSP, 64);
+ as_modrr(c, OP_MOVE, R_RBP, R_RSP);
+
+ // Null Segment
+ as_modri(c, OP_MOVI, R_RAX, 0x00000000);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 8);
+ as_modri(c, OP_MOVI, R_RAX, 0x00000000);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 12);
+
+ // Kernel code segment
+ as_modri(c, OP_MOVI, R_RAX, 0x00000000);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 16);
+ as_modri(c, OP_MOVI, R_RAX, 0x00209800);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 20);
+
+ // Kernel data segment
+ as_modri(c, OP_MOVI, R_RAX, 0x00000000);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 24);
+ as_modri(c, OP_MOVI, R_RAX, 0x00009200);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 28);
+
+ // Load gdt
+ as_modri(c, OP_MOVI, R_RAX, 23);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 0);
+ as_modrm(c, OP_LEA, R_RAX, R_RBP, 0, 0, 8);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 2);
+ as_modm(c, OP_LGDTM, R_RBP, 0, 0, 0);
+
+ // Load null lldt
+ as_modri(c, OP_MOVI, R_RAX, 0);
+ as_modr(c, OP_LLDTM, R_RAX);
+
+ // Load null idt
+ as_modm(c, OP_LIDTM, R_RBP, 0, 0, 8);
+
+ // Enable pae
+ as_modri(c, OP_MOVI, R_RAX, 0xa0);
+ as_modrr(c, OP_WRCRR, R_CR4, R_RAX);
+
+ // Enable long mode
+ as_modri(c, OP_MOVI, R_RCX, (-1 << 32) + (0xc0 << 24) + 0x000080);
+ as_op(c, OP_RDMSR);
+ as_modri(c, OP_ORI, R_RAX, 0x100);
+ as_op(c, OP_WRMSR);
+
+ // Enable paging
+ as_modrr(c, OP_RDCRR, R_CR0, R_RAX);
+ as_modri(c, OP_ORI, R_RAX, (-0x80000000) | 0x0001);
+ as_modrr(c, OP_WRCRR, R_CR0, R_RAX);
+
+ // flags
+ as_modri(c, OP_MOVI, R_RAX, 0);
+ as_opr(c, OP_PUSHR, R_RAX);
+ // cs
+ as_modri(c, OP_MOVI, R_RAX, 8);
+ as_opr(c, OP_PUSHR, R_RAX);
+ // pointer
+ as_jmp(c, OP_CALL, do_iret);
+
+ c.bits32 = 0;
+
+ // Jump to top half
+ as_jmp(c, OP_CALL, do_ret);
+
+ // Reload the gdt in the top half
+ as_modri(c, OP_ORI, R_RBP, -0x80000000);
+ as_modri(c, OP_MOVI, R_RAX, 23);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 0);
+ as_modrm(c, OP_LEA, R_RAX, R_RBP, 0, 0, 8);
+ as_modrm(c, OP_STORE, R_RAX, R_RBP, 0, 0, 2);
+ as_modm(c, OP_LGDTM, R_RBP, 0, 0, 0);
+
+ // Reload segments
+ as_modri(c, OP_MOVI, R_RAX, 16);
+ as_modrr(c, OP_WRSR, R_ES, R_RAX);
+ as_modrr(c, OP_WRSR, R_DS, R_RAX);
+ as_modrr(c, OP_WRSR, R_FS, R_RAX);
+ as_modrr(c, OP_WRSR, R_GS, R_RAX);
+ as_modrr(c, OP_WRSR, R_SS, R_RAX);
+ as_modrr(c, OP_MOVE, R_RSP, R_RSP);
+
+ // Reload stack in the top half
+ as_modri(c, OP_ORI, R_RSP, -0x80000000);
+
+ // Kill the lower mapping
+ as_modri(c, OP_MOVI, R_RAX, 0);
+ as_modrm(c, OP_LEA, R_RDI, R_RBP, 0, 0, 64);
+ as_modrm(c, OP_STORE, R_RAX, R_RDI, 0, 0, 4096);
+ as_modrm(c, OP_STORE, R_RAX, R_RDI, 0, 0, 0);
+ as_modri(c, OP_ANDI, R_RDI, 0x7fffffff);
+ as_modrr(c, OP_WRCRR, R_CR3, R_RDI);
+
+ // Setup a call frame for _kstart
+ as_jmp(c, OP_JMP, done);
+
+ // hlt forever
+ fixup_label(c, hang);
+ as_op(c, OP_CLI);
+ as_op(c, OP_HLT);
+ as_jmp(c, OP_JMP, hang);
+
+ // iret to long mode
+ fixup_label(c, do_iret);
+ as_op(c, OP_IRET);
+
+ // ret to top half
+ fixup_label(c, do_ret);
+ as_opr(c, OP_POPR, R_RAX);
+ as_modri(c, OP_ORI, R_RAX, -0x80000000);
+ as_opr(c, OP_PUSHR, R_RAX);
+ as_op(c, OP_RET);
+
+ // Setup a call frame for _kstart
+ fixup_label(c, done);
+ as_modrr(c, OP_XORRM, R_RBP, R_RBP);
+ as_modrr(c, OP_MOVE, R_RDI, R_RBX);
+ as_opr(c, OP_PUSHR, R_RBP);
+}
+
+func emit_align(c: *assembler, n: int, b: int) {
+ var pad: int;
+
+ pad = c.at & (n - 1);
+
+ if pad == 0 {
+ return;
+ }
+
+ loop {
+ if pad == n {
+ break;
+ }
+
+ as_emit(c, b);
+
+ pad = pad + 1;
+ }
+}
+
func output_ir(c: *compiler, d: *decl) {
var ic: *irfunc;
@@ -1389,9 +1575,12 @@ func output_ir(c: *compiler, d: *decl) {
add_symbol(c.s, d.name, d.func_label);
if strcmp(d.name, "_start") == 0 {
- emit_preamble(c.s, 0, 1);
+ as_modrm(c.s, OP_LOAD, R_RDI, R_RSP, 0, 0, 0);
+ as_modrm(c.s, OP_LEA, R_RSI, R_RSP, 0, 0, 8);
+ as_modrm(c.s, OP_LEA, R_RDX, R_RSI, R_RDI, 8, 8);
+ as_opr(c.s, OP_PUSHR, R_RBP);
} else if strcmp(d.name, "_kstart") == 0 {
- emit_preamble(c.s, 0, 2);
+ emit_kstart(c.s);
}
//fputc(nil, '\n');
@@ -1922,11 +2111,9 @@ func output_irexpr(ic: *irfunc, b: *irblock, o: *irop) {
}
}
-// line numbers
// evaluator
// instruction selection
// register allocation
-// assemble from ir
// inline
// intrinsics
// common subexpression