aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-09-20 17:32:52 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-09-20 17:32:52 -0700
commitf8b914fcf328b30f98d31bb6461c953e4b7a33a7 (patch)
tree06b74c36e25e94c1a8a5e384d289ffd556fdd4a9 /src/codegen
parentabc30f79489b68f6dc0ee4b408c63a8e783215d1 (diff)
parent619260d94d68bdecdac649fa7b156dc8962a9889 (diff)
downloadzig-f8b914fcf328b30f98d31bb6461c953e4b7a33a7.tar.gz
zig-f8b914fcf328b30f98d31bb6461c953e4b7a33a7.zip
Merge branch 'address-space' of Snektron/zig into Snektron-address-space
There were two things to resolve here: * Snektron's branch edited Zir printing, but in master branch I moved the printing code from Zir.zig to print_zir.zig. So that just had to be moved over. * In master branch I fleshed out coerceInMemory a bit more, which caused one of Snektron's test cases to fail, so I had to add addrspace awareness to that. Once I did that the tests passed again.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig2
-rw-r--r--src/codegen/llvm.zig38
-rw-r--r--src/codegen/llvm/bindings.zig68
3 files changed, 99 insertions, 9 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 6da791cb46..fb8211f6b8 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -251,7 +251,7 @@ pub const DeclGen = struct {
try writer.writeByte('(');
try dg.renderType(writer, t);
try writer.writeAll("){");
- var buf: Type.Payload.ElemType = undefined;
+ var buf: Type.SlicePtrFieldTypeBuffer = undefined;
try dg.renderValue(writer, t.slicePtrFieldType(&buf), val);
try writer.writeAll(", ");
try writer.print("{d}", .{val.sliceLen()});
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),
diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig
index 16445fa2d1..039232426b 100644
--- a/src/codegen/llvm/bindings.zig
+++ b/src/codegen/llvm/bindings.zig
@@ -197,6 +197,9 @@ pub const Module = opaque {
pub const addFunction = LLVMAddFunction;
extern fn LLVMAddFunction(*const Module, Name: [*:0]const u8, FunctionTy: *const Type) *const Value;
+ pub const addFunctionInAddressSpace = ZigLLVMAddFunctionInAddressSpace;
+ extern fn ZigLLVMAddFunctionInAddressSpace(*const Module, Name: [*:0]const u8, FunctionTy: *const Type, AddressSpace: c_uint) *const Value;
+
pub const getNamedFunction = LLVMGetNamedFunction;
extern fn LLVMGetNamedFunction(*const Module, Name: [*:0]const u8) ?*const Value;
@@ -209,6 +212,9 @@ pub const Module = opaque {
pub const addGlobal = LLVMAddGlobal;
extern fn LLVMAddGlobal(M: *const Module, Ty: *const Type, Name: [*:0]const u8) *const Value;
+ pub const addGlobalInAddressSpace = LLVMAddGlobalInAddressSpace;
+ extern fn LLVMAddGlobalInAddressSpace(M: *const Module, Ty: *const Type, Name: [*:0]const u8, AddressSpace: c_uint) *const Value;
+
pub const getNamedGlobal = LLVMGetNamedGlobal;
extern fn LLVMGetNamedGlobal(M: *const Module, Name: [*:0]const u8) ?*const Value;
@@ -1005,3 +1011,65 @@ pub const TypeKind = enum(c_int) {
BFloat,
X86_AMX,
};
+
+pub const address_space = struct {
+ pub const default: c_uint = 0;
+
+ // See llvm/lib/Target/X86/X86.h
+ pub const x86_64 = x86;
+ pub const x86 = struct {
+ pub const gs: c_uint = 256;
+ pub const fs: c_uint = 257;
+ pub const ss: c_uint = 258;
+
+ pub const ptr32_sptr: c_uint = 270;
+ pub const ptr32_uptr: c_uint = 271;
+ pub const ptr64: c_uint = 272;
+ };
+
+ // See llvm/lib/Target/AVR/AVR.h
+ pub const avr = struct {
+ pub const data_memory: c_uint = 0;
+ pub const program_memory: c_uint = 1;
+ };
+
+ // See llvm/lib/Target/NVPTX/NVPTX.h
+ pub const nvptx = struct {
+ pub const generic: c_uint = 0;
+ pub const global: c_uint = 1;
+ pub const constant: c_uint = 2;
+ pub const shared: c_uint = 3;
+ pub const param: c_uint = 4;
+ pub const local: c_uint = 5;
+ };
+
+ // See llvm/lib/Target/AMDGPU/AMDGPU.h
+ pub const amdgpu = struct {
+ pub const flat: c_uint = 0;
+ pub const global: c_uint = 1;
+ pub const region: c_uint = 2;
+ pub const local: c_uint = 3;
+ pub const constant: c_uint = 4;
+ pub const private: c_uint = 5;
+ pub const constant_32bit: c_uint = 6;
+ pub const buffer_fat_pointer: c_uint = 7;
+ pub const param_d: c_uint = 6;
+ pub const param_i: c_uint = 7;
+ pub const constant_buffer_0: c_uint = 8;
+ pub const constant_buffer_1: c_uint = 9;
+ pub const constant_buffer_2: c_uint = 10;
+ pub const constant_buffer_3: c_uint = 11;
+ pub const constant_buffer_4: c_uint = 12;
+ pub const constant_buffer_5: c_uint = 13;
+ pub const constant_buffer_6: c_uint = 14;
+ pub const constant_buffer_7: c_uint = 15;
+ pub const constant_buffer_8: c_uint = 16;
+ pub const constant_buffer_9: c_uint = 17;
+ pub const constant_buffer_10: c_uint = 18;
+ pub const constant_buffer_11: c_uint = 19;
+ pub const constant_buffer_12: c_uint = 20;
+ pub const constant_buffer_13: c_uint = 21;
+ pub const constant_buffer_14: c_uint = 22;
+ pub const constant_buffer_15: c_uint = 23;
+ };
+};