Skip to content

Commit bef9c4a

Browse files
WasmGen: Add "unary" category
1 parent 80581d8 commit bef9c4a

File tree

6 files changed

+175
-374
lines changed

6 files changed

+175
-374
lines changed

Sources/WAT/InstructionEncoder.swift

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,38 @@ extension InstructionEncoder {
212212
try encodeInstruction(opcode, prefix)
213213
}
214214
mutating func visitI64Eqz() throws { try encodeInstruction(0x50, nil) }
215-
mutating func visitI32Clz() throws { try encodeInstruction(0x67, nil) }
216-
mutating func visitI32Ctz() throws { try encodeInstruction(0x68, nil) }
217-
mutating func visitI32Popcnt() throws { try encodeInstruction(0x69, nil) }
215+
mutating func visitUnary(_ unary: Instruction.Unary) throws {
216+
let (prefix, opcode): (UInt8?, UInt8)
217+
switch unary {
218+
case .i32Clz: (prefix, opcode) = (nil, 0x67)
219+
case .i32Ctz: (prefix, opcode) = (nil, 0x68)
220+
case .i32Popcnt: (prefix, opcode) = (nil, 0x69)
221+
case .i64Clz: (prefix, opcode) = (nil, 0x79)
222+
case .i64Ctz: (prefix, opcode) = (nil, 0x7A)
223+
case .i64Popcnt: (prefix, opcode) = (nil, 0x7B)
224+
case .f32Abs: (prefix, opcode) = (nil, 0x8B)
225+
case .f32Neg: (prefix, opcode) = (nil, 0x8C)
226+
case .f32Ceil: (prefix, opcode) = (nil, 0x8D)
227+
case .f32Floor: (prefix, opcode) = (nil, 0x8E)
228+
case .f32Trunc: (prefix, opcode) = (nil, 0x8F)
229+
case .f32Nearest: (prefix, opcode) = (nil, 0x90)
230+
case .f32Sqrt: (prefix, opcode) = (nil, 0x91)
231+
case .f64Abs: (prefix, opcode) = (nil, 0x99)
232+
case .f64Neg: (prefix, opcode) = (nil, 0x9A)
233+
case .f64Ceil: (prefix, opcode) = (nil, 0x9B)
234+
case .f64Floor: (prefix, opcode) = (nil, 0x9C)
235+
case .f64Trunc: (prefix, opcode) = (nil, 0x9D)
236+
case .f64Nearest: (prefix, opcode) = (nil, 0x9E)
237+
case .f64Sqrt: (prefix, opcode) = (nil, 0x9F)
238+
case .i32Extend8S: (prefix, opcode) = (nil, 0xC0)
239+
case .i32Extend16S: (prefix, opcode) = (nil, 0xC1)
240+
case .i64Extend8S: (prefix, opcode) = (nil, 0xC2)
241+
case .i64Extend16S: (prefix, opcode) = (nil, 0xC3)
242+
case .i64Extend32S: (prefix, opcode) = (nil, 0xC4)
243+
}
244+
245+
try encodeInstruction(opcode, prefix)
246+
}
218247
mutating func visitBinary(_ binary: Instruction.Binary) throws {
219248
let (prefix, opcode): (UInt8?, UInt8)
220249
switch binary {
@@ -266,23 +295,6 @@ extension InstructionEncoder {
266295

267296
try encodeInstruction(opcode, prefix)
268297
}
269-
mutating func visitI64Clz() throws { try encodeInstruction(0x79, nil) }
270-
mutating func visitI64Ctz() throws { try encodeInstruction(0x7A, nil) }
271-
mutating func visitI64Popcnt() throws { try encodeInstruction(0x7B, nil) }
272-
mutating func visitF32Abs() throws { try encodeInstruction(0x8B, nil) }
273-
mutating func visitF32Neg() throws { try encodeInstruction(0x8C, nil) }
274-
mutating func visitF32Ceil() throws { try encodeInstruction(0x8D, nil) }
275-
mutating func visitF32Floor() throws { try encodeInstruction(0x8E, nil) }
276-
mutating func visitF32Trunc() throws { try encodeInstruction(0x8F, nil) }
277-
mutating func visitF32Nearest() throws { try encodeInstruction(0x90, nil) }
278-
mutating func visitF32Sqrt() throws { try encodeInstruction(0x91, nil) }
279-
mutating func visitF64Abs() throws { try encodeInstruction(0x99, nil) }
280-
mutating func visitF64Neg() throws { try encodeInstruction(0x9A, nil) }
281-
mutating func visitF64Ceil() throws { try encodeInstruction(0x9B, nil) }
282-
mutating func visitF64Floor() throws { try encodeInstruction(0x9C, nil) }
283-
mutating func visitF64Trunc() throws { try encodeInstruction(0x9D, nil) }
284-
mutating func visitF64Nearest() throws { try encodeInstruction(0x9E, nil) }
285-
mutating func visitF64Sqrt() throws { try encodeInstruction(0x9F, nil) }
286298
mutating func visitI32WrapI64() throws { try encodeInstruction(0xA7, nil) }
287299
mutating func visitI32TruncF32S() throws { try encodeInstruction(0xA8, nil) }
288300
mutating func visitI32TruncF32U() throws { try encodeInstruction(0xA9, nil) }
@@ -308,11 +320,6 @@ extension InstructionEncoder {
308320
mutating func visitI64ReinterpretF64() throws { try encodeInstruction(0xBD, nil) }
309321
mutating func visitF32ReinterpretI32() throws { try encodeInstruction(0xBE, nil) }
310322
mutating func visitF64ReinterpretI64() throws { try encodeInstruction(0xBF, nil) }
311-
mutating func visitI32Extend8S() throws { try encodeInstruction(0xC0, nil) }
312-
mutating func visitI32Extend16S() throws { try encodeInstruction(0xC1, nil) }
313-
mutating func visitI64Extend8S() throws { try encodeInstruction(0xC2, nil) }
314-
mutating func visitI64Extend16S() throws { try encodeInstruction(0xC3, nil) }
315-
mutating func visitI64Extend32S() throws { try encodeInstruction(0xC4, nil) }
316323
mutating func visitMemoryInit(dataIndex: UInt32) throws {
317324
try encodeInstruction(0x08, 0xFC)
318325
try encodeImmediates(dataIndex: dataIndex)

Sources/WAT/ParseInstruction.swift

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,9 @@ func parseTextInstruction<V: InstructionVisitor>(keyword: String, expressionPars
188188
case "f64.gt": return { return try $0.visitCmp(.f64Gt) }
189189
case "f64.le": return { return try $0.visitCmp(.f64Le) }
190190
case "f64.ge": return { return try $0.visitCmp(.f64Ge) }
191-
case "i32.clz": return { return try $0.visitI32Clz() }
192-
case "i32.ctz": return { return try $0.visitI32Ctz() }
193-
case "i32.popcnt": return { return try $0.visitI32Popcnt() }
191+
case "i32.clz": return { return try $0.visitUnary(.i32Clz) }
192+
case "i32.ctz": return { return try $0.visitUnary(.i32Ctz) }
193+
case "i32.popcnt": return { return try $0.visitUnary(.i32Popcnt) }
194194
case "i32.add": return { return try $0.visitBinary(.i32Add) }
195195
case "i32.sub": return { return try $0.visitBinary(.i32Sub) }
196196
case "i32.mul": return { return try $0.visitBinary(.i32Mul) }
@@ -206,9 +206,9 @@ func parseTextInstruction<V: InstructionVisitor>(keyword: String, expressionPars
206206
case "i32.shr_u": return { return try $0.visitBinary(.i32ShrU) }
207207
case "i32.rotl": return { return try $0.visitBinary(.i32Rotl) }
208208
case "i32.rotr": return { return try $0.visitBinary(.i32Rotr) }
209-
case "i64.clz": return { return try $0.visitI64Clz() }
210-
case "i64.ctz": return { return try $0.visitI64Ctz() }
211-
case "i64.popcnt": return { return try $0.visitI64Popcnt() }
209+
case "i64.clz": return { return try $0.visitUnary(.i64Clz) }
210+
case "i64.ctz": return { return try $0.visitUnary(.i64Ctz) }
211+
case "i64.popcnt": return { return try $0.visitUnary(.i64Popcnt) }
212212
case "i64.add": return { return try $0.visitBinary(.i64Add) }
213213
case "i64.sub": return { return try $0.visitBinary(.i64Sub) }
214214
case "i64.mul": return { return try $0.visitBinary(.i64Mul) }
@@ -224,27 +224,27 @@ func parseTextInstruction<V: InstructionVisitor>(keyword: String, expressionPars
224224
case "i64.shr_u": return { return try $0.visitBinary(.i64ShrU) }
225225
case "i64.rotl": return { return try $0.visitBinary(.i64Rotl) }
226226
case "i64.rotr": return { return try $0.visitBinary(.i64Rotr) }
227-
case "f32.abs": return { return try $0.visitF32Abs() }
228-
case "f32.neg": return { return try $0.visitF32Neg() }
229-
case "f32.ceil": return { return try $0.visitF32Ceil() }
230-
case "f32.floor": return { return try $0.visitF32Floor() }
231-
case "f32.trunc": return { return try $0.visitF32Trunc() }
232-
case "f32.nearest": return { return try $0.visitF32Nearest() }
233-
case "f32.sqrt": return { return try $0.visitF32Sqrt() }
227+
case "f32.abs": return { return try $0.visitUnary(.f32Abs) }
228+
case "f32.neg": return { return try $0.visitUnary(.f32Neg) }
229+
case "f32.ceil": return { return try $0.visitUnary(.f32Ceil) }
230+
case "f32.floor": return { return try $0.visitUnary(.f32Floor) }
231+
case "f32.trunc": return { return try $0.visitUnary(.f32Trunc) }
232+
case "f32.nearest": return { return try $0.visitUnary(.f32Nearest) }
233+
case "f32.sqrt": return { return try $0.visitUnary(.f32Sqrt) }
234234
case "f32.add": return { return try $0.visitBinary(.f32Add) }
235235
case "f32.sub": return { return try $0.visitBinary(.f32Sub) }
236236
case "f32.mul": return { return try $0.visitBinary(.f32Mul) }
237237
case "f32.div": return { return try $0.visitBinary(.f32Div) }
238238
case "f32.min": return { return try $0.visitBinary(.f32Min) }
239239
case "f32.max": return { return try $0.visitBinary(.f32Max) }
240240
case "f32.copysign": return { return try $0.visitBinary(.f32Copysign) }
241-
case "f64.abs": return { return try $0.visitF64Abs() }
242-
case "f64.neg": return { return try $0.visitF64Neg() }
243-
case "f64.ceil": return { return try $0.visitF64Ceil() }
244-
case "f64.floor": return { return try $0.visitF64Floor() }
245-
case "f64.trunc": return { return try $0.visitF64Trunc() }
246-
case "f64.nearest": return { return try $0.visitF64Nearest() }
247-
case "f64.sqrt": return { return try $0.visitF64Sqrt() }
241+
case "f64.abs": return { return try $0.visitUnary(.f64Abs) }
242+
case "f64.neg": return { return try $0.visitUnary(.f64Neg) }
243+
case "f64.ceil": return { return try $0.visitUnary(.f64Ceil) }
244+
case "f64.floor": return { return try $0.visitUnary(.f64Floor) }
245+
case "f64.trunc": return { return try $0.visitUnary(.f64Trunc) }
246+
case "f64.nearest": return { return try $0.visitUnary(.f64Nearest) }
247+
case "f64.sqrt": return { return try $0.visitUnary(.f64Sqrt) }
248248
case "f64.add": return { return try $0.visitBinary(.f64Add) }
249249
case "f64.sub": return { return try $0.visitBinary(.f64Sub) }
250250
case "f64.mul": return { return try $0.visitBinary(.f64Mul) }
@@ -277,11 +277,11 @@ func parseTextInstruction<V: InstructionVisitor>(keyword: String, expressionPars
277277
case "i64.reinterpret_f64": return { return try $0.visitI64ReinterpretF64() }
278278
case "f32.reinterpret_i32": return { return try $0.visitF32ReinterpretI32() }
279279
case "f64.reinterpret_i64": return { return try $0.visitF64ReinterpretI64() }
280-
case "i32.extend8_s": return { return try $0.visitI32Extend8S() }
281-
case "i32.extend16_s": return { return try $0.visitI32Extend16S() }
282-
case "i64.extend8_s": return { return try $0.visitI64Extend8S() }
283-
case "i64.extend16_s": return { return try $0.visitI64Extend16S() }
284-
case "i64.extend32_s": return { return try $0.visitI64Extend32S() }
280+
case "i32.extend8_s": return { return try $0.visitUnary(.i32Extend8S) }
281+
case "i32.extend16_s": return { return try $0.visitUnary(.i32Extend16S) }
282+
case "i64.extend8_s": return { return try $0.visitUnary(.i64Extend8S) }
283+
case "i64.extend16_s": return { return try $0.visitUnary(.i64Extend16S) }
284+
case "i64.extend32_s": return { return try $0.visitUnary(.i64Extend32S) }
285285
case "memory.init":
286286
let (dataIndex) = try expressionParser.visitMemoryInit(wat: &wat)
287287
return { return try $0.visitMemoryInit(dataIndex: dataIndex) }

Sources/WasmKit/Translator.swift

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,26 +1952,37 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
19521952
.i64Eqz(Instruction.UnaryOperand(result: LVReg(result), input: LVReg(value)))
19531953
}
19541954
}
1955-
mutating func visitI32Clz() throws -> Output { try visitUnary(.i32, Instruction.i32Clz) }
1956-
mutating func visitI32Ctz() throws -> Output { try visitUnary(.i32, Instruction.i32Ctz) }
1957-
mutating func visitI32Popcnt() throws -> Output { try visitUnary(.i32, Instruction.i32Popcnt) }
1958-
mutating func visitI64Clz() throws -> Output { try visitUnary(.i64, Instruction.i64Clz) }
1959-
mutating func visitI64Ctz() throws -> Output { try visitUnary(.i64, Instruction.i64Ctz) }
1960-
mutating func visitI64Popcnt() throws -> Output { try visitUnary(.i64, Instruction.i64Popcnt) }
1961-
mutating func visitF32Abs() throws -> Output { try visitUnary(.f32, Instruction.f32Abs) }
1962-
mutating func visitF32Neg() throws -> Output { try visitUnary(.f32, Instruction.f32Neg) }
1963-
mutating func visitF32Ceil() throws -> Output { try visitUnary(.f32, Instruction.f32Ceil) }
1964-
mutating func visitF32Floor() throws -> Output { try visitUnary(.f32, Instruction.f32Floor) }
1965-
mutating func visitF32Trunc() throws -> Output { try visitUnary(.f32, Instruction.f32Trunc) }
1966-
mutating func visitF32Nearest() throws -> Output { try visitUnary(.f32, Instruction.f32Nearest) }
1967-
mutating func visitF32Sqrt() throws -> Output { try visitUnary(.f32, Instruction.f32Sqrt) }
1968-
mutating func visitF64Abs() throws -> Output { try visitUnary(.f64, Instruction.f64Abs) }
1969-
mutating func visitF64Neg() throws -> Output { try visitUnary(.f64, Instruction.f64Neg) }
1970-
mutating func visitF64Ceil() throws -> Output { try visitUnary(.f64, Instruction.f64Ceil) }
1971-
mutating func visitF64Floor() throws -> Output { try visitUnary(.f64, Instruction.f64Floor) }
1972-
mutating func visitF64Trunc() throws -> Output { try visitUnary(.f64, Instruction.f64Trunc) }
1973-
mutating func visitF64Nearest() throws -> Output { try visitUnary(.f64, Instruction.f64Nearest) }
1974-
mutating func visitF64Sqrt() throws -> Output { try visitUnary(.f64, Instruction.f64Sqrt) }
1955+
mutating func visitUnary(_ unary: WasmParser.Instruction.Unary) throws {
1956+
let operand: ValueType, instruction: (Instruction.UnaryOperand) -> Instruction
1957+
switch unary {
1958+
case .i32Clz: (operand, instruction) = (.i32, Instruction.i32Clz)
1959+
case .i32Ctz: (operand, instruction) = (.i32, Instruction.i32Ctz)
1960+
case .i32Popcnt: (operand, instruction) = (.i32, Instruction.i32Popcnt)
1961+
case .i64Clz: (operand, instruction) = (.i64, Instruction.i64Clz)
1962+
case .i64Ctz: (operand, instruction) = (.i64, Instruction.i64Ctz)
1963+
case .i64Popcnt: (operand, instruction) = (.i64, Instruction.i64Popcnt)
1964+
case .f32Abs: (operand, instruction) = (.f32, Instruction.f32Abs)
1965+
case .f32Neg: (operand, instruction) = (.f32, Instruction.f32Neg)
1966+
case .f32Ceil: (operand, instruction) = (.f32, Instruction.f32Ceil)
1967+
case .f32Floor: (operand, instruction) = (.f32, Instruction.f32Floor)
1968+
case .f32Trunc: (operand, instruction) = (.f32, Instruction.f32Trunc)
1969+
case .f32Nearest: (operand, instruction) = (.f32, Instruction.f32Nearest)
1970+
case .f32Sqrt: (operand, instruction) = (.f32, Instruction.f32Sqrt)
1971+
case .f64Abs: (operand, instruction) = (.f64, Instruction.f64Abs)
1972+
case .f64Neg: (operand, instruction) = (.f64, Instruction.f64Neg)
1973+
case .f64Ceil: (operand, instruction) = (.f64, Instruction.f64Ceil)
1974+
case .f64Floor: (operand, instruction) = (.f64, Instruction.f64Floor)
1975+
case .f64Trunc: (operand, instruction) = (.f64, Instruction.f64Trunc)
1976+
case .f64Nearest: (operand, instruction) = (.f64, Instruction.f64Nearest)
1977+
case .f64Sqrt: (operand, instruction) = (.f64, Instruction.f64Sqrt)
1978+
case .i32Extend8S: (operand, instruction) = (.i32, Instruction.i32Extend8S)
1979+
case .i32Extend16S: (operand, instruction) = (.i32, Instruction.i32Extend16S)
1980+
case .i64Extend8S: (operand, instruction) = (.i64, Instruction.i64Extend8S)
1981+
case .i64Extend16S: (operand, instruction) = (.i64, Instruction.i64Extend16S)
1982+
case .i64Extend32S: (operand, instruction) = (.i64, Instruction.i64Extend32S)
1983+
}
1984+
try visitUnary(operand, instruction)
1985+
}
19751986
mutating func visitI32WrapI64() throws -> Output { try visitConversion(.i64, .i32, Instruction.i32WrapI64) }
19761987
mutating func visitI32TruncF32S() throws -> Output { try visitConversion(.f32, .i32, Instruction.i32TruncF32S) }
19771988
mutating func visitI32TruncF32U() throws -> Output { try visitConversion(.f32, .i32, Instruction.i32TruncF32U) }
@@ -1997,11 +2008,7 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
19972008
mutating func visitI64ReinterpretF64() throws -> Output { try visitConversion(.f64, .i64, Instruction.i64ReinterpretF64) }
19982009
mutating func visitF32ReinterpretI32() throws -> Output { try visitConversion(.i32, .f32, Instruction.f32ReinterpretI32) }
19992010
mutating func visitF64ReinterpretI64() throws -> Output { try visitConversion(.i64, .f64, Instruction.f64ReinterpretI64) }
2000-
mutating func visitI32Extend8S() throws -> Output { try visitUnary(.i32, Instruction.i32Extend8S) }
2001-
mutating func visitI32Extend16S() throws -> Output { try visitUnary(.i32, Instruction.i32Extend16S) }
2002-
mutating func visitI64Extend8S() throws -> Output { try visitUnary(.i64, Instruction.i64Extend8S) }
2003-
mutating func visitI64Extend16S() throws -> Output { try visitUnary(.i64, Instruction.i64Extend16S) }
2004-
mutating func visitI64Extend32S() throws -> Output { try visitUnary(.i64, Instruction.i64Extend32S) }
2011+
20052012
mutating func visitMemoryInit(dataIndex: UInt32) throws -> Output {
20062013
try self.module.validateDataSegment(dataIndex)
20072014
let addressType = try module.addressType(memoryIndex: 0)

0 commit comments

Comments
 (0)