This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/62180] New: (RX600) - compiler doesn't honor -fstrict-volatile-bitfields and generates incorrect machine code for I/O register access
- From: "jan.capek at braiins dot cz" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 19 Aug 2014 08:20:19 +0000
- Subject: [Bug target/62180] New: (RX600) - compiler doesn't honor -fstrict-volatile-bitfields and generates incorrect machine code for I/O register access
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62180
Bug ID: 62180
Summary: (RX600) - compiler doesn't honor
-fstrict-volatile-bitfields and generates incorrect
machine code for I/O register access
Product: gcc
Version: 4.9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: jan.capek at braiins dot cz
Created attachment 33359
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33359&action=edit
broken output from gcc 4.9.0
I have come across this issue while testing 4.9.x series of the compiler with
Renesas RX600 target
The compiler now generates byte accesses when writing bitfields completely
ignoring their 'type'. The strict-volatile-bitfields options seems to have no
effect. Our original compiler version 4.7.2 seems to work correctly and
generates accesses to the bitfields based on their type. This is essentially
what the documentation for the 'strict-volatile-bitfields' says.
I have tested this with 4.8.2 and 4.8.3, too with the same result. The test
case demonstrates access to a 16-bit memory mapped peripheral register. It is
absolutely necessary that the register is always being written in 16-bit
quantities.
A simple testcase:
struct st_cmt0 {
union {
unsigned short WORD;
struct {
volatile unsigned short CKS:2;
volatile unsigned short :4;
volatile unsigned short CMIE:1;
volatile unsigned short :9;
} BIT;
} CMCR;
unsigned short CMCNT;
unsigned short CMCOR;
};
void test(volatile struct st_cmt0 *reg)
{
reg->CMCR.BIT.CMIE = 1;
}
The output for gcc 4.7.2 is:
.file "test.c"
.section P,"ax"
.global _test
.type _test, @function
_test:
pushm r6-r11
add #-4, r0, r6
mov.L r6, r0
mov.L r1, [r6]
mov.L [r6], r11
mov.W [r11], r10 ; HONORS the 16-bit register size
bset #6, r10
mov.W r10, [r11] ; HONORS the 16-bit register size
rtsd #28, r6-r11
.size _test, .-_test
.ident "GCC: (GNU) 4.7.2"
The output for gcc 4.9.0 is:
.file "test.c"
.section P,"ax"
.global _test
.type _test, @function
_test:
pushm r6-r11
add #-4, r0, r6
mov.L r6, r0
mov.L r1, [r6]
mov.L [r6], r11
mov.B [r11], r10 ; broken - reads only part of the register
bset #6, r10
mov.B r10, [r11] ; broken - writes only part of the register
rtsd #28, r6-r11
.size _test, .-_test
.ident "GCC: (GNU) 4.9.0"