Skip to content

Commit a29d7d3

Browse files
committed
LLVM: implement STSWI, LSWI...
Fix DIVD, DIVDU, DIVW, DIVWU, MULHW Removed __adde_get_ca in ADDE, SUBFE
1 parent 155f13e commit a29d7d3

File tree

1 file changed

+87
-23
lines changed

1 file changed

+87
-23
lines changed

rpcs3/Emu/Cell/PPUTranslator.cpp

+87-23
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,6 @@ void PPUTranslator::SUBFIC(ppu_opcode_t op)
17101710
const auto result = m_ir->CreateSub(imm, a);
17111711
SetGpr(op.rd, result);
17121712
SetCarry(m_ir->CreateICmpULE(result, imm));
1713-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", m_ir->CreateNot(a), imm, m_ir->getTrue()));
17141713
}
17151714

17161715
void PPUTranslator::CMPLI(ppu_opcode_t op)
@@ -1730,7 +1729,6 @@ void PPUTranslator::ADDIC(ppu_opcode_t op)
17301729
const auto result = m_ir->CreateAdd(a, imm);
17311730
SetGpr(op.rd, result);
17321731
SetCarry(m_ir->CreateICmpULT(result, imm));
1733-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, imm, m_ir->getFalse()));
17341732
if (op.main & 1) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
17351733
}
17361734

@@ -2285,7 +2283,6 @@ void PPUTranslator::SUBFC(ppu_opcode_t op)
22852283
const auto result = m_ir->CreateSub(b, a);
22862284
SetGpr(op.rd, result);
22872285
SetCarry(m_ir->CreateICmpULE(result, b));
2288-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", m_ir->CreateNot(a), b, m_ir->getTrue()));
22892286
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
22902287
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__subfc_get_ov", a, b));
22912288
}
@@ -2297,7 +2294,6 @@ void PPUTranslator::ADDC(ppu_opcode_t op)
22972294
const auto result = m_ir->CreateAdd(a, b);
22982295
SetGpr(op.rd, result);
22992296
SetCarry(m_ir->CreateICmpULT(result, b));
2300-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, b, m_ir->getFalse()));
23012297
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
23022298
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__addc_get_ov", a, b));
23032299
}
@@ -2487,7 +2483,7 @@ void PPUTranslator::MULHW(ppu_opcode_t op)
24872483
{
24882484
const auto a = SExt(GetGpr(op.ra, 32));
24892485
const auto b = SExt(GetGpr(op.rb, 32));
2490-
SetGpr(op.rd, m_ir->CreateLShr(m_ir->CreateMul(a, b), 32));
2486+
SetGpr(op.rd, m_ir->CreateAShr(m_ir->CreateMul(a, b), 32));
24912487
if (op.rc) SetCrField(0, GetUndef<bool>(), GetUndef<bool>(), GetUndef<bool>());
24922488
}
24932489

@@ -2545,10 +2541,11 @@ void PPUTranslator::SUBFE(ppu_opcode_t op)
25452541
const auto a = m_ir->CreateNot(GetGpr(op.ra));
25462542
const auto b = GetGpr(op.rb);
25472543
const auto c = GetCarry();
2548-
const auto result = m_ir->CreateAdd(m_ir->CreateAdd(a, b), ZExt(c, GetType<u64>()));
2549-
SetGpr(op.rd, result);
2550-
SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, b, c)); // TODO
2551-
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
2544+
const auto r1 = m_ir->CreateAdd(a, b);
2545+
const auto r2 = m_ir->CreateAdd(r1, ZExt(c, GetType<u64>()));
2546+
SetGpr(op.rd, r2);
2547+
SetCarry(m_ir->CreateOr(m_ir->CreateICmpULT(r1, a), m_ir->CreateICmpULT(r2, r1)));
2548+
if (op.rc) SetCrFieldSignedCmp(0, r2, m_ir->getInt64(0));
25522549
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__subfe_get_ov", a, b, c));
25532550
}
25542551

@@ -2557,10 +2554,11 @@ void PPUTranslator::ADDE(ppu_opcode_t op)
25572554
const auto a = GetGpr(op.ra);
25582555
const auto b = GetGpr(op.rb);
25592556
const auto c = GetCarry();
2560-
const auto result = m_ir->CreateAdd(m_ir->CreateAdd(a, b), ZExt(c, GetType<u64>()));
2561-
SetGpr(op.rd, result);
2562-
SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, b, c)); // TODO
2563-
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
2557+
const auto r1 = m_ir->CreateAdd(a, b);
2558+
const auto r2 = m_ir->CreateAdd(r1, ZExt(c, GetType<u64>()));
2559+
SetGpr(op.rd, r2);
2560+
SetCarry(m_ir->CreateOr(m_ir->CreateICmpULT(r1, a), m_ir->CreateICmpULT(r2, r1)));
2561+
if (op.rc) SetCrFieldSignedCmp(0, r2, m_ir->getInt64(0));
25642562
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__adde_get_ov", a, b, c));
25652563
}
25662564

@@ -2645,7 +2643,6 @@ void PPUTranslator::ADDZE(ppu_opcode_t op)
26452643
const auto result = m_ir->CreateAdd(a, ZExt(c, GetType<u64>()));
26462644
SetGpr(op.rd, result);
26472645
SetCarry(m_ir->CreateICmpULT(result, a));
2648-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(0), c));
26492646
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
26502647
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__addze_get_ov", a, c));
26512648
}
@@ -2657,7 +2654,6 @@ void PPUTranslator::SUBFZE(ppu_opcode_t op)
26572654
const auto result = m_ir->CreateAdd(a, ZExt(c, GetType<u64>()));
26582655
SetGpr(op.rd, result);
26592656
SetCarry(m_ir->CreateICmpULT(result, a));
2660-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(0), c));
26612657
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
26622658
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__subfze_get_ov", a, c));
26632659
}
@@ -2687,7 +2683,6 @@ void PPUTranslator::SUBFME(ppu_opcode_t op)
26872683
const auto result = m_ir->CreateSub(a, ZExt(m_ir->CreateNot(c), GetType<u64>()));
26882684
SetGpr(op.rd, result);
26892685
SetCarry(m_ir->CreateOr(c, IsNotZero(a)));
2690-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(-1), c));
26912686
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
26922687
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__subfme_get_ov", a, c));
26932688
}
@@ -2709,7 +2704,6 @@ void PPUTranslator::ADDME(ppu_opcode_t op)
27092704
const auto result = m_ir->CreateSub(a, ZExt(m_ir->CreateNot(c), GetType<u64>()));
27102705
SetGpr(op.rd, result);
27112706
SetCarry(m_ir->CreateOr(c, IsNotZero(a)));
2712-
//SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(-1), c));
27132707
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
27142708
if (op.oe) SetOverflow(Call(GetType<bool>(), m_pure_attr, "__addme_get_ov", a, c));
27152709
}
@@ -2907,7 +2901,7 @@ void PPUTranslator::DIVDU(ppu_opcode_t op)
29072901
const auto b = GetGpr(op.rb);
29082902
const auto o = IsZero(b);
29092903
const auto result = m_ir->CreateUDiv(a, m_ir->CreateSelect(o, m_ir->getInt64(-1), b));
2910-
SetGpr(op.rd, result);
2904+
SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt64(0), result));
29112905
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
29122906
if (op.oe) SetOverflow(o);
29132907
}
@@ -2917,7 +2911,8 @@ void PPUTranslator::DIVWU(ppu_opcode_t op)
29172911
const auto a = GetGpr(op.ra, 32);
29182912
const auto b = GetGpr(op.rb, 32);
29192913
const auto o = IsZero(b);
2920-
SetGpr(op.rd, m_ir->CreateUDiv(a, m_ir->CreateSelect(o, m_ir->getInt32(0xffffffff), b)));
2914+
const auto result = m_ir->CreateUDiv(a, m_ir->CreateSelect(o, m_ir->getInt32(0xffffffff), b));
2915+
SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt32(0), result));
29212916
if (op.rc) SetCrField(0, GetUndef<bool>(), GetUndef<bool>(), GetUndef<bool>());
29222917
if (op.oe) SetOverflow(o);
29232918
}
@@ -2967,7 +2962,7 @@ void PPUTranslator::DIVD(ppu_opcode_t op)
29672962
const auto b = GetGpr(op.rb);
29682963
const auto o = m_ir->CreateOr(IsZero(b), m_ir->CreateAnd(m_ir->CreateICmpEQ(a, m_ir->getInt64(1ull << 63)), IsOnes(b)));
29692964
const auto result = m_ir->CreateSDiv(a, m_ir->CreateSelect(o, m_ir->getInt64(1ull << 63), b));
2970-
SetGpr(op.rd, result);
2965+
SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt64(0), result));
29712966
if (op.rc) SetCrFieldSignedCmp(0, result, m_ir->getInt64(0));
29722967
if (op.oe) SetOverflow(o);
29732968
}
@@ -2977,7 +2972,8 @@ void PPUTranslator::DIVW(ppu_opcode_t op)
29772972
const auto a = GetGpr(op.ra, 32);
29782973
const auto b = GetGpr(op.rb, 32);
29792974
const auto o = m_ir->CreateOr(IsZero(b), m_ir->CreateAnd(m_ir->CreateICmpEQ(a, m_ir->getInt32(1 << 31)), IsOnes(b)));
2980-
SetGpr(op.rd, m_ir->CreateSDiv(a, m_ir->CreateSelect(o, m_ir->getInt32(1 << 31), b)));
2975+
const auto result = m_ir->CreateSDiv(a, m_ir->CreateSelect(o, m_ir->getInt32(1 << 31), b));
2976+
SetGpr(op.rd, m_ir->CreateSelect(o, m_ir->getInt32(0), result));
29812977
if (op.rc) SetCrField(0, GetUndef<bool>(), GetUndef<bool>(), GetUndef<bool>());
29822978
if (op.oe) SetOverflow(o);
29832979
}
@@ -3032,7 +3028,43 @@ void PPUTranslator::LVRX(ppu_opcode_t op)
30323028

30333029
void PPUTranslator::LSWI(ppu_opcode_t op)
30343030
{
3035-
Call(GetType<void>(), "__lswi", m_ir->getInt32(op.rd), m_ir->getInt32(op.rb), op.ra ? GetGpr(op.ra) : m_ir->getInt64(0));
3031+
Value* addr = op.ra ? GetGpr(op.ra) : m_ir->getInt64(0);
3032+
u32 index = op.rb ? op.rb : 32;
3033+
u32 reg = op.rd;
3034+
3035+
while (index)
3036+
{
3037+
if (index > 3)
3038+
{
3039+
SetGpr(reg, ReadMemory(addr, GetType<u32>()));
3040+
index -= 4;
3041+
3042+
if (index)
3043+
{
3044+
addr = m_ir->CreateAdd(addr, m_ir->getInt64(4));
3045+
}
3046+
}
3047+
else
3048+
{
3049+
Value* buf = nullptr;
3050+
u32 i = 3;
3051+
3052+
while (index)
3053+
{
3054+
const auto byte = m_ir->CreateShl(ZExt(ReadMemory(addr, GetType<u8>()), GetType<u32>()), i * 8);
3055+
3056+
buf = buf ? m_ir->CreateOr(buf, byte) : byte;
3057+
3058+
if (--index)
3059+
{
3060+
addr = m_ir->CreateAdd(addr, m_ir->getInt64(1));
3061+
}
3062+
}
3063+
3064+
SetGpr(reg, buf);
3065+
}
3066+
reg = (reg + 1) % 32;
3067+
}
30363068
}
30373069

30383070
void PPUTranslator::LFSUX(ppu_opcode_t op)
@@ -3098,7 +3130,39 @@ void PPUTranslator::STFSUX(ppu_opcode_t op)
30983130

30993131
void PPUTranslator::STSWI(ppu_opcode_t op)
31003132
{
3101-
Call(GetType<void>(), "__stswi", m_ir->getInt32(op.rd), m_ir->getInt32(op.rb), op.ra ? GetGpr(op.ra) : m_ir->getInt64(0));
3133+
Value* addr = op.ra ? GetGpr(op.ra) : m_ir->getInt64(0);
3134+
u32 index = op.rb ? op.rb : 32;
3135+
u32 reg = op.rd;
3136+
3137+
while (index)
3138+
{
3139+
if (index > 3)
3140+
{
3141+
WriteMemory(GetGpr(reg, 32), addr);
3142+
index -= 4;
3143+
3144+
if (index)
3145+
{
3146+
addr = m_ir->CreateAdd(addr, m_ir->getInt64(4));
3147+
}
3148+
}
3149+
else
3150+
{
3151+
Value* buf = GetGpr(reg, 32);
3152+
3153+
while (index)
3154+
{
3155+
WriteMemory(m_ir->CreateLShr(buf, 24), addr);
3156+
3157+
if (--index)
3158+
{
3159+
buf = m_ir->CreateShl(buf, 8);
3160+
addr = m_ir->CreateAdd(addr, m_ir->getInt64(1));
3161+
}
3162+
}
3163+
}
3164+
reg = (reg + 1) % 32;
3165+
}
31023166
}
31033167

31043168
void PPUTranslator::STFDX(ppu_opcode_t op)

0 commit comments

Comments
 (0)