| ... | @@ -2238,10 +2238,16 @@ fn airFence(self: *Self) !void { | ... | @@ -2238,10 +2238,16 @@ fn airFence(self: *Self) !void { |
| 2238 | | 2238 | |
| 2239 | fn airCall(self: *Self, inst: Air.Inst.Index) !void { | 2239 | fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2240 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 2240 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 2241 | const fn_ty = self.air.typeOf(pl_op.operand); | | |
| 2242 | const callee = pl_op.operand; | 2241 | const callee = pl_op.operand; |
| 2243 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 2242 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 2244 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]); | 2243 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]); |
| | 2244 | const ty = self.air.typeOf(callee); |
| | 2245 | |
| | 2246 | const fn_ty = switch (ty.zigTypeTag()) { |
| | 2247 | .Fn => ty, |
| | 2248 | .Pointer => ty.childType(), |
| | 2249 | else => unreachable, |
| | 2250 | }; |
| 2245 | | 2251 | |
| 2246 | var info = try self.resolveCallingConventionValues(fn_ty); | 2252 | var info = try self.resolveCallingConventionValues(fn_ty); |
| 2247 | defer info.deinit(self); | 2253 | defer info.deinit(self); |
| ... | @@ -2310,39 +2316,42 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2310,39 +2316,42 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2310 | unreachable; | 2316 | unreachable; |
| 2311 | | 2317 | |
| 2312 | try self.genSetReg(Type.initTag(.usize), .lr, .{ .memory = got_addr }); | 2318 | try self.genSetReg(Type.initTag(.usize), .lr, .{ .memory = got_addr }); |
| 2313 | | | |
| 2314 | // TODO: add Instruction.supportedOn | | |
| 2315 | // function for ARM | | |
| 2316 | if (Target.arm.featureSetHas(self.target.cpu.features, .has_v5t)) { | | |
| 2317 | _ = try self.addInst(.{ | | |
| 2318 | .tag = .blx, | | |
| 2319 | .cond = .al, | | |
| 2320 | .data = .{ .reg = .lr }, | | |
| 2321 | }); | | |
| 2322 | } else { | | |
| 2323 | return self.fail("TODO fix blx emulatio for ARM <v5", .{}); | | |
| 2324 | // _ = try self.addInst(.{ | | |
| 2325 | // .tag = .mov, | | |
| 2326 | // .cond = .al, | | |
| 2327 | // .data = .{ .rr_op = .{ | | |
| 2328 | // .rd = .lr, | | |
| 2329 | // .rn = .r0, | | |
| 2330 | // .op = Instruction.Operand.reg(.pc, Instruction.Operand.Shift.none), | | |
| 2331 | // } }, | | |
| 2332 | // }); | | |
| 2333 | // _ = try self.addInst(.{ | | |
| 2334 | // .tag = .bx, | | |
| 2335 | // .cond = .al, | | |
| 2336 | // .data = .{ .reg = .lr }, | | |
| 2337 | // }); | | |
| 2338 | } | | |
| 2339 | } else if (func_value.castTag(.extern_fn)) |_| { | 2319 | } else if (func_value.castTag(.extern_fn)) |_| { |
| 2340 | return self.fail("TODO implement calling extern functions", .{}); | 2320 | return self.fail("TODO implement calling extern functions", .{}); |
| 2341 | } else { | 2321 | } else { |
| 2342 | return self.fail("TODO implement calling bitcasted functions", .{}); | 2322 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| 2343 | } | 2323 | } |
| 2344 | } else { | 2324 | } else { |
| 2345 | return self.fail("TODO implement calling runtime known function pointer", .{}); | 2325 | assert(ty.zigTypeTag() == .Pointer); |
| | 2326 | const mcv = try self.resolveInst(callee); |
| | 2327 | |
| | 2328 | try self.genSetReg(Type.initTag(.usize), .lr, mcv); |
| | 2329 | } |
| | 2330 | |
| | 2331 | // TODO: add Instruction.supportedOn |
| | 2332 | // function for ARM |
| | 2333 | if (Target.arm.featureSetHas(self.target.cpu.features, .has_v5t)) { |
| | 2334 | _ = try self.addInst(.{ |
| | 2335 | .tag = .blx, |
| | 2336 | .cond = .al, |
| | 2337 | .data = .{ .reg = .lr }, |
| | 2338 | }); |
| | 2339 | } else { |
| | 2340 | return self.fail("TODO fix blx emulation for ARM <v5", .{}); |
| | 2341 | // _ = try self.addInst(.{ |
| | 2342 | // .tag = .mov, |
| | 2343 | // .cond = .al, |
| | 2344 | // .data = .{ .rr_op = .{ |
| | 2345 | // .rd = .lr, |
| | 2346 | // .rn = .r0, |
| | 2347 | // .op = Instruction.Operand.reg(.pc, Instruction.Operand.Shift.none), |
| | 2348 | // } }, |
| | 2349 | // }); |
| | 2350 | // _ = try self.addInst(.{ |
| | 2351 | // .tag = .bx, |
| | 2352 | // .cond = .al, |
| | 2353 | // .data = .{ .reg = .lr }, |
| | 2354 | // }); |
| 2346 | } | 2355 | } |
| 2347 | } else if (self.bin_file.cast(link.File.MachO)) |_| { | 2356 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 2348 | unreachable; // unsupported architecture for MachO | 2357 | unreachable; // unsupported architecture for MachO |