aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm/CodeGen.zig
diff options
context:
space:
mode:
authorPavel Verigo <paul.verigo@gmail.com>2024-06-28 00:39:49 +0200
committerLuuk de Gram <luuk@degram.dev>2024-07-02 15:02:59 +0200
commit1a951b49af90d04832ec7e928eb2f87630499d59 (patch)
tree2516baefd77288eaf580522cc5a52425d188c078 /src/arch/wasm/CodeGen.zig
parent5a9495002fb8de2b70462c40dd27938c2fef6271 (diff)
downloadzig-1a951b49af90d04832ec7e928eb2f87630499d59.tar.gz
zig-1a951b49af90d04832ec7e928eb2f87630499d59.zip
stage2-wasm: not op for <= 128 bits ints
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
-rw-r--r--src/arch/wasm/CodeGen.zig53
1 files changed, 35 insertions, 18 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index 9effa75967..b1ebf9126d 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -3729,32 +3729,49 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
try func.addLabel(.local_set, not_tmp.local.value);
break :result not_tmp;
} else {
- const operand_bits = operand_ty.intInfo(mod).bits;
- const wasm_bits = toWasmBits(operand_bits) orelse {
- return func.fail("TODO: Implement binary NOT for integer with bitsize '{d}'", .{operand_bits});
+ const int_info = operand_ty.intInfo(mod);
+ const wasm_bits = toWasmBits(int_info.bits) orelse {
+ return func.fail("TODO: Implement binary NOT for {}", .{operand_ty.fmt(mod)});
};
switch (wasm_bits) {
32 => {
- const bin_op = try func.binOp(operand, .{ .imm32 = ~@as(u32, 0) }, operand_ty, .xor);
- break :result try (try func.wrapOperand(bin_op, operand_ty)).toLocal(func, operand_ty);
+ try func.emitWValue(operand);
+ try func.addImm32(switch (int_info.signedness) {
+ .unsigned => ~@as(u32, 0) >> @intCast(32 - int_info.bits),
+ .signed => ~@as(u32, 0),
+ });
+ try func.addTag(.i32_xor);
+ break :result try @as(WValue, .stack).toLocal(func, operand_ty);
},
64 => {
- const bin_op = try func.binOp(operand, .{ .imm64 = ~@as(u64, 0) }, operand_ty, .xor);
- break :result try (try func.wrapOperand(bin_op, operand_ty)).toLocal(func, operand_ty);
+ try func.emitWValue(operand);
+ try func.addImm64(switch (int_info.signedness) {
+ .unsigned => ~@as(u64, 0) >> @intCast(64 - int_info.bits),
+ .signed => ~@as(u64, 0),
+ });
+ try func.addTag(.i64_xor);
+ break :result try @as(WValue, .stack).toLocal(func, operand_ty);
},
128 => {
- const result_ptr = try func.allocStack(operand_ty);
- try func.emitWValue(result_ptr);
- const msb = try func.load(operand, Type.u64, 0);
- const msb_xor = try func.binOp(msb, .{ .imm64 = ~@as(u64, 0) }, Type.u64, .xor);
- try func.store(.{ .stack = {} }, msb_xor, Type.u64, 0 + result_ptr.offset());
-
- try func.emitWValue(result_ptr);
- const lsb = try func.load(operand, Type.u64, 8);
- const lsb_xor = try func.binOp(lsb, .{ .imm64 = ~@as(u64, 0) }, Type.u64, .xor);
- try func.store(result_ptr, lsb_xor, Type.u64, 8 + result_ptr.offset());
- break :result result_ptr;
+ const ptr = try func.allocStack(operand_ty);
+
+ try func.emitWValue(ptr);
+ _ = try func.load(operand, Type.u64, 0);
+ try func.addImm64(~@as(u64, 0));
+ try func.addTag(.i64_xor);
+ try func.store(.stack, .stack, Type.u64, ptr.offset());
+
+ try func.emitWValue(ptr);
+ _ = try func.load(operand, Type.u64, 8);
+ try func.addImm64(switch (int_info.signedness) {
+ .unsigned => ~@as(u64, 0) >> @intCast(128 - int_info.bits),
+ .signed => ~@as(u64, 0),
+ });
+ try func.addTag(.i64_xor);
+ try func.store(.stack, .stack, Type.u64, ptr.offset() + 8);
+
+ break :result ptr;
},
else => unreachable,
}