ИАР МСП еволюшн в.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 } ====================================================