How to mirror a byte

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

How to mirror a byte

Jump to solution
6,038 Views
pelle2005reg
Contributor I

Hi to all,

i would like to say if in the HCS12 assembler there is a instruction to mirror a byte.

That is, "convert" a byte in his mirror, for example:
$01 --> $80

$A1 --> $85

 

An istruction o a set of instruction (the fatest) .

Thank you

Labels (1)
0 Kudos
Reply
1 Solution
2,030 Views
CompilerGuru
NXP Employee
NXP Employee

The fastest way is probably a table lookup if you can afford the memory for a 256 bytes table.

 

Daniel

View solution in original post

0 Kudos
Reply
6 Replies
2,031 Views
CompilerGuru
NXP Employee
NXP Employee

The fastest way is probably a table lookup if you can afford the memory for a 256 bytes table.

 

Daniel

0 Kudos
Reply
2,030 Views
pelle2005reg
Contributor I
The table solution was also my first idea.
0 Kudos
Reply
2,030 Views
bigmac
Specialist III

Hello,

 

If my estimations are correct, the byte table lookup method should occupy about 7 cycles.  The nybble table lookup method would seem much less efficient at about 30 cycles (using assembly code, rather than C).  This would compare with the "shift loop" method at about 44 cycles.  I assumed that ACCB contained the byte value to be mirrored, and that the result was also in ACCB.

 

The byte table lookup code might consist of the following:

   ldx   #BYTETAB   ; Start of byte table

   abx

   ldab  0,x

 

Regards,

Mac

 

0 Kudos
Reply
2,030 Views
kef
Specialist I

Mac,

 

HC12 indexed addressing allows LDAB  B,X  , so -2 cycles saved on ABX.

Also loop unrolling should be considered. With single cycle shift instructions RORB, ROLA, or similar, reversing bits order from B to A should take 2cycles per bit, 2*8=16 cycles. + 1 cycle to transfer result back from A to B.

 

0 Kudos
Reply
2,030 Views
Lundin
Senior Contributor IV
This C code is fairly effective too. It works on nibble-level instead of byte-level, to save ROM:

#pragma CONST_SEG GLOBAL_ROM

static const uint8 MIRROR_TABLE[16] =
{
  0x0, 0x8, 0x4, 0xC,  /*  0-3  */
  0x2, 0xA, 0x6, 0xE,  /*  4-7  */
  0x1, 0x9, 0x5, 0xD,  /*  8-11 */
  0x3, 0xB, 0x7, 0xF   /* 12-15 */
};

#pragma CONST_SEG DEFAULT


uint8 my_byte; /* byte to mirror */
uint8 tmp;

tmp = MIRROR_TABLE[my_byte >> 4];
tmp <<= 4;
my_byte = MIRROR_TABLE[my_byte & 0x0F] | tmp;


On a Freescale micro, the left shift will be optimized into a MUL instruction, saving a few ticks. The right shift will become 4 LSRx instructions (no optimization possible).

If you expand the lookup table from 16 bytes to 256 bytes you don't need to do the shifting and thus save 10 CPU ticks or so, at the cost of ROM.
Message Edited by Lundin on 2009-12-01 11:46 AM
0 Kudos
Reply
2,030 Views
AndersJ
Contributor IV

The C code to mirror a byte may be fairly effective, but unfortunately it doesn't work.

It basically does what it should but swaps the output nibbles.

 

Try this  instead:

tmp = MIRROR_TABLE[my_byte & 0x0F];
tmp <<= 4;
my_byte = MIRROR_TABLE[my_byte >> 4]; | tmp;

 

Anders Johansson

0 Kudos
Reply