diff --git a/src/codegen.zig b/src/codegen.zig index 6962dcf8e4..6a7b67aee2 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -2114,6 +2114,47 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { return MCValue.none; } }, + .aarch64 => { + for (inst.inputs) |input, i| { + if (input.len < 3 or input[0] != '{' or input[input.len - 1] != '}') { + return self.fail(inst.base.src, "unrecognized asm input constraint: '{}'", .{input}); + } + const reg_name = input[1 .. input.len - 1]; + const reg = parseRegName(reg_name) orelse + return self.fail(inst.base.src, "unrecognized register: '{}'", .{reg_name}); + const arg = try self.resolveInst(inst.args[i]); + try self.genSetReg(inst.base.src, reg, arg); + } + + // TODO move this to lib/std/{elf, macho}.zig, etc. + const is_syscall_inst = switch (self.bin_file.tag) { + .macho => mem.eql(u8, inst.asm_source, "svc #0x80"), + .elf => mem.eql(u8, inst.asm_source, "svc #0"), + else => |tag| return self.fail(inst.base.src, "TODO implement aarch64 support for other syscall instructions for file format: '{}'", .{tag}), + }; + if (is_syscall_inst) { + const imm16: u16 = switch (self.bin_file.tag) { + .macho => 0x80, + .elf => 0, + else => unreachable, + }; + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.svc(imm16).toU32()); + } else { + return self.fail(inst.base.src, "TODO implement support for more aarch64 assembly instructions", .{}); + } + + if (inst.output) |output| { + if (output.len < 4 or output[0] != '=' or output[1] != '{' or output[output.len - 1] != '}') { + return self.fail(inst.base.src, "unrecognized asm output constraint: '{}'", .{output}); + } + const reg_name = output[2 .. output.len - 1]; + const reg = parseRegName(reg_name) orelse + return self.fail(inst.base.src, "unrecognized register: '{}'", .{reg_name}); + return MCValue{ .register = reg }; + } else { + return MCValue.none; + } + }, .riscv64 => { for (inst.inputs) |input, i| { if (input.len < 3 or input[0] != '{' or input[input.len - 1] != '}') { diff --git a/src/codegen/aarch64.zig b/src/codegen/aarch64.zig index 2ca9a71292..97491cdfd6 100644 --- a/src/codegen/aarch64.zig +++ b/src/codegen/aarch64.zig @@ -59,6 +59,8 @@ pub const callee_preserved_regs = [_]Register{ .x19, .x20, .x21, .x22, .x23, .x24, .x25, .x26, .x27, .x28, }; +pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 }; +pub const c_abi_int_return_regs = [_]Register{ .x0, .x1 }; test "Register.id" { testing.expectEqual(@as(u5, 0), Register.x0.id()); @@ -215,7 +217,7 @@ pub const Instruction = union(enum) { // Supervisor Call - fn svc(imm16: u16) Instruction { + pub fn svc(imm16: u16) Instruction { return supervisorCall(imm16); } };