| ... | ... | @@ -13341,28 +13341,14 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13341 | 13341 | const target = sema.mod.getTarget(); |
| 13342 | 13342 | const dest_info = dest_scalar_ty.intInfo(target); |
| 13343 | 13343 | |
| 13344 | | if (dest_info.bits == 0) { |
| 13345 | | if (is_vector) { |
| 13346 | | return sema.addConstant( |
| 13347 | | dest_ty, |
| 13348 | | try Value.Tag.repeated.create(sema.arena, Value.zero), |
| 13349 | | ); |
| 13350 | | } else { |
| 13351 | | return sema.addConstant(dest_ty, Value.zero); |
| 13352 | | } |
| 13344 | if (try sema.typeHasOnePossibleValue(block, dest_ty_src, dest_ty)) |val| { |
| 13345 | return sema.addConstant(dest_ty, val); |
| 13353 | 13346 | } |
| 13354 | 13347 | |
| 13355 | 13348 | if (operand_scalar_ty.zigTypeTag() != .ComptimeInt) { |
| 13356 | 13349 | const operand_info = operand_ty.intInfo(target); |
| 13357 | | if (operand_info.bits == 0) { |
| 13358 | | if (is_vector) { |
| 13359 | | return sema.addConstant( |
| 13360 | | dest_ty, |
| 13361 | | try Value.Tag.repeated.create(sema.arena, Value.zero), |
| 13362 | | ); |
| 13363 | | } else { |
| 13364 | | return sema.addConstant(dest_ty, Value.zero); |
| 13365 | | } |
| 13350 | if (try sema.typeHasOnePossibleValue(block, operand_src, operand_ty)) |val| { |
| 13351 | return sema.addConstant(operand_ty, val); |
| 13366 | 13352 | } |
| 13367 | 13353 | |
| 13368 | 13354 | if (operand_info.signedness != dest_info.signedness) { |
| ... | ... | @@ -13461,15 +13447,9 @@ fn zirBitCount( |
| 13461 | 13447 | _ = try checkIntOrVector(sema, block, operand, operand_src); |
| 13462 | 13448 | const target = sema.mod.getTarget(); |
| 13463 | 13449 | const bits = operand_ty.intInfo(target).bits; |
| 13464 | | if (bits == 0) { |
| 13465 | | switch (operand_ty.zigTypeTag()) { |
| 13466 | | .Vector => return sema.addConstant( |
| 13467 | | try Type.vector(sema.arena, operand_ty.vectorLen(), Type.comptime_int), |
| 13468 | | try Value.Tag.repeated.create(sema.arena, Value.zero), |
| 13469 | | ), |
| 13470 | | .Int => return Air.Inst.Ref.zero, |
| 13471 | | else => unreachable, |
| 13472 | | } |
| 13450 | |
| 13451 | if (try sema.typeHasOnePossibleValue(block, operand_src, operand_ty)) |val| { |
| 13452 | return sema.addConstant(operand_ty, val); |
| 13473 | 13453 | } |
| 13474 | 13454 | |
| 13475 | 13455 | const result_scalar_ty = try Type.smallestUnsignedInt(sema.arena, bits); |
| ... | ... | @@ -13528,10 +13508,12 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13528 | 13508 | ); |
| 13529 | 13509 | } |
| 13530 | 13510 | |
| 13511 | if (try sema.typeHasOnePossibleValue(block, operand_src, operand_ty)) |val| { |
| 13512 | return sema.addConstant(operand_ty, val); |
| 13513 | } |
| 13514 | |
| 13531 | 13515 | switch (operand_ty.zigTypeTag()) { |
| 13532 | 13516 | .Int, .ComptimeInt => { |
| 13533 | | if (bits == 0) return Air.Inst.Ref.zero; |
| 13534 | | |
| 13535 | 13517 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13536 | 13518 | if (val.isUndef()) return sema.addConstUndef(operand_ty); |
| 13537 | 13519 | const result_val = try val.byteSwap(operand_ty, target, sema.arena); |
| ... | ... | @@ -13542,13 +13524,6 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13542 | 13524 | return block.addTyOp(.byte_swap, operand_ty, operand); |
| 13543 | 13525 | }, |
| 13544 | 13526 | .Vector => { |
| 13545 | | if (bits == 0) { |
| 13546 | | return sema.addConstant( |
| 13547 | | operand_ty, |
| 13548 | | try Value.Tag.repeated.create(sema.arena, Value.zero), |
| 13549 | | ); |
| 13550 | | } |
| 13551 | | |
| 13552 | 13527 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13553 | 13528 | if (val.isUndef()) |
| 13554 | 13529 | return sema.addConstUndef(operand_ty); |
| ... | ... | @@ -13575,28 +13550,50 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13575 | 13550 | |
| 13576 | 13551 | fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 13577 | 13552 | 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 | 13553 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 13580 | 13554 | const operand = sema.resolveInst(inst_data.operand); |
| 13581 | 13555 | const operand_ty = sema.typeOf(operand); |
| 13582 | | // TODO implement support for vectors |
| 13583 | | if (operand_ty.zigTypeTag() != .Int) { |
| 13584 | | return sema.fail(block, ty_src, "expected integer type, found '{}'", .{ |
| 13585 | | operand_ty, |
| 13586 | | }); |
| 13556 | _ = try sema.checkIntOrVectorAllowComptime(block, operand, operand_src); |
| 13557 | |
| 13558 | if (try sema.typeHasOnePossibleValue(block, operand_src, operand_ty)) |val| { |
| 13559 | return sema.addConstant(operand_ty, val); |
| 13587 | 13560 | } |
| 13561 | |
| 13588 | 13562 | const target = sema.mod.getTarget(); |
| 13589 | | const bits = operand_ty.intInfo(target).bits; |
| 13590 | | if (bits == 0) return Air.Inst.Ref.zero; |
| 13563 | switch (operand_ty.zigTypeTag()) { |
| 13564 | .Int, .ComptimeInt => { |
| 13565 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13566 | if (val.isUndef()) return sema.addConstUndef(operand_ty); |
| 13567 | const result_val = try val.bitReverse(operand_ty, target, sema.arena); |
| 13568 | return sema.addConstant(operand_ty, result_val); |
| 13569 | } else operand_src; |
| 13591 | 13570 | |
| 13592 | | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13593 | | if (val.isUndef()) return sema.addConstUndef(operand_ty); |
| 13594 | | const result_val = try val.bitReverse(operand_ty, target, sema.arena); |
| 13595 | | return sema.addConstant(operand_ty, result_val); |
| 13596 | | } else operand_src; |
| 13571 | try sema.requireRuntimeBlock(block, runtime_src); |
| 13572 | return block.addTyOp(.bit_reverse, operand_ty, operand); |
| 13573 | }, |
| 13574 | .Vector => { |
| 13575 | const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { |
| 13576 | if (val.isUndef()) |
| 13577 | return sema.addConstUndef(operand_ty); |
| 13597 | 13578 | |
| 13598 | | try sema.requireRuntimeBlock(block, runtime_src); |
| 13599 | | return block.addTyOp(.bit_reverse, operand_ty, operand); |
| 13579 | const vec_len = operand_ty.vectorLen(); |
| 13580 | var elem_buf: Value.ElemValueBuffer = undefined; |
| 13581 | const elems = try sema.arena.alloc(Value, vec_len); |
| 13582 | for (elems) |*elem, i| { |
| 13583 | const elem_val = val.elemValueBuffer(i, &elem_buf); |
| 13584 | elem.* = try elem_val.bitReverse(operand_ty, target, sema.arena); |
| 13585 | } |
| 13586 | return sema.addConstant( |
| 13587 | operand_ty, |
| 13588 | try Value.Tag.aggregate.create(sema.arena, elems), |
| 13589 | ); |
| 13590 | } else operand_src; |
| 13591 | |
| 13592 | try sema.requireRuntimeBlock(block, runtime_src); |
| 13593 | return block.addTyOp(.bit_reverse, operand_ty, operand); |
| 13594 | }, |
| 13595 | else => unreachable, |
| 13596 | } |
| 13600 | 13597 | } |
| 13601 | 13598 | |
| 13602 | 13599 | fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |