| ... | @@ -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}), |