stage2: Implement genBreakpoint for ARM
This commit is contained in:
@@ -76,8 +76,8 @@ pub fn generateSymbol(
|
||||
switch (bin_file.options.target.cpu.arch) {
|
||||
.wasm32 => unreachable, // has its own code path
|
||||
.wasm64 => unreachable, // has its own code path
|
||||
//.arm => return Function(.arm).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs),
|
||||
//.armeb => return Function(.armeb).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs),
|
||||
.arm => return Function(.arm).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs),
|
||||
.armeb => return Function(.armeb).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs),
|
||||
//.aarch64 => return Function(.aarch64).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs),
|
||||
//.aarch64_be => return Function(.aarch64_be).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs),
|
||||
//.aarch64_32 => return Function(.aarch64_32).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs),
|
||||
@@ -1270,8 +1270,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
var instr = Instruction{ .condition = .always, .input0 = .zero, .input1 = .zero, .modify_flags = false, .output = .discard, .command = .undefined1 };
|
||||
mem.writeIntLittle(u16, self.code.items[self.code.items.len - 2 ..][0..2], @bitCast(u16, instr));
|
||||
},
|
||||
.arm => {
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.bkpt(0).toU32());
|
||||
},
|
||||
.armeb => {
|
||||
mem.writeIntBig(u32, try self.code.addManyAsArray(4), Instruction.bkpt(0).toU32());
|
||||
},
|
||||
else => return self.fail(src, "TODO implement @breakpoint() for {}", .{self.target.cpu.arch}),
|
||||
}
|
||||
}
|
||||
return .none;
|
||||
}
|
||||
|
||||
@@ -2373,6 +2379,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
.riscv64 => @import("codegen/riscv64.zig"),
|
||||
.spu_2 => @import("codegen/spu-mk2.zig"),
|
||||
.arm => @import("codegen/arm.zig"),
|
||||
.armeb => @import("codegen/arm.zig"),
|
||||
else => struct {
|
||||
pub const Register = enum {
|
||||
dummy,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const std = @import("std");
|
||||
const DW = std.dwarf;
|
||||
const testing = std.testing;
|
||||
|
||||
/// The condition field specifies the flags neccessary for an
|
||||
@@ -93,6 +94,18 @@ pub const Register = enum(u5) {
|
||||
pub fn id(self: Register) u4 {
|
||||
return @truncate(u4, @enumToInt(self));
|
||||
}
|
||||
|
||||
/// Returns the index into `callee_preserved_regs`.
|
||||
pub fn allocIndex(self: Register) ?u4 {
|
||||
inline for (callee_preserved_regs) |cpreg, i| {
|
||||
if (self.id() == cpreg.id()) return i;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn dwarfLocOp(self: Register) u8 {
|
||||
return @as(u8, self.id()) + DW.OP_reg0;
|
||||
}
|
||||
};
|
||||
|
||||
test "Register.id" {
|
||||
@@ -149,6 +162,12 @@ pub const Instruction = union(enum) {
|
||||
fixed: u4 = 0b1111,
|
||||
cond: u4,
|
||||
},
|
||||
Breakpoint: packed struct {
|
||||
imm4: u4,
|
||||
fixed_1: u4 = 0b0111,
|
||||
imm12: u12,
|
||||
fixed_2_and_cond: u12 = 0b1110_0001_0010,
|
||||
},
|
||||
|
||||
/// Represents the possible operations which can be performed by a
|
||||
/// DataProcessing instruction
|
||||
@@ -326,6 +345,7 @@ pub const Instruction = union(enum) {
|
||||
.Branch => |v| @bitCast(u32, v),
|
||||
.BranchExchange => |v| @bitCast(u32, v),
|
||||
.SoftwareInterrupt => |v| @bitCast(u32, v),
|
||||
.Breakpoint => |v| @intCast(u32, v.imm4) | (@intCast(u32, v.fixed_1) << 4) | (@intCast(u32, v.imm12) << 8) | (@intCast(u32, v.fixed_2_and_cond) << 20),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -408,6 +428,15 @@ pub const Instruction = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
fn breakpoint(imm: u16) Instruction {
|
||||
return Instruction{
|
||||
.Breakpoint = .{
|
||||
.imm12 = @truncate(u12, imm >> 4),
|
||||
.imm4 = @truncate(u4, imm),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Public functions replicating assembler syntax as closely as
|
||||
// possible
|
||||
|
||||
@@ -512,6 +541,12 @@ pub const Instruction = union(enum) {
|
||||
pub fn swi(cond: Condition, comment: u24) Instruction {
|
||||
return softwareInterrupt(cond, comment);
|
||||
}
|
||||
|
||||
// Breakpoint
|
||||
|
||||
pub fn bkpt(imm: u16) Instruction {
|
||||
return breakpoint(imm);
|
||||
}
|
||||
};
|
||||
|
||||
test "serialize instructions" {
|
||||
@@ -557,6 +592,10 @@ test "serialize instructions" {
|
||||
.inst = Instruction.swi(.al, 0),
|
||||
.expected = 0b1110_1111_0000_0000_0000_0000_0000_0000,
|
||||
},
|
||||
.{ // bkpt #42
|
||||
.inst = Instruction.bkpt(42),
|
||||
.expected = 0b1110_0001_0010_000000000010_0111_1010,
|
||||
},
|
||||
};
|
||||
|
||||
for (testcases) |case| {
|
||||
|
||||
Reference in New Issue
Block a user