[LLVMdev] endian issue of llvm-gcc and llvm backend
dodo
dodohack at gmail.com
Thu Jun 4 01:14:28 PDT 2009
Hi, all
As I'm a Chinese, be patient of my poor description below.
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:
little endian:
=============================================
......
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"
target triple = "nds32le-linux"
define i64 @__ashldi3(i64 %u, i32 %b) nounwind readnone {
entry:
%0 = icmp eq i32 %b, 0 ; <i1> [#uses=1]
br i1 %0, label %bb5, label %bb1
bb1: ; preds = %entry
%1 = trunc i64 %u to i32 ; <i32> [#uses=3]
%2 = sub i32 32, %b ; <i32> [#uses=3]
%3 = icmp sgt i32 %2, 0 ; <i1> [#uses=1]
br i1 %3, label %bb3, label %bb2
......
==============================================
big endian:
==============================================
......
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"
target triple = "nds32-linux"
define i64 @__ashldi3(i64 %u, i32 %b) nounwind readnone {
entry:
%0 = icmp eq i32 %b, 0 ; <i1> [#uses=1]
br i1 %0, label %bb5, label %bb1
bb1: ; preds = %entry
%sroa.store.elt = lshr i64 %u, 32 ; <i64> [#uses=1]
%1 = trunc i64 %sroa.store.elt to i32 ; <i32> [#uses=3]
%2 = sub i32 32, %b ; <i32> [#uses=3]
%3 = icmp sgt i32 %2, 0 ; <i1> [#uses=1]
br i1 %3, label %bb3, label %bb2
......
==============================================
>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.
While generate asm code from these 2 different IR, I got the same asm code.
The following is the asm code which are mips like:
(NOTE: $rx indicates a 32 bits register x, #x indicates constant, subri $r3,
$r2, #32 means r3 = 32 - r2,
r0, r1 contain the first 64 bits parameter which contains %u, r2 contains
the second parameter %b)
beqz $r2,83f6 <__ashldi3+0x2a>
subri $r3,$r2,#32
blez $r3,83fa <__ashldi3+0x2e>
sll $r1,$r1,$r2
srl $r3,$r0,$r3
or $r3,$r3,$r1
sll $r1,$r0,$r2
movi $r2,#0
mov $r0,$r1
or $r1,$r3,$r2
ret $lp
ret $lp
subri $r3,$r3,#0
movi $r1,#0
sll $r3,$r0,$r3
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.
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.
The result is that: llvm-gcc gen'ed big endian code + llc gen'ed big endian
code = little endian code, am I right?
If I want to generate correct asm code for big endian? what should I do?
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!
--
dodohack at ybu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090604/7f7a6d26/attachment.html>
More information about the llvm-dev
mailing list