Page 1 of 1

Shifts and masks

Posted: Mon Jan 03, 2011 6:01 am
by Helpdesk
How is the best way to do the Pascal equivalent of:

Code: Select all

R := ( R shr 6) and $3FF;

Re: Shifts and masks

Posted: Mon Jan 03, 2011 6:12 am
by cfbsoftware
There are several possible ways. The style most often seen in Oberon code is:

Code: Select all

R := LSR(R, 6) MOD 0400H;

The code generated is:

Code: Select all

E1B0B32BH   MOV  S  R11,R11 LSR 6    
E1A0BB0BH   MOV     R11,R11 LSL 22    
E1B0BB2BH   MOV  S  R11,R11 LSR 22
An alternative is:

Code: Select all

R := LSR(LSL(value, 16));
Initially this might appear less readable. However, it does makes it clearer that you are completely ignoring the top 16 bits. The code generated uses one less instruction than the previous example:

Code: Select all

E1B0B80BH   MOV  S  R11,R11 LSL 16    
E1B0BB2BH   MOV  S  R11,R11 LSR 22
Choose the one that you think most clearly illustrates the problem being solved.

Re: Shifts and masks

Posted: Sat Mar 26, 2011 8:25 pm
by pompey
I'm sure its obvious to everyone else - but just in case:

I think

Code: Select all

R := LSR(LSL(value, 16));
Should be

Code: Select all

R := LSR(LSL(value, 16), 22);

Re: Shifts and masks

Posted: Sat Mar 26, 2011 11:07 pm
by cfbsoftware
Yes - of course. Sorry about the blooper!

With the benefit of hindsight, it might be clearer to write it as two separate statements:

Code: Select all

R := LSL(value, 16);
R := LSR(R, 22);
If this form is used in a leaf procedure you do not need to worry about efficiency as it generates code which is identical to the single-line version.