Shop OBEX P1 Docs P2 Docs Learn Events
Pasm - shift multiple longs? — Parallax Forums

Pasm - shift multiple longs?

Agent420Agent420 Posts: 439
edited 2009-09-02 14:40 in Propeller 1
I've got bit pattern data that is 64 bits wide comprised of 2 longs.· I'm trying to think of the most efficient method to shift them right or left multiple bits as a single unit.· The number or bits to shift right or left will be in 2 variables, cshr & cshl.

Right now I'm thinking of something like this:

cseg_l and cseg_r are the 2 longs comprising the 64 bit pattern to shift
cshr = number of bits to shift right
chsr_m32 = 32-number of bits to shift right, to be used for reversing operations
chsr_mask = bit pattern shifted out of cseg_l lsb into cseg_r msb

                        mov     cshr,#0                 'reset shift bitcount
                        mov     chsr_m32,#32            'reset reverse bitcount  
                        cmps    cx,#0           wc      'if cx < 0 calc bits to shift
        if_c            neg     cshr,cx                 '# bits to shift = - cursor x
        if_c            sub     cshr_m32,chsr           '32 - bitcount to reverse
        if_c            mov     cx,#0
        
                        mov     cshr_mask,cseg_l        'copy cseg_l to temp mask
                        rev     cshr_mask,chsr_m32      'rev btm chsr bits, clears msb balance
                        rev     cshr_mask,#0            'reverse bits to make them msb
                        shr     cseg_l,cshr             'shift cseg_l pixels right
                        shr     cseg_r,cshr             'shift cseg_r pixels right
                        or      cseg_r,cshr_mask        'set cseg2 bits shifted out from cseg


The basic idea is to calculate 32 minus # bits to reverse (chsr_m32), then use that value on a copy of the left side long (cshr_mask).· This should provide a reverse image of the lsb bits that will be shifted out of the left side long (cseg_l) into the msb of the right side long (cseg_r).· The copied image (cshr_mask) is then entirely reversed resulting in the bit pattern shifted out from·the left long·is no longer reversed and also now in the msb position, where it is OR'd to the right side long after it is shifted.

Same idea would be used for shifting left.

Any comments / suggestions?· A better way?· I was curious if some shift / rotate with carry operation would be better, but I couldn't figure out a way to apply it.· This might have to be applied to longer multiple long data, it is for shifting graphic bitmap data.



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Post Edited (Agent420) : 9/2/2009 12:42:12 PM GMT

Comments

  • ericballericball Posts: 774
    edited 2009-09-02 12:45
    I think this will work.
     shr  cseg_r, cshr   ' right shift right long, fill with zeros
     ror  cseg_l, cshr   ' right roll left long
     neg  mask_r, #1     ' mask_r = FFFF_FFFF
     neg  mask_l, #1     ' mask_l = FFFF_FFFF
     shr  mask_l, cshr   ' mask for left long
     xor  mask_r, mask_l ' mask for right long mask_r := !mask_l
     and  mask_r, cseg_l ' save bits shifted out of left long
     and  cseg_l, mask_l ' mask off right bits of left long
     or   cseg_r, mask_r ' merge the two longs
    
    




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Composite NTSC sprite driver: Forum
    NTSC & PAL driver templates: ObEx Forum
    OnePinTVText driver: ObEx Forum
  • Agent420Agent420 Posts: 439
    edited 2009-09-02 13:09
    Clever.· I'll have to give that a try.· XOR is probably the least well understood cmd in my vocabulary.

    Regarding the REV reverse command, 0 reverses all bits, 31 reverses all but msb... so there is no value you can use that basically results in no reversing correct?· If I were to use that elsewhere with the possibility of not requiring a reverse operation, I'd probably have to use the conditional flags (it's not like rol or shr commands where a value of 0 results in no bits modified)?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • AleAle Posts: 2,363
    edited 2009-09-02 13:49
    Here a long version

    DAT
    
        ' cshr number of bits to shift right
        ' cseg_r, cseg_l
    
        shr    cseg_r, cshr    ' first shift, we make place
        mov    temp, cseg_l
        shr    cseg_l, cshr    ' second shift
        mov    temp2, 3 wc    ' sets C flag
        mov    temp2, #0    ' clears mask 
        rcl    temp2, cshr    ' generates mask
        and    temp, temp2    ' extracts data
        mov    temp2, #32
        sub    temp2, cshr
        shl    temp, temp2    ' positions bits
        or    cseg_r, temp    ' or to get result
        
    
    cseg_r    long    $5000_0005
    cseg_l    long    $B000_000A
    cshr    long    4
    temp    long    0
    temp2    long    0
    
    
    



    Here is another shorter one but not shorter than eric's (with his great use of xor):

        shr    cseg_r, cshr    ' first shift, we make place
        mov    temp, cseg_l
        shr    cseg_l, cshr    ' second shift
        ror    temp, cshr
        mov    mask_l, $ wc
        mov    mask_l, #0
        rcr    mask_l, cshr
        and    temp, mask_l    ' extracts data
        or    cseg_r, temp    ' or to get result
        
    
    cseg_r    long    $5000_0005
    cseg_l    long    $B000_000A
    cshr    long    4
    mask_r  long    0
    mask_l  long    0
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Visit some of my articles at Propeller Wiki:
    MATH on the propeller propeller.wikispaces.com/MATH
    pPropQL: propeller.wikispaces.com/pPropQL
    pPropQL020: propeller.wikispaces.com/pPropQL020
    OMU for the pPropQL/020 propeller.wikispaces.com/OMU

    Post Edited (Ale) : 9/2/2009 2:44:05 PM GMT
  • Agent420Agent420 Posts: 439
    edited 2009-09-02 13:54
    > mov····mask_l,·$·wc
    What does that do?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • AleAle Posts: 2,363
    edited 2009-09-02 14:40
    That is just pure cleverness (I think it was PhilPI who came with that idea):

    $ is the current address, so mask_i is loaded with the value of the opcode (located at position $). But that is not important, what it is is that the carry flag is loaded with the bit 31 for every mov. As the encoding for mov has the bit 31 set, that instruction sets the carry flag ! (effect wc forces the load of the flag).

    Then rcl/rcr can be used to generate a right or left aligned mask.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Visit some of my articles at Propeller Wiki:
    MATH on the propeller propeller.wikispaces.com/MATH
    pPropQL: propeller.wikispaces.com/pPropQL
    pPropQL020: propeller.wikispaces.com/pPropQL020
    OMU for the pPropQL/020 propeller.wikispaces.com/OMU
Sign In or Register to comment.