| ... | ... | @@ -564,11 +564,11 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 564 | 564 | .cmp_gt => try self.airCmp(inst, .gt), |
| 565 | 565 | .cmp_neq => try self.airCmp(inst, .neq), |
| 566 | 566 | |
| 567 | | .bool_and => try self.airBoolOp(inst), |
| 568 | | .bool_or => try self.airBoolOp(inst), |
| 569 | | .bit_and => try self.airBitAnd(inst), |
| 570 | | .bit_or => try self.airBitOr(inst), |
| 571 | | .xor => try self.airXor(inst), |
| 567 | .bool_and => try self.airBinOp(inst), |
| 568 | .bool_or => try self.airBinOp(inst), |
| 569 | .bit_and => try self.airBinOp(inst), |
| 570 | .bit_or => try self.airBinOp(inst), |
| 571 | .xor => try self.airBinOp(inst), |
| 572 | 572 | .shr, .shr_exact => try self.airShr(inst), |
| 573 | 573 | |
| 574 | 574 | .alloc => try self.airAlloc(inst), |
| ... | ... | @@ -1110,9 +1110,19 @@ fn binOpRegister( |
| 1110 | 1110 | if (!rhs_is_register) try self.genSetReg(rhs_ty, rhs_reg, rhs); |
| 1111 | 1111 | |
| 1112 | 1112 | const mir_tag: Mir.Inst.Tag = switch (tag) { |
| 1113 | | .add, .ptr_add => .add_shifted_register, |
| 1114 | | .sub, .ptr_sub => .sub_shifted_register, |
| 1113 | .add, |
| 1114 | .ptr_add, |
| 1115 | => .add_shifted_register, |
| 1116 | .sub, |
| 1117 | .ptr_sub, |
| 1118 | => .sub_shifted_register, |
| 1115 | 1119 | .mul => .mul, |
| 1120 | .bit_and, |
| 1121 | .bool_and, |
| 1122 | => .and_shifted_register, |
| 1123 | .bit_or, |
| 1124 | .bool_or, |
| 1125 | => .orr_shifted_register, |
| 1116 | 1126 | .xor => .eor_shifted_register, |
| 1117 | 1127 | else => unreachable, |
| 1118 | 1128 | }; |
| ... | ... | @@ -1133,7 +1143,12 @@ fn binOpRegister( |
| 1133 | 1143 | .rn = lhs_reg, |
| 1134 | 1144 | .rm = rhs_reg, |
| 1135 | 1145 | } }, |
| 1136 | | .xor => .{ .rrr_imm6_logical_shift = .{ |
| 1146 | .bit_and, |
| 1147 | .bool_and, |
| 1148 | .bit_or, |
| 1149 | .bool_or, |
| 1150 | .xor, |
| 1151 | => .{ .rrr_imm6_logical_shift = .{ |
| 1137 | 1152 | .rd = dest_reg, |
| 1138 | 1153 | .rn = lhs_reg, |
| 1139 | 1154 | .rm = rhs_reg, |
| ... | ... | @@ -1311,7 +1326,7 @@ fn binOp( |
| 1311 | 1326 | // lowered to a << 1 |
| 1312 | 1327 | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 1313 | 1328 | } else { |
| 1314 | | return self.fail("TODO ARM binary operations on integers > u32/i32", .{}); |
| 1329 | return self.fail("TODO binary operations on int with bits > 64", .{}); |
| 1315 | 1330 | } |
| 1316 | 1331 | }, |
| 1317 | 1332 | else => unreachable, |
| ... | ... | @@ -1324,7 +1339,29 @@ fn binOp( |
| 1324 | 1339 | => { |
| 1325 | 1340 | switch (lhs_ty.zigTypeTag()) { |
| 1326 | 1341 | .Vector => return self.fail("TODO binary operations on vectors", .{}), |
| 1327 | | .Int => return self.fail("TODO binary operations on integers", .{}), |
| 1342 | .Int => { |
| 1343 | assert(lhs_ty.eql(rhs_ty)); |
| 1344 | const int_info = lhs_ty.intInfo(self.target.*); |
| 1345 | if (int_info.bits <= 64) { |
| 1346 | // TODO implement bitwise operations with immediates |
| 1347 | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 1348 | } else { |
| 1349 | return self.fail("TODO binary operations on int with bits > 64", .{}); |
| 1350 | } |
| 1351 | }, |
| 1352 | else => unreachable, |
| 1353 | } |
| 1354 | }, |
| 1355 | .bool_and, |
| 1356 | .bool_or, |
| 1357 | => { |
| 1358 | switch (lhs_ty.zigTypeTag()) { |
| 1359 | .Bool => { |
| 1360 | assert(lhs != .immediate); // should have been handled by Sema |
| 1361 | assert(rhs != .immediate); // should have been handled by Sema |
| 1362 | |
| 1363 | return try self.binOpRegister(tag, maybe_inst, lhs, rhs, lhs_ty, rhs_ty); |
| 1364 | }, |
| 1328 | 1365 | else => unreachable, |
| 1329 | 1366 | } |
| 1330 | 1367 | }, |
| ... | ... | @@ -1444,24 +1481,6 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void { |
| 1444 | 1481 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1445 | 1482 | } |
| 1446 | 1483 | |
| 1447 | | fn airBitAnd(self: *Self, inst: Air.Inst.Index) !void { |
| 1448 | | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1449 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement bitwise and for {}", .{self.target.cpu.arch}); |
| 1450 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1451 | | } |
| 1452 | | |
| 1453 | | fn airBitOr(self: *Self, inst: Air.Inst.Index) !void { |
| 1454 | | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1455 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement bitwise or for {}", .{self.target.cpu.arch}); |
| 1456 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1457 | | } |
| 1458 | | |
| 1459 | | fn airXor(self: *Self, inst: Air.Inst.Index) !void { |
| 1460 | | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1461 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement xor for {}", .{self.target.cpu.arch}); |
| 1462 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 1463 | | } |
| 1464 | | |
| 1465 | 1484 | fn airShl(self: *Self, inst: Air.Inst.Index) !void { |
| 1466 | 1485 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 1467 | 1486 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement shl for {}", .{self.target.cpu.arch}); |
| ... | ... | @@ -2969,15 +2988,6 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void { |
| 2969 | 2988 | return self.finishAir(inst, .dead, .{ branch.operand, .none, .none }); |
| 2970 | 2989 | } |
| 2971 | 2990 | |
| 2972 | | fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void { |
| 2973 | | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2974 | | const air_tags = self.air.instructions.items(.tag); |
| 2975 | | _ = air_tags; |
| 2976 | | |
| 2977 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement boolean operations for {}", .{self.target.cpu.arch}); |
| 2978 | | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2979 | | } |
| 2980 | | |
| 2981 | 2991 | fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void { |
| 2982 | 2992 | const block_data = self.blocks.getPtr(block).?; |
| 2983 | 2993 | |