aboutsummaryrefslogtreecommitdiff
path: root/src/arch/aarch64/CodeGen.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-01-24 20:38:56 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-01-24 21:53:57 -0700
commita2abbeef90bc3fa33acaf85902b4b97383999aaf (patch)
treeba7dfaf67adf2420ac40cbb765e01407387c399b /src/arch/aarch64/CodeGen.zig
parent8bb679bc6e25d1f7c08bb4e5e5272ae5f27aed47 (diff)
downloadzig-a2abbeef90bc3fa33acaf85902b4b97383999aaf.tar.gz
zig-a2abbeef90bc3fa33acaf85902b4b97383999aaf.zip
stage2: rework a lot of stuff
AstGen: * rename the known_has_bits flag to known_non_opv to make it better reflect what it actually means. * add a known_comptime_only flag. * make the flags take advantage of identifiers of primitives and the fact that zig has no shadowing. * correct the known_non_opv flag for function bodies. Sema: * Rename `hasCodeGenBits` to `hasRuntimeBits` to better reflect what it does. - This function got a bit more complicated in this commit because of the duality of function bodies: on one hand they have runtime bits, but on the other hand they require being comptime known. * WipAnonDecl now takes a LazySrcDecl parameter and performs the type resolutions that it needs during finish(). * Implement comptime `@ptrToInt`. Codegen: * Improved handling of lowering decl_ref; make it work for comptime-known ptr-to-int values. - This same change had to be made many different times; perhaps we should look into merging the implementations of `genTypedValue` across x86, arm, aarch64, and riscv.
Diffstat (limited to 'src/arch/aarch64/CodeGen.zig')
-rw-r--r--src/arch/aarch64/CodeGen.zig70
1 files changed, 40 insertions, 30 deletions
diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig
index d5993ea5d7..cb686b8242 100644
--- a/src/arch/aarch64/CodeGen.zig
+++ b/src/arch/aarch64/CodeGen.zig
@@ -713,7 +713,7 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
switch (self.debug_output) {
.dwarf => |dbg_out| {
- assert(ty.hasCodeGenBits());
+ assert(ty.hasRuntimeBits());
const index = dbg_out.dbg_info.items.len;
try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
@@ -1279,7 +1279,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const elem_ty = self.air.typeOfIndex(inst);
const result: MCValue = result: {
- if (!elem_ty.hasCodeGenBits())
+ if (!elem_ty.hasRuntimeBits())
break :result MCValue.none;
const ptr = try self.resolveInst(ty_op.operand);
@@ -2155,7 +2155,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
const block_data = self.blocks.getPtr(block).?;
- if (self.air.typeOf(operand).hasCodeGenBits()) {
+ if (self.air.typeOf(operand).hasRuntimeBits()) {
const operand_mcv = try self.resolveInst(operand);
const block_mcv = block_data.mcv;
if (block_mcv == .none) {
@@ -2608,7 +2608,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
const ref_int = @enumToInt(inst);
if (ref_int < Air.Inst.Ref.typed_value_map.len) {
const tv = Air.Inst.Ref.typed_value_map[ref_int];
- if (!tv.ty.hasCodeGenBits()) {
+ if (!tv.ty.hasRuntimeBits()) {
return MCValue{ .none = {} };
}
return self.genTypedValue(tv);
@@ -2616,7 +2616,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
// If the type has no codegen bits, no need to store it.
const inst_ty = self.air.typeOf(inst);
- if (!inst_ty.hasCodeGenBits())
+ if (!inst_ty.hasRuntimeBits())
return MCValue{ .none = {} };
const inst_index = @intCast(Air.Inst.Index, ref_int - Air.Inst.Ref.typed_value_map.len);
@@ -2672,11 +2672,43 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
return mcv;
}
+fn lowerDeclRef(self: *Self, tv: TypedValue, decl: *Module.Decl) InnerError!MCValue {
+ const ptr_bits = self.target.cpu.arch.ptrBitWidth();
+ const ptr_bytes: u64 = @divExact(ptr_bits, 8);
+ decl.alive = true;
+ if (self.bin_file.cast(link.File.Elf)) |elf_file| {
+ const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
+ const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
+ return MCValue{ .memory = got_addr };
+ } else if (self.bin_file.cast(link.File.MachO)) |_| {
+ // TODO I'm hacking my way through here by repurposing .memory for storing
+ // index to the GOT target symbol index.
+ return MCValue{ .memory = decl.link.macho.local_sym_index };
+ } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
+ const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
+ return MCValue{ .memory = got_addr };
+ } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
+ try p9.seeDecl(decl);
+ const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
+ return MCValue{ .memory = got_addr };
+ } else {
+ return self.fail("TODO codegen non-ELF const Decl pointer", .{});
+ }
+ _ = tv;
+}
+
fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
if (typed_value.val.isUndef())
return MCValue{ .undef = {} };
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
- const ptr_bytes: u64 = @divExact(ptr_bits, 8);
+
+ if (typed_value.val.castTag(.decl_ref)) |payload| {
+ return self.lowerDeclRef(typed_value, payload.data);
+ }
+ if (typed_value.val.castTag(.decl_ref_mut)) |payload| {
+ return self.lowerDeclRef(typed_value, payload.data.decl);
+ }
+
switch (typed_value.ty.zigTypeTag()) {
.Pointer => switch (typed_value.ty.ptrSize()) {
.Slice => {
@@ -2693,28 +2725,6 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
return self.fail("TODO codegen for const slices", .{});
},
else => {
- if (typed_value.val.castTag(.decl_ref)) |payload| {
- const decl = payload.data;
- decl.alive = true;
- if (self.bin_file.cast(link.File.Elf)) |elf_file| {
- const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
- const got_addr = got.p_vaddr + decl.link.elf.offset_table_index * ptr_bytes;
- return MCValue{ .memory = got_addr };
- } else if (self.bin_file.cast(link.File.MachO)) |_| {
- // TODO I'm hacking my way through here by repurposing .memory for storing
- // index to the GOT target symbol index.
- return MCValue{ .memory = decl.link.macho.local_sym_index };
- } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
- const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
- return MCValue{ .memory = got_addr };
- } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
- try p9.seeDecl(decl);
- const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
- return MCValue{ .memory = got_addr };
- } else {
- return self.fail("TODO codegen non-ELF const Decl pointer", .{});
- }
- }
if (typed_value.val.tag() == .int_u64) {
return MCValue{ .immediate = typed_value.val.toUnsignedInt() };
}
@@ -2794,7 +2804,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
const payload_type = typed_value.ty.errorUnionPayload();
const sub_val = typed_value.val.castTag(.eu_payload).?.data;
- if (!payload_type.hasCodeGenBits()) {
+ if (!payload_type.hasRuntimeBits()) {
// We use the error type directly as the type.
return self.genTypedValue(.{ .ty = error_type, .val = sub_val });
}
@@ -2888,7 +2898,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
if (ret_ty.zigTypeTag() == .NoReturn) {
result.return_value = .{ .unreach = {} };
- } else if (!ret_ty.hasCodeGenBits()) {
+ } else if (!ret_ty.hasRuntimeBits()) {
result.return_value = .{ .none = {} };
} else switch (cc) {
.Naked => unreachable,