| ... | @@ -13575,28 +13575,58 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13575,28 +13575,58 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13575 | | 13575 | |
| 13576 | fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13576 | fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13577 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 13577 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 13578 | const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | | |
| 13579 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 13578 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 13580 | const operand = sema.resolveInst(inst_data.operand); | 13579 | const operand = sema.resolveInst(inst_data.operand); |
| 13581 | const operand_ty = sema.typeOf(operand); | 13580 | const operand_ty = sema.typeOf(operand); |
| 13582 | // TODO implement support for vectors | 13581 | const scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand, operand_src); |
| 13583 | if (operand_ty.zigTypeTag() != .Int) { | 13582 | |
| 13584 | return sema.fail(block, ty_src, "expected integer type, found '{}'", .{ | | |
| 13585 | operand_ty, | | |
| 13586 | }); | | |
| 13587 | } | | |
| 13588 | const target = sema.mod.getTarget(); | 13583 | const target = sema.mod.getTarget(); |
| 13589 | const bits = operand_ty.intInfo(target).bits; | 13584 | const bits = scalar_ty.intInfo(target).bits; |
| 13590 | if (bits == 0) return Air.Inst.Ref.zero; | 13585 | if (bits == 0) { |
| | 13586 | switch (operand_ty.zigTypeTag()) { |
| | 13587 | .Vector => return sema.addConstant( |
| | 13588 | operand_ty, |
| | 13589 | try Value.Tag.repeated.create(sema.arena, Value.zero), |
| | 13590 | ), |
| | 13591 | .Int => return Air.Inst.Ref.zero, |
| | 13592 | else => unreachable, |
| | 13593 | } |
| | 13594 | } |
| 13591 | | 13595 | |
| 13592 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { | 13596 | switch (operand_ty.zigTypeTag()) { |
| 13593 | if (val.isUndef()) return sema.addConstUndef(operand_ty); | 13597 | .Int, .ComptimeInt => { |
| 13594 | const result_val = try val.bitReverse(operand_ty, target, sema.arena); | 13598 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13595 | return sema.addConstant(operand_ty, result_val); | 13599 | if (val.isUndef()) return sema.addConstUndef(operand_ty); |
| 13596 | } else operand_src; | 13600 | const result_val = try val.bitReverse(operand_ty, target, sema.arena); |
| | 13601 | return sema.addConstant(operand_ty, result_val); |
| | 13602 | } else operand_src; |
| 13597 | | 13603 | |
| 13598 | try sema.requireRuntimeBlock(block, runtime_src); | 13604 | try sema.requireRuntimeBlock(block, runtime_src); |
| 13599 | return block.addTyOp(.bit_reverse, operand_ty, operand); | 13605 | return block.addTyOp(.bit_reverse, operand_ty, operand); |
| | 13606 | }, |
| | 13607 | .Vector => { |
| | 13608 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| | 13609 | if (val.isUndef()) |
| | 13610 | return sema.addConstUndef(operand_ty); |
| | 13611 | |
| | 13612 | const vec_len = operand_ty.vectorLen(); |
| | 13613 | var elem_buf: Value.ElemValueBuffer = undefined; |
| | 13614 | const elems = try sema.arena.alloc(Value, vec_len); |
| | 13615 | for (elems) |*elem, i| { |
| | 13616 | const elem_val = val.elemValueBuffer(i, &elem_buf); |
| | 13617 | elem.* = try elem_val.bitReverse(operand_ty, target, sema.arena); |
| | 13618 | } |
| | 13619 | return sema.addConstant( |
| | 13620 | operand_ty, |
| | 13621 | try Value.Tag.aggregate.create(sema.arena, elems), |
| | 13622 | ); |
| | 13623 | } else operand_src; |
| | 13624 | |
| | 13625 | try sema.requireRuntimeBlock(block, runtime_src); |
| | 13626 | return block.addTyOp(.bit_reverse, operand_ty, operand); |
| | 13627 | }, |
| | 13628 | else => unreachable, |
| | 13629 | } |
| 13600 | } | 13630 | } |
| 13601 | | 13631 | |
| 13602 | fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 13632 | fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |