- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Could this be a bug in the NIOS2-GCC ?
char testsub(void) {
return __builtin_ldbio (0x1000);
}
Generates the following Assembly code (Using -O2 and -fomit-frame-pointer): movi r3, 4096
ldhio r2, 0(r3)
slli r2, r2, 24
srai r2, r2, 24
ret
Why doesn't it just generate a ldbio r2, 0(r3) I also found the following Code in the (Nios Homedir)/bin/nios2-gnutools/src/gcc/gcc/config/nios2/nios2.md File (available only if GCC Sources are installed) : (define_insn "ldbio"
UNSPEC_LDBIO))
(use (match_operand:SI 1 "memory_operand" "m"))]
""
"ldhio\t%0, %1"
)
Does anybody know why GCC translates every __builtin_ldbio into a ldhio?
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sgan,
Thank you very much for finding this issue in the compiler. You are correct that there is a bug here, __builtin_ldbio() should be translating to a ldbio instruction, not a ldhio. This issue will be fixed for the next release of the compiler. If this is causing you a particular issue, I recommend either using __builtin_ldbuio() and sign extending it, or using extended assembly statements. That said, there is a related conversation elsewhere on the forum that you may be interested in. http://www.niosforum.com/forum/index.php?a...ct=st&f=2&t=435 (http://www.niosforum.com/forum/index.php?act=st&f=2&t=435) This discusses some of the other issues that you point out here, as even if this bug did not exist, the generated assembly would be:movi r3, 4096
ldbio r2, 0(r3)
slli r2, r2, 24
srai r2, r2, 24
ret
in this case as __builtin_ldXio returns ints. Jonah
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, the Subroutine testfunc above at least returns the correct result, because of the shifts... BUT look at this:
long testsub(void) {
return __builtin_ldbio (0x1000);
}
When you compile this code, you can be sure that you get wrong results... the generated assembly code looks like this: movhi r3, 4096
ldhio r2, 0(r3)
ret
With this code, you can be sure you get wrong results... Simon
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sgan,
<div class='quotetop'>QUOTE </div> --- Quote Start --- With this code, you can be sure you get wrong results...[/b] --- Quote End --- You are correct. Which is why I recommend not using the defective builtin. <div class='quotetop'>QUOTE </div> --- Quote Start --- Thank you very much for finding this issue in the compiler. You are correct that there is a bug here, __builtin_ldbio() should be translating to a ldbio instruction, not a ldhio. This issue will be fixed for the next release of the compiler. If this is causing you a particular issue, I recommend either using __builtin_ldbuio() and sign extending it, or using extended assembly statements.[/b] --- Quote End --- Let me elaborate on the above. What I recommend your code look like is this:int testsub1(void) {
char x = __builtin_ldbuio ((void *)0x1000);
return (int)x; // sign extend x
}
Or using asm statements: int testsub2(void) {
int x;
asm ("ldbio %, 0(%)" : "=r" (x) : "r" (0x1000));
return x;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jonah,
Just wanted to say thanks! I used your asm example in my legacy NiosII port just this hour with great results! This may be a topic for another thread, but is there any way to read one and only one byte from an 8 bit peripheral? I did the trick of ignoring the bottom 2 address bits to read one and only one address, but still issues 4 read pulses. Not always good with an 8 bit fifo. LDWIO is smart enough to grab all 4 fifo pops into a single long word, but there aren't always 4 bytes in the fifo. Ken
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page