| ... | ... | @@ -4433,7 +4433,6 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4433 | 4433 | const ty = func.air.typeOfIndex(inst); |
| 4434 | 4434 | const elem_ty = ty.childType(); |
| 4435 | 4435 | |
| 4436 | | const result = try func.allocLocal(ty); |
| 4437 | 4436 | if (determineSimdStoreStrategy(ty, func.target) == .direct) blk: { |
| 4438 | 4437 | switch (operand) { |
| 4439 | 4438 | // when the operand lives in the linear memory section, we can directly |
| ... | ... | @@ -4447,6 +4446,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4447 | 4446 | 64 => std.wasm.simdOpcode(.v128_load64_splat), |
| 4448 | 4447 | else => break :blk, // Cannot make use of simd-instructions |
| 4449 | 4448 | }; |
| 4449 | const result = try func.allocLocal(ty); |
| 4450 | 4450 | try func.emitWValue(operand); |
| 4451 | 4451 | // TODO: Add helper functions for simd opcodes |
| 4452 | 4452 | const extra_index = @intCast(u32, func.mir_extra.items.len); |
| ... | ... | @@ -4468,6 +4468,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4468 | 4468 | 64 => if (elem_ty.isInt()) std.wasm.simdOpcode(.i64x2_splat) else std.wasm.simdOpcode(.f64x2_splat), |
| 4469 | 4469 | else => break :blk, // Cannot make use of simd-instructions |
| 4470 | 4470 | }; |
| 4471 | const result = try func.allocLocal(ty); |
| 4471 | 4472 | try func.emitWValue(operand); |
| 4472 | 4473 | const extra_index = @intCast(u32, func.mir_extra.items.len); |
| 4473 | 4474 | try func.mir_extra.append(func.gpa, opcode); |
| ... | ... | @@ -4478,8 +4479,22 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4478 | 4479 | else => unreachable, |
| 4479 | 4480 | } |
| 4480 | 4481 | } |
| 4482 | const elem_size = elem_ty.bitSize(func.target); |
| 4483 | const vector_len = @intCast(usize, ty.vectorLen()); |
| 4484 | if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) { |
| 4485 | return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size}); |
| 4486 | } |
| 4487 | |
| 4488 | const result = try func.allocStack(ty); |
| 4489 | const elem_byte_size = @intCast(u32, elem_ty.abiSize(func.target)); |
| 4490 | var index: usize = 0; |
| 4491 | var offset: u32 = 0; |
| 4492 | while (index < vector_len) : (index += 1) { |
| 4493 | try func.store(result, operand, elem_ty, offset); |
| 4494 | offset += elem_byte_size; |
| 4495 | } |
| 4481 | 4496 | |
| 4482 | | return func.fail("TODO: Implement wasm airSplat unrolled", .{}); |
| 4497 | return func.finishAir(inst, result, &.{ty_op.operand}); |
| 4483 | 4498 | } |
| 4484 | 4499 | |
| 4485 | 4500 | fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |