m68k: some assembler SwapEndian() implementations I did a while back. disabled for now, because they weren't extensively tested and benchmarked

git-svn-id: trunk@29380 -
This commit is contained in:
Károly Balogh 2015-01-04 01:39:49 +00:00
parent 3d2fca152b
commit f2c7a3efbf

View File

@ -376,3 +376,176 @@ function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comp
if Target = Comperand then
Target := NewValue;
end;
{$if defined(CPUM68K_HAS_BYTEREV) or defined(CPUM68K_HAS_ROLROR)}
{ Disabled for now, because not all cases below were tested. (KB) }
{.$define FPC_SYSTEM_HAS_SWAPENDIAN}
{$endif}
{$if defined(FPC_SYSTEM_HAS_SWAPENDIAN)}
function SwapEndian(const AValue: SmallInt): SmallInt; assembler; nostackframe;
asm
{$if defined(CPUM68K_HAS_ROLROR)}
move.w avalue, d0
ror.w #8, d0
{$elseif defined(CPUM68K_HAS_BYTEREV)}
move.w avalue, d0
byterev d0
swap d0
{$else}
// only ISA A/B ColdFire can end in this branch, so use long ops everywhere
clr.l d0
move.w avalue, d0
move.w d0, d1
lsr.l #8, d0
lsl.l #8, d1
or.l d1, d0
{$endif}
end;
function SwapEndian(const AValue: Word): Word; assembler; nostackframe;
asm
{$if defined(CPUM68K_HAS_ROLROR)}
move.w avalue, d0
ror.w #8, d0
{$elseif defined(CPUM68K_HAS_BYTEREV)}
move.w avalue, d0
byterev d0
swap d0
{$else}
// only ISA A/B ColdFire can end in this branch, so use long ops everywhere
clr.l d0
move.w avalue, d0
move.w d0, d1
lsr.l #8, d0
lsl.l #8, d1
or.l d1, d0
{$endif}
end;
function SwapEndian(const AValue: LongInt): LongInt; assembler; nostackframe;
asm
{$if defined(CPUM68K_HAS_ROLROR)}
move.l avalue, d0
ror.w #8, d0
swap d0
ror.w #8, d0
{$elseif defined(CPUM68K_HAS_BYTEREV)}
move.l avalue, d0
byterev d0
{$else}
// only ISA A/B ColdFire can end in this branch, so use long ops everywhere
move.l avalue, d0
move.l d0, d1
andi.l #$ff00ff00, d0
andi.l #$00ff00ff, d1
lsr.l #8, d0
lsl.l #8, d1
or.l d1, d0
swap d0
{$endif}
end;
function SwapEndian(const AValue: DWord): DWord; assembler; nostackframe;
asm
{$if defined(CPUM68K_HAS_ROLROR)}
move.l avalue, d0
ror.w #8, d0
swap d0
ror.w #8, d0
{$elseif defined(CPUM68K_HAS_BYTEREV)}
move.l avalue, d0
byterev d0
{$else}
// only ISA A/B ColdFire can end in this branch, so use long ops everywhere
move.l avalue, d0
move.l d0, d1
andi.l #$ff00ff00, d0
andi.l #$00ff00ff, d1
lsr.l #8, d0
lsl.l #8, d1
or.l d1, d0
swap d0
{$endif}
end;
function SwapEndian(const AValue: Int64): Int64; assembler; nostackframe;
asm
{$if defined(CPUM68K_HAS_ROLROR)}
move.l avalue+4, d0
ror.w #8, d0
swap d0
ror.w #8, d0
move.l avalue, d1
ror.w #8, d1
swap d1
ror.w #8, d1
{$elseif defined(CPUM68K_HAS_BYTEREV)}
move.l avalue+4, d0
move.l avalue, d1
byterev d0
byterev d1
{$else}
// only ISA A/B ColdFire can end in this branch, so use long ops everywhere
move.l d2, -(sp)
move.l avalue+4, d0
move.l d0, d1
andi.l #$ff00ff00, d0
andi.l #$00ff00ff, d1
lsr.l #8, d0
lsl.l #8, d1
or.l d1, d0
swap d0
move.l avalue, d1
move.l d1, d2
andi.l #$ff00ff00, d1
andi.l #$00ff00ff, d2
lsr.l #8, d1
lsl.l #8, d2
or.l d2, d1
swap d1
move.l (sp)+, d2
{$endif}
end;
function SwapEndian(const AValue: QWord): QWord; assembler; nostackframe;
asm
{$if defined(CPUM68K_HAS_ROLROR)}
move.l avalue+4, d0
ror.w #8, d0
swap d0
ror.w #8, d0
move.l avalue, d1
ror.w #8, d1
swap d1
ror.w #8, d1
{$elseif defined(CPUM68K_HAS_BYTEREV)}
move.l avalue+4, d0
move.l avalue, d1
byterev d0
byterev d1
{$else}
// only ISA A/B ColdFire can end in this branch, so use long ops everywhere
move.l d2, -(sp)
move.l avalue+4, d0
move.l d0, d1
andi.l #$ff00ff00, d0
andi.l #$00ff00ff, d1
lsr.l #8, d0
lsl.l #8, d1
or.l d1, d0
swap d0
move.l avalue, d1
move.l d1, d2
andi.l #$ff00ff00, d1
andi.l #$00ff00ff, d2
lsr.l #8, d1
lsl.l #8, d2
or.l d2, d1
swap d1
move.l (sp)+, d2
{$endif}
end;
{$endif FPC_SYSTEM_HAS_SWAPENDIAN}