Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#102 Invalid OP_SET may be used for floating data assignments

compiler
open-fixed
John Hansen
NBC (24)
5
2014-08-28
2012-03-04
No

/***************************************************************************
* POC : Invalid opcode OP_SET may be used for floating data assignments
* Tested in Windows with nbc.exe version 1.2.1 r4 and 1.2.1 r5.
* Firmware tested : version 1.29 and 1.31
*
* OP_SET opcode must used for assign only scalar data (byte, sbyte, word,
* sword, long and slong) otherwise firmware crash.
*
* See also : In this POC, the data named "float_16" is not considered by the
* compiler and doesn't appear in the final rxe file. Why ?
* ----------------------------------------------------------------------
* Lego Firmware souces (version 1.29)
* ----------------------------------------------------------------------
*
* NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode)
* {
* ...
* case OP_SET:
* {
* //!!! Should throw error if TypeCode1 is non-scalar
* // Accepting non-scalar destinations could have unpredictable results!
* cCmdSetScalarValFromDataArg(Arg1, Arg2);
* }
* break;
* ....
* }
*
* // Only for scalar types and no offset
* void cCmdSetScalarValFromDataArg(DATA_ARG DataArg, ULONG NewVal)
* {
* DS_TOC_ENTRY *dsTOCPtr= &VarsCmd.pDataspaceTOC[DataArg];
* SetProcArray[dsTOCPtr->TypeCode](VarsCmd.pDataspace + dsTOCPtr->DSOffset, NewVal);
* }
*
* typedef void (*pSetOperand)(void *, ULONG);
* static pSetOperand SetProcArray[9]= {cCmdSetByte, cCmdSetByte, cCmdSetByte, cCmdSetWord, cCmdSetWord, cCmdSetLong, cCmdSetLong, cCmdSetError, cCmdSetError}; // dup UByte to line up
*
* void cCmdSetError(void * pVal, ULONG NewVal)
* {
* NXT_BREAK;
* }
* ----------------------------------------------------------------------
*
* enum DSTOC_RECORD_TYPE
* {
* // 0 to 7
* TC_VOID, TC_UBYTE, TC_SBYTE, TC_UWORD, TC_SWORD, TC_ULONG, TC_SLONG,
* // 8 to 9
* TC_ARRAY, TC_CLUSTER,
* // 10 to 11
* TC_MUTEX, TC_FLOAT
* };
*
* If Destitation type is between 0 and 7 : OK
* If Destitation type is between 8 and 9 : ERROR -> NXT_BREAK is called
* If Destitation type is other : ERROR -> Exception Array index out of bounds and firmware crash.
***************************************************************************
* Sorry for my pitiful english. :(
* And a big thank for your excellent tools !!!! :)
*
* Lionel d'Hauenens (www.laboskopia.com)
***************************************************************************/

// Global declaration and assignment : OK
float float_1 = 0; // GOOB -> assigned from Static Default Segment (rxe file)
float float_2 = 1; // GOOB -> assigned from Static Default Segment (rxe file)
float float_3= 0x7FFF; // GOOB -> assigned from Static Default Segment (rxe file)
float float_4 = 0x8000; // GOOB -> assigned from Static Default Segment (rxe file)

// Global declaration
float float_5;
float float_6;
float float_7;
float float_8;

float result;

task main ()
{
// Local declaration and assignment
float float_13 = 0; // BAD : constant is a positive signed word -> invalid OP_SET is used with immediate SWORD to FLOAT
float float_14 = 1; // BAD : constant is a positive signed word -> invalid OP_SET is used with immediate SWORD to FLOAT
float float_15 = 0x7FFF; // BAD : constant is a positive signed word -> invalid OP_SET is used with immediate SWORD to FLOAT
float float_16 = 0x8000; // ERROR ! The data named "float_16" is not considered by the compiler and doesn't appear in the final rxe file.

// Global declaration and local assignment
float_5 = 0; // BAD : constant is a positive signed word -> invalid OP_SET is used with immediate SWORD to FLOAT
float_6 = 1; // BAD : constant is a positive signed word -> invalid OP_SET is used with immediate SWORD to FLOAT
float_7 = 0x7FFF; // BAD : constant is a positive signed word -> invalid OP_SET is used with immediate SWORD to FLOAT
float_8 = 0x8000; // GOOB : constant is a negative signed word -> OP_MOV is used

// Now, when a floating data is assigned with an explicite floating value
// all following local assignments of floating data are good
float float_9 = 2; // BAD : constant is a positive signed word -> invalid OP_SET is used with immediate SWORD to FLOAT
float float_10 = 3.0; // GOOD -> OP_MOV is used and OP_MOV is used for all following assignments of floating data
float float_11 = 4; // GOOB -> constant is a positive signed word but OP_MOV is correctly used
float float_12 = 0x7FFF; // GOOB -> constant is a positive signed word but OP_MOV is correctly used

// Only for compiler optimization doesn't ignore the floating code assignments
// ERROR ! The data named "float_16" is not considered by the compiler and doesn't appear in the final rxe file.
result = float_1 + float_2 + float_3 + float_4 + float_5 + float_6 + float_7 + float_8 + float_9 + float_10 + float_11 + float_12 + float_13 + float_14 + float_15 + float_16;
}

Discussion

  • nxc + rxe + disam files

     
    Attachments
    • labels: 943074 --> NBC
     
  • John Hansen
    John Hansen
    2012-03-05

    • status: open --> closed-fixed
     
  • John Hansen
    John Hansen
    2012-03-05

    I'm pretty sure the latest test release of the compiler fixes all of the issues that you describe in the bug report. SET is never used with float types anymore. NXC never interprets a hexadecimal constant as a floating point constant so the static initializations and local initializations are correct from that perspective. You just can't specify a floating point constant except in decimal notation. Lastly, the optimizer is removing float_16 from the program entirely because the only place where its value is used is to calculate the value of result but since result's value is never used the optimizer removes all references to result from the program as well. If the optimizer were really smart it would also remove all the other float variables since they are never used other than to calculate the value of a variable that has already been optimized out of the program. Adding a "result += 1" or "NumOut(0, LCD_LINE1, result);" to the end of the program forces the compiler to keep both result and float_16 in the generated code.

    Have a look at the test_releases folder at http://bricxcc.sourceforge.net/test_releases/

     
  • OK, I'm sorry.
    I had not seen the link to test_release.
    I'm a newbie in the NXC world .

    I just tested with test_release20111024 and the problem is effectively fixed.

    I could only download the file test_release20111024.zip from the link http://sourceforge.net/projects/bricxcc/files/testrelease/.
    All "test_release" I download from the link http://bricxcc.sourceforge.net/test_releases/ are interrupted at about 2 MB
    Is this what it comes from me or are there any download restrictions?

     
    • status: closed-fixed --> open-fixed