[LLVMdev] llc generated machine assembly code for NASM

Bengu Li libengu at gmail.com
Wed Jan 27 19:28:15 PST 2010


Hello,

I am new here. This is my first post.
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.

Here is an example C code:

int gv;
int foo(int p)
{
  int lv;
  gv = p;
  if (p > 5) {
    lv = 0;
    while (gv>0) {
      lv = lv + gv;
      gv = gv - 1;
    }
  }
  else {
    lv = 1;
    while (gv>0) {
      lv = lv * gv;
      gv = gv - 1;
    }
  }
  return lv;
}

Here is the LLVM IR I generated:

; ModuleID = 'my cool jit'
@gv = weak global i32 0                           ; <i32*> [#uses=9]
define i32 @foo(i32 %p) {
entry:
  %lv = alloca i32                                ; <i32*> [#uses=8]
  %p1 = alloca i32                                ; <i32*> [#uses=3]
  store i32 %p, i32* %p1
  store i32 0, i32* %lv
  %p2 = load i32* %p1                             ; <i32> [#uses=1]
  store i32 %p2, i32* @gv
  %p3 = load i32* %p1                             ; <i32> [#uses=1]
  %0 = icmp ugt i32 %p3, 5                        ; <i1> [#uses=1]
  %1 = zext i1 %0 to i32                          ; <i32> [#uses=1]
  %2 = icmp ne i32 %1, 0                          ; <i1> [#uses=1]
  br i1 %2, label %then, label %else
then:                                             ; preds = %entry
  store i32 0, i32* %lv
  br label %while
while:                                            ; preds = %whilebody,
%then
  %gv = load i32* @gv                             ; <i32> [#uses=1]
  %3 = icmp ugt i32 %gv, 0                        ; <i1> [#uses=1]
  %4 = zext i1 %3 to i32                          ; <i32> [#uses=1]
  %5 = icmp ne i32 %4, 0                          ; <i1> [#uses=1]
  br i1 %5, label %whilebody, label %whilecont
whilebody:                                        ; preds = %while
  %lv4 = load i32* %lv                            ; <i32> [#uses=1]
  %gv5 = load i32* @gv                            ; <i32> [#uses=1]
  %6 = add i32 %lv4, %gv5                         ; <i32> [#uses=1]
  store i32 %6, i32* %lv
  %gv6 = load i32* @gv                            ; <i32> [#uses=1]
  %7 = sub i32 %gv6, 1                            ; <i32> [#uses=1]
  store i32 %7, i32* @gv
  br label %while
whilecont:                                        ; preds = %while
  br label %ifcont
else:                                             ; preds = %entry
  store i32 1, i32* %lv
  br label %while7
while7:                                           ; preds = %whilebody9,
%else
  %gv8 = load i32* @gv                            ; <i32> [#uses=1]
  %8 = icmp ugt i32 %gv8, 0                       ; <i1> [#uses=1]
  %9 = zext i1 %8 to i32                          ; <i32> [#uses=1]
  %10 = icmp ne i32 %9, 0                         ; <i1> [#uses=1]
  br i1 %10, label %whilebody9, label %whilecont13
whilebody9:                                       ; preds = %while7
  %lv10 = load i32* %lv                           ; <i32> [#uses=1]
  %gv11 = load i32* @gv                           ; <i32> [#uses=1]
  %11 = mul i32 %lv10, %gv11                      ; <i32> [#uses=1]
  store i32 %11, i32* %lv
  %gv12 = load i32* @gv                           ; <i32> [#uses=1]
  %12 = sub i32 %gv12, 1                          ; <i32> [#uses=1]
  store i32 %12, i32* @gv
  br label %while7
whilecont13:                                      ; preds = %while7
  br label %ifcont
ifcont:                                           ; preds = %whilecont13,
%whilecont
  %lv14 = load i32* %lv                           ; <i32> [#uses=1]
  ret i32 %lv14
}

And here is the assembly code I generated with "llc -march=x86
-x86-asm-sytax=intel filename".
 .686
 .MMX
 .XMM
 .model flat
 EXTERN _abort:near

 .text
 public _foo
 ALIGN 16
_foo proc near
 sub ESP, 8
$label1:
 mov EAX, DWORD PTR [ESP + 12]
 mov DWORD PTR [ESP], EAX
 mov DWORD PTR [ESP + 4], 0
 mov EAX, DWORD PTR [ESP]
 mov DWORD PTR [_gv], EAX
 cmp DWORD PTR [ESP], 6
 jb $BB1_4
$BB1_1:                                                     ; %then
 mov DWORD PTR [ESP + 4], 0
 ALIGN 16
$BB1_2:                                                     ; %while
                                                            ; Loop Depth 1
                                                            ; Loop Header
                                                            ; Inner Loop
 cmp DWORD PTR [_gv], 0
 je $BB1_7
$BB1_3:                                                     ; %whilebody
                                                            ; Loop Depth 1
                                                            ; Loop Header is
BB1_2
                                                            ; Inner Loop
 mov EAX, DWORD PTR [_gv]
 add DWORD PTR [ESP + 4], EAX
 dec DWORD PTR [_gv]
 jmp $BB1_2
$BB1_4:                                                     ; %else
 mov DWORD PTR [ESP + 4], 1
 jmp $BB1_6
 ALIGN 16
$BB1_5:                                                     ; %whilebody9
                                                            ; Loop Depth 1
                                                            ; Loop Header is
BB1_6
                                                            ; Inner Loop
 mov EAX, DWORD PTR [_gv]
 imul EAX, DWORD PTR [ESP + 4]
 mov DWORD PTR [ESP + 4], EAX
 dec DWORD PTR [_gv]
$BB1_6:                                                     ; %while7
                                                            ; Loop Depth 1
                                                            ; Loop Header
                                                            ; Inner Loop
 cmp DWORD PTR [_gv], 0
 jne $BB1_5
$BB1_7:                                                     ; %ifcont
 mov EAX, DWORD PTR [ESP + 4]
 add ESP, 8
 ret
_foo endp
_gv? SEGEMNT PARA common 'COMMON'
_gv:                                                        ; gv
 db 4 dup(0)
_gv? ends
 end

The above assembly code cannot be assembled by NASM. I got the following
error message:

cg1.s:1: error: attempt to define a local label before any non-local labels
cg1.s:2: error: attempt to define a local label before any non-local labels
cg1.s:3: error: attempt to define a local label before any non-local labels
cg1.s:4: error: attempt to define a local label before any non-local labels
cg1.s:4: error: parser: instruction expected
cg1.s:6: error: binary format does not support any special symbol types
cg1.s:9: error: attempt to define a local label before any non-local labels
cg1.s:10: error: parser: instruction expected
cg1.s:12: error: parser: instruction expected
cg1.s:15: error: comma, colon or end of line expected
cg1.s:16: error: comma, colon or end of line expected
cg1.s:17: error: comma, colon or end of line expected
cg1.s:18: error: comma, colon or end of line expected
cg1.s:19: error: comma, colon or end of line expected
cg1.s:20: error: comma, colon or end of line expected
cg1.s:23: error: comma, colon or end of line expected
cg1.s:29: error: comma, colon or end of line expected
cg1.s:35: error: comma, colon or end of line expected
cg1.s:36: error: comma, colon or end of line expected
cg1.s:37: error: comma, colon or end of line expected
cg1.s:40: error: comma, colon or end of line expected
cg1.s:47: error: comma, colon or end of line expected
cg1.s:48: error: comma, colon or end of line expected
cg1.s:49: error: comma, colon or end of line expected
cg1.s:50: error: comma, colon or end of line expected
cg1.s:55: error: comma, colon or end of line expected
cg1.s:58: error: comma, colon or end of line expected
cg1.s:61: error: symbol `_foo' redefined
cg1.s:61: error: parser: instruction expected
cg1.s:62: error: parser: instruction expected
cg1.s:64: error: comma expected after operand 1
cg1.s:65: error: symbol `_gv?' redefined
cg1.s:65: error: parser: instruction expected

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.

BTW: The getting started document with Visual Studio looks very
out-of-dated.

Thanks,

Bengu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100127/e66e1a9e/attachment.html>


More information about the llvm-dev mailing list