[LLVMdev] Help with a Microblaze code generation problem.

Richard Pennington rich at pennware.com
Thu Oct 3 03:49:47 PDT 2013


Sorry if this is a duplicate: I tried to send it last night and it 
didn't go through. I'm trimming some text to see if it helps.

I have a simple program that fails on the Microblaze:

int main()
{
     unsigned long long x, y;

     x = 100;
     y = 0x8000000000000000ULL;
     return !(x > y);
}

As you can see, the test case compares two unsigned long long values. To 
try to track the problem down I tried compiling it for the Mips (which 
works, of course) for both unsigned long long and signed long long with 
the following results:

unsigned long long:
main:
         .frame  $fp,24,$ra
         .mask   0x40000000,-4
         .fmask  0x00000000,0
         .set    noreorder
         .set    nomacro
         .set    noat
         addiu   $sp, $sp, -24
         sw      $fp, 20($sp)
         move     $fp, $sp
         sw      $zero, 16($fp)
         addiu   $1, $zero, 100
         sw      $1, 12($fp)
         sw      $zero, 8($fp)
         lui     $1, 32768
         sw      $1, 0($fp)
         sw      $zero, 4($fp)
         lw      $2, 8($fp)
         xor     $1, $2, $1
         addiu   $3, $zero, -1
         slt     $2, $3, $2
         lw      $3, 12($fp)
         sltiu   $3, $3, 1
         movz    $2, $3, $1
         move     $sp, $fp
         lw      $fp, 20($sp)
         addiu   $sp, $sp, 24
         jr      $ra
         nop

signed long long:

main:
         .frame  $fp,24,$ra
         .mask   0x40000000,-4
         .fmask  0x00000000,0
         .set    noreorder
         .set    nomacro
         .set    noat
         addiu   $sp, $sp, -24
         sw      $fp, 20($sp)
         move     $fp, $sp
         sw      $zero, 16($fp)
         addiu   $1, $zero, 100
         sw      $1, 12($fp)
         sw      $zero, 8($fp)
         lui     $1, 32768
         sw      $1, 0($fp)
         sw      $zero, 4($fp)
         lw      $2, 8($fp)
         xor     $1, $2, $1
         lw      $2, 12($fp)
         or      $1, $2, $1
         sltiu   $2, $1, 1
         move     $sp, $fp
         lw      $fp, 20($sp)
         addiu   $sp, $sp, 24
         jr      $ra
         nop

The two comparisons are very similar.

For the Microblaze, I get:

signed long long:
main:
         .frame  r19,40,r15
         .mask   0x80000
         addik     r1, r1, -40
         swi       r19, r1, 4
         add       r19, r1, r0
         swi       r0, r19, 8
         addik     r3, r0, 100
         swi       r3, r19, 20
         swi       r0, r19, 16
         addik     r3, r0, -2147483648
         swi       r3, r19, 24
         swi       r0, r19, 28
         lwi       r4, r19, 16
         xor       r3, r4, r3
         lwi       r4, r19, 20
         or        r3, r4, r3
         addik     r4, r0, 0
         addik     r5, r0, 1
         swi       r5, r19, 32
         beqid     r3, ($BB0_2)
         swi       r4, r19, 36
         lwi       r3, r19, 36
         swi       r3, r19, 32
$BB0_2:
         lwi       r3, r19, 32
         add       r1, r19, r0
         lwi       r19, r1, 4
         rtsd      r15, 8
         addik     r1, r1, 40
         .end    main

Which is very similar to the Mips version. But for unsigned long long, I 
get:

main:
         .frame  r19,76,r15
         .mask   0x80000
         addik     r1, r1, -76
         swi       r19, r1, 4
         add       r19, r1, r0
         swi       r0, r19, 8
         addik     r3, r0, 100
         swi       r3, r19, 20
         swi       r0, r19, 16
         addik     r3, r0, -2147483648
         swi       r3, r19, 24
         swi       r0, r19, 28
         addik     r4, r0, -1
         lwi       r5, r19, 16
         cmp       r4, r4, r5
         cmp       r3, r3, r5 main% cat PR54.mbu
         .file   "PR54.c"
         .text
         .globl  main
         .align  2
         .type   main, at function
         .ent    main
         addik     r5, r0, 0
         addik     r6, r0, 1
         lwi       r7, r19, 20
         addk      r8, r6, r0
         swi       r4, r19, 32
         swi       r3, r19, 36
         swi       r5, r19, 40
         swi       r6, r19, 44
         beqid     r7, ($BB0_2)
         swi       r8, r19, 48
         lwi       r3, r19, 40
         swi       r3, r19, 48
$BB0_2:
         lwi       r3, r19, 48
         lwi       r4, r19, 44
         lwi       r5, r19, 36
         swi       r3, r19, 52
         beqid     r5, ($BB0_4)
         swi       r4, r19, 56
         lwi       r3, r19, 40
         swi       r3, r19, 56
$BB0_4:
         lwi       r3, r19, 56
         lwi       r4, r19, 44
         lwi       r5, r19, 32
         swi       r3, r19, 60
         bgtid     r5, ($BB0_6)
         swi       r4, r19, 64
         lwi       r3, r19, 40
         swi       r3, r19, 64
$BB0_6:
         lwi       r3, r19, 64
         lwi       r4, r19, 52
         lwi       r5, r19, 60
         swi       r3, r19, 68
         bneid     r5, ($BB0_8)
         swi       r4, r19, 72
         lwi       r3, r19, 68
         swi       r3, r19, 72
$BB0_8:
         lwi       r3, r19, 72
         add       r1, r19, r0
         lwi       r19, r1, 4
         rtsd      r15, 8
         addik     r1, r1, 76

which is quite a bit different from the signed version and obviously 
quite a bit longer.

I have two questions.

1. Where is the transformation made for a 64 bit comparison to this 
code? I can't seem to find it.
2. What might be missing in the Microblaze code generator that the 
unsigned case is failing so badly?

I know that the Microblaze has been removed from current. This is part 
of my feeble attempt to keep it alive in my source tree until I can 
devote the time to bring it back to the main line.

Thanks for any help or suggestions.

-Rich





More information about the llvm-dev mailing list