<div dir="ltr"><div>The details can be found in SPARC Architecture Manuals, but the high level is that local registers are safe to use if the register window has changed. For a leaf function (that does not call any other function), the compiler can "leaf-optimize" the function by not changing the register window. In such case, only the output (o0-o7) and global registers can safely be accessed. My guess is that your contractor tried to get around this somewhat with the (poorly designed, incorrectly implemented) save/restore pair. The better solution would have been to let gcc assign the register, as you are now doing, or to use a register that is "safe" such as %o0 and put it in the clobber list.<br>
<br></div>-Gedare<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 24, 2013 at 9:31 AM, Leonard Bise <span dir="ltr"><<a href="mailto:leonard.bise@syderal.ch" target="_blank">leonard.bise@syderal.ch</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thank you Gedare for the input. <div>There is also something not very clear for me.</div><div>Claudio earlier told me that using %l7 register was not safe but how come?</div>
<div>Since it is a local register I'd expect I can do whatever I want with it?</div>
</div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">2013/4/24 Gedare Bloom <span dir="ltr"><<a href="mailto:gedare@rtems.org" target="_blank">gedare@rtems.org</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">This is a lot better. As Joel said, there is still a problem if an interrupt can come. For that you should use a general timer if available. Also, I made one comment below.<br><div><div class="gmail_extra">

<br>
<br><div class="gmail_quote"><div>On Wed, Apr 24, 2013 at 5:54 AM, Leonard Bise <span dir="ltr"><<a href="mailto:leonard.bise@syderal.ch" target="_blank">leonard.bise@syderal.ch</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div dir="ltr">Thanks a lot for your inputs guys. I realise now that I actually didn't know exactly how to write inline assembly code properly.<div><br></div><div>Joel: Yes the goal of this function is to have a known number of cycles. Thank you for your precious input.<br>



<div><br></div><div>Here is the final code version we settled on.</div><div><br></div><div><div><p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">void SCET_wait_2us(void) {<u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    {<u></u><u></u></span></p><p style="font-family:arial,sans-serif;font-size:13px">



<span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">        /*#[ operation SCET_wait_2us() */<u></u><u></u></span></p></div><p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    uint32 count;<u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">        /* Performs a 60us delay using an __asm__ __volatile__ loop, this piece of code has been<u></u><u></u></span></p>


<div>
<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">         * measured on HW to validate the duration is correct */<u></u><u></u></span></p>



</div><p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("set " XSTR(NB_ITER_60US) ", %0" : "=r"(count));<u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("StartLoop1us:");<u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("dec 1, %0" : "=r" (count));<u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("cmp %0, 0" : "=r" (count));</span></p>


</div></div></div></blockquote></div><div>While this should work, the count variable is actually an input here, so you really just need<br></div><div>__asm__ __volatile__("cmp %0, 0" : :  "r" (count));<br>

</div>
<div> <br></div><div>As always, check the output of the assembler pass to make sure your function looks like how you expect. The compiler could (in theory) move data between memory and register within this code block.<br>


</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div dir="ltr"><div><div><p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)"><u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("bne StartLoop1us");<u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">    __asm__ __volatile__("nop");<u></u><u></u></span></p>
<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)">        </span><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)" lang="FR-BE">/*#]*/<u></u><u></u></span></p>



<p style="font-family:arial,sans-serif;font-size:13px"><span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)" lang="FR-BE">    }<u></u><u></u></span></p><p style="font-family:arial,sans-serif;font-size:13px">



<span style="font-size:11pt;font-family:'Courier New',serif;color:rgb(31,73,125)" lang="FR-BE">}</span></p></div></div></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">
2013/4/23 Joel Sherrill <span dir="ltr"><<a href="mailto:joel.sherrill@oarcorp.com" target="_blank">joel.sherrill@oarcorp.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    <div>Hi<br>
      <br>
      SPARC register usage combined with the the register windowing<br>
      makes things difficult to figure out.  Using save/restore in the
      middle<br>
      of inline assembly like that is too scary for my personal taste.
      It is<br>
      certainly not normal SPARC programming.<br>
      <br>
      I don't like the fact they used a "trivial" save instruction which
      adds<br>
      0 bytes to the stack as best I can tell. It is equivalent to <br>
      "save %g0,%g0,%g0". Normal usage includes three real arguments<br>
      and looks more like this:<br>
      <br>
              PUBLIC(_CPU_Context_save_fp)<br>
      SYM(_CPU_Context_save_fp):<br>
              save    %sp, -CPU_MINIMUM_STACK_FRAME_SIZE, %sp<br>
      <br>
      That saves space on the stack to save the window. I THINK the
      trivial<br>
      save rotates the CWP but doesn't make space. I expect this would <br>
      lead to a crash eventually as (my guess) is that you end up with<br>
      two register windows associated with the same spot on the stack.<br>
      You have rotated twice but only saved one hole on the stack. As<br>
      you start returning and restoring, I expect this would result in<br>
      some odd type of stack reuse.<br>
      <br>
      My first question is always ... Why is this in inline assembly
      anyway?<br>
      <br>
      If it is to do a tight loop with a known number of cycles, then
      the<br>
      second round of questions are: <br>
      <br>
      + Why didn't they use the proper asm statement constraints?<br>
      + Why isn't this asm volatile?<br>
      + What happens if an interrupt occurs in the middle of this?<br>
      <br>
      If you are using a general purpose register gcc may use, then you
      need to<br>
      specify that. Generally speaking, you can declare local variables
      and "pass"<br>
      them to inline asm via constraint specifications. This lets gcc
      pick the register(s)<br>
      and avoids one type of trouble.<br>
      <br>
      There are some asm with constraint examples in
      cpukit/score/cpu/sparc.<br>
      <br>
      --joel<div><div><br>
      <br>
      On 4/23/2013 4:02 AM, Leonard Bise wrote:<br>
    </div></div></div><div><div>
    <blockquote type="cite">
      <div dir="ltr">Hello all,
        <div><br>
        </div>
        <div>I'm having a problem regarding the processor window
          registers that I cannot explain easily mostly because I'm not
          super familiar with this subject.</div>
        <div><br>
        </div>
        <div>
          First, I'm using a LEON2 Sparc v8 processor and RTEMS 4.8
          version which is required by our project.</div>
        <div><br>
        </div>
        <div>We have a function using inline assembly to perform a flat
          delay, here is the code it use.</div>
        <div><br>
        </div>
        <div>
          <div style="border:1pt solid windowtext;padding:1pt 4pt">
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">void
                SCET_wait_2us(void)
                {</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">    {</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  /*#[ operation SCET_wait_2us() */</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  /* Performs a 60us delay using an ASM loop, this piece
                of code has been</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                   * measured on HW to validate the duration is correct
                */</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  __asm__("                
                               \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          </span><span>save;          
                                 \</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          set " XSTR(NB_ITER_60US) ", %l7; \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          StartLoop1us:        
                           \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          dec 1, %l7;        
                             \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          cmp %l7, 0;        
                             \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          bne StartLoop1us;      
                         \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          nop;          
                                  \</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          </span><span>restore;          
                              \</span><span></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                          ");</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">     
                  /*#]*/</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">    }</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
            <p style="border:none;padding:0cm"><span style="font-size:9pt;font-family:'Courier New'">}</span><span style="font-size:9pt;font-family:'Courier New'"></span></p>
          </div>
          <div><br>
          </div>
          <div>Originally this code didn't have the save and
            restore instruction but our sub contractor added them
            because they had problems compiling. I find it an odd
            solution but whatever.</div>
          <div>
            <br>
          </div>
          <div>Once this code was implemented we started seeing
            random processor reset occurring in various contexts.</div>
          <div><br>
          </div>
          <div>I tested this code while being in the Eclipse
            debugger and once the crash happened I noticed I had a
            segmentation fault in Eclipse. I used GRMON to check the
            processor register and noticed that the last trap that
            occurred was a window underflow trap 0x06.</div>
          <div><br>
          </div>
          <div>I found in the RTEMS sources the code for this
            handler, and while I haven't understood everything I took
            out that the code was trying to recover from this error, is
            this correct?</div>
          <div>
            I copied the trap handler code below.</div>
          <div><br>
          </div>
          <div>RTEMS 4.8 branch</div>
          file : rtems / c / src / lib / libcpu / sparc / reg_win /
          window.S
          <div><b style="line-height:25px;font-size:18px;font-family:Helvetica,arial,freesans,clean,sans-serif;margin:0px;border:0px;padding:0px"><br>
            </b></div>
          SYM(window_underflow_trap_handler):<br>
          <br>
                  /*<br>
                   * Calculate new WIM by "rotating" the valid bits in
          the WIM left<br>
                   * by one position. The following shows how the bits
          move for a SPARC<br>
                   * cpu implementation where
          SPARC_NUMBER_OF_REGISTER_WINDOWS is 8.<br>
                   *<br>
                   * OLD WIM = 76543210<br>
                   * NEW WIM = 07654321<br>
                   *<br>
                   * NOTE: New WIM must be stored in a global register
          since the<br>
                   * "save" instruction just prior to the load of the
          wim<br>
                   * register will result in the local register set
          changing.<br>
                   */<br>
          <br>
                  mov %wim, %l3 ! Calculate new WIM<br>
                  sll %l3, 1, %l4 ! l4 = WIM << 1<br>
                  srl %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1, %l5<br>
                                                  ! l5 = WIM >>
          (Number Windows-1)<br>
                  or %l5, %l4, %l5 ! l5 = (WIM << 1) |<br>
                                                  ! (WIM >>
          (Number Windows-1))<br>
                  mov %l5, %wim ! load the new WIM<br>
                  nop; nop; nop<br>
                  restore ! Two restores to get into the<br>
                  restore ! window to restore<br>
                  ldd [%sp + 0x00], %l0 ! First the local register set<br>
                  ldd [%sp + 0x08], %l2<br>
                  ldd [%sp + 0x10], %l4<br>
                  ldd [%sp + 0x18], %l6<br>
                  ldd [%sp + 0x20], %i0 ! Then the input registers<br>
                  ldd [%sp + 0x28], %i2<br>
                  ldd [%sp + 0x30], %i4<br>
                  ldd [%sp + 0x38], %i6<br>
                  save ! Get back to the trap window.<br>
                  save<br>
                  jmp %l1 ! Re-execute restore.<br>
                  rett %l2
          <div><br>
          </div>
          <div>From my understanding this code should not ever
            fail, is that correct?</div>
          <div>What I'm not sure is that if this type of trap
            can be a common occurrence or if that means something went
            bad in the software.</div>
          <div><br>
          </div>
          <div>Basically now I removed the save/restore and it
            seems to be working fine but I'll have to explain exactly
            what was happening before.</div>
          <div>Is the compiler not expecting the user to add
            save/restore and could that lead to the behavior we see
            sometimes (processor reset). What are the usual way to
            handle this type of inline assembly? Never use save/restore?</div>
          <div><br>
          </div>
          <div>Also our customer gave us a sequence of command
            to send to the software that would produce this reset
            systematically however when we got the equipment over here,
            I tried with the same code the sequence and it is not
            happening as often as they say. There seem to be a lot of
            randomness to this problem.</div>
          <div><br>
          </div>
          <div>I really hope someone can provide some knowledge
            on this type of issue.</div>
          -- <br>
          <div><span>
              <div><b><img><br>
                </b></div>
              <div>
                <b>Léonard Bise</b></div>
              <div>Software Design Engineer
              </div>
              <div>Direct Line <a href="tel:%2B41%20%280%2932%20338%209902" value="+41323389902" target="_blank">+41 (0)32 338 9902</a></div>
              <div><br>
              </div>
              <div><b>SYDERAL SA</b></div>
              <div>Neuenburgstrasse 7</div>
              <div>CH-3238 Gals (Switzerland)</div>
              <div>Desk Line <a href="tel:%2B41%20%280%2932%20338%209800" value="+41323389800" target="_blank">+41 (0)32 338 9800</a></div>
              <div>Web Site <a href="http://www.syderal.ch" target="_blank">http://www.syderal.ch</a></div>
            </span></div>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    </div></div><span><font color="#888888"><pre cols="72">-- 
Joel Sherrill, Ph.D.             Director of Research & Development 
<a href="mailto:joel.sherrill@OARcorp.com" target="_blank">joel.sherrill@OARcorp.com</a>        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805 
Support Available                <a href="tel:%28256%29%20722-9985" value="+12567229985" target="_blank">(256) 722-9985</a> </pre>
  </font></span></div>

</blockquote></div><br><br clear="all"><div><br></div>-- <br><div><span><div><b><img><br></b></div><div><b>Léonard Bise</b></div><div>Software Design Engineer
</div><div>Direct Line <a href="tel:%2B41%20%280%2932%20338%209902" value="+41323389902" target="_blank">+41 (0)32 338 9902</a></div><div><br></div><div><b>SYDERAL SA</b></div><div>Neuenburgstrasse 7</div><div>CH-3238 Gals (Switzerland)</div>


<div>Desk Line <a href="tel:%2B41%20%280%2932%20338%209800" value="+41323389800" target="_blank">+41 (0)32 338 9800</a></div><div>Web Site <a href="http://www.syderal.ch" target="_blank">http://www.syderal.ch</a></div>
</span></div>
</div>
</div></div><br></div></div><div>_______________________________________________<br>
rtems-users mailing list<br>
<a href="mailto:rtems-users@rtems.org" target="_blank">rtems-users@rtems.org</a><br>
<a href="http://www.rtems.org/mailman/listinfo/rtems-users" target="_blank">http://www.rtems.org/mailman/listinfo/rtems-users</a><br>
<br></div></blockquote></div><br></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div><span><div><b><img><br></b></div><div><b>Léonard Bise</b></div><div>Software Design Engineer
</div><div>Direct Line <a href="tel:%2B41%20%280%2932%20338%209902" value="+41323389902" target="_blank">+41 (0)32 338 9902</a></div><div><br></div><div><b>SYDERAL SA</b></div><div>Neuenburgstrasse 7</div><div>CH-3238 Gals (Switzerland)</div>
<div>Desk Line <a href="tel:%2B41%20%280%2932%20338%209800" value="+41323389800" target="_blank">+41 (0)32 338 9800</a></div><div>Web Site <a href="http://www.syderal.ch" target="_blank">http://www.syderal.ch</a></div>
</span></div>
</div>
</div></div></blockquote></div><br></div>