authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-12-10 20:44:13+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-12-10 21:11:14+07:00
log57616debf9708e61decba96134f89d2305da055b
tree0242c962898a6ccd83cf8535ad77e510d78c82f8
parentef532ada8ada987a5b66db630b374520d04553d8

stage2: sparc64: Implement airTrunc


1 files changed, 61 insertions(+), 1 deletions(-)

src/arch/sparc64/CodeGen.zig+61-1
......@@ -573,7 +573,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
573573 .fptrunc => @panic("TODO try self.airFptrunc(inst)"),
574574 .fpext => @panic("TODO try self.airFpext(inst)"),
575575 .intcast => try self.airIntCast(inst),
576 .trunc => @panic("TODO try self.airTrunc(inst)"),
576 .trunc => try self.airTrunc(inst),
577577 .bool_to_int => try self.airBoolToInt(inst),
578578 .is_non_null => try self.airIsNonNull(inst),
579579 .is_non_null_ptr => @panic("TODO try self.airIsNonNullPtr(inst)"),
......@@ -2406,6 +2406,19 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
24062406 return self.finishAir(inst, result, .{ un_op, .none, .none });
24072407}
24082408
2409fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2410 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2411 const operand = try self.resolveInst(ty_op.operand);
2412 const operand_ty = self.air.typeOf(ty_op.operand);
2413 const dest_ty = self.air.typeOfIndex(inst);
2414
2415 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else blk: {
2416 break :blk try self.trunc(inst, operand, operand_ty, dest_ty);
2417 };
2418
2419 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
2420}
2421
24092422fn airTry(self: *Self, inst: Air.Inst.Index) !void {
24102423 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
24112424 const extra = self.air.extraData(Air.Try, pl_op.payload);
......@@ -4369,6 +4382,53 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde
43694382 };
43704383}
43714384
4385fn trunc(
4386 self: *Self,
4387 maybe_inst: ?Air.Inst.Index,
4388 operand: MCValue,
4389 operand_ty: Type,
4390 dest_ty: Type,
4391) !MCValue {
4392 const info_a = operand_ty.intInfo(self.target.*);
4393 const info_b = dest_ty.intInfo(self.target.*);
4394
4395 if (info_b.bits <= 64) {
4396 const operand_reg = switch (operand) {
4397 .register => |r| r,
4398 else => operand_reg: {
4399 if (info_a.bits <= 64) {
4400 const reg = try self.copyToTmpRegister(operand_ty, operand);
4401 break :operand_reg reg;
4402 } else {
4403 return self.fail("TODO load least significant word into register", .{});
4404 }
4405 },
4406 };
4407 const lock = self.register_manager.lockReg(operand_reg);
4408 defer if (lock) |reg| self.register_manager.unlockReg(reg);
4409
4410 const dest_reg = if (maybe_inst) |inst| blk: {
4411 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4412
4413 if (operand == .register and self.reuseOperand(inst, ty_op.operand, 0, operand)) {
4414 break :blk operand_reg;
4415 } else {
4416 const reg = try self.register_manager.allocReg(inst, gp);
4417 break :blk reg;
4418 }
4419 } else blk: {
4420 const reg = try self.register_manager.allocReg(null, gp);
4421 break :blk reg;
4422 };
4423
4424 try self.truncRegister(operand_reg, dest_reg, info_b.signedness, info_b.bits);
4425
4426 return MCValue{ .register = dest_reg };
4427 } else {
4428 return self.fail("TODO: truncate to ints > 64 bits", .{});
4429 }
4430}
4431
43724432fn truncRegister(
43734433 self: *Self,
43744434 operand_reg: Register,