Js::AsmJsVarType AsmJsVarType::FromCheckedType(AsmJsType type) { Assert( type.isInt() || type.isMaybeDouble() || type.isFloatish() || type.isSIMDType()); if (type.isMaybeDouble()) return Double; else if (type.isFloatish()) return Float; else if (type.isInt()) return Int; else { // SIMD type return AsmJsVarType::Which(type.GetWhich()); } }
void AsmJsByteCodeDumper::Dump(AsmJsFunc* func, FunctionBody* body) { ByteCodeReader reader; reader.Create(body); StatementReader statementReader; statementReader.Create(body); body->DumpFullFunctionName(); Output::Print(L" Asm.js ("); const ArgSlot argCount = func->GetArgCount(); for (ArgSlot i = 0; i < argCount; i++) { AsmJsType var = func->GetArgType(i); if (i > 0) { Output::Print(L", "); } if (var.isDouble()) { Output::Print(L"+In%hu", i); } else if (var.isFloat()) { Output::Print(L"flt(In%hu)", i); } else if (var.isInt()) { Output::Print(L"In%hu|0", i); } else if (var.isSIMDType()) { switch (var.GetWhich()) { case AsmJsType::Int32x4: Output::Print(L"I4(In%hu)", i); break; case AsmJsType::Float32x4: Output::Print(L"F4(In%hu)", i); break; case AsmJsType::Float64x2: Output::Print(L"D2(In%hu)", i); break; } } else { Assert(UNREACHED); } } Output::Print(L") "); Output::Print(L"(size: %d [%d])\n", body->GetByteCodeCount(), body->GetByteCodeWithoutLDACount()); const auto& intRegisters = func->GetRegisterSpace<int>(); const auto& doubleRegisters = func->GetRegisterSpace<double>(); const auto& floatRegisters = func->GetRegisterSpace<float>(); Output::Print( L" Integer : %u locals (%u temps from I%u)\n", intRegisters.GetVarCount(), intRegisters.GetTmpCount(), intRegisters.GetFirstTmpRegister()); Output::Print( L" Doubles : %u locals (%u temps from D%u)\n", doubleRegisters.GetVarCount(), doubleRegisters.GetTmpCount(), doubleRegisters.GetFirstTmpRegister()); Output::Print( L" Floats : %u locals (%u temps from F%u)\n", floatRegisters.GetVarCount(), floatRegisters.GetTmpCount(), floatRegisters.GetFirstTmpRegister()); const auto& simdRegisters = func->GetRegisterSpace<AsmJsSIMDValue>(); Output::Print( L" SIMDs : %u locals (%u temps from SIMD%u)\n", simdRegisters.GetVarCount(), simdRegisters.GetTmpCount(), simdRegisters.GetFirstTmpRegister()); uint32 statementIndex = 0; DumpConstants(func, body); Output::Print(L" Implicit Arg Ins:\n ======== =====\n "); int iArg = intRegisters.GetConstCount(), dArg = doubleRegisters.GetConstCount(), fArg = floatRegisters.GetConstCount(); int simdArg = simdRegisters.GetConstCount(); for (ArgSlot i = 0; i < argCount; i++) { const AsmJsType& var = func->GetArgType(i); if (var.isDouble()) { Output::Print(L" D%d In%d", dArg++, i); } else if (var.isFloat()) { Output::Print(L" F%d In%d", fArg++, i); } else if (var.isInt()) { Output::Print(L" I%d In%d", iArg++, i); } else if (var.isSIMDType()) { Output::Print(L" SIMD%d In%d", simdArg++, i); } else { Assert(UNREACHED); } Output::Print(L"\n "); } Output::Print(L"\n"); if (func->GetReturnType() == AsmJsRetType::Void) { Output::Print(L" 0000 %-20s R0\n", OpCodeUtilAsmJs::GetOpCodeName(OpCodeAsmJs::LdUndef)); } while (true) { while (statementReader.AtStatementBoundary(&reader)) { body->PrintStatementSourceLine(statementIndex); statementIndex = statementReader.MoveNextStatementBoundary(); } int byteOffset = reader.GetCurrentOffset(); LayoutSize layoutSize; OpCodeAsmJs op = (OpCodeAsmJs)reader.ReadOp(layoutSize); if (op == OpCodeAsmJs::EndOfBlock) { Assert(reader.GetCurrentOffset() == body->GetByteCode()->GetLength()); break; } Output::Print(L" %04x %2s", byteOffset, layoutSize == LargeLayout ? L"L-" : layoutSize == MediumLayout ? L"M-" : L""); DumpOp(op, layoutSize, reader, body); if (Js::Configuration::Global.flags.Verbose) { int layoutStart = byteOffset + 2; // Account for the prefix op int endByteOffset = reader.GetCurrentOffset(); Output::SkipToColumn(70); if (layoutSize == LargeLayout) { Output::Print(L"%02X ", op > Js::OpCodeAsmJs::MaxByteSizedOpcodes ? Js::OpCodeAsmJs::ExtendedLargeLayoutPrefix : Js::OpCodeAsmJs::LargeLayoutPrefix); } else if (layoutSize == MediumLayout) { Output::Print(L"%02X ", op > Js::OpCodeAsmJs::MaxByteSizedOpcodes ? Js::OpCodeAsmJs::ExtendedMediumLayoutPrefix : Js::OpCodeAsmJs::MediumLayoutPrefix); } else { Assert(layoutSize == SmallLayout); if (op > Js::OpCodeAsmJs::MaxByteSizedOpcodes) { Output::Print(L"%02X ", Js::OpCodeAsmJs::ExtendedOpcodePrefix); } else { Output::Print(L" "); layoutStart--; // don't have a prefix } } Output::Print(L"%02x", (byte)op); for (int i = layoutStart; i < endByteOffset; i++) { Output::Print(L" %02x", reader.GetRawByte(i)); } } Output::Print(L"\n"); } if (statementReader.AtStatementBoundary(&reader)) { body->PrintStatementSourceLine(statementIndex); statementIndex = statementReader.MoveNextStatementBoundary(); } Output::Print(L"\n"); Output::Flush(); }