| ... | ... | @@ -6584,15 +6584,86 @@ fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6584 | 6584 | } |
| 6585 | 6585 | |
| 6586 | 6586 | fn airSelect(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6587 | | if (f.liveness.isUnused(inst)) return .none; |
| 6587 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; |
| 6588 | const extra = f.air.extraData(Air.Bin, pl_op.payload).data; |
| 6589 | |
| 6590 | if (f.liveness.isUnused(inst)) { |
| 6591 | try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs }); |
| 6592 | return .none; |
| 6593 | } |
| 6594 | |
| 6595 | const pred = try f.resolveInst(pl_op.operand); |
| 6596 | const lhs = try f.resolveInst(extra.lhs); |
| 6597 | const rhs = try f.resolveInst(extra.rhs); |
| 6598 | try reap(f, inst, &.{ pl_op.operand, extra.lhs, extra.rhs }); |
| 6599 | |
| 6600 | const inst_ty = f.air.typeOfIndex(inst); |
| 6601 | |
| 6602 | const writer = f.object.writer(); |
| 6603 | const local = try f.allocLocal(inst, inst_ty); |
| 6604 | const v = try Vectorizer.start(f, inst, writer, inst_ty); |
| 6605 | try f.writeCValue(writer, local, .Other); |
| 6606 | try v.elem(f, writer); |
| 6607 | try writer.writeAll(" = "); |
| 6608 | try f.writeCValue(writer, pred, .Other); |
| 6609 | try v.elem(f, writer); |
| 6610 | try writer.writeAll(" ? "); |
| 6611 | try f.writeCValue(writer, lhs, .Other); |
| 6612 | try v.elem(f, writer); |
| 6613 | try writer.writeAll(" : "); |
| 6614 | try f.writeCValue(writer, rhs, .Other); |
| 6615 | try v.elem(f, writer); |
| 6616 | try writer.writeAll(";\n"); |
| 6617 | try v.end(f, inst, writer); |
| 6588 | 6618 | |
| 6589 | | return f.fail("TODO: C backend: implement airSelect", .{}); |
| 6619 | return local; |
| 6590 | 6620 | } |
| 6591 | 6621 | |
| 6592 | 6622 | fn airShuffle(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6593 | | if (f.liveness.isUnused(inst)) return .none; |
| 6623 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 6624 | const extra = f.air.extraData(Air.Shuffle, ty_pl.payload).data; |
| 6625 | |
| 6626 | if (f.liveness.isUnused(inst)) { |
| 6627 | try reap(f, inst, &.{ extra.a, extra.b }); |
| 6628 | return .none; |
| 6629 | } |
| 6630 | |
| 6631 | const mask = f.air.values[extra.mask]; |
| 6632 | const lhs = try f.resolveInst(extra.a); |
| 6633 | const rhs = try f.resolveInst(extra.b); |
| 6594 | 6634 | |
| 6595 | | return f.fail("TODO: C backend: implement airShuffle", .{}); |
| 6635 | const module = f.object.dg.module; |
| 6636 | const target = module.getTarget(); |
| 6637 | const inst_ty = f.air.typeOfIndex(inst); |
| 6638 | |
| 6639 | const writer = f.object.writer(); |
| 6640 | const local = try f.allocLocal(inst, inst_ty); |
| 6641 | try reap(f, inst, &.{ extra.a, extra.b }); // local cannot alias operands |
| 6642 | for (0..extra.mask_len) |index| { |
| 6643 | var dst_pl = Value.Payload.U64{ |
| 6644 | .base = .{ .tag = .int_u64 }, |
| 6645 | .data = @intCast(u64, index), |
| 6646 | }; |
| 6647 | |
| 6648 | try f.writeCValue(writer, local, .Other); |
| 6649 | try writer.writeByte('['); |
| 6650 | try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&dst_pl.base), .Other); |
| 6651 | try writer.writeAll("] = "); |
| 6652 | |
| 6653 | var buf: Value.ElemValueBuffer = undefined; |
| 6654 | const mask_elem = mask.elemValueBuffer(module, index, &buf).toSignedInt(target); |
| 6655 | var src_pl = Value.Payload.U64{ |
| 6656 | .base = .{ .tag = .int_u64 }, |
| 6657 | .data = @intCast(u64, mask_elem ^ mask_elem >> 63), |
| 6658 | }; |
| 6659 | |
| 6660 | try f.writeCValue(writer, if (mask_elem >= 0) lhs else rhs, .Other); |
| 6661 | try writer.writeByte('['); |
| 6662 | try f.object.dg.renderValue(writer, Type.usize, Value.initPayload(&src_pl.base), .Other); |
| 6663 | try writer.writeAll("];\n"); |
| 6664 | } |
| 6665 | |
| 6666 | return local; |
| 6596 | 6667 | } |
| 6597 | 6668 | |
| 6598 | 6669 | fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |