mirror of
https://github.com/wazero/wazero
synced 2026-06-21 14:12:37 +00:00
wazevo: passes simd_bitwise spec tests (#1715)
Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This commit is contained in:
@@ -1502,6 +1502,16 @@ func (b vecOp) String() string {
|
||||
return "uaddlv"
|
||||
case vecOpBit:
|
||||
return "bit"
|
||||
case vecOpBic:
|
||||
return "bic"
|
||||
case vecOpBsl:
|
||||
return "bsl"
|
||||
case vecOpNot:
|
||||
return "not"
|
||||
case vecOpAnd:
|
||||
return "and"
|
||||
case vecOpOrr:
|
||||
return "orr"
|
||||
case vecOpEOR:
|
||||
return "eor"
|
||||
case vecOpAdd:
|
||||
@@ -1540,6 +1550,11 @@ const (
|
||||
vecOpCnt vecOp = iota
|
||||
vecOpUaddlv
|
||||
vecOpBit
|
||||
vecOpBic
|
||||
vecOpBsl
|
||||
vecOpNot
|
||||
vecOpAnd
|
||||
vecOpOrr
|
||||
vecOpEOR
|
||||
vecOpAdd
|
||||
vecOpSqadd
|
||||
@@ -1552,6 +1567,7 @@ const (
|
||||
vecOpUmin
|
||||
vecOpSmax
|
||||
vecOpUmax
|
||||
vecOpUmaxp
|
||||
vecOpUrhadd
|
||||
vecOpMul
|
||||
vecOpUmlal
|
||||
|
||||
@@ -348,6 +348,27 @@ func encodeVecRRR(op vecOp, rd, rn, rm uint32, arr vecArrangement) uint32 {
|
||||
case vecOpBit:
|
||||
_, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b00011, 0b10 /* always has size 0b10 */, 0b1, q)
|
||||
case vecOpBic:
|
||||
if arr > vecArrangement16B {
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
}
|
||||
_, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b00011, 0b01 /* always has size 0b01 */, 0b0, q)
|
||||
case vecOpBsl:
|
||||
if arr > vecArrangement16B {
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
}
|
||||
_, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b00011, 0b01 /* always has size 0b01 */, 0b1, q)
|
||||
case vecOpAnd:
|
||||
if arr > vecArrangement16B {
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
}
|
||||
_, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b00011, 0b00 /* always has size 0b00 */, 0b0, q)
|
||||
case vecOpOrr:
|
||||
_, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b00011, 0b10 /* always has size 0b10 */, 0b0, q)
|
||||
case vecOpEOR:
|
||||
size, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b00011, size, 0b1, q)
|
||||
@@ -417,6 +438,12 @@ func encodeVecRRR(op vecOp, rd, rn, rm uint32, arr vecArrangement) uint32 {
|
||||
}
|
||||
size, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b01100, size, 0b1, q)
|
||||
case vecOpUmaxp:
|
||||
if arr > vecArrangement4S {
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
}
|
||||
size, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeSame(rd, rn, rm, 0b10100, size, 0b1, q)
|
||||
case vecOpUrhadd:
|
||||
if arr > vecArrangement4S {
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
@@ -436,7 +463,7 @@ func encodeVecRRR(op vecOp, rd, rn, rm uint32, arr vecArrangement) uint32 {
|
||||
size, q := arrToSizeQEncoded(arr)
|
||||
return encodeAdvancedSIMDThreeDifferent(rd, rn, rm, 0b1000, size, 0b1, q)
|
||||
default:
|
||||
panic("TODO")
|
||||
panic("TODO: " + op.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1445,6 +1472,17 @@ func encodeAdvancedSIMDTwoMisc(op vecOp, rd, rn uint32, arr vecArrangement) uint
|
||||
default:
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
}
|
||||
case vecOpNot:
|
||||
u = 1
|
||||
opcode = 0b00101
|
||||
switch arr {
|
||||
case vecArrangement8B:
|
||||
q, size = 0b0, 0b00
|
||||
case vecArrangement16B:
|
||||
q, size = 0b1, 0b00
|
||||
default:
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
}
|
||||
case vecOpAbs:
|
||||
if arr == vecArrangement1D {
|
||||
panic("unsupported arrangement: " + arr.String())
|
||||
|
||||
@@ -878,6 +878,36 @@ func TestInstruction_encode(t *testing.T) {
|
||||
{want: "4138b06e", setup: func(i *instruction) {
|
||||
i.asVecLanes(vecOpUaddlv, operandNR(v1VReg), operandNR(v2VReg), vecArrangement4S)
|
||||
}},
|
||||
{want: "411c630e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpBic, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement8B)
|
||||
}},
|
||||
{want: "411c634e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpBic, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement16B)
|
||||
}},
|
||||
{want: "411c632e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpBsl, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement8B)
|
||||
}},
|
||||
{want: "411c636e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpBsl, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement16B)
|
||||
}},
|
||||
{want: "4158202e", setup: func(i *instruction) {
|
||||
i.asVecMisc(vecOpNot, operandNR(v1VReg), operandNR(v2VReg), vecArrangement8B)
|
||||
}},
|
||||
{want: "4158206e", setup: func(i *instruction) {
|
||||
i.asVecMisc(vecOpNot, operandNR(v1VReg), operandNR(v2VReg), vecArrangement16B)
|
||||
}},
|
||||
{want: "411c230e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpAnd, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement8B)
|
||||
}},
|
||||
{want: "411c234e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpAnd, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement16B)
|
||||
}},
|
||||
{want: "411ca30e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpOrr, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement8B)
|
||||
}},
|
||||
{want: "411ca34e", setup: func(i *instruction) {
|
||||
i.asVecRRR(vecOpOrr, operandNR(v1VReg), operandNR(v2VReg), operandNR(v3VReg), vecArrangement16B)
|
||||
}},
|
||||
{want: "4158200e", setup: func(i *instruction) { i.asVecMisc(vecOpCnt, operandNR(v1VReg), operandNR(v2VReg), vecArrangement8B) }},
|
||||
{want: "4158204e", setup: func(i *instruction) { i.asVecMisc(vecOpCnt, operandNR(v1VReg), operandNR(v2VReg), vecArrangement16B) }},
|
||||
{want: "41c0221e", setup: func(i *instruction) {
|
||||
|
||||
@@ -299,28 +299,83 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) {
|
||||
v := m.allocateInstr()
|
||||
v.asLoadFpuConst128(result, lo, hi)
|
||||
m.insert(v)
|
||||
case ssa.OpcodeVbnot:
|
||||
x := instr.Arg()
|
||||
ins := m.allocateInstr()
|
||||
rn := m.getOperand_NR(m.compiler.ValueDefinition(x), extModeNone)
|
||||
rd := operandNR(m.compiler.VRegOf(instr.Return()))
|
||||
ins.asVecMisc(vecOpNot, rd, rn, vecArrangement16B)
|
||||
m.insert(ins)
|
||||
case ssa.OpcodeVbxor:
|
||||
x, y := instr.Arg2()
|
||||
m.lowerVecRRR(vecOpEOR, x, y, instr.Return(), vecArrangement16B)
|
||||
case ssa.OpcodeVbor:
|
||||
x, y := instr.Arg2()
|
||||
m.lowerVecRRR(vecOpOrr, x, y, instr.Return(), vecArrangement16B)
|
||||
case ssa.OpcodeVband:
|
||||
x, y := instr.Arg2()
|
||||
m.lowerVecRRR(vecOpAnd, x, y, instr.Return(), vecArrangement16B)
|
||||
case ssa.OpcodeVbandnot:
|
||||
x, y := instr.Arg2()
|
||||
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)
|
||||
|
||||
rd := m.compiler.VRegOf(instr.Return())
|
||||
mov := m.allocateInstr()
|
||||
mov.asFpuMov128(rd, creg.nr())
|
||||
|
||||
m.insert(mov)
|
||||
case ssa.OpcodeVIadd:
|
||||
m.lowerVecRRR(vecOpAdd, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpAdd, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVSaddSat:
|
||||
m.lowerVecRRR(vecOpSqadd, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpSqadd, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVUaddSat:
|
||||
m.lowerVecRRR(vecOpUqadd, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpUqadd, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVIsub:
|
||||
m.lowerVecRRR(vecOpSub, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpSub, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVSsubSat:
|
||||
m.lowerVecRRR(vecOpSqsub, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpSqsub, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVUsubSat:
|
||||
m.lowerVecRRR(vecOpUqsub, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpUqsub, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVImin:
|
||||
m.lowerVecRRR(vecOpSmin, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpSmin, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVUmin:
|
||||
m.lowerVecRRR(vecOpUmin, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpUmin, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVImax:
|
||||
m.lowerVecRRR(vecOpSmax, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpSmax, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVUmax:
|
||||
m.lowerVecRRR(vecOpUmax, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpUmax, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVAvgRound:
|
||||
m.lowerVecRRR(vecOpUrhadd, instr)
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
m.lowerVecRRR(vecOpUrhadd, x, y, instr.Return(), arr)
|
||||
case ssa.OpcodeVImul:
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
@@ -350,13 +405,11 @@ func (m *machine) lowerVecMisc(op vecOp, instr *ssa.Instruction) {
|
||||
m.insert(ins)
|
||||
}
|
||||
|
||||
func (m *machine) lowerVecRRR(op vecOp, instr *ssa.Instruction) {
|
||||
x, y, lane := instr.Arg2WithLane()
|
||||
arr := ssaLaneToArrangement(lane)
|
||||
func (m *machine) lowerVecRRR(op vecOp, x, y, ret ssa.Value, arr vecArrangement) {
|
||||
ins := m.allocateInstr()
|
||||
rn := m.getOperand_NR(m.compiler.ValueDefinition(x), extModeNone)
|
||||
rm := m.getOperand_NR(m.compiler.ValueDefinition(y), extModeNone)
|
||||
rd := operandNR(m.compiler.VRegOf(instr.Return()))
|
||||
rd := operandNR(m.compiler.VRegOf(ret))
|
||||
ins.asVecRRR(op, rd, rn, rm, arr)
|
||||
m.insert(ins)
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ func TestSpectestV2(t *testing.T) {
|
||||
{"conversions"},
|
||||
{"if"},
|
||||
{"loop"},
|
||||
{"simd_bitwise"},
|
||||
{"simd_const"},
|
||||
{"simd_i8x16_arith"},
|
||||
{"simd_i8x16_arith2"},
|
||||
|
||||
@@ -1355,6 +1355,65 @@ func (c *Compiler) lowerCurrentOpcode() {
|
||||
state.pc += 7
|
||||
ret := builder.AllocateInstruction().AsVconst(lo, hi).Insert(builder).Return()
|
||||
state.push(ret)
|
||||
case wasm.OpcodeVecV128Load:
|
||||
_, offset := c.readMemArg()
|
||||
if state.unreachable {
|
||||
break
|
||||
}
|
||||
baseAddr := state.pop()
|
||||
addr := c.memOpSetup(baseAddr, uint64(offset), 16)
|
||||
load := builder.AllocateInstruction()
|
||||
load.AsLoad(addr, offset, ssa.TypeV128)
|
||||
builder.InsertInstruction(load)
|
||||
state.push(load.Return())
|
||||
case wasm.OpcodeVecV128Not:
|
||||
if state.unreachable {
|
||||
break
|
||||
}
|
||||
v1 := state.pop()
|
||||
ret := builder.AllocateInstruction().AsVbnot(v1).Insert(builder).Return()
|
||||
state.push(ret)
|
||||
case wasm.OpcodeVecV128And:
|
||||
if state.unreachable {
|
||||
break
|
||||
}
|
||||
v2 := state.pop()
|
||||
v1 := state.pop()
|
||||
ret := builder.AllocateInstruction().AsVband(v1, v2).Insert(builder).Return()
|
||||
state.push(ret)
|
||||
case wasm.OpcodeVecV128AndNot:
|
||||
if state.unreachable {
|
||||
break
|
||||
}
|
||||
v2 := state.pop()
|
||||
v1 := state.pop()
|
||||
ret := builder.AllocateInstruction().AsVbandnot(v1, v2).Insert(builder).Return()
|
||||
state.push(ret)
|
||||
case wasm.OpcodeVecV128Or:
|
||||
if state.unreachable {
|
||||
break
|
||||
}
|
||||
v2 := state.pop()
|
||||
v1 := state.pop()
|
||||
ret := builder.AllocateInstruction().AsVbor(v1, v2).Insert(builder).Return()
|
||||
state.push(ret)
|
||||
case wasm.OpcodeVecV128Xor:
|
||||
if state.unreachable {
|
||||
break
|
||||
}
|
||||
v2 := state.pop()
|
||||
v1 := state.pop()
|
||||
ret := builder.AllocateInstruction().AsVbxor(v1, v2).Insert(builder).Return()
|
||||
state.push(ret)
|
||||
case wasm.OpcodeVecV128Bitselect:
|
||||
if state.unreachable {
|
||||
break
|
||||
}
|
||||
c := state.pop()
|
||||
v2 := state.pop()
|
||||
v1 := state.pop()
|
||||
ret := builder.AllocateInstruction().AsVbitselect(c, v1, v2).Insert(builder).Return()
|
||||
state.push(ret)
|
||||
case wasm.OpcodeVecI8x16Abs, wasm.OpcodeVecI16x8Abs, wasm.OpcodeVecI32x4Abs, wasm.OpcodeVecI64x2Abs:
|
||||
if state.unreachable {
|
||||
break
|
||||
|
||||
@@ -290,6 +290,25 @@ const (
|
||||
// OpcodeVconst represents the 128bit vector const.
|
||||
OpcodeVconst
|
||||
|
||||
// OpcodeVbor computes binary or between two 128bit vectors: `v = bor x, y`.
|
||||
OpcodeVbor
|
||||
|
||||
// OpcodeVbxor computes binary xor between two 128bit vectors: `v = bxor x, y`.
|
||||
OpcodeVbxor
|
||||
|
||||
// OpcodeVband computes binary and between two 128bit vectors: `v = band x, y`.
|
||||
OpcodeVband
|
||||
|
||||
// OpcodeVbandnot computes binary and-not between two 128bit vectors: `v = bandnot x, y`.
|
||||
OpcodeVbandnot
|
||||
|
||||
// OpcodeVbnot negates a 128bit vector: `v = bnot x`.
|
||||
OpcodeVbnot
|
||||
|
||||
// OpcodeVbitselect uses the bits in the control mask c to select the corresponding bit from x when 1
|
||||
// and y when 0: `v = bitselect c, x, y`.
|
||||
OpcodeVbitselect
|
||||
|
||||
// OpcodeShuffle ...
|
||||
// `v = shuffle a, b, mask`.
|
||||
OpcodeShuffle
|
||||
@@ -851,6 +870,15 @@ var instructionSideEffects = [opcodeEnd]sideEffect{
|
||||
OpcodeFabs: sideEffectNone,
|
||||
OpcodeFcopysign: sideEffectNone,
|
||||
OpcodeVconst: sideEffectNone,
|
||||
OpcodeVbor: sideEffectNone,
|
||||
OpcodeVbxor: sideEffectNone,
|
||||
OpcodeVband: sideEffectNone,
|
||||
OpcodeVbandnot: sideEffectNone,
|
||||
OpcodeVbnot: sideEffectNone,
|
||||
OpcodeVbitselect: sideEffectTraps,
|
||||
OpcodeVanyTrue: sideEffectNone,
|
||||
OpcodeVallTrue: sideEffectNone,
|
||||
OpcodeVhighBits: sideEffectNone,
|
||||
OpcodeVIadd: sideEffectNone,
|
||||
OpcodeVSaddSat: sideEffectNone,
|
||||
OpcodeVUaddSat: sideEffectNone,
|
||||
@@ -879,48 +907,57 @@ func (i *Instruction) sideEffect() sideEffect {
|
||||
|
||||
// instructionReturnTypes provides the function to determine the return types of an instruction.
|
||||
var instructionReturnTypes = [opcodeEnd]returnTypesFn{
|
||||
OpcodeVIadd: returnTypesFnV128,
|
||||
OpcodeVSaddSat: returnTypesFnV128,
|
||||
OpcodeVUaddSat: returnTypesFnV128,
|
||||
OpcodeVIsub: returnTypesFnV128,
|
||||
OpcodeVSsubSat: returnTypesFnV128,
|
||||
OpcodeVUsubSat: returnTypesFnV128,
|
||||
OpcodeVImin: returnTypesFnV128,
|
||||
OpcodeVUmin: returnTypesFnV128,
|
||||
OpcodeVImax: returnTypesFnV128,
|
||||
OpcodeVUmax: returnTypesFnV128,
|
||||
OpcodeVImul: returnTypesFnV128,
|
||||
OpcodeVAvgRound: returnTypesFnV128,
|
||||
OpcodeVIabs: returnTypesFnV128,
|
||||
OpcodeVIneg: returnTypesFnV128,
|
||||
OpcodeVIpopcnt: returnTypesFnV128,
|
||||
OpcodeBand: returnTypesFnSingle,
|
||||
OpcodeFcopysign: returnTypesFnSingle,
|
||||
OpcodeBitcast: returnTypesFnSingle,
|
||||
OpcodeBor: returnTypesFnSingle,
|
||||
OpcodeBxor: returnTypesFnSingle,
|
||||
OpcodeRotl: returnTypesFnSingle,
|
||||
OpcodeRotr: returnTypesFnSingle,
|
||||
OpcodeIshl: returnTypesFnSingle,
|
||||
OpcodeSshr: returnTypesFnSingle,
|
||||
OpcodeSdiv: returnTypesFnSingle,
|
||||
OpcodeSrem: returnTypesFnSingle,
|
||||
OpcodeUdiv: returnTypesFnSingle,
|
||||
OpcodeUrem: returnTypesFnSingle,
|
||||
OpcodeUshr: returnTypesFnSingle,
|
||||
OpcodeJump: returnTypesFnNoReturns,
|
||||
OpcodeUndefined: returnTypesFnNoReturns,
|
||||
OpcodeIconst: returnTypesFnSingle,
|
||||
OpcodeSelect: returnTypesFnSingle,
|
||||
OpcodeSExtend: returnTypesFnSingle,
|
||||
OpcodeUExtend: returnTypesFnSingle,
|
||||
OpcodeIreduce: returnTypesFnSingle,
|
||||
OpcodeFabs: returnTypesFnSingle,
|
||||
OpcodeSqrt: returnTypesFnSingle,
|
||||
OpcodeCeil: returnTypesFnSingle,
|
||||
OpcodeFloor: returnTypesFnSingle,
|
||||
OpcodeTrunc: returnTypesFnSingle,
|
||||
OpcodeNearest: returnTypesFnSingle,
|
||||
OpcodeVbor: returnTypesFnV128,
|
||||
OpcodeVbxor: returnTypesFnV128,
|
||||
OpcodeVband: returnTypesFnV128,
|
||||
OpcodeVbnot: returnTypesFnV128,
|
||||
OpcodeVbandnot: returnTypesFnV128,
|
||||
OpcodeVbitselect: returnTypesFnV128,
|
||||
OpcodeVanyTrue: returnTypesFnV128,
|
||||
OpcodeVallTrue: returnTypesFnV128,
|
||||
OpcodeVhighBits: returnTypesFnV128,
|
||||
OpcodeVIadd: returnTypesFnV128,
|
||||
OpcodeVSaddSat: returnTypesFnV128,
|
||||
OpcodeVUaddSat: returnTypesFnV128,
|
||||
OpcodeVIsub: returnTypesFnV128,
|
||||
OpcodeVSsubSat: returnTypesFnV128,
|
||||
OpcodeVUsubSat: returnTypesFnV128,
|
||||
OpcodeVImin: returnTypesFnV128,
|
||||
OpcodeVUmin: returnTypesFnV128,
|
||||
OpcodeVImax: returnTypesFnV128,
|
||||
OpcodeVUmax: returnTypesFnV128,
|
||||
OpcodeVImul: returnTypesFnV128,
|
||||
OpcodeVAvgRound: returnTypesFnV128,
|
||||
OpcodeVIabs: returnTypesFnV128,
|
||||
OpcodeVIneg: returnTypesFnV128,
|
||||
OpcodeVIpopcnt: returnTypesFnV128,
|
||||
OpcodeBand: returnTypesFnSingle,
|
||||
OpcodeFcopysign: returnTypesFnSingle,
|
||||
OpcodeBitcast: returnTypesFnSingle,
|
||||
OpcodeBor: returnTypesFnSingle,
|
||||
OpcodeBxor: returnTypesFnSingle,
|
||||
OpcodeRotl: returnTypesFnSingle,
|
||||
OpcodeRotr: returnTypesFnSingle,
|
||||
OpcodeIshl: returnTypesFnSingle,
|
||||
OpcodeSshr: returnTypesFnSingle,
|
||||
OpcodeSdiv: returnTypesFnSingle,
|
||||
OpcodeSrem: returnTypesFnSingle,
|
||||
OpcodeUdiv: returnTypesFnSingle,
|
||||
OpcodeUrem: returnTypesFnSingle,
|
||||
OpcodeUshr: returnTypesFnSingle,
|
||||
OpcodeJump: returnTypesFnNoReturns,
|
||||
OpcodeUndefined: returnTypesFnNoReturns,
|
||||
OpcodeIconst: returnTypesFnSingle,
|
||||
OpcodeSelect: returnTypesFnSingle,
|
||||
OpcodeSExtend: returnTypesFnSingle,
|
||||
OpcodeUExtend: returnTypesFnSingle,
|
||||
OpcodeIreduce: returnTypesFnSingle,
|
||||
OpcodeFabs: returnTypesFnSingle,
|
||||
OpcodeSqrt: returnTypesFnSingle,
|
||||
OpcodeCeil: returnTypesFnSingle,
|
||||
OpcodeFloor: returnTypesFnSingle,
|
||||
OpcodeTrunc: returnTypesFnSingle,
|
||||
OpcodeNearest: returnTypesFnSingle,
|
||||
OpcodeCallIndirect: func(b *builder, instr *Instruction) (t1 Type, ts []Type) {
|
||||
sigID := SignatureID(instr.u1)
|
||||
sig, ok := b.signatures[sigID]
|
||||
@@ -1465,6 +1502,60 @@ func (i *Instruction) AsVconst(lo, hi uint64) *Instruction {
|
||||
return i
|
||||
}
|
||||
|
||||
// AsVbnot initializes this instruction as a vector negation instruction with OpcodeVbnot.
|
||||
func (i *Instruction) AsVbnot(v Value) *Instruction {
|
||||
i.opcode = OpcodeVbnot
|
||||
i.typ = TypeV128
|
||||
i.v = v
|
||||
return i
|
||||
}
|
||||
|
||||
// AsVband initializes this instruction as an and vector instruction with OpcodeVband.
|
||||
func (i *Instruction) AsVband(x, y Value) *Instruction {
|
||||
i.opcode = OpcodeVband
|
||||
i.typ = TypeV128
|
||||
i.v = x
|
||||
i.v2 = y
|
||||
return i
|
||||
}
|
||||
|
||||
// AsVbor initializes this instruction as an or vector instruction with OpcodeVbor.
|
||||
func (i *Instruction) AsVbor(x, y Value) *Instruction {
|
||||
i.opcode = OpcodeVbor
|
||||
i.typ = TypeV128
|
||||
i.v = x
|
||||
i.v2 = y
|
||||
return i
|
||||
}
|
||||
|
||||
// AsVbxor initializes this instruction as a xor vector instruction with OpcodeVbxor.
|
||||
func (i *Instruction) AsVbxor(x, y Value) *Instruction {
|
||||
i.opcode = OpcodeVbxor
|
||||
i.typ = TypeV128
|
||||
i.v = x
|
||||
i.v2 = y
|
||||
return i
|
||||
}
|
||||
|
||||
// AsVbandnot initializes this instruction as an and-not vector instruction with OpcodeVbandnot.
|
||||
func (i *Instruction) AsVbandnot(x, y Value) *Instruction {
|
||||
i.opcode = OpcodeVbandnot
|
||||
i.typ = TypeV128
|
||||
i.v = x
|
||||
i.v2 = y
|
||||
return i
|
||||
}
|
||||
|
||||
// AsVbitselect initializes this instruction as a bit select vector instruction with OpcodeVbitselect.
|
||||
func (i *Instruction) AsVbitselect(c, x, y Value) *Instruction {
|
||||
i.opcode = OpcodeVbitselect
|
||||
i.typ = TypeV128
|
||||
i.v = c
|
||||
i.v2 = x
|
||||
i.v3 = y
|
||||
return i
|
||||
}
|
||||
|
||||
// VconstData returns the operands of this vector constant instruction.
|
||||
func (i *Instruction) VconstData() (lo, hi uint64) {
|
||||
return i.u1, i.u2
|
||||
@@ -1883,7 +1974,7 @@ func (i *Instruction) Format(b Builder) string {
|
||||
instSuffix = fmt.Sprintf(" %s, %#x", i.v.Format(b), int32(i.u1))
|
||||
case OpcodeUload8, OpcodeUload16, OpcodeUload32, OpcodeSload8, OpcodeSload16, OpcodeSload32:
|
||||
instSuffix = fmt.Sprintf(" %s, %#x", i.v.Format(b), int32(i.u1))
|
||||
case OpcodeSelect:
|
||||
case OpcodeSelect, OpcodeVbitselect:
|
||||
instSuffix = fmt.Sprintf(" %s, %s, %s", i.v.Format(b), i.v2.Format(b), i.v3.Format(b))
|
||||
case OpcodeIconst:
|
||||
switch i.typ {
|
||||
@@ -1941,16 +2032,18 @@ func (i *Instruction) Format(b Builder) string {
|
||||
}
|
||||
instSuffix += "]"
|
||||
case OpcodeBand, OpcodeBor, OpcodeBxor, OpcodeRotr, OpcodeRotl, OpcodeIshl, OpcodeSshr, OpcodeUshr,
|
||||
OpcodeSdiv, OpcodeUdiv, OpcodeFcopysign, OpcodeSrem, OpcodeUrem:
|
||||
OpcodeSdiv, OpcodeUdiv, OpcodeFcopysign, OpcodeSrem, OpcodeUrem,
|
||||
OpcodeVbnot, OpcodeVbxor, OpcodeVbor, OpcodeVband, OpcodeVbandnot:
|
||||
instSuffix = fmt.Sprintf(" %s, %s", i.v.Format(b), i.v2.Format(b))
|
||||
case OpcodeUndefined:
|
||||
case OpcodeClz, OpcodeCtz, OpcodePopcnt, OpcodeFneg, OpcodeFcvtToSint, OpcodeFcvtToUint, OpcodeFcvtFromSint,
|
||||
OpcodeFcvtFromUint, OpcodeFcvtToSintSat, OpcodeFcvtToUintSat, OpcodeFdemote, OpcodeFpromote, OpcodeIreduce, OpcodeBitcast, OpcodeSqrt, OpcodeFabs,
|
||||
OpcodeCeil, OpcodeFloor, OpcodeTrunc, OpcodeNearest:
|
||||
instSuffix = " " + i.v.Format(b)
|
||||
case OpcodeVIadd, OpcodeVSaddSat, OpcodeVUaddSat, OpcodeVIsub, OpcodeVSsubSat, OpcodeVUsubSat, OpcodeVImin, OpcodeVUmin, OpcodeVImax, OpcodeVUmax, OpcodeVImul:
|
||||
case OpcodeVIadd, OpcodeVSaddSat, OpcodeVUaddSat, OpcodeVIsub, OpcodeVSsubSat, OpcodeVUsubSat,
|
||||
OpcodeVImin, OpcodeVUmin, OpcodeVImax, OpcodeVUmax, OpcodeVImul:
|
||||
instSuffix = fmt.Sprintf(".%s %s, %s", VecLane(i.u1), i.v.Format(b), i.v2.Format(b))
|
||||
case OpcodeVIabs, OpcodeVIneg, OpcodeVIpopcnt:
|
||||
case OpcodeVIabs, OpcodeVIneg, OpcodeVIpopcnt, OpcodeVhighBits, OpcodeVallTrue, OpcodeVanyTrue:
|
||||
instSuffix = fmt.Sprintf(".%s %s", VecLane(i.u1), i.v.Format(b))
|
||||
default:
|
||||
panic(fmt.Sprintf("TODO: format for %s", i.opcode))
|
||||
@@ -2322,6 +2415,18 @@ func (o Opcode) String() (ret string) {
|
||||
return "Fence"
|
||||
case OpcodeExtractVector:
|
||||
return "ExtractVector"
|
||||
case OpcodeVbor:
|
||||
return "Vbor"
|
||||
case OpcodeVbxor:
|
||||
return "Vbxor"
|
||||
case OpcodeVband:
|
||||
return "Vband"
|
||||
case OpcodeVbandnot:
|
||||
return "Vbandnot"
|
||||
case OpcodeVbnot:
|
||||
return "Vbnot"
|
||||
case OpcodeVbitselect:
|
||||
return "Vbitselect"
|
||||
case OpcodeVIadd:
|
||||
return "VIadd"
|
||||
case OpcodeVSaddSat:
|
||||
|
||||
Reference in New Issue
Block a user