Shop OBEX P1 Docs P2 Docs Learn Events
How can I do a circular bit shift in propeller C — Parallax Forums

How can I do a circular bit shift in propeller C

Invent-O-DocInvent-O-Doc Posts: 768
edited 2013-10-14 03:05 in Propeller 1
I know people use statements all the time like a = z << 2; , which gives a bit shift and everything that goes to the end of the variable's bit range gets chopped off, but doesn't the propeller have a PASM for a bit rotation that takes bits from one side to another in the form of a rotation???

SPIN has the '->' and '<-' operators that do this.

Is there any equivalent to this rotation command using C or C++ in Simple IDE????

The examples I see on C sites are fairly inefficient compared to an equivalent of the prop's own bit rotate.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-10-13 18:43
    I wouldn't worry too much. The compilers are quite clever in spotting the intent, i.e. propgcc will convert
    (a << b)|(a >> (32 - b)) to [COLOR="#020FC0"]rol a, b[/COLOR] and
    (a << (32 - b))|(a >> b) to [COLOR="#FF8C00"]ror a, b[/COLOR]
    
  • Heater.Heater. Posts: 21,230
    edited 2013-10-14 02:17
    kuroneko,
    The compilers are quite clever in spotting the intent

    Not in this case with propgcc it seems:
    #include <stdio.h>
    #include <math.h>
    
    int roller (int a, int b)
    {
            return ((a << b)|(a >> (32 - b)));        // To rol a, b and
    }
    
    int main (int argc, char* argv[])
    {
            return (roller(3, 9));
    }
    
    Compiles down to:
    .text
            .balign 4
            .global _roller
    _roller
            mov     r7, #32
            sub     r7, r1
            mov     r6, r0
            sar     r6, r7:Q
            shl     r0, r1
            mov     r7, r6
            or      r7, r0
            mov     r0, r7
            lret
            .balign 4
            .global _main
    _main
            mvi     r0,#1536
            lret
    
    Using: /opt/parallax/bin/propeller-elf-gcc -Os -Wall -S -o rol.s rol.c

    As we see there are two shifts and an OR operation.

    Similar with GCC on my PC.

    Don't we have an intrinsic in propgcc to do this inline?
  • kuronekokuroneko Posts: 3,623
    edited 2013-10-14 02:30
    Fair enough, I used unsigned int:
    unsigned int rol(unsigned int a, int b) {
      return (a << b)|(a >> (32 - b));
    }
    
    unsigned int ror(unsigned int a, int b) {
      return (a << (32 - b))|(a >> b);
    }
    
    int main()                                    // Main function
    {
        return rol(3, 9);
    }
    
    with your command line I get:
    .text
    	.balign	4
    	.global	_rol
    _rol
    	rol	r0, r1
    	mov	pc,lr
    	.balign	4
    	.global	_ror
    _ror
    	ror	r0, r1
    	mov	pc,lr
    	.balign	4
    	.global	_main
    _main
    	mvi	r0,#1536
    	mov	pc,lr
    
    I believe your >> on a signed int spoils it somehow.
  • Heater.Heater. Posts: 21,230
    edited 2013-10-14 02:52
    Ah yes, quite so. You would not believe the number of times I forgotten that signed vs unsigned thing over the years when dealing with shifts:)

    Of course a >> on a signed number propagates the sign bit down from the top so it can never be the same as a ror. Unless some extra masking is in place to remove propagated bits.
    In the rol case we would also be applying a >> to a signed number (the "(a >> (32 - b))" part. That would then require a mask to get rid of the propagated sign bits so it's probably better for the compiler to do what it does.
  • Heater.Heater. Posts: 21,230
    edited 2013-10-14 03:00
    Interesting. Something has changed. With your code I get:
    .text
            .balign 4
            .global _rol
    _rol
            rol     r0, r1
            lret
            .balign 4
            .global _ror
    _ror
            ror     r0, r1
            lret
            .balign 4
            .global _main
    _main
            mvi     r0,#1536
            lret
    

    Note the use of "lret". I guess it's the same thing.

    Except.. If I compile with "-mcog" then it the same as yours.

    Never mind.
  • Heater.Heater. Posts: 21,230
    edited 2013-10-14 03:05
    What we did not say is that it is important to have optimizations switched on to get this rol and ror.
    -Os or -O2 or -O3 work.
    -O1 does not.
Sign In or Register to comment.