Compiler creates wrong additional bit shift operation.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GNU Arm Embedded Toolchain |
Invalid
|
Undecided
|
Dennis Pahl |
Bug Description
Hi,
I have a problem with the Compilers GCC 5.4_2016q2 and 5.2_2015q4.
In my system there exists a memory which has the size of a multiple of 2. The memory is aligned to a matching memory address. Right after the last address of the memory, the same memory is mapped in the address space again. So each variable in the memory can be accesses by adding the size of the memory to the address of the variable. This is used by the function below to detect the memory size.
The function writes a special pattern into a global variable. Afterwards a loop starts which checks if the address of the global variable plus the memory size contains the same pattern as the global variable. As long as the content isn't the same, the variable "memory size" is increased by 2 (left shift by 1).
Problem: The compiler creates binary code which performs an additional left shift by 2 for the content of variable "memory size".
So instead of performing:
while (*(&u32ExternRa
The generated program performs:
while (*(&u32ExternRa
Am I doing something wrong or am I missing something?
Dennis Pahl
----------------
Source Code:
#define OS_HW_MEM_
#define OS_HW_MEM_SIZE_64MB 0x04000000
typedef unsigned int INT32U;
static INT32U u32ExternRamSiz
static INT32U u32MemSize_g;
static INT32U u32MemEndAddress_g;
void vFindMemSize(void)
{
u32MemSize_g = OS_HW_MEM_
//---
// write test pattern
//---
u32ExternRamS
//---
// Double the memory size as long as the test pattern cannot be found.
//---
while (*(&u32ExternRa
{
//set the memory size to the next multiple of 2
u32MemSize_g = u32MemSize_g << 1;
}
u32MemEndAddr
}
main()
{
vFindMemSize();
}
------------------
The resulting list file:
1 .cpu cortex-a9
2 .fpu softvfp
3 .eabi_attribute 20, 1
4 .eabi_attribute 21, 1
5 .eabi_attribute 23, 3
6 .eabi_attribute 24, 1
7 .eabi_attribute 25, 1
8 .eabi_attribute 26, 1
9 .eabi_attribute 30, 6
10 .eabi_attribute 34, 1
11 .eabi_attribute 18, 4
12 .arm
13 .syntax divided
14 .file "main.c"
15 .text
16 .Ltext0:
17 .cfi_sections .debug_frame
18 .section .bss.u32ExternR
19 .align 2
22 u32ExternRamSiz
23 0000 00000000 .space 4
24 .section .bss.u32MemSize
25 .align 2
28 u32MemSize_g:
29 0000 00000000 .space 4
30 .section .bss.u32MemEndA
31 .align 2
34 u32MemEndAddress_g:
35 0000 00000000 .space 4
36 .section .text.vFindMemS
37 .align 2
38 .global vFindMemSize
40 vFindMemSize:
41 .LFB0:
42 .file 1 "../main.c"
1:../main.c **** /*
2:../main.c **** * Copyright 2008 Pilz GmbH & Co KG.
3:../main.c **** * All Rights Reserved.
4:../main.c **** * PILZ PROPRIETARY/
5:../main.c **** *
6:../main.c **** * $HeadURL: $
7:../main.c **** * $Author: $
8:../main.c **** * $Date: $
9:../main.c **** * $Revision: $
10:../main.c **** */
11:../main.c ****
12:../main.c **** #define OS_HW_MEM_
13:../main.c **** #define OS_HW_MEM_SIZE_64MB 0x04000000
14:../main.c ****
15:../main.c **** typedef unsigned int INT32U;
16:../main.c ****
17:../main.c **** static INT32U u32ExternRamSiz
18:../main.c **** static INT32U u32MemSize_g;
19:../main.c **** static INT32U u32MemEndAddress_g;
20:../main.c ****
21:../main.c **** void vFindMemSize(void)
22:../main.c **** {
43 .loc 1 22 0
44 .cfi_startproc
45 @ args = 0, pretend = 0, frame = 0
46 @ frame_needed = 1, uses_anonymous_args = 0
47 @ link register save eliminated.
48 0000 04B02DE5 str fp, [sp, #-4]!
49 .cfi_def_cfa_offset 4
50 .cfi_offset 11, -4
51 0004 00B08DE2 add fp, sp, #0
52 .cfi_def_
23:../main.c ****
24:../main.c **** u32MemSize_g = OS_HW_MEM_
53 .loc 1 24 0
54 0008 003000E3 movw r3, #:lower16:
55 000c 003040E3 movt r3, #:upper16:
56 0010 0123A0E3 mov r2, #67108864
57 0014 002083E5 str r2, [r3]
25:../main.c ****
26:../main.c **** //-----
27:../main.c **** // write test pattern
28:../main.c **** //-----
29:../main.c **** u32ExternRamSiz
58 .loc 1 29 0
59 0018 002000E3 movw r2, #:lower16:
60 001c 002040E3 movt r2, #:upper16:
61 0020 CD3B0AE3 movw r3, #43981
62 0024 343241E3 movt r3, 4660
63 0028 003082E5 str r3, [r2]
30:../main.c ****
31:../main.c **** //-----
32:../main.c **** // Double the memory size as long as the test pattern cannot be found.
33:../main.c **** //-----
34:../main.c ****
35:../main.c **** while (*(&u32ExternRa
64 .loc 1 35 0
65 002c 060000EA b .L2
66 .L3:
36:../main.c **** {
37:../main.c **** //set the memory size to the next multiple of 2
38:../main.c **** u32MemSize_g = u32MemSize_g << 1;
67 .loc 1 38 0
68 0030 003000E3 movw r3, #:lower16:
69 0034 003040E3 movt r3, #:upper16:
70 0038 003093E5 ldr r3, [r3]
71 003c 8320A0E1 mov r2, r3, asl #1
72 0040 003000E3 movw r3, #:lower16:
73 0044 003040E3 movt r3, #:upper16:
74 0048 002083E5 str r2, [r3]
75 .L2:
35:../main.c **** {
76 .loc 1 35 0
77 004c 003000E3 movw r3, #:lower16:
78 0050 003040E3 movt r3, #:upper16:
79 0054 003093E5 ldr r3, [r3]
80 0058 0321A0E1 mov r2, r3, asl #2
81 005c 003000E3 movw r3, #:lower16:
82 0060 003040E3 movt r3, #:upper16:
83 0064 033082E0 add r3, r2, r3
84 0068 002093E5 ldr r2, [r3]
85 006c 003000E3 movw r3, #:lower16:
86 0070 003040E3 movt r3, #:upper16:
87 0074 003093E5 ldr r3, [r3]
88 0078 030052E1 cmp r2, r3
89 007c EBFFFF1A bne .L3
39:../main.c **** }
40:../main.c ****
41:../main.c **** u32MemEndAddress_g = OS_HW_MEM_
90 .loc 1 41 0
91 0080 003000E3 movw r3, #:lower16:
92 0084 003040E3 movt r3, #:upper16:
93 0088 002093E5 ldr r2, [r3]
94 008c 003000E3 movw r3, #:lower16:
95 0090 003040E3 movt r3, #:upper16:
96 0094 002083E5 str r2, [r3]
42:../main.c **** }
97 .loc 1 42 0
98 0098 0000A0E1 mov r0, r0 @ nop
99 009c 00D04BE2 sub sp, fp, #0
100 .cfi_def_
101 @ sp needed
102 00a0 04B09DE4 ldr fp, [sp], #4
103 .cfi_restore 11
104 .cfi_def_cfa_offset 0
105 00a4 1EFF2FE1 bx lr
106 .cfi_endproc
107 .LFE0:
109 .section .text.main,
110 .align 2
111 .global main
113 main:
114 .LFB1:
43:../main.c ****
44:../main.c **** main()
45:../main.c **** {
115 .loc 1 45 0
116 .cfi_startproc
117 @ args = 0, pretend = 0, frame = 0
118 @ frame_needed = 1, uses_anonymous_args = 0
119 0000 00482DE9 stmfd sp!, {fp, lr}
120 .cfi_def_cfa_offset 8
121 .cfi_offset 11, -8
122 .cfi_offset 14, -4
123 0004 04B08DE2 add fp, sp, #4
124 .cfi_def_cfa 11, 4
46:../main.c **** vFindMemSize();
125 .loc 1 46 0
126 0008 FEFFFFEB bl vFindMemSize
127 000c 0030A0E3 mov r3, #0
47:../main.c **** }
128 .loc 1 47 0
129 0010 0300A0E1 mov r0, r3
130 0014 0088BDE8 ldmfd sp!, {fp, pc}
131 .cfi_endproc
132 .LFE1:
134 .text
135 .Letext0:
DEFINED SYMBOLS
R:\TEMP\
R:\TEMP\
R:\TEMP\
R:\TEMP\
R:\TEMP\
R:\TEMP\
R:\TEMP\
R:\TEMP\
R:\TEMP\
R:\TEMP\
NO UNDEFINED SYMBOLS
------
- release version GCC 5.4_2016q2
- binary package
- x86 Windows 10
------
14:54:13 **** Build of configuration Debug for project BitShiftError ****
make all
Building file: ../main.c
Invoking: Cross ARM C Compiler
arm-none-eabi-gcc -mcpu=cortex-a9 -march=armv7-a -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3 -std=gnu11 -Wa,-adhlns=
Using built-in specs.
Reading specs from c:/compiler/
rename spec link_gcc_c_sequence to nosys_link_
COLLECT_
Target: arm-none-eabi
Configured with: /home/build/
Thread model: single
gcc version 5.4.1 20160609 (release) [ARM/embedded-
COLLECT_
c:/compiler/
GNU C11 (GNU Tools for ARM Embedded Processors) version 5.4.1 20160609 (release) [ARM/embedded-
compiled by GNU C version 4.7.4, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-
ignoring duplicate directory "c:/compiler/
ignoring nonexistent directory "c:\compiler\
ignoring duplicate directory "c:/compiler/
ignoring duplicate directory "c:/compiler/
ignoring nonexistent directory "c:\compiler\
#include "..." search starts here:
#include <...> search starts here:
c:\compiler\
c:\compiler\
c:\compiler\
End of search list.
GNU C11 (GNU Tools for ARM Embedded Processors) version 5.4.1 20160609 (release) [ARM/embedded-
compiled by GNU C version 4.7.4, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-
Compiler executable checksum: 7f99c11e705642e
../main.c:44:1: warning: return type defaults to 'int' [-Wimplicit-int]
main()
^
COLLECT_
c:/compiler/
GNU assembler version 2.26.0 (arm-none-eabi) using BFD version (GNU Tools for ARM Embedded Processors) 2.26.0.20160616
COMPILER_
LIBRARY_
COLLECT_
Finished building: ../main.c
Building target: BitShiftError.elf
Invoking: Cross ARM C Linker
arm-none-eabi-gcc -mcpu=cortex-a9 -march=armv7-a -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -g3 -Xlinker --gc-sections -Wl,-Map,
Using built-in specs.
Reading specs from c:/compiler/
rename spec link_gcc_c_sequence to nosys_link_
COLLECT_
COLLECT_
Target: arm-none-eabi
Configured with: /home/build/
Thread model: single
gcc version 5.4.1 20160609 (release) [ARM/embedded-
COMPILER_
LIBRARY_
COLLECT_
c:/compiler/
Finished building target: BitShiftError.elf
Invoking: Cross ARM GNU Create Flash Image
arm-none-
Finished building: BitShiftError.hex
Invoking: Cross ARM GNU Print Size
arm-none-eabi-size --format=berkeley "BitShiftError.elf"
text data bss dec hex filename
1232 1080 40 2352 930 BitShiftError.elf
Finished building: BitShiftError.siz
14:54:14 Build Finished (took 576ms)
&u32ExternRamSi zeDetectionVari able_g + u32MemSize_g
is doing pointer arithmetic. You will need to cast the & to an unsigned int and then do the addition.
(*(unsigned int)(&u32Extern RamSizeDetectio nVariable_ g) + u32MemSize_g)