News:

Let's find out together what makes a PIC Tick!

Main Menu

Signed Right Shifts

Started by top204, Aug 24, 2024, 09:30 AM

Previous topic - Next topic

top204

Just a heads up for the next free update of the Positron8 compiler.

I have added Signed Right Shifts for signed variables and expressions the same as is in Positron16. It took a while to work out how to implement them in assembler for all the variable types, and to create the code for them, but it is complete, and as optimised as I can get it for now. :-)

Because of the superb mnemonics on dsPIC33 and PIC24 devices, signed right shifts were fairly straightforward to implement, so they have been with the 16-bit compiler since day one, but the 8-bit device mnemonics do not make it as straightforward, so I kept putting it off when I first created signed variables in the 8-bit compiler. However, over the years it has gotten to me that they should be in there, so I set about it last week, and it took the full week to create the C++ functions for the different variable types on different device families with their different assembler mnemonics, and querks of some of them. However, I finally finished them and implemented them in the Positron8 compiler version 4.0.4.6.

So for a code such as:

Dim SWordin  As SWord = -32768
Dim SWordout As SWord

SWordOut = SWordin >> 2


SWordout will contain the value -8192, which is -32768 shifted twice to the right, and still retaining its 2s complement sign bits, if the value being shifted is negative, otherwise, it performs an unsigned shift right for positive values. The equivalent of a signed division of 4.

And the code:

Dim bShifts   As Byte
Dim SDwordout As SDword
Dim SDwordin  As SDword = %10000000000000000000000000000000

For bShifts = 0 To 31
    SDwordout = SDwordin >> bShifts
    HRSOutLn SDec10 SDwordin, " >> ", Dec2 bShifts, " = ", SDec10 SDwordout, " : ", Bin32 SDwordout
Next

Will display the text below on a serial terminal, so it shows the shift amount can also be a variable:

-2147483648 >> 00 = -2147483648 : 10000000000000000000000000000000
-2147483648 >> 01 = -1073741824 : 11000000000000000000000000000000
-2147483648 >> 02 = -0536870912 : 11100000000000000000000000000000
-2147483648 >> 03 = -0268435456 : 11110000000000000000000000000000
-2147483648 >> 04 = -0134217728 : 11111000000000000000000000000000
-2147483648 >> 05 = -0067108864 : 11111100000000000000000000000000
-2147483648 >> 06 = -0033554432 : 11111110000000000000000000000000
-2147483648 >> 07 = -0016777216 : 11111111000000000000000000000000
-2147483648 >> 08 = -0008388608 : 11111111100000000000000000000000
-2147483648 >> 09 = -0004194304 : 11111111110000000000000000000000
-2147483648 >> 10 = -0002097152 : 11111111111000000000000000000000
-2147483648 >> 11 = -0001048576 : 11111111111100000000000000000000
-2147483648 >> 12 = -0000524288 : 11111111111110000000000000000000
-2147483648 >> 13 = -0000262144 : 11111111111111000000000000000000
-2147483648 >> 14 = -0000131072 : 11111111111111100000000000000000
-2147483648 >> 15 = -0000065536 : 11111111111111110000000000000000
-2147483648 >> 16 = -0000032768 : 11111111111111111000000000000000
-2147483648 >> 17 = -0000016384 : 11111111111111111100000000000000
-2147483648 >> 18 = -0000008192 : 11111111111111111110000000000000
-2147483648 >> 19 = -0000004096 : 11111111111111111111000000000000
-2147483648 >> 20 = -0000002048 : 11111111111111111111100000000000
-2147483648 >> 21 = -0000001024 : 11111111111111111111110000000000
-2147483648 >> 22 = -0000000512 : 11111111111111111111111000000000
-2147483648 >> 23 = -0000000256 : 11111111111111111111111100000000
-2147483648 >> 24 = -0000000128 : 11111111111111111111111110000000
-2147483648 >> 25 = -0000000064 : 11111111111111111111111111000000
-2147483648 >> 26 = -0000000032 : 11111111111111111111111111100000
-2147483648 >> 27 = -0000000016 : 11111111111111111111111111110000
-2147483648 >> 28 = -0000000008 : 11111111111111111111111111111000
-2147483648 >> 29 = -0000000004 : 11111111111111111111111111111100
-2147483648 >> 30 = -0000000002 : 11111111111111111111111111111110
-2147483648 >> 31 = -0000000001 : 11111111111111111111111111111111


The shifts work with all signed integer variable types, but not Floats because they operate very differently, and a right shift works with the shift amount as a constant, variable, or expression, just as it does with an unsigned right shift.

Just to be on the safe side, I have also added a Declare to disable Signed Right Shifts, just in case some users are using signed variable types and the original unsigned Right Shifts on them, and make the compiler backward compatible as much as possible.

The compiler's manual has been updated with the Signed Right Shift information, and the Declare to enable/disable it (Declare Signed_Right_Shifts = On/Off), and I will be uploading the update ASAP. However, please remember, the Signed Right Shift implementation is still in Beta, until you have checked it out more thoroughly than I can on my own.


Frizie

#1
Les, I pressume that Declare Signed_Right_Shifts = Off is the default setting?
Ohm sweet Ohm | www.picbasic.nl

top204

#2
The Signed Right Shifts will be enabled by default in version 4.0.4.6 onwards, because it only shifts the sign bits with signed variables and signed expressions, so a present right shift will not give a correct result, because it is unsigned, and will knock off the sign of variable values.

If a user is experiencing any difficulties with an expression that has a right shift in it, which will be a rarity in itself, they can add the declare to the program. However, I have noticed that most programs I have seen, do not use signed variables.