From 862b4e96881a866826fb7a5edaacf30ee444310f Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 13 Apr 2025 07:47:52 -0500 Subject: [PATCH] Add sysir test suite stub --- examples/sysir/hello.janet | 16 ++++++++++++++ meson.build | 1 + src/core/sysir_x86.c | 45 ++++++++++++++++++++------------------ test/suite-sysir.janet | 27 +++++++++++++++++++++++ 4 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 examples/sysir/hello.janet create mode 100644 test/suite-sysir.janet diff --git a/examples/sysir/hello.janet b/examples/sysir/hello.janet new file mode 100644 index 00000000..4d3f1b05 --- /dev/null +++ b/examples/sysir/hello.janet @@ -0,0 +1,16 @@ +(use ./frontend) + +(defn-external printf:int [fmt:pointer]) +(defn-external exit:void [x:int]) + +(defsys _start:void [] + (printf "hello, world!\n") + (exit (the int 0)) + (return)) + +(defn main [& args] + (def [_ what] args) + (eprint "MODE: " what) + (case what + "c" (dumpc) + "x64" (dumpx64))) diff --git a/meson.build b/meson.build index afd84e7a..6b7aa962 100644 --- a/meson.build +++ b/meson.build @@ -296,6 +296,7 @@ test_files = [ 'test/suite-strtod.janet', 'test/suite-struct.janet', 'test/suite-symcache.janet', + 'test/suite-sysir.janet', 'test/suite-table.janet', 'test/suite-tuple.janet', 'test/suite-unknown.janet', diff --git a/src/core/sysir_x86.c b/src/core/sysir_x86.c index 683ab59d..d98facee 100644 --- a/src/core/sysir_x86.c +++ b/src/core/sysir_x86.c @@ -167,6 +167,25 @@ static x64RegKind get_slot_regkind(JanetSysx64Context *ctx, uint32_t o) { } } +static const char *sysemit_sizestr(x64RegKind kind) { + switch (kind) { + case JANET_SYSREG_8: + return "byte"; + case JANET_SYSREG_16: + return "word"; + case JANET_SYSREG_32: + return "dword"; + case JANET_SYSREG_64: + return "qword"; + default: + return "qword"; + } +} + +static const char *sysemit_sizestr_reg(x64Reg reg) { + return sysemit_sizestr(reg.kind); +} + /* Convert a slot index to a register. Handles constants as well. */ x64Reg to_reg(JanetSysx64Context *ctx, uint32_t slot) { if (slot > JANET_SYS_MAX_OPERAND) { @@ -351,6 +370,7 @@ static void e_mov_to_reg(JanetSysx64Context *ctx, x64Reg d, x64Reg s, MoveMode m uint16_t opcode = 0; int flip = 0; InstrChunk dispchunk = empty_chunk; + const char *sizestr = sysemit_sizestr_reg(d); if (s.storage != JANET_SYSREG_REGISTER && d.storage != JANET_SYSREG_REGISTER) { /* src -> RAX -> dest : flat */ /* src -> RAX -> dest[0] : store */ @@ -399,6 +419,7 @@ static void e_mov_to_reg(JanetSysx64Context *ctx, x64Reg d, x64Reg s, MoveMode m if (!rex) prefix.bytes = 0; InstrChunk modregrm = {1, mod_rm}; i_combine(ctx, prefix, opcode, modregrm, empty_chunk, dispchunk, empty_chunk, msg); + janet_formatb(ctx->buffer, ";mov %s <- %s, mode=%d, %s\n", register_names[d.index], register_names[s.index], mm, sizestr); } static void e_mov(JanetSysx64Context *ctx, uint32_t dest, uint32_t src, const char *msg) { @@ -514,25 +535,6 @@ static x64Reg mk_tmpreg(JanetSysx64Context *ctx, uint32_t src) { return tempreg; } -static const char *sysemit_sizestr(x64RegKind kind) { - switch (kind) { - case JANET_SYSREG_8: - return "byte"; - case JANET_SYSREG_16: - return "word"; - case JANET_SYSREG_32: - return "dword"; - case JANET_SYSREG_64: - return "qword"; - default: - return "qword"; - } -} - -static const char *sysemit_sizestr_reg(x64Reg reg) { - return sysemit_sizestr(reg.kind); -} - static void sysemit_reg(JanetSysx64Context *ctx, x64Reg reg, const char *after) { const char *sizestr = sysemit_sizestr_reg(reg); if (reg.storage == JANET_SYSREG_STACK) { @@ -678,7 +680,7 @@ static void sysemit_movfromreg(JanetSysx64Context *ctx, uint32_t dest, uint32_t e_mov_to_reg(ctx, ctx->regs[dest], tempreg, MOV_FLAT, "move from specific register"); } -/* Move a value to a register, and save the contents of the old register on fhe stack */ +/* Move a value to a register, and save the contents of the old register on the stack */ static void sysemit_mov_save(JanetSysx64Context *ctx, uint32_t dest_reg, uint32_t src) { e_pushreg(ctx, dest_reg); sysemit_movreg(ctx, dest_reg, src); @@ -795,6 +797,7 @@ static void sysemit_cast(JanetSysx64Context *ctx, JanetSysInstruction instructio static void sysemit_sysv_call(JanetSysx64Context *ctx, JanetSysInstruction instruction, uint32_t *args, uint32_t argcount) { /* Push first 6 arguments to particular registers */ + janet_formatb(ctx->buffer, ";sysv call %u\n", argcount); JanetBuffer *buffer = ctx->buffer; int save_rdi = argcount >= 1 || (ctx->occupied_registers & (1 << RDI)); int save_rsi = argcount >= 2 || (ctx->occupied_registers & (1 << RSI)); @@ -828,7 +831,7 @@ static void sysemit_sysv_call(JanetSysx64Context *ctx, JanetSysInstruction instr janet_formatb(buffer, "syscall\n"); } else { /* Save RAX to number of floating point args for varags - for now, always 0 :) */ - janet_formatb(buffer, "mov rax, 0\n"); + janet_formatb(buffer, "db 0x48, 0x31, 0xc0 ; xor rax, rax\n"); janet_formatb(buffer, "call "); sysemit_operand(ctx, instruction.call.callee, "\n"); } diff --git a/test/suite-sysir.janet b/test/suite-sysir.janet new file mode 100644 index 00000000..1cb2bd77 --- /dev/null +++ b/test/suite-sysir.janet @@ -0,0 +1,27 @@ +# Copyright (c) 2025 Calvin Rose +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +(import ./helper :prefix "" :exit true) +(start-suite) + +(use ../examples/sysir/frontend) +(assert true) # smoke test + +(end-suite)