authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-11-22 18:57:34+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-11-30 17:56:01+01:00
log7cf442cabcb08b84b21ebc3850f52ac796093ecb
tree9f3db1a4ef99e4870630f3fd9e65e16072099b33
parent2be0d5bbca5a261533b96dbc0e7bc400000e6e07
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Support bitcasting between floats and ints


1 files changed, 21 insertions(+), 0 deletions(-)

src/arch/wasm/CodeGen.zig+21
...@@ -3091,11 +3091,32 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3091,11 +3091,32 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3091 const ty_op = func.air.instructions.items(.data)[inst].ty_op;3091 const ty_op = func.air.instructions.items(.data)[inst].ty_op;
3092 const result = if (!func.liveness.isUnused(inst)) result: {3092 const result = if (!func.liveness.isUnused(inst)) result: {
3093 const operand = try func.resolveInst(ty_op.operand);3093 const operand = try func.resolveInst(ty_op.operand);
3094 const wanted_ty = func.air.typeOfIndex(inst);
3095 const given_ty = func.air.typeOf(ty_op.operand);
3096 if (given_ty.isAnyFloat() or wanted_ty.isAnyFloat()) {
3097 const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand);
3098 break :result try bitcast_result.toLocal(func, wanted_ty);
3099 }
3094 break :result func.reuseOperand(ty_op.operand, operand);3100 break :result func.reuseOperand(ty_op.operand, operand);
3095 } else WValue{ .none = {} };3101 } else WValue{ .none = {} };
3096 func.finishAir(inst, result, &.{});3102 func.finishAir(inst, result, &.{});
3097}3103}
30983104
3105fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {
3106 // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction
3107 if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand;
3108 assert((wanted_ty.isInt() and given_ty.isAnyFloat()) or (wanted_ty.isAnyFloat() and given_ty.isInt()));
3109
3110 const opcode = buildOpcode(.{
3111 .op = .reinterpret,
3112 .valtype1 = typeToValtype(wanted_ty, func.target),
3113 .valtype2 = typeToValtype(given_ty, func.target),
3114 });
3115 try func.emitWValue(operand);
3116 try func.addTag(Mir.Inst.Tag.fromOpcode(opcode));
3117 return WValue{ .stack = {} };
3118}
3119
3099fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {3120fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3100 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;3121 const ty_pl = func.air.instructions.items(.data)[inst].ty_pl;
3101 const extra = func.air.extraData(Air.StructField, ty_pl.payload);3122 const extra = func.air.extraData(Air.StructField, ty_pl.payload);