| ... | @@ -4670,11 +4670,40 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -4670,11 +4670,40 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4670 | } | 4670 | } |
| 4671 | | 4671 | |
| 4672 | fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4672 | fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4673 | const ty_op = func.air.instructions.items(.data)[inst].ty_op; | 4673 | const inst_ty = func.air.typeOfIndex(inst); |
| 4674 | const operand = try func.resolveInst(ty_op.operand); | 4674 | const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; |
| | 4675 | const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 4675 | | 4676 | |
| 4676 | _ = operand; | 4677 | const a = try func.resolveInst(extra.a); |
| 4677 | return func.fail("TODO: Implement wasm airShuffle", .{}); | 4678 | const b = try func.resolveInst(extra.b); |
| | 4679 | const mask = func.air.values[extra.mask]; |
| | 4680 | const mask_len = extra.mask_len; |
| | 4681 | |
| | 4682 | const child_ty = inst_ty.childType(); |
| | 4683 | const elem_size = child_ty.abiSize(func.target); |
| | 4684 | |
| | 4685 | if (func.liveness.isUnused(inst)) { |
| | 4686 | return func.finishAir(inst, .none, &.{ extra.a, extra.b }); |
| | 4687 | } |
| | 4688 | |
| | 4689 | const module = func.bin_file.base.options.module.?; |
| | 4690 | const result = try func.allocStack(inst_ty); |
| | 4691 | |
| | 4692 | for (0..mask_len) |index| { |
| | 4693 | var buf: Value.ElemValueBuffer = undefined; |
| | 4694 | const value = mask.elemValueBuffer(module, index, &buf).toSignedInt(func.target); |
| | 4695 | |
| | 4696 | try func.emitWValue(result); |
| | 4697 | |
| | 4698 | const loaded = if (value >= 0) |
| | 4699 | try func.load(a, child_ty, @intCast(u32, @intCast(i64, elem_size) * value)) |
| | 4700 | else |
| | 4701 | try func.load(b, child_ty, @intCast(u32, @intCast(i64, elem_size) * ~value)); |
| | 4702 | |
| | 4703 | try func.store(.stack, loaded, child_ty, result.stack_offset.value + @intCast(u32, elem_size) * @intCast(u32, index)); |
| | 4704 | } |
| | 4705 | |
| | 4706 | return func.finishAir(inst, result, &.{ extra.a, extra.b }); |
| 4678 | } | 4707 | } |
| 4679 | | 4708 | |
| 4680 | fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 4709 | fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| ... | @@ -5125,7 +5154,12 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5125,7 +5154,12 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5125 | } | 5154 | } |
| 5126 | | 5155 | |
| 5127 | fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5156 | fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5128 | func.finishAir(inst, .{ .imm32 = 0 }, &.{}); | 5157 | // TODO: Implement this properly once stack serialization is solved |
| | 5158 | func.finishAir(inst, switch (func.arch()) { |
| | 5159 | .wasm32 => .{ .imm32 = 0 }, |
| | 5160 | .wasm64 => .{ .imm64 = 0 }, |
| | 5161 | else => unreachable, |
| | 5162 | }, &.{}); |
| 5129 | } | 5163 | } |
| 5130 | | 5164 | |
| 5131 | fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5165 | fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |