| author | |
| committer | |
| log | 1c53c070535c519cbdc39a2094a24723f5245799 |
| tree | 3eda4394f30e67286e229c43d956e1dcb2cd9585 |
| parent | f31cee5393bbfd29883a7b253cd518db145b8b19 |
2 files changed, 49 insertions(+), 3 deletions(-)
src-self-hosted/codegen.zig+10-3| ... | @@ -76,8 +76,8 @@ pub fn generateSymbol( | ... | @@ -76,8 +76,8 @@ pub fn generateSymbol( |
| 76 | switch (bin_file.options.target.cpu.arch) { | 76 | switch (bin_file.options.target.cpu.arch) { |
| 77 | .wasm32 => unreachable, // has its own code path | 77 | .wasm32 => unreachable, // has its own code path |
| 78 | .wasm64 => unreachable, // has its own code path | 78 | .wasm64 => unreachable, // has its own code path |
| 79 | //.arm => return Function(.arm).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), | 79 | .arm => return Function(.arm).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), |
| 80 | //.armeb => return Function(.armeb).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), | 80 | .armeb => return Function(.armeb).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), |
| 81 | //.aarch64 => return Function(.aarch64).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), | 81 | //.aarch64 => return Function(.aarch64).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), |
| 82 | //.aarch64_be => return Function(.aarch64_be).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), | 82 | //.aarch64_be => return Function(.aarch64_be).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), |
| 83 | //.aarch64_32 => return Function(.aarch64_32).generateSymbol(bin_file, src, typed_value, code, dbg_line, dbg_info, dbg_info_type_relocs), | 83 | //.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 { | ... | @@ -1270,8 +1270,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1270 | var instr = Instruction{ .condition = .always, .input0 = .zero, .input1 = .zero, .modify_flags = false, .output = .discard, .command = .undefined1 }; | 1270 | var instr = Instruction{ .condition = .always, .input0 = .zero, .input1 = .zero, .modify_flags = false, .output = .discard, .command = .undefined1 }; |
| 1271 | mem.writeIntLittle(u16, self.code.items[self.code.items.len - 2 ..][0..2], @bitCast(u16, instr)); | 1271 | mem.writeIntLittle(u16, self.code.items[self.code.items.len - 2 ..][0..2], @bitCast(u16, instr)); |
| 1272 | }, | 1272 | }, |
| 1273 | .arm => { | ||
| 1274 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.bkpt(0).toU32()); | ||
| 1275 | }, | ||
| 1276 | .armeb => { | ||
| 1277 | mem.writeIntBig(u32, try self.code.addManyAsArray(4), Instruction.bkpt(0).toU32()); | ||
| 1278 | }, | ||
| 1273 | else => return self.fail(src, "TODO implement @breakpoint() for {}", .{self.target.cpu.arch}), | 1279 | else => return self.fail(src, "TODO implement @breakpoint() for {}", .{self.target.cpu.arch}), |
| 1274 | } | 1280 | } |
| 1275 | return .none; | 1281 | return .none; |
| 1276 | } | 1282 | } |
| 1277 | 1283 | ||
| ... | @@ -2373,6 +2379,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2373,6 +2379,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2373 | .riscv64 => @import("codegen/riscv64.zig"), | 2379 | .riscv64 => @import("codegen/riscv64.zig"), |
| 2374 | .spu_2 => @import("codegen/spu-mk2.zig"), | 2380 | .spu_2 => @import("codegen/spu-mk2.zig"), |
| 2375 | .arm => @import("codegen/arm.zig"), | 2381 | .arm => @import("codegen/arm.zig"), |
| 2382 | .armeb => @import("codegen/arm.zig"), | ||
| 2376 | else => struct { | 2383 | else => struct { |
| 2377 | pub const Register = enum { | 2384 | pub const Register = enum { |
| 2378 | dummy, | 2385 | dummy, |
src-self-hosted/codegen/arm.zig+39| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const DW = std.dwarf; | ||
| 2 | const testing = std.testing; | 3 | const testing = std.testing; |
| 3 | 4 | ||
| 4 | /// The condition field specifies the flags neccessary for an | 5 | /// The condition field specifies the flags neccessary for an |
| ... | @@ -93,6 +94,18 @@ pub const Register = enum(u5) { | ... | @@ -93,6 +94,18 @@ pub const Register = enum(u5) { |
| 93 | pub fn id(self: Register) u4 { | 94 | pub fn id(self: Register) u4 { |
| 94 | return @truncate(u4, @enumToInt(self)); | 95 | return @truncate(u4, @enumToInt(self)); |
| 95 | } | 96 | } |
| 97 | |||
| 98 | /// Returns the index into `callee_preserved_regs`. | ||
| 99 | pub fn allocIndex(self: Register) ?u4 { | ||
| 100 | inline for (callee_preserved_regs) |cpreg, i| { | ||
| 101 | if (self.id() == cpreg.id()) return i; | ||
| 102 | } | ||
| 103 | return null; | ||
| 104 | } | ||
| 105 | |||
| 106 | pub fn dwarfLocOp(self: Register) u8 { | ||
| 107 | return @as(u8, self.id()) + DW.OP_reg0; | ||
| 108 | } | ||
| 96 | }; | 109 | }; |
| 97 | 110 | ||
| 98 | test "Register.id" { | 111 | test "Register.id" { |
| ... | @@ -149,6 +162,12 @@ pub const Instruction = union(enum) { | ... | @@ -149,6 +162,12 @@ pub const Instruction = union(enum) { |
| 149 | fixed: u4 = 0b1111, | 162 | fixed: u4 = 0b1111, |
| 150 | cond: u4, | 163 | cond: u4, |
| 151 | }, | 164 | }, |
| 165 | Breakpoint: packed struct { | ||
| 166 | imm4: u4, | ||
| 167 | fixed_1: u4 = 0b0111, | ||
| 168 | imm12: u12, | ||
| 169 | fixed_2_and_cond: u12 = 0b1110_0001_0010, | ||
| 170 | }, | ||
| 152 | 171 | ||
| 153 | /// Represents the possible operations which can be performed by a | 172 | /// Represents the possible operations which can be performed by a |
| 154 | /// DataProcessing instruction | 173 | /// DataProcessing instruction |
| ... | @@ -326,6 +345,7 @@ pub const Instruction = union(enum) { | ... | @@ -326,6 +345,7 @@ pub const Instruction = union(enum) { |
| 326 | .Branch => |v| @bitCast(u32, v), | 345 | .Branch => |v| @bitCast(u32, v), |
| 327 | .BranchExchange => |v| @bitCast(u32, v), | 346 | .BranchExchange => |v| @bitCast(u32, v), |
| 328 | .SoftwareInterrupt => |v| @bitCast(u32, v), | 347 | .SoftwareInterrupt => |v| @bitCast(u32, v), |
| 348 | .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), | ||
| 329 | }; | 349 | }; |
| 330 | } | 350 | } |
| 331 | 351 | ||
| ... | @@ -408,6 +428,15 @@ pub const Instruction = union(enum) { | ... | @@ -408,6 +428,15 @@ pub const Instruction = union(enum) { |
| 408 | }; | 428 | }; |
| 409 | } | 429 | } |
| 410 | 430 | ||
| 431 | fn breakpoint(imm: u16) Instruction { | ||
| 432 | return Instruction{ | ||
| 433 | .Breakpoint = .{ | ||
| 434 | .imm12 = @truncate(u12, imm >> 4), | ||
| 435 | .imm4 = @truncate(u4, imm), | ||
| 436 | }, | ||
| 437 | }; | ||
| 438 | } | ||
| 439 | |||
| 411 | // Public functions replicating assembler syntax as closely as | 440 | // Public functions replicating assembler syntax as closely as |
| 412 | // possible | 441 | // possible |
| 413 | 442 | ||
| ... | @@ -512,6 +541,12 @@ pub const Instruction = union(enum) { | ... | @@ -512,6 +541,12 @@ pub const Instruction = union(enum) { |
| 512 | pub fn swi(cond: Condition, comment: u24) Instruction { | 541 | pub fn swi(cond: Condition, comment: u24) Instruction { |
| 513 | return softwareInterrupt(cond, comment); | 542 | return softwareInterrupt(cond, comment); |
| 514 | } | 543 | } |
| 544 | |||
| 545 | // Breakpoint | ||
| 546 | |||
| 547 | pub fn bkpt(imm: u16) Instruction { | ||
| 548 | return breakpoint(imm); | ||
| 549 | } | ||
| 515 | }; | 550 | }; |
| 516 | 551 | ||
| 517 | test "serialize instructions" { | 552 | test "serialize instructions" { |
| ... | @@ -557,6 +592,10 @@ test "serialize instructions" { | ... | @@ -557,6 +592,10 @@ test "serialize instructions" { |
| 557 | .inst = Instruction.swi(.al, 0), | 592 | .inst = Instruction.swi(.al, 0), |
| 558 | .expected = 0b1110_1111_0000_0000_0000_0000_0000_0000, | 593 | .expected = 0b1110_1111_0000_0000_0000_0000_0000_0000, |
| 559 | }, | 594 | }, |
| 595 | .{ // bkpt #42 | ||
| 596 | .inst = Instruction.bkpt(42), | ||
| 597 | .expected = 0b1110_0001_0010_000000000010_0111_1010, | ||
| 598 | }, | ||
| 560 | }; | 599 | }; |
| 561 | 600 | ||
| 562 | for (testcases) |case| { | 601 | for (testcases) |case| { |