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 clear="all">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>-- <br>dodohack@ybu<br>