Pasm - shift multiple longs?
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
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
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Composite NTSC sprite driver: Forum
NTSC & PAL driver templates: ObEx Forum
OnePinTVText driver: ObEx Forum
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)?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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 0Here 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
What does that do?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
$ 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