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:
Luuk de Gram 2021-07-30 20:35:30 +02:00
parent 5589edf45c
commit 5667ab7dcd
No known key found for this signature in database
GPG Key ID: A8CFE58E4DC7D664
2 changed files with 36 additions and 3 deletions

View File

@ -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,

View File

@ -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;
}
};