diff options
| author | Noam Preil <noam@pixelhero.dev> | 2020-09-08 14:39:47 -0400 |
|---|---|---|
| committer | Noam Preil <noam@pixelhero.dev> | 2020-10-06 15:09:57 -0400 |
| commit | ea7b2750c823e7160db790582a1dcb96a9feebc7 (patch) | |
| tree | 841841bd51f53c8403cdd81bfe6b6054f023cc23 | |
| parent | e06ba9e86e53797d90d74e87724b897858fe2d77 (diff) | |
| download | zig-ea7b2750c823e7160db790582a1dcb96a9feebc7.tar.gz zig-ea7b2750c823e7160db790582a1dcb96a9feebc7.zip | |
CBE: addition and subtraction
| -rw-r--r-- | src/codegen/c.zig | 15 | ||||
| -rw-r--r-- | test/stage2/cbe.zig | 48 |
2 files changed, 63 insertions, 0 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 5d350f7bd5..99ac0cfe00 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -160,6 +160,8 @@ fn genFn(file: *C, decl: *Decl) !void { if (switch (inst.tag) { .assembly => try genAsm(&ctx, inst.castTag(.assembly).?), .call => try genCall(&ctx, inst.castTag(.call).?), + .add => try genBinOp(&ctx, inst.cast(Inst.BinOp).?, "+"), + .sub => try genBinOp(&ctx, inst.cast(Inst.BinOp).?, "-"), .ret => try genRet(&ctx, inst.castTag(.ret).?), .retvoid => try genRetVoid(&ctx), .arg => try genArg(&ctx), @@ -207,6 +209,19 @@ fn genIntCast(ctx: *Context, inst: *Inst.UnOp) !?[]u8 { return name; } +fn genBinOp(ctx: *Context, inst: *Inst.BinOp, comptime operator: []const u8) !?[]u8 { + if (inst.base.isUnused()) + return null; + const lhs = ctx.resolveInst(inst.lhs); + const rhs = ctx.resolveInst(inst.rhs); + const writer = ctx.file.main.writer(); + const name = try ctx.name(); + try writer.writeAll(indentation ++ "const "); + try renderType(ctx, writer, inst.base.ty); + try writer.print(" {} = {} " ++ operator ++ " {};\n", .{ name, lhs, rhs }); + return name; +} + fn genCall(ctx: *Context, inst: *Inst.Call) !?[]u8 { const writer = ctx.file.main.writer(); const header = ctx.file.header.writer(); diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig index 2a176e0368..0be5bd8704 100644 --- a/test/stage2/cbe.zig +++ b/test/stage2/cbe.zig @@ -147,4 +147,52 @@ pub fn addCases(ctx: *TestContext) !void { \\} \\ ); + ctx.c("exit with u8 arithmetic", linux_x64, + \\export fn _start() noreturn { + \\ exitMath(1); + \\} + \\ + \\fn exitMath(a: u8) noreturn { + \\ exit(0 + a - a); + \\} + \\ + \\fn exit(code: u8) noreturn { + \\ asm volatile ("syscall" + \\ : + \\ : [number] "{rax}" (231), + \\ [arg1] "{rdi}" (code) + \\ ); + \\ unreachable; + \\} + \\ + , + \\#include <stddef.h> + \\#include <stdint.h> + \\ + \\zig_noreturn void exitMath(uint8_t arg0); + \\zig_noreturn void exit(uint8_t arg0); + \\ + \\const char *const exit__anon_0 = "{rax}"; + \\const char *const exit__anon_1 = "{rdi}"; + \\const char *const exit__anon_2 = "syscall"; + \\ + \\zig_noreturn void _start(void) { + \\ exitMath(1); + \\} + \\ + \\zig_noreturn void exitMath(uint8_t arg0) { + \\ const uint8_t __temp_0 = 0 + arg0; + \\ const uint8_t __temp_1 = __temp_0 - arg0; + \\ exit(__temp_1); + \\} + \\ + \\zig_noreturn void exit(uint8_t arg0) { + \\ const size_t __temp_0 = (size_t)arg0; + \\ register size_t rax_constant __asm__("rax") = 231; + \\ register size_t rdi_constant __asm__("rdi") = __temp_0; + \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant)); + \\ zig_unreachable(); + \\} + \\ + ); } |
