<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"Book Antiqua";
        panose-1:2 4 6 2 5 3 5 3 3 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.msochpdefault, li.msochpdefault, div.msochpdefault
        {mso-style-name:msochpdefault;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:10.0pt;
        font-family:"Times New Roman",serif;}
span.emailstyle17
        {mso-style-name:emailstyle17;
        font-family:"Book Antiqua",serif;
        color:#943634;
        font-weight:normal;
        font-style:normal;
        text-decoration:none none;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Book Antiqua",serif;
        color:#943634;
        font-weight:normal;
        font-style:normal;
        text-decoration:none none;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-IE link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'>With my GCC implementation for this, it was the 64-bit ‘</span><span style='font-family:"Courier New";color:black;mso-fareast-language:EN-US'>ldd</span><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'>’ and ‘</span><span style='font-family:"Courier New";color:black;mso-fareast-language:EN-US'>std</span><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'>’ handling that I had to change.  It was working ok for big-endian, but since we use a little-endian Leon4 the usual implementation was getting the two FP registers loaded the wrong way round, but it wasn’t zeroing one of them.  The change I made was just to ensure that the endian ordering was correct (ditto 64-bit int).<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'>If you try hand-written assembly using ‘</span><span style='font-family:"Courier New";color:black;mso-fareast-language:EN-US'>ldd</span><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'>’ what happens?  I’m wondering if there is a hardware issue failing to perform the 64-bit load.  I’m assuming that you are using a proprietary development board for this, and it is possible that the bus has not been configured for the 64-bit load store extensions.  Just a thought.<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#002060;mso-fareast-language:EN-US'>            MartinO<o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634;mso-fareast-language:EN-US'><o:p> </o:p></span></p><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif'>From:</span></b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif'> Chris.Dewhurst [mailto:Chris.Dewhurst@lero.ie] <br><b>Sent:</b> 19 October 2016 23:37<br><b>To:</b> Martin.ORiordan@Movidius.com<br><b>Cc:</b> 'LLVM Developers' <llvm-dev@lists.llvm.org><br><b>Subject:</b> RE: [llvm-dev] [Sparc] vararg double issue on 32 bit Sparc processors<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>Hi Martin, <o:p></o:p></span></p><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'><o:p> </o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>That does sound like a very similar problem. As far as I've been able to tell, only half the value is loaded and the other half is zeroed-out (resulting, in fact, in an invalid floating point number, which is trapped when the register is next used). However, whether the other half is zeroed specifically by whatever this error is, or if it's just that the two halves are swapped, I can't be sure because I'm not 100% sure about what the correct floating-point representation of the number actually should be.<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'><o:p> </o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>Further, I still can't understand why the store and load makes the problem "go away".<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'><o:p> </o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>This is on a sparc, not sparcel.<o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'><o:p> </o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>Chris.<o:p></o:p></span></p><div><div class=MsoNormal align=center style='text-align:center'><span style='color:black'><hr size=2 width="100%" align=center></span></div><div id=divRpF452726><p class=MsoNormal style='margin-bottom:12.0pt'><b><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> Martin J. O'Riordan [martin.oriordan@movidius.com]<br><b>Sent:</b> 19 October 2016 23:18<br><b>To:</b> Chris.Dewhurst<br><b>Cc:</b> 'LLVM Developers'<br><b>Subject:</b> RE: [llvm-dev] [Sparc] vararg double issue on 32 bit Sparc processors</span><span style='color:black'><o:p></o:p></span></p></div><div><div><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'>Hi Chris,</span><span style='color:black'><o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'> </span><span style='color:black'><o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'>Can I bring this in a bit closer to Leon - is this specifically to do with 64-bit FP transactions with memory?  The reason I ask is that I had similar problems adapting Sparc Leon 3 and 4 which are V8 Sparc, but with 64-bit memory bus transactions with the GCC compiler.  It “feels” like the same problem, but LLVM versus GCC.  In the GCC case, the 64-bit memory transaction had the register endian ordering the wrong way round; perhaps it is something similar in LLVM?</span><span style='color:black'><o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'> </span><span style='color:black'><o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'>Are you doing this with “sparc” or “sparcel”?</span><span style='color:black'><o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'> </span><span style='color:black'><o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'>Thanks, MartinO</span><span style='color:black'><o:p></o:p></span></p><p class=MsoNormal><span style='font-family:"Book Antiqua",serif;color:#943634'> </span><span style='color:black'><o:p></o:p></span></p><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:black'>From:</span></b><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri",sans-serif;color:black'> llvm-dev [<a href="mailto:llvm-dev-bounces@lists.llvm.org">mailto:llvm-dev-bounces@lists.llvm.org</a>] <b>On Behalf Of </b>Chris.Dewhurst via llvm-dev<br><b>Sent:</b> 19 October 2016 22:27<br><b>To:</b> <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br><b>Subject:</b> [llvm-dev] [Sparc] vararg double issue on 32 bit Sparc processors</span><span style='color:black'><o:p></o:p></span></p></div></div><p class=MsoNormal><span style='color:black'> <o:p></o:p></span></p><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>Hi, </span><span style='color:black'><o:p></o:p></span></p><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>I've discovered a problem on Sparc processors (specifically, LEON, but I suspect but can't verify that it also happens on all Sparc processors).</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>The problem is, or appears to be with using double values in Sparc (32 bit).</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>Specifically, double values are not being loaded into registers correctly within a function using va_args. Only half the value is loaded (i.e. 32, rather than 64 bits of the value).</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>What I have also found is that the failure does not happen in all circumstances. The simplest situation I've been able to re-create that avoids the problem is to put a store and subsequent load instruction around the va_arg instruction that deals with the double value. e.g. (in an .ll file):</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>This code fragment does not work:</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>  define void @foo(i32 %v, i8* %ap) local_unnamed_addr {</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>  entry:</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %ap.addr = alloca i8*, align 4</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    store i8* %ap, i8** %ap.addr, align 4</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %0 = va_arg i8** %ap.addr, i64</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %conv = trunc i64 %0 to i32</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %1 = va_arg i8** %ap.addr, double</span><span style='color:black'><o:p></o:p></span></p></div></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    ...</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>Whereas this nearly identical code fragment, wrapping the store and load around the "double" va_arg instruction does work:</span><span style='color:black'><o:p></o:p></span></p></div><div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>  define void @foo(i32 %v, i8* %ap) local_unnamed_addr {</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    entry:</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %ap.addr = alloca i8*, align 4</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    store i8* %ap, i8** %ap.addr, align 4</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %0 = va_arg i8** %ap.addr, i64</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %conv = trunc i64 %0 to i32</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    store i32 %conv, i32* @foo_arg, align 4</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %1 = va_arg i8** %ap.addr, double</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    %2 = load i32, i32* @foo_arg, align 4</span><span style='color:black'><o:p></o:p></span></p></div></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>    ...</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>I had been attempting to make various changes to SparcISelLowering.cpp to try to simulate something similar where the code is output, but I don't feel as though I'm heading in the right direction. I'm still not sure quite where the source of the problem lies.</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>I can provide more details on specifics, but rather than head off into excessive details immediately, I'd appreciate if anyone can help me identify what direction I really should be taking to fix this problem. I'm not convinced I've been going about it the right way so far.</span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'> </span><span style='color:black'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Tahoma",sans-serif;color:black'>Chris Dewhurst, Lero, University of Limerick.</span><span style='color:black'><o:p></o:p></span></p></div></div></div></div></div></div></div></div></body></html>