<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: (DSC) (Codewarrior 11) 32bit variable register optimization bug in DSC Compiler in CodeWarrior for MCU</title>
    <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859129#M14960</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Lorenzo Micheletto,&lt;/P&gt;&lt;P&gt;Thanks for your reply.&lt;/P&gt;&lt;P&gt;I have escalated this problem to develpement team. I will let you know if I get any feedback from them.&lt;/P&gt;&lt;P&gt;Thanks,&lt;/P&gt;&lt;P&gt;Jun Zhang&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Thu, 31 Jan 2019 06:37:19 GMT</pubDate>
    <dc:creator>ZhangJennie</dc:creator>
    <dc:date>2019-01-31T06:37:19Z</dc:date>
    <item>
      <title>(DSC) (Codewarrior 11) 32bit variable register optimization bug in DSC Compiler</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859126#M14957</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I'm using Codewarrior 11 for MCU with the DSC toolchain.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DSC compiler&amp;nbsp;and/or inline assembly&amp;nbsp; optimizer for MC56F84789VLL (DSP 56800EX core)&amp;nbsp; &amp;nbsp;do not handle correctly access to LSP (lower 16bit word) of 32bit variable when it is mapped to an accumulator register.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;When using maximum optimization options ( -DOPTION_CORE_V3=1&amp;nbsp; -opt level=4 -opt speed -inline level=8 -inline auto -sprog -v3 -requireprotos -v3 ) the following byte-swapping code:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;inline UINT32 swapGetUINT32(register const UINT8 *R2Reg)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;{&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; register UINT32 AReg;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; // N.B. by declaring "register UINT32 XReg;"&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; // into assembly istructions you can use&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; // Areg --&amp;gt; 32bit register (either dst A,B,C,D or src A10,B10,C10,D10)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; // Areg.0 --&amp;gt; lower 16bit word (either A0,B0,C0,D0) &lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; // Areg.1 --&amp;gt; upper 16bit word (either A1,B1,C1,D1)&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;__asm{&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; .optimize_iasm on&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; moveu.bp X:(R2Reg)+,Y1&amp;nbsp; &amp;nbsp;// 1 1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; moveu.bp X:(R2Reg)+,AReg // 1 1 // *(p+1) into AReg.1 , clear AReg.2,AReg.0 &lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; moveu.bp X:(R2Reg)+,Y0&amp;nbsp; &amp;nbsp;// 1 1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; moveu.bp X:(R2Reg)+,X0&amp;nbsp; &amp;nbsp;// 1 1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; asll.l #8,Y&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // 2 1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; move.w X0,AReg.0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// 1 1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; or.l Y,AReg&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; // 1 1 &lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; .optimize_iasm off&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; }&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt; return AReg;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;}&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;INSTEAD&amp;nbsp;of generating the following code &amp;nbsp;(in the example below AReg gets mapped to A, but the compiler can generate the same inline sequence using A,B,C or D):&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,Y1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,A&amp;nbsp; // writes to A1 and clears A0&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,Y0&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,X0 // DSC does not have "&lt;SPAN style="background-color: #f6f6f6;"&gt;moveu.bp X:(R1)+,A0", so we copy to X0&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;asll.l #0x000008,Y&amp;nbsp;&amp;nbsp;&lt;SPAN style="background-color: #f6f6f6;"&gt;// shift lower bytes in Y1,Y0 to upper bytes&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;move.w X0,A0 // and then we copy X0 to A0&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;or.l Y,A&amp;nbsp; &amp;nbsp; &amp;nbsp;// now we merge the byte-swapped upper and lower bytes&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;SOMETIMES the function &lt;SPAN style="background-color: #f6f6f6;"&gt;swapGetUINT32&amp;nbsp;&lt;/SPAN&gt;gets compiled as:&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,Y1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,A&amp;nbsp; &amp;nbsp;// WRITES (R1) to (A1), CLEAR A2, A0&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;adda #-3,SP,R4&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;move.l A10,X:(R4)&amp;nbsp; &amp;nbsp; // WRITES A0 to (SP-3), A1 to (SP-2)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,Y0&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;moveu.bp X:(R1)+,X0&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;asll.l #0x000008,Y // shift lower bytes in Y1,Y0 to upper bytes&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;move.w X0,X:(SP-2) // WRITES X0 to (SP-2) (where A1 was stored, overwriting it)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;move.l X:(R4),A&amp;nbsp; &amp;nbsp; // reload A (it contains A1 = X0, A0 = 0 )&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN style="font-family: 'courier new', courier, monospace;"&gt;or.l Y,A&amp;nbsp; &amp;nbsp; //&amp;nbsp;now we merge, but the result is not a correct 32bit byte-swap&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;The resulting code is less efficient and the returned value is WRONG!&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;It seems like the compiler or the code optimizer assumes "moveu.bp X:(R1)+,A" writes (R1) to A0, while on 56800EX cores&amp;nbsp;a 16bit write to an accumulator register (either A,B,C or D) writes to the MSP (either A1,B1,C1,D1) and CLEARS the associated&amp;nbsp;LSP and&amp;nbsp;EXT registers.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Also the optimizer chooses to write A to external memory and then read it back&lt;/P&gt;&lt;P&gt;when it is absolutely not necessary.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The attached files contain the source code to reproduce the bug and a disassembly of the output.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In the attached file xxxx.c I also included two solutions to this problem (both are based on forcing the usage of A register instead of letting the compiler choose the best optimization).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I solved the issue in my program by modifying the assembly code, but the root cause of this bug needs to be identified and fixed, because &lt;EM&gt;it&amp;nbsp;is likely to have more widespread manifestations than just this one&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;(&amp;nbsp;it wrongly handles register mapping and stack access of 32bit values).&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 24 Jan 2019 16:33:22 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859126#M14957</guid>
      <dc:creator>Lorenzo_Mch_IT</dc:creator>
      <dc:date>2019-01-24T16:33:22Z</dc:date>
    </item>
    <item>
      <title>Re: (DSC) (Codewarrior 11) 32bit variable register optimization bug in DSC Compiler</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859127#M14958</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Lorenzo Micheletto,&lt;/P&gt;&lt;P&gt;Can you please send us a demo project for this problem? We need to reproduce it on our side.&lt;/P&gt;&lt;P&gt;Please also specify how to reproduce your problem with the demo.&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;&lt;P&gt;Jun Zhang&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 28 Jan 2019 08:48:15 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859127#M14958</guid>
      <dc:creator>ZhangJennie</dc:creator>
      <dc:date>2019-01-28T08:48:15Z</dc:date>
    </item>
    <item>
      <title>Re: (DSC) (Codewarrior 11) 32bit variable register optimization bug in DSC Compiler</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859128#M14959</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello&amp;nbsp;&lt;SPAN style="color: #000000; background-color: #ffffff;"&gt;Jun Zhang,&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The attached file TEST_20190128.zip contains a project reproducing the problem.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;When the test code is run, the "outer level" sequence wrongly outputs different values for nominal and nominal2&lt;/P&gt;&lt;P&gt;while the "inside if()" sequence correctly outputs the same value for nominal and nominal 2.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In file main.c inline function swapGetUINT32() gets wrongly expanded inside the outer level of&lt;/P&gt;&lt;P&gt;function APDU_FakeNetConf(), while inside the body of the if(){ ... }&amp;nbsp; statement&lt;/P&gt;&lt;P&gt;it gets correctly expanded.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;swapGetUINT32() was coded so that Areg variable could be mapped by the compiler's&lt;/P&gt;&lt;P&gt;code optimizer to one of the accumulator registers (A,B,C or D) .&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;But instead in the outer level it gets written to stack and accessed in the wrong word order&lt;/P&gt;&lt;P&gt;when accessing its lower word.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So there are two bugs:&lt;/P&gt;&lt;P&gt;1) a register allocation optimization bug (compiler does not understand it is not&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp;necessary to write Areg to stack)&lt;/P&gt;&lt;P&gt;2) wrong access to lower word of 32bit variable when mapped on stack.&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; It would be correct if the WHOLE 32bit variable was accessed&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; or if the intention was to access the HIGHER 16bit word&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; but it is WRONGwrong when trying to access the&amp;nbsp;LOWER 16bit word&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;That is, the faulty code generated in the "outer level" sequence of instructions is:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;adda #-3,SP,R1&lt;BR /&gt;move.l A10,X:(R1)&amp;nbsp; &amp;nbsp; // writes lower word to (SP-3), higher word to (SP-2)&lt;BR /&gt;......&lt;BR /&gt;move.w X0,X:(SP-2) // writes X0 to the higher word of the 32bit variable&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;while the "correct" code (besides not taking advantage of register caching) should be:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;&lt;SPAN&gt;adda #-3,SP,R1&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;move.l A10,X:(R1)&amp;nbsp; &amp;nbsp; // writes lower word to (SP-3), higher word to (SP-2)&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;......&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;move.w X0,X:(SP-3) // writes X0 to the&amp;nbsp;lower word of the 32bit variable&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;and the "perfect" code (as generated in the "inside if()" sequence of statements) is&lt;/SPAN&gt;&lt;SPAN&gt;:&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;SPAN&gt;move.w X0,A0&lt;/SPAN&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I hope this will be useful to pinpoint the source of the bug.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Best Regards&lt;/P&gt;&lt;P&gt;Lorenzo Micheletto&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 28 Jan 2019 11:38:29 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859128#M14959</guid>
      <dc:creator>Lorenzo_Mch_IT</dc:creator>
      <dc:date>2019-01-28T11:38:29Z</dc:date>
    </item>
    <item>
      <title>Re: (DSC) (Codewarrior 11) 32bit variable register optimization bug in DSC Compiler</title>
      <link>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859129#M14960</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Lorenzo Micheletto,&lt;/P&gt;&lt;P&gt;Thanks for your reply.&lt;/P&gt;&lt;P&gt;I have escalated this problem to develpement team. I will let you know if I get any feedback from them.&lt;/P&gt;&lt;P&gt;Thanks,&lt;/P&gt;&lt;P&gt;Jun Zhang&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 31 Jan 2019 06:37:19 GMT</pubDate>
      <guid>https://community.nxp.com/t5/CodeWarrior-for-MCU/DSC-Codewarrior-11-32bit-variable-register-optimization-bug-in/m-p/859129#M14960</guid>
      <dc:creator>ZhangJennie</dc:creator>
      <dc:date>2019-01-31T06:37:19Z</dc:date>
    </item>
  </channel>
</rss>

