ИАР МСП еволюшн в.3.30а: Ошибка оптимизатора при установленой оптимизации "Function inlining"
Ошибка оптимизатора при установленой оптимизации "Function inlining"
==========================================================================================
Код:
inline int is_circle_full( CIRCULAR_BUFFER *buf ) // "буфер полон" == 1
{
return( buf->tail == NULL );
}
......
int uart1_tx( int c )
{
while ( is_circle_full( &tx1buf )) // ждем пустого места
;
put_circle( c, &tx1buf ); // положим байт в буффер передачи
return( c );
}
-----------------------------------------------------------------------------
Результат компиляции
НЕ ПРАВИЛЬНО!!!
78 while ( is_circle_full( &tx1buf )) // ждем пустого места
\ 000004 8293.... CMP.W #0x0, &tx1buf + 4
\ 000008 0120 JNE ??uart1_tx_1
\ ??uart1_tx_0: // ********************
\ 00000A FF3F JMP ??uart1_tx_0 // ********************
79 ;
80 // while ( ( &tx1buf )->tail == NULL ) // ждем пустого места
81 // ;
Правильно!!! (ручками вписали...)
78 // while ( is_circle_full( &tx1buf )) // ждем пустого места
79 // ;
80 while ( ( &tx1buf )->tail == NULL ) // ждем пустого места
\ ??uart1_tx_0:
\ 000004 8293.... CMP.W #0x0, &tx1buf + 4
\ 000008 FD27 JEQ ??uart1_tx_0
81 ;
или так - оптимизатор сам делает инлайн-подстановку
Код:
int is_circle_full( CIRCULAR_BUFFER *buf ) // "буфер полон" == 1
{
return( buf->tail == NULL );
}
......
int uart1_tx( int c )
{
while ( is_circle_full( &tx1buf )) // ждем пустого места
;
put_circle( c, &tx1buf ); // положим байт в буффер передачи
return( c );
}
-----------------------------------------------------------------------------
76 int is_circle_full( CIRCULAR_BUFFER *buf ) // "буфер полон" == 1
\ is_circle_full:
77 {
78 return( buf->tail == NULL );
\ 000000 8C930400 CMP.W #0x0, 0x4(R12)
\ 000004 0224 JEQ ??is_circle_full_0
\ 000006 4C43 MOV.B #0x0, R12
\ 000008 3041 RET
\ ??is_circle_full_0:
\ 00000A 5C43 MOV.B #0x1, R12
\ 00000C 3041 RET
79 }
80
\ In segment CODE, align 2
81 int uart1_tx( int c )
\ uart1_tx:
82 {
\ 000000 0A12 PUSH.W R10
\ 000002 0A4C MOV.W R12, R10
83 while ( is_circle_full( (&tx1buf) )) // ждем пустого места
\ 000004 8293.... CMP.W #0x0, &tx1buf + 4
\ 000008 0120 JNE ??uart1_tx_1
\ ??uart1_tx_0: // *******************
\ 00000A FF3F JMP ??uart1_tx_0 // *******************
84 ;
85 // while ( ( &tx1buf )->tail == NULL ) // ждем пустого места
86 // ;
87 put_circle( c, &tx1buf ); // положим байт в буффер передачи
\ ??uart1_tx_1:
\ 00000C 3E40.... MOV.W #tx1buf, R14
\ 000010 B012.... CALL #put_circle
88 return( c );
\ 000014 0C4A MOV.W R10, R12
\ 000016 3A41 POP.W R10
\ 000018 3041 RET
89 }
90
-------------------------------------------------------------------
Обходится использованием макроса (в данном случае) и наблюдением за листингом - если компилятор сам вставляет функцию inline-ом.
#define is_circle_full_p( buf_ptr ) ( ( buf_ptr )->tail == NULL ) // Для указателя
+++++++++++++++++++++++++++++++++
76 int uart1_tx( int c )
\ uart1_tx:
77 {
\ 000000 0A12 PUSH.W R10
\ 000002 0A4C MOV.W R12, R10
78 while ( is_circle_full_p( &tx1buf )) // ждем пустого места
\ ??uart1_tx_0:
\ 000004 8293.... CMP.W #0x0, &tx1buf + 4
\ 000008 FD27 JEQ ??uart1_tx_0
79 ;
80 // while ( ( &tx1buf )->tail == NULL ) // ждем пустого места
81 // ;
82 put_circle( c, &tx1buf ); // положим байт в буффер передачи
\ 00000A 3E40.... MOV.W #tx1buf, R14
\ 00000E B012.... CALL #put_circle
83 return( c );
\ 000012 0C4A MOV.W R10, R12
\ 000014 3A41 POP.W R10
\ 000016 3041 RET
84 }
=========================================
#define is_circle_full( buf ) ( ( buf ).tail == NULL )
+++++++++++++++++++++++++++++++++
76 int uart1_tx( int c )
\ uart1_tx:
77 {
\ 000000 0A12 PUSH.W R10
\ 000002 0A4C MOV.W R12, R10
78 while ( is_circle_full( tx1buf )) // ждем пустого места
\ ??uart1_tx_0:
\ 000004 8293.... CMP.W #0x0, &tx1buf + 4
\ 000008 FD27 JEQ ??uart1_tx_0
79 ;
80 // while ( ( &tx1buf )->tail == NULL ) // ждем пустого места
81 // ;
82 put_circle( c, &tx1buf ); // положим байт в буффер передачи
\ 00000A 3E40.... MOV.W #tx1buf, R14
\ 00000E B012.... CALL #put_circle
83 return( c );
\ 000012 0C4A MOV.W R10, R12
\ 000014 3A41 POP.W R10
\ 000016 3041 RET
84 }
====================================================
)