Loading ...
Sorry, an error occurred while loading the content.

RE: [gnuarm] Bitwise operations in GCC? Also stdlib on ARM.

Expand Messages
  • Charles Manning
    ... They don t have to be, but are by default. unsigned xx:1; // Can be zero or 1 signed xx:1; // Can be 0 or -1
    Message 1 of 19 , Nov 1, 2006
    View Source
    • 0 Attachment
      > -----Original Message-----
      > From: gnuarm@yahoogroups.com [mailto:gnuarm@yahoogroups.com]
      > On Behalf Of Robert Adsett
      > Sent: Tuesday, 31 October 2006 2:15 p.m.
      > To: gnuarm@yahoogroups.com; gnuarm@yahoogroups.com
      > Subject: Re: [gnuarm] Bitwise operations in GCC? Also stdlib on ARM.
      >
      > At 04:39 PM 10/30/2006 -0800, William "Chops" Westfield wrote:
      > >have been pre-defined for you.) On the other hand, it isn't obvious
      > >from the initial example whether BCFG2_bit.WST1 is defined as a
      > >multi-bit field (the name would imply otherwise, to me,
      > anyway.) If it
      > >isn't, I'm not sure I approve of a compiler that does something
      > >"sensible" when assigning a value other than 1 or 0 to a
      > single bit...
      >
      > Note that bitfields are signed, for a one bit bitfield 1 is
      > technically out of range, it does wrap around as expected though.

      They don't have to be, but are by default.

      unsigned xx:1; // Can be zero or 1
      signed xx:1; // Can be 0 or -1

      >
      > That's one of the dragons I mentioned.
      >
      > Robert
      >
      > "C is known as a language that gives you enough rope to shoot
      > yourself in the foot." -- David Brown in comp.arch.embedded
      > http://www.aeolusdevelopment.com/
      >
      >
      >
      >
      > Yahoo! Groups Links
      >
      >
      >
      >
      >
    • lairlab
      Apologizing upfront for reposting (did my first not get through?) So, there is no fix for the differences in the bitfield sizes between compilers? I m
      Message 2 of 19 , Aug 17, 2007
      View Source
      • 0 Attachment
        Apologizing upfront for reposting (did my first not get through?)

        So, there is no fix for the differences in the bitfield sizes between compilers?

        I'm communicating from an ARM linux box with some firmware in an existing instrument
        running on an x86 - and the API define bitfields in the parameter block as ints - resulting
        in 2-byte fields on the x86. However, the same parameter block structure ends up with
        4-byte fields on the ARM compiler - adding a vexing 40 bytes to the length of the the
        parameter block size and naturally causing all sorts of addressing problems.

        Is there no fix beyond a clumsy union and some #defines to catch all the accesses to
        parameter block structure elements in the API code that supports this instrument?

        I could abandon the ARM and get an x86 box to perform this task but what a headache.



        --- In gnuarm@yahoogroups.com, David Hawkins <dwh@...> wrote:
        >
        >
        > >
        > > bit fields are great for compressing integer values into a limited
        > > range. They are a tempting trap for use in I/O.
        >
        > I can't resist, I have to add my one:
        >
        > Bitfields are defined in terms of integers, but check
        > out the gcc assembler a bitfield generates on an x86, it
        > uses byte instructions. So if you are manipulating a
        > 32-bit register, eg. a PCI memory mapped location,
        > then although the byte-enables get generated appropriately,
        > the 32-bit destination of the bit-field operation gets
        > the byte you intended to manipulate and 3 garbage bytes.
        >
        > Go figure :)
        >
        > Rebuilding the same test code with MSVC++ compiled into
        > integer operations, so even compilers can't agree on
        > what to do with them.
        >
        > I've never used them since!
        >
      • Brian Sidebotham
        The C standard (not that I have a copy!) defines that a bitfield shall be of size int. However, it is possible to use different size bitfields in gcc. if you
        Message 3 of 19 , Aug 17, 2007
        View Source
        • 0 Attachment
          The C standard (not that I have a copy!) defines that a bitfield shall be of
          size int. However, it is possible to use different size bitfields in gcc.

          if you need 2-byte bitfields, you can state:

          struct bitfield_16bit {
          unsigned short:1 bit0;
          ...
          unsigned short:1 bit15;
          }

          instead of

          struct bitfield_16bit {
          unsigned int:1 bit0;
          ...
          unsigned int:1 bit15;
          }

          You're problem is not a compiler issue as far as I can see. An int is 32-bit for
          a 32-bit ARM processor, and an int could be 16-bit for the x86 architecture.

          So, the compiler is doing as it ought to, defining an int to the correct size
          for the target processor.

          Best Regards,

          Brian Sidebotham.

          lairlab wrote:
          > Apologizing upfront for reposting (did my first not get through?)
          >
          > So, there is no fix for the differences in the bitfield sizes between compilers?
          >
          > I'm communicating from an ARM linux box with some firmware in an existing instrument
          > running on an x86 - and the API define bitfields in the parameter block as ints - resulting
          > in 2-byte fields on the x86. However, the same parameter block structure ends up with
          > 4-byte fields on the ARM compiler - adding a vexing 40 bytes to the length of the the
          > parameter block size and naturally causing all sorts of addressing problems.
          >
          > Is there no fix beyond a clumsy union and some #defines to catch all the accesses to
          > parameter block structure elements in the API code that supports this instrument?
          >
          > I could abandon the ARM and get an x86 box to perform this task but what a headache.
          >
          >
          >
          > --- In gnuarm@yahoogroups.com, David Hawkins <dwh@...> wrote:
          >>
          >>> bit fields are great for compressing integer values into a limited
          >>> range. They are a tempting trap for use in I/O.
          >> I can't resist, I have to add my one:
          >>
          >> Bitfields are defined in terms of integers, but check
          >> out the gcc assembler a bitfield generates on an x86, it
          >> uses byte instructions. So if you are manipulating a
          >> 32-bit register, eg. a PCI memory mapped location,
          >> then although the byte-enables get generated appropriately,
          >> the 32-bit destination of the bit-field operation gets
          >> the byte you intended to manipulate and 3 garbage bytes.
          >>
          >> Go figure :)
          >>
          >> Rebuilding the same test code with MSVC++ compiled into
          >> integer operations, so even compilers can't agree on
          >> what to do with them.
          >>
          >> I've never used them since!
          >>
          >
          >
        • lairlab
          Brian, Unfortunately, this was already tried... sizeof(unsigned int) is equal to sizeof(unsigned short) and so the following code: struct short_bitfield_16bit
          Message 4 of 19 , Aug 18, 2007
          View Source
          • 0 Attachment
            Brian,

            Unfortunately, this was already tried...

            sizeof(unsigned int) is equal to sizeof(unsigned short) and so the following code:

            struct short_bitfield_16bit {
            unsigned short bit0:1 ;
            unsigned short bit1:1 ;
            ...
            unsigned short bit15:1 ;
            } shortbitfield;

            struct int_bitfield_16bit {
            unsigned int bit0:1 ;
            unsigned int bit1:1 ;
            ...
            unsigned int bit15:1 ;
            } intbitfield;

            printf("sizeof(short)=%d\n", sizeof(short));
            printf("sizeof(int)=%d\n", sizeof(int));
            printf("sizeof(shortbitfield)=%d\n", sizeof(shortbitfield));
            printf("sizeof(intbitfield)=%d\n", sizeof(intbitfield));


            produces this result:

            sizeof(short)=2
            sizeof(int)=2
            sizeof(shortbitfield)=4
            sizeof(intbitfield)=4

            clearly the compiler has decided that it will use 4 bytes as a minimum size for bitfields....





            --- In gnuarm@yahoogroups.com, Brian Sidebotham <micros@...> wrote:
            >
            > The C standard (not that I have a copy!) defines that a bitfield shall be of
            > size int. However, it is possible to use different size bitfields in gcc.
            >
            > if you need 2-byte bitfields, you can state:
            >
            > struct bitfield_16bit {
            > unsigned short:1 bit0;
            > ...
            > unsigned short:1 bit15;
            > }
            >
            > instead of
            >
            > struct bitfield_16bit {
            > unsigned int:1 bit0;
            > ...
            > unsigned int:1 bit15;
            > }
            >
            > You're problem is not a compiler issue as far as I can see. An int is 32-bit for
            > a 32-bit ARM processor, and an int could be 16-bit for the x86 architecture.
            >
            > So, the compiler is doing as it ought to, defining an int to the correct size
            > for the target processor.
            >
            > Best Regards,
            >
            > Brian Sidebotham.
            >
            > lairlab wrote:
            > > Apologizing upfront for reposting (did my first not get through?)
            > >
            > > So, there is no fix for the differences in the bitfield sizes between compilers?
            > >
            > > I'm communicating from an ARM linux box with some firmware in an existing
            instrument
            > > running on an x86 - and the API define bitfields in the parameter block as ints -
            resulting
            > > in 2-byte fields on the x86. However, the same parameter block structure ends up
            with
            > > 4-byte fields on the ARM compiler - adding a vexing 40 bytes to the length of the the
            > > parameter block size and naturally causing all sorts of addressing problems.
            > >
            > > Is there no fix beyond a clumsy union and some #defines to catch all the accesses to
            > > parameter block structure elements in the API code that supports this instrument?
            > >
            > > I could abandon the ARM and get an x86 box to perform this task but what a
            headache.
            > >
            > >
            > >
            > > --- In gnuarm@yahoogroups.com, David Hawkins <dwh@> wrote:
            > >>
            > >>> bit fields are great for compressing integer values into a limited
            > >>> range. They are a tempting trap for use in I/O.
            > >> I can't resist, I have to add my one:
            > >>
            > >> Bitfields are defined in terms of integers, but check
            > >> out the gcc assembler a bitfield generates on an x86, it
            > >> uses byte instructions. So if you are manipulating a
            > >> 32-bit register, eg. a PCI memory mapped location,
            > >> then although the byte-enables get generated appropriately,
            > >> the 32-bit destination of the bit-field operation gets
            > >> the byte you intended to manipulate and 3 garbage bytes.
            > >>
            > >> Go figure :)
            > >>
            > >> Rebuilding the same test code with MSVC++ compiled into
            > >> integer operations, so even compilers can't agree on
            > >> what to do with them.
            > >>
            > >> I've never used them since!
            > >>
            > >
            > >
            >
          • Tom Walsh
            ... Or you could try the packed attribute? ================ publicdefs.h ============== typedef struct __attribute__((packed)) { bool updateLedData:1; bool
            Message 5 of 19 , Aug 18, 2007
            View Source
            • 0 Attachment
              lairlab wrote:
              >
              > Apologizing upfront for reposting (did my first not get through?)
              >
              > So, there is no fix for the differences in the bitfield sizes between
              > compilers?
              >
              > I'm communicating from an ARM linux box with some firmware in an
              > existing instrument
              > running on an x86 - and the API define bitfields in the parameter
              > block as ints - resulting
              > in 2-byte fields on the x86. However, the same parameter block
              > structure ends up with
              > 4-byte fields on the ARM compiler - adding a vexing 40 bytes to the
              > length of the the
              > parameter block size and naturally causing all sorts of addressing
              > problems.
              >
              > Is there no fix beyond a clumsy union and some #defines to catch all
              > the accesses to
              > parameter block structure elements in the API code that supports this
              > instrument?
              >
              > I could abandon the ARM and get an x86 box to perform this task but
              > what a headache.
              >

              Or you could try the packed attribute?

              ================ publicdefs.h ==============
              typedef struct __attribute__((packed)) {
              bool updateLedData:1;
              bool stopLedUpdate:1;
              bool ramtestFailed:1;
              bool ethernetFailed:1;
              bool serial0XmitSuspended:1; // caused by flow control.
              bool serial1XmitSuspended:1; // caused by flow control.
              bool serial0RecvSuspended:1;
              bool serial1RecvSuspended:1;
              bool serial0breakInterrupt:1;
              bool serial0IsNowDown:1;
              bool serial1breakInterrupt:1;
              bool driveRemoved:1;
              bool tripDriveRemoved:1;
              bool tripDailyTest:1;
              } boolean_bits_t;
              ================= snip ===================



              ============= publicdefs.c ==================
              #include <publicdefs.h>

              // public array of boolean control bits.
              boolean_bits_t booleans;

              bool ZonesNeedBursting;
              ================ snip ====================



              ================ publicdefs.lst ==============
              527 6164205A
              527 6F6E6520
              527 2338204F
              527 66662D4E
              528 .comm DriveDesc,30,1
              529 .comm booleans,2,1
              530 .comm buttonTime,4,4
              531 .comm buzzerRate,12,4
              ...
              ...
              /home/tom/tmp/cc3hPTBL.s:359 .rodata:000000000000000c cmdSetBlock
              /home/tom/tmp/cc3hPTBL.s:370 .rodata:0000000000000014 PanelTypes
              /home/tom/tmp/cc3hPTBL.s:377 .rodata:0000000000000054 $d
              /home/tom/tmp/cc3hPTBL.s:499 .data:0000000000000034 runtimeConfig
              *COM*:000000000000001e DriveDesc
              *COM*:0000000000000002 booleans
              *COM*:0000000000000004 buttonTime
              *COM*:000000000000000c buzzerRate
              *COM*:000000000000000c lampsRate
              *COM*:0000000000000004 milliSecondSleepTimer
              ================ snip ====================


              As you can see, on my ARM7TDMI project that the bitfield "booleans" is
              only two 8 bit bytes long? The packed attribute is used to assist in
              aligning fields within a struct.


              Regards,

              TomW


              --
              Tom Walsh - WN3L - Embedded Systems Consultant
              http://openhardware.net http://cyberiansoftware.com http://openzipit.org
              "Windows? No thanks, I have work to do..."
              ----------------------------------------------------
            • Brian Sidebotham
              ... Yep, sorry I missed that out. I compile with -fpack-struct. Best Regards, Brian Sidebotham.
              Message 6 of 19 , Aug 20, 2007
              View Source
              • 0 Attachment
                > Or you could try the packed attribute?
                >
                > ================ publicdefs.h ==============
                > typedef struct __attribute__((packed)) {
                > bool updateLedData:1;
                > bool stopLedUpdate:1;
                > bool ramtestFailed:1;
                > bool ethernetFailed:1;
                > bool serial0XmitSuspended:1; // caused by flow control.
                > bool serial1XmitSuspended:1; // caused by flow control.
                > bool serial0RecvSuspended:1;
                > bool serial1RecvSuspended:1;
                > bool serial0breakInterrupt:1;
                > bool serial0IsNowDown:1;
                > bool serial1breakInterrupt:1;
                > bool driveRemoved:1;
                > bool tripDriveRemoved:1;
                > bool tripDailyTest:1;
                > } boolean_bits_t;
                > ================= snip ===================

                Yep, sorry I missed that out. I compile with -fpack-struct.

                Best Regards,

                Brian Sidebotham.
              Your message has been successfully submitted and would be delivered to recipients shortly.