[fpc-pascal] rotating bits
Florian Klaempfl
florian at freepascal.org
Wed May 24 17:33:38 CEST 2006
Пётр Косаревский wrote:
>> On 24 mei 2006, at 10:56, Пётр Косаревский wrote:
>>> Is there high level operator/(inline)function for rotating bits?
>> No.
>>> Am I supposed to implement rotating bits (like ror/rol in i386 asm)
>>> by inline assembler or some ugly workarounds (shifts and or-s)?
>> Yes. I think there's already a feature request to provide these
>> operations, but no one worked on it yet.
>> Jonas_______________________________________________
>
> Why don't use this code?
The inline is useless, assembler procedures aren't really inlinable.
>
> {$INLINE ON}
> interface
> {$IFDEF CPUI386}
> function brol(b: byte; c: byte): byte; assembler; inline;
> function wrol(w: word; c: byte): word; assembler; inline;
> function lrol(l: longword; c: byte): longword; assembler; inline;
> function bror(b: byte; c: byte): byte; assembler; inline;
> function wror(w: word; c: byte): word; assembler; inline;
> function lror(l: longword; c: byte): longword; assembler; inline;
> {$ELSE}
> function brol(b: byte; c: byte): byte; inline;
> function wrol(w: word; c: byte): word; inline;
> function lrol(l: longword; c: byte): longword; inline;
> function bror(b: byte; c: byte): byte; inline;
> function wror(w: word; c: byte): word; inline;
> function lror(l: longword; c: byte): longword; inline;
> {$ENDIF}
>
> implementation
> {$IFDEF CPUI386}
> function brol(b: byte; c: byte): byte; assembler; inline;
> asm
> movb b,%al
> movb c,%cl
> rolb %cl,%al
> movb %al,result
> end ['al','cl'];
> function wrol(w: word; c: byte): word; assembler; inline;
> asm
> movw w,%ax
> movb c,%cl
> rolw %cl,%ax
> movw %ax,result
> end ['ax','cl'];
> function lrol(l: longword; c: byte): longword; assembler; inline;
> asm
> movl l,%eax
> movb c,%cl
> roll %cl,%eax
> movl %eax,result
> end ['eax','cl'];
> function bror(b: byte; c: byte): byte; assembler; inline;
> asm
> movb b,%al
> movb c,%cl
> rorb %cl,%al
> movb %al,result
> end ['al','cl'];
> function wror(w: word; c: byte): word; assembler; inline;
> asm
> movw w,%ax
> movb c,%cl
> rorw %cl,%ax
> movw %ax,result
> end ['ax','cl'];
> function lror(l: longword; c: byte): longword; assembler; inline;
> asm
> movl l,%eax
> movb c,%cl
> rorl %cl,%eax
> movl %eax,result
> end ['eax','cl'];
> {$ELSE}
> function brol(b: byte; c: byte): byte; inline;
> var s,r: byte;
> begin
> s:=c and $7;
> r:=byte(b shl s);
> r:=r or byte(b shr (8-s)); // c may be over 8 and should be processed correctly
> brol:=r; // "result" is not supported in inline procedures
> end;
> function wrol(w: word; c: byte): word; inline;
> var s: byte; r: word;
> begin
> s:=c and $f;
> r:=word(w shl s);
> r:=r or word(w shr (16-s)); // c may be over 16 and should be processed correctly
> wrol:=r;
> end;
> function lrol(l: longword; c: byte): longword; inline;
> var s: byte; r: longword;
> begin
> s:=c and $1f;
> r:=longword(l shl s);
> r:=r or longword(l shr (32-s)); // c may be over 32 and should be processed correctly
> lrol:=r;
> end;
> function bror(b: byte; c: byte): byte; inline;
> var s,r: byte;
> begin
> s:=c and $7;
> r:=byte(b shr s);
> r:=r or byte(b shl (8-s)); // c may be over 8 and should be processed correctly
> bror:=r;
> end;
> function wror(w: word; c: byte): word; inline;
> var s: byte; r: word;
> begin
> s:=c and $f;
> r:=word(w shr s);
> r:=r or word(w shl (16-s)); // c may be over 16 and should be processed correctly
> wror:=r;
> end;
> function lror(l: longword; c: byte): longword; inline;
> var s: byte; r: longword;
> begin
> s:=c and $1f;
> r:=longword(l shr s);
> r:=r or longword(l shl (32-s)); // c may be over 32 and should be processed correctly
> lror:=r;
> end;
> {$ENDIF}
>
>
> Comments:
> I. style/consistency
> I didn't use all needed {$if}s: current code should word with range checks on both on i386 and not.
> {$Asmmode} was not used either.
> First symbol denotes type: while shl/shr emit longword, cyclic shifts shouldn't
> Endianness is not supported, because I don't understand, why it should be.
> II. performance
> "Result" is not supported in the inline mode.
> I don't know how to use "ret" to achieve the same goal with fewer commands.
>
> Test:
> {$INLINE ON}
> program testb;
> uses commonthingies;
> var i: byte; b: byte; w: word; l: longword;
> begin
> write('Enter byte (dec):');readln(b);
> for i:=0 to 16 do
> writeln('Orig:',binstr(b,8),' Left:',binstr(brol(b,i),8),' Right:',binstr(bror(b,i),8));
> write('Enter word (dec):');readln(w);
> for i:=0 to 32 do
> writeln('Orig:',binstr(w,16),' Left:',binstr(wrol(w,i),16),' Right:',binstr(wror(w,i),16));
> write('Enter lw (dec) :');readln(l);
> for i:=0 to 64 do
> writeln('Orig:',binstr(l,32),' Left:',binstr(lrol(l,i),32),' Right:',binstr(lror(l,i),32));
> end.
> _______________________________________________
> fpc-pascal maillist - fpc-pascal at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
More information about the fpc-pascal
mailing list