| ... | ... | @@ -2238,10 +2238,16 @@ fn airFence(self: *Self) !void { |
| 2238 | 2238 | |
| 2239 | 2239 | fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2240 | 2240 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 2241 | | const fn_ty = self.air.typeOf(pl_op.operand); |
| 2242 | 2241 | const callee = pl_op.operand; |
| 2243 | 2242 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 2244 | 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 | 2252 | var info = try self.resolveCallingConventionValues(fn_ty); |
| 2247 | 2253 | defer info.deinit(self); |
| ... | ... | @@ -2310,39 +2316,42 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2310 | 2316 | unreachable; |
| 2311 | 2317 | |
| 2312 | 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 | 2319 | } else if (func_value.castTag(.extern_fn)) |_| { |
| 2340 | 2320 | return self.fail("TODO implement calling extern functions", .{}); |
| 2341 | 2321 | } else { |
| 2342 | 2322 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| 2343 | 2323 | } |
| 2344 | 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 | 2356 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 2348 | 2357 | unreachable; // unsupported architecture for MachO |