From 3a3201ff808c1258bd8cea8c6ae471c446dd2ed9 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Fri, 8 Mar 2024 17:15:09 +0100 Subject: 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. --- src/c_cmd.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'src') 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) -- cgit v1.2.3