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 {...@@ -1329,6 +1329,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1329 .fptrunc => self.airFptrunc(inst),1329 .fptrunc => self.airFptrunc(inst),
1330 .fpext => self.airFpext(inst),1330 .fpext => self.airFpext(inst),
1331 .float_to_int => self.airFloatToInt(inst),1331 .float_to_int => self.airFloatToInt(inst),
1332 .int_to_float => self.airIntToFloat(inst),
1332 .get_union_tag => self.airGetUnionTag(inst),1333 .get_union_tag => self.airGetUnionTag(inst),
13331334
1334 // TODO1335 // TODO
...@@ -1382,6 +1383,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1382,6 +1383,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1382 .slice_elem_val => self.airSliceElemVal(inst),1383 .slice_elem_val => self.airSliceElemVal(inst),
1383 .slice_elem_ptr => self.airSliceElemPtr(inst),1384 .slice_elem_ptr => self.airSliceElemPtr(inst),
1384 .slice_ptr => self.airSlicePtr(inst),1385 .slice_ptr => self.airSlicePtr(inst),
1386 .ptr_slice_len_ptr => self.airPtrSliceFieldPtr(inst, self.ptrSize()),
1387 .ptr_slice_ptr_ptr => self.airPtrSliceFieldPtr(inst, 0),
1385 .store => self.airStore(inst),1388 .store => self.airStore(inst),
13861389
1387 .set_union_tag => self.airSetUnionTag(inst),1390 .set_union_tag => self.airSetUnionTag(inst),
...@@ -1398,8 +1401,10 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1398,8 +1401,10 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1398 .unreach => self.airUnreachable(inst),1401 .unreach => self.airUnreachable(inst),
13991402
1400 .wrap_optional => self.airWrapOptional(inst),1403 .wrap_optional => self.airWrapOptional(inst),
1401 .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst),1404 .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst, false),
1402 .unwrap_errunion_err => self.airUnwrapErrUnionError(inst),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),
1403 .wrap_errunion_payload => self.airWrapErrUnionPayload(inst),1408 .wrap_errunion_payload => self.airWrapErrUnionPayload(inst),
1404 .wrap_errunion_err => self.airWrapErrUnionErr(inst),1409 .wrap_errunion_err => self.airWrapErrUnionErr(inst),
1405 .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst),1410 .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst),
...@@ -1429,8 +1434,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1429,8 +1434,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1429 .bit_reverse,1434 .bit_reverse,
1430 .is_err_ptr,1435 .is_err_ptr,
1431 .is_non_err_ptr,1436 .is_non_err_ptr,
1432 .unwrap_errunion_payload_ptr,
1433 .unwrap_errunion_err_ptr,
14341437
1435 .sqrt,1438 .sqrt,
1436 .sin,1439 .sin,
...@@ -1446,9 +1449,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1446,9 +1449,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1446 .round,1449 .round,
1447 .trunc_float,1450 .trunc_float,
14481451
1449 .ptr_slice_len_ptr,
1450 .ptr_slice_ptr_ptr,
1451 .int_to_float,
1452 .cmpxchg_weak,1452 .cmpxchg_weak,
1453 .cmpxchg_strong,1453 .cmpxchg_strong,
1454 .fence,1454 .fence,
...@@ -2560,30 +2560,32 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W...@@ -2560,30 +2560,32 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W
2560 return is_err_tmp;2560 return is_err_tmp;
2561}2561}
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 {
2564 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };2564 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
2565 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2565 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2566 const operand = try self.resolveInst(ty_op.operand);2566 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;
2568 const payload_ty = err_ty.errorUnionPayload();2569 const payload_ty = err_ty.errorUnionPayload();
2569 if (!payload_ty.hasRuntimeBits()) return WValue{ .none = {} };2570 if (!payload_ty.hasRuntimeBits()) return WValue{ .none = {} };
2570 const err_align = err_ty.abiAlignment(self.target);2571 const err_align = err_ty.abiAlignment(self.target);
2571 const set_size = err_ty.errorUnionSet().abiSize(self.target);2572 const set_size = err_ty.errorUnionSet().abiSize(self.target);
2572 const offset = mem.alignForwardGeneric(u64, set_size, err_align);2573 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)) {
2574 return self.buildPointerOffset(operand, offset, .new);2575 return self.buildPointerOffset(operand, offset, .new);
2575 }2576 }
2576 return self.load(operand, payload_ty, @intCast(u32, offset));2577 return self.load(operand, payload_ty, @intCast(u32, offset));
2577}2578}
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 {
2580 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };2581 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
25812582
2582 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2583 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2583 const operand = try self.resolveInst(ty_op.operand);2584 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;
2585 const payload_ty = err_ty.errorUnionPayload();2587 const payload_ty = err_ty.errorUnionPayload();
2586 if (!payload_ty.hasRuntimeBits()) {2588 if (op_is_ptr or !payload_ty.hasRuntimeBits()) {
2587 return operand;2589 return operand;
2588 }2590 }
25892591
...@@ -3231,6 +3233,28 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3231,6 +3233,28 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3231 return result;3233 return result;
3232}3234}
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
3234fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {3258fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3235 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };3259 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
32363260
...@@ -3682,3 +3706,11 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3682,3 +3706,11 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3682 try self.addLabel(.local_set, result_ptr.local);3706 try self.addLabel(.local_set, result_ptr.local);
3683 return result_ptr;3707 return result_ptr;
3684}3708}
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 {...@@ -203,6 +203,14 @@ pub fn emitMir(emit: *Emit) InnerError!void {
203 .i64_trunc_f32_u => try emit.emitTag(tag),203 .i64_trunc_f32_u => try emit.emitTag(tag),
204 .i64_trunc_f64_s => try emit.emitTag(tag),204 .i64_trunc_f64_s => try emit.emitTag(tag),
205 .i64_trunc_f64_u => try emit.emitTag(tag),205 .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),
206 .i32_rem_s => try emit.emitTag(tag),214 .i32_rem_s => try emit.emitTag(tag),
207 .i32_rem_u => try emit.emitTag(tag),215 .i32_rem_u => try emit.emitTag(tag),
208 .i64_rem_s => try emit.emitTag(tag),216 .i64_rem_s => try emit.emitTag(tag),
src/arch/wasm/Mir.zig+16
...@@ -451,8 +451,24 @@ pub const Inst = struct {...@@ -451,8 +451,24 @@ pub const Inst = struct {
451 /// Uses `tag`451 /// Uses `tag`
452 i64_trunc_f64_u = 0xB1,452 i64_trunc_f64_u = 0xB1,
453 /// Uses `tag`453 /// 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`
454 f32_demote_f64 = 0xB6,462 f32_demote_f64 = 0xB6,
455 /// Uses `tag`463 /// 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`
456 f64_promote_f32 = 0xBB,472 f64_promote_f32 = 0xBB,
457 /// Uses `tag`473 /// Uses `tag`
458 i32_reinterpret_f32 = 0xBC,474 i32_reinterpret_f32 = 0xBC,