Swapping bytes & ASR/ASL

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Swapping bytes & ASR/ASL

5,954 Views
Bloodhound
Contributor I

Hi All,

 

On a Coldfire V1 I want to swap the bytes in a word, eg.

$1234 

to

$3412

 

I came up with this convoluted method, is there a simpler way?

 

Enter with value to swap in d0

 moveq        #0,d1
 lsl.l        #8,d0
 add.l        d0,d1
 andi.l       #$FFFF,d0
 lsr.l        #8,d1
 lsr.l        #8,d1
 add.l        d1,d0

 

One final question, with the ROR & ROL Opcodes gone in the CFV1 Core, is the best option to use ASR,ASL instead and monitor the CCR(C)?

 

Thanks,

Ross

Message Edited by Bloodhound on 2009-07-14 04:57 PM
Labels (1)
0 Kudos
Reply
17 Replies

3,262 Views
jbezem
Contributor III

Either use byterev (ISA_C, if available) and use the upper 16 bits of the result, or consider:

move.l d0,d1

lsl.l #8,d0

lsr.l #8,d1

add.l d1,d0

andi.l #$FFFF,d0

 

Syntax errors possible, but the idea hopefully is clear.

 

HTH,

 

Johan

0 Kudos
Reply

3,262 Views
admin
Specialist II

jbezem ,

your second idea of byte swapping (inside 16-bit word) is tested Ok. I only replaced ADD instruction with OR instruction.

The tested code in GNU notation:

 

/* Let d0 = 0x1234 */

 

move.l %d0, %d1 /* d1 = 0x1234 */

lsl.l #8, %d0 /* d0 = 0x123400 */

lsr.l #8, %d1 /* d1 = 0x12 */

or.l %d1, %d0 /* d0 = 0x123412 */

andi.l #0xFFFF, %d0 /* d0 = 0x3412 */

 

0 Kudos
Reply

3,262 Views
Bloodhound
Contributor I

Well, the final thing was how to handle what would have been the ROR / ROL opcodes they had in the CPU32. The Coldfire dropped them and only has LSL/R or ASL/R, are you supposed to keep checking the CCR(C) on every shift? I can see that would get a little messy if you are rotating 6 bits (as an example).

I can't imagine Freescale would have dropped the ROR / ROL opcodes unless there was an easy way to use LSL/R or ASL/R to do the same thing?

 

Cheers,
Ross

0 Kudos
Reply

3,262 Views
admin
Specialist II

> are you supposed to keep checking the CCR(C) on every shift?

 

Bloodhound , the solution of jbezem doesn't use CCR(C).

 

 

> I can't imagine Freescale would have dropped the ROR / ROL opcodes unless there was an

> easy way to use LSL/R or ASL/R to do the same thing?

 

Your question is not specific enough. Could you, please, give the specific problem to resolve in the new post?

 

0 Kudos
Reply

3,262 Views
Bloodhound
Contributor I

Sorry, I'll try to explain better. It didn't help that I posted two questions!

The solution to the byte swap is perfect, thanks, my second question was on rotation of bits.

 

On the 68332 they had the opcodes ROR & ROL where the bits where shifted right or left.

For ROL the bits are rotated out the high-order bit, but the bits rotated out are passed back in to the low-order bit.

Eg 

assume %11110000

ROL #1

becomes 11100001

ROL #1

becomes 11000011

and so on.

 

Or another example:

assume %11110000

ROL #4

becomes %00001111

 

With the Coldfire there is no ROL or ROR opcode.

Doing an ASL or LSL to the above example will always result in the high order bit being lost (though it will change the C flag).

 

My question is, how do you rotate a byte or a word on the Coldfire so the bits are not lost?

I don't see any equivilent opcode to the ROR / ROL so I am assuming you need to do some checking of the CCR(C) bit after each bit is shifted.

 

Thanks,
Ross

Message Edited by Bloodhound on 2009-07-15 03:14 PM
Message Edited by Bloodhound on 2009-07-15 03:16 PM
0 Kudos
Reply

3,262 Views
jbezem
Contributor III

My solution is easily adaptable to use a different number of bits instead of 8, and

so create the equivalent of ROR/ROL.It may need a few more instructions, though.

 

HTH,

 

Johan

0 Kudos
Reply

3,262 Views
Bloodhound
Contributor I

Thanks Johan, but I can't see how that works.

Rotate instructions are circular,your example does not seem to be that, sorry, I'll 'get it' at some point.

 

Cheers,
Ross

0 Kudos
Reply

3,262 Views
admin
Specialist II

> My question is, how do you rotate a byte or a word on the Coldfire so the bits are not lost?

> I don't see any equivilent opcode to the ROR / ROL so I am assuming you need to do some

> checking of the CCR(C) bit after each bit is shifted.

 

> Rotate instructions are circular,your example does not seem to be that, sorry,

> 'll 'get it' at some point.

 

Let register d0 initially contains value 0xA3.

See the below tested code (GNU notation).

 

/* Rotate left by one bit the least significant byte */

lsl.l #1, %d0 /* d0 = 0x146 */

move.l %d0, %d1 /* d1 = 0x146 */

lsr.l #8, %d1 /* d1 = 0x1 */

or.l %d1, %d0 /* d0 = 0x147 */

andi.l #0xFF, %d0 /* d0 = 0x47 */

 

 

Let register d0 initially contains value 0xA3.

See the below tested code (GNU notation).

 

/* Rotate right by one bit the least significant byte */

move.l %d0, %d1 /* d1 = 0xA3 */

lsl.l #7, %d1 /* d1 = 0x5180 */

lsr.l #1, %d0 /* d0 = 0x51 */

or.l %d1, %d0 /* d0 = 0x51D1 */

andi.l #0xFF, %d0 /* d0 = 0xD1 */

0 Kudos
Reply

3,262 Views
jbezem
Contributor III
Exactly as yevgenit described. If you want to use this method for more than a byte, you may need more instructions, since the lsl/lsr immediate instructions shift 8 bits max at a time.

HTH,

Johan
0 Kudos
Reply

3,262 Views
Bloodhound
Contributor I

Thanks for the suggestions everyone.

In the end I just come up with a routine that allows me to define the shift length, in this example I am manipulating 16bit values.

 

Before entering the rotate subroutine I load d3 with the number of bit shifts: (Rotate Right Example)

d0 contains the value to rotate and the final result.

It's annoying it uses 4 registers and lots of CPU cycles, but it will be fine for what I am trying to do.

 

 moveq        #3,d3     ; Rotate Right 3 bits                        
 bsr.w        RotateRight

 

;------------------------------------

 

RotateRight:
 moveq        #15,d2    ; Shifting 15 bits at a time
RotateRightLoop:
 move.l       d0,d1                              
 lsl.l        d2,d1
 lsr.l        #1,d0
 or.l         d1,d0
 andi.l       #$FFFF,d0
 subi.l       #1,d3
 bne.b        RotateRightLoop
 rts

 

If only Freescale didn't drop the ROR / ROL opcodes from the Coldfire :smileysad:

 

Cheers,
Ross

Message Edited by Bloodhound on 2009-07-16 10:11 AM
0 Kudos
Reply

3,262 Views
tupdegrove
Contributor III

To implement ROL for a 32-bit value, how about this for a single-pass routine using 3 registers? The "trick" is using NEG to save one register.

 

 

input parameters:
d0=32-bit input value,32-bit return value
d1=number of bits to rotate left

move.l   d0,d2     //d2=orig d0
lsl.l    d1,d0     //d0=ls portion "rotated" to ms
neg      d1        //d1=negative orig shift amount
addi.l   #32,d1    //d1=shift right amount
lsr.l    d1,d2     //d2=ms portion "rotated" to ls
or.l     d2,d0     //d0=rotated result
rts

 

 

 

By the way, how do you get code to be nicely formatted in a post?

 

 

 

Message Edited by tupdegrove on 2009-07-15 10:48 PM
0 Kudos
Reply

3,262 Views
Bloodhound
Contributor I

Thanks.

 

To get the nice text format, select all your code and change it to the 'Courier New' font in the drop down list (Font Family).

 

Cheers,

Ross

Message Edited by Bloodhound on 2009-07-16 01:13 PM
0 Kudos
Reply

3,262 Views
kef
Specialist I

I see it like this:

 

Shifting left 2 dwords pair D0:smileyvery-happy:1 << 4

 

1) D2 = D1 >> (32-4) ;   // move bits to be shifted out from D1 to D2 and shift them right

2) D0 = D0<< 4;            // shift left higher order reg D0

3) D0 |= D2;                  // paste bits shifted out from D1

4) D1 <<= 4;                // shift left lower order reg

 

 

Rotating left D0 << 4

1) D2 = D0 >> (32-4);    // move bits to be shifted out to temporary register and shift them in opposite direction

2) D0 <<= 4;                 // shift left

3) D0 |= D2;                 // paste bits from temporary register

Message Edited by kef on 2009-07-15 11:35 AM
0 Kudos
Reply

3,262 Views
Bloodhound
Contributor I

Now I feel a bit silly!

I have been using a hardcopy CF Programmers Ref Manual from 2001, the BYTEREV command is not listed in that, I just downloaded the latest 2005 revision of that document and what do you know!

 

Thanks,

Ross

0 Kudos
Reply

3,262 Views
admin
Specialist II

> I have been using a hardcopy CF Programmers Ref Manual from 2001

 

The latest version: 

ColdFire® Family

Programmer’s Reference Manual

Document Number: CFPRM

Rev. 3

03/2005

(http://www.freescale.com/files/dsp/doc/ref_manual/CFPRM.pdf?fsrch=1)

0 Kudos
Reply

3,262 Views
kef
Specialist I

Also consider SWAP.W to swap words after .L-only BYTEREV, and 

 

   MVZ.W D0,D0    to clear upper word

0 Kudos
Reply

3,262 Views
kef
Specialist I

Use byterev instruction

0 Kudos
Reply