Shift and rotate instructions
Opcode | P/U | Category | Description |
ASL |
user | ALU: shift-rotate | arithmetic shift left |
ASR |
user | ALU: shift-rotate | arithmetic shift right |
LSL |
user | ALU: shift-rotate | logical shift left |
LSR |
user | ALU: shift-rotate | logical shift right |
ROL |
user | ALU: shift-rotate | rotate left |
DSL
(double shift left) is a multiply instruction, not a shift and rotate instruction.
Dauug|36’s shift instructions have unconventional terminology.
Arithmetic shift means multiplication or division by a power of two, rounding towards negative infinity in the case of division. In traditional forums, arithmetic shift means that a signed number is being shifted. But my position is that it’s moot whether the number is unsigned or unsigned. What is important is whether the intent is to perform arithmetic, and if this is the intent, the result must be tested for overrange irrespective of signedness.
Logical shift means a shift in the absence of any intent to multiply or divide. Logical shifts are not tested for overflow, because the bits involved do not represent quantities.
The architecture does not need or have an ROR
instruction to rotate right, because ROL
does that just fine.
ASL
Arithmetic shift left
Syntax |
c = a asl cw |
Register | Signedness |
Left | unsigned or signed |
Right | ignored |
Destination | unsigned or signed |
4 opcodes total |
Flag | Set if and only if |
N |
a < 0 |
Z |
a = 0 |
T |
c cannot fit entire result |
R |
T is set or R is already set |
The 2-instruction PSL
(prepare to shift left) and ASL
(arithmetic shift left) sequence enables safe, range-checked power-of-two multiplication, despite its many signedness combinations and corner cases. ASL
multiplies left operand a
by a non-negative power of two, and writes the product’s 36 least significant bits to destination c
. If the full result does not fit in c
without loss of information, the T
and R
flags will be set. Otherwise, T
is cleared and R
does not change.
The PSL
macro is used to convert the desired exponent of two into control word cw
. This exponent is clamped to a maximum of 36, and then copied into all tribbles.
Note: PSL
, like all macros, is not yet implemented. Construct cw
another way.
ASR
Arithmetic shift right
Syntax |
c = a asr cw |
Register | Signedness |
Left | unsigned or signed |
Right | ignored |
Destination | unsigned or signed |
4 opcodes total |
Flag | Set if and only if |
N |
a < 0 |
Z |
a = 0 |
T |
c cannot fit entire result |
R |
T is set or R is already set |
The 2-instruction PSR
(prepare to shift right) and ASR
(arithmetic shift right) sequence enables safe, range-checked division by powers of two, despite its many signedness combinations and corner cases. ASR
divides left operand a
by a non-negative power of two with rounding towards negative infinity, and writes the quotient’s 36 least significant bits (the 36 bits left of the radix mark, that is, the integer part of the quotient) to destination c
. If the rounded quotient does not fit in c
without loss of information, the T
and R
flags will be set, otherwise T
is cleared and R
does not change.
Note that because of the rounding towards negative infinity, ASR
is not (for most purposes) a stand-alone means for dividing by powers of two numbers that are or may be negative.
The PSR
macro is used to convert the desired exponent of two into control word cw
. If the exponent is 36 or more, it is clamped to 36. If the exponent is zero, it is left as zero. Otherwise, the exponent is subtracted from 36 in order to represent it from the internal hardware perspective of a left rotation. After this clamping, leaving as zero, or subtracting, the exponent is copied to all tribbles.
Note: PSR
, like all macros, is not yet implemented. Construct cw
another way.
LSL
Logical shift left
Syntax |
c = a lsl cw |
Register | Signedness |
All | ignored |
1 opcode only |
Flag | Set if and only if |
N |
bit 35 of the result is set |
Z |
all result bits are zero |
T |
flag does not change |
R |
flag does not change |
LSL
(logical shift left) shifts the bits of register a
left. Bits shifted out are discarded, and bits shifted in are zeros. The number of positions to shift may not be negative, and must be copied into every tribble of control word cw
.
The PSL
macro can convert any unsigned value into a suitable control word. N
and Z
are set as if the destination is a signed register. T
and R
are not changed by LSL
or any preceding PSL
.
Note: PSL
, like all macros, is not yet implemented. Construct cw
another way.
LSR
Logical shift right
Syntax |
c = a lsr cw |
Register | Signedness |
All | ignored |
1 opcode only |
Flag | Set if and only if |
N |
bit 35 of the result is set |
Z |
all result bits are zero |
T |
flag does not change |
R |
flag does not change |
LSR
(logical shift right) shifts the bits of register a
right. Bits shifted out are discarded, and bits shifted in are zeros. The number of positions to shift may not be negative, is specified from the perspective of a left rotation, and must be copied into every tribble of control word cw
.
The PSR
macro can convert any unsigned value into a suitable control word. N
and Z
are set as if the destination is a signed register. T
and R
are not changed by LSR
or any preceding PSR
.
Note: PSR
, like all macros, is not yet implemented. Construct cw
another way.
ROL
Rotate left
Syntax |
c = a rol cw |
Register | Signedness |
All | ignored |
1 opcode only |
Flag | Set if and only if |
N |
bit 35 of the result is set |
Z |
all result bits are zero |
T |
flag does not change |
R |
flag does not change |
ROL
(rotate left) rotates the bits of a
. The number of positions to rotate must be specified from the perspective of a left rotation, may not be negative, and must be copied into every tribble of control word cw. The PRL
and PRR
macros offer a range-checked mechanism to set up the control word for left and right rotations. N
and Z
are set as if the destination is a signed register. ROL
will not change T
or R
, although a preceding PRL
and PRR
may.
Unlike left and right shifts, left and right rotations are limited to 63 positions due to their repetition modulo 36. Evaluating a shift of more than 63 positions modulo 36 is computationally expensive and is not directly supported by Dauug|36. This is why PRL
and PRR
have to include a range check.
Again, there is no ROR
instruction to rotate right. ROL
is the instruction to rotate right or left. Remember also that the amount to rotate by is never negative.
Note: PRL
and PRR
, like all macros, is not yet implemented. Construct cw
another way.