authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2020-11-09 01:02:57+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-11-11 14:34:53+01:00
logca0016a225e7ad96d286923594d4077dbd215f0d
treead59e5a436fe8e8542f50fccaea5d86916b8edb8
parentaa9df72f714c0bd3c8653ea0c5431d43543b6f6f

stage2 ARM: start implementing genCall for ELF + genSetReg immediates


1 files changed, 69 insertions(+), 1 deletions(-)

src/codegen.zig+69-1
...@@ -1586,6 +1586,60 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1586,6 +1586,60 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1586 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});1586 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
1587 }1587 }
1588 },1588 },
1589 .aarch64 => {
1590 for (info.args) |mc_arg, arg_i| {
1591 const arg = inst.args[arg_i];
1592 const arg_mcv = try self.resolveInst(inst.args[arg_i]);
1593
1594 switch (mc_arg) {
1595 .none => continue,
1596 .undef => unreachable,
1597 .immediate => unreachable,
1598 .unreach => unreachable,
1599 .dead => unreachable,
1600 .embedded_in_code => unreachable,
1601 .memory => unreachable,
1602 .compare_flags_signed => unreachable,
1603 .compare_flags_unsigned => unreachable,
1604 .register => |reg| {
1605 try self.genSetReg(arg.src, reg, arg_mcv);
1606 // TODO interact with the register allocator to mark the instruction as moved.
1607 },
1608 .stack_offset => {
1609 return self.fail(inst.base.src, "TODO implement calling with parameters in memory", .{});
1610 },
1611 .ptr_stack_offset => {
1612 return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_stack_offset arg", .{});
1613 },
1614 .ptr_embedded_in_code => {
1615 return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_embedded_in_code arg", .{});
1616 },
1617 }
1618 }
1619
1620 if (inst.func.cast(ir.Inst.Constant)) |func_inst| {
1621 if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
1622 const func = func_val.func;
1623 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
1624 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
1625 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
1626 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
1627 break :blk @intCast(u32, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * ptr_bytes);
1628 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|
1629 coff_file.offset_table_virtual_address + func.owner_decl.link.coff.offset_table_index * ptr_bytes
1630 else
1631 unreachable;
1632
1633 try self.genSetReg(inst.base.src, .x30, .{ .memory = got_addr });
1634
1635 writeInt(u32, try self.code.addManyAsArray(4), Instruction.blr(.x30).toU32());
1636 } else {
1637 return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
1638 }
1639 } else {
1640 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
1641 }
1642 },
1589 else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}),1643 else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}),
1590 }1644 }
1591 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {1645 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
...@@ -1702,6 +1756,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -1702,6 +1756,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1702 try self.code.resize(self.code.items.len + 4);1756 try self.code.resize(self.code.items.len + 4);
1703 try self.exitlude_jump_relocs.append(self.gpa, self.code.items.len - 4);1757 try self.exitlude_jump_relocs.append(self.gpa, self.code.items.len - 4);
1704 },1758 },
1759 .aarch64 => {
1760 // TODO: relocations
1761 writeInt(u32, try self.code.addManyAsArray(4), Instruction.ret(null).toU32());
1762 },
1705 else => return self.fail(src, "TODO implement return for {}", .{self.target.cpu.arch}),1763 else => return self.fail(src, "TODO implement return for {}", .{self.target.cpu.arch}),
1706 }1764 }
1707 return .unreach;1765 return .unreach;
...@@ -2510,8 +2568,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2510,8 +2568,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2510 .immediate => |x| {2568 .immediate => |x| {
2511 if (x <= math.maxInt(u16)) {2569 if (x <= math.maxInt(u16)) {
2512 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movz(reg, @intCast(u16, x), 0).toU32());2570 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movz(reg, @intCast(u16, x), 0).toU32());
2571 } else if (x <= math.maxInt(u32)) {
2572 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movz(reg, @truncate(u16, x), 0).toU32());
2573 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 16), 16).toU32());
2574 } else if (x <= math.maxInt(u32)) {
2575 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movz(reg, @intCast(u16, x), 0).toU32());
2576 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 16), 16).toU32());
2577 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 32), 32).toU32());
2513 } else {2578 } else {
2514 return self.fail(src, "TODO genSetReg with 32,48,64bit immediates", .{});2579 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movz(reg, @intCast(u16, x), 0).toU32());
2580 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 16), 16).toU32());
2581 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 32), 32).toU32());
2582 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 48), 48).toU32());
2515 }2583 }
2516 },2584 },
2517 .register => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),2585 .register => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),