aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Schodet2024-03-08 17:15:09 +0100
committerNicolas Schodet2024-03-08 17:19:04 +0100
commit3a3201ff808c1258bd8cea8c6ae471c446dd2ed9 (patch)
treecc95aad971dadabbbe56a033a8c7f5e90eae9796
parente724e2be533c3b1571aaa2020af78e76e8b3b573 (diff)
Fix signed float to int conversion
This can be visible using this test: task main() { float a = -12.34; NumOut(0, 32, a); char b = a; NumOut(0, 24, b); Wait(3000); } Thanks to Andreas Weber for reporting the problem and for the test program. This was actually fixed in NXT Enhanced Firmware, not sure if it was by accident or not as the original firmware source code comment suggests that special casing this conversion could improve speed. Imported from NXT Enhanced Firmware.
-rw-r--r--src/c_cmd.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/c_cmd.c b/src/c_cmd.c
index 87b3e24..876297e 100644
--- a/src/c_cmd.c
+++ b/src/c_cmd.c
@@ -5588,7 +5588,7 @@ NXT_STATUS cCmdInterpShortSubCall(CODE_WORD * const pCode)
return Status;
}
-ULONG moveSameInt= 0, moveDiffInt= 0, moveFloat= 0, moveArrInt= 0, moveOther= 0;
+ULONG moveSameInt= 0, moveDiffInt= 0, moveFloat= 0, moveIntFloat= 0, moveFloatInt= 0, moveArrInt= 0, moveOther= 0;
NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2)
{
NXT_STATUS Status;
@@ -5621,13 +5621,49 @@ NXT_STATUS cCmdMove(DATA_ARG Arg1, DATA_ARG Arg2)
Status= NO_ERR;
}
}
- else if(tc1 == TC_FLOAT && tc2 == TC_FLOAT) { // may also need to speed up float to int and int to float conversions
+ else if(tc1 == TC_FLOAT && tc2 == TC_FLOAT) { // float to float
moveFloat++;
pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset;
pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset;
*(float*)pArg1= *(float*)pArg2;
Status= NO_ERR;
}
+ else if(tc1 == TC_FLOAT && tc2 <= TC_LAST_INT_SCALAR) { // int to float
+ moveIntFloat++;
+ pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset;
+ pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset;
+ if (tc2 == TC_SLONG)
+ *(float*)pArg1 = *(SLONG*)pArg2;
+ else if (tc2 == TC_ULONG)
+ *(float*)pArg1 = *(ULONG*)pArg2;
+ else if (tc2 == TC_SBYTE)
+ *(float*)pArg1 = *(SBYTE*)pArg2;
+ else if (tc2 == TC_UBYTE)
+ *(float*)pArg1 = *(UBYTE*)pArg2;
+ else if (tc2 == TC_UWORD)
+ *(float*)pArg1 = *(UWORD*)pArg2;
+ else
+ *(float*)pArg1= *(SWORD*)pArg2;
+ Status= NO_ERR;
+ }
+ else if(tc2 == TC_FLOAT && tc1 <= TC_LAST_INT_SCALAR) { // float to int
+ moveFloatInt++;
+ pArg1= VarsCmd.pDataspace + TOC1Ptr->DSOffset;
+ pArg2= VarsCmd.pDataspace + TOC2Ptr->DSOffset;
+ if (tc1 == TC_SLONG)
+ *(SLONG*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_ULONG)
+ *(ULONG*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_SBYTE)
+ *(SBYTE*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_UBYTE)
+ *(UBYTE*)pArg1 = *(float*)pArg2;
+ else if (tc1 == TC_UWORD)
+ *(UWORD*)pArg1 = *(float*)pArg2;
+ else
+ *(SWORD*)pArg1 = *(float*)pArg2;
+ Status= NO_ERR;
+ }
//!!! Optimized move for arrays of ints.
else if ((tc1 == TC_ARRAY) && (tc2 == TC_ARRAY)
&& ((TOC1Ptr+1)->TypeCode <= TC_LAST_INT_SCALAR)