aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-09-21 22:33:00 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-09-21 23:21:07 -0700
commitaecebf38acc8835db21eeea7b53e4ee26ec739a8 (patch)
tree132a3982487ae7bb1a0210a4ff2b7cd7a2934855 /src/codegen
parent0e2b9ac7770df07212d4d1cbfb15c3aaed0bef18 (diff)
downloadzig-aecebf38acc8835db21eeea7b53e4ee26ec739a8.tar.gz
zig-aecebf38acc8835db21eeea7b53e4ee26ec739a8.zip
stage2: progress towards ability to compile compiler-rt
* prepare compiler-rt to support being compiled by stage2 - put in a few minor workarounds that will be removed later, such as using `builtin.stage2_arch` rather than `builtin.cpu.arch`. - only try to export a few symbols for now - we'll move more symbols over to the "working in stage2" section as they become functional and gain test coverage. - use `inline fn` at function declarations rather than `@call` with an always_inline modifier at the callsites, to avoid depending on the anonymous array literal syntax language feature (for now). * AIR: replace floatcast instruction with fptrunc and fpext for shortening and widening floating point values, respectively. * Introduce a new ZIR instruction, `export_value`, which implements `@export` for the case when the thing to be exported is a local comptime value that points to a function. - AstGen: fix `@export` not properly reporting ambiguous decl references. * Sema: handle ExportOptions linkage. The value is now available to all backends. - Implement setting global linkage as appropriate in the LLVM backend. I did not yet inspect the LLVM IR, so this still needs to be audited. There is already a pending task to make sure the alias stuff is working as intended, and this is related. - Sema almost handles section, just a tiny bit more code is needed in `resolveExportOptions`. * Sema: implement float widening and shortening for both `@floatCast` and float coercion. - Implement the LLVM backend code for this as well.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig10
-rw-r--r--src/codegen/llvm.zig36
-rw-r--r--src/codegen/llvm/bindings.zig16
3 files changed, 53 insertions, 9 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index c4e1d48062..a82f0e57f7 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -954,7 +954,12 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
.atomic_rmw => try airAtomicRmw(f, inst),
.atomic_load => try airAtomicLoad(f, inst),
- .int_to_float, .float_to_int => try airSimpleCast(f, inst),
+ .int_to_float,
+ .float_to_int,
+ .fptrunc,
+ .fpext,
+ .ptrtoint,
+ => try airSimpleCast(f, inst),
.atomic_store_unordered => try airAtomicStore(f, inst, toMemoryOrder(.Unordered)),
.atomic_store_monotonic => try airAtomicStore(f, inst, toMemoryOrder(.Monotonic)),
@@ -982,9 +987,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
.unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst),
.wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
.wrap_errunion_err => try airWrapErrUnionErr(f, inst),
-
- .ptrtoint => return f.fail("TODO: C backend: implement codegen for ptrtoint", .{}),
- .floatcast => return f.fail("TODO: C backend: implement codegen for floatcast", .{}),
// zig fmt: on
};
switch (result_value) {
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 3a977bc582..0d3bca2b03 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -472,7 +472,18 @@ pub const Object = struct {
alias.setAliasee(llvm_fn);
} else {
const alias = self.llvm_module.addAlias(llvm_fn.typeOf(), llvm_fn, exp_name_z);
- _ = alias;
+ switch (exp.options.linkage) {
+ .Internal => alias.setLinkage(.Internal),
+ .Strong => alias.setLinkage(.External),
+ .Weak => {
+ if (is_extern) {
+ alias.setLinkage(.ExternalWeak);
+ } else {
+ alias.setLinkage(.WeakODR);
+ }
+ },
+ .LinkOnce => alias.setLinkage(.LinkOnceODR),
+ }
}
}
}
@@ -1137,7 +1148,8 @@ pub const FuncGen = struct {
.cond_br => try self.airCondBr(inst),
.intcast => try self.airIntCast(inst),
.trunc => try self.airTrunc(inst),
- .floatcast => try self.airFloatCast(inst),
+ .fptrunc => try self.airFptrunc(inst),
+ .fpext => try self.airFpext(inst),
.ptrtoint => try self.airPtrToInt(inst),
.load => try self.airLoad(inst),
.loop => try self.airLoop(inst),
@@ -2060,12 +2072,26 @@ pub const FuncGen = struct {
return self.builder.buildTrunc(operand, dest_llvm_ty, "");
}
- fn airFloatCast(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
+ fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
if (self.liveness.isUnused(inst))
return null;
- // TODO split floatcast AIR into float_widen and float_shorten
- return self.todo("implement 'airFloatCast'", .{});
+ const ty_op = self.air.instructions.items(.data)[inst].ty_op;
+ const operand = try self.resolveInst(ty_op.operand);
+ const dest_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));
+
+ return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");
+ }
+
+ fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
+ if (self.liveness.isUnused(inst))
+ return null;
+
+ const ty_op = self.air.instructions.items(.data)[inst].ty_op;
+ const operand = try self.resolveInst(ty_op.operand);
+ const dest_llvm_ty = try self.dg.llvmType(self.air.typeOfIndex(inst));
+
+ return self.builder.buildFPExt(operand, dest_llvm_ty, "");
}
fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig
index 039232426b..bf951fa67e 100644
--- a/src/codegen/llvm/bindings.zig
+++ b/src/codegen/llvm/bindings.zig
@@ -601,6 +601,22 @@ pub const Builder = opaque {
DestTy: *const Type,
Name: [*:0]const u8,
) *const Value;
+
+ pub const buildFPTrunc = LLVMBuildFPTrunc;
+ extern fn LLVMBuildFPTrunc(
+ *const Builder,
+ Val: *const Value,
+ DestTy: *const Type,
+ Name: [*:0]const u8,
+ ) *const Value;
+
+ pub const buildFPExt = LLVMBuildFPExt;
+ extern fn LLVMBuildFPExt(
+ *const Builder,
+ Val: *const Value,
+ DestTy: *const Type,
+ Name: [*:0]const u8,
+ ) *const Value;
};
pub const IntPredicate = enum(c_uint) {