| ... | ... | @@ -4527,17 +4527,38 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 4527 | 4527 | } else { |
| 4528 | 4528 | std.debug.assert(array_ty.zigTypeTag() == .Vector); |
| 4529 | 4529 | |
| 4530 | | // TODO: Check if index is constant; if so, use a lane extract |
| 4530 | switch (index) { |
| 4531 | inline .imm32, .imm64 => |lane| { |
| 4532 | const opcode: wasm.SimdOpcode = switch (elem_ty.bitSize(func.target)) { |
| 4533 | 8 => if (elem_ty.isSignedInt()) .i8x16_extract_lane_s else .i8x16_extract_lane_u, |
| 4534 | 16 => if (elem_ty.isSignedInt()) .i16x8_extract_lane_s else .i16x8_extract_lane_u, |
| 4535 | 32 => if (elem_ty.isInt()) .i32x4_extract_lane else .f32x4_extract_lane, |
| 4536 | 64 => if (elem_ty.isInt()) .i64x2_extract_lane else .f64x2_extract_lane, |
| 4537 | else => unreachable, |
| 4538 | }; |
| 4531 | 4539 | |
| 4532 | | var stack_vec = try func.allocStack(array_ty); |
| 4533 | | try func.store(stack_vec, array, array_ty, 0); |
| 4540 | var operands = [_]u32{ std.wasm.simdOpcode(opcode), @intCast(u8, lane) }; |
| 4534 | 4541 | |
| 4535 | | // Is a non-unrolled vector (v128) |
| 4536 | | try func.lowerToStack(stack_vec); |
| 4537 | | try func.emitWValue(index); |
| 4538 | | try func.addImm32(@bitCast(i32, @intCast(u32, elem_size))); |
| 4539 | | try func.addTag(.i32_mul); |
| 4540 | | try func.addTag(.i32_add); |
| 4542 | try func.emitWValue(array); |
| 4543 | |
| 4544 | const extra_index = @intCast(u32, func.mir_extra.items.len); |
| 4545 | try func.mir_extra.appendSlice(func.gpa, &operands); |
| 4546 | try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } }); |
| 4547 | |
| 4548 | return func.finishAir(inst, try WValue.toLocal(.stack, func, elem_ty), &.{ bin_op.lhs, bin_op.rhs }); |
| 4549 | }, |
| 4550 | else => { |
| 4551 | var stack_vec = try func.allocStack(array_ty); |
| 4552 | try func.store(stack_vec, array, array_ty, 0); |
| 4553 | |
| 4554 | // Is a non-unrolled vector (v128) |
| 4555 | try func.lowerToStack(stack_vec); |
| 4556 | try func.emitWValue(index); |
| 4557 | try func.addImm32(@bitCast(i32, @intCast(u32, elem_size))); |
| 4558 | try func.addTag(.i32_mul); |
| 4559 | try func.addTag(.i32_add); |
| 4560 | }, |
| 4561 | } |
| 4541 | 4562 | } |
| 4542 | 4563 | |
| 4543 | 4564 | const elem_result = val: { |