fix r12
The 3 bits that represent rsp are used as a signaling mechanism to
choose between compact base + disp encoding and full base + disp +
scale*index encoding, one byte longer. If a base is encoded as rsp in
the MOD R/M byte, an SIB byte follows.
r12 shares its 3 bottom bits with rsp, so we need to treat it like rsp
when deciding whether or not we need an SIB byte. (As usual registers
r8-15's distinguishing upper bit is carried by a REX/VEX prefix.)
rsp is also treated as a special signal in the index field of the SIB
byte, meaning essentially scale=0, and as a result it's not possible to
use rsp as an index. It _is_ possible to use r12 as an index, with a
test added here. This worked without any code change. It seems the
index=rsp -> scale=0 signal is triggered by all four bits of the index
registger, including the X upper bit from REX/VEX.
I have found these charts useful:
https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing_2
Looking at those charts I noticed that rbp/r13 are also special cases,
so I'm eyeing them warily and will avoid using them for now.
Change-Id: Id78f826a39c060b03000eae7c50c642ef44d57db
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/306237
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/tests/SkVMTest.cpp b/tests/SkVMTest.cpp
index d48b632..581f248 100644
--- a/tests/SkVMTest.cpp
+++ b/tests/SkVMTest.cpp
@@ -1113,7 +1113,10 @@
a.add(A::Mem{A::rsi}, 7); // addq $7, (%rsi)
a.add(A::Mem{A::rsi, 12}, 7); // addq $7, 12(%rsi)
a.add(A::Mem{A::rsp, 12}, 7); // addq $7, 12(%rsp)
+ a.add(A::Mem{A::r12, 12}, 7); // addq $7, 12(%r12)
a.add(A::Mem{A::rsp, 12, A::rax, A::FOUR}, 7); // addq $7, 12(%rsp,%rax,4)
+ a.add(A::Mem{A::r12, 12, A::rax, A::FOUR}, 7); // addq $7, 12(%r12,%rax,4)
+ a.add(A::Mem{A::rax, 12, A::r12, A::FOUR}, 7); // addq $7, 12(%rax,%r12,4)
a.add(A::Mem{A::r11, 12, A::r8 , A::TWO }, 7); // addq $7, 12(%r11,%r8,2)
a.add(A::Mem{A::r11, 12, A::rax} , 7); // addq $7, 12(%r11,%rax)
a.add(A::Mem{A::rax, 12, A::r11} , 7); // addq $7, 12(%rax,%r11)
@@ -1142,7 +1145,10 @@
0x48,0x83,0x06,0x07,
0x48,0x83,0x46,0x0c,0x07,
0x48,0x83,0x44,0x24,0x0c,0x07,
+ 0x49,0x83,0x44,0x24,0x0c,0x07,
0x48,0x83,0x44,0x84,0x0c,0x07,
+ 0x49,0x83,0x44,0x84,0x0c,0x07,
+ 0x4a,0x83,0x44,0xa0,0x0c,0x07,
0x4b,0x83,0x44,0x43,0x0c,0x07,
0x49,0x83,0x44,0x03,0x0c,0x07,
0x4a,0x83,0x44,0x18,0x0c,0x07,