This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/62180] New: (RX600) - compiler doesn't honor -fstrict-volatile-bitfields and generates incorrect machine code for I/O register access


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"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]