| ... | @@ -3470,10 +3470,10 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO | ... | @@ -3470,10 +3470,10 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO |
| 3470 | // both lhs and rhs, as well as checking the payload are matching of lhs and rhs | 3470 | // both lhs and rhs, as well as checking the payload are matching of lhs and rhs |
| 3471 | return func.cmpOptionals(lhs, rhs, ty, op); | 3471 | return func.cmpOptionals(lhs, rhs, ty, op); |
| 3472 | } | 3472 | } |
| | 3473 | } else if (ty.isAnyFloat()) { |
| | 3474 | return func.cmpFloat(ty, lhs, rhs, op); |
| 3473 | } else if (isByRef(ty, mod)) { | 3475 | } else if (isByRef(ty, mod)) { |
| 3474 | return func.cmpBigInt(lhs, rhs, ty, op); | 3476 | return func.cmpBigInt(lhs, rhs, ty, op); |
| 3475 | } else if (ty.isAnyFloat() and ty.floatBits(func.target) == 16) { | | |
| 3476 | return func.cmpFloat16(lhs, rhs, op); | | |
| 3477 | } | 3477 | } |
| 3478 | | 3478 | |
| 3479 | // ensure that when we compare pointers, we emit | 3479 | // ensure that when we compare pointers, we emit |
| ... | @@ -3505,26 +3505,47 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO | ... | @@ -3505,26 +3505,47 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO |
| 3505 | return WValue{ .stack = {} }; | 3505 | return WValue{ .stack = {} }; |
| 3506 | } | 3506 | } |
| 3507 | | 3507 | |
| 3508 | /// Compares 16-bit floats | 3508 | /// Compares two floats. |
| 3509 | /// NOTE: The result value remains on top of the stack. | 3509 | /// NOTE: Leaves the result of the comparison on top of the stack. |
| 3510 | fn cmpFloat16(func: *CodeGen, lhs: WValue, rhs: WValue, op: std.math.CompareOperator) InnerError!WValue { | 3510 | fn cmpFloat(func: *CodeGen, ty: Type, lhs: WValue, rhs: WValue, cmp_op: std.math.CompareOperator) InnerError!WValue { |
| 3511 | const opcode: wasm.Opcode = buildOpcode(.{ | 3511 | const float_bits = ty.floatBits(func.target); |
| 3512 | .op = switch (op) { | 3512 | |
| 3513 | .lt => .lt, | 3513 | const op: Op = switch (cmp_op) { |
| 3514 | .lte => .le, | 3514 | .lt => .lt, |
| 3515 | .eq => .eq, | 3515 | .lte => .le, |
| 3516 | .neq => .ne, | 3516 | .eq => .eq, |
| 3517 | .gte => .ge, | 3517 | .neq => .ne, |
| 3518 | .gt => .gt, | 3518 | .gte => .ge, |
| | 3519 | .gt => .gt, |
| | 3520 | }; |
| | 3521 | |
| | 3522 | switch (float_bits) { |
| | 3523 | 16 => { |
| | 3524 | _ = try func.fpext(lhs, Type.f16, Type.f32); |
| | 3525 | _ = try func.fpext(rhs, Type.f16, Type.f32); |
| | 3526 | const opcode = buildOpcode(.{ .op = op, .valtype1 = .f32 }); |
| | 3527 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); |
| | 3528 | return .stack; |
| 3519 | }, | 3529 | }, |
| 3520 | .valtype1 = .f32, | 3530 | 32, 64 => { |
| 3521 | .signedness = .unsigned, | 3531 | try func.emitWValue(lhs); |
| 3522 | }); | 3532 | try func.emitWValue(rhs); |
| 3523 | _ = try func.fpext(lhs, Type.f16, Type.f32); | 3533 | const val_type: wasm.Valtype = if (float_bits == 32) .f32 else .f64; |
| 3524 | _ = try func.fpext(rhs, Type.f16, Type.f32); | 3534 | const opcode = buildOpcode(.{ .op = op, .valtype1 = val_type }); |
| 3525 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); | 3535 | try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); |
| | 3536 | return .stack; |
| | 3537 | }, |
| | 3538 | 80, 128 => { |
| | 3539 | var fn_name_buf: [32]u8 = undefined; |
| | 3540 | const fn_name = std.fmt.bufPrint(&fn_name_buf, "__{s}{s}f2", .{ |
| | 3541 | @tagName(op), target_util.compilerRtFloatAbbrev(float_bits), |
| | 3542 | }) catch unreachable; |
| 3526 | | 3543 | |
| 3527 | return WValue{ .stack = {} }; | 3544 | const result = try func.callIntrinsic(fn_name, &.{ ty.ip_index, ty.ip_index }, Type.bool, &.{ lhs, rhs }); |
| | 3545 | return func.cmp(result, WValue{ .imm32 = 0 }, Type.i32, cmp_op); |
| | 3546 | }, |
| | 3547 | else => unreachable, |
| | 3548 | } |
| 3528 | } | 3549 | } |
| 3529 | | 3550 | |
| 3530 | fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 3551 | fn airCmpVector(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |