ARM64: Fix for Multiplication with Overflow Check
authorKyungwoo Lee <kyulee@microsoft.com>
Tue, 1 Mar 2016 17:33:13 +0000 (09:33 -0800)
committerKyungwoo Lee <kyulee@microsoft.com>
Wed, 2 Mar 2016 18:13:22 +0000 (10:13 -0800)
commit445a810039d0801d099fd5ba543876456b248c47
tree2294b740b801df48e6b16b6f1f9e8120a3fadc89
parent9c8484734621f36d2e4113644e56109cb76192e3
ARM64: Fix for Multiplication with Overflow Check

For 4 byte integer multiplication, JIT emits a bad-code which is valid
only for 8 byte (i8) multiplication.
For the fix, I use ```smull```(signed)/```umull```(unsigned) instructions
that contain 8 byte results from 4 byte by 4 byte multiplication.
So only one multiplication is needed instead of two for this case.
By simply shifting the results, we could get the upper results that is
used to detect overflow.
Similar transform is made for the unsigned case.
Lower is also changed to reserve a register for overflow check.

Before
smulh   w10, w8, w9  --> Incorrect use: smulh is for obtaining the upper
bits [127:64] of x8 * x9
mul     w8, w8, w9
cmp     x10, x8, ASR #63

After
smull   x8, x8, x9   --> x8 = w8 * w9
lsr     x10, x8, #32 --> shift the upper bit of x8 to get sign bit
cmp     w10, w8, ASR #31 --> check sign bit
src/jit/emitarm64.cpp
src/jit/lowerarm64.cpp
tests/arm64/Tests.lst