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

Getting the compiler to use BSET/BCLR

Expand Messages
  • bgilbert_s5w
    Is there a way to get the GCC compiler to use BSET and BCLR? When I do an operation that is effectively a BSET or BCLR, the compiler generates three
    Message 1 of 8 , Jul 11, 2006

      Is there a way to get the GCC compiler to use BSET and BCLR?  When I do an operation that is effectively a BSET or BCLR, the compiler generates three instructions.  It reads in the register, ORs in or ANDs out the correct bit, then writes out the whole byte again.

       

      Here is a sample of the code I am using:

       

      typedef union {

             uint8 byte;

             struct {

                    uint8 BIT7 : 1;

                    uint8 BIT6 : 1;

                    uint8 BIT5 : 1;

                    uint8 BIT4 : 1;

                    uint8 BIT3 : 1;

                    uint8 BIT2 : 1;

                    uint8 BIT1 : 1;

                    uint8 BIT0 : 1;

             }bit;

      }reg08;

       

      #define PTG   (*((volatile reg08*)(0x0250 + REG_BASE)))

       

       

       

       

      void func()

      {

          PTG.bit.BIT1 = 1;

      }

       

       

      And the code that is generated is:

       

          7e58:     f6 02 50      ldab   250 <.LC6+0x6>

          7e5b:     ca 02         orab   #2

          7e5d:     7b 02 50      stab   250 <.LC6+0x6>

       

       

      But, what I want is:

       

          7e60:     1c 02 50 01   bset   250 <.LC6+0x6> #$01

       

      Is there a way in C to insure that the simpler BSET or BCLR gets generated?

       

      Thanks,

      -Brett

       

    • Jefferson Smith
      ... For HC12 it s kinda tricky because GCC doesn t seem to realize that BSET can work with both Direct addressing and Extended addressing. It only optimizes as
      Message 2 of 8 , Jul 12, 2006
        --- In gnu-m68hc11@yahoogroups.com, "bgilbert_s5w" <bgilbert@...> wrote:
        > Is there a way to get the GCC compiler to use BSET and BCLR?

        For HC12 it's kinda tricky because GCC doesn't seem to realize that
        BSET can work with both Direct addressing and Extended addressing. It
        only optimizes as desired if it knows that the address is in page0
      • Tom Burrell
        Message Brett, I don t use bit fields, I am old and don t trust them to be stable from compiler to compiler; however, I looked in my listings and found BSET
        Message 3 of 8 , Jul 12, 2006
          Message
          Brett,
          I don't use bit fields, I am old and don't trust them to be stable from compiler to compiler; however, I looked in my listings and found BSET and BCLR for |= and &= equations.  I don't know if there is anything to turn it on and off.
           
          To test it change the bit fields to &= and |= and see what is output.
          Good Luck,
          Tom
          -----Original Message-----
          From: bgilbert [mailto:bgilbert@...]
          Sent: Tuesday, July 11, 2006 9:06 AM
          To: gnu-m68hc11
          Subject: Getting the compiler to use BSET/BCLR

          Is there a way to get the GCC compiler to use BSET and BCLR?  When I do an operation that is effectively a BSET or BCLR, the compiler generates three instructions.  It reads in the register, ORs in or ANDs out the correct bit, then writes out the whole byte again.

          Here is a sample of the code I am using:

          typedef union {

                 uint8 byte;

                 struct {

                        uint8 BIT7 : 1;

                        uint8 BIT6 : 1;

                        uint8 BIT5 : 1;

                        uint8 BIT4 : 1;

                        uint8 BIT3 : 1;

                        uint8 BIT2 : 1;

                        uint8 BIT1 : 1;

                        uint8 BIT0 : 1;

                 }bit;

          }reg08;

          #define PTG   (*((volatile reg08*)(0x0250 + REG_BASE)))

          void func()

          {

              PTG.bit.BIT1 = 1;

          }

          And the code that is generated is:

              7e58:     f6 02 50      ldab   250 <.LC6+0x6>

              7e5b:     ca 02         orab   #2

              7e5d:     7b 02 50      stab   250 <.LC6+0x6>

          But, what I want is:

              7e60:     1c 02 50 01   bset   250 <.LC6+0x6> #$01

          Is there a way in C to insure that the simpler BSET or BCLR gets generated?

          Thanks,

          -Brett

           

        • Jefferson Smith
          Tom, Could you verify whether any of those BSET/BCLR you saw are target addresses greater that 0xff? I suspect they are all in page0, where the addr in the
          Message 4 of 8 , Jul 13, 2006
            Tom,

            Could you verify whether any of those BSET/BCLR you saw are target
            addresses greater that 0xff? I suspect they are all in page0, where
            the addr in the struct is not.
          • Tom Burrell
            Jeff, This one is 9,x It is doing work on an automatic variable so it can t be below 0x4000. uiFree is a unsigned short uiFree &= 0xfffe; // even sectors 582
            Message 5 of 8 , Jul 13, 2006
              Jeff,
              This one is 9,x It is doing work on an automatic variable so it can't be
              below 0x4000.
              uiFree is a unsigned short
              uiFree &= 0xfffe; // even sectors
              582 015e 0D 09 01 bclr 9,x, #1
              This is the one I find on the windows side. I noticed 3 on th Linux side
              before.

              Tom
              -----Original Message-----
              From: imajeff84663 [mailto:imajeff84663@...]
              Sent: Thursday, July 13, 2006 8:45 AM
              To: gnu-m68hc11
              Subject: Re: Getting the compiler to use BSET/BCLR


              Tom,

              Could you verify whether any of those BSET/BCLR you saw are target
              addresses greater that 0xff? I suspect they are all in page0, where the
              addr in the struct is not.





              To Post a message, send it to: gnu-m68hc11@...

              To Unsubscribe, send a blank message to:
              gnu-m68hc11-unsubscribe@...
              Yahoo! Groups Links
            • Stephane Carrez
              ... Hash: SHA1 ... If you compile the following: unsigned char mask; void flag_it() { mask |= 0x10; } with -Os -m68hc12 -mshort -fomit-frame-pointer the
              Message 6 of 8 , Jul 14, 2006
                -----BEGIN PGP SIGNED MESSAGE-----
                Hash: SHA1

                bgilbert_s5w wrote:
                >
                >
                > Is there a way to get the GCC compiler to use BSET and BCLR? When I do
                > an operation that is effectively a BSET or BCLR, the compiler generates
                > three instructions. It reads in the register, ORs in or ANDs out the
                > correct bit, then writes out the whole byte again.
                >
                >

                If you compile the following:

                unsigned char mask;

                void flag_it()
                {
                mask |= 0x10;
                }


                with '-Os -m68hc12 -mshort -fomit-frame-pointer' the compiler generates:

                flag_it:
                bset mask, #16
                rts

                For 68HC11, you'll need to put the 'mask' variable in page0 for this to happen.

                Stephane
                -----BEGIN PGP SIGNATURE-----
                Version: GnuPG v1.4.2 (GNU/Linux)
                Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

                iD8DBQFEt0RsNyQxO2LzKT0RAsP6AKCAA9hzKhEqe7wwWHo4K+OoDIpRDwCg44Jl
                kFlLP7wAWtj4rD8WjVX5to4=
                =HUnP
                -----END PGP SIGNATURE-----
              • bgilbert_s5w
                Stephane, As I have looked into this further, I found that this issue is a function of the optimization setting on the compiler. I had optimization turned off
                Message 7 of 8 , Jul 14, 2006

                  Stephane,

                  As I have looked into this further, I found that this issue is a function of the optimization setting on the compiler.  I had optimization turned off so that I wouldn't have any problems with debugging.  Once I set it even to level 1, my original sample code compiled to a BSET or BCLR.

                  The issue of Page0 hasn't been an issue for me because I have the registers and RAM mapped all below 0x4000.

                  There was an oddity I found with strings with optimization turned on, but I'll start a new thread for that one.

                  Thanks,

                  -Brett


                  --- In gnu-m68hc11@yahoogroups.com, Stephane Carrez <stcarrez@...> wrote:
                  >
                  > If you compile the following:
                  >
                  > unsigned char mask;
                  >
                  > void flag_it()
                  > {
                  > mask |= 0x10;
                  > }
                  >
                  >
                  > with '-Os -m68hc12 -mshort -fomit-frame-pointer' the compiler generates:
                  >
                  > flag_it:
                  > bset mask, #16
                  > rts
                  >
                  > For 68HC11, you'll need to put the 'mask' variable in page0 for this to happen.

                • Jefferson Smith
                  ... Good, sorry I didn t think of saying it only does it with optimizations. I think using bset and bclr works better than I remember when I was trying to work
                  Message 8 of 8 , Jul 14, 2006
                    --- In gnu-m68hc11@yahoogroups.com, "bgilbert_s5w" <bgilbert@...> wrote:
                    > As I have looked into this further, I found that this issue is a
                    > function of the optimization setting on the compiler. I had
                    > optimization turned off so that I wouldn't have any problems with
                    > debugging. Once I set it even to level 1, my original sample code
                    > compiled to a BSET or BCLR.

                    Good, sorry I didn't think of saying it only does it with
                    optimizations. I think using bset and bclr works better than I
                    remember when I was trying to work things out in the past years
                    (thanks, Stephane).


                    > The issue of Page0 hasn't been an issue for me because I have the
                    > registers and RAM mapped all below 0x4000.

                    Interresting, page0 is indeed *below* 0x4000, and ranges
                    0x0000..0x00ff. To avoid confusion, the Flash region you are thinking
                    of is referred to as "bank 0" or PPAGE 0 (PPAGE stands for Program Page).
                  Your message has been successfully submitted and would be delivered to recipients shortly.