| ... | ... | @@ -1316,6 +1316,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1316 | 1316 | .shl_with_overflow => self.airBinOpOverflow(inst, .shl), |
| 1317 | 1317 | .mul_with_overflow => self.airBinOpOverflow(inst, .mul), |
| 1318 | 1318 | |
| 1319 | .clz => self.airClz(inst), |
| 1320 | |
| 1319 | 1321 | .cmp_eq => self.airCmp(inst, .eq), |
| 1320 | 1322 | .cmp_gte => self.airCmp(inst, .gte), |
| 1321 | 1323 | .cmp_gt => self.airCmp(inst, .gt), |
| ... | ... | @@ -1438,7 +1440,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1438 | 1440 | .shl_sat, |
| 1439 | 1441 | .ret_addr, |
| 1440 | 1442 | .frame_addr, |
| 1441 | | .clz, |
| 1442 | 1443 | .ctz, |
| 1443 | 1444 | .byte_swap, |
| 1444 | 1445 | .bit_reverse, |
| ... | ... | @@ -3932,3 +3933,48 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3932 | 3933 | const mul_result = try self.binOp(lhs, rhs, ty, .mul); |
| 3933 | 3934 | return self.binOp(mul_result, addend, ty, .add); |
| 3934 | 3935 | } |
| 3936 | |
| 3937 | fn airClz(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3938 | if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; |
| 3939 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3940 | const ty = self.air.typeOf(ty_op.operand); |
| 3941 | const result_ty = self.air.typeOfIndex(inst); |
| 3942 | if (ty.zigTypeTag() == .Vector) { |
| 3943 | return self.fail("TODO: `@clz` for vectors", .{}); |
| 3944 | } |
| 3945 | |
| 3946 | const operand = try self.resolveInst(ty_op.operand); |
| 3947 | const int_info = ty.intInfo(self.target); |
| 3948 | const wasm_bits = toWasmBits(int_info.bits) orelse { |
| 3949 | return self.fail("TODO: `@clz` for integers with bitsize '{d}'", .{int_info.bits}); |
| 3950 | }; |
| 3951 | |
| 3952 | try self.emitWValue(operand); |
| 3953 | switch (wasm_bits) { |
| 3954 | 32 => { |
| 3955 | try self.addTag(.i32_clz); |
| 3956 | |
| 3957 | if (wasm_bits != int_info.bits) { |
| 3958 | const tmp = try self.allocLocal(ty); |
| 3959 | try self.addLabel(.local_set, tmp.local); |
| 3960 | const val: i32 = -@intCast(i32, wasm_bits - int_info.bits); |
| 3961 | return self.wrapBinOp(tmp, .{ .imm32 = @bitCast(u32, val) }, ty, .add); |
| 3962 | } |
| 3963 | }, |
| 3964 | 64 => { |
| 3965 | try self.addTag(.i64_clz); |
| 3966 | |
| 3967 | if (wasm_bits != int_info.bits) { |
| 3968 | const tmp = try self.allocLocal(ty); |
| 3969 | try self.addLabel(.local_set, tmp.local); |
| 3970 | const val: i64 = -@intCast(i64, wasm_bits - int_info.bits); |
| 3971 | return self.wrapBinOp(tmp, .{ .imm64 = @bitCast(u64, val) }, ty, .add); |
| 3972 | } |
| 3973 | }, |
| 3974 | else => unreachable, |
| 3975 | } |
| 3976 | |
| 3977 | const result = try self.allocLocal(result_ty); |
| 3978 | try self.addLabel(.local_set, result.local); |
| 3979 | return result; |
| 3980 | } |