Merge pull request #18360 from unknownbrackets/arm64jit-fixes

Fix some arm64jit issues
This commit is contained in:
Henrik Rydgård 2023-10-15 07:34:03 +02:00 committed by GitHub
commit 8ff38d0a9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 4 deletions

View File

@ -608,7 +608,7 @@ void Arm64JitBackend::CompIR_VecHoriz(IRInst inst) {
regs_.SpillLockFPR(inst.src1, inst.src2);
regs_.MapVec4(inst.src1);
regs_.MapVec4(inst.src2);
regs_.MapVec4(inst.dest, MIPSMap::DIRTY);
regs_.MapVec4(inst.dest & ~3, MIPSMap::DIRTY);
fp_.FMUL(32, EncodeRegToQuad(SCRATCHF1), regs_.FQ(inst.src1), regs_.FQ(inst.src2));
fp_.FADDP(32, EncodeRegToQuad(SCRATCHF1), EncodeRegToQuad(SCRATCHF1), EncodeRegToQuad(SCRATCHF1));
fp_.FADDP(32, EncodeRegToQuad(SCRATCHF1), EncodeRegToQuad(SCRATCHF1), EncodeRegToQuad(SCRATCHF1));

View File

@ -167,11 +167,14 @@ void Arm64IRRegCache::FlushBeforeCall() {
continue;
if (!nr[mr[i].nReg].isDirty || !nr[mr[i + 1].nReg].isDirty)
continue;
// Make sure not to try to pair a GPR and FPR.
if (IsValidGPR(i) != IsValidGPR(i + 1))
continue;
int offset = GetMipsRegOffset(i);
// Okay, it's a maybe. Are we flushing both as GPRs?
if (!isGPRSaved(mr[i].nReg) && !isGPRSaved(mr[i + 1].nReg) && offset <= 252) {
if (!isGPRSaved(mr[i].nReg) && !isGPRSaved(mr[i + 1].nReg) && IsValidGPR(i) && offset <= 252) {
// If either is mapped as a pointer, fix it.
if (mr[i].loc == MIPSLoc::REG_AS_PTR)
AdjustNativeRegAsPtr(mr[i].nReg, false);
@ -190,7 +193,7 @@ void Arm64IRRegCache::FlushBeforeCall() {
// Perhaps as FPRs? Note: these must be single lane at this point.
// TODO: Could use STP on quads etc. too, i.e. i & i + 4.
if (!isFPRSaved(mr[i].nReg) && !isFPRSaved(mr[i + 1].nReg) && offset <= 252) {
if (!isFPRSaved(mr[i].nReg) && !isFPRSaved(mr[i + 1].nReg) && !IsValidGPR(i) && offset <= 252) {
fp_->STP(32, INDEX_SIGNED, FromNativeReg(mr[i].nReg), FromNativeReg(mr[i + 1].nReg), CTXREG, offset);
DiscardNativeReg(mr[i].nReg);

View File

@ -2095,7 +2095,9 @@ bool ReduceVec4Flush(const IRWriter &in, IRWriter &out, const IROptions &opts) {
if (overlapped(inst.dest, 1, inst.src1, 4, inst.src2, 4) && findAvailTempVec4()) {
out.Write(inst.op, temp, inst.src1, inst.src2, inst.constant);
if (usedLaterAsVec4(inst.dest & ~3)) {
out.Write(IROp::Vec4Shuffle, temp, inst.src1 & ~3, 0);
// Broadcast to other lanes if needed.
if ((inst.dest & 3) != 0)
out.Write(IROp::Vec4Shuffle, temp, temp, 0);
out.Write(IROp::Vec4Blend, inst.dest & ~3, inst.dest & ~3, temp, 1 << (inst.dest & 3));
// It's overlapped, so it'll get marked as Vec4 and used anyway.
isVec4Dirty[inst.dest & ~3] = true;