authorgravatar for noam@pixelhero.devNoam Preil <noam@pixelhero.dev> 2020-08-09 19:44:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-12 21:58:21-07:00
logdbd1e42ef227bf55e9356b2d1a1cbde1fbec0e82
treee9f750a333568308eeed154fe23de362752622ba
parent78fe86dcd23821b6a40bc5a0067513c452e50265

CBE: Sorta working intcasts?


2 files changed, 55 insertions(+), 8 deletions(-)

src-self-hosted/codegen/c.zig+19-8
......@@ -117,6 +117,8 @@ fn genFn(file: *C, decl: *Decl) !void {
117117 .dbg_stmt => try genDbgStmt(file, inst.castTag(.dbg_stmt).?, decl),
118118 .breakpoint => try genBreak(file, inst.castTag(.breakpoint).?, decl),
119119 .unreach => try genUnreach(file, inst.castTag(.unreach).?, decl),
120 // This will be handled correctly later?
121 .intcast => {},
120122 else => |e| return file.fail(decl.src(), "TODO implement C codegen for {}", .{e}),
121123 }
122124 }
......@@ -129,6 +131,20 @@ fn genRet(file: *C, inst: *Inst.UnOp, decl: *Decl, expected_return_type: Type) !
129131 return file.fail(decl.src(), "TODO return {}", .{expected_return_type});
130132}
131133
134fn genIntCast(file: *C, inst: *Inst.UnOp, decl: *Decl, argdex: *usize) !void {
135 const op = inst.operand;
136 const writer = file.main.writer();
137 try writer.writeByte('(');
138 try renderType(file, writer, inst.base.ty, decl.src());
139 try writer.writeByte(')');
140 if (op.castTag(.arg)) |_| {
141 try writer.print("arg{}", .{argdex.*});
142 argdex.* += 1;
143 } else {
144 return file.fail(decl.src(), "TODO intcast {} to {}", .{ op, inst.base.ty });
145 }
146}
147
132148fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void {
133149 const writer = file.main.writer();
134150 const header = file.header.writer();
......@@ -196,6 +212,8 @@ fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl, argdex: *usize) !void {
196212 } else if (arg.castTag(.arg)) |inst| {
197213 try writer.print("arg{}", .{argdex.*});
198214 argdex.* += 1;
215 } else if (arg.castTag(.intcast)) |inst| {
216 try genIntCast(file, inst, decl, argdex);
199217 } else {
200218 return file.fail(decl.src(), "TODO non-constant inline asm args ({})", .{arg.tag});
201219 }
......@@ -220,14 +238,7 @@ fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl, argdex: *usize) !void {
220238 if (index > 0) {
221239 try writer.writeAll(", ");
222240 }
223 try writer.writeAll("\"\"(");
224 if (arg.tag == .constant or arg.tag == .arg) {
225 try writer.print("{}_constant", .{reg});
226 } else {
227 // This is blocked by the earlier test
228 unreachable;
229 }
230 try writer.writeByte(')');
241 try writer.print("\"\"({}_constant)", .{reg});
231242 } else {
232243 // This is blocked by the earlier test
233244 unreachable;
test/stage2/cbe.zig+36
......@@ -100,4 +100,40 @@ pub fn addCases(ctx: *TestContext) !void {
100100 \\}
101101 \\
102102 );
103 ctx.c("exit with u8 parameter", linux_x64,
104 \\export fn _start() noreturn {
105 \\ exit(0);
106 \\}
107 \\
108 \\fn exit(code: u8) noreturn {
109 \\ asm volatile ("syscall"
110 \\ :
111 \\ : [number] "{rax}" (231),
112 \\ [arg1] "{rdi}" (code)
113 \\ );
114 \\ unreachable;
115 \\}
116 \\
117 ,
118 \\#include <stddef.h>
119 \\#include <stdint.h>
120 \\
121 \\zig_noreturn void exit(uint8_t arg0);
122 \\
123 \\const char *const exit__anon_0 = "{rax}";
124 \\const char *const exit__anon_1 = "{rdi}";
125 \\const char *const exit__anon_2 = "syscall";
126 \\
127 \\zig_noreturn void _start(void) {
128 \\ exit(0);
129 \\}
130 \\
131 \\zig_noreturn void exit(uint8_t arg0) {
132 \\ register size_t rax_constant __asm__("rax") = 231;
133 \\ register size_t rdi_constant __asm__("rdi") = (size_t)arg0;
134 \\ __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
135 \\ zig_unreachable();
136 \\}
137 \\
138 );
103139}