| ... | @@ -196,35 +196,36 @@ const Function = struct { | ... | @@ -196,35 +196,36 @@ const Function = struct { |
| 196 | } | 196 | } |
| 197 | | 197 | |
| 198 | fn genCall(self: *Function, inst: *ir.Inst.Call) !MCValue { | 198 | fn genCall(self: *Function, inst: *ir.Inst.Call) !MCValue { |
| 199 | if (inst.args.func.cast(ir.Inst.Constant)) |func_inst| { | 199 | switch (self.target.cpu.arch) { |
| 200 | if (inst.args.args.len != 0) { | 200 | .x86_64, .i386 => { |
| 201 | return self.fail(inst.base.src, "TODO implement call with more than 0 parameters", .{}); | 201 | if (inst.args.func.cast(ir.Inst.Constant)) |func_inst| { |
| 202 | } | 202 | if (inst.args.args.len != 0) { |
| | 203 | return self.fail(inst.base.src, "TODO implement call with more than 0 parameters", .{}); |
| | 204 | } |
| 203 | | 205 | |
| 204 | if (func_inst.val.cast(Value.Payload.Function)) |func_val| { | 206 | if (func_inst.val.cast(Value.Payload.Function)) |func_val| { |
| 205 | const func = func_val.func; | 207 | const func = func_val.func; |
| 206 | const got = &self.bin_file.program_headers.items[self.bin_file.phdr_got_index.?]; | 208 | const got = &self.bin_file.program_headers.items[self.bin_file.phdr_got_index.?]; |
| 207 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); | 209 | const ptr_bits = self.target.cpu.arch.ptrBitWidth(); |
| 208 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); | 210 | const ptr_bytes: u64 = @divExact(ptr_bits, 8); |
| 209 | const got_addr = @intCast(u32, got.p_vaddr + func.owner_decl.link.offset_table_index * ptr_bytes); | 211 | const got_addr = @intCast(u32, got.p_vaddr + func.owner_decl.link.offset_table_index * ptr_bytes); |
| 210 | // ff 14 25 xx xx xx xx call [addr] | 212 | // ff 14 25 xx xx xx xx call [addr] |
| 211 | try self.code.resize(self.code.items.len + 7); | 213 | try self.code.resize(self.code.items.len + 7); |
| 212 | self.code.items[self.code.items.len - 7 ..][0..3].* = [3]u8{ 0xff, 0x14, 0x25 }; | 214 | self.code.items[self.code.items.len - 7 ..][0..3].* = [3]u8{ 0xff, 0x14, 0x25 }; |
| 213 | mem.writeIntLittle(u32, self.code.items[self.code.items.len - 4 ..][0..4], got_addr); | 215 | mem.writeIntLittle(u32, self.code.items[self.code.items.len - 4 ..][0..4], got_addr); |
| 214 | const return_type = func.fn_type.fnReturnType(); | 216 | const return_type = func.fn_type.fnReturnType(); |
| 215 | switch (return_type.zigTypeTag()) { | 217 | switch (return_type.zigTypeTag()) { |
| 216 | .Void => return MCValue{ .none = {} }, | 218 | .Void => return MCValue{ .none = {} }, |
| 217 | .NoReturn => return MCValue{ .unreach = {} }, | 219 | .NoReturn => return MCValue{ .unreach = {} }, |
| 218 | else => return self.fail(inst.base.src, "TODO implement fn call with non-void return value", .{}), | 220 | else => return self.fail(inst.base.src, "TODO implement fn call with non-void return value", .{}), |
| | 221 | } |
| | 222 | } else { |
| | 223 | return self.fail(inst.base.src, "TODO implement calling weird function values", .{}); |
| | 224 | } |
| | 225 | } else { |
| | 226 | return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); |
| 219 | } | 227 | } |
| 220 | } else { | 228 | }, |
| 221 | return self.fail(inst.base.src, "TODO implement calling weird function values", .{}); | | |
| 222 | } | | |
| 223 | } else { | | |
| 224 | return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); | | |
| 225 | } | | |
| 226 | | | |
| 227 | switch (self.target.cpu.arch) { | | |
| 228 | else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}), | 229 | else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}), |
| 229 | } | 230 | } |
| 230 | } | 231 | } |