authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-01-26 19:50:46+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-01 08:47:25+02:00
log81c512f35b1926cf3fb6f29b97e68256aa164f68
tree5513bdb01680455a7fd69ab61bcf7230a5530dfd
parentbf76501b5d46277d3706a1f0b92ba52f2a47d894
signaturelock-open Commit is signed but in an unrecognized format.

stage2 cbe: loop instruction


1 files changed, 58 insertions(+), 41 deletions(-)

src/codegen/c.zig+58-41
......@@ -6,7 +6,8 @@ const Writer = std.ArrayList(u8).Writer;
66const link = @import("../link.zig");
77const Module = @import("../Module.zig");
88const Compilation = @import("../Compilation.zig");
9const Inst = @import("../ir.zig").Inst;
9const ir = @import("../ir.zig");
10const Inst = ir.Inst;
1011const Value = @import("../value.zig").Value;
1112const Type = @import("../type.zig").Type;
1213const TypedValue = @import("../TypedValue.zig");
......@@ -324,51 +325,13 @@ pub fn genDecl(o: *Object) !void {
324325 try fwd_decl_writer.writeAll(";\n");
325326
326327 const func: *Module.Fn = func_payload.data;
327 const instructions = func.body.instructions;
328328 const writer = o.code.writer();
329329 try writer.writeAll("\n");
330330 try o.dg.renderFunctionSignature(writer, is_global);
331 if (instructions.len == 0) {
332 try writer.writeAll(" {}\n");
333 return;
334 }
335
336 try writer.writeAll(" {");
331
332 try genBody(o, func.body);
337333
338334 try writer.writeAll("\n");
339 for (instructions) |inst| {
340 const result_value = switch (inst.tag) {
341 .add => try genBinOp(o, inst.castTag(.add).?, " + "),
342 .alloc => try genAlloc(o, inst.castTag(.alloc).?),
343 .arg => genArg(o),
344 .assembly => try genAsm(o, inst.castTag(.assembly).?),
345 .block => try genBlock(o, inst.castTag(.block).?),
346 .bitcast => try genBitcast(o, inst.castTag(.bitcast).?),
347 .breakpoint => try genBreakpoint(o, inst.castTag(.breakpoint).?),
348 .call => try genCall(o, inst.castTag(.call).?),
349 .cmp_eq => try genBinOp(o, inst.castTag(.cmp_eq).?, " == "),
350 .cmp_gt => try genBinOp(o, inst.castTag(.cmp_gt).?, " > "),
351 .cmp_gte => try genBinOp(o, inst.castTag(.cmp_gte).?, " >= "),
352 .cmp_lt => try genBinOp(o, inst.castTag(.cmp_lt).?, " < "),
353 .cmp_lte => try genBinOp(o, inst.castTag(.cmp_lte).?, " <= "),
354 .cmp_neq => try genBinOp(o, inst.castTag(.cmp_neq).?, " != "),
355 .dbg_stmt => try genDbgStmt(o, inst.castTag(.dbg_stmt).?),
356 .intcast => try genIntCast(o, inst.castTag(.intcast).?),
357 .load => try genLoad(o, inst.castTag(.load).?),
358 .ret => try genRet(o, inst.castTag(.ret).?),
359 .retvoid => try genRetVoid(o),
360 .store => try genStore(o, inst.castTag(.store).?),
361 .sub => try genBinOp(o, inst.castTag(.sub).?, " - "),
362 .unreach => try genUnreach(o, inst.castTag(.unreach).?),
363 else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),
364 };
365 switch (result_value) {
366 .none => {},
367 else => try o.value_map.putNoClobber(inst, result_value),
368 }
369 }
370
371 try writer.writeAll("}\n");
372335 } else if (tv.val.tag() == .extern_fn) {
373336 const writer = o.code.writer();
374337 try writer.writeAll("ZIG_EXTERN_C ");
......@@ -410,6 +373,52 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
410373 }
411374}
412375
376pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!void {
377 const writer = o.code.writer();
378 if (body.instructions.len == 0) {
379 try writer.writeAll(" {}");
380 return;
381 }
382
383 try writer.writeAll(" {");
384
385 try writer.writeAll("\n");
386 for (body.instructions) |inst| {
387 const result_value = switch (inst.tag) {
388 .add => try genBinOp(o, inst.castTag(.add).?, " + "),
389 .alloc => try genAlloc(o, inst.castTag(.alloc).?),
390 .arg => genArg(o),
391 .assembly => try genAsm(o, inst.castTag(.assembly).?),
392 .block => try genBlock(o, inst.castTag(.block).?),
393 .bitcast => try genBitcast(o, inst.castTag(.bitcast).?),
394 .breakpoint => try genBreakpoint(o, inst.castTag(.breakpoint).?),
395 .call => try genCall(o, inst.castTag(.call).?),
396 .cmp_eq => try genBinOp(o, inst.castTag(.cmp_eq).?, " == "),
397 .cmp_gt => try genBinOp(o, inst.castTag(.cmp_gt).?, " > "),
398 .cmp_gte => try genBinOp(o, inst.castTag(.cmp_gte).?, " >= "),
399 .cmp_lt => try genBinOp(o, inst.castTag(.cmp_lt).?, " < "),
400 .cmp_lte => try genBinOp(o, inst.castTag(.cmp_lte).?, " <= "),
401 .cmp_neq => try genBinOp(o, inst.castTag(.cmp_neq).?, " != "),
402 .dbg_stmt => try genDbgStmt(o, inst.castTag(.dbg_stmt).?),
403 .intcast => try genIntCast(o, inst.castTag(.intcast).?),
404 .load => try genLoad(o, inst.castTag(.load).?),
405 .ret => try genRet(o, inst.castTag(.ret).?),
406 .retvoid => try genRetVoid(o),
407 .store => try genStore(o, inst.castTag(.store).?),
408 .sub => try genBinOp(o, inst.castTag(.sub).?, " - "),
409 .unreach => try genUnreach(o, inst.castTag(.unreach).?),
410 .loop => try genLoop(o, inst.castTag(.loop).?),
411 else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),
412 };
413 switch (result_value) {
414 .none => {},
415 else => try o.value_map.putNoClobber(inst, result_value),
416 }
417 }
418
419 try writer.writeAll("}");
420}
421
413422fn genAlloc(o: *Object, alloc: *Inst.NoOp) !CValue {
414423 const writer = o.code.writer();
415424
......@@ -627,6 +636,14 @@ fn genUnreach(o: *Object, inst: *Inst.NoOp) !CValue {
627636 return CValue.none;
628637}
629638
639fn genLoop(o: *Object, inst: *Inst.Loop) !CValue {
640 try o.indent();
641 try o.code.writer().writeAll("while (true)");
642 try genBody(o, inst.body);
643 try o.code.writer().writeAll("\n");
644 return CValue.none;
645}
646
630647fn genAsm(o: *Object, as: *Inst.Assembly) !CValue {
631648 if (as.base.isUnused() and !as.is_volatile)
632649 return CValue.none;