Note, this problem only happens with -thumb and -O2 (eg. nothing, -O, -O1 and - O3 work fine). Here's the original snippet of code: int mmcsd_read(void * dst, void * src, unsigned int len) { int return_val = NETI_OK; int i = 0; cyg_mutex_lock(&mmcsd.mutex); if(!mmcsd.card_initialized) { cyg_mutex_unlock(&mmcsd.mutex); NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n", (unsigned int) src, len); return NETI_MMCSD_CARD_UNINITIALIZED; } MMCSD_REG_SET_BIT(MMCSD_INT_MASK, MMCSD_INT_MASK_AUTO_CARD_DETECT); disconnect_card_detect_pullup(); if(!len) { cyg_mutex_unlock(&mmcsd.mutex); NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returning len = 0\n", (unsigned int) src, len); return NETI_OK; } if((((unsigned int)src)/MMCSD_BLOCK_LENGTH + len/MMCSD_BLOCK_LENGTH) > mmcsd.device_size) { cyg_mutex_unlock(&mmcsd.mutex); NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n", (unsigned int) src, len); return NETI_MMCSD_INVALID_CARD_ADDRESS; } if(len % MMCSD_BLOCK_LENGTH) { cyg_mutex_unlock(&mmcsd.mutex); NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n", (unsigned int) src, len); return NETI_MMCSD_INVALID_CARD_ADDRESS; } if(((unsigned int)src) % MMCSD_BLOCK_LENGTH) { cyg_mutex_unlock(&mmcsd.mutex); NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n", (unsigned int) src, len); return NETI_MMCSD_INVALID_CARD_ADDRESS; } if((return_val = mmcsd_dma_read_blks(dst, (unsigned int) src, len/MMCSD_BLOCK_LENGTH)) != NETI_OK) { cyg_mutex_unlock(&mmcsd.mutex); NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n", (unsigned int) src, len); return return_val; } connect_card_detect_pullup(); MMCSD_REG_CLEAR_BIT(MMCSD_INT_MASK, MMCSD_INT_MASK_AUTO_CARD_DETECT); cyg_mutex_unlock(&mmcsd.mutex); return return_val; } Here's the output from; arm-elf-gcc -S -Wall -Wa,--gstabs -g -O2 -mcpu=arm920t ... -o mmcsd.s -c mmcsd.c mmcsd_read: .LFB59: .loc 1 1953 0 push {r4, r5, r6, r7, lr} .LCFI33: mov r7, fp mov r6, sl mov r5, r9 mov r4, r8 push {r4, r5, r6, r7} .LCFI34: .loc 1 1957 0 ldr r4, .L623 .loc 1 1953 0 mov fp, r0 .loc 1 1957 0 mov r0, r4 .loc 1 1953 0 mov r7, r2 mov r6, r1 .loc 1 1957 0 bl cyg_mutex_lock .loc 1 1960 0 mov r2, #116 neg r2, r2 add r2, r2, r4 ldr r3, [r2, #112] mov r8, r2 cmp r3, #0 bne .LCB2871 b .L615 @long jump .LCB2871: .LBB133: .loc 1 1972 0 ldr r3, .L623+4 .LBE133: mov r1, #64 ldr r2, [r3] orr r2, r2, r1 str r2, [r3] .loc 1 1975 0 bl disconnect_card_detect_pullup .loc 1 1977 0 cmp r7, #0 beq .L616 .loc 1 1984 0 lsr r3, r7, #9 mov r5, r8 mov sl, r3 lsr r2, r6, #9 ldr r3, [r5, #68] add r2, r2, sl cmp r2, r3 bls .LCB2893 b .L611 @long jump .LCB2893: .loc 1 1992 0 ldr r3, .L623+8 tst r7, r3 beq .LCB2898 b .L611 @long jump .LCB2898: .loc 1 2000 0 tst r6, r3 beq .LCB2902 b .L611 @long jump .LCB2902: .LBB134: .LBB135: .loc 1 1376 0 ldr r3, [r5, #92] cmp r3, #0 bne .L583 mov r4, #23 .L610: .LBE135: .LBE134: .loc 1 2010 0 ldr r0, .L623 bl cyg_mutex_unlock .loc 1 2012 0 ldr r0, .L623+12 mov r1, r6 mov r2, r7 bl printf .loc 1 2014 0 mov r0, r4 .L573: .loc 1 2040 0 @ sp needed for prologue pop {r3, r4, r5, r6} mov r8, r3 mov r9, r4 mov sl, r5 mov fp, r6 pop {r4, r5, r6, r7} pop {r1} bx r1 .L616: .loc 1 1978 0 mov r0, r4 bl cyg_mutex_unlock .loc 1 1980 0 ldr r0, .L623+16 mov r1, r6 mov r2, #0 bl printf .loc 1 2039 0 mov r0, #0 b .L573 .L583: .LBB136: .LBB137: .loc 1 1379 0 mov r0, #128 lsl r0, r0, #2 mov r1, sl bl mmcsd_setup_transfer cmp r0, #0 mov r9, r0 beq .L617 .L602: .loc 1 1503 0 mov r4, r9 .LBE137: .LBE136: .loc 1 1371 0 cmp r4, #0 bne .L610 .loc 1 2031 0 bl connect_card_detect_pullup .LBB138: .loc 1 2032 0 ldr r3, .L623+4 .LBE138: mov r1, #64 ldr r2, [r3] .loc 1 2035 0 ldr r0, .L623 .loc 1 2032 0 bic r2, r2, r1 str r2, [r3] .loc 1 2035 0 bl cyg_mutex_unlock .loc 1 2039 0 mov r0, #0 b .L573 .L617: .LBB139: .LBB140: .loc 1 1383 0 mov r1, #1 ldr r0, [r5, #56] bl dma_channel_set_operation .loc 1 1386 0 ldr r1, .L623+20 mov r2, #0 ldr r0, [r5, #56] bl dma_channel_set_source_addr .loc 1 1389 0 mov r1, fp mov r2, #1 ldr r0, [r5, #56] bl dma_channel_set_dest_addr .loc 1 1392 0 mov r2, sl ldr r0, [r5, #56] lsl r1, r2, #9 bl dma_channel_set_count_reg .loc 1 1394 0 ldr r3, [r5, #84] cmp r3, #0 bne .L618 .loc 1 1421 0 mov r2, r8 ldr r0, [r2, #56] mov r1, #16 bl dma_channel_set_burst_length .loc 1 1424 0 mov r3, sl cmp r3, #1 beq .L619 .loc 1 1436 0 lsl r2, r6, #16 mov r0, #18 lsr r1, r6, #16 lsr r2, r2, #16 mov r3, #9 bl mmcsd_send_cmd_wait_resp cmp r0, #0 mov r9, r0 bne .L602 .L591: .loc 1 1451 0 ldr r2, .L623+4 mov r3, #2 neg r3, r3 str r3, [r2] .loc 1 1458 0 bl dma_cache_sync .loc 1 1462 0 ldr r4, .L623+24 ldr r1, .L623+28 ldr r0, [r4, #56] bl dma_channel_set_control_register .loc 1 1474 0 mov r0, r4 add r0, r0, #60 bl cyg_semaphore_wait .loc 1 1479 0 bl dma_cache_sync .loc 1 1484 0 mov r0, r4 add r0, r0, #48 bl cyg_semaphore_wait .loc 1 1489 0 ldr r3, .L623+32 ldr r1, [r3] mov r3, #47 tst r1, r3 bne .L600 lsl r2, r1, #20 bmi .L599 .L600: .loc 1 1491 0 ldr r3, .L623+36 ldr r3, [r3] cmp r3, #0 bne .L620 mov r4, #24 b .L610 .L615: .LBE140: .LBE139: .loc 1 1961 0 mov r0, r4 bl cyg_mutex_unlock .loc 1 1962 0 ldr r0, .L623+12 mov r1, r6 mov r2, r7 bl printf .loc 1 1963 0 mov r0, #27 b .L573 .L618: .LBB141: .LBB142: .loc 1 1396 0 ldr r0, [r5, #56] mov r1, #0 bl dma_channel_set_burst_length .loc 1 1398 0 mov r3, sl cmp r3, #1 beq .L621 .loc 1 1409 0 lsl r2, r6, #16 mov r0, #18 .L613: ldr r3, .L623+40 lsr r1, r6, #16 lsr r2, r2, #16 .L614: .loc 1 1426 0 bl mmcsd_send_cmd_wait_resp cmp r0, #0 mov r9, r0 beq .L591 b .L602 .L620: .loc 1 1491 0 ldr r0, .L623+44 bl printf mov r4, #24 b .L610 .L611: .LBE142: .LBE141: .loc 1 2001 0 mov r0, r4 bl cyg_mutex_unlock .loc 1 2003 0 ldr r0, .L623+12 mov r1, r6 mov r2, r7 bl printf .loc 1 2005 0 mov r0, #26 b .L573 .L621: .LBB143: .LBB144: .loc 1 1399 0 lsl r2, r6, #16 mov r0, #17 b .L613 .L619: .loc 1 1426 0 lsl r2, r6, #16 mov r0, #17 lsr r1, r6, #16 lsr r2, r2, #16 mov r3, #9 b .L614 .L599: .loc 1 1496 0 mov r3, sl cmp r3, #1 bhi .LCB3173 b .L602 @long jump .LCB3173: .loc 1 1497 0 mov r0, #12 mov r1, #0 mov r2, #0 mov r3, #1 bl mmcsd_send_cmd_wait_resp cmp r0, #0 mov r9, r0 beq .LCB3181 b .L622 @long jump .LCB3181: b .L602 .L624: .align 2 .L623: .word mmcsd+116 .word -1610530780 .word 511 .word .LC105 .word .LC107 .word 2179128 .word mmcsd .word 2089 .word mmcsd_status_reg .word neti_debug .word 521 .word .LC101 .LBE144: .LBE143: .LFE59: .size mmcsd_read, .-mmcsd_read .section .text.mmcsd_erase,"ax",%progbits .align 2 .global mmcsd_erase .code 16 .thumb_func .type mmcsd_erase, %function
can you provide the preprocessed source? And does -W -Wall give any warnings?
-Wall gives a warning about i not being used, but that's it. We normally always build with -Wall enabled. Here's the preprocessed output: int mmcsd_read(void * dst, void * src, unsigned int len) { int return_val = NETI_OK; int i = 0; cyg_mutex_lock(&mmcsd.mutex); if(!mmcsd.card_initialized) { cyg_mutex_unlock(&mmcsd.mutex); printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len); return NETI_MMCSD_CARD_UNINITIALIZED; } *((volatile CYG_WORD32 *)(({ CYG_ADDRWORD _p = (CYG_ADDRWORD)(0x00214000 + 0x24); if (_p >= 0x12000000 && _p < (0x12000000 +0x00400000)) _p = (_p & (0x00400000 -1)) + 0x00000000; else if (_p >= 0x00200000 && _p < (0x00200000 +0x00100000)) _p = (_p & (0x00100000 -1)) + 0xA0000000; _p; }))) |= ((1 << 6)); disconnect_card_detect_pullup(); if(!len) { cyg_mutex_unlock(&mmcsd.mutex); printf("mmcsd_read(buf, 0x%x, %d) returning len = 0\n",(unsigned int) src, len); return NETI_OK; } if((((unsigned int)src)/512 + len/512) > mmcsd.device_size) { cyg_mutex_unlock(&mmcsd.mutex); printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len); return NETI_MMCSD_INVALID_CARD_ADDRESS; } if(len % 512) { cyg_mutex_unlock(&mmcsd.mutex); printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len); return NETI_MMCSD_INVALID_CARD_ADDRESS; } if(((unsigned int)src) % 512) { cyg_mutex_unlock(&mmcsd.mutex); printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len); return NETI_MMCSD_INVALID_CARD_ADDRESS; } if((return_val = mmcsd_dma_read_blks(dst, (unsigned int) src, len/512)) != NETI_OK) { cyg_mutex_unlock(&mmcsd.mutex); printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len); return return_val; } connect_card_detect_pullup(); *((volatile CYG_WORD32 *)(({ CYG_ADDRWORD _p = (CYG_ADDRWORD)(0x00214000 + 0x24); if (_p >= 0x12000000 && _p < (0x12000000 +0x00400000)) _p = (_p & (0x00400000 -1)) + 0x00000000; else if (_p >= 0x00200000 && _p < (0x00200000 +0x00100000)) _p = (_p & (0x00100000 -1)) + 0xA0000000; _p; }))) = *((volatile CYG_WORD32 *)(({ CYG_ADDRWORD _p = (CYG_ADDRWORD)(0x00214000 + 0x24); if (_p >= 0x12000000 && _p < (0x12000000 +0x00400000)) _p = (_p & (0x00400000 -1)) + 0x00000000; else if (_p >= 0x00200000 && _p < (0x00200000 +0x00100000)) _p = (_p & (0x00100000 -1)) + 0xA0000000; _p; }))) & ~((1 << 6)); cyg_mutex_unlock(&mmcsd.mutex); return return_val; }
Please send the entire pre-processed file, not just a fragment of it. Use the 'create a new attachment' link on the bugzilla page (see URL below). You are also going to have to explain what you think is wrong with the currently generated assembly file. I can't tell from the information you've provided what you think is wrong.
Created attachment 9927 [details] mmcsd.s What happens is that a bogus label (.L622) gets created, and is treated as an unresolved symbol at link time. Please find mmcsd.s (arm-elf-objdump -D mmcsd.o) attached. If you still need the entire pre-processed source, I can attach that as well.
Yes we need the preprocessed source code. Unless I can run the compiler under a debugger there's no chance of working out what's going wrong.
Created attachment 9928 [details] mmcsd.i This is the pre-processed output
The problem here is that we have a complex compare-and-jump insn with side effects, so the insn can't be simply removed. cfgrtl is getting confused and is generating code that references a deleted label.
Fixed in 4.0.0. 3.4.6 has been tagged already and has been released (no announcement has been made but it is up on the ftp server already).