diff --git a/src/compiler/backend/s390/code-generator-s390.cc b/src/compiler/backend/s390/code-generator-s390.cc index f7101fb15f..6f318f1fbf 100644 --- a/src/compiler/backend/s390/code-generator-s390.cc +++ b/src/compiler/backend/s390/code-generator-s390.cc @@ -4186,8 +4186,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kS390_I32x4BitMask: { +#ifdef V8_TARGET_BIG_ENDIAN __ lgfi(kScratchReg, Operand(0x204060)); - __ aih(kScratchReg, Operand(0x80808080)); // Zeroing the high bits + __ iihf(kScratchReg, Operand(0x80808080)); // Zeroing the high bits. +#else + __ lgfi(kScratchReg, Operand(0x80808080)); + __ iihf(kScratchReg, Operand(0x60402000)); +#endif __ vlvg(kScratchDoubleReg, kScratchReg, MemOperand(r0, 1), Condition(3)); __ vbperm(kScratchDoubleReg, i.InputSimd128Register(0), kScratchDoubleReg, Condition(0), Condition(0), Condition(0)); @@ -4196,8 +4201,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kS390_I16x8BitMask: { +#ifdef V8_TARGET_BIG_ENDIAN __ lgfi(kScratchReg, Operand(0x40506070)); - __ aih(kScratchReg, Operand(0x102030)); + __ iihf(kScratchReg, Operand(0x102030)); +#else + __ lgfi(kScratchReg, Operand(0x30201000)); + __ iihf(kScratchReg, Operand(0x70605040)); +#endif __ vlvg(kScratchDoubleReg, kScratchReg, MemOperand(r0, 1), Condition(3)); __ vbperm(kScratchDoubleReg, i.InputSimd128Register(0), kScratchDoubleReg, Condition(0), Condition(0), Condition(0)); @@ -4206,10 +4216,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kS390_I8x16BitMask: { +#ifdef V8_TARGET_BIG_ENDIAN __ lgfi(r0, Operand(0x60687078)); - __ aih(r0, Operand(0x40485058)); + __ iihf(r0, Operand(0x40485058)); __ lgfi(ip, Operand(0x20283038)); - __ aih(ip, Operand(0x81018)); + __ iihf(ip, Operand(0x81018)); +#else + __ lgfi(ip, Operand(0x58504840)); + __ iihf(ip, Operand(0x78706860)); + __ lgfi(r0, Operand(0x18100800)); + __ iihf(r0, Operand(0x38302820)); +#endif __ vlvgp(kScratchDoubleReg, ip, r0); __ vbperm(kScratchDoubleReg, i.InputSimd128Register(0), kScratchDoubleReg, Condition(0), Condition(0), Condition(0)); diff --git a/src/execution/s390/simulator-s390.cc b/src/execution/s390/simulator-s390.cc index f41288f6a9..0f74168ffe 100644 --- a/src/execution/s390/simulator-s390.cc +++ b/src/execution/s390/simulator-s390.cc @@ -785,9 +785,10 @@ void Simulator::EvalTableInit() { V(vlc, VLC, 0xE7DE) /* type = VRR_A VECTOR LOAD COMPLEMENT */ \ V(vsel, VSEL, 0xE78D) /* type = VRR_E VECTOR SELECT */ \ V(vperm, VPERM, 0xE78C) /* type = VRR_E VECTOR PERMUTE */ \ - V(vtm, VTM, 0xE7D8) /* type = VRR_A VECTOR TEST UNDER MASK */ \ - V(vesl, VESL, 0xE730) /* type = VRS_A VECTOR ELEMENT SHIFT LEFT */ \ - V(veslv, VESLV, 0xE770) /* type = VRR_C VECTOR ELEMENT SHIFT LEFT */ \ + V(vbperm, VBPERM, 0xE785) /* type = VRR_C VECTOR BIT PERMUTE */ \ + V(vtm, VTM, 0xE7D8) /* type = VRR_A VECTOR TEST UNDER MASK */ \ + V(vesl, VESL, 0xE730) /* type = VRS_A VECTOR ELEMENT SHIFT LEFT */ \ + V(veslv, VESLV, 0xE770) /* type = VRR_C VECTOR ELEMENT SHIFT LEFT */ \ V(vesrl, VESRL, \ 0xE738) /* type = VRS_A VECTOR ELEMENT SHIFT RIGHT LOGICAL */ \ V(vesrlv, VESRLV, \ @@ -3702,6 +3703,34 @@ EVALUATE(VPERM) { return length; } +EVALUATE(VBPERM) { + DCHECK_OPCODE(VBPERM); + DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4); + USE(m4); + USE(m5); + USE(m6); + uint16_t result_bits = 0; + for (int i = 0; i < kSimd128Size; i++) { + result_bits <<= 1; + uint8_t selected_bit_index = get_simd_register_by_lane(r3, i); + unsigned __int128 src_bits = + *(reinterpret_cast<__int128*>(get_simd_register(r2).int8)); + if (selected_bit_index < (kSimd128Size * kBitsPerByte)) { + unsigned __int128 bit_value = + (src_bits << selected_bit_index) >> (kSimd128Size * kBitsPerByte - 1); + result_bits |= bit_value; + } + } + set_simd_register_by_lane(r1, 0, 0); + set_simd_register_by_lane(r1, 1, 0); + // Write back in bytes to avoid endianness problems. + set_simd_register_by_lane(r1, 6, + static_cast(result_bits >> 8)); + set_simd_register_by_lane( + r1, 7, static_cast((result_bits << 8) >> 8)); + return length; +} + EVALUATE(VSEL) { DCHECK_OPCODE(VSEL); DECODE_VRR_E_INSTRUCTION(r1, r2, r3, r4, m6, m5);