mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-30 23:23:07 +00:00 
			
		
		
		
	Start removing NASM dependence.
Start setting up a test suite for sysir and work towards emitting jitted x86 machine code.
This commit is contained in:
		| @@ -1,55 +0,0 @@ | |||||||
| ### typedef struct {float x; float y; float z;} Vec3; |  | ||||||
| ### |  | ||||||
| ### Vec3 addv(Vec3 a, Vec3 b) { |  | ||||||
| ###     Vec3 ret; |  | ||||||
| ###     ret.x = a.x + b.x; |  | ||||||
| ###     ret.y = a.y + b.y; |  | ||||||
| ###     ret.z = a.z + b.z; |  | ||||||
| ###     return ret; |  | ||||||
| ### } |  | ||||||
|  |  | ||||||
| (def ir-asm |  | ||||||
|   '((link-name "addv_with_err") |  | ||||||
|     (parameter-count 2) |  | ||||||
|     # Types |  | ||||||
|     (type-prim Real f32) |  | ||||||
|     (type-struct Vec3 Real Real Real) |  | ||||||
|     (type-pointer PReal Real) |  | ||||||
|  |  | ||||||
|     # Declarations |  | ||||||
|     (bind position Vec3) |  | ||||||
|     (bind velocity Vec3) |  | ||||||
|     (bind next-position Vec3) |  | ||||||
|     (bind dest Real) |  | ||||||
|     (bind lhs Real) |  | ||||||
|     (bind rhs Real) |  | ||||||
|     (bind pdest PReal) |  | ||||||
|     (bind plhs PReal) |  | ||||||
|     (bind prhs PReal) |  | ||||||
|  |  | ||||||
|     # Code (has type errors) |  | ||||||
|     (fgetp pdest next-position 0) |  | ||||||
|     (fgetp plhs position 0) |  | ||||||
|     (fgetp prhs velocity 0) |  | ||||||
|     (add dest plhs prhs) |  | ||||||
|     (store pdest dest) |  | ||||||
|  |  | ||||||
|     (fgetp pdest next-position 1) |  | ||||||
|     (fgetp plhs position 1) |  | ||||||
|     (fgetp prhs velocity 1) |  | ||||||
|     (add dest lhs rhs) |  | ||||||
|     (load lhs plhs) |  | ||||||
|     (load rhs prhs) |  | ||||||
|     (store pdest dest) |  | ||||||
|  |  | ||||||
|     (fgetp pdest next-position 2) |  | ||||||
|     (fgetp plhs position 2) |  | ||||||
|     (fgetp prhs velocity 2) |  | ||||||
|     (add dest plhs prhs) |  | ||||||
|     (store pdest dest) |  | ||||||
|  |  | ||||||
|     (return next-position))) |  | ||||||
|  |  | ||||||
| (def ctx (sysir/context)) |  | ||||||
| (sysir/asm ctx ir-asm) |  | ||||||
| (print (sysir/to-c ctx)) |  | ||||||
| @@ -52,31 +52,6 @@ | |||||||
| #define REX_X 0x42 | #define REX_X 0x42 | ||||||
| #define REX_B 0x41 | #define REX_B 0x41 | ||||||
|  |  | ||||||
| static const char *register_names[] = { |  | ||||||
|     "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", |  | ||||||
|     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const char *register_names_32[] = { |  | ||||||
|     "eax", "ecx", "edx", "ebx", "rsp", "rbp", "esi", "edi", |  | ||||||
|     "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const char *register_names_16[] = { |  | ||||||
|     "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", |  | ||||||
|     "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const char *register_names_8[] = { |  | ||||||
|     "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", |  | ||||||
|     "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const char *register_names_xmm[] = { |  | ||||||
|     "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", |  | ||||||
|     "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
|     JANET_SYSREG_8, |     JANET_SYSREG_8, | ||||||
|     JANET_SYSREG_16, |     JANET_SYSREG_16, | ||||||
| @@ -103,6 +78,9 @@ typedef struct { | |||||||
|     JanetSysIRLinkage *linkage; |     JanetSysIRLinkage *linkage; | ||||||
|     JanetSysIR *ir; |     JanetSysIR *ir; | ||||||
|     JanetBuffer *buffer; |     JanetBuffer *buffer; | ||||||
|  |     JanetBuffer *constant_data; /* A buffer of constants for RIP-relative addressing to point to */ | ||||||
|  |     uint32_t *v_rip_indicies; /* An array of pointers of all emitted addresses to patch at end. */ | ||||||
|  |     JanetTable *constant_to_data; /* Table mapping constants to index into v_constant_data (dedupe constants) */ | ||||||
|     x64Reg *regs; /* Map IR virtual registers to hardware register or stack offset */ |     x64Reg *regs; /* Map IR virtual registers to hardware register or stack offset */ | ||||||
|     JanetSysTypeLayout *layouts; |     JanetSysTypeLayout *layouts; | ||||||
|     JanetSysTypeLayout *ir_layouts; |     JanetSysTypeLayout *ir_layouts; | ||||||
| @@ -317,6 +295,30 @@ static int operand_isreg(JanetSysx64Context *ctx, uint32_t o, uint32_t regindex) | |||||||
|     return reg.index == regindex; |     return reg.index == regindex; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Visit a constant and return the index into the constant data buffer. */ | ||||||
|  | static uint32_t janet_x64_constant(JanetSysx64Context *ctx, uint32_t const_index) { | ||||||
|  |     Janet key = janet_wrap_number((double) const_index); | ||||||
|  |     Janet check = janet_table_get(ctx->constant_to_data, key); | ||||||
|  |     if (janet_checktype(check, JANET_NUMBER)) { | ||||||
|  |         /* Constant has been seen before */ | ||||||
|  |         return (uint32_t) janet_unwrap_integer(check); | ||||||
|  |     } | ||||||
|  |     JanetSysConstant jsc = ctx->ir->constants[const_index]; | ||||||
|  |     JanetSysTypeInfo tinfo = ctx->linkage->type_defs[jsc.type]; | ||||||
|  |     /* TODO - check type and alignment for data types beyond pointers such as large struct and other immediates */ | ||||||
|  |     uint32_t index = ctx->constant_data->count; | ||||||
|  |     switch (janet_type(jsc.value)) { | ||||||
|  |         default: | ||||||
|  |             janet_assert(0, "cannot emit constant"); | ||||||
|  |             break; | ||||||
|  |         case JANET_STRING: | ||||||
|  |             janet_assert(tinfo.prim == JANET_PRIM_POINTER, "expected pointer type for string constant"); | ||||||
|  |             janet_buffer_push_string(ctx->constant_data, janet_unwrap_string(jsc.value)); | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  |     return index; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Machine code emission |  * Machine code emission | ||||||
|  */ |  */ | ||||||
| @@ -330,7 +332,7 @@ static const InstrChunk empty_chunk = { 0, 0 }; | |||||||
|  |  | ||||||
| static void i_chunk(JanetSysx64Context *C, InstrChunk c) { | static void i_chunk(JanetSysx64Context *C, InstrChunk c) { | ||||||
|     for (int i = 0; i < c.bytes; i++) { |     for (int i = 0; i < c.bytes; i++) { | ||||||
|         janet_formatb(C->buffer, "0x%.2X,", c.data & 0xFF); |         janet_buffer_push_u8(C->buffer, c.data & 0xFF); | ||||||
|         c.data = c.data >> 8; |         c.data = c.data >> 8; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -347,22 +349,17 @@ static void i_combine(JanetSysx64Context *C, | |||||||
|     assert(mod_reg_rm.bytes < 3); |     assert(mod_reg_rm.bytes < 3); | ||||||
|     assert(scaled_index.bytes < 2); |     assert(scaled_index.bytes < 2); | ||||||
|     assert(opcode < 512); |     assert(opcode < 512); | ||||||
|     janet_buffer_push_cstring(C->buffer, "db "); |  | ||||||
|     i_chunk(C, prefix); |     i_chunk(C, prefix); | ||||||
|     if (opcode >= 256) { |     if (opcode >= 256) { | ||||||
|         janet_formatb(C->buffer, "0x%.2X,", 0x0Fu); |         janet_buffer_push_u8(C->buffer, 0x0Fu); | ||||||
|         opcode -= 256; |         opcode -= 256; | ||||||
|     } |     } | ||||||
|     janet_formatb(C->buffer, "0x%.2X,", opcode); |     janet_buffer_push_u8(C->buffer, opcode); | ||||||
|     i_chunk(C, mod_reg_rm); |     i_chunk(C, mod_reg_rm); | ||||||
|     i_chunk(C, scaled_index); |     i_chunk(C, scaled_index); | ||||||
|     i_chunk(C, displacement); |     i_chunk(C, displacement); | ||||||
|     i_chunk(C, immediate); |     i_chunk(C, immediate); | ||||||
|     if (msg) { |     (void) msg; | ||||||
|         janet_formatb(C->buffer, "; %s\n", msg); |  | ||||||
|     } else { |  | ||||||
|         janet_buffer_push_cstring(C->buffer, "\n"); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| typedef enum { | typedef enum { | ||||||
| @@ -380,16 +377,19 @@ static void e_mov_ext(JanetSysx64Context *ctx, x64Reg d, x64Reg s, MoveMode mm, | |||||||
|  |  | ||||||
|     /* src is a constant */ |     /* src is a constant */ | ||||||
|     if (s.storage == JANET_SYSREG_CONSTANT) { |     if (s.storage == JANET_SYSREG_CONSTANT) { | ||||||
|  |         //uint32_t disp = janet_x64_constant(ctx, s.index); | ||||||
|         if (d.index >= 8) rex |= REX_R; |         if (d.index >= 8) rex |= REX_R; | ||||||
|         if (d.kind >= JANET_SYSREG_64) rex |= REX_W; |         if (d.kind >= JANET_SYSREG_64) rex |= REX_W; | ||||||
|         Janet c = ctx->ir->constants[s.index].value; |         Janet c = ctx->ir->constants[s.index].value; | ||||||
|         int32_t imm = 0; |         int32_t imm = 0; | ||||||
|         uint64_t imm64 = 0; |         uint64_t imm64 = 0; | ||||||
|         int is64 = 0; |         int is64 = 0; | ||||||
|  |         //int isRipRel = 0; | ||||||
|         InstrChunk dispchunk = empty_chunk; |         InstrChunk dispchunk = empty_chunk; | ||||||
|         if (janet_checktype(c, JANET_STRING)) { |         if (janet_checktype(c, JANET_STRING)) { | ||||||
|             is64 = 1; |             is64 = 1; | ||||||
|             imm64 = (uint64_t) janet_unwrap_pointer(c); |             imm64 = (uint64_t) janet_unwrap_pointer(c);// janet_x64_constant(ctx, s.index); | ||||||
|  |             //isRipRel = 1; | ||||||
|         } else if (s.kind >= JANET_SYSREG_64) { |         } else if (s.kind >= JANET_SYSREG_64) { | ||||||
|             is64 = 1; |             is64 = 1; | ||||||
|             imm64 = janet_unwrap_u64(c); |             imm64 = janet_unwrap_u64(c); | ||||||
| @@ -407,7 +407,7 @@ static void e_mov_ext(JanetSysx64Context *ctx, x64Reg d, x64Reg s, MoveMode mm, | |||||||
|             } |             } | ||||||
|             /* encode movabsq */ |             /* encode movabsq */ | ||||||
|             rex |= REX_W; |             rex |= REX_W; | ||||||
|             imm64 = 0xDEADBEEFCAFEBABEULL; |             // imm64 = 0xDEADBEEFCAFEBABEULL; | ||||||
|             opcode = 0xB8; |             opcode = 0xB8; | ||||||
|             opcode += (d.index & 7); |             opcode += (d.index & 7); | ||||||
|             if (d.index >= 8) rex |= REX_R; |             if (d.index >= 8) rex |= REX_R; | ||||||
| @@ -496,7 +496,6 @@ static void e_mov_ext(JanetSysx64Context *ctx, x64Reg d, x64Reg s, MoveMode mm, | |||||||
|     if (!rex) prefix.bytes = 0; |     if (!rex) prefix.bytes = 0; | ||||||
|     InstrChunk modregrm = {1, mod_rm}; |     InstrChunk modregrm = {1, mod_rm}; | ||||||
|     i_combine(ctx, prefix, opcode, modregrm, empty_chunk, dispchunk, empty_chunk, msg); |     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) { | static void e_mov(JanetSysx64Context *ctx, uint32_t dest, uint32_t src, const char *msg) { | ||||||
| @@ -516,9 +515,11 @@ static void e_fn_prefix(JanetSysx64Context *ctx, int32_t stack) { | |||||||
|         int b = (stack >> 8) & 0xFF; |         int b = (stack >> 8) & 0xFF; | ||||||
|         int c = (stack >> 16) & 0xFF; |         int c = (stack >> 16) & 0xFF; | ||||||
|         int d = (stack >> 24) & 0xFF; |         int d = (stack >> 24) & 0xFF; | ||||||
|         janet_formatb(ctx->buffer, "db 0x55, 0x48, 0x89, 0xe5, 0x48, 0x81, 0xec, 0x%.2X, 0x%.2X, 0x%2X, 0x%2X ; function prefix\n", a, b, c, d); |         uint8_t bytes[] = {0x55, 0x48, 0x89, 0xe5, 0x48, 0x81, 0xec, a, b, c, d}; | ||||||
|  |         janet_buffer_push_bytes(ctx->buffer, bytes, sizeof(bytes)); | ||||||
|     } else { |     } else { | ||||||
|         janet_formatb(ctx->buffer, "db 0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x%.2X ; function prefix\n", stack); |         uint8_t bytes[] = {0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, stack}; | ||||||
|  |         janet_buffer_push_bytes(ctx->buffer, bytes, sizeof(bytes)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -526,9 +527,11 @@ static void e_pushreg(JanetSysx64Context *ctx, uint32_t reg) { | |||||||
|     assert(reg < 16); |     assert(reg < 16); | ||||||
|     if (reg >= 8) { |     if (reg >= 8) { | ||||||
|         /* Use REX prefix */ |         /* Use REX prefix */ | ||||||
|         janet_formatb(ctx->buffer, "db 0x41, 0x%.2X ; push %s\n", 0x50 + (reg - 8), register_names[reg]); |         uint8_t bytes[] = {0x41, 0x50 + (reg - 8)}; | ||||||
|  |         janet_buffer_push_bytes(ctx->buffer, bytes, sizeof(bytes)); | ||||||
|     } else { |     } else { | ||||||
|         janet_formatb(ctx->buffer, "db 0x%.2X ; push %s\n", 0x50 + reg, register_names[reg]); |         uint8_t bytes[] = {0x50 + reg}; | ||||||
|  |         janet_buffer_push_bytes(ctx->buffer, bytes, sizeof(bytes)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -536,15 +539,18 @@ static void e_popreg(JanetSysx64Context *ctx, uint32_t reg) { | |||||||
|     assert(reg < 16); |     assert(reg < 16); | ||||||
|     if (reg >= 8) { |     if (reg >= 8) { | ||||||
|         /* Use REX prefix */ |         /* Use REX prefix */ | ||||||
|         janet_formatb(ctx->buffer, "db 0x41, 0x%.2X ; pop %s\n", 0x58 + (reg - 8), register_names[reg]); |         uint8_t bytes[] = {0x41, 0x58 + (reg - 8)}; | ||||||
|  |         janet_buffer_push_bytes(ctx->buffer, bytes, sizeof(bytes)); | ||||||
|     } else { |     } else { | ||||||
|         janet_formatb(ctx->buffer, "db 0x%.2X ; pop %s\n", 0x58 + reg, register_names[reg]); |         uint8_t bytes[] = {0x58 + reg}; | ||||||
|  |         janet_buffer_push_bytes(ctx->buffer, bytes, sizeof(bytes)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void e_fn_suffix(JanetSysx64Context *ctx) { | static void e_fn_suffix(JanetSysx64Context *ctx) { | ||||||
|     /* leave, ret */ |     /* leave, ret */ | ||||||
|     janet_formatb(ctx->buffer, "db 0xc9, 0xc3 ; function suffix\n"); |     uint8_t bytes[] = {0xc9, 0xc3}; | ||||||
|  |     janet_buffer_push_bytes(ctx->buffer, bytes, sizeof(bytes)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Assembly emission */ | /* Assembly emission */ | ||||||
| @@ -557,47 +563,18 @@ static x64Reg mk_tmpreg(JanetSysx64Context *ctx, uint32_t src) { | |||||||
|     return tempreg; |     return tempreg; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void sysemit_reg(JanetSysx64Context *ctx, x64Reg reg, const char *after) { | static void sysemit_movreg(JanetSysx64Context *ctx, uint32_t regdest, uint32_t src) { | ||||||
|     const char *sizestr = sysemit_sizestr_reg(reg); |     if (operand_isreg(ctx, src, regdest)) return; | ||||||
|     if (reg.storage == JANET_SYSREG_STACK) { |     x64Reg tempreg = mk_tmpreg(ctx, src); | ||||||
|         // TODO - use LEA for parameters larger than a qword |     tempreg.index = regdest; | ||||||
|         janet_formatb(ctx->buffer, "%s [rbp-%u]", sizestr, reg.index); |     e_mov_ext(ctx, tempreg, to_reg(ctx, src), MOV_FLAT, "sysemit_movreg"); | ||||||
|     } else if (reg.storage == JANET_SYSREG_STACK_PARAMETER) { |  | ||||||
|         // TODO - use LEA for parameters larger than a qword |  | ||||||
|         janet_formatb(ctx->buffer, "%s [rbp+%u]", sizestr, reg.index); |  | ||||||
|     } else if (reg.kind == JANET_SYSREG_64) { |  | ||||||
|         janet_formatb(ctx->buffer, "%s", register_names[reg.index]); |  | ||||||
|     } else if (reg.kind == JANET_SYSREG_32) { |  | ||||||
|         janet_formatb(ctx->buffer, "%s", register_names_32[reg.index]); |  | ||||||
|     } else if (reg.kind == JANET_SYSREG_16) { |  | ||||||
|         janet_formatb(ctx->buffer, "%s", register_names_16[reg.index]); |  | ||||||
|     } else if (reg.kind == JANET_SYSREG_8) { |  | ||||||
|         janet_formatb(ctx->buffer, "%s", register_names_8[reg.index]); |  | ||||||
|     } else { |  | ||||||
|         janet_formatb(ctx->buffer, "%s", register_names_xmm[reg.index]); |  | ||||||
|     } |  | ||||||
|     if (after) janet_buffer_push_cstring(ctx->buffer, after); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void sysemit_operand(JanetSysx64Context *ctx, uint32_t o, const char *after) { | static void sysemit_movfromreg(JanetSysx64Context *ctx, uint32_t dest, uint32_t srcreg) { | ||||||
|     if (o <= JANET_SYS_MAX_OPERAND) { |     if (operand_isreg(ctx, dest, srcreg)) return; | ||||||
|         sysemit_reg(ctx, ctx->regs[o], NULL); |     x64Reg tempreg = mk_tmpreg(ctx, dest); | ||||||
|     } else { |     tempreg.index = srcreg; | ||||||
|         /* Constant */ |     e_mov_ext(ctx, ctx->regs[dest], tempreg, MOV_FLAT, "move from specific register"); | ||||||
|         uint32_t index = o - JANET_SYS_CONSTANT_PREFIX; |  | ||||||
|         Janet c = ctx->ir->constants[index].value; |  | ||||||
|         // TODO - do this properly |  | ||||||
|         if (janet_checktype(c, JANET_STRING)) { |  | ||||||
|             janet_formatb(ctx->buffer, "CONST_%d_%u", ctx->ir_index, index); |  | ||||||
|         } else { |  | ||||||
|             // TODO - do this properly too. |  | ||||||
|             // Also figure out how to load large constants to a temporary register |  | ||||||
|             // In x64, only move to register is allowed to take a 64 bit immediate, so |  | ||||||
|             // our methodology here changes based on what kind of operand we need. |  | ||||||
|             janet_formatb(ctx->buffer, "%V", c); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     if (after) janet_buffer_push_cstring(ctx->buffer, after); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* A = A op B */ | /* A = A op B */ | ||||||
| @@ -607,14 +584,16 @@ static void sysemit_binop(JanetSysx64Context *ctx, const char *op, uint32_t dest | |||||||
|         x64Reg tempreg = mk_tmpreg(ctx, dest); |         x64Reg tempreg = mk_tmpreg(ctx, dest); | ||||||
|         x64Reg srcreg = ctx->regs[src]; |         x64Reg srcreg = ctx->regs[src]; | ||||||
|         e_mov_ext(ctx, tempreg, srcreg, MOV_FLAT, "mem -> RAX temp"); |         e_mov_ext(ctx, tempreg, srcreg, MOV_FLAT, "mem -> RAX temp"); | ||||||
|         janet_formatb(ctx->buffer, "%s ", op); |  | ||||||
|         sysemit_operand(ctx, dest, ", "); |  | ||||||
|         sysemit_reg(ctx, tempreg, "\n"); |  | ||||||
|     } else { |  | ||||||
|         janet_formatb(ctx->buffer, "%s ", op); |  | ||||||
|         sysemit_operand(ctx, dest, ", "); |  | ||||||
|         sysemit_operand(ctx, src, "\n"); |  | ||||||
|     }  |     }  | ||||||
|  |     janet_formatb(ctx->buffer, "%s ", op); | ||||||
|  |     //sysemit_operand(ctx, dest, ", "); | ||||||
|  |     //sysemit_operand(ctx, src, "\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Dest = LHS op RHS */ | ||||||
|  | static void sysemit_threeop(JanetSysx64Context *ctx, const char *op, uint32_t dest, uint32_t lhs, uint32_t rhs) { | ||||||
|  |     e_mov(ctx, dest, lhs, op); | ||||||
|  |     sysemit_binop(ctx, op, dest, rhs); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* dest = src[0] */ | /* dest = src[0] */ | ||||||
| @@ -684,52 +663,15 @@ static void sysemit_store(JanetSysx64Context *ctx, uint32_t dest, uint32_t src) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void sysemit_movreg(JanetSysx64Context *ctx, uint32_t regdest, uint32_t src) { |  | ||||||
|     if (operand_isreg(ctx, src, regdest)) return; |  | ||||||
|     x64Reg tempreg = mk_tmpreg(ctx, src); |  | ||||||
|     tempreg.index = regdest; |  | ||||||
|     e_mov_ext(ctx, tempreg, to_reg(ctx, src), MOV_FLAT, "sysemit_movreg"); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void sysemit_movfromreg(JanetSysx64Context *ctx, uint32_t dest, uint32_t srcreg) { |  | ||||||
|     if (operand_isreg(ctx, dest, srcreg)) return; |  | ||||||
|     x64Reg tempreg = mk_tmpreg(ctx, dest); |  | ||||||
|     tempreg.index = srcreg; |  | ||||||
|     e_mov_ext(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 the 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 regdest, uint32_t src) { | static void sysemit_mov_save(JanetSysx64Context *ctx, uint32_t regdest, uint32_t src) { | ||||||
|     e_pushreg(ctx, regdest); |     e_pushreg(ctx, regdest); | ||||||
|     if (operand_isreg(ctx, src, regdest)) return; |     if (operand_isreg(ctx, src, regdest)) return; | ||||||
|     x64Reg tempreg = mk_tmpreg(ctx, src); |     x64Reg tempreg = mk_tmpreg(ctx, src); | ||||||
|     tempreg.index = regdest; |     tempreg.index = regdest; | ||||||
|     janet_formatb(ctx->buffer, "; mov save %s <- %u\n", register_names[regdest], src); |  | ||||||
|     e_mov_ext(ctx, tempreg, to_reg(ctx, src), MOV_FLAT, "mov save"); |     e_mov_ext(ctx, tempreg, to_reg(ctx, src), MOV_FLAT, "mov save"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void sysemit_threeop(JanetSysx64Context *ctx, const char *op, uint32_t dest, uint32_t lhs, uint32_t rhs) { |  | ||||||
|     e_mov(ctx, dest, lhs, op); |  | ||||||
|     sysemit_binop(ctx, op, dest, rhs); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void sysemit_threeop_nodeststack(JanetSysx64Context *ctx, const char *op, uint32_t dest, uint32_t lhs, |  | ||||||
|                                         uint32_t rhs) { |  | ||||||
|     if (operand_isstack(ctx, dest)) { |  | ||||||
|         sysemit_movreg(ctx, RAX, lhs); |  | ||||||
|         x64Reg tempreg; |  | ||||||
|         tempreg.kind = get_slot_regkind(ctx, dest); |  | ||||||
|         tempreg.storage = JANET_SYSREG_REGISTER; |  | ||||||
|         tempreg.index = RAX; |  | ||||||
|         janet_formatb(ctx->buffer, "%s ", op); |  | ||||||
|         sysemit_reg(ctx, tempreg, ", "); |  | ||||||
|         sysemit_operand(ctx, lhs, "\n"); |  | ||||||
|         sysemit_movfromreg(ctx, dest, RAX); |  | ||||||
|     } else { |  | ||||||
|         sysemit_threeop(ctx, op, dest, lhs, rhs); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void sysemit_three_inst(JanetSysx64Context *ctx, const char *op, JanetSysInstruction instruction) { | static void sysemit_three_inst(JanetSysx64Context *ctx, const char *op, JanetSysInstruction instruction) { | ||||||
|     sysemit_threeop(ctx, op, instruction.three.dest, instruction.three.lhs, instruction.three.rhs); |     sysemit_threeop(ctx, op, instruction.three.dest, instruction.three.lhs, instruction.three.rhs); | ||||||
| } | } | ||||||
| @@ -778,7 +720,7 @@ static int sysemit_comp(JanetSysx64Context *ctx, uint32_t index, | |||||||
|             /* Zero the upper bits */ |             /* Zero the upper bits */ | ||||||
|             sysemit_binop(ctx, "xor", instruction.three.dest, instruction.three.dest); |             sysemit_binop(ctx, "xor", instruction.three.dest, instruction.three.dest); | ||||||
|         } |         } | ||||||
|         janet_formatb(ctx->buffer, "%s %s\n", set, register_names_8[instruction.three.dest]); |         //janet_formatb(ctx->buffer, "%s %s\n", set, register_names_8[instruction.three.dest]); | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -846,7 +788,7 @@ static void sysemit_sysv_call(JanetSysx64Context *ctx, JanetSysInstruction instr | |||||||
|     for (int32_t argo = argcount - 1; argo >= 6; argo--) { |     for (int32_t argo = argcount - 1; argo >= 6; argo--) { | ||||||
|         janet_panic("nyi push sysv args"); |         janet_panic("nyi push sysv args"); | ||||||
|         janet_formatb(buffer, "push "); |         janet_formatb(buffer, "push "); | ||||||
|         sysemit_operand(ctx, args[argo], "\n"); |         //sysemit_operand(ctx, args[argo], "\n"); | ||||||
|     } |     } | ||||||
|     if (instruction.opcode == JANET_SYSOP_SYSCALL) { |     if (instruction.opcode == JANET_SYSOP_SYSCALL) { | ||||||
|         sysemit_movreg(ctx, RAX, instruction.call.callee); |         sysemit_movreg(ctx, RAX, instruction.call.callee); | ||||||
| @@ -855,7 +797,7 @@ static void sysemit_sysv_call(JanetSysx64Context *ctx, JanetSysInstruction instr | |||||||
|         /* Save RAX to number of floating point args for varags - for now, always 0 :) */ |         /* Save RAX to number of floating point args for varags - for now, always 0 :) */ | ||||||
|         janet_formatb(buffer, "db 0x48, 0x31, 0xc0 ; xor rax, rax\n"); |         janet_formatb(buffer, "db 0x48, 0x31, 0xc0 ; xor rax, rax\n"); | ||||||
|         janet_formatb(buffer, "call "); |         janet_formatb(buffer, "call "); | ||||||
|         sysemit_operand(ctx, instruction.call.callee, "\n"); |         //sysemit_operand(ctx, instruction.call.callee, "\n"); | ||||||
|     } |     } | ||||||
|     if (save_r11) e_popreg(ctx, 11); |     if (save_r11) e_popreg(ctx, 11); | ||||||
|     if (save_r10) e_popreg(ctx, 10); |     if (save_r10) e_popreg(ctx, 10); | ||||||
| @@ -895,7 +837,7 @@ static void sysemit_win64_call(JanetSysx64Context *ctx, JanetSysInstruction inst | |||||||
|         janet_formatb(buffer, "syscall\n"); |         janet_formatb(buffer, "syscall\n"); | ||||||
|     } else { |     } else { | ||||||
|         janet_formatb(buffer, "call "); |         janet_formatb(buffer, "call "); | ||||||
|         sysemit_operand(ctx, instruction.call.callee, "\n"); |         //sysemit_operand(ctx, instruction.call.callee, "\n"); | ||||||
|     } |     } | ||||||
|     if (argcount > 4) { |     if (argcount > 4) { | ||||||
|         janet_formatb(buffer, "add rsp, %u\n", 8 * (argcount - 4)); |         janet_formatb(buffer, "add rsp, %u\n", 8 * (argcount - 4)); | ||||||
| @@ -909,12 +851,42 @@ static void sysemit_win64_call(JanetSysx64Context *ctx, JanetSysInstruction inst | |||||||
|     if (instruction.call.flags & JANET_SYS_CALLFLAG_HAS_DEST) sysemit_movfromreg(ctx, instruction.call.dest, RAX); |     if (instruction.call.flags & JANET_SYS_CALLFLAG_HAS_DEST) sysemit_movfromreg(ctx, instruction.call.dest, RAX); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void emit_nasm_string(JanetBuffer *buffer, const uint8_t *str, int32_t len) { | ||||||
|  |     /* Nasm syntax */ | ||||||
|  |     int in_string = 0; | ||||||
|  |     for (int32_t ci = 0; ci < len; ci++) { | ||||||
|  |         int c = str[ci]; | ||||||
|  |         if (c < 32) { | ||||||
|  |             if (in_string) { | ||||||
|  |                 janet_formatb(buffer, "\", %d", c); | ||||||
|  |             } else { | ||||||
|  |                 janet_formatb(buffer, ci ? ", %d" : "%d", c); | ||||||
|  |             } | ||||||
|  |             in_string = 0; | ||||||
|  |         } else { | ||||||
|  |             if (!in_string) { | ||||||
|  |                 janet_buffer_push_cstring(buffer, ci ? ", \"" : "\""); | ||||||
|  |             } | ||||||
|  |             janet_buffer_push_u8(buffer, c); | ||||||
|  |             in_string = 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     if (!in_string) { | ||||||
|  |         janet_buffer_push_cstring(buffer, ", 0\n"); | ||||||
|  |     } else { | ||||||
|  |         janet_buffer_push_cstring(buffer, "\", 0\n"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetSysTarget target, JanetBuffer *buffer) { | void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetSysTarget target, JanetBuffer *buffer) { | ||||||
|  |  | ||||||
|     /* Partially setup context */ |     /* Partially setup context */ | ||||||
|     JanetSysx64Context ctx; |     JanetSysx64Context ctx; | ||||||
|     ctx.linkage = linkage; |     ctx.linkage = linkage; | ||||||
|     ctx.buffer = buffer; |     ctx.buffer = buffer; | ||||||
|  |     ctx.constant_data = janet_buffer(0); | ||||||
|  |     ctx.v_rip_indicies = NULL; | ||||||
|  |     ctx.constant_to_data = janet_table(0); | ||||||
|     ctx.layouts = janet_smalloc(linkage->type_def_count * sizeof(JanetSysTypeLayout)); |     ctx.layouts = janet_smalloc(linkage->type_def_count * sizeof(JanetSysTypeLayout)); | ||||||
|     for (uint32_t i = 0; i < linkage->type_def_count; i++) { |     for (uint32_t i = 0; i < linkage->type_def_count; i++) { | ||||||
|         ctx.layouts[i] = get_x64layout(linkage->type_defs[i]); |         ctx.layouts[i] = get_x64layout(linkage->type_defs[i]); | ||||||
| @@ -1018,7 +990,7 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetSysTarget target | |||||||
|                     sysemit_three_inst(&ctx, "sub", instruction); |                     sysemit_three_inst(&ctx, "sub", instruction); | ||||||
|                     break; |                     break; | ||||||
|                 case JANET_SYSOP_MULTIPLY: |                 case JANET_SYSOP_MULTIPLY: | ||||||
|                     sysemit_threeop_nodeststack(&ctx, "imul", instruction.three.dest, |                     sysemit_threeop(&ctx, "imul", instruction.three.dest, | ||||||
|                                                 instruction.three.lhs, instruction.three.rhs); |                                                 instruction.three.lhs, instruction.three.rhs); | ||||||
|                     break; |                     break; | ||||||
|                 case JANET_SYSOP_DIVIDE: |                 case JANET_SYSOP_DIVIDE: | ||||||
| @@ -1073,7 +1045,7 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetSysTarget target | |||||||
|                 case JANET_SYSOP_BRANCH_NOT: |                 case JANET_SYSOP_BRANCH_NOT: | ||||||
|                     janet_formatb(buffer, "test "); |                     janet_formatb(buffer, "test "); | ||||||
|                     // TODO - ensure branch condition is not a const |                     // TODO - ensure branch condition is not a const | ||||||
|                     sysemit_operand(&ctx, instruction.branch.cond, ", 0\n"); |                     //sysemit_operand(&ctx, instruction.branch.cond, ", 0\n"); | ||||||
|                     janet_formatb(buffer, |                     janet_formatb(buffer, | ||||||
|                                   "%s label_%d_%u\n", |                                   "%s label_%d_%u\n", | ||||||
|                                   instruction.opcode == JANET_SYSOP_BRANCH ? "jnz" : "jz", |                                   instruction.opcode == JANET_SYSOP_BRANCH ? "jnz" : "jz", | ||||||
| @@ -1103,39 +1075,20 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetSysTarget target | |||||||
|     } |     } | ||||||
|     /* End section .text */ |     /* End section .text */ | ||||||
|  |  | ||||||
|  |     /* rodata */ | ||||||
|     janet_formatb(buffer, "\nsection .rodata\n"); |     janet_formatb(buffer, "\nsection .rodata\n"); | ||||||
|  |     janet_formatb(buffer, "CONST_DATA: db "); | ||||||
|  |     emit_nasm_string(buffer, ctx.constant_data->data, ctx.constant_data->count); | ||||||
|  |  | ||||||
|  |     /* old rodata */ | ||||||
|     for (int32_t i = 0; i < linkage->ir_ordered->count; i++) { |     for (int32_t i = 0; i < linkage->ir_ordered->count; i++) { | ||||||
|         JanetSysIR *ir = janet_unwrap_pointer(linkage->ir_ordered->data[i]); |         JanetSysIR *ir = janet_unwrap_pointer(linkage->ir_ordered->data[i]); | ||||||
|         /* Emit constant strings */ |         /* Emit constant strings */ | ||||||
|         for (uint32_t j = 0; j < ir->constant_count; j++) { |         for (uint32_t j = 0; j < ir->constant_count; j++) { | ||||||
|             if (janet_checktype(ir->constants[j].value, JANET_STRING)) { |             if (janet_checktype(ir->constants[j].value, JANET_STRING)) { | ||||||
|  |                 janet_formatb(buffer, "CONST_%d_%d: db ", i, j); | ||||||
|                 JanetString str = janet_unwrap_string(ir->constants[j].value); |                 JanetString str = janet_unwrap_string(ir->constants[j].value); | ||||||
|                 janet_formatb(buffer, "CONST_%d_%u: db ", i, j); |                 emit_nasm_string(buffer, str, janet_string_length(str)); | ||||||
|                 /* Nasm syntax */ |  | ||||||
|                 int in_string = 0; |  | ||||||
|                 for (int32_t ci = 0; ci < janet_string_length(str); ci++) { |  | ||||||
|                     int c = str[ci]; |  | ||||||
|                     if (c < 32) { |  | ||||||
|                         if (in_string) { |  | ||||||
|                             janet_formatb(buffer, "\", %d", c); |  | ||||||
|                         } else { |  | ||||||
|                             janet_formatb(buffer, ci ? ", %d" : "%d", c); |  | ||||||
|                         } |  | ||||||
|                         in_string = 0; |  | ||||||
|                     } else { |  | ||||||
|                         if (!in_string) { |  | ||||||
|                             janet_buffer_push_cstring(buffer, ci ? ", \"" : "\""); |  | ||||||
|                         } |  | ||||||
|                         janet_buffer_push_u8(buffer, c); |  | ||||||
|                         in_string = 1; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 if (!in_string) { |  | ||||||
|                     janet_buffer_push_cstring(buffer, ", 0\n"); |  | ||||||
|                 } else { |  | ||||||
|                     janet_buffer_push_cstring(buffer, "\", 0\n"); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ | |||||||
|   (if x |   (if x | ||||||
|     (when is-verbose (eprintf "\e[32m✔\e[0m %s: %s: %v" line-info (describe e) x)) |     (when is-verbose (eprintf "\e[32m✔\e[0m %s: %s: %v" line-info (describe e) x)) | ||||||
|     (do |     (do | ||||||
|       (eprintf "\e[31m✘\e[0m %s: %s: %v" line-info (describe e) x) (eflush))) |       (eprintf "\e[31m✘\e[0m %s: %s: %v" line-info (string e) x) (eflush))) | ||||||
|   x) |   x) | ||||||
|  |  | ||||||
| (defn skip-asserts | (defn skip-asserts | ||||||
|   | |||||||
| @@ -24,4 +24,27 @@ | |||||||
| (use ../examples/sysir/frontend) | (use ../examples/sysir/frontend) | ||||||
| (assert true) # smoke test | (assert true) # smoke test | ||||||
|  |  | ||||||
|  | (def janet (dyn *executable*)) | ||||||
|  | (def run (filter next (string/split " " (os/getenv "SUBRUN" "")))) | ||||||
|  |  | ||||||
|  | (defn do-expect-directory | ||||||
|  |   "Iterate a directory, evaluating all scripts in the directory. Assert that the captured output of the script | ||||||
|  |   is as expected according to a matching .expect file." | ||||||
|  |   [dir] | ||||||
|  |   (each path (sorted (os/dir dir)) | ||||||
|  |     (when (string/has-suffix? ".janet" path) | ||||||
|  |       (def fullpath (string dir "/" path)) | ||||||
|  |       (def proc (os/spawn [;run janet fullpath] :p {:out :pipe :err :out})) | ||||||
|  |       (def buff @"") | ||||||
|  |       (var ret-code nil) | ||||||
|  |       (ev/gather | ||||||
|  |         (while (ev/read (proc :out) 4096 buff)) | ||||||
|  |         (set ret-code (os/proc-wait proc))) | ||||||
|  |       (def expect-file (string dir "/" path ".expect")) | ||||||
|  |       (def expected-out (slurp expect-file)) | ||||||
|  |       (assert (= (string/trim expected-out) (string/trim buff)) | ||||||
|  |               (string "\nfile: " fullpath "\nexpected:\n======\n" expected-out "\n======\ngot:\n======\n" buff "\n======\n"))))) | ||||||
|  |  | ||||||
|  | (do-expect-directory "test/sysir") | ||||||
|  |  | ||||||
| (end-suite) | (end-suite) | ||||||
|   | |||||||
| @@ -25,4 +25,4 @@ | |||||||
| (sysir/asm ctx types-asm) | (sysir/asm ctx types-asm) | ||||||
| (sysir/asm ctx add-asm) | (sysir/asm ctx add-asm) | ||||||
| (sysir/asm ctx sub-asm) | (sysir/asm ctx sub-asm) | ||||||
| (print (sysir/to-c ctx)) | (printf "%.99j" (sysir/to-ir ctx)) | ||||||
							
								
								
									
										1
									
								
								test/sysir/arrays1.janet.expect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/sysir/arrays1.janet.expect
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | @[@[(type-prim Double f64) (type-array BigVec Double 100)] @[(parameter-count 0)] @[(link-name "add_vector") (parameter-count 2) (type-bind 0 BigVec) (type-bind 1 BigVec) (type-bind 2 BigVec) (add 2 0 1) (return 2)] @[(link-name "sub_vector") (parameter-count 2) (type-bind 0 BigVec) (type-bind 1 BigVec) (type-bind 2 BigVec) (subtract 2 0 1) (return 2)]] | ||||||
| @@ -16,8 +16,7 @@ | |||||||
| 
 | 
 | ||||||
| (def ctx (sysir/context)) | (def ctx (sysir/context)) | ||||||
| (sysir/asm ctx ir-asm) | (sysir/asm ctx ir-asm) | ||||||
| (print (sysir/to-c ctx)) | (printf "%j" (sysir/to-ir ctx)) | ||||||
| (printf "%.99M" (sysir/to-ir ctx)) | (sysir/scalarize ctx) | ||||||
| (print (sysir/scalarize ctx)) | (printf "%j" (sysir/to-ir ctx)) | ||||||
| (printf "%.99M" (sysir/to-ir ctx)) |  | ||||||
| (print (sysir/to-c ctx)) | (print (sysir/to-c ctx)) | ||||||
							
								
								
									
										66
									
								
								test/sysir/arrays2.janet.expect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								test/sysir/arrays2.janet.expect
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | @[@[(type-prim Double f64) (type-array BigVec Double 100) (type-pointer BigVecP BigVec)] @[(link-name "add_vectorp") (parameter-count 2) (type-bind 0 BigVecP) (type-bind 1 BigVecP) (type-bind 2 BigVecP) (add 2 0 1) (return 2)]] | ||||||
|  | @[@[(type-prim Double f64) (type-array BigVec Double 100) (type-pointer BigVecP BigVec)] @[(link-name "add_vectorp") (parameter-count 2) (type-bind 0 BigVecP) (type-bind 1 BigVecP) (type-bind 2 BigVecP) (type-bind 3 U32Index) (type-bind 5 PointerTo) (type-bind 6 PointerTo) (type-bind 7 PointerTo) (type-bind 4 Boolean) (load 3 [U32Index 0]) (label 7) (gte 4 3 [U32Index 0]) (branch 4 21) (apgetp 5 0 3) (apgetp 6 1 3) (apgetp 7 2 3) (add 7 5 6) (add 3 3 [U32Index 1]) (jump 7) (label 21) (return 2)]] | ||||||
|  | #include <stddef.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <sys/syscall.h> | ||||||
|  | #define _t0 void | ||||||
|  |  | ||||||
|  | #line 6 | ||||||
|  | typedef double _t1; | ||||||
|  | #line 7 | ||||||
|  | typedef struct { _t1 els[100]; } _t2; | ||||||
|  | #line 8 | ||||||
|  | typedef _t2 *_t3; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | _t3 add_vectorp(_t3 _r0, _t3 _r1) | ||||||
|  | { | ||||||
|  |     _t3 _r2; | ||||||
|  |     _t4 _r3; | ||||||
|  |     _t5 _r4; | ||||||
|  |     _t6 _r5; | ||||||
|  |     _t6 _r6; | ||||||
|  |     _t6 _r7; | ||||||
|  |  | ||||||
|  | #line 6 | ||||||
|  | #line 7 | ||||||
|  | #line 8 | ||||||
|  | #line 11 | ||||||
|  | #line 12 | ||||||
|  | #line 13 | ||||||
|  | #line 14 | ||||||
|  | #line 14 | ||||||
|  | #line 14 | ||||||
|  | #line 14 | ||||||
|  | #line 14 | ||||||
|  | #line 14 | ||||||
|  |   _r3 = *(0); | ||||||
|  | #line 14 | ||||||
|  |  | ||||||
|  | _label_0: | ||||||
|  | #line 14 | ||||||
|  |   _r4 = _r3 > 0; | ||||||
|  | #line 14 | ||||||
|  |   if (_r4) goto _label_1; | ||||||
|  | #line 14 | ||||||
|  |   _r5 = &(_r0->els[_r3]); | ||||||
|  | #line 14 | ||||||
|  |   _r6 = &(_r1->els[_r3]); | ||||||
|  | #line 14 | ||||||
|  |   _r7 = &(_r2->els[_r3]); | ||||||
|  | #line 14 | ||||||
|  |   _r7 = _r5 + _r6; | ||||||
|  | #line 14 | ||||||
|  |   _r3 = _r3 + 1; | ||||||
|  | #line 14 | ||||||
|  |   goto _label_0; | ||||||
|  | #line 14 | ||||||
|  |  | ||||||
|  | _label_1: | ||||||
|  | #line 15 | ||||||
|  |   return _r2; | ||||||
|  | } | ||||||
| @@ -5,7 +5,7 @@ | |||||||
|     (type-prim Int s32) |     (type-prim Int s32) | ||||||
|     (type-prim Double f64) |     (type-prim Double f64) | ||||||
|     (type-struct MyPair 0 1) |     (type-struct MyPair 0 1) | ||||||
|     (type-pointer PInt 0) |     (type-pointer PInt Int) | ||||||
|     (type-array DoubleArray 1 1024) |     (type-array DoubleArray 1 1024) | ||||||
| 
 | 
 | ||||||
|     # Declarations |     # Declarations | ||||||
| @@ -18,14 +18,14 @@ | |||||||
|     (bind 6 MyPair) |     (bind 6 MyPair) | ||||||
| 
 | 
 | ||||||
|     # Code |     # Code | ||||||
|     (constant 0 10) |     (move 0 (Int 10)) | ||||||
|     (constant 0 21) |     (move 0 (Int 21)) | ||||||
|     :location |     :location | ||||||
|     (add 2 1 0) |     (add 2 1 0) | ||||||
|     (constant 3 1.77) |     (move 3 (Double 1.77)) | ||||||
|     (call 3 sin 3) |     (call :default 3 (PInt sin) 3) | ||||||
|     (cast bob 2) |     (cast bob 2) | ||||||
|     (call :default bob test_function) |     (call :default bob (PInt test_function)) | ||||||
|     (add 5 bob 3) |     (add 5 bob 3) | ||||||
|     (jump :location) |     (jump :location) | ||||||
|     (return 5))) |     (return 5))) | ||||||
							
								
								
									
										71
									
								
								test/sysir/basic1.janet.expect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								test/sysir/basic1.janet.expect
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | #include <stddef.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <sys/syscall.h> | ||||||
|  | #define _t0 void | ||||||
|  |  | ||||||
|  | #line 5 | ||||||
|  | typedef int32_t _t1; | ||||||
|  | #line 6 | ||||||
|  | typedef double _t2; | ||||||
|  | #line 7 | ||||||
|  | typedef struct { | ||||||
|  |     _t0 _f0; | ||||||
|  |     _t1 _f1; | ||||||
|  | } _t3; | ||||||
|  | #line 8 | ||||||
|  | typedef _t1 *_t4; | ||||||
|  | #line 9 | ||||||
|  | typedef struct { _t1 els[1024]; } _t5; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | _t2 test_function() | ||||||
|  | { | ||||||
|  |     _t1 _r0; | ||||||
|  |     _t1 _r1; | ||||||
|  |     _t1 _r2; | ||||||
|  |     _t2 _r3; | ||||||
|  |     _t2 _r4; | ||||||
|  |     _t2 _r5; | ||||||
|  |     _t3 _r6; | ||||||
|  |  | ||||||
|  | #line 5 | ||||||
|  | #line 6 | ||||||
|  | #line 7 | ||||||
|  | #line 7 | ||||||
|  | #line 8 | ||||||
|  | #line 9 | ||||||
|  | #line 12 | ||||||
|  | #line 13 | ||||||
|  | #line 14 | ||||||
|  | #line 15 | ||||||
|  | #line 16 | ||||||
|  | #line 17 | ||||||
|  | #line 18 | ||||||
|  | #line 21 | ||||||
|  |   _r0 = 10; | ||||||
|  | #line 22 | ||||||
|  |   _r0 = 21; | ||||||
|  |  | ||||||
|  | _label_0: | ||||||
|  | #line 24 | ||||||
|  |   _r2 = _r1 + _r0; | ||||||
|  | #line 25 | ||||||
|  |   _r3 = 1.77; | ||||||
|  | #line 26 | ||||||
|  |   _r3 = sin(_r3); | ||||||
|  | #line 26 | ||||||
|  | #line 27 | ||||||
|  |   _r4 = (_t2) _r2; | ||||||
|  | #line 28 | ||||||
|  |   _r4 = test_function(); | ||||||
|  | #line 29 | ||||||
|  |   _r5 = _r4 + _r3; | ||||||
|  | #line 30 | ||||||
|  |   goto _label_0; | ||||||
|  | #line 31 | ||||||
|  |   return _r5; | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								test/sysir/basic2.janet.expect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/sysir/basic2.janet.expect
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | nope | ||||||
							
								
								
									
										1
									
								
								test/sysir/smoke.janet
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/sysir/smoke.janet
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | (print "hello") | ||||||
							
								
								
									
										1
									
								
								test/sysir/smoke.janet.expect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/sysir/smoke.janet.expect
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | hello | ||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose