authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-31 15:07:48+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-31 15:07:48+01:00
log5ec9f39dfe90890adef4dca1b48bf71176fe99f1
tree0735d4db200152217bf6d421ec2cfbc5939a09b9
parente7ac05e882fa4290af4a41e9cae63105bcacb283

stage2: implement isNull() and isNonNull()


1 files changed, 33 insertions(+), 26 deletions(-)

src/arch/x86_64/CodeGen.zig+33-26
......@@ -2371,31 +2371,30 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
23712371 return self.finishAir(inst, .unreach, .{ pl_op.operand, .none, .none });
23722372}
23732373
2374fn isNull(self: *Self, operand: MCValue) !MCValue {
2375 _ = operand;
2376 // Here you can specialize this instruction if it makes sense to, otherwise the default
2377 // will call isNonNull and invert the result.
2378 return self.fail("TODO call isNonNull and invert the result", .{});
2374fn isNull(self: *Self, ty: Type, operand: MCValue) !MCValue {
2375 try self.genBinMathOpMir(.cmp, ty, operand, MCValue{ .immediate = 0 });
2376 return MCValue{ .compare_flags_unsigned = .eq };
23792377}
23802378
2381fn isNonNull(self: *Self, operand: MCValue) !MCValue {
2382 _ = operand;
2383 // Here you can specialize this instruction if it makes sense to, otherwise the default
2384 // will call isNull and invert the result.
2385 return self.fail("TODO call isNull and invert the result", .{});
2379fn isNonNull(self: *Self, ty: Type, operand: MCValue) !MCValue {
2380 const is_null_res = try self.isNull(ty, operand);
2381 assert(is_null_res.compare_flags_unsigned == .eq);
2382 return MCValue{ .compare_flags_unsigned = .neq };
23862383}
23872384
2388fn isErr(self: *Self, operand: MCValue) !MCValue {
2385fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
2386 _ = ty;
23892387 _ = operand;
23902388 // Here you can specialize this instruction if it makes sense to, otherwise the default
2391 // will call isNonNull and invert the result.
2389 // will call isNonErr and invert the result.
23922390 return self.fail("TODO call isNonErr and invert the result", .{});
23932391}
23942392
2395fn isNonErr(self: *Self, operand: MCValue) !MCValue {
2393fn isNonErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
2394 _ = ty;
23962395 _ = operand;
23972396 // Here you can specialize this instruction if it makes sense to, otherwise the default
2398 // will call isNull and invert the result.
2397 // will call isErr and invert the result.
23992398 return self.fail("TODO call isErr and invert the result", .{});
24002399}
24012400
......@@ -2403,7 +2402,8 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
24032402 const un_op = self.air.instructions.items(.data)[inst].un_op;
24042403 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
24052404 const operand = try self.resolveInst(un_op);
2406 break :result try self.isNull(operand);
2405 const ty = self.air.typeOf(un_op);
2406 break :result try self.isNull(ty, operand);
24072407 };
24082408 return self.finishAir(inst, result, .{ un_op, .none, .none });
24092409}
......@@ -2420,8 +2420,9 @@ fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
24202420 break :blk try self.allocRegOrMem(inst, true);
24212421 }
24222422 };
2423 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
2424 break :result try self.isNull(operand);
2423 const ptr_ty = self.air.typeOf(un_op);
2424 try self.load(operand, operand_ptr, ptr_ty);
2425 break :result try self.isNull(ptr_ty.elemType(), operand);
24252426 };
24262427 return self.finishAir(inst, result, .{ un_op, .none, .none });
24272428}
......@@ -2430,7 +2431,8 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
24302431 const un_op = self.air.instructions.items(.data)[inst].un_op;
24312432 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
24322433 const operand = try self.resolveInst(un_op);
2433 break :result try self.isNonNull(operand);
2434 const ty = self.air.typeOf(un_op);
2435 break :result try self.isNonNull(ty, operand);
24342436 };
24352437 return self.finishAir(inst, result, .{ un_op, .none, .none });
24362438}
......@@ -2447,8 +2449,9 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
24472449 break :blk try self.allocRegOrMem(inst, true);
24482450 }
24492451 };
2450 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
2451 break :result try self.isNonNull(operand);
2452 const ptr_ty = self.air.typeOf(un_op);
2453 try self.load(operand, operand_ptr, ptr_ty);
2454 break :result try self.isNonNull(ptr_ty.elemType(), operand);
24522455 };
24532456 return self.finishAir(inst, result, .{ un_op, .none, .none });
24542457}
......@@ -2457,7 +2460,8 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
24572460 const un_op = self.air.instructions.items(.data)[inst].un_op;
24582461 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
24592462 const operand = try self.resolveInst(un_op);
2460 break :result try self.isErr(operand);
2463 const ty = self.air.typeOf(un_op);
2464 break :result try self.isErr(ty, operand);
24612465 };
24622466 return self.finishAir(inst, result, .{ un_op, .none, .none });
24632467}
......@@ -2474,8 +2478,9 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
24742478 break :blk try self.allocRegOrMem(inst, true);
24752479 }
24762480 };
2477 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
2478 break :result try self.isErr(operand);
2481 const ptr_ty = self.air.typeOf(un_op);
2482 try self.load(operand, operand_ptr, ptr_ty);
2483 break :result try self.isErr(ptr_ty.elemType(), operand);
24792484 };
24802485 return self.finishAir(inst, result, .{ un_op, .none, .none });
24812486}
......@@ -2484,7 +2489,8 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
24842489 const un_op = self.air.instructions.items(.data)[inst].un_op;
24852490 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
24862491 const operand = try self.resolveInst(un_op);
2487 break :result try self.isNonErr(operand);
2492 const ty = self.air.typeOf(un_op);
2493 break :result try self.isNonErr(ty, operand);
24882494 };
24892495 return self.finishAir(inst, result, .{ un_op, .none, .none });
24902496}
......@@ -2501,8 +2507,9 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
25012507 break :blk try self.allocRegOrMem(inst, true);
25022508 }
25032509 };
2504 try self.load(operand, operand_ptr, self.air.typeOf(un_op));
2505 break :result try self.isNonErr(operand);
2510 const ptr_ty = self.air.typeOf(un_op);
2511 try self.load(operand, operand_ptr, ptr_ty);
2512 break :result try self.isNonErr(ptr_ty.elemType(), operand);
25062513 };
25072514 return self.finishAir(inst, result, .{ un_op, .none, .none });
25082515}