What should the right notation be for the rotate (...
# thinking-together
k
What should the right notation be for the rotate (circular shift) operation? This seems like an important question since the operation is common in cryptography, and since the ARM instruction set goes to great lengths to allow any instruction to perform it. But apparently there's never been a good notation for it: https://stackoverflow.com/questions/32785998/symbol-for-bitwise-circular-shifts Desirable properties: * Stop thinking in terms of shift. Every rotation left can also be viewed as a rotation right. It feels most natural to think of rotate(X, n) to mean "X rotated to start at bit n." * No distracting ambiguous usage anywhere. Luckily we've already discarded '<<<' above.
<>
has distracting connotations of inequality. Maybe
><
? * Ideally just ascii characters. Though I suppose we could use one of the circular unicode arrows at a pinch.
a
Maybe
>@>
and
<@<
, playing on how @ looks vaguely circular. Actually those would be a huge pain to type, putting the @ on one end or another would be less aggressively unergonomic.
k
Yeah. I've been thinking of
>|<
which is also quite terrible on the fingers.
a
Also looks even more like a face, or a dragonfly. That could be a benefit or drawback depending on your perspective. ;)
k
The horizontal symmetry is indeed an irksome distraction.
Maybe
>^<
? Still a dragonfly or butterfly.
>-<
is one shift less. That seems worth the horizontal symmetry.
a
rotate_right
I understand why you propose a symmetrical operator (because you can rotate left via rotate right). But I still find the symmetrical operators confusing—that's still rotate right, but the operator does not show this
e
How about >>< and ><<, they describe in what direction each bit goes if you imagine a 3-bit integer.
👍 2
a
My recommendation is to go with full name and is what Rust uses. Rust has many intrinsics—functions that have special meaning for the compiler. Many operations that have special support in some processors are exposed as intrinsics. I very much like this approach as it allows you to use processor support when you need it, and you don't have to remember special syntax https://doc.rust-lang.org/std/intrinsics/index.html
âž• 1
k
@Alexey I was careful to ask for a notation. It's not really possible to make a general recommendation like this that works in all contexts. Imagine designing https://en.wikipedia.org/wiki/Salsa20 with pen and paper. I think having to write out
rotate_left
each time would hinder thought (https://dl.acm.org/doi/pdf/10.1145/358896.358899) In this case the problem I'm working on is coming up with a reasonable representation of the ARM ISA. ARM binary operators all support one immediate operand that must fit in 12 bits. However the 12 bits are used in a strange way, starting with 8 bits and then using the remaining 4 to determine how to rotate it. The recommended "universal assembly language" for ARM is to just provide constants and let the toolchain give you errors like:
Copy code
A1510E:Immediate 0x<imm> cannot be represented by 0-255 and a rotation
(https://developer.arm.com/documentation/100074/0612/assembler-errors-and-warnings/list-of-the-armasm-error-and-warning-messages) This seems pretty lousy. I'd prefer something that's more "correct by construction", that's not one of these:
Copy code
ADD Rd, Rn, 0xff, 4
ADD Rd, Rn, rotate_left(0xff, 4)
(I'm focusing on immediates just to simplify exposition. Making the second operand register-based opens up a larger can of worms.) Tl;dr - There is nothing "reduced" about this RISC intruction set.
d
You want a concise notation for a function that is naturally called
rotate(X,n)
. Suggestions: • n`⌽`X -- the APL rotate operator. APL was originally a mathematical notation, and was only later turned into a programming language. • n
<|>
X -- an ASCII approximation of the above. • n
rot
X -- yes, this is a notation, just as
sin x
is mathematical notation for the sine function.
âž• 1
r
How about
n -o X
or
n o- X
. Think of that as a wheel with a tail. Or possibly
n o! X
or
n !o X
.
e
those salsa diagrams look adorable 🙂
perhaps a more general solution would try to express subscript of any operator, say with some sort of underscore. Then you could subscript any operator.
<<<_3
is the obvious thought
I know you ruled
<<<
out before but since it seems like it used in all those famous papers, perhaps worth keeping. It is also easy to write and subscript with a pencil
k
Indeed. When I wrote OP I'd heard of the use of
<<<
for this purpose, but also that it used to have a
rot
on top of it. Which suffers from the obvious drawbacks. To describe why
<<<
still doesn't work, I need to expand the context from immediates to also include registers. The ARM instruction set can be summarized lossily in the following gestalt lines:
Copy code
Rd <- Rn op Rm
Rd <- Rn op (imm8 <|> k)  # rotate until LSB is at bit k from the right; k must be even and in [0, 32)
Rd <- Rn op (Rm << imm5)
Rd <- Rn op (Rm >> imm5)  # ASR/signed
Rd <- Rn op (Rm >>> imm5)  # LSR/unsigned
Rd <- Rn op (Rm <|> k)  # rotate
Rd <- Rn op (Rm c>> 1)  # shift right and insert carry flag
(So far my favorite option is @Doug Moen's
<|>
. I've come to terms with its conflicting association with alternation in Haskell.)