@@ -744,7 +744,21 @@ void PPCRecompilerImlGen_ClampInteger(ppcImlGenContext_t* ppcImlGenContext, IMLR
744
744
);
745
745
}
746
746
747
- void PPCRecompilerImlGen_EmitPSQLoadCase (ppcImlGenContext_t* ppcImlGenContext, Espresso::PSQ_LOAD_TYPE loadType, bool readPS1, IMLReg gprA, sint32 imm, IMLReg fprDPS0, IMLReg fprDPS1)
747
+ void PPCRecompilerIMLGen_GetPSQScale (ppcImlGenContext_t* ppcImlGenContext, IMLReg gqrRegister, IMLReg fprRegScaleOut, bool isLoad)
748
+ {
749
+ IMLReg gprTmp2 = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_TEMPORARY + 2 );
750
+ // extract scale factor and sign extend it
751
+ ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_LEFT_SHIFT, gprTmp2, gqrRegister, 32 - ((isLoad ? 24 : 8 )+7 ));
752
+ ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_RIGHT_SHIFT_S, gprTmp2, gprTmp2, (32 -23 )-7 );
753
+ ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_AND, gprTmp2, gprTmp2, 0x1FF <<23 );
754
+ if (isLoad)
755
+ ppcImlGenContext->emitInst ().make_r_r (PPCREC_IML_OP_NEG, gprTmp2, gprTmp2);
756
+ ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_ADD, gprTmp2, gprTmp2, 0x7F <<23 );
757
+ // gprTmp2 now holds the scale float bits, bitcast to float
758
+ ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_BITCAST_INT_TO_FLOAT, fprRegScaleOut, gprTmp2);
759
+ }
760
+
761
+ void PPCRecompilerImlGen_EmitPSQLoadCase (ppcImlGenContext_t* ppcImlGenContext, sint32 gqrIndex, Espresso::PSQ_LOAD_TYPE loadType, bool readPS1, IMLReg gprA, sint32 imm, IMLReg fprDPS0, IMLReg fprDPS1)
748
762
{
749
763
if (loadType == Espresso::PSQ_LOAD_TYPE::TYPE_F32)
750
764
{
@@ -756,26 +770,42 @@ void PPCRecompilerImlGen_EmitPSQLoadCase(ppcImlGenContext_t* ppcImlGenContext, E
756
770
}
757
771
if (loadType == Espresso::PSQ_LOAD_TYPE::TYPE_U16 || loadType == Espresso::PSQ_LOAD_TYPE::TYPE_S16)
758
772
{
773
+ // get scale factor
774
+ IMLReg gqrRegister = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_SPR0 + SPR_UGQR0 + gqrIndex);
775
+ IMLReg fprScaleReg = _GetFPRTemp (ppcImlGenContext, 2 );
776
+ PPCRecompilerIMLGen_GetPSQScale (ppcImlGenContext, gqrRegister, fprScaleReg, true );
777
+
759
778
bool isSigned = (loadType == Espresso::PSQ_LOAD_TYPE::TYPE_S16);
760
779
IMLReg gprTmp = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_TEMPORARY + 0 );
761
780
ppcImlGenContext->emitInst ().make_r_memory (gprTmp, gprA, imm, 16 , isSigned, true );
762
781
ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_INT_TO_FLOAT, fprDPS0, gprTmp);
782
+
783
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprDPS0, fprDPS0, fprScaleReg);
784
+
763
785
if (readPS1)
764
786
{
765
787
ppcImlGenContext->emitInst ().make_r_memory (gprTmp, gprA, imm + 2 , 16 , isSigned, true );
766
788
ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_INT_TO_FLOAT, fprDPS1, gprTmp);
789
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprDPS1, fprDPS1, fprScaleReg);
767
790
}
768
791
}
769
792
else if (loadType == Espresso::PSQ_LOAD_TYPE::TYPE_U8 || loadType == Espresso::PSQ_LOAD_TYPE::TYPE_S8)
770
793
{
794
+ // get scale factor
795
+ IMLReg gqrRegister = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_SPR0 + SPR_UGQR0 + gqrIndex);
796
+ IMLReg fprScaleReg = _GetFPRTemp (ppcImlGenContext, 2 );
797
+ PPCRecompilerIMLGen_GetPSQScale (ppcImlGenContext, gqrRegister, fprScaleReg, true );
798
+
771
799
bool isSigned = (loadType == Espresso::PSQ_LOAD_TYPE::TYPE_S8);
772
800
IMLReg gprTmp = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_TEMPORARY + 0 );
773
801
ppcImlGenContext->emitInst ().make_r_memory (gprTmp, gprA, imm, 8 , isSigned, true );
774
802
ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_INT_TO_FLOAT, fprDPS0, gprTmp);
803
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprDPS0, fprDPS0, fprScaleReg);
775
804
if (readPS1)
776
805
{
777
806
ppcImlGenContext->emitInst ().make_r_memory (gprTmp, gprA, imm + 1 , 8 , isSigned, true );
778
807
ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_INT_TO_FLOAT, fprDPS1, gprTmp);
808
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprDPS1, fprDPS1, fprScaleReg);
779
809
}
780
810
}
781
811
}
@@ -812,14 +842,15 @@ bool PPCRecompilerImlGen_PSQ_L(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
812
842
IMLReg gqrRegister = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_SPR0 + SPR_UGQR0 + gqrIndex);
813
843
IMLReg loadTypeReg = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_TEMPORARY + 0 );
814
844
// extract the load type from the GQR register
815
- ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_AND, loadTypeReg, gqrRegister, 0x7 );
845
+ ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_RIGHT_SHIFT_U, loadTypeReg, gqrRegister, 16 );
846
+ ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_AND, loadTypeReg, loadTypeReg, 0x7 );
816
847
IMLSegment* caseSegment[6 ];
817
848
sint32 compareValues[6 ] = {0 , 4 , 5 , 6 , 7 };
818
849
PPCIMLGen_CreateSegmentBranchedPathMultiple (*ppcImlGenContext, *ppcImlGenContext->currentBasicBlock , caseSegment, loadTypeReg, compareValues, 5 , 0 );
819
850
for (sint32 i=0 ; i<5 ; i++)
820
851
{
821
852
IMLRedirectInstOutput outputToCase (ppcImlGenContext, caseSegment[i]); // while this is in scope, instructions go to caseSegment[i]
822
- PPCRecompilerImlGen_EmitPSQLoadCase (ppcImlGenContext, static_cast <Espresso::PSQ_LOAD_TYPE>(compareValues[i]), readPS1, gprA, imm, fprDPS0, fprDPS1);
853
+ PPCRecompilerImlGen_EmitPSQLoadCase (ppcImlGenContext, gqrIndex, static_cast <Espresso::PSQ_LOAD_TYPE>(compareValues[i]), readPS1, gprA, imm, fprDPS0, fprDPS1);
823
854
// create the case jump instructions here because we need to add it last
824
855
caseSegment[i]->AppendInstruction ()->make_jump ();
825
856
}
@@ -839,11 +870,11 @@ bool PPCRecompilerImlGen_PSQ_L(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
839
870
return false ;
840
871
}
841
872
842
- PPCRecompilerImlGen_EmitPSQLoadCase (ppcImlGenContext, type, readPS1, gprA, imm, fprDPS0, fprDPS1);
873
+ PPCRecompilerImlGen_EmitPSQLoadCase (ppcImlGenContext, gqrIndex, type, readPS1, gprA, imm, fprDPS0, fprDPS1);
843
874
return true ;
844
875
}
845
876
846
- void PPCRecompilerImlGen_EmitPSQStoreCase (ppcImlGenContext_t* ppcImlGenContext, Espresso::PSQ_LOAD_TYPE storeType, bool storePS1, IMLReg gprA, sint32 imm, IMLReg fprDPS0, IMLReg fprDPS1)
877
+ void PPCRecompilerImlGen_EmitPSQStoreCase (ppcImlGenContext_t* ppcImlGenContext, sint32 gqrIndex, Espresso::PSQ_LOAD_TYPE storeType, bool storePS1, IMLReg gprA, sint32 imm, IMLReg fprDPS0, IMLReg fprDPS1)
847
878
{
848
879
cemu_assert_debug (!storePS1 || fprDPS1.IsValid ());
849
880
if (storeType == Espresso::PSQ_LOAD_TYPE::TYPE_F32)
@@ -856,19 +887,27 @@ void PPCRecompilerImlGen_EmitPSQStoreCase(ppcImlGenContext_t* ppcImlGenContext,
856
887
}
857
888
else if (storeType == Espresso::PSQ_LOAD_TYPE::TYPE_U16 || storeType == Espresso::PSQ_LOAD_TYPE::TYPE_S16)
858
889
{
890
+ // get scale factor
891
+ IMLReg gqrRegister = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_SPR0 + SPR_UGQR0 + gqrIndex);
892
+ IMLReg fprScaleReg = _GetFPRTemp (ppcImlGenContext, 2 );
893
+ PPCRecompilerIMLGen_GetPSQScale (ppcImlGenContext, gqrRegister, fprScaleReg, false );
894
+
859
895
bool isSigned = (storeType == Espresso::PSQ_LOAD_TYPE::TYPE_S16);
896
+ IMLReg fprTmp = _GetFPRTemp (ppcImlGenContext, 0 );
897
+
860
898
IMLReg gprTmp = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_TEMPORARY + 0 );
861
- ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp, fprDPS0);
862
- // todo - scaling
899
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprTmp, fprDPS0, fprScaleReg);
900
+ ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp, fprTmp);
901
+
863
902
if (isSigned)
864
903
PPCRecompilerImlGen_ClampInteger (ppcImlGenContext, gprTmp, -32768 , 32767 );
865
904
else
866
905
PPCRecompilerImlGen_ClampInteger (ppcImlGenContext, gprTmp, 0 , 65535 );
867
906
ppcImlGenContext->emitInst ().make_memory_r (gprTmp, gprA, imm, 16 , true );
868
907
if (storePS1)
869
908
{
870
- ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp , fprDPS1);
871
- // todo - scaling
909
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprTmp , fprDPS1, fprScaleReg );
910
+ ppcImlGenContext-> emitInst (). make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp, fprTmp);
872
911
if (isSigned)
873
912
PPCRecompilerImlGen_ClampInteger (ppcImlGenContext, gprTmp, -32768 , 32767 );
874
913
else
@@ -878,18 +917,25 @@ void PPCRecompilerImlGen_EmitPSQStoreCase(ppcImlGenContext_t* ppcImlGenContext,
878
917
}
879
918
else if (storeType == Espresso::PSQ_LOAD_TYPE::TYPE_U8 || storeType == Espresso::PSQ_LOAD_TYPE::TYPE_S8)
880
919
{
920
+ // get scale factor
921
+ IMLReg gqrRegister = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_SPR0 + SPR_UGQR0 + gqrIndex);
922
+ IMLReg fprScaleReg = _GetFPRTemp (ppcImlGenContext, 2 );
923
+ PPCRecompilerIMLGen_GetPSQScale (ppcImlGenContext, gqrRegister, fprScaleReg, false );
924
+
881
925
bool isSigned = (storeType == Espresso::PSQ_LOAD_TYPE::TYPE_S8);
926
+ IMLReg fprTmp = _GetFPRTemp (ppcImlGenContext, 0 );
882
927
IMLReg gprTmp = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_TEMPORARY + 0 );
883
- ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp, fprDPS0);
928
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprTmp, fprDPS0, fprScaleReg);
929
+ ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp, fprTmp);
884
930
if (isSigned)
885
931
PPCRecompilerImlGen_ClampInteger (ppcImlGenContext, gprTmp, -128 , 127 );
886
932
else
887
933
PPCRecompilerImlGen_ClampInteger (ppcImlGenContext, gprTmp, 0 , 255 );
888
934
ppcImlGenContext->emitInst ().make_memory_r (gprTmp, gprA, imm, 8 , true );
889
935
if (storePS1)
890
936
{
891
- ppcImlGenContext->emitInst ().make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp , fprDPS1);
892
- // todo - scaling
937
+ ppcImlGenContext->emitInst ().make_fpr_r_r_r (PPCREC_IML_OP_FPR_MULTIPLY, fprTmp , fprDPS1, fprScaleReg );
938
+ ppcImlGenContext-> emitInst (). make_fpr_r_r (PPCREC_IML_OP_FPR_FLOAT_TO_INT, gprTmp, fprTmp);
893
939
if (isSigned)
894
940
PPCRecompilerImlGen_ClampInteger (ppcImlGenContext, gprTmp, -128 , 127 );
895
941
else
@@ -928,16 +974,15 @@ bool PPCRecompilerImlGen_PSQ_ST(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
928
974
IMLReg gqrRegister = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_SPR0 + SPR_UGQR0 + gqrIndex);
929
975
IMLReg loadTypeReg = PPCRecompilerImlGen_loadRegister (ppcImlGenContext, PPCREC_NAME_TEMPORARY + 0 );
930
976
// extract the load type from the GQR register
931
- ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_RIGHT_SHIFT_U, loadTypeReg, gqrRegister, 16 );
932
- ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_AND, loadTypeReg, loadTypeReg, 0x7 );
977
+ ppcImlGenContext->emitInst ().make_r_r_s32 (PPCREC_IML_OP_AND, loadTypeReg, gqrRegister, 0x7 );
933
978
934
979
IMLSegment* caseSegment[5 ];
935
980
sint32 compareValues[5 ] = {0 , 4 , 5 , 6 , 7 };
936
981
PPCIMLGen_CreateSegmentBranchedPathMultiple (*ppcImlGenContext, *ppcImlGenContext->currentBasicBlock , caseSegment, loadTypeReg, compareValues, 5 , 0 );
937
982
for (sint32 i=0 ; i<5 ; i++)
938
983
{
939
984
IMLRedirectInstOutput outputToCase (ppcImlGenContext, caseSegment[i]); // while this is in scope, instructions go to caseSegment[i]
940
- PPCRecompilerImlGen_EmitPSQStoreCase (ppcImlGenContext, static_cast <Espresso::PSQ_LOAD_TYPE>(compareValues[i]), storePS1, gprA, imm, fprDPS0, fprDPS1);
985
+ PPCRecompilerImlGen_EmitPSQStoreCase (ppcImlGenContext, gqrIndex, static_cast <Espresso::PSQ_LOAD_TYPE>(compareValues[i]), storePS1, gprA, imm, fprDPS0, fprDPS1);
941
986
ppcImlGenContext->emitInst ().make_jump (); // finalize case
942
987
}
943
988
return true ;
@@ -954,7 +999,7 @@ bool PPCRecompilerImlGen_PSQ_ST(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
954
999
return false ;
955
1000
}
956
1001
957
- PPCRecompilerImlGen_EmitPSQStoreCase (ppcImlGenContext, type, storePS1, gprA, imm, fprDPS0, fprDPS1);
1002
+ PPCRecompilerImlGen_EmitPSQStoreCase (ppcImlGenContext, gqrIndex, type, storePS1, gprA, imm, fprDPS0, fprDPS1);
958
1003
return true ;
959
1004
}
960
1005
0 commit comments