mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
wasm: Implement wrapping operands, add opcodes to wasm.zig
- Some opcodes have the incorrect value set in std. - Some opcodes were missing and have now been added to std. - Adding wrapping operands for add,sub and mul. - Implement intCast which either extends or shortens the type.
This commit is contained in:
parent
5589edf45c
commit
5667ab7dcd
@ -162,8 +162,14 @@ pub const Opcode = enum(u8) {
|
||||
i32_wrap_i64 = 0xA7,
|
||||
i32_trunc_f32_s = 0xA8,
|
||||
i32_trunc_f32_u = 0xA9,
|
||||
i32_trunc_f64_s = 0xB0,
|
||||
i32_trunc_f64_u = 0xB1,
|
||||
i32_trunc_f64_s = 0xAA,
|
||||
i32_trunc_f64_u = 0xAB,
|
||||
i64_extend_i32_s = 0xAC,
|
||||
i64_extend_i32_u = 0xAD,
|
||||
i64_trunc_f32_s = 0xAE,
|
||||
i64_trunc_f32_u = 0xAF,
|
||||
i64_trunc_f64_s = 0xB0,
|
||||
i64_trunc_f64_u = 0xB1,
|
||||
f32_convert_i32_s = 0xB2,
|
||||
f32_convert_i32_u = 0xB3,
|
||||
f32_convert_i64_s = 0xB4,
|
||||
|
||||
@ -591,7 +591,7 @@ pub const Context = struct {
|
||||
.ErrorSet,
|
||||
=> wasm.Valtype.i32,
|
||||
.Struct, .ErrorUnion => unreachable, // Multi typed, must be handled individually.
|
||||
else => self.fail("TODO - Wasm valtype for type '{s}'", .{ty.zigTypeTag()}),
|
||||
else => |tag| self.fail("TODO - Wasm valtype for type '{s}'", .{tag}),
|
||||
};
|
||||
}
|
||||
|
||||
@ -800,8 +800,11 @@ pub const Context = struct {
|
||||
const air_tags = self.air.instructions.items(.tag);
|
||||
return switch (air_tags[inst]) {
|
||||
.add => self.airBinOp(inst, .add),
|
||||
.addwrap => self.airBinOp(inst, .add),
|
||||
.sub => self.airBinOp(inst, .sub),
|
||||
.subwrap => self.airBinOp(inst, .sub),
|
||||
.mul => self.airBinOp(inst, .mul),
|
||||
.mulwrap => self.airBinOp(inst, .mul),
|
||||
.div => self.airBinOp(inst, .div),
|
||||
.bit_and => self.airBinOp(inst, .@"and"),
|
||||
.bit_or => self.airBinOp(inst, .@"or"),
|
||||
@ -826,6 +829,7 @@ pub const Context = struct {
|
||||
.cond_br => self.airCondBr(inst),
|
||||
.constant => unreachable,
|
||||
.dbg_stmt => WValue.none,
|
||||
.intcast => self.airIntcast(inst),
|
||||
.is_err => self.airIsErr(inst, .i32_ne),
|
||||
.is_non_err => self.airIsErr(inst, .i32_eq),
|
||||
.load => self.airLoad(inst),
|
||||
@ -1494,4 +1498,27 @@ pub const Context = struct {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
return self.resolveInst(ty_op.operand);
|
||||
}
|
||||
|
||||
fn airIntcast(self: *Context, inst: Air.Inst.Index) InnerError!WValue {
|
||||
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
|
||||
const ty = self.air.getRefType(ty_op.ty);
|
||||
const operand = self.resolveInst(ty_op.operand);
|
||||
const ref_ty = self.air.typeOf(ty_op.operand);
|
||||
const ref_info = ref_ty.intInfo(self.target);
|
||||
const op_bits = ref_info.bits;
|
||||
const wanted_bits = ty.intInfo(self.target).bits;
|
||||
|
||||
try self.emitWValue(operand);
|
||||
if (op_bits > 32 and wanted_bits <= 32) {
|
||||
try self.code.append(wasm.opcode(.i32_wrap_i64));
|
||||
} else if (op_bits <= 32 and wanted_bits > 32) {
|
||||
try self.code.append(wasm.opcode(switch (ref_info.signedness) {
|
||||
.signed => .i64_extend_i32_s,
|
||||
.unsigned => .i64_extend_i32_u,
|
||||
}));
|
||||
}
|
||||
|
||||
// other cases are no-op
|
||||
return .none;
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user