aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-10-31 23:52:48 +0100
committerJakub Konka <kubkon@jakubkonka.com>2020-11-11 14:34:53 +0100
commitd542e8870688eeaa46f84efe892c9ab5d51d09c9 (patch)
tree261de0e7279f9300bb1224eb531d99629606dbce /src/codegen.zig
parent5ad501c00b59205154caeec95685351ee613ea5e (diff)
downloadzig-d542e8870688eeaa46f84efe892c9ab5d51d09c9.tar.gz
zig-d542e8870688eeaa46f84efe892c9ab5d51d09c9.zip
Implement genAsm on aarch64
Add remaining PCS info: param and return registers in procedure calls.
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig41
1 files changed, 41 insertions, 0 deletions
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] != '}') {