wazevo: passes simd_bitwise spec tests (#1715)

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
This commit is contained in:
Edoardo Vacchi
2023-09-18 14:07:53 +02:00
committed by GitHub
parent 57b44b653f
commit 9b261b3aa7
7 changed files with 364 additions and 62 deletions
@@ -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)
}
+1
View File
@@ -139,6 +139,7 @@ func TestSpectestV2(t *testing.T) {
{"conversions"},
{"if"},
{"loop"},
{"simd_bitwise"},
{"simd_const"},
{"simd_i8x16_arith"},
{"simd_i8x16_arith2"},
+59
View File
@@ -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
+151 -46
View File
@@ -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: