Commit 1c53c07053
Changed files (2)
src-self-hosted
codegen
src-self-hosted/codegen/arm.zig
@@ -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| {
src-self-hosted/codegen.zig
@@ -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,