https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81273
Bug ID: 81273
Summary: Wrong code generated for ARM setting volatile struct
field with a literal
Product: gcc
Version: 6.3.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: ldeboer at gateway dot net.au
Target Milestone: ---
struct __attribute__((__packed__)) TimerRegisters {
volatile uint32_t Load; //0x00
volatile uint32_t Value; //0x04
};
uint32_t base_addr = 0x3F000000;
#define TIMER ((struct TimerRegisters*)(base_addr + 0xB400))
void ShowBug (void){
TIMER->Load = 0x400; // -02 compile and look at code
}
void ShowFix1 (void){
*(volatile uint32_t*)ARMTIMER->Load = 0x400;
}
void ShowFix2 (void){
volatile uint32_t temp = 0x400;
ARMTIMER->Load = temp;
}
Code generated you can see the two fixes produce markedly different and correct
code. Fun trying to write to hardware registers with this bug.
383 .section .text.ShowBug,"ax",%progbits
384 .align 2
385 .global ShowBug
386 .syntax unified
387 .arm
388 .fpu neon-vfpv4
389 .type ShowBug, %function
390 ShowBug:
391 @ args = 0, pretend = 0, frame = 0
392 @ frame_needed = 0, uses_anonymous_args = 0
393 @ link register save eliminated.
394 0000 003000E3 movw r3, #:lower16:.LANCHOR0
395 0004 003040E3 movt r3, #:upper16:.LANCHOR0
396 0008 0020A0E3 mov r2, #0
397 000c 0410A0E3 mov r1, #4
398 0010 003093E5 ldr r3, [r3]
399 0014 2D3B83E2 add r3, r3, #46080
400 0018 0000D3E5 ldrb r0, [r3] @ zero_extendqisi2
401 001c 0020C3E5 strb r2, [r3]
402 0020 0100D3E5 ldrb r0, [r3, #1] @ zero_extendqisi2
403 0024 0110C3E5 strb r1, [r3, #1]
404 0028 0210D3E5 ldrb r1, [r3, #2] @ zero_extendqisi2
405 002c 0220C3E5 strb r2, [r3, #2]
406 0030 0310D3E5 ldrb r1, [r3, #3] @ zero_extendqisi2
407 0034 0320C3E5 strb r2, [r3, #3]
408 0038 1EFF2FE1 bx lr
409 .size ShowBug, .-ShowBug
410 .section .text.ShowFix1,"ax",%progbits
411 .align 2
412 .global ShowFix1
413 .syntax unified
414 .arm
415 .fpu neon-vfpv4
416 .type ShowFix1, %function
417 ShowFix1:
418 @ args = 0, pretend = 0, frame = 0
419 @ frame_needed = 0, uses_anonymous_args = 0
420 @ link register save eliminated.
421 0000 003000E3 movw r3, #:lower16:RPi_IO_Base_Addr
422 0004 003040E3 movt r3, #:upper16:RPi_IO_Base_Addr
423 0008 012BA0E3 mov r2, #1024
424 000c 003093E5 ldr r3, [r3]
425 0010 2D3B83E2 add r3, r3, #46080
426 0014 003093E5 ldr r3, [r3] @ unaligned
427 0018 002083E5 str r2, [r3]
428 001c 1EFF2FE1 bx lr
429 .size ShowFix1, .-ShowFix1
430 .section .text.ShowFix2,"ax",%progbits
431 .align 2
432 .global ShowFix2
433 .syntax unified
434 .arm
435 .fpu neon-vfpv4
436 .type ShowFix2, %function
437 ShowFix2:
438 @ args = 0, pretend = 0, frame = 8
439 @ frame_needed = 0, uses_anonymous_args = 0
440 @ link register save eliminated.
441 0000 003000E3 movw r3, #:lower16:RPi_IO_Base_Addr
442 0004 003040E3 movt r3, #:upper16:RPi_IO_Base_Addr
443 0008 08D04DE2 sub sp, sp, #8
444 000c 012BA0E3 mov r2, #1024
445 0010 003093E5 ldr r3, [r3]
446 0014 04208DE5 str r2, [sp, #4]
447 0018 2D3B83E2 add r3, r3, #46080
448 001c 04209DE5 ldr r2, [sp, #4]
449 0020 002083E5 str r2, [r3] @ unaligned
450 0024 08D08DE2 add sp, sp, #8
451 @ sp needed
452 0028 1EFF2FE1 bx lr
453 .size ShowFix2, .-ShowFix2