s390x: Support both big- and little-endian vector lane order (#4682)
This implements the s390x back-end portion of the solution for https://github.com/bytecodealliance/wasmtime/issues/4566 We now support both big- and little-endian vector lane order in code generation. The order used for a function is determined by the function's ABI: if it uses a Wasmtime ABI, it will use little-endian lane order, and big-endian lane order otherwise. (This ensures that all raw_bitcast instructions generated by both wasmtime and other cranelift frontends can always be implemented as a no-op.) Lane order affects the implementation of a number of operations: - Vector immediates - Vector memory load / store (in big- and little-endian variants) - Operations explicitly using lane numbers (insertlane, extractlane, shuffle, swizzle) - Operations implicitly using lane numbers (iadd_pairwise, narrow/widen, promote/demote, fcvt_low, vhigh_bits) In addition, when calling a function using a different lane order, we need to lane-swap all vector values passed or returned in registers. A small number of changes to common code were also needed: - Ensure we always select a Wasmtime calling convention on s390x in crates/cranelift (func_signature). - Fix vector immediates for filetests/runtests. In PR #4427, I attempted to fix this by byte-swapping the V128 value, but with the new scheme, we'd instead need to perform a per-lane byte swap. Since we do not know the actual type in write_to_slice and read_from_slice, this isn't easily possible. Revert this part of PR #4427 again, and instead just mark the memory buffer as little-endian when emitting the trampoline; the back-end will then emit correct code to load the constant. - Change a runtest in simd-bitselect-to-vselect.clif to no longer make little-endian lane order assumptions. - Remove runtests in simd-swizzle.clif that make little-endian lane order assumptions by relying on implicit type conversion when using a non-i16x8 swizzle result type (this feature should probably be removed anyway). Tested with both wasmtime and cg_clif.
This commit is contained in:
@@ -20,7 +20,8 @@ block0(v0: i64x2, v1: i64x2, v2: i32x4):
|
||||
v4 = bitselect v3, v0, v1
|
||||
return v4
|
||||
}
|
||||
; run: %mask_casted([0 0], [0xFFFFFF 0xFFFF4F], [0xFFF1 0 0xF 0]) == [0xFF000E 0xFFFF40]
|
||||
; N.B. The mask is chosen such that the result is correct with either LE or BE lane order.
|
||||
; run: %mask_casted([0 0], [0xFFFFFF 0xFFFF4F], [0xFFF1 0xFFF1 0xF 0xF]) == [0xFF000E 0xFFFF40]
|
||||
|
||||
function %good_const_mask(i32x4, i32x4) -> i32x4 {
|
||||
block0(v0: i32x4, v1: i32x4):
|
||||
|
||||
@@ -12,23 +12,3 @@ block0(v0: i8x16, v1: i8x16):
|
||||
}
|
||||
; run: %swizzle_i8x16([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == [1 10 16 2 7 14 8 12 11 9 0 13 5 3 4 6]
|
||||
|
||||
function %swizzle_i16x8(i8x16, i8x16) -> i16x8 {
|
||||
block0(v0: i8x16, v1: i8x16):
|
||||
v2 = swizzle.i16x8 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %swizzle_i16x8([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == 0x060403050d00090b0c080e0702100a01
|
||||
|
||||
function %swizzle_i32x4(i8x16, i8x16) -> i32x4 {
|
||||
block0(v0: i8x16, v1: i8x16):
|
||||
v2 = swizzle.i32x4 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %swizzle_i32x4([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == 0x060403050d00090b0c080e0702100a01
|
||||
|
||||
function %swizzle_i64x2(i8x16, i8x16) -> i64x2 {
|
||||
block0(v0: i8x16, v1: i8x16):
|
||||
v2 = swizzle.i64x2 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %swizzle_i64x2([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == 0x060403050d00090b0c080e0702100a01
|
||||
|
||||
Reference in New Issue
Block a user