Skip to content

Commit ce7c743

Browse files
authored
Update wasmi_ir2 crate (#1656)
* fix codegen for v128.splat operators * remove unused identifier * fix identifier of I64MulWide operator * update call operator fields * fix snake case bit{and,or,xor} operator identifiers * apply rustfmt * add missing store instruction variants * add Encoder::block_fuel trait method and adjust impl
1 parent 774995b commit ce7c743

File tree

5 files changed

+91
-51
lines changed

5 files changed

+91
-51
lines changed

crates/ir2/build/ident.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ define_ident!(
125125
NotLt: not_lt,
126126
NotLe: not_le,
127127

128-
BitAnd: bit_and,
129-
BitOr: bit_or,
130-
BitXor: bit_xor,
128+
BitAnd: bitand,
129+
BitOr: bitor,
130+
BitXor: bitxor,
131131

132132
Branch: branch,
133133
BranchTable: branch_table,
@@ -209,6 +209,7 @@ define_ident!(
209209
Value: value,
210210
Result: result,
211211
Results: results,
212+
Params: params,
212213
Len: len,
213214
LenTargets: len_targets,
214215
LenValues: len_values,
@@ -244,7 +245,7 @@ define_ident!(
244245

245246
I64Add128: i64_add128,
246247
I64Sub128: i64_sub128,
247-
S64MulWide: s64_mul_wide,
248+
I64MulWide: i64_mul_wide,
248249
U64MulWide: u64_mul_wide,
249250

250251
Lhs: lhs,
@@ -264,7 +265,10 @@ define_ident!(
264265

265266
V128: v128,
266267
Lane: lane,
267-
Splat: splat,
268+
Splat8: splat8,
269+
Splat16: splat16,
270+
Splat32: splat32,
271+
Splat64: splat64,
268272
S8x16ExtractLane: s8x16_extract_lane,
269273
U8x16ExtractLane: u8x16_extract_lane,
270274
S16x8ExtractLane: s16x8_extract_lane,

crates/ir2/build/isa.rs

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -373,41 +373,12 @@ fn add_store_ops(isa: &mut Isa) {
373373
StoreOpKind::I64Store32,
374374
];
375375
for op in ops {
376-
isa.push_op(StoreOp::new(
377-
op,
378-
OperandKind::Slot,
379-
OperandKind::Slot,
380-
false,
381-
false,
382-
));
383-
isa.push_op(StoreOp::new(
384-
op,
385-
OperandKind::Slot,
386-
OperandKind::Immediate,
387-
false,
388-
false,
389-
));
390-
isa.push_op(StoreOp::new(
391-
op,
392-
OperandKind::Immediate,
393-
OperandKind::Slot,
394-
false,
395-
false,
396-
));
397-
isa.push_op(StoreOp::new(
398-
op,
399-
OperandKind::Slot,
400-
OperandKind::Slot,
401-
true,
402-
true,
403-
));
404-
isa.push_op(StoreOp::new(
405-
op,
406-
OperandKind::Slot,
407-
OperandKind::Immediate,
408-
true,
409-
true,
410-
));
376+
for value in [OperandKind::Slot, OperandKind::Immediate] {
377+
for ptr in [OperandKind::Slot, OperandKind::Immediate] {
378+
isa.push_op(StoreOp::new(op, ptr, value, false, false));
379+
}
380+
isa.push_op(StoreOp::new(op, OperandKind::Slot, value, true, true));
381+
}
411382
}
412383
}
413384

@@ -509,37 +480,44 @@ fn add_call_ops(isa: &mut Isa) {
509480
Op::from(GenericOp::new(
510481
Ident::CallInternal,
511482
[
512-
Field::new(Ident::Results, FieldTy::SlotSpan),
483+
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
513484
Field::new(Ident::Func, FieldTy::InternalFunc),
514485
],
515486
)),
516487
Op::from(GenericOp::new(
517488
Ident::CallImported,
518489
[
519-
Field::new(Ident::Results, FieldTy::SlotSpan),
490+
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
520491
Field::new(Ident::Func, FieldTy::Func),
521492
],
522493
)),
523494
Op::from(GenericOp::new(
524495
Ident::CallIndirect,
525496
[
526-
Field::new(Ident::Results, FieldTy::SlotSpan),
497+
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
527498
Field::new(Ident::Index, FieldTy::Slot),
528499
Field::new(Ident::FuncType, FieldTy::FuncType),
529500
Field::new(Ident::Table, FieldTy::Table),
530501
],
531502
)),
532503
Op::from(GenericOp::new(
533504
Ident::ReturnCallInternal,
534-
[Field::new(Ident::Func, FieldTy::InternalFunc)],
505+
[
506+
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
507+
Field::new(Ident::Func, FieldTy::InternalFunc),
508+
],
535509
)),
536510
Op::from(GenericOp::new(
537511
Ident::ReturnCallImported,
538-
[Field::new(Ident::Func, FieldTy::Func)],
512+
[
513+
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
514+
Field::new(Ident::Func, FieldTy::Func),
515+
],
539516
)),
540517
Op::from(GenericOp::new(
541518
Ident::ReturnCallIndirect,
542519
[
520+
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
543521
Field::new(Ident::Index, FieldTy::Slot),
544522
Field::new(Ident::FuncType, FieldTy::FuncType),
545523
Field::new(Ident::Table, FieldTy::Table),
@@ -724,7 +702,7 @@ fn add_wide_arithmetic_ops(isa: &mut Isa) {
724702
],
725703
)),
726704
Op::from(GenericOp::new(
727-
Ident::S64MulWide,
705+
Ident::I64MulWide,
728706
[
729707
Field::new(Ident::Results, FieldTy::FixedSlotSpan2),
730708
Field::new(Ident::Lhs, FieldTy::Slot),
@@ -776,7 +754,12 @@ fn add_simd_ops(isa: &mut Isa, config: &Config) {
776754
}
777755

778756
fn add_simd_splat_ops(isa: &mut Isa) {
779-
let kinds = [UnaryOpKind::V128Splat32, UnaryOpKind::V128Splat64];
757+
let kinds = [
758+
UnaryOpKind::V128Splat8,
759+
UnaryOpKind::V128Splat16,
760+
UnaryOpKind::V128Splat32,
761+
UnaryOpKind::V128Splat64,
762+
];
780763
for kind in kinds {
781764
isa.push_op(UnaryOp::new(kind, OperandKind::Slot));
782765
isa.push_op(UnaryOp::new(kind, OperandKind::Immediate));

crates/ir2/build/op.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ pub enum UnaryOpKind {
214214
F64ConvertU64,
215215

216216
// SIMD: Generic Unary Ops
217+
V128Splat8,
218+
V128Splat16,
217219
V128Splat32,
218220
V128Splat64,
219221
V128Not,
@@ -287,6 +289,8 @@ pub enum UnaryOpKind {
287289
impl UnaryOpKind {
288290
pub fn is_conversion(&self) -> bool {
289291
self.value_ty() != self.result_ty()
292+
&& self.value_ty().is_wasm()
293+
&& self.result_ty().is_wasm()
290294
}
291295

292296
pub fn value_ty(&self) -> Ty {
@@ -328,6 +332,8 @@ impl UnaryOpKind {
328332
| Self::F64ConvertU64 => Ty::U64,
329333

330334
// SIMD: Generic Unary Ops
335+
| Self::V128Splat8 => Ty::B8,
336+
| Self::V128Splat16 => Ty::B16,
331337
| Self::V128Splat32 => Ty::B32,
332338
| Self::V128Splat64 => Ty::B64,
333339
| Self::V128Not | Self::V128AnyTrue => Ty::V128,
@@ -435,7 +441,12 @@ impl UnaryOpKind {
435441
| Self::F64ConvertU64 => Ty::F64,
436442

437443
// SIMD: Generic Unary Ops
438-
| Self::V128Splat32 | Self::V128Splat64 | Self::V128Not | Self::V128AnyTrue => Ty::V128,
444+
| Self::V128Splat8
445+
| Self::V128Splat16
446+
| Self::V128Splat32
447+
| Self::V128Splat64
448+
| Self::V128Not
449+
| Self::V128AnyTrue => Ty::V128,
439450
// SIMD: `i8x16` Unary Ops
440451
| Self::I8x16Abs
441452
| Self::I8x16Neg
@@ -551,8 +562,10 @@ impl UnaryOpKind {
551562
Self::F64ConvertU64 => Ident::Convert,
552563

553564
// SIMD: Generic Unary Ops
554-
Self::V128Splat32 => Ident::Splat,
555-
Self::V128Splat64 => Ident::Splat,
565+
Self::V128Splat8 => Ident::Splat8,
566+
Self::V128Splat16 => Ident::Splat16,
567+
Self::V128Splat32 => Ident::Splat32,
568+
Self::V128Splat64 => Ident::Splat64,
556569
Self::V128Not => Ident::Not,
557570
Self::V128AnyTrue => Ident::AnyTrue,
558571
// SIMD: `i8x16` Unary Ops
@@ -1384,6 +1397,10 @@ pub enum Ty {
13841397
U32,
13851398
/// A unsigned 64-bit integer type.
13861399
U64,
1400+
/// A generic 8-bits value.
1401+
B8,
1402+
/// A generic 16-bits value.
1403+
B16,
13871404
/// A generic 32-bits value.
13881405
B32,
13891406
/// A generic 64-bits value.
@@ -1425,8 +1442,14 @@ pub enum Ty {
14251442
}
14261443

14271444
impl Ty {
1445+
pub fn is_wasm(&self) -> bool {
1446+
!matches!(self, Self::B8 | Self::B16 | Self::B32 | Self::B64)
1447+
}
1448+
14281449
pub fn to_field_ty(self) -> Option<FieldTy> {
14291450
let ty = match self {
1451+
| Ty::B8 => FieldTy::U8,
1452+
| Ty::B16 => FieldTy::U16,
14301453
| Ty::S32 | Ty::I32 => FieldTy::I32,
14311454
| Ty::S64 | Ty::I64 => FieldTy::I64,
14321455
| Ty::B32 | Ty::U32 => FieldTy::U32,
@@ -1448,6 +1471,8 @@ impl Display for Ty {
14481471
Ty::S64 => "i64",
14491472
Ty::U32 => "u32",
14501473
Ty::U64 => "u64",
1474+
Ty::B8 => "8",
1475+
Ty::B16 => "16",
14511476
Ty::B32 => "32",
14521477
Ty::B64 => "64",
14531478
Ty::F32 => "f32",
@@ -1487,6 +1512,8 @@ impl Display for CamelCase<Ty> {
14871512
Ty::S64 => "I64",
14881513
Ty::U32 => "U32",
14891514
Ty::U64 => "U64",
1515+
Ty::B8 => "8",
1516+
Ty::B16 => "16",
14901517
Ty::B32 => "32",
14911518
Ty::B64 => "64",
14921519
Ty::F32 => "F32",
@@ -1515,6 +1542,7 @@ impl Display for CamelCase<Ty> {
15151542
pub enum FieldTy {
15161543
Slot,
15171544
SlotSpan,
1545+
BoundedSlotSpan,
15181546
FixedSlotSpan2,
15191547
U8,
15201548
U16,
@@ -1557,6 +1585,7 @@ impl Display for FieldTy {
15571585
let s = match self {
15581586
Self::Slot => "Slot",
15591587
Self::SlotSpan => "SlotSpan",
1588+
Self::BoundedSlotSpan => "BoundedSlotSpan",
15601589
Self::FixedSlotSpan2 => "FixedSlotSpan<2>",
15611590
Self::U8 => "u8",
15621591
Self::U16 => "u16",

crates/ir2/src/encode.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ pub trait Encoder {
4242

4343
/// Registers an encoded [`BranchOffset`] to the encoder.
4444
///
45+
/// This is required in order to update the branch offsets of
46+
/// branch operators once all forward branch offsets are known.
47+
///
4548
/// # Errors
4649
///
4750
/// If the encoder cannot register the `branch_offset`.
@@ -50,6 +53,16 @@ pub trait Encoder {
5053
pos: Self::Pos,
5154
branch_offset: BranchOffset,
5255
) -> Result<(), Self::Error>;
56+
57+
/// Registers an encoded [`BlockFuel`] to the encoder.
58+
///
59+
/// This is required in order to update the consumed fuel of
60+
/// [`Op::ConsumeFuel`] operators during translation.
61+
///
62+
/// # Errors
63+
///
64+
/// If the encoder cannot register the `block_fuel`.
65+
fn block_fuel(&mut self, pos: Self::Pos, block_fuel: BlockFuel) -> Result<(), Self::Error>;
5366
}
5467

5568
/// Types that can be encoded by types that implement [`Encoder`].
@@ -80,6 +93,17 @@ impl Encode for BranchOffset {
8093
}
8194
}
8295

96+
impl Encode for BlockFuel {
97+
fn encode<E>(&self, encoder: &mut E) -> Result<E::Pos, E::Error>
98+
where
99+
E: Encoder,
100+
{
101+
let pos = u64::from(*self).encode(encoder)?;
102+
encoder.block_fuel(pos, *self)?;
103+
Ok(pos)
104+
}
105+
}
106+
83107
impl Encode for BoundedSlotSpan {
84108
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<E::Pos, E::Error> {
85109
(self.span(), self.len()).encode(encoder)
@@ -128,7 +152,6 @@ macro_rules! impl_encode_using {
128152
impl_encode_using! {
129153
bool as u8 = Into::into,
130154
Offset16 as u16 = Into::into,
131-
BlockFuel as u64 = Into::into,
132155
Address as u64 = Into::into,
133156
Slot as u16 = Into::into,
134157
Func as u32 = Into::into,

crates/ir2/src/op.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
index::{Data, Elem, Func, FuncType, Global, InternalFunc, Memory, Table},
66
Address,
77
BlockFuel,
8+
BoundedSlotSpan,
89
BranchOffset,
910
FixedSlotSpan,
1011
Offset16,

0 commit comments

Comments
 (0)