mirror of
https://github.com/ziglang/zig.git
synced 2025-12-29 09:33:18 +00:00
wasm: Preliminary fptrunc support
This implements the initial fptrunc instruction. For all other floating-point truncating, a call to compiler-rt is required. (This also updates fpext to emit the same error).
This commit is contained in:
parent
684b81f366
commit
d01bfa032d
@ -1220,6 +1220,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
.cond_br => self.airCondBr(inst),
|
||||
.dbg_stmt => WValue.none,
|
||||
.intcast => self.airIntcast(inst),
|
||||
.fptrunc => self.airFptrunc(inst),
|
||||
.fpext => self.airFpext(inst),
|
||||
.float_to_int => self.airFloatToInt(inst),
|
||||
.get_union_tag => self.airGetUnionTag(inst),
|
||||
@ -1300,7 +1301,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
|
||||
.bit_reverse,
|
||||
.is_err_ptr,
|
||||
.is_non_err_ptr,
|
||||
.fptrunc,
|
||||
.unwrap_errunion_payload_ptr,
|
||||
.unwrap_errunion_err_ptr,
|
||||
|
||||
@ -3189,23 +3189,40 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
|
||||
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const ty = self.air.typeOfIndex(inst);
|
||||
const wanted_bits = ty.floatBits(self.target);
|
||||
const have_bits = self.air.typeOf(ty_op.operand).floatBits(self.target);
|
||||
const dest_ty = self.air.typeOfIndex(inst);
|
||||
const dest_bits = dest_ty.floatBits(self.target);
|
||||
const src_bits = self.air.typeOf(ty_op.operand).floatBits(self.target);
|
||||
const operand = try self.resolveInst(ty_op.operand);
|
||||
|
||||
const have = toWasmBits(have_bits) orelse {
|
||||
return self.fail("TODO: Implement 'fpext' for floats with bitsize: {d}", .{have_bits});
|
||||
};
|
||||
const wanted = toWasmBits(wanted_bits) orelse {
|
||||
return self.fail("TODO: Implement 'fpext' for floats with bitsize: {d}", .{wanted_bits});
|
||||
};
|
||||
if (have == wanted) return operand;
|
||||
|
||||
assert(have < wanted);
|
||||
const result = try self.allocLocal(ty);
|
||||
try self.emitWValue(operand);
|
||||
try self.addTag(.f64_promote_f32);
|
||||
try self.addLabel(.local_set, result.local);
|
||||
return result;
|
||||
if (dest_bits == 64 and src_bits == 32) {
|
||||
const result = try self.allocLocal(dest_ty);
|
||||
try self.emitWValue(operand);
|
||||
try self.addTag(.f64_promote_f32);
|
||||
try self.addLabel(.local_set, result.local);
|
||||
return result;
|
||||
} else {
|
||||
// TODO: Emit a call to compiler-rt to extend the float. e.g. __extendhfsf2
|
||||
return self.fail("TODO: Implement 'fpext' for floats with bitsize: {d}", .{dest_bits});
|
||||
}
|
||||
}
|
||||
|
||||
fn airFptrunc(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
|
||||
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const dest_ty = self.air.typeOfIndex(inst);
|
||||
const dest_bits = dest_ty.floatBits(self.target);
|
||||
const src_bits = self.air.typeOf(ty_op.operand).floatBits(self.target);
|
||||
const operand = try self.resolveInst(ty_op.operand);
|
||||
|
||||
if (dest_bits == 32 and src_bits == 64) {
|
||||
const result = try self.allocLocal(dest_ty);
|
||||
try self.emitWValue(operand);
|
||||
try self.addTag(.f32_demote_f64);
|
||||
try self.addLabel(.local_set, result.local);
|
||||
return result;
|
||||
} else {
|
||||
// TODO: Emit a call to compiler-rt to trunc the float. e.g. __truncdfhf2
|
||||
return self.fail("TODO: Implement 'fptrunc' for floats with bitsize: {d}", .{dest_bits});
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,6 +161,7 @@ pub fn emitMir(emit: *Emit) InnerError!void {
|
||||
.i64_extend8_s => try emit.emitTag(tag),
|
||||
.i64_extend16_s => try emit.emitTag(tag),
|
||||
.i64_extend32_s => try emit.emitTag(tag),
|
||||
.f32_demote_f64 => try emit.emitTag(tag),
|
||||
.f64_promote_f32 => try emit.emitTag(tag),
|
||||
.i32_reinterpret_f32 => try emit.emitTag(tag),
|
||||
.i64_reinterpret_f64 => try emit.emitTag(tag),
|
||||
|
||||
@ -391,6 +391,8 @@ pub const Inst = struct {
|
||||
/// Uses `tag`
|
||||
i64_trunc_f64_u = 0xB1,
|
||||
/// Uses `tag`
|
||||
f32_demote_f64 = 0xB6,
|
||||
/// Uses `tag`
|
||||
f64_promote_f32 = 0xBB,
|
||||
/// Uses `tag`
|
||||
i32_reinterpret_f32 = 0xBC,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user