wazevo(arm64): fixes VBitselect translation (#1718)
Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
@@ -320,18 +320,18 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) {
|
||||
m.lowerVecRRR(vecOpBic, x, y, instr.Return(), vecArrangement16B)
|
||||
case ssa.OpcodeVbitselect:
|
||||
c, x, y := instr.SelectData()
|
||||
ins := m.allocateInstr()
|
||||
rn := m.getOperand_NR(m.compiler.ValueDefinition(x), extModeNone)
|
||||
rm := m.getOperand_NR(m.compiler.ValueDefinition(y), extModeNone)
|
||||
creg := m.getOperand_NR(m.compiler.ValueDefinition(c), extModeNone)
|
||||
ins.asVecRRR(vecOpBsl, creg, rn, rm, vecArrangement16B)
|
||||
m.insert(ins)
|
||||
|
||||
// creg is overwritten by BSL, so we need to move it to the result register before the instruction
|
||||
// in case when it is used somewhere else.
|
||||
rd := m.compiler.VRegOf(instr.Return())
|
||||
mov := m.allocateInstr()
|
||||
mov.asFpuMov128(rd, creg.nr())
|
||||
|
||||
m.insert(mov)
|
||||
ins := m.allocateInstr()
|
||||
ins.asVecRRR(vecOpBsl, operandNR(rd), rn, rm, vecArrangement16B)
|
||||
m.insert(ins)
|
||||
case ssa.OpcodeVIadd:
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
|
||||
@@ -261,7 +261,6 @@ func TestE2E(t *testing.T) {
|
||||
{params: []uint64{uint64(wasm.MemoryPageSize) - 3, 0}, expErr: "out of bounds memory access"},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "memory_load_basic",
|
||||
m: testcases.MemoryLoadBasic.Module,
|
||||
@@ -379,6 +378,13 @@ func TestE2E(t *testing.T) {
|
||||
{params: []uint64{1, 200}, expResults: []uint64{1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "vector_bit_select",
|
||||
m: testcases.VecBitSelect.Module,
|
||||
calls: []callCase{
|
||||
{params: []uint64{1, 2, 3, 4, 5, 6}, expResults: []uint64{0x3, 0x2, 0x5, 0x6}},
|
||||
},
|
||||
},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
@@ -1512,6 +1512,26 @@ var (
|
||||
}}},
|
||||
},
|
||||
}
|
||||
|
||||
VecBitSelect = TestCase{
|
||||
Name: "vector_bit_select",
|
||||
Module: &wasm.Module{
|
||||
TypeSection: []wasm.FunctionType{{Params: []wasm.ValueType{v128, v128, v128}, Results: []wasm.ValueType{v128, v128}}},
|
||||
ExportSection: []wasm.Export{{Name: ExportedFunctionName, Type: wasm.ExternTypeFunc, Index: 0}},
|
||||
FunctionSection: []wasm.Index{0},
|
||||
CodeSection: []wasm.Code{{Body: []byte{
|
||||
// In arm64, the "C" of BSL instruction is overwritten by the result,
|
||||
// so this case can be used to ensure that it is still alive if 'c' is used somewhere else,
|
||||
// which in this case is as a return value.
|
||||
wasm.OpcodeLocalGet, 0,
|
||||
wasm.OpcodeLocalGet, 1,
|
||||
wasm.OpcodeLocalGet, 2,
|
||||
wasm.OpcodeVecPrefix, wasm.OpcodeVecV128Bitselect,
|
||||
wasm.OpcodeLocalGet, 2, // Returns the 'c' as-is.
|
||||
wasm.OpcodeEnd,
|
||||
}}},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type TestCase struct {
|
||||
@@ -1546,10 +1566,11 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
i32 = wasm.ValueTypeI32
|
||||
i64 = wasm.ValueTypeI64
|
||||
f32 = wasm.ValueTypeF32
|
||||
f64 = wasm.ValueTypeF64
|
||||
i32 = wasm.ValueTypeI32
|
||||
i64 = wasm.ValueTypeI64
|
||||
f32 = wasm.ValueTypeF32
|
||||
f64 = wasm.ValueTypeF64
|
||||
v128 = wasm.ValueTypeV128
|
||||
|
||||
blockSignature_vv = 0x40 // 0x40 is the v_v signature in 33-bit signed. See wasm.DecodeBlockType.
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user