authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-01-27 11:05:22+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-01 08:47:25+02:00
log258f3ec5ecf8d2a165382d5837bed0dac2e0375b
tree6288700e17a3e4c2a39ac8d742ce85800a88fab4
parentbdfe3aeab8310a64cc9c2f5fac194a609aa0f13d
signaturelock-open Commit is signed but in an unrecognized format.

stage2 cbe: block results


2 files changed, 48 insertions(+), 11 deletions(-)

src/codegen/c.zig+27-11
...@@ -325,7 +325,7 @@ pub fn genDecl(o: *Object) !void {...@@ -325,7 +325,7 @@ pub fn genDecl(o: *Object) !void {
325 const func: *Module.Fn = func_payload.data;325 const func: *Module.Fn = func_payload.data;
326 try o.indent_writer.insertNewline();326 try o.indent_writer.insertNewline();
327 try o.dg.renderFunctionSignature(o.writer(), is_global);327 try o.dg.renderFunctionSignature(o.writer(), is_global);
328 328
329 try o.writer().writeByte(' ');329 try o.writer().writeByte(' ');
330 try genBody(o, func.body);330 try genBody(o, func.body);
331331
...@@ -586,28 +586,44 @@ fn genDbgStmt(o: *Object, inst: *Inst.NoOp) !CValue {...@@ -586,28 +586,44 @@ fn genDbgStmt(o: *Object, inst: *Inst.NoOp) !CValue {
586fn genBlock(o: *Object, inst: *Inst.Block) !CValue {586fn genBlock(o: *Object, inst: *Inst.Block) !CValue {
587 const block_id: usize = o.next_block_index;587 const block_id: usize = o.next_block_index;
588 o.next_block_index += 1;588 o.next_block_index += 1;
589 // abuse codegen.msv to store the block's id589 const writer = o.writer();
590 inst.codegen.mcv.a = block_id;590
591 // store the block id in relocs.capacity as it is not used for anything else in the C backend.
592 inst.codegen.relocs.capacity = block_id;
593 const result = if (inst.base.ty.tag() != .void and !inst.base.isUnused()) blk: {
594 // allocate a location for the result
595 const local = try o.allocLocal(inst.base.ty, .Mut);
596 try writer.writeAll(";\n");
597 break :blk local;
598 } else
599 CValue{ .none = {} };
600
601 inst.codegen.mcv = @bitCast(@import("../codegen.zig").AnyMCValue, result);
591 try genBody(o, inst.body);602 try genBody(o, inst.body);
592 try o.indent_writer.insertNewline();603 try o.indent_writer.insertNewline();
593 // label must be followed by an expression, add an empty one.604 // label must be followed by an expression, add an empty one.
594 try o.writer().print("zig_block_{d}:;\n", .{block_id});605 try writer.print("zig_block_{d}:;\n", .{block_id});
595606 return result;
596 // blocks in C cannot result in values
597 // TODO we need some other way to pass the result of the block
598 return CValue.none;
599}607}
600608
601fn genBr(o: *Object, inst: *Inst.Br) !CValue {609fn genBr(o: *Object, inst: *Inst.Br) !CValue {
602 if (inst.operand.ty.tag() != .void) {610 const result = @bitCast(CValue, inst.block.codegen.mcv);
603 return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement block return values", .{});611 const writer = o.writer();
612
613 // If result is .none then the value of the block is unused.
614 if (inst.operand.ty.tag() != .void and result != .none) {
615 const operand = try o.resolveInst(inst.operand);
616 try o.writeCValue(writer, result);
617 try writer.writeAll(" = ");
618 try o.writeCValue(writer, operand);
619 try writer.writeAll(";\n");
604 }620 }
605621
606 return genBrVoid(o, inst.block);622 return genBrVoid(o, inst.block);
607}623}
608624
609fn genBrVoid(o: *Object, block: *Inst.Block) !CValue {625fn genBrVoid(o: *Object, block: *Inst.Block) !CValue {
610 try o.writer().print("goto zig_block_{d};\n", .{block.codegen.mcv.a});626 try o.writer().print("goto zig_block_{d};\n", .{block.codegen.relocs.capacity});
611 return CValue.none;627 return CValue.none;
612}628}
613629
test/stage2/cbe.zig+21
...@@ -151,6 +151,27 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -151,6 +151,27 @@ pub fn addCases(ctx: *TestContext) !void {
151 \\ unreachable;151 \\ unreachable;
152 \\}152 \\}
153 , "");153 , "");
154
155 // If expression
156 case.addCompareOutput(
157 \\export fn main() c_int {
158 \\ var cond: c_int = 0;
159 \\ var a: c_int = @as(c_int, if (cond == 0)
160 \\ 2
161 \\ else
162 \\ 3) + 9;
163 \\ exit(a - 11);
164 \\}
165 \\
166 \\fn exit(code: usize) noreturn {
167 \\ asm volatile ("syscall"
168 \\ :
169 \\ : [number] "{rax}" (231),
170 \\ [arg1] "{rdi}" (code)
171 \\ );
172 \\ unreachable;
173 \\}
174 , "");
154 }175 }
155176
156 {177 {