@@ -1710,7 +1710,6 @@ void PPUTranslator::SUBFIC(ppu_opcode_t op)
1710
1710
const auto result = m_ir->CreateSub (imm, a);
1711
1711
SetGpr (op.rd , result);
1712
1712
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()));
1714
1713
}
1715
1714
1716
1715
void PPUTranslator::CMPLI (ppu_opcode_t op)
@@ -1730,7 +1729,6 @@ void PPUTranslator::ADDIC(ppu_opcode_t op)
1730
1729
const auto result = m_ir->CreateAdd (a, imm);
1731
1730
SetGpr (op.rd , result);
1732
1731
SetCarry (m_ir->CreateICmpULT (result, imm));
1733
- // SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, imm, m_ir->getFalse()));
1734
1732
if (op.main & 1 ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
1735
1733
}
1736
1734
@@ -2285,7 +2283,6 @@ void PPUTranslator::SUBFC(ppu_opcode_t op)
2285
2283
const auto result = m_ir->CreateSub (b, a);
2286
2284
SetGpr (op.rd , result);
2287
2285
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()));
2289
2286
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2290
2287
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __subfc_get_ov" , a, b));
2291
2288
}
@@ -2297,7 +2294,6 @@ void PPUTranslator::ADDC(ppu_opcode_t op)
2297
2294
const auto result = m_ir->CreateAdd (a, b);
2298
2295
SetGpr (op.rd , result);
2299
2296
SetCarry (m_ir->CreateICmpULT (result, b));
2300
- // SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, b, m_ir->getFalse()));
2301
2297
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2302
2298
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __addc_get_ov" , a, b));
2303
2299
}
@@ -2487,7 +2483,7 @@ void PPUTranslator::MULHW(ppu_opcode_t op)
2487
2483
{
2488
2484
const auto a = SExt (GetGpr (op.ra , 32 ));
2489
2485
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 ));
2491
2487
if (op.rc ) SetCrField (0 , GetUndef<bool >(), GetUndef<bool >(), GetUndef<bool >());
2492
2488
}
2493
2489
@@ -2545,10 +2541,11 @@ void PPUTranslator::SUBFE(ppu_opcode_t op)
2545
2541
const auto a = m_ir->CreateNot (GetGpr (op.ra ));
2546
2542
const auto b = GetGpr (op.rb );
2547
2543
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 ));
2552
2549
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __subfe_get_ov" , a, b, c));
2553
2550
}
2554
2551
@@ -2557,10 +2554,11 @@ void PPUTranslator::ADDE(ppu_opcode_t op)
2557
2554
const auto a = GetGpr (op.ra );
2558
2555
const auto b = GetGpr (op.rb );
2559
2556
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 ));
2564
2562
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __adde_get_ov" , a, b, c));
2565
2563
}
2566
2564
@@ -2645,7 +2643,6 @@ void PPUTranslator::ADDZE(ppu_opcode_t op)
2645
2643
const auto result = m_ir->CreateAdd (a, ZExt (c, GetType<u64>()));
2646
2644
SetGpr (op.rd , result);
2647
2645
SetCarry (m_ir->CreateICmpULT (result, a));
2648
- // SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(0), c));
2649
2646
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2650
2647
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __addze_get_ov" , a, c));
2651
2648
}
@@ -2657,7 +2654,6 @@ void PPUTranslator::SUBFZE(ppu_opcode_t op)
2657
2654
const auto result = m_ir->CreateAdd (a, ZExt (c, GetType<u64>()));
2658
2655
SetGpr (op.rd , result);
2659
2656
SetCarry (m_ir->CreateICmpULT (result, a));
2660
- // SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(0), c));
2661
2657
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2662
2658
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __subfze_get_ov" , a, c));
2663
2659
}
@@ -2687,7 +2683,6 @@ void PPUTranslator::SUBFME(ppu_opcode_t op)
2687
2683
const auto result = m_ir->CreateSub (a, ZExt (m_ir->CreateNot (c), GetType<u64>()));
2688
2684
SetGpr (op.rd , result);
2689
2685
SetCarry (m_ir->CreateOr (c, IsNotZero (a)));
2690
- // SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(-1), c));
2691
2686
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2692
2687
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __subfme_get_ov" , a, c));
2693
2688
}
@@ -2709,7 +2704,6 @@ void PPUTranslator::ADDME(ppu_opcode_t op)
2709
2704
const auto result = m_ir->CreateSub (a, ZExt (m_ir->CreateNot (c), GetType<u64>()));
2710
2705
SetGpr (op.rd , result);
2711
2706
SetCarry (m_ir->CreateOr (c, IsNotZero (a)));
2712
- // SetCarry(Call(GetType<bool>(), m_pure_attr, "__adde_get_ca", a, m_ir->getInt64(-1), c));
2713
2707
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2714
2708
if (op.oe ) SetOverflow (Call (GetType<bool >(), m_pure_attr, " __addme_get_ov" , a, c));
2715
2709
}
@@ -2907,7 +2901,7 @@ void PPUTranslator::DIVDU(ppu_opcode_t op)
2907
2901
const auto b = GetGpr (op.rb );
2908
2902
const auto o = IsZero (b);
2909
2903
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) );
2911
2905
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2912
2906
if (op.oe ) SetOverflow (o);
2913
2907
}
@@ -2917,7 +2911,8 @@ void PPUTranslator::DIVWU(ppu_opcode_t op)
2917
2911
const auto a = GetGpr (op.ra , 32 );
2918
2912
const auto b = GetGpr (op.rb , 32 );
2919
2913
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));
2921
2916
if (op.rc ) SetCrField (0 , GetUndef<bool >(), GetUndef<bool >(), GetUndef<bool >());
2922
2917
if (op.oe ) SetOverflow (o);
2923
2918
}
@@ -2967,7 +2962,7 @@ void PPUTranslator::DIVD(ppu_opcode_t op)
2967
2962
const auto b = GetGpr (op.rb );
2968
2963
const auto o = m_ir->CreateOr (IsZero (b), m_ir->CreateAnd (m_ir->CreateICmpEQ (a, m_ir->getInt64 (1ull << 63 )), IsOnes (b)));
2969
2964
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) );
2971
2966
if (op.rc ) SetCrFieldSignedCmp (0 , result, m_ir->getInt64 (0 ));
2972
2967
if (op.oe ) SetOverflow (o);
2973
2968
}
@@ -2977,7 +2972,8 @@ void PPUTranslator::DIVW(ppu_opcode_t op)
2977
2972
const auto a = GetGpr (op.ra , 32 );
2978
2973
const auto b = GetGpr (op.rb , 32 );
2979
2974
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));
2981
2977
if (op.rc ) SetCrField (0 , GetUndef<bool >(), GetUndef<bool >(), GetUndef<bool >());
2982
2978
if (op.oe ) SetOverflow (o);
2983
2979
}
@@ -3032,7 +3028,43 @@ void PPUTranslator::LVRX(ppu_opcode_t op)
3032
3028
3033
3029
void PPUTranslator::LSWI (ppu_opcode_t op)
3034
3030
{
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
+ }
3036
3068
}
3037
3069
3038
3070
void PPUTranslator::LFSUX (ppu_opcode_t op)
@@ -3098,7 +3130,39 @@ void PPUTranslator::STFSUX(ppu_opcode_t op)
3098
3130
3099
3131
void PPUTranslator::STSWI (ppu_opcode_t op)
3100
3132
{
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
+ }
3102
3166
}
3103
3167
3104
3168
void PPUTranslator::STFDX (ppu_opcode_t op)
0 commit comments