Changeset 209083 in webkit
- Timestamp:
- Nov 29, 2016 11:37:00 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r208953 r209083 1 2016-11-29 Keith Miller <keith_miller@apple.com> 2 3 Add simple way to implement Wasm ops that require more than one B3 opcode 4 https://bugs.webkit.org/show_bug.cgi?id=165129 5 6 Reviewed by Geoffrey Garen. 7 8 * wasm/function-tests/eqz.js: Added. 9 * wasm/function-tests/max.js: Added. 10 * wasm/function-tests/min.js: Added. 11 * wasm/wasm.json: 12 1 13 2016-11-21 Yusuke Suzuki <utatane.tea@gmail.com> 2 14 -
trunk/JSTests/wasm/wasm.json
r208855 r209083 121 121 "i32.ctz": { "category": "arithmetic", "value": 88, "return": ["i32"], "parameter": ["i32"], "immediate": [] }, 122 122 "i32.popcnt": { "category": "arithmetic", "value": 89, "return": ["i32"], "parameter": ["i32"], "immediate": [] }, 123 "i32.eqz": { "category": "comparison", "value": 90, "return": ["bool"], "parameter": ["i32"], "immediate": [] 123 "i32.eqz": { "category": "comparison", "value": 90, "return": ["bool"], "parameter": ["i32"], "immediate": [], "b3op": "Equal(i32(0), @0)" }, 124 124 "i64.add": { "category": "arithmetic", "value": 91, "return": ["i64"], "parameter": ["i64", "i64"], "immediate": [], "b3op": "Add" }, 125 125 "i64.sub": { "category": "arithmetic", "value": 92, "return": ["i64"], "parameter": ["i64", "i64"], "immediate": [], "b3op": "Sub" }, … … 150 150 "i64.ctz": { "category": "arithmetic", "value": 115, "return": ["i64"], "parameter": ["i64"], "immediate": [] }, 151 151 "i64.popcnt": { "category": "arithmetic", "value": 116, "return": ["i64"], "parameter": ["i64"], "immediate": [] }, 152 "i64.eqz": { "category": "comparison", "value": 186, "return": ["bool"], "parameter": ["i64"], "immediate": [] 152 "i64.eqz": { "category": "comparison", "value": 186, "return": ["bool"], "parameter": ["i64"], "immediate": [], "b3op": "Equal(i32(0), @0)" }, 153 153 "f32.add": { "category": "arithmetic", "value": 117, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Add" }, 154 154 "f32.sub": { "category": "arithmetic", "value": 118, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Sub" }, 155 155 "f32.mul": { "category": "arithmetic", "value": 119, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Mul" }, 156 156 "f32.div": { "category": "arithmetic", "value": 120, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Div" }, 157 "f32.min": { "category": "arithmetic", "value": 121, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [] 158 "f32.max": { "category": "arithmetic", "value": 122, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [] 157 "f32.min": { "category": "arithmetic", "value": 121, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" }, 158 "f32.max": { "category": "arithmetic", "value": 122, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" }, 159 159 "f32.abs": { "category": "arithmetic", "value": 123, "return": ["f32"], "parameter": ["f32"], "immediate": [], "b3op": "Abs" }, 160 "f32.neg": { "category": "arithmetic", "value": 124, "return": ["f32"], "parameter": ["f32"], "immediate": [] 160 "f32.neg": { "category": "arithmetic", "value": 124, "return": ["f32"], "parameter": ["f32"], "immediate": [], "b3op": "Neg" }, 161 161 "f32.copysign": { "category": "arithmetic", "value": 125, "return": ["f32"], "parameter": ["f32"], "immediate": [] }, 162 162 "f32.ceil": { "category": "arithmetic", "value": 126, "return": ["f32"], "parameter": ["f32"], "immediate": [], "b3op": "Ceil" }, … … 175 175 "f64.mul": { "category": "arithmetic", "value": 139, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Mul" }, 176 176 "f64.div": { "category": "arithmetic", "value": 140, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Div" }, 177 "f64.min": { "category": "arithmetic", "value": 141, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [] 178 "f64.max": { "category": "arithmetic", "value": 142, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [] 177 "f64.min": { "category": "arithmetic", "value": 141, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" }, 178 "f64.max": { "category": "arithmetic", "value": 142, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" }, 179 179 "f64.abs": { "category": "arithmetic", "value": 143, "return": ["f64"], "parameter": ["f64"], "immediate": [], "b3op": "Abs" }, 180 "f64.neg": { "category": "arithmetic", "value": 144, "return": ["f64"], "parameter": ["f64"], "immediate": [] 180 "f64.neg": { "category": "arithmetic", "value": 144, "return": ["f64"], "parameter": ["f64"], "immediate": [], "b3op": "Neg" }, 181 181 "f64.copysign": { "category": "arithmetic", "value": 145, "return": ["f64"], "parameter": ["f64"], "immediate": [] }, 182 182 "f64.ceil": { "category": "arithmetic", "value": 146, "return": ["f64"], "parameter": ["f64"], "immediate": [], "b3op": "Ceil" }, -
trunk/Source/JavaScriptCore/ChangeLog
r209080 r209083 1 2016-11-29 Keith Miller <keith_miller@apple.com> 2 3 Add simple way to implement Wasm ops that require more than one B3 opcode 4 https://bugs.webkit.org/show_bug.cgi?id=165129 5 6 Reviewed by Geoffrey Garen. 7 8 This patch adds a simple way to show the B3IRGenerator opcode script how 9 to generate code for Wasm opcodes that do not have a one to one mapping. 10 The syntax is pretty simple right now. There are only three things one 11 can use as of this patch (although more things might be added in the future) 12 1) Wasm opcode arguments: These are referred to as @<argument_number>. For example, 13 I32.sub would map to Sub(@0, @1). 14 2) 32-bit int constants: These are reffered to as i32(<value>). For example, i32.inc 15 would map to Add(@0, i32(1)) 16 3) B3 opcodes: These are referred to as the B3 opcode name followed by the B3Value's constructor 17 arguments. A value may take the result of another value as an argument. For example, you can do 18 Div(Mul(@0, Add(@0, i32(1))), i32(2)) if there was a b3 opcode that computed the sum from 1 to n. 19 20 These scripts are used to implement Wasm's eqz and floating point max/min opcodes. This patch 21 also adds missing support for the Wasm Neg opcodes. 22 23 * jsc.cpp: 24 (box): 25 (functionTestWasmModuleFunctions): 26 * wasm/WasmB3IRGenerator.cpp: 27 (JSC::Wasm::toB3Op): Deleted. 28 * wasm/WasmFunctionParser.h: 29 (JSC::Wasm::FunctionParser<Context>::parseBody): 30 * wasm/WasmModuleParser.cpp: 31 (JSC::Wasm::ModuleParser::parseType): 32 * wasm/WasmParser.h: 33 (JSC::Wasm::Parser::parseUInt8): 34 (JSC::Wasm::Parser::parseValueType): 35 * wasm/generateWasmB3IRGeneratorInlinesHeader.py: 36 (Source): 37 (Source.__init__): 38 (read): 39 (lex): 40 (CodeGenerator): 41 (CodeGenerator.__init__): 42 (CodeGenerator.advance): 43 (CodeGenerator.token): 44 (CodeGenerator.parseError): 45 (CodeGenerator.consume): 46 (CodeGenerator.generateParameters): 47 (CodeGenerator.generateOpcode): 48 (CodeGenerator.generate): 49 (temp): 50 (generateB3OpCode): 51 (generateI32ConstCode): 52 (generateB3Code): 53 (generateSimpleCode): 54 * wasm/wasm.json: 55 1 56 2016-11-29 Mark Lam <mark.lam@apple.com> 2 57 -
trunk/Source/JavaScriptCore/jsc.cpp
r208985 r209083 2510 2510 2511 2511 RELEASE_ASSERT(typeString == "f64"); 2512 return value;2512 return JSValue::decode(bitwise_cast<uint64_t>(value.asNumber())); 2513 2513 } 2514 2514 … … 2549 2549 Wasm::Plan plan(&vm, static_cast<uint8_t*>(source->vector()), source->length()); 2550 2550 plan.run(); 2551 if (plan.failed()) 2551 if (plan.failed()) { 2552 dataLogLn("failed to parse module: ", plan.errorMessage()); 2552 2553 CRASH(); 2554 } 2553 2555 2554 2556 if (plan.compiledFunctionCount() != functionCount) -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r208821 r209083 60 60 } 61 61 62 inline B3::Opcode toB3Op(BinaryOpType op)63 {64 switch (op) {65 #define CREATE_CASE(name, op, b3op) case BinaryOpType::name: return b3op;66 FOR_EACH_WASM_BINARY_OP(CREATE_CASE)67 #undef CREATE_CASE68 }69 RELEASE_ASSERT_NOT_REACHED();70 }71 72 inline B3::Opcode toB3Op(UnaryOpType op)73 {74 switch (op) {75 #define CREATE_CASE(name, op, b3op) case UnaryOpType::name: return b3op;76 FOR_EACH_WASM_UNARY_OP(CREATE_CASE)77 #undef CREATE_CASE78 }79 RELEASE_ASSERT_NOT_REACHED();80 }81 82 62 class B3IRGenerator { 83 63 public: -
trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h
r208821 r209083 124 124 while (true) { 125 125 uint8_t op; 126 if (!parseUInt 7(op) || !isValidOpType(op)) {126 if (!parseUInt8(op) || !isValidOpType(op)) { 127 127 if (verbose) 128 128 WTF::dataLogLn("attempted to decode invalid op: ", RawPointer(reinterpret_cast<void*>(op)), " at offset: ", RawPointer(reinterpret_cast<void*>(m_offset))); … … 351 351 case OpType::Block: { 352 352 Type inlineSignature; 353 if (!parse ValueType(inlineSignature))353 if (!parseResultType(inlineSignature)) 354 354 return false; 355 355 … … 361 361 case OpType::Loop: { 362 362 Type inlineSignature; 363 if (!parse ValueType(inlineSignature))363 if (!parseResultType(inlineSignature)) 364 364 return false; 365 365 … … 371 371 case OpType::If: { 372 372 Type inlineSignature; 373 if (!parse ValueType(inlineSignature))373 if (!parseResultType(inlineSignature)) 374 374 return false; 375 375 -
trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp
r208627 r209083 186 186 187 187 for (unsigned i = 0; i != argumentCount; ++i) { 188 uint8_targumentType;189 if (!parse UInt7(argumentType) || !isValueType(static_cast<Type>(argumentType)))190 return false; 191 argumentTypes.uncheckedAppend( static_cast<Type>(argumentType));188 Type argumentType; 189 if (!parseResultType(argumentType)) 190 return false; 191 argumentTypes.uncheckedAppend(argumentType); 192 192 } 193 193 -
trunk/Source/JavaScriptCore/wasm/WasmParser.h
r208567 r209083 50 50 bool WARN_UNUSED_RETURN parseInt7(int8_t&); 51 51 bool WARN_UNUSED_RETURN parseUInt7(uint8_t&); 52 bool WARN_UNUSED_RETURN parseUInt8(uint8_t&); 52 53 bool WARN_UNUSED_RETURN parseUInt32(uint32_t&); 53 54 bool WARN_UNUSED_RETURN parseVarUInt32(uint32_t&); 54 55 bool WARN_UNUSED_RETURN parseVarUInt64(uint64_t&); 55 56 57 bool WARN_UNUSED_RETURN parseResultType(Type&); 56 58 bool WARN_UNUSED_RETURN parseValueType(Type&); 57 59 bool WARN_UNUSED_RETURN parseExternalKind(External::Kind&); … … 132 134 } 133 135 136 ALWAYS_INLINE bool Parser::parseUInt8(uint8_t& result) 137 { 138 if (m_offset >= length()) 139 return false; 140 result = source()[m_offset++]; 141 return true; 142 } 143 134 144 ALWAYS_INLINE bool Parser::parseInt7(int8_t& result) 135 145 { … … 158 168 } 159 169 160 ALWAYS_INLINE bool Parser::parse ValueType(Type& result)170 ALWAYS_INLINE bool Parser::parseResultType(Type& result) 161 171 { 162 172 uint8_t value; 163 173 if (!parseUInt7(value)) 164 174 return false; 165 if (value > =static_cast<uint8_t>(Type::LastValueType))175 if (value > static_cast<uint8_t>(Type::LastValueType)) 166 176 return false; 167 177 result = static_cast<Type>(value); 168 178 return true; 179 } 180 181 ALWAYS_INLINE bool Parser::parseValueType(Type& result) 182 { 183 return parseResultType(result) && isValueType(result); 169 184 } 170 185 -
trunk/Source/JavaScriptCore/wasm/generateWasmB3IRGeneratorInlinesHeader.py
r208821 r209083 29 29 import optparse 30 30 import sys 31 import re 31 32 32 33 parser = optparse.OptionParser(usage="usage: %prog <wasm.json> <WasmOps.h>") … … 38 39 opcodes = wasm.opcodes 39 40 wasmB3IRGeneratorHFile = open(args[2], "w") 41 42 opcodeRegex = re.compile('([a-zA-Z0-9]+)') 43 argumentRegex = re.compile('(\@[0-9]+)') 44 decimalRegex = re.compile('([-]?[0-9]+)') 45 whitespaceRegex = re.compile('\s+') 46 commaRegex = re.compile('(,)') 47 oparenRegex = re.compile('(\()') 48 cparenRegex = re.compile('(\))') 49 50 51 class Source: 52 def __init__(self, contents, offset=0): 53 self.contents = contents 54 self.offset = offset 55 56 57 def read(regex, source): 58 match = regex.match(source.contents, source.offset) 59 if not match: 60 return None 61 source.offset = match.end() 62 return match.group() 63 64 65 def lex(source): 66 result = [] 67 while source.offset != len(source.contents): 68 read(whitespaceRegex, source) 69 opcode = read(opcodeRegex, source) 70 if opcode: 71 result.append(opcode) 72 continue 73 74 argument = read(argumentRegex, source) 75 if argument: 76 result.append(argument) 77 continue 78 79 number = read(decimalRegex, source) 80 if number: 81 result.append(int(number)) 82 continue 83 84 oparen = read(oparenRegex, source) 85 if oparen: 86 result.append(oparen) 87 continue 88 89 cparen = read(cparenRegex, source) 90 if cparen: 91 result.append(cparen) 92 continue 93 94 comma = read(commaRegex, source) 95 if comma: 96 # Skip commas 97 continue 98 99 raise Exception("Lexing Error: could not lex token from: " + source.contents + " at offset: " + str(source.offset) + " (" + source.contents[source.offset:] + "). With tokens: [" + ", ".join(result) + "]") 100 return result 101 102 103 class CodeGenerator: 104 def __init__(self, tokens): 105 self.tokens = tokens 106 self.index = 0 107 self.code = [] 108 109 def advance(self): 110 self.index += 1 111 112 def token(self): 113 return self.tokens[self.index] 114 115 def parseError(self, string): 116 raise Exception("Parse error " + string) 117 118 def consume(self, string): 119 if self.token() != string: 120 self.parseError("Expected " + string + " but got " + self.token()) 121 self.advance() 122 123 def generateParameters(self): 124 self.advance() 125 params = [] 126 tokens = self.tokens 127 while self.index < len(tokens): 128 if self.token() == ")": 129 self.advance() 130 return params 131 params.append(self.generateOpcode()) 132 self.parseError("Parsing arguments fell off end") 133 134 def generateOpcode(self): 135 result = None 136 if self.token() == "i32": 137 self.advance() 138 self.consume("(") 139 self.code.append(generateI32ConstCode(self.index, self.token())) 140 result = temp(self.index) 141 self.advance() 142 self.consume(")") 143 elif argumentRegex.match(self.token()): 144 result = "arg" + self.token()[1:] 145 self.advance() 146 else: 147 op = self.token() 148 index = self.index 149 self.advance() 150 params = self.generateParameters() 151 self.code.append(generateB3OpCode(index, op, params)) 152 result = temp(index) 153 154 return result 155 156 def generate(self, wasmOp): 157 if len(self.tokens) == 1: 158 params = ["arg" + str(param) for param in range(len(wasmOp["parameter"]))] 159 return " result = m_currentBlock->appendNew<Value>(m_proc, B3::" + self.token() + ", Origin(), " + ", ".join(params) + ")" 160 result = self.generateOpcode() 161 self.code.append("result = " + result) 162 return " " + " \n".join(self.code) 163 164 165 def temp(index): 166 return "temp" + str(index) 167 168 169 def generateB3OpCode(index, op, params): 170 return "Value* " + temp(index) + " = m_currentBlock->appendNew<Value>(m_proc, B3::" + op + ", Origin(), " + ", ".join(params) + ");" 171 172 173 def generateI32ConstCode(index, value): 174 return "Value* " + temp(index) + " = m_currentBlock->appendIntConstant(m_proc, Origin(), B3::Int32, " + value + ");" 175 176 177 def generateB3Code(wasmOp, source): 178 tokens = lex(Source(source)) 179 parser = CodeGenerator(tokens) 180 return parser.generate(wasmOp) 40 181 41 182 … … 45 186 args = ["ExpressionType arg" + str(param) for param in range(len(opcode["parameter"]))] 46 187 args.append("ExpressionType& result") 47 params = ["arg" + str(param) for param in range(len(opcode["parameter"]))]48 188 return """ 49 189 template<> bool B3IRGenerator::addOp<OpType::""" + wasm.toCpp(op["name"]) + ">(" + ", ".join(args) + """) 50 190 { 51 result = m_currentBlock->appendNew<Value>(m_proc, B3::""" + opcode["b3op"] + ", Origin(), " + ", ".join(params) + """);191 """ + generateB3Code(opcode, b3op) + """; 52 192 return true; 53 193 } 54 194 """ 55 195 196 56 197 definitions = [generateSimpleCode(op) for op in wasm.opcodeIterator(lambda op: isSimple(op) and (isBinary(op) or isUnary(op)))] 57 198 contents = wasm.header + """ -
trunk/Source/JavaScriptCore/wasm/wasm.json
r208855 r209083 121 121 "i32.ctz": { "category": "arithmetic", "value": 88, "return": ["i32"], "parameter": ["i32"], "immediate": [] }, 122 122 "i32.popcnt": { "category": "arithmetic", "value": 89, "return": ["i32"], "parameter": ["i32"], "immediate": [] }, 123 "i32.eqz": { "category": "comparison", "value": 90, "return": ["bool"], "parameter": ["i32"], "immediate": [] 123 "i32.eqz": { "category": "comparison", "value": 90, "return": ["bool"], "parameter": ["i32"], "immediate": [], "b3op": "Equal(i32(0), @0)" }, 124 124 "i64.add": { "category": "arithmetic", "value": 91, "return": ["i64"], "parameter": ["i64", "i64"], "immediate": [], "b3op": "Add" }, 125 125 "i64.sub": { "category": "arithmetic", "value": 92, "return": ["i64"], "parameter": ["i64", "i64"], "immediate": [], "b3op": "Sub" }, … … 150 150 "i64.ctz": { "category": "arithmetic", "value": 115, "return": ["i64"], "parameter": ["i64"], "immediate": [] }, 151 151 "i64.popcnt": { "category": "arithmetic", "value": 116, "return": ["i64"], "parameter": ["i64"], "immediate": [] }, 152 "i64.eqz": { "category": "comparison", "value": 186, "return": ["bool"], "parameter": ["i64"], "immediate": [] 152 "i64.eqz": { "category": "comparison", "value": 186, "return": ["bool"], "parameter": ["i64"], "immediate": [], "b3op": "Equal(i32(0), @0)" }, 153 153 "f32.add": { "category": "arithmetic", "value": 117, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Add" }, 154 154 "f32.sub": { "category": "arithmetic", "value": 118, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Sub" }, 155 155 "f32.mul": { "category": "arithmetic", "value": 119, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Mul" }, 156 156 "f32.div": { "category": "arithmetic", "value": 120, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Div" }, 157 "f32.min": { "category": "arithmetic", "value": 121, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [] 158 "f32.max": { "category": "arithmetic", "value": 122, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [] 157 "f32.min": { "category": "arithmetic", "value": 121, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" }, 158 "f32.max": { "category": "arithmetic", "value": 122, "return": ["f32"], "parameter": ["f32", "f32"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" }, 159 159 "f32.abs": { "category": "arithmetic", "value": 123, "return": ["f32"], "parameter": ["f32"], "immediate": [], "b3op": "Abs" }, 160 "f32.neg": { "category": "arithmetic", "value": 124, "return": ["f32"], "parameter": ["f32"], "immediate": [] 160 "f32.neg": { "category": "arithmetic", "value": 124, "return": ["f32"], "parameter": ["f32"], "immediate": [], "b3op": "Neg" }, 161 161 "f32.copysign": { "category": "arithmetic", "value": 125, "return": ["f32"], "parameter": ["f32"], "immediate": [] }, 162 162 "f32.ceil": { "category": "arithmetic", "value": 126, "return": ["f32"], "parameter": ["f32"], "immediate": [], "b3op": "Ceil" }, … … 175 175 "f64.mul": { "category": "arithmetic", "value": 139, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Mul" }, 176 176 "f64.div": { "category": "arithmetic", "value": 140, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Div" }, 177 "f64.min": { "category": "arithmetic", "value": 141, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [] 178 "f64.max": { "category": "arithmetic", "value": 142, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [] 177 "f64.min": { "category": "arithmetic", "value": 141, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @0, @1)" }, 178 "f64.max": { "category": "arithmetic", "value": 142, "return": ["f64"], "parameter": ["f64", "f64"], "immediate": [], "b3op": "Select(LessThan(@0, @1), @1, @0)" }, 179 179 "f64.abs": { "category": "arithmetic", "value": 143, "return": ["f64"], "parameter": ["f64"], "immediate": [], "b3op": "Abs" }, 180 "f64.neg": { "category": "arithmetic", "value": 144, "return": ["f64"], "parameter": ["f64"], "immediate": [] 180 "f64.neg": { "category": "arithmetic", "value": 144, "return": ["f64"], "parameter": ["f64"], "immediate": [], "b3op": "Neg" }, 181 181 "f64.copysign": { "category": "arithmetic", "value": 145, "return": ["f64"], "parameter": ["f64"], "immediate": [] }, 182 182 "f64.ceil": { "category": "arithmetic", "value": 146, "return": ["f64"], "parameter": ["f64"], "immediate": [], "b3op": "Ceil" },
Note: See TracChangeset
for help on using the changeset viewer.