diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-11-22 18:57:34 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-11-30 17:56:01 +0100 |
| commit | 7cf442cabcb08b84b21ebc3850f52ac796093ecb (patch) | |
| tree | 9f3db1a4ef99e4870630f3fd9e65e16072099b33 /src/arch/wasm/CodeGen.zig | |
| parent | 2be0d5bbca5a261533b96dbc0e7bc400000e6e07 (diff) | |
| download | zig-7cf442cabcb08b84b21ebc3850f52ac796093ecb.tar.gz zig-7cf442cabcb08b84b21ebc3850f52ac796093ecb.zip | |
wasm: Support bitcasting between floats and ints
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index f89eb938ee..3b5ca72563 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -3091,11 +3091,32 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const ty_op = func.air.instructions.items(.data)[inst].ty_op; const result = if (!func.liveness.isUnused(inst)) result: { const operand = try func.resolveInst(ty_op.operand); + const wanted_ty = func.air.typeOfIndex(inst); + const given_ty = func.air.typeOf(ty_op.operand); + if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) { + const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand); + break :result try bitcast_result.toLocal(func, wanted_ty); + } break :result func.reuseOperand(ty_op.operand, operand); } else WValue{ .none = {} }; func.finishAir(inst, result, &.{}); } +fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue { + // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction + if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand; + assert((wanted_ty.isInt() and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt())); + + const opcode = buildOpcode(.{ + .op = .reinterpret, + .valtype1 = typeToValtype(wanted_ty, func.target), + .valtype2 = typeToValtype(given_ty, func.target), + }); + try func.emitWValue(operand); + try func.addTag(Mir.Inst.Tag.fromOpcode(opcode)); + return WValue{ .stack = {} }; +} + fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; const extra = func.air.extraData(Air.StructField, ty_pl.payload); |
