aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-09-20 20:37:04 -0400
committerGitHub <noreply@github.com>2021-09-20 20:37:04 -0400
commit1ad905c71e0896295d4781853cd577bbe1b4111a (patch)
tree7d81da6b6fd3ee721b041eb33b3918707f2698df /src/codegen/llvm.zig
parent2a728f6e5f0c5d12e110313342e714f9f23c4044 (diff)
parentf8b914fcf328b30f98d31bb6461c953e4b7a33a7 (diff)
downloadzig-1ad905c71e0896295d4781853cd577bbe1b4111a.tar.gz
zig-1ad905c71e0896295d4781853cd577bbe1b4111a.zip
Merge pull request #9649 from Snektron/address-space
Address Spaces
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig38
1 files changed, 30 insertions, 8 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 2f703e2d68..29efa27685 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -558,7 +558,8 @@ pub const DeclGen = struct {
llvm_params_len,
.False,
);
- const llvm_fn = self.llvmModule().addFunction(decl.name, fn_type);
+ const llvm_addrspace = self.llvmAddressSpace(decl.@"addrspace");
+ const llvm_fn = self.llvmModule().addFunctionInAddressSpace(decl.name, fn_type, llvm_addrspace);
const is_extern = decl.val.tag() == .extern_fn;
if (!is_extern) {
@@ -580,7 +581,24 @@ pub const DeclGen = struct {
if (llvm_module.getNamedGlobal(decl.name)) |val| return val;
// TODO: remove this redundant `llvmType`, it is also called in `genTypedValue`.
const llvm_type = try self.llvmType(decl.ty);
- return llvm_module.addGlobal(llvm_type, decl.name);
+ const llvm_addrspace = self.llvmAddressSpace(decl.@"addrspace");
+ return llvm_module.addGlobalInAddressSpace(llvm_type, decl.name, llvm_addrspace);
+ }
+
+ fn llvmAddressSpace(self: DeclGen, address_space: std.builtin.AddressSpace) c_uint {
+ const target = self.module.getTarget();
+ return switch (target.cpu.arch) {
+ .i386, .x86_64 => switch (address_space) {
+ .generic => llvm.address_space.default,
+ .gs => llvm.address_space.x86.gs,
+ .fs => llvm.address_space.x86.fs,
+ .ss => llvm.address_space.x86.ss,
+ },
+ else => switch (address_space) {
+ .generic => llvm.address_space.default,
+ else => unreachable,
+ },
+ };
}
fn llvmType(self: *DeclGen, t: Type) error{ OutOfMemory, CodegenFail }!*const llvm.Type {
@@ -609,7 +627,7 @@ pub const DeclGen = struct {
.Bool => return self.context.intType(1),
.Pointer => {
if (t.isSlice()) {
- var buf: Type.Payload.ElemType = undefined;
+ var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_type = t.slicePtrFieldType(&buf);
const fields: [2]*const llvm.Type = .{
@@ -619,7 +637,8 @@ pub const DeclGen = struct {
return self.context.structType(&fields, fields.len, .False);
} else {
const elem_type = try self.llvmType(t.elemType());
- return elem_type.pointerType(0);
+ const llvm_addrspace = self.llvmAddressSpace(t.ptrAddressSpace());
+ return elem_type.pointerType(llvm_addrspace);
}
},
.Array => {
@@ -685,7 +704,9 @@ pub const DeclGen = struct {
@intCast(c_uint, llvm_params.len),
llvm.Bool.fromBool(is_var_args),
);
- return llvm_fn_ty.pointerType(0);
+ // TODO make .Fn not both a pointer type and a prototype
+ const llvm_addrspace = self.llvmAddressSpace(.generic);
+ return llvm_fn_ty.pointerType(llvm_addrspace);
},
.ComptimeInt => unreachable,
.ComptimeFloat => unreachable,
@@ -753,7 +774,7 @@ pub const DeclGen = struct {
.Pointer => switch (tv.val.tag()) {
.decl_ref => {
if (tv.ty.isSlice()) {
- var buf: Type.Payload.ElemType = undefined;
+ var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = tv.ty.slicePtrFieldType(&buf);
var slice_len: Value.Payload.U64 = .{
.base = .{ .tag = .int_u64 },
@@ -783,12 +804,13 @@ pub const DeclGen = struct {
decl.alive = true;
const val = try self.resolveGlobalDecl(decl);
const llvm_var_type = try self.llvmType(tv.ty);
- const llvm_type = llvm_var_type.pointerType(0);
+ const llvm_addrspace = self.llvmAddressSpace(decl.@"addrspace");
+ const llvm_type = llvm_var_type.pointerType(llvm_addrspace);
return val.constBitCast(llvm_type);
},
.slice => {
const slice = tv.val.castTag(.slice).?.data;
- var buf: Type.Payload.ElemType = undefined;
+ var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const fields: [2]*const llvm.Value = .{
try self.genTypedValue(.{
.ty = tv.ty.slicePtrFieldType(&buf),