aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-11-22 18:57:34 +0100
committerLuuk de Gram <luuk@degram.dev>2022-11-30 17:56:01 +0100
commit7cf442cabcb08b84b21ebc3850f52ac796093ecb (patch)
tree9f3db1a4ef99e4870630f3fd9e65e16072099b33 /src
parent2be0d5bbca5a261533b96dbc0e7bc400000e6e07 (diff)
downloadzig-7cf442cabcb08b84b21ebc3850f52ac796093ecb.tar.gz
zig-7cf442cabcb08b84b21ebc3850f52ac796093ecb.zip
wasm: Support bitcasting between floats and ints
Diffstat (limited to 'src')
-rw-r--r--src/arch/wasm/CodeGen.zig21
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);