aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/c.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2021-01-27 12:22:38 +0200
committerVeikka Tuominen <git@vexu.eu>2021-02-01 08:48:24 +0200
commit3ec5c9a3bcae09c01cbe4f0505e6ab03834bbb98 (patch)
tree2558bfafc885f48c78b8035b3b0431a4cb7545d7 /src/codegen/c.zig
parent106520329e5adc6cf5ef83595da6c9d5dd3c4b35 (diff)
downloadzig-3ec5c9a3bcae09c01cbe4f0505e6ab03834bbb98.tar.gz
zig-3ec5c9a3bcae09c01cbe4f0505e6ab03834bbb98.zip
stage2 cbe: implement not and some bitwise ops
Diffstat (limited to 'src/codegen/c.zig')
-rw-r--r--src/codegen/c.zig24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 7fcbe44205..39fa80ea3d 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -293,6 +293,7 @@ pub const DeclGen = struct {
try dg.renderType(w, t.elemType());
try w.writeAll(" *");
},
+ .Null, .Undefined => unreachable, // must be const or comptime
else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{
@tagName(e),
}),
@@ -387,6 +388,7 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi
for (body.instructions) |inst| {
const result_value = switch (inst.tag) {
+ .constant => unreachable, // excluded from function bodies
.add => try genBinOp(o, inst.castTag(.add).?, " + "),
.alloc => try genAlloc(o, inst.castTag(.alloc).?),
.arg => genArg(o),
@@ -415,8 +417,10 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi
.brvoid => try genBrVoid(o, inst.castTag(.brvoid).?.block),
.switchbr => try genSwitchBr(o, inst.castTag(.switchbr).?),
// booland and boolor are non-short-circuit operations
- .booland => try genBinOp(o, inst.castTag(.booland).?, " & "),
- .boolor => try genBinOp(o, inst.castTag(.boolor).?, " | "),
+ .booland, .bitand => try genBinOp(o, inst.castTag(.booland).?, " & "),
+ .boolor, .bitor => try genBinOp(o, inst.castTag(.boolor).?, " | "),
+ .xor => try genBinOp(o, inst.castTag(.xor).?, " ^ "),
+ .not => try genUnOp(o, inst.castTag(.not).?, "!"),
else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),
};
switch (result_value) {
@@ -541,6 +545,22 @@ fn genBinOp(o: *Object, inst: *Inst.BinOp, operator: []const u8) !CValue {
return local;
}
+fn genUnOp(o: *Object, inst: *Inst.UnOp, operator: []const u8) !CValue {
+ if (inst.base.isUnused())
+ return CValue.none;
+
+ const operand = try o.resolveInst(inst.operand);
+
+ const writer = o.writer();
+ const local = try o.allocLocal(inst.base.ty, .Const);
+
+ try writer.print(" = {s}", .{operator});
+ try o.writeCValue(writer, operand);
+ try writer.writeAll(";\n");
+
+ return local;
+}
+
fn genCall(o: *Object, inst: *Inst.Call) !CValue {
if (inst.func.castTag(.constant)) |func_inst| {
const fn_decl = if (func_inst.val.castTag(.extern_fn)) |extern_fn|