diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp index 18b19e90d..0d20a987e 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.cpp @@ -449,6 +449,12 @@ void CArmOps::MoveConstToVariable(uint32_t Const, void * Variable, const char * StoreArmRegToArmRegPointer(Arm_R1,Arm_R2,0); } +void CArmOps::MoveFloatRegToVariable(ArmFpuSingle reg, void * Variable, const char * VariableName) +{ + MoveConstToArmReg(Arm_R0,(uint32_t)Variable,VariableName); + StoreFloatRegToArmRegPointer(reg,Arm_R0,0); +} + void CArmOps::MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg) { MoveConstToArmReg(reg,(uint32_t)Variable,VariableName); @@ -588,6 +594,29 @@ void CArmOps::StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t } } +void CArmOps::StoreFloatRegToArmRegPointer(ArmFpuSingle Reg, ArmReg RegPointer, uint8_t Offset) +{ + if (Offset != 0) + { + CPU_Message(" vstr\t%s, [%s, #%d]", ArmFpuSingleName(Reg), ArmRegName(RegPointer), (uint32_t)Offset); + } + else + { + CPU_Message(" vstr\t%s, [%s]", ArmFpuSingleName(Reg), ArmRegName(RegPointer)); + } + Arm32Opcode op = {0}; + op.RnVdImm8.Rn = RegPointer; + op.RnVdImm8.op3 = 0; + op.RnVdImm8.D = Reg & 1; + op.RnVdImm8.U = 1; + op.RnVdImm8.op2 = 0xED; + + op.RnVdImm8.imm8 = Offset; + op.RnVdImm8.op1 = 0xA; + op.RnVdImm8.vd = Reg >> 1; + AddCode32(op.Hex); +} + void CArmOps::SubConstFromArmReg(ArmReg Reg, uint32_t Const) { if (Reg <= 7 && (Const & (~0xFF)) == 0) diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h index 489410a69..1684e20c7 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmOps.h @@ -156,11 +156,13 @@ protected: static void MoveConstToArmRegTop(ArmReg DestReg, uint16_t Const, const char * comment = NULL); static void MoveConstToArmReg(ArmReg DestReg, uint32_t Const, const char * comment = NULL); static void MoveConstToVariable(uint32_t Const, void * Variable, const char * VariableName); + static void MoveFloatRegToVariable(ArmFpuSingle reg, void * Variable, const char * VariableName); static void MoveVariableToArmReg(void * Variable, const char * VariableName, ArmReg reg); static void PushArmReg(uint16_t Registers); static void PopArmReg(uint16_t Registers); static void ShiftRightSignImmed(ArmReg DestReg, ArmReg SourceReg, uint32_t shift); static void StoreArmRegToArmRegPointer(ArmReg Reg, ArmReg RegPointer, uint8_t offset); + static void StoreFloatRegToArmRegPointer(ArmFpuSingle Reg, ArmReg RegPointer, uint8_t Offset); static void SubConstFromArmReg(ArmReg Reg, uint32_t Const); static void SubConstFromVariable(uint32_t Const, void * Variable, const char * VariableName); static void TestVariable(uint32_t Const, void * Variable, const char * VariableName);