Files
wasmtime/cranelift/filetests/filetests/runtests/i128-bitops.clif
Ulrich Weigand b17b1eb25d [s390x, abi_impl] Add i128 support (#4598)
This adds full i128 support to the s390x target, including new filetests
and enabling the existing i128 runtest on s390x.

The ABI requires that i128 is passed and returned via implicit pointer,
but the front end still generates direct i128 types in call.  This means
we have to implement ABI support to implicitly convert i128 types to
pointers when passing arguments.

To do so, we add a new variant ABIArg::ImplicitArg.  This acts like
StructArg, except that the value type is the actual target type,
not a pointer type.  The required conversions have to be inserted
in the prologue and at function call sites.

Note that when dereferencing the implicit pointer in the prologue,
we may require a temp register: the pointer may be passed on the
stack so it needs to be loaded first, but the value register may
be in the wrong class for pointer values.  In this case, we use
the "stack limit" register, which should be available at this
point in the prologue.

For return values, we use a mechanism similar to the one used for
supporting multiple return values in the Wasmtime ABI.  The only
difference is that the hidden pointer to the return buffer must
be the *first*, not last, argument in this case.

(This implements the second half of issue #4565.)
2022-08-04 20:41:26 +00:00

56 lines
2.0 KiB
Plaintext

test run
set enable_llvm_abi_extensions=true
target aarch64
target s390x
target x86_64
function %bnot_i128(i128) -> i128 {
block0(v0: i128):
v1 = bnot v0
return v1
}
; run: %bnot_i128(0) == -1
; run: %bnot_i128(-1) == 0
; run: %bnot_i128(0xFFFFFFFF_FFFFFFFF_00000000_00000000) == 0x00000000_00000000_FFFFFFFF_FFFFFFFF
; run: %bnot_i128(0x3F001111_3F001111_21350000_21350000) == 0xC0FFEEEE_C0FFEEEE_DECAFFFF_DECAFFFF
function %band_i128(i128, i128) -> i128 {
block0(v0: i128, v1: i128):
v2 = band v0, v1
return v2
}
; run: %band_i128(0, 0) == 0
; run: %band_i128(-1, 0) == 0
; run: %band_i128(-1, -1) == -1
; run: %band_i128(-1, 0x00000000_00000000_FFFFFFFF_FFFFFFFF) == 0x00000000_00000000_FFFFFFFF_FFFFFFFF
; run: %band_i128(0xFEDCBA98_76543210_01234567_89ABCDEF, 0x01234567_89ABCDEF_FEDCBA98_76543210) == 0
; run: %band_i128(0xFEEEFFFF_FEEEFFFF_F1FFFEFE_F1FFFEFE, 0xDFDBFFFF_DFDBFFFF_CEFFEFEF_CEFFEFEF) == 0xDECAFFFF_DECAFFFF_C0FFEEEE_C0FFEEEE
function %bor_i128(i128, i128) -> i128 {
block0(v0: i128, v1: i128):
v2 = bor v0, v1
return v2
}
; run: %bor_i128(0, 0) == 0
; run: %bor_i128(-1, 0) == -1
; run: %bor_i128(-1, -1) == -1
; run: %bor_i128(0, 0x00000000_00000000_FFFFFFFF_FFFFFFFF) == 0x00000000_00000000_FFFFFFFF_FFFFFFFF
; run: %bor_i128(0xFEDCBA98_76543210_01234567_89ABCDEF, 0x01234567_89ABCDEF_FEDCBA98_76543210) == -1
; run: %bor_i128(0x8A8AAAAA_8A8AAAAA_80AAAAAA_80AAAAAA, 0x54405555_54405555_40554444_40554444) == 0xDECAFFFF_DECAFFFF_C0FFEEEE_C0FFEEEE
function %bxor_i128(i128, i128) -> i128 {
block0(v0: i128, v1: i128):
v2 = bxor v0, v1
return v2
}
; run: %bxor_i128(0, 0) == 0
; run: %bxor_i128(-1, 0) == -1
; run: %bxor_i128(-1, -1) == 0
; run: %bxor_i128(-1, 0xFFFFFFFF_FFFFFFFF_00000000_00000000) == 0x00000000_00000000_FFFFFFFF_FFFFFFFF
; run: %bxor_i128(0xFEDCBA98_76543210_01234567_89ABCDEF, 0x01234567_89ABCDEF_FEDCBA98_76543210) == -1
; run: %bxor_i128(0x9440A07D_9440A07D_8FA50A64_8FA50A64, 0x4A8A5F82_4A8A5F82_4F5AE48A_4F5AE48A) == 0xDECAFFFF_DECAFFFF_C0FFEEEE_C0FFEEEE