diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index f52506c393ef9b730d2c690b386e835e3b84fdb8..38ab19cb6038d2483b8812b5b3e1c5066327d1d8 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3889,27 +3889,26 @@ fn airMaxMin(self: *Self, inst: Air.Inst.Index, op: enum { max, min }) InnerErro const lhs = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); + // operands to select from + try self.emitWValue(lhs); + try self.emitWValue(rhs); + + // operands to compare + try self.emitWValue(lhs); + try self.emitWValue(rhs); + const opcode = buildOpcode(.{ + .op = if (op == .max) .gt else .lt, + .signedness = if (ty.isSignedInt()) .signed else .unsigned, + .valtype1 = typeToValtype(ty, self.target), + }); + try self.addTag(Mir.Inst.Tag.fromOpcode(opcode)); + + // based on the result from comparison, return operand 0 or 1. + try self.addTag(.select); + + // store result in local const result = try self.allocLocal(ty); - - try self.startBlock(.block, wasm.block_empty); - try self.startBlock(.block, wasm.block_empty); - - // check if LHS is greater/lesser than RHS - const cmp_result = try self.cmp(lhs, rhs, ty, if (op == .max) .gt else .lt); - try self.addLabel(.local_get, cmp_result.local); - try self.addLabel(.br_if, 0); // break to outer loop if LHS is greater/lesser than RHS - - // set RHS as max/min - try self.emitWValue(rhs); try self.addLabel(.local_set, result.local); - try self.addLabel(.br, 1); // break out of all blocks - try self.endBlock(); - - // set LHS as max/min - try self.emitWValue(lhs); - try self.addLabel(.local_set, result.local); - try self.endBlock(); - return result; } diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 6fc2dfa3b3f7c7397611ab4beac4378e4221079c..bcbff8d19501a4c70be61651a68333f328ed4fae 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -96,6 +96,8 @@ pub fn emitMir(emit: *Emit) InnerError!void { .@"return" => try emit.emitTag(tag), .@"unreachable" => try emit.emitTag(tag), + .select => try emit.emitTag(tag), + // arithmetic .i32_eqz => try emit.emitTag(tag), .i32_eq => try emit.emitTag(tag), diff --git a/src/arch/wasm/Mir.zig b/src/arch/wasm/Mir.zig index b15dbd90201072cffe5734b45704e8b0f31fce19..87e64ce9e08dd6447524cb39bad70a7edea37714 100644 --- a/src/arch/wasm/Mir.zig +++ b/src/arch/wasm/Mir.zig @@ -77,6 +77,10 @@ pub const Inst = struct { /// /// Uses `label` call_indirect = 0x11, + /// Pops three values from the stack and pushes + /// the first or second value dependent on the third value. + /// Uses `tag` + select = 0x1B, /// Loads a local at given index onto the stack. /// /// Uses `label`