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)
commit9d7739c8666eea50232cb4d0e92be8090674ceb4
tree35cc7e323f6c63361d9431a7b36e98cf221e90e0
parent59a2c7dab1153e976afff3a3d358b4a1d6aa1e23
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 dotnet/coreclr#63

After
smull   x8, x8, x9   --> x8 = w8 * w9
lsr     x10, x8, dotnet/coreclr#32 --> shift the upper bit of x8 to get sign bit
cmp     w10, w8, ASR dotnet/coreclr#31 --> check sign bit

Commit migrated from https://github.com/dotnet/coreclr/commit/445a810039d0801d099fd5ba543876456b248c47
src/coreclr/src/jit/emitarm64.cpp
src/coreclr/src/jit/lowerarm64.cpp
src/coreclr/tests/arm64/Tests.lst