stage2: Implement genBreakpoint for ARM

This commit is contained in:
joachimschmidt557
2020-08-20 23:09:46 +02:00
parent f31cee5393
commit 1c53c07053
2 changed files with 49 additions and 3 deletions

View File

@@ -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,

View File

@@ -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| {