- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there,
Recently I've ported a program from NIOS I to NIOS II. When debugging the ported program I noticed a strange problem in the code generated. Basically, the compiler generated a wrong code for a nested switch statement. The problem arises if the code for the switch is bigger than a certain size. The C code that shows the problem is as follows:#include <stdio.h>
void Func1() {
int j = 0;
for(int i=0; i<10; i++)
j += i;
}
void Func2() {
int j = 0;
for(int i=0; i<10; i++)
j -= i;
}
void Func3() {
int j = 0;
for(int i=0; i<10; i++)
j += 2 * i;
}
# define SOME_CODE()
asm(".rept 71\n"
" nop\n"
".endr\n")
void BugSample(int var1, int var2)
{# define HANDLE_CASE(__tag)
case __tag:
printf(#__tag "\n");
SOME_CODE();
printf(#__tag "\n");
break;
switch(var1)
{
HANDLE_CASE(0)
HANDLE_CASE(1)
HANDLE_CASE(2)
HANDLE_CASE(3)
HANDLE_CASE(4)
HANDLE_CASE(5)
HANDLE_CASE(6)
HANDLE_CASE(7)
HANDLE_CASE(8)
HANDLE_CASE(9)
HANDLE_CASE(10)
HANDLE_CASE(11)
HANDLE_CASE(12)
HANDLE_CASE(13)
HANDLE_CASE(14)
HANDLE_CASE(15)
HANDLE_CASE(16)
HANDLE_CASE(17)
HANDLE_CASE(18)
HANDLE_CASE(19)
HANDLE_CASE(20)
HANDLE_CASE(21)
HANDLE_CASE(22)
HANDLE_CASE(23)
HANDLE_CASE(24)
HANDLE_CASE(25)
HANDLE_CASE(26)
HANDLE_CASE(27)
HANDLE_CASE(28)
HANDLE_CASE(29)
HANDLE_CASE(30)
HANDLE_CASE(31)
HANDLE_CASE(32)
HANDLE_CASE(33)
HANDLE_CASE(34)
HANDLE_CASE(35)
HANDLE_CASE(36)
HANDLE_CASE(37)
HANDLE_CASE(38)
HANDLE_CASE(39)
HANDLE_CASE(40)
HANDLE_CASE(41)
HANDLE_CASE(42)
HANDLE_CASE(43)
HANDLE_CASE(44)
HANDLE_CASE(45)
HANDLE_CASE(46)
HANDLE_CASE(47)
HANDLE_CASE(48)
HANDLE_CASE(49)
HANDLE_CASE(50)
HANDLE_CASE(51)
HANDLE_CASE(52)
HANDLE_CASE(53)
HANDLE_CASE(54)
HANDLE_CASE(55)
HANDLE_CASE(56)
HANDLE_CASE(57)
HANDLE_CASE(58)
HANDLE_CASE(59)
HANDLE_CASE(60)
HANDLE_CASE(61)
HANDLE_CASE(62)
HANDLE_CASE(63)
HANDLE_CASE(64)
HANDLE_CASE(65)
HANDLE_CASE(66)
HANDLE_CASE(67)
HANDLE_CASE(68)
HANDLE_CASE(69)
HANDLE_CASE(70)
HANDLE_CASE(71)
HANDLE_CASE(72)
HANDLE_CASE(73)
HANDLE_CASE(74)
HANDLE_CASE(75)
HANDLE_CASE(76)
HANDLE_CASE(77)
HANDLE_CASE(78)
HANDLE_CASE(79)
HANDLE_CASE(80)
HANDLE_CASE(81)
HANDLE_CASE(82)
HANDLE_CASE(83)
HANDLE_CASE(84)
HANDLE_CASE(85)
HANDLE_CASE(86)
HANDLE_CASE(87)
HANDLE_CASE(88)
HANDLE_CASE(89)
HANDLE_CASE(90)
HANDLE_CASE(91)
HANDLE_CASE(92)
HANDLE_CASE(93)
HANDLE_CASE(94)
HANDLE_CASE(95)
HANDLE_CASE(96)
HANDLE_CASE(97)
HANDLE_CASE(98)
HANDLE_CASE(99)
case 100:
{
Func1();
printf("Func1 called");
switch(var2)
{
case 2:
case 3:
{
Func2();
printf("Func2 called");
break;
}
case 4:
case 5:
{
Func3();
printf("Func3 called");
break;
}
default: break;
}
break;
}
}
}
In the above program we can see that the handling for the cases ranging from 0 to 99 simply call printf and insert a lot of NOPs. In the handling for the value 100, we have another switch and that is where the problem happens. If var2 equals 3 the function func3() gets called !!! I'm compiling the program under Eclipse using the Release configuration. The compiler flags are: -DALT_RELEASE -O2 -g -Wall The version of GCC is 3.4.1 (Altera Nios II 5.1 b93) Note 1: The real program where I found the bug uses no inline assembly. Note 2: If I change to optimization level 1 (-O1) the code generated is correct. The disassembly of the function BugSample() for the case of wrong code generation (with comments added): 010001e8 <_Z9BugSampleii>:
10001e8: defffe04 addi sp,sp,-8
10001ec: 00801904 movi r2,100
10001f0: dc000015 stw r16,0(sp)
10001f4: dfc00115 stw ra,4(sp)
10001f8: 2821883a mov r16,r5
10001fc: 11000636 bltu r2,r4,1000218 <_Z9BugSampleii+0x30>
1000200: 200490ba slli r2,r4,2
1000204: 00c04074 movhi r3,257
1000208: 18caa704 addi r3,r3,10908
100020c: 10c5883a add r2,r2,r3
1000210: 11000017 ldw r4,0(r2)
1000214: 2000683a jmp r4
;;; <Return>:
;;;
1000218: dfc00117 ldw ra,4(sp)
100021c: dc000017 ldw r16,0(sp)
1000220: dec00204 addi sp,sp,8
1000224: f800283a ret
;;; Handling of case 100:
;;;
1000228: 10001ac0 call 10001ac <_Z5Func1v>
100022c: 01004074 movhi r4,257
1000230: 210a3704 addi r4,r4,10460
1000234: 10082c40 call 10082c4 <printf>
1000238: 00c00084 movi r3,2
100023c: 80fff616 blt r16,r3,1000218 <_Z9BugSampleii+0x30> ; -> goto <Return>
1000240: 008000c4 movi r2,3
1000244: 8080030e bge r16,r2,1000254 <_Z9BugSampleii+0x6c> ; -> goto <label1> (WRONG: should be bg, not bge)
1000248: 00404034 movhi at,256
100024c: 0860a814 ori at,at,33440
1000250: 0800683a jmp at (address: 0x10082A0) ; goto case 2/3
;;; <label1>:
1000254: 00800144 movi r2,5
1000258: 143fef16 blt r2,r16,1000218 <_Z9BugSampleii+0x30>
100025c: 10001d40 call 10001d4 <_Z5Func3v>
1000260: 01004074 movhi r4,257
1000264: 210a3b04 addi r4,r4,10476
1000268: 02004074 movhi r8,257
100026c: 4220b104 addi r8,r8,-32060
1000270: dfc00117 ldw ra,4(sp)
1000274: dc000017 ldw r16,0(sp)
1000278: dec00204 addi sp,sp,8
100027c: 4000683a jmp r8
1000280: 01004074 movhi r4,257
1000284: 210a3f04 addi r4,r4,10492
1000288: 100837c0 call 100837c <puts>
100028c: 0001883a nop
1000290: 0001883a nop
...
;;; Code generated for:
;;;
;;; switch(var2)
;;; case 2:
;;; case 3:
;;; {
;;; Func2();
;;; printf("Func2 called");
;;; break;
;;; }
10082a0: 10001c00 call 10001c0 <_Z5Func2v>
10082a4: 01004074 movhi r4,257
10082a8: 210aa304 addi r4,r4,10892
10082ac: 02004074 movhi r8,257
10082b0: 4220b104 addi r8,r8,-32060
10082b4: dfc00117 ldw ra,4(sp)
10082b8: dc000017 ldw r16,0(sp)
10082bc: dec00204 addi sp,sp,8
10082c0: 4000683a jmp r8
As a workaround, I'll use optmization level 1 to generate my real program. Anyway, I believe that this subject deserves some investigation. Regards, mrwar
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No one any comment on this? It seems to be importand enough to know if it's a mistake from mrwar, or a real bug!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- originally posted by svhb@Sep 21 2006, 04:11 PM no one any comment on this? it seems to be importand enough to know if it's a mistake from mrwar, or a real bug!
<div align='right'><{post_snapback}> (index.php?act=findpost&pid=18394)
--- quote end ---
--- Quote End --- Yes, I can reproduce this on our NIOS2 board using the nios2-elf-g++ version 3.4.1 under Linux. I've crosschecked this with a i686-pc-linux-gnu-g++ 3.4.1. With this one, the generated code runs correctly and also a fast search in the gcc bugzilla didn't come up with a matching bugreport, so it seems like this is a nios2-port specific bug. @mrwar: Did you already forward this to Altera support? Regards, Andreas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Andreas for confirming the bug.
It seems that the bug is related to the size of a relative jump, which I believe is handled in a platform dependent way in GCC. Today, I sent a bug report to Altera. When I get any answers, I'll send to the Forum. Regards, mrwar- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Should some Altera-NIOSII people not keep an eye on the forum??
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