authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-03-23 20:42:11+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-03-23 21:40:33+01:00
log60676a0ba50ece8363883bdbaa803f31d8284c8c
treea2eb7c44d0b505967895eba446ee79a928f71624
parent685f05b562b1e5d001ae2da23485c03b704d19f6
signature Commit is signed but in an unrecognized format.

wasm: Implement more instructions

Implements the following instructions: - int_to_float - ptr_slice_len_ptr - ptr_slice_ptr_ptr - unwrap_errunion_payload_ptr - unwrap_errunion_err_ptr

3 files changed, 69 insertions(+), 13 deletions(-)

src/arch/wasm/CodeGen.zig+45-13
......@@ -1329,6 +1329,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
13291329 .fptrunc => self.airFptrunc(inst),
13301330 .fpext => self.airFpext(inst),
13311331 .float_to_int => self.airFloatToInt(inst),
1332 .int_to_float => self.airIntToFloat(inst),
13321333 .get_union_tag => self.airGetUnionTag(inst),
13331334
13341335 // TODO
......@@ -1382,6 +1383,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
13821383 .slice_elem_val => self.airSliceElemVal(inst),
13831384 .slice_elem_ptr => self.airSliceElemPtr(inst),
13841385 .slice_ptr => self.airSlicePtr(inst),
1386 .ptr_slice_len_ptr => self.airPtrSliceFieldPtr(inst, self.ptrSize()),
1387 .ptr_slice_ptr_ptr => self.airPtrSliceFieldPtr(inst, 0),
13851388 .store => self.airStore(inst),
13861389
13871390 .set_union_tag => self.airSetUnionTag(inst),
......@@ -1398,8 +1401,10 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
13981401 .unreach => self.airUnreachable(inst),
13991402
14001403 .wrap_optional => self.airWrapOptional(inst),
1401 .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst),
1402 .unwrap_errunion_err => self.airUnwrapErrUnionError(inst),
1404 .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst, false),
1405 .unwrap_errunion_payload_ptr => self.airUnwrapErrUnionPayload(inst, true),
1406 .unwrap_errunion_err => self.airUnwrapErrUnionError(inst, false),
1407 .unwrap_errunion_err_ptr => self.airUnwrapErrUnionError(inst, true),
14031408 .wrap_errunion_payload => self.airWrapErrUnionPayload(inst),
14041409 .wrap_errunion_err => self.airWrapErrUnionErr(inst),
14051410 .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst),
......@@ -1429,8 +1434,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
14291434 .bit_reverse,
14301435 .is_err_ptr,
14311436 .is_non_err_ptr,
1432 .unwrap_errunion_payload_ptr,
1433 .unwrap_errunion_err_ptr,
14341437
14351438 .sqrt,
14361439 .sin,
......@@ -1446,9 +1449,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
14461449 .round,
14471450 .trunc_float,
14481451
1449 .ptr_slice_len_ptr,
1450 .ptr_slice_ptr_ptr,
1451 .int_to_float,
14521452 .cmpxchg_weak,
14531453 .cmpxchg_strong,
14541454 .fence,
......@@ -2560,30 +2560,32 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W
25602560 return is_err_tmp;
25612561}
25622562
2563fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2563fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!WValue {
25642564 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
25652565 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
25662566 const operand = try self.resolveInst(ty_op.operand);
2567 const err_ty = self.air.typeOf(ty_op.operand);
2567 const op_ty = self.air.typeOf(ty_op.operand);
2568 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
25682569 const payload_ty = err_ty.errorUnionPayload();
25692570 if (!payload_ty.hasRuntimeBits()) return WValue{ .none = {} };
25702571 const err_align = err_ty.abiAlignment(self.target);
25712572 const set_size = err_ty.errorUnionSet().abiSize(self.target);
25722573 const offset = mem.alignForwardGeneric(u64, set_size, err_align);
2573 if (isByRef(payload_ty, self.target)) {
2574 if (op_is_ptr or isByRef(payload_ty, self.target)) {
25742575 return self.buildPointerOffset(operand, offset, .new);
25752576 }
25762577 return self.load(operand, payload_ty, @intCast(u32, offset));
25772578}
25782579
2579fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2580fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!WValue {
25802581 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
25812582
25822583 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
25832584 const operand = try self.resolveInst(ty_op.operand);
2584 const err_ty = self.air.typeOf(ty_op.operand);
2585 const op_ty = self.air.typeOf(ty_op.operand);
2586 const err_ty = if (op_is_ptr) op_ty.childType() else op_ty;
25852587 const payload_ty = err_ty.errorUnionPayload();
2586 if (!payload_ty.hasRuntimeBits()) {
2588 if (op_is_ptr or !payload_ty.hasRuntimeBits()) {
25872589 return operand;
25882590 }
25892591
......@@ -3231,6 +3233,28 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
32313233 return result;
32323234}
32333235
3236fn airIntToFloat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3237 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
3238
3239 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3240 const operand = try self.resolveInst(ty_op.operand);
3241 const dest_ty = self.air.typeOfIndex(inst);
3242 const op_ty = self.air.typeOf(ty_op.operand);
3243
3244 try self.emitWValue(operand);
3245 const op = buildOpcode(.{
3246 .op = .convert,
3247 .valtype1 = typeToValtype(dest_ty, self.target),
3248 .valtype2 = typeToValtype(op_ty, self.target),
3249 .signedness = if (op_ty.isSignedInt()) .signed else .unsigned,
3250 });
3251 try self.addTag(Mir.Inst.Tag.fromOpcode(op));
3252
3253 const result = try self.allocLocal(dest_ty);
3254 try self.addLabel(.local_set, result.local);
3255 return result;
3256}
3257
32343258fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
32353259 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
32363260
......@@ -3682,3 +3706,11 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
36823706 try self.addLabel(.local_set, result_ptr.local);
36833707 return result_ptr;
36843708}
3709
3710fn airPtrSliceFieldPtr(self: *Self, inst: Air.Inst.Index, offset: u32) InnerError!WValue {
3711 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
3712
3713 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3714 const slice_ptr = try self.resolveInst(ty_op.operand);
3715 return self.buildPointerOffset(slice_ptr, offset, .new);
3716}
src/arch/wasm/Emit.zig+8
......@@ -203,6 +203,14 @@ pub fn emitMir(emit: *Emit) InnerError!void {
203203 .i64_trunc_f32_u => try emit.emitTag(tag),
204204 .i64_trunc_f64_s => try emit.emitTag(tag),
205205 .i64_trunc_f64_u => try emit.emitTag(tag),
206 .f32_convert_i32_s => try emit.emitTag(tag),
207 .f32_convert_i32_u => try emit.emitTag(tag),
208 .f32_convert_i64_s => try emit.emitTag(tag),
209 .f32_convert_i64_u => try emit.emitTag(tag),
210 .f64_convert_i32_s => try emit.emitTag(tag),
211 .f64_convert_i32_u => try emit.emitTag(tag),
212 .f64_convert_i64_s => try emit.emitTag(tag),
213 .f64_convert_i64_u => try emit.emitTag(tag),
206214 .i32_rem_s => try emit.emitTag(tag),
207215 .i32_rem_u => try emit.emitTag(tag),
208216 .i64_rem_s => try emit.emitTag(tag),
src/arch/wasm/Mir.zig+16
......@@ -451,8 +451,24 @@ pub const Inst = struct {
451451 /// Uses `tag`
452452 i64_trunc_f64_u = 0xB1,
453453 /// Uses `tag`
454 f32_convert_i32_s = 0xB2,
455 /// Uses `tag`
456 f32_convert_i32_u = 0xB3,
457 /// Uses `tag`
458 f32_convert_i64_s = 0xB4,
459 /// Uses `tag`
460 f32_convert_i64_u = 0xB5,
461 /// Uses `tag`
454462 f32_demote_f64 = 0xB6,
455463 /// Uses `tag`
464 f64_convert_i32_s = 0xB7,
465 /// Uses `tag`
466 f64_convert_i32_u = 0xB8,
467 /// Uses `tag`
468 f64_convert_i64_s = 0xB9,
469 /// Uses `tag`
470 f64_convert_i64_u = 0xBA,
471 /// Uses `tag`
456472 f64_promote_f32 = 0xBB,
457473 /// Uses `tag`
458474 i32_reinterpret_f32 = 0xBC,