| ... | ... | @@ -5389,37 +5389,73 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void { |
| 5389 | 5389 | const result: MCValue = result: { |
| 5390 | 5390 | const mir_tag = @as(?Mir.Inst.FixedTag, switch (ty.zigTypeTag(mod)) { |
| 5391 | 5391 | else => null, |
| 5392 | | .Int => { |
| 5393 | | if (ty.abiSize(mod) > 8) { |
| 5394 | | return self.fail("TODO implement abs for integer abi sizes larger than 8", .{}); |
| 5395 | | } |
| 5396 | | const src_mcv = try self.resolveInst(ty_op.operand); |
| 5397 | | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, src_mcv); |
| 5392 | .Int => switch (ty.abiSize(mod)) { |
| 5393 | 1...8 => { |
| 5394 | try self.spillEflagsIfOccupied(); |
| 5395 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 5396 | const dst_mcv = try self.copyToRegisterWithInstTracking(inst, ty, src_mcv); |
| 5398 | 5397 | |
| 5399 | | try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv); |
| 5398 | try self.genUnOpMir(.{ ._, .neg }, ty, dst_mcv); |
| 5400 | 5399 | |
| 5401 | | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); |
| 5402 | | switch (src_mcv) { |
| 5403 | | .register => |val_reg| try self.asmCmovccRegisterRegister( |
| 5404 | | registerAlias(dst_mcv.register, cmov_abi_size), |
| 5405 | | registerAlias(val_reg, cmov_abi_size), |
| 5406 | | .l, |
| 5407 | | ), |
| 5408 | | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( |
| 5409 | | registerAlias(dst_mcv.register, cmov_abi_size), |
| 5410 | | src_mcv.mem(Memory.PtrSize.fromSize(cmov_abi_size)), |
| 5411 | | .l, |
| 5412 | | ), |
| 5413 | | else => { |
| 5414 | | const val_reg = try self.copyToTmpRegister(ty, src_mcv); |
| 5415 | | try self.asmCmovccRegisterRegister( |
| 5400 | const cmov_abi_size = @max(@as(u32, @intCast(ty.abiSize(mod))), 2); |
| 5401 | switch (src_mcv) { |
| 5402 | .register => |val_reg| try self.asmCmovccRegisterRegister( |
| 5416 | 5403 | registerAlias(dst_mcv.register, cmov_abi_size), |
| 5417 | 5404 | registerAlias(val_reg, cmov_abi_size), |
| 5418 | 5405 | .l, |
| 5406 | ), |
| 5407 | .memory, .indirect, .load_frame => try self.asmCmovccRegisterMemory( |
| 5408 | registerAlias(dst_mcv.register, cmov_abi_size), |
| 5409 | src_mcv.mem(Memory.PtrSize.fromSize(cmov_abi_size)), |
| 5410 | .l, |
| 5411 | ), |
| 5412 | else => { |
| 5413 | const val_reg = try self.copyToTmpRegister(ty, src_mcv); |
| 5414 | try self.asmCmovccRegisterRegister( |
| 5415 | registerAlias(dst_mcv.register, cmov_abi_size), |
| 5416 | registerAlias(val_reg, cmov_abi_size), |
| 5417 | .l, |
| 5418 | ); |
| 5419 | }, |
| 5420 | } |
| 5421 | break :result dst_mcv; |
| 5422 | }, |
| 5423 | 9...16 => { |
| 5424 | try self.spillEflagsIfOccupied(); |
| 5425 | const src_mcv = try self.resolveInst(ty_op.operand); |
| 5426 | const dst_mcv = if (src_mcv == .register_pair and |
| 5427 | self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: { |
| 5428 | const dst_regs = try self.register_manager.allocRegs( |
| 5429 | 2, |
| 5430 | .{ inst, inst }, |
| 5431 | abi.RegisterClass.gp, |
| 5419 | 5432 | ); |
| 5420 | | }, |
| 5421 | | } |
| 5422 | | break :result dst_mcv; |
| 5433 | const dst_mcv: MCValue = .{ .register_pair = dst_regs }; |
| 5434 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 5435 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 5436 | |
| 5437 | try self.genCopy(ty, dst_mcv, src_mcv); |
| 5438 | break :dst dst_mcv; |
| 5439 | }; |
| 5440 | const dst_regs = dst_mcv.register_pair; |
| 5441 | const dst_locks = self.register_manager.lockRegs(2, dst_regs); |
| 5442 | defer for (dst_locks) |dst_lock| if (dst_lock) |lock| |
| 5443 | self.register_manager.unlockReg(lock); |
| 5444 | |
| 5445 | const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 5446 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 5447 | defer self.register_manager.unlockReg(tmp_lock); |
| 5448 | |
| 5449 | try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, dst_regs[1]); |
| 5450 | try self.asmRegisterImmediate(.{ ._r, .sa }, tmp_reg, Immediate.u(63)); |
| 5451 | try self.asmRegisterRegister(.{ ._, .xor }, dst_regs[0], tmp_reg); |
| 5452 | try self.asmRegisterRegister(.{ ._, .xor }, dst_regs[1], tmp_reg); |
| 5453 | try self.asmRegisterRegister(.{ ._, .sub }, dst_regs[0], tmp_reg); |
| 5454 | try self.asmRegisterRegister(.{ ._, .sbb }, dst_regs[1], tmp_reg); |
| 5455 | |
| 5456 | break :result dst_mcv; |
| 5457 | }, |
| 5458 | else => return self.fail("TODO implement abs for {}", .{ty.fmt(mod)}), |
| 5423 | 5459 | }, |
| 5424 | 5460 | .Float => return self.floatSign(inst, ty_op.operand, ty), |
| 5425 | 5461 | .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { |
| ... | ... | @@ -6106,8 +6142,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void { |
| 6106 | 6142 | const dst_locks = self.register_manager.lockRegsAssumeUnused(2, dst_regs); |
| 6107 | 6143 | defer for (dst_locks) |lock| self.register_manager.unlockReg(lock); |
| 6108 | 6144 | |
| 6109 | | try self.genSetReg(dst_regs[0], Type.usize, .{ .register = src_regs[0] }); |
| 6110 | | try self.genSetReg(dst_regs[1], Type.usize, .{ .register = src_regs[1] }); |
| 6145 | try self.genCopy(container_ty, .{ .register_pair = dst_regs }, src_mcv); |
| 6111 | 6146 | break :dst dst_regs; |
| 6112 | 6147 | }; |
| 6113 | 6148 | const dst_mcv = MCValue{ .register_pair = dst_regs }; |