When compiling with Nios II SBT, the optimize option (-O2) causes it to stop working.
Hi.
I am currently developing on Nios II Cyclone 10,
but when I add the optimization option, it stops working.
Is there any possible cause for this?
Development environment is as follows:
* FPGA:Cyclone10 10CL016YE144C8G
* ROM:EPCQ16ASI8N
* Quartus Prime:Ver18.0
Details are as follows Sorry this is so long.
-----detail-----
This is the source code around the area where the problem seems to be occurring.
```C
#define GG_MMIO_OUTPUT_STS_ROW_MAX 3
#define GG_REG_IOWR_ADDRESS_DECODER(base, offset, data) IOWR_16DIRECT(base, offset * 4, data)
#define EXT_BUFFERS_BASE 0x3400000
#define GG_REG_ADDRESS_DECODER_BASE EXT_BUFFERS_BASE
unsigned char ggMmioInitialize(void)
{
unsigned char result = GG_MMIO_RET_OK;
GG_TIM_ATTRIBUTE_ST timParamSt;
unsigned char idx;
for( idx=0; idx<GG_MMIO_OUTPUT_STS_ROW_MAX; idx++ )
{
GG_REG_IOWR_ADDRESS_DECODER( GG_REG_ADDRESS_DECODER_BASE, idx, 0x00 ); // stops here.
}
memset( ggMmioInputSettingsTable, GG_SYS_DEFAULT_BYTE, sizeof(GG_MMIO_INPUT_PARAM_ST) * GG_MMIO_INPUT_SETTINGS_MAX );
// ...
}
```
* When the following code is compiled with optimization option level2(-O2) in Debuger and then executed, it stops at the comment line `stops here`.
* If the optimization option is set to level 0(-O0), it runs without problems.
* If you apply the optimization option level2 and add `#pragma GCC optimize ("O0")` so that only the function `ggMmioInitialize` is not optimized, it will run without problems.
I believe these are problems with the compile-time optimization of the function `ggMmioInitialize`.
To investigate the cause in detail, I compared the assembler code WITHOUT OPTIMIZATION with the assembler code WITH OPTIMIZATION.
The two codes are shown below, respectively.
* assembler code WITHOUT OPTIMIZATION
```
unsigned char ggMmioInitialize(void)
{
0: defff704 addi sp,sp,-36
4: dfc00815 stw ra,32(sp)
8: df000715 stw fp,28(sp)
c: df000704 addi fp,sp,28
unsigned char result = GG_MMIO_RET_OK;
10: e03ffb05 stb zero,-20(fp)
GG_TIM_ATTRIBUTE_ST timParamSt;
unsigned char idx;
for( idx=0; idx<GG_MMIO_OUTPUT_STS_ROW_MAX; idx++ )
14: e03ffb45 stb zero,-19(fp)
18: 00000b06 br 48 <ggMmioInitialize+0x48>
{
GG_REG_IOWR_ADDRESS_DECODER( GG_REG_ADDRESS_DECODER_BASE, idx, 0x00 );
1c: e0bffb43 ldbu r2,-19(fp)
20: 1085883a add r2,r2,r2
24: 1085883a add r2,r2,r2
28: 1007883a mov r3,r2
2c: 0080d034 movhi r2,832
30: 1885883a add r2,r3,r2
34: 0007883a mov r3,zero
38: 10c0002d sthio r3,0(r2)
GG_TIM_ATTRIBUTE_ST timParamSt;
unsigned char idx;
for( idx=0; idx<GG_MMIO_OUTPUT_STS_ROW_MAX; idx++ )
3c: e0bffb43 ldbu r2,-19(fp)
40: 10800044 addi r2,r2,1
44: e0bffb45 stb r2,-19(fp)
48: e0bffb43 ldbu r2,-19(fp)
4c: 108000f0 cmpltui r2,r2,3
50: 103ff21e bne r2,zero,1c <mmioInputStatusSamplingTimerExpired+0xfffff4b8>
GG_REG_IOWR_ADDRESS_DECODER( GG_REG_ADDRESS_DECODER_BASE, idx, 0x00 );
}
memset( ggMmioInputSettingsTable, GG_SYS_DEFAULT_BYTE, sizeof(GG_MMIO_INPUT_PARAM_ST) * GG_MMIO_INPUT_SETTINGS_MAX );
54: 01800504 movi r6,20
58: 01403fc4 movi r5,255
5c: 01000034 movhi r4,0
60: 21000004 addi r4,r4,0
64: 00000000 call 0 <ggMmioInitialize>
// ...
```
* assembler code WITH OPTIMIZATION
```
unsigned char ggMmioInitialize(void)
{
c: defff804 addi sp,sp,-32
10: dfc00715 stw ra,28(sp)
14: dc000615 stw r16,24(sp)
unsigned char idx;
for( idx=0; idx<GG_MMIO_OUTPUT_STS_ROW_MAX; idx++ )
{
GG_REG_IOWR_ADDRESS_DECODER( GG_REG_ADDRESS_DECODER_BASE, idx, 0x00 );
18: 0080d034 movhi r2,832
1c: 1000002d sthio zero,0(r2)
20: 10800104 addi r2,r2,4
24: 1000002d sthio zero,0(r2)
28: 0080d034 movhi r2,832
2c: 10800204 addi r2,r2,8
30: 1000002d sthio zero,0(r2)
memset( ggMmioInputSettingsTable, GG_SYS_DEFAULT_BYTE, sizeof(GG_MMIO_INPUT_PARAM_ST) * GG_MMIO_INPUT_SETTINGS_MAX );
memset( ggMmioInputSts, GG_SYS_DEFAULT_BYTE_ZERO, sizeof(ggMmioInputSts) );
34: 00c00034 movhi r3,0
...
```
There does not appear to be anything wrong with either.
The following are among the codes that have been optimized.
```
sthio zero,0(r2)
```
Assuming we are stopping at this instruction.
To prevent the operand `zero` from being taken for the opcode `sthio`,
I modified the source as follows
```C
#define GG_MMIO_OUTPUT_STS_ROW_MAX 3
#define GG_REG_IOWR_ADDRESS_DECODER(base, offset, data) IOWR_16DIRECT(base, offset * 4, data)
#define EXT_BUFFERS_BASE 0x3400000
#define GG_REG_ADDRESS_DECODER_BASE EXT_BUFFERS_BASE
unsigned char ggMmioInitialize(void)
{
unsigned char result = GG_MMIO_RET_OK;
GG_TIM_ATTRIBUTE_ST timParamSt;
volatile int write_data = 0x00; // fixed
unsigned char idx;
for( idx=0; idx<GG_MMIO_OUTPUT_STS_ROW_MAX; idx++ )
{
GG_REG_IOWR_ADDRESS_DECODER( GG_REG_ADDRESS_DECODER_BASE, idx, write_data ); // fixed
}
memset( ggMmioInputSettingsTable, GG_SYS_DEFAULT_BYTE, sizeof(GG_MMIO_INPUT_PARAM_ST) * GG_MMIO_INPUT_SETTINGS_MAX );
// ...
}
```
The comment line `fixed` is the modified line.
The compiled assembler code sequence with optimization (-O2) looks like this
```
unsigned char ggMmioInitialize(void)
{
c: defff704 addi sp,sp,-36
GG_TIM_ATTRIBUTE_ST timParamSt;
unsigned char idx;
volatile int write_data = 0x00;
10: d8000615 stw zero,24(sp)
for( idx=0; idx<GG_MMIO_OUTPUT_STS_ROW_MAX; idx++ )
{
GG_REG_IOWR_ADDRESS_DECODER( GG_REG_ADDRESS_DECODER_BASE, idx, write_data );
14: d8c00617 ldw r3,24(sp)
unsigned char ggMmioInitialize(void)
{
18: dfc00815 stw ra,32(sp)
1c: dc000715 stw r16,28(sp)
unsigned char idx;
volatile int write_data = 0x00;
for( idx=0; idx<GG_MMIO_OUTPUT_STS_ROW_MAX; idx++ )
{
GG_REG_IOWR_ADDRESS_DECODER( GG_REG_ADDRESS_DECODER_BASE, idx, write_data );
20: 0080d034 movhi r2,832
24: 10c0002d sthio r3,0(r2)
28: d8c00617 ldw r3,24(sp)
2c: 10800104 addi r2,r2,4
30: 10c0002d sthio r3,0(r2)
34: d8c00617 ldw r3,24(sp)
38: 0080d034 movhi r2,832
3c: 10800204 addi r2,r2,8
40: 10c0002d sthio r3,0(r2)
```
The operand `r3` is changed to take the operand `r3` for the opcode `sthio`.
This change allows us to run.
At length, my questions are as follows.
* It stopped working when I put on the optimize option. Is there any possible cause for this?
* Based on my investigation, it appears that the `sthio zero ... `assembler code appears to be stuck when outputting
Does this sequence of assembler code have anything to do with the inability to execute?
Or is there another cause?
Best regards.