Hello, Sam<br><br>I used non-arm backend, and I used a target which likes mips has both big and little endianness. And I have ported llvm-gcc to this platform along with llvm backend.<br>The issue is about IR endianness and how backend deal with the data and instructions in different endian, since I discovered 2 different IR generates the same asm code by llc for different endian target.<br>
<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
Message: 27<br>
Date: Thu, 4 Jun 2009 05:22:07 -0700 (PDT)<br>
From: Samuel Crow <<a href="mailto:samuraileumas@yahoo.com">samuraileumas@yahoo.com</a>><br>
Subject: Re: [LLVMdev] endian issue of llvm-gcc and llvm backend<br>
To: LLVM Developers Mailing List <<a href="mailto:llvmdev@cs.uiuc.edu">llvmdev@cs.uiuc.edu</a>><br>
Message-ID: <<a href="mailto:157221.53893.qm@web62002.mail.re1.yahoo.com">157221.53893.qm@web62002.mail.re1.yahoo.com</a>><br>
Content-Type: text/plain; charset=us-ascii<br>
<br>
<br>
Hello,<br>
<br>
According to the frequently asked questions on the LLVM webpage, C++ and C cannot currently be used for platform indedpendent usage.  Your discovery doesn't fall on one of the often discovered problems though so it may be a bug in the ARM backend.  The ARM backend is considered to be experimental at this point so it is likely to have incorrect code in it.<br>

<br>
I hope I answered your question well enough,<br>
<br>
--Sam<br>
________________________________<br>
From: dodo <<a href="mailto:dodohack@gmail.com">dodohack@gmail.com</a>><br>
To: <a href="mailto:llvmdev@cs.uiuc.edu">llvmdev@cs.uiuc.edu</a><br>
Sent: Thursday, June 4, 2009 3:14:28 AM<br>
Subject: [LLVMdev] endian issue of llvm-gcc and llvm backend<br>
<br>
Hi, all<br>
<br>
As I'm a Chinese, be patient of my poor description below.<br>
<br>
I compiled libgcc into llvm bitcode in both big endian and little endian. and got 2 different version of function: _ashldi3, the following is the fragment of this function:<br>
<br>
little endian:<br>
=============================================<br>
......<br>
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"<br>
target triple = "nds32le-linux"<br>
<br>
define i64 @__ashldi3(i64 %u, i32 %b) nounwind readnone {<br>
entry:<br>
        %0 = icmp eq i32 %b, 0          ; <i1> [#uses=1]<br>
        br i1 %0, label %bb5, label %bb1<br>
<br>
bb1:            ; preds = %entry<br>
        %1 = trunc i64 %u to i32                ; <i32> [#uses=3]<br>
        %2 = sub i32 32, %b             ; <i32> [#uses=3]<br>
        %3 = icmp sgt i32 %2, 0         ; <i1> [#uses=1]<br>
        br i1 %3, label %bb3, label %bb2<br>
......<br>
==============================================<br>
<br>
big endian:<br>
==============================================<br>
......<br>
target datalayout = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"<br>
target triple = "nds32-linux"<br>
<br>
define i64 @__ashldi3(i64 %u, i32 %b) nounwind readnone {<br>
entry:<br>
        %0 = icmp eq i32 %b, 0          ; <i1> [#uses=1]<br>
        br i1 %0, label %bb5, label %bb1<br>
<br>
bb1:            ; preds = %entry<br>
        %sroa.store.elt = lshr i64 %u, 32               ; <i64> [#uses=1]<br>
        %1 = trunc i64 %sroa.store.elt to i32           ; <i32> [#uses=3]<br>
        %2 = sub i32 32, %b             ; <i32> [#uses=3]<br>
        %3 = icmp sgt i32 %2, 0         ; <i1> [#uses=1]<br>
        br i1 %3, label %bb3, label %bb2<br>
......<br>
==============================================<br>
<br>
>From the generated IR, we could see that llvm IR is endian dependent and it know how to get the low 32 bits of a 64 bits parameter.<br>
<br>
While generate asm code from these 2 different IR,  I got the same asm code.<br>
The following is the asm code which are mips like:<br>
(NOTE: $rx indicates a 32 bits register x, #x indicates constant, subri $r3, $r2, #32 means r3 = 32 - r2,<br>
r0, r1 contain the first 64 bits parameter which contains %u, r2 contains the second parameter %b)<br>
<br>
beqz $r2,83f6 <__ashldi3+0x2a><br>
subri $r3,$r2,#32<br>
blez $r3,83fa <__ashldi3+0x2e><br>
sll $r1,$r1,$r2<br>
srl $r3,$r0,$r3<br>
or $r3,$r3,$r1<br>
sll $r1,$r0,$r2<br>
movi $r2,#0<br>
mov $r0,$r1<br>
or $r1,$r3,$r2<br>
ret $lp<br>
ret $lp<br>
subri $r3,$r3,#0<br>
movi $r1,#0<br>
sll $r3,$r0,$r3<br>
<br>
The above asm code is tested ok in little endian, and not ok in big endian, because it does not get paramter %u correctly, for big endian, r0, r1 in  that asm code should be exchanged  for endian  issue.<br>
<br>
One possible reason is that I generate code for big endian and llvm-gcc really generates big endian IR for me(from the presented IR, it did). Then I use llc to generate asm code, llc eat the target triple and/or datalayout from the bitcode and generates big endian asm code for me again.<br>

The result is that:  llvm-gcc gen'ed big endian code + llc gen'ed big endian code = little endian code, am I right?<br>
<br>
If I want to generate correct asm code for big endian? what should I do?<br>
I have tried to generate big endian asm code from little endian IR by giving -march option to llc to force the target to big endian, but this seems to be unworkable!<br>
<br></blockquote></div><br>-- <br>dodohack@ybu<br>