| ... | @@ -2056,7 +2056,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2056,7 +2056,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2056 | return self.fail("TODO implement calling bitcasted functions", .{}); | 2056 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| 2057 | } | 2057 | } |
| 2058 | } else { | 2058 | } else { |
| 2059 | return self.fail("TODO implement calling runtime known function pointer", .{}); | 2059 | assert(ty.zigTypeTag() == .Pointer); |
| | 2060 | const mcv = try self.resolveInst(callee); |
| | 2061 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); |
| 2060 | } | 2062 | } |
| 2061 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { | 2063 | } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| 2062 | for (info.args) |mc_arg, arg_i| { | 2064 | for (info.args) |mc_arg, arg_i| { |
| ... | @@ -2099,7 +2101,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2099,7 +2101,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2099 | const func = func_payload.data; | 2101 | const func = func_payload.data; |
| 2100 | // TODO I'm hacking my way through here by repurposing .memory for storing | 2102 | // TODO I'm hacking my way through here by repurposing .memory for storing |
| 2101 | // index to the GOT target symbol index. | 2103 | // index to the GOT target symbol index. |
| 2102 | try self.genSetReg(Type.initTag(.u64), .rax, .{ | 2104 | try self.genSetReg(Type.initTag(.usize), .rax, .{ |
| 2103 | .memory = func.owner_decl.link.macho.local_sym_index, | 2105 | .memory = func.owner_decl.link.macho.local_sym_index, |
| 2104 | }); | 2106 | }); |
| 2105 | // callq *%rax | 2107 | // callq *%rax |
| ... | @@ -2123,7 +2125,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2123,7 +2125,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2123 | return self.fail("TODO implement calling bitcasted functions", .{}); | 2125 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| 2124 | } | 2126 | } |
| 2125 | } else { | 2127 | } else { |
| 2126 | return self.fail("TODO implement calling runtime known function pointer", .{}); | 2128 | assert(ty.zigTypeTag() == .Pointer); |
| | 2129 | const mcv = try self.resolveInst(callee); |
| | 2130 | try self.genSetReg(Type.initTag(.usize), .rax, mcv); |
| 2127 | } | 2131 | } |
| 2128 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { | 2132 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 2129 | for (info.args) |mc_arg, arg_i| { | 2133 | for (info.args) |mc_arg, arg_i| { |
| ... | @@ -2241,12 +2245,19 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2241,12 +2245,19 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2241 | | 2245 | |
| 2242 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | 2246 | fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 2243 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 2247 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2244 | if (self.liveness.isUnused(inst)) | 2248 | |
| | 2249 | if (self.liveness.isUnused(inst)) { |
| 2245 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); | 2250 | return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none }); |
| | 2251 | } |
| | 2252 | |
| 2246 | const ty = self.air.typeOf(bin_op.lhs); | 2253 | const ty = self.air.typeOf(bin_op.lhs); |
| 2247 | assert(ty.eql(self.air.typeOf(bin_op.rhs))); | 2254 | const signedness: std.builtin.Signedness = blk: { |
| 2248 | if (ty.zigTypeTag() == .ErrorSet) | 2255 | // For non-int types, we treat the values as unsigned |
| 2249 | return self.fail("TODO implement cmp for errors", .{}); | 2256 | if (ty.zigTypeTag() != .Int) break :blk .unsigned; |
| | 2257 | |
| | 2258 | // Otherwise, we take the signedness of the actual int |
| | 2259 | break :blk ty.intInfo(self.target.*).signedness; |
| | 2260 | }; |
| 2250 | | 2261 | |
| 2251 | const lhs = try self.resolveInst(bin_op.lhs); | 2262 | const lhs = try self.resolveInst(bin_op.lhs); |
| 2252 | const rhs = try self.resolveInst(bin_op.rhs); | 2263 | const rhs = try self.resolveInst(bin_op.rhs); |
| ... | @@ -2262,9 +2273,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { | ... | @@ -2262,9 +2273,9 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { |
| 2262 | const src_mcv = try self.limitImmediateType(bin_op.rhs, i32); | 2273 | const src_mcv = try self.limitImmediateType(bin_op.rhs, i32); |
| 2263 | | 2274 | |
| 2264 | try self.genBinMathOpMir(.cmp, ty, dst_mcv, src_mcv); | 2275 | try self.genBinMathOpMir(.cmp, ty, dst_mcv, src_mcv); |
| 2265 | break :result switch (ty.isSignedInt()) { | 2276 | break :result switch (signedness) { |
| 2266 | true => MCValue{ .compare_flags_signed = op }, | 2277 | .signed => MCValue{ .compare_flags_signed = op }, |
| 2267 | false => MCValue{ .compare_flags_unsigned = op }, | 2278 | .unsigned => MCValue{ .compare_flags_unsigned = op }, |
| 2268 | }; | 2279 | }; |
| 2269 | }; | 2280 | }; |
| 2270 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | 2281 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |