<div>Hello,</div>
<div> </div>
<div>I am new here. This is my first post.</div>
<div>I spent about three days on trying out LLVM by developing a front-end which is able to generate LLVM IR for a subset of C language. I have not applied any optimization pass yet. On linux, it can go all the way through with the system native assemlber and linker to generate executables. And it runs. I ran into problems on Windows since the generated assembly code is not able to be assembled by NASM.</div>
<div> </div>
<div>Here is an example C code:</div>
<div> </div>
<div>int gv;</div>
<div>int foo(int p)<br>{<br> int lv;<br> gv = p;</div>
<div> if (p > 5) {<br> lv = 0;<br> while (gv>0) {<br> lv = lv + gv;<br> gv = gv - 1;<br> }<br> }<br> else {<br> lv = 1;<br> while (gv>0) {<br> lv = lv * gv;<br> gv = gv - 1;<br>
}<br> }</div>
<div> return lv;<br>}</div>
<div> </div>
<div>Here is the LLVM IR I generated:</div>
<div> </div>
<div>; ModuleID = 'my cool jit'</div>
<div>@gv = weak global i32 0 ; <i32*> [#uses=9]</div>
<div>define i32 @foo(i32 %p) {<br>entry:<br> %lv = alloca i32 ; <i32*> [#uses=8]<br> %p1 = alloca i32 ; <i32*> [#uses=3]<br> store i32 %p, i32* %p1<br>
store i32 0, i32* %lv<br> %p2 = load i32* %p1 ; <i32> [#uses=1]<br> store i32 %p2, i32* @gv<br> %p3 = load i32* %p1 ; <i32> [#uses=1]<br> %0 = icmp ugt i32 %p3, 5 ; <i1> [#uses=1]<br>
%1 = zext i1 %0 to i32 ; <i32> [#uses=1]<br> %2 = icmp ne i32 %1, 0 ; <i1> [#uses=1]<br> br i1 %2, label %then, label %else</div>
<div>then: ; preds = %entry<br> store i32 0, i32* %lv<br> br label %while</div>
<div>while: ; preds = %whilebody, %then<br> %gv = load i32* @gv ; <i32> [#uses=1]<br> %3 = icmp ugt i32 %gv, 0 ; <i1> [#uses=1]<br>
%4 = zext i1 %3 to i32 ; <i32> [#uses=1]<br> %5 = icmp ne i32 %4, 0 ; <i1> [#uses=1]<br> br i1 %5, label %whilebody, label %whilecont</div>
<div>whilebody: ; preds = %while<br> %lv4 = load i32* %lv ; <i32> [#uses=1]<br> %gv5 = load i32* @gv ; <i32> [#uses=1]<br>
%6 = add i32 %lv4, %gv5 ; <i32> [#uses=1]<br> store i32 %6, i32* %lv<br> %gv6 = load i32* @gv ; <i32> [#uses=1]<br> %7 = sub i32 %gv6, 1 ; <i32> [#uses=1]<br>
store i32 %7, i32* @gv<br> br label %while</div>
<div>whilecont: ; preds = %while<br> br label %ifcont</div>
<div>else: ; preds = %entry<br> store i32 1, i32* %lv<br> br label %while7</div>
<div>while7: ; preds = %whilebody9, %else<br> %gv8 = load i32* @gv ; <i32> [#uses=1]<br> %8 = icmp ugt i32 %gv8, 0 ; <i1> [#uses=1]<br>
%9 = zext i1 %8 to i32 ; <i32> [#uses=1]<br> %10 = icmp ne i32 %9, 0 ; <i1> [#uses=1]<br> br i1 %10, label %whilebody9, label %whilecont13</div>
<div>whilebody9: ; preds = %while7<br> %lv10 = load i32* %lv ; <i32> [#uses=1]<br> %gv11 = load i32* @gv ; <i32> [#uses=1]<br>
%11 = mul i32 %lv10, %gv11 ; <i32> [#uses=1]<br> store i32 %11, i32* %lv<br> %gv12 = load i32* @gv ; <i32> [#uses=1]<br> %12 = sub i32 %gv12, 1 ; <i32> [#uses=1]<br>
store i32 %12, i32* @gv<br> br label %while7</div>
<div>whilecont13: ; preds = %while7<br> br label %ifcont</div>
<div>ifcont: ; preds = %whilecont13, %whilecont<br> %lv14 = load i32* %lv ; <i32> [#uses=1]<br> ret i32 %lv14<br>}</div>
<div> </div>
<div>And here is the assembly code I generated with "llc -march=x86 -x86-asm-sytax=intel filename".</div>
<div> .686<br> .MMX<br> .XMM<br> .model flat</div>
<div> EXTERN _abort:near</div>
<div><br> .text<br> public _foo<br> ALIGN 16<br>_foo proc near<br> sub ESP, 8<br>$label1:<br> mov EAX, DWORD PTR [ESP + 12]<br> mov DWORD PTR [ESP], EAX<br> mov DWORD PTR [ESP + 4], 0<br> mov EAX, DWORD PTR [ESP]<br> mov DWORD PTR [_gv], EAX<br>
cmp DWORD PTR [ESP], 6<br> jb $BB1_4<br>$BB1_1: ; %then<br> mov DWORD PTR [ESP + 4], 0<br> ALIGN 16<br>$BB1_2: ; %while<br>
; Loop Depth 1<br> ; Loop Header<br> ; Inner Loop<br>
cmp DWORD PTR [_gv], 0<br> je $BB1_7<br>$BB1_3: ; %whilebody<br> ; Loop Depth 1<br> ; Loop Header is BB1_2<br>
; Inner Loop<br> mov EAX, DWORD PTR [_gv]<br> add DWORD PTR [ESP + 4], EAX<br> dec DWORD PTR [_gv]<br> jmp $BB1_2<br>$BB1_4: ; %else<br>
mov DWORD PTR [ESP + 4], 1<br> jmp $BB1_6<br> ALIGN 16<br>$BB1_5: ; %whilebody9<br> ; Loop Depth 1<br> ; Loop Header is BB1_6<br>
; Inner Loop<br> mov EAX, DWORD PTR [_gv]<br> imul EAX, DWORD PTR [ESP + 4]<br> mov DWORD PTR [ESP + 4], EAX<br> dec DWORD PTR [_gv]<br>$BB1_6: ; %while7<br>
; Loop Depth 1<br> ; Loop Header<br> ; Inner Loop<br>
cmp DWORD PTR [_gv], 0<br> jne $BB1_5<br>$BB1_7: ; %ifcont<br> mov EAX, DWORD PTR [ESP + 4]<br> add ESP, 8<br> ret<br>_foo endp<br>_gv? SEGEMNT PARA common 'COMMON'<br>
_gv: ; gv<br> db 4 dup(0)<br>_gv? ends<br> end</div>
<div> </div>
<div>The above assembly code cannot be assembled by NASM. I got the following error message:</div>
<div> </div>
<div>cg1.s:1: error: attempt to define a local label before any non-local labels<br>cg1.s:2: error: attempt to define a local label before any non-local labels<br>cg1.s:3: error: attempt to define a local label before any non-local labels<br>
cg1.s:4: error: attempt to define a local label before any non-local labels<br>cg1.s:4: error: parser: instruction expected<br>cg1.s:6: error: binary format does not support any special symbol types<br>cg1.s:9: error: attempt to define a local label before any non-local labels<br>
cg1.s:10: error: parser: instruction expected<br>cg1.s:12: error: parser: instruction expected<br>cg1.s:15: error: comma, colon or end of line expected<br>cg1.s:16: error: comma, colon or end of line expected<br>cg1.s:17: error: comma, colon or end of line expected<br>
cg1.s:18: error: comma, colon or end of line expected<br>cg1.s:19: error: comma, colon or end of line expected<br>cg1.s:20: error: comma, colon or end of line expected<br>cg1.s:23: error: comma, colon or end of line expected<br>
cg1.s:29: error: comma, colon or end of line expected<br>cg1.s:35: error: comma, colon or end of line expected<br>cg1.s:36: error: comma, colon or end of line expected<br>cg1.s:37: error: comma, colon or end of line expected<br>
cg1.s:40: error: comma, colon or end of line expected<br>cg1.s:47: error: comma, colon or end of line expected<br>cg1.s:48: error: comma, colon or end of line expected<br>cg1.s:49: error: comma, colon or end of line expected<br>
cg1.s:50: error: comma, colon or end of line expected<br>cg1.s:55: error: comma, colon or end of line expected<br>cg1.s:58: error: comma, colon or end of line expected<br>cg1.s:61: error: symbol `_foo' redefined<br>cg1.s:61: error: parser: instruction expected<br>
cg1.s:62: error: parser: instruction expected<br>cg1.s:64: error: comma expected after operand 1<br>cg1.s:65: error: symbol `_gv?' redefined<br>cg1.s:65: error: parser: instruction expected</div>
<div> </div>
<div>I am not sure whether there is any command line option that is required for generating NASM assembly code. Looked into the document and command line help. But I cannot find anything that helps. I would appreciate it if anyone could provide some hint.</div>
<div> </div>
<div>BTW: The getting started document with Visual Studio looks very out-of-dated.</div>
<div> </div>
<div>Thanks,</div>
<div> </div>
<div>Bengu </div>
<div> </div>
<div> </div>