[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