| ... | @@ -587,11 +587,36 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -587,11 +587,36 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 587 | | 587 | |
| 588 | try self.dbgSetEpilogueBegin(); | 588 | try self.dbgSetEpilogueBegin(); |
| 589 | | 589 | |
| | 590 | // exitlude jumps |
| | 591 | if (self.exitlude_jump_relocs.items.len == 1) { |
| | 592 | // There is only one relocation. Hence, |
| | 593 | // this relocation must be at the end of |
| | 594 | // the code. Therefore, we can just delete |
| | 595 | // the space initially reserved for the |
| | 596 | // jump |
| | 597 | self.code.items.len -= 4; |
| | 598 | } else for (self.exitlude_jump_relocs.items) |jmp_reloc| { |
| | 599 | const amt = self.code.items.len - (jmp_reloc + 4); |
| | 600 | if (amt == 0) { |
| | 601 | // This return is at the end of the |
| | 602 | // code block. We can't just delete |
| | 603 | // the space because there may be |
| | 604 | // other jumps we already relocated to |
| | 605 | // the address. Instead, insert a nop |
| | 606 | mem.writeIntLittle(u32, self.code.items[jmp_reloc..][0..4], Instruction.nop().toU32()); |
| | 607 | } else { |
| | 608 | if (math.cast(i26, amt)) |offset| { |
| | 609 | mem.writeIntLittle(u32, self.code.items[jmp_reloc..][0..4], Instruction.b(.al, offset).toU32()); |
| | 610 | } else |err| { |
| | 611 | return self.fail(self.src, "exitlude jump is too large", .{}); |
| | 612 | } |
| | 613 | } |
| | 614 | } |
| | 615 | |
| 590 | // mov sp, fp | 616 | // mov sp, fp |
| 591 | // pop {fp, pc} | 617 | // pop {fp, pc} |
| 592 | // TODO: return by jumping to this code, use relocations | 618 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .sp, Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none)).toU32()); |
| 593 | // mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .sp, Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none)).toU32()); | 619 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.pop(.al, .{ .fp, .pc }).toU32()); |
| 594 | // mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.pop(.al, .{ .fp, .pc }).toU32()); | | |
| 595 | } else { | 620 | } else { |
| 596 | try self.dbgSetPrologueEnd(); | 621 | try self.dbgSetPrologueEnd(); |
| 597 | try self.genBody(self.mod_fn.analysis.success); | 622 | try self.genBody(self.mod_fn.analysis.success); |
| ... | @@ -1661,12 +1686,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -1661,12 +1686,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1661 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.jalr(.zero, 0, .ra).toU32()); | 1686 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.jalr(.zero, 0, .ra).toU32()); |
| 1662 | }, | 1687 | }, |
| 1663 | .arm => { | 1688 | .arm => { |
| 1664 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.mov(.al, .sp, Instruction.Operand.reg(.fp, Instruction.Operand.Shift.none)).toU32()); | 1689 | // Just add space for an instruction, patch this later |
| 1665 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.pop(.al, .{ .fp, .pc }).toU32()); | 1690 | try self.code.resize(self.code.items.len + 4); |
| 1666 | // TODO: jump to the end with relocation | 1691 | try self.exitlude_jump_relocs.append(self.gpa, self.code.items.len - 4); |
| 1667 | // // Just add space for an instruction, patch this later | | |
| 1668 | // try self.code.resize(self.code.items.len + 4); | | |
| 1669 | // try self.exitlude_jump_relocs.append(self.gpa, self.code.items.len - 4); | | |
| 1670 | }, | 1692 | }, |
| 1671 | else => return self.fail(src, "TODO implement return for {}", .{self.target.cpu.arch}), | 1693 | else => return self.fail(src, "TODO implement return for {}", .{self.target.cpu.arch}), |
| 1672 | } | 1694 | } |
| ... | @@ -1932,6 +1954,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -1932,6 +1954,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1932 | mem.writeIntLittle(i32, self.code.addManyAsArrayAssumeCapacity(4), delta); | 1954 | mem.writeIntLittle(i32, self.code.addManyAsArrayAssumeCapacity(4), delta); |
| 1933 | } | 1955 | } |
| 1934 | }, | 1956 | }, |
| | 1957 | .arm => { |
| | 1958 | if (math.cast(i26, @intCast(i32, index) - @intCast(i32, self.code.items.len))) |delta| { |
| | 1959 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(.al, delta).toU32()); |
| | 1960 | } else |err| { |
| | 1961 | return self.fail(src, "TODO: enable larger branch offset", .{}); |
| | 1962 | } |
| | 1963 | }, |
| 1935 | else => return self.fail(src, "TODO implement jump for {}", .{self.target.cpu.arch}), | 1964 | else => return self.fail(src, "TODO implement jump for {}", .{self.target.cpu.arch}), |
| 1936 | } | 1965 | } |
| 1937 | } | 1966 | } |