diff options
Diffstat (limited to 'lib/Target/JSBackend/JSBackend.cpp')
-rw-r--r-- | lib/Target/JSBackend/JSBackend.cpp | 231 |
1 files changed, 134 insertions, 97 deletions
diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp index fccdb52bf7..75e4a1a5e7 100644 --- a/lib/Target/JSBackend/JSBackend.cpp +++ b/lib/Target/JSBackend/JSBackend.cpp @@ -50,7 +50,7 @@ using namespace llvm; #define dump(x) fprintf(stderr, x "\n") #define dumpv(x, ...) fprintf(stderr, x "\n", __VA_ARGS__) -#define dumpfail(x) { fprintf(stderr, x "\n"); fprintf(stderr, "%s : %d\n", __FILE__, __LINE__); report_fatal_error("fail"); } +#define dumpfail(x) { fputs(x "\n", stderr); fprintf(stderr, "%s : %d\n", __FILE__, __LINE__); report_fatal_error("fail"); } #define dumpfailv(x, ...) { fprintf(stderr, x "\n", __VA_ARGS__); fprintf(stderr, "%s : %d\n", __FILE__, __LINE__); report_fatal_error("fail"); } #define dumpIR(value) { \ std::string temp; \ @@ -217,7 +217,7 @@ namespace { else if (T->isFloatTy() || T->isDoubleTy()) return 'd'; // TODO: float else return 'i'; } - std::string getFunctionSignature(const FunctionType *F, std::string *Name=NULL) { + std::string getFunctionSignature(const FunctionType *F, const std::string *Name=NULL) { if (Name) { // special-case some function signatures, because of how we emit code for them FIXME this is hackish if (*Name == "_llvm_memcpy_p0i8_p0i8_i32" || *Name == "_memcpy" || @@ -235,7 +235,7 @@ namespace { return Ret; } unsigned getFunctionIndex(const Function *F) { - std::string Name = getJSName(F); + const std::string &Name = getJSName(F); if (IndexedFunctions.find(Name) != IndexedFunctions.end()) return IndexedFunctions[Name]; std::string Sig = getFunctionSignature(F->getFunctionType(), &Name); FunctionTable &Table = FunctionTables[Sig]; @@ -310,7 +310,7 @@ namespace { std::string getValueAsParenStr(const Value*); std::string getValueAsCastParenStr(const Value*, AsmCast sign=ASM_SIGNED); - std::string getJSName(const Value* val); + const std::string &getJSName(const Value* val); std::string getPhiCode(const BasicBlock *From, const BasicBlock *To); @@ -381,7 +381,7 @@ std::string JSWriter::getPhiCode(const BasicBlock *From, const BasicBlock *To) { int index = P->getBasicBlockIndex(From); if (index < 0) continue; // we found it - std::string name = getJSName(P); + const std::string &name = getJSName(P); assigns[name] = getAssign(name, P->getType()); Value *V = P->getIncomingValue(index); values[name] = V; @@ -424,12 +424,12 @@ std::string JSWriter::getPhiCode(const BasicBlock *From, const BasicBlock *To) { return pre + post; } -std::string JSWriter::getJSName(const Value* val) { - std::string name; +const std::string &JSWriter::getJSName(const Value* val) { ValueMap::iterator I = ValueNames.find(val); if (I != ValueNames.end() && I->first == val) return I->second; + std::string name; if (val->hasName()) { if (isa<Function>(val) || isa<Constant>(val)) { name = std::string("_") + val->getName().str(); @@ -875,30 +875,37 @@ bool JSWriter::generateSIMDInstruction(const std::string &iName, const Instructi switch (I->getOpcode()) { default: dumpIR(I); error("invalid vector instr"); break; - case Instruction::FAdd: Code << "SIMD.float32x4.add(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::FSub: Code << "SIMD.float32x4.sub(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::FMul: Code << "SIMD.float32x4.mul(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::FDiv: Code << "SIMD.float32x4.div(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::Add: Code << "SIMD.int32x4.add(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::Sub: Code << "SIMD.int32x4.sub(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::Mul: Code << "SIMD.int32x4.mul(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::And: Code << "SIMD.int32x4.and(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::Or: Code << "SIMD.int32x4.or(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; - case Instruction::Xor: Code << "SIMD.int32x4.xor(" + getValueAsStr(I->getOperand(0)) + "," + getValueAsStr(I->getOperand(1)) + ")"; break; + case Instruction::FAdd: Code << "SIMD.float32x4.add(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::FMul: Code << "SIMD.float32x4.mul(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::FDiv: Code << "SIMD.float32x4.div(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::Add: Code << "SIMD.int32x4.add(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::Sub: Code << "SIMD.int32x4.sub(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::Mul: Code << "SIMD.int32x4.mul(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::And: Code << "SIMD.int32x4.and(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::Or: Code << "SIMD.int32x4.or(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::Xor: Code << "SIMD.int32x4.xor(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; break; + case Instruction::FSub: + // LLVM represents an fneg(x) as -0.0 - x. + if (BinaryOperator::isFNeg(I)) { + Code << "SIMD.float32x4.neg(" << getValueAsStr(BinaryOperator::getFNegArgument(I)) << ")"; + } else { + Code << "SIMD.float32x4.sub(" << getValueAsStr(I->getOperand(0)) << "," << getValueAsStr(I->getOperand(1)) << ")"; + } + break; case Instruction::BitCast: { if (cast<VectorType>(I->getType())->getElementType()->isIntegerTy()) { - Code << "SIMD.float32x4.bitsToInt32x4(" + getValueAsStr(I->getOperand(0)) + ')'; + Code << "SIMD.float32x4.bitsToInt32x4(" << getValueAsStr(I->getOperand(0)) << ')'; } else { - Code << "SIMD.int32x4.bitsToInt32x4(" + getValueAsStr(I->getOperand(0)) + ')'; + Code << "SIMD.int32x4.bitsToInt32x4(" << getValueAsStr(I->getOperand(0)) << ')'; } break; } case Instruction::Load: { std::string PS = getOpName(I->getOperand(0)); if (VT->getElementType()->isIntegerTy()) { - Code << "int32x4(HEAPU32[" + PS + ">>2],HEAPU32[" + PS + "+4>>2],HEAPU32[" + PS + "+8>>2],HEAPU32[" + PS + "+12>>2])"; + Code << "int32x4(HEAPU32[" << PS << ">>2],HEAPU32[" << PS << "+4>>2],HEAPU32[" << PS << "+8>>2],HEAPU32[" << PS << "+12>>2])"; } else { - Code << "float32x4(HEAPF32[" + PS + ">>2],HEAPF32[" + PS + "+4>>2],HEAPF32[" + PS + "+8>>2],HEAPF32[" + PS + "+12>>2])"; + Code << "float32x4(HEAPF32[" << PS << ">>2],HEAPF32[" << PS << "+4>>2],HEAPF32[" << PS << "+8>>2],HEAPF32[" << PS << "+12>>2])"; } break; } @@ -913,7 +920,7 @@ bool JSWriter::generateSIMDInstruction(const std::string &iName, const Instructi Code << "SIMD.float32x4.with"; } Code << SIMDLane[Index]; - Code << "(" + getValueAsStr(III->getOperand(0)) + ',' + getValueAsStr(III->getOperand(1)) + ')'; + Code << "(" << getValueAsStr(III->getOperand(0)) << ',' << getValueAsStr(III->getOperand(1)) << ')'; break; } case Instruction::ShuffleVector: { @@ -930,10 +937,10 @@ bool JSWriter::generateSIMDInstruction(const std::string &iName, const Instructi if (Mask < 0) { Code << "0"; } else if (Mask < 4) { - Code << A + "." + simdLane[Mask]; + Code << A << "." << simdLane[Mask]; } else { assert(Mask < 8); - Code << B + "." + simdLane[Mask-4]; + Code << B << "." << simdLane[Mask-4]; } if (i < 3) Code << ","; } @@ -949,9 +956,9 @@ bool JSWriter::generateSIMDInstruction(const std::string &iName, const Instructi std::string PS = getOpName(I->getOperand(1)); std::string VS = getValueAsStr(I->getOperand(0)); if (VT->getElementType()->isIntegerTy()) { - Code << "HEAPU32[" + PS + ">>2]=" + VS + ".x;HEAPU32[" + PS + "+4>>2]=" + VS + ".y;HEAPU32[" + PS + "+8>>2]=" + VS + ".z;HEAPU32[" + PS + "+12>>2]=" + VS + ".w"; + Code << "HEAPU32[" << PS << ">>2]=" << VS << ".x;HEAPU32[" << PS << "+4>>2]=" << VS << ".y;HEAPU32[" << PS << "+8>>2]=" << VS << ".z;HEAPU32[" << PS << "+12>>2]=" << VS << ".w"; } else { - Code << "HEAPF32[" + PS + ">>2]=" + VS + ".x;HEAPF32[" + PS + "+4>>2]=" + VS + ".y;HEAPF32[" + PS + "+8>>2]=" + VS + ".z;HEAPF32[" + PS + "+12>>2]=" + VS + ".w"; + Code << "HEAPF32[" << PS << ">>2]=" << VS << ".x;HEAPF32[" << PS << "+4>>2]=" << VS << ".y;HEAPF32[" << PS << "+8>>2]=" << VS << ".z;HEAPF32[" << PS << "+12>>2]=" << VS << ".w"; } return true; } else if (I->getOpcode() == Instruction::ExtractElement) { @@ -962,20 +969,20 @@ bool JSWriter::generateSIMDInstruction(const std::string &iName, const Instructi unsigned Index = IndexInt->getZExtValue(); assert(Index <= 3); Code << getAssign(iName, I->getType()); - Code << getValueAsStr(EEI->getVectorOperand()) + '.' + simdLane[Index]; + Code << getValueAsStr(EEI->getVectorOperand()) << '.' << simdLane[Index]; return true; } } return false; } -uint64_t LSBMask(unsigned numBits) { +static uint64_t LSBMask(unsigned numBits) { return numBits >= 64 ? 0xFFFFFFFFFFFFFFFFULL : (1ULL << numBits) - 1; } // generateInstruction - This member is called for each Instruction in a function. void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Code) { - std::string iName(getJSName(I)); + const std::string &iName(getJSName(I)); Type *T = I->getType(); if (T->isIntegerTy() && T->getIntegerBitWidth() > 32) { @@ -997,7 +1004,7 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod if (RV == NULL) { Code << ";"; } else { - Code << " " + getValueAsCastStr(RV, ASM_NONSPECIFIC) + ";"; + Code << " " << getValueAsCastStr(RV, ASM_NONSPECIFIC) << ";"; } break; } @@ -1045,14 +1052,14 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod case Instruction::UDiv: case Instruction::SDiv: case Instruction::URem: - case Instruction::SRem: Code << "(" + - getValueAsCastParenStr(I->getOperand(0), (opcode == Instruction::SDiv || opcode == Instruction::SRem) ? ASM_SIGNED : ASM_UNSIGNED) + - ((opcode == Instruction::UDiv || opcode == Instruction::SDiv) ? " / " : " % ") + - getValueAsCastParenStr(I->getOperand(1), (opcode == Instruction::SDiv || opcode == Instruction::SRem) ? ASM_SIGNED : ASM_UNSIGNED) + + case Instruction::SRem: Code << "(" << + getValueAsCastParenStr(I->getOperand(0), (opcode == Instruction::SDiv || opcode == Instruction::SRem) ? ASM_SIGNED : ASM_UNSIGNED) << + ((opcode == Instruction::UDiv || opcode == Instruction::SDiv) ? " / " : " % ") << + getValueAsCastParenStr(I->getOperand(1), (opcode == Instruction::SDiv || opcode == Instruction::SRem) ? ASM_SIGNED : ASM_UNSIGNED) << ")&-1"; break; - case Instruction::And: Code << getValueAsStr(I->getOperand(0)) + " & " + getValueAsStr(I->getOperand(1)); break; - case Instruction::Or: Code << getValueAsStr(I->getOperand(0)) + " | " + getValueAsStr(I->getOperand(1)); break; - case Instruction::Xor: Code << getValueAsStr(I->getOperand(0)) + " ^ " + getValueAsStr(I->getOperand(1)); break; + case Instruction::And: Code << getValueAsStr(I->getOperand(0)) << " & " << getValueAsStr(I->getOperand(1)); break; + case Instruction::Or: Code << getValueAsStr(I->getOperand(0)) << " | " << getValueAsStr(I->getOperand(1)); break; + case Instruction::Xor: Code << getValueAsStr(I->getOperand(0)) << " ^ " << getValueAsStr(I->getOperand(1)); break; case Instruction::Shl: { std::string Shifted = getValueAsStr(I->getOperand(0)) + " << " + getValueAsStr(I->getOperand(1)); if (I->getType()->getIntegerBitWidth() < 32) { @@ -1067,14 +1074,21 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod if (I->getType()->getIntegerBitWidth() < 32) { Input = '(' + getCast(Input, I->getType(), opcode == Instruction::AShr ? ASM_SIGNED : ASM_UNSIGNED) + ')'; // fill in high bits, as shift needs those and is done in 32-bit } - Code << Input + (opcode == Instruction::AShr ? " >> " : " >>> ") + getValueAsStr(I->getOperand(1)); + Code << Input << (opcode == Instruction::AShr ? " >> " : " >>> ") << getValueAsStr(I->getOperand(1)); break; } - case Instruction::FAdd: Code << getValueAsStr(I->getOperand(0)) + " + " + getValueAsStr(I->getOperand(1)); break; // TODO: ensurefloat here - case Instruction::FSub: Code << getValueAsStr(I->getOperand(0)) + " - " + getValueAsStr(I->getOperand(1)); break; - case Instruction::FMul: Code << getValueAsStr(I->getOperand(0)) + " * " + getValueAsStr(I->getOperand(1)); break; - case Instruction::FDiv: Code << getValueAsStr(I->getOperand(0)) + " / " + getValueAsStr(I->getOperand(1)); break; - case Instruction::FRem: Code << getValueAsStr(I->getOperand(0)) + " % " + getValueAsStr(I->getOperand(1)); break; + case Instruction::FAdd: Code << getValueAsStr(I->getOperand(0)) << " + " << getValueAsStr(I->getOperand(1)); break; // TODO: ensurefloat here + case Instruction::FMul: Code << getValueAsStr(I->getOperand(0)) << " * " << getValueAsStr(I->getOperand(1)); break; + case Instruction::FDiv: Code << getValueAsStr(I->getOperand(0)) << " / " << getValueAsStr(I->getOperand(1)); break; + case Instruction::FRem: Code << getValueAsStr(I->getOperand(0)) << " % " << getValueAsStr(I->getOperand(1)); break; + case Instruction::FSub: + // LLVM represents an fneg(x) as -0.0 - x. + if (BinaryOperator::isFNeg(I)) { + Code << "-" << getValueAsStr(BinaryOperator::getFNegArgument(I)); + } else { + Code << getValueAsStr(I->getOperand(0)) << " - " << getValueAsStr(I->getOperand(1)); + } + break; default: error("bad icmp"); break; } Code << ';'; @@ -1083,24 +1097,50 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod case Instruction::FCmp: { Code << getAssign(iName, I->getType()); switch (cast<FCmpInst>(I)->getPredicate()) { - case FCmpInst::FCMP_OEQ: - case FCmpInst::FCMP_UEQ: Code << getValueAsStr(I->getOperand(0)) + " == " + getValueAsStr(I->getOperand(1)); break; + // Comparisons which are simple JS operators. + case FCmpInst::FCMP_OEQ: Code << getValueAsStr(I->getOperand(0)) << " == " << getValueAsStr(I->getOperand(1)); break; + case FCmpInst::FCMP_UNE: Code << getValueAsStr(I->getOperand(0)) << " != " << getValueAsStr(I->getOperand(1)); break; + case FCmpInst::FCMP_OGT: Code << getValueAsStr(I->getOperand(0)) << " > " << getValueAsStr(I->getOperand(1)); break; + case FCmpInst::FCMP_OGE: Code << getValueAsStr(I->getOperand(0)) << " >= " << getValueAsStr(I->getOperand(1)); break; + case FCmpInst::FCMP_OLT: Code << getValueAsStr(I->getOperand(0)) << " < " << getValueAsStr(I->getOperand(1)); break; + case FCmpInst::FCMP_OLE: Code << getValueAsStr(I->getOperand(0)) << " <= " << getValueAsStr(I->getOperand(1)); break; + + // Comparisons which are inverses of JS operators. + case FCmpInst::FCMP_UGT: + Code << "!(" << getValueAsStr(I->getOperand(0)) << " <= " << getValueAsStr(I->getOperand(1)) << ")"; + break; + case FCmpInst::FCMP_UGE: + Code << "!(" << getValueAsStr(I->getOperand(0)) << " < " << getValueAsStr(I->getOperand(1)) << ")"; + break; + case FCmpInst::FCMP_ULT: + Code << "!(" << getValueAsStr(I->getOperand(0)) << " >= " << getValueAsStr(I->getOperand(1)) << ")"; + break; + case FCmpInst::FCMP_ULE: + Code << "!(" << getValueAsStr(I->getOperand(0)) << " > " << getValueAsStr(I->getOperand(1)) << ")"; + break; + + // Comparisons which require explicit NaN checks. + case FCmpInst::FCMP_UEQ: + Code << "(" << getValueAsStr(I->getOperand(0)) << " != " << getValueAsStr(I->getOperand(0)) << ") | " << + "(" << getValueAsStr(I->getOperand(1)) << " != " << getValueAsStr(I->getOperand(1)) << ") |" << + "(" << getValueAsStr(I->getOperand(0)) << " == " << getValueAsStr(I->getOperand(1)) << ")"; + break; case FCmpInst::FCMP_ONE: - case FCmpInst::FCMP_UNE: Code << getValueAsStr(I->getOperand(0)) + " != " + getValueAsStr(I->getOperand(1)); break; - case FCmpInst::FCMP_OGT: - case FCmpInst::FCMP_UGT: Code << getValueAsStr(I->getOperand(0)) + " > " + getValueAsStr(I->getOperand(1)); break; - case FCmpInst::FCMP_OGE: - case FCmpInst::FCMP_UGE: Code << getValueAsStr(I->getOperand(0)) + " >= " + getValueAsStr(I->getOperand(1)); break; - case FCmpInst::FCMP_OLT: - case FCmpInst::FCMP_ULT: Code << getValueAsStr(I->getOperand(0)) + " < " + getValueAsStr(I->getOperand(1)); break; - case FCmpInst::FCMP_OLE: - case FCmpInst::FCMP_ULE: Code << getValueAsStr(I->getOperand(0)) + " <= " + getValueAsStr(I->getOperand(1)); break; - case FCmpInst::FCMP_ORD: Code << "(" + getValueAsStr(I->getOperand(0)) + " == " + getValueAsStr(I->getOperand(0)) + ") & " + - "(" + getValueAsStr(I->getOperand(1)) + " == " + getValueAsStr(I->getOperand(1)) + ")"; break; - case FCmpInst::FCMP_UNO: Code << "(" + getValueAsStr(I->getOperand(0)) + " != " + getValueAsStr(I->getOperand(0)) + ") | " + - "(" + getValueAsStr(I->getOperand(1)) + " != " + getValueAsStr(I->getOperand(1)) + ")"; break; + Code << "(" << getValueAsStr(I->getOperand(0)) << " == " << getValueAsStr(I->getOperand(0)) << ") & " << + "(" << getValueAsStr(I->getOperand(1)) << " == " << getValueAsStr(I->getOperand(1)) << ") &" << + "(" << getValueAsStr(I->getOperand(0)) << " != " << getValueAsStr(I->getOperand(1)) << ")"; + break; + + // Simple NaN checks. + case FCmpInst::FCMP_ORD: Code << "(" << getValueAsStr(I->getOperand(0)) << " == " << getValueAsStr(I->getOperand(0)) << ") & " << + "(" << getValueAsStr(I->getOperand(1)) << " == " << getValueAsStr(I->getOperand(1)) << ")"; break; + case FCmpInst::FCMP_UNO: Code << "(" << getValueAsStr(I->getOperand(0)) << " != " << getValueAsStr(I->getOperand(0)) << ") | " << + "(" << getValueAsStr(I->getOperand(1)) << " != " << getValueAsStr(I->getOperand(1)) << ")"; break; + + // Simple constants. case FCmpInst::FCMP_FALSE: Code << "0"; break; case FCmpInst::FCMP_TRUE : Code << "1"; break; + default: error("bad fcmp"); break; } Code << ";"; @@ -1108,12 +1148,9 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod } case Instruction::ICmp: { unsigned predicate = cast<ICmpInst>(I)->getPredicate(); - AsmCast sign = (predicate == ICmpInst::ICMP_ULE || - predicate == ICmpInst::ICMP_UGE || - predicate == ICmpInst::ICMP_ULT || - predicate == ICmpInst::ICMP_UGT) ? ASM_UNSIGNED : ASM_SIGNED; - Code << getAssign(iName, Type::getInt32Ty(I->getContext())) + "(" + - getValueAsCastStr(I->getOperand(0), sign) + + AsmCast sign = CmpInst::isUnsigned(predicate) ? ASM_UNSIGNED : ASM_SIGNED; + Code << getAssign(iName, Type::getInt32Ty(I->getContext())) << "(" << + getValueAsCastStr(I->getOperand(0), sign) << ")"; switch (predicate) { case ICmpInst::ICMP_EQ: Code << "=="; break; @@ -1128,8 +1165,8 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod case ICmpInst::ICMP_SGT: Code << ">"; break; default: assert(0); } - Code << "(" + - getValueAsCastStr(I->getOperand(1), sign) + + Code << "(" << + getValueAsCastStr(I->getOperand(1), sign) << ");"; break; } @@ -1155,7 +1192,7 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod Size = memAlignStr("((" + utostr(BaseSize) + '*' + getValueAsStr(AS) + ")|0)"); } } - Code << getAssign(iName, Type::getInt32Ty(I->getContext())) + "STACKTOP; STACKTOP = STACKTOP + " + Size + "|0;"; + Code << getAssign(iName, Type::getInt32Ty(I->getContext())) << "STACKTOP; STACKTOP = STACKTOP + " << Size << "|0;"; break; } case Instruction::Load: { @@ -1164,9 +1201,9 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod unsigned Alignment = LI->getAlignment(); std::string Assign = getAssign(iName, LI->getType()); if (NativizedVars.count(P)) { - Code << Assign + getValueAsStr(P) + ';'; + Code << Assign << getValueAsStr(P) << ';'; } else { - Code << getLoad(Assign, P, LI->getType(), Alignment) + ';'; + Code << getLoad(Assign, P, LI->getType(), Alignment) << ';'; } break; } @@ -1177,9 +1214,9 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod unsigned Alignment = SI->getAlignment(); std::string VS = getValueAsStr(V); if (NativizedVars.count(P)) { - Code << getValueAsStr(P) + " = " + VS + ';'; + Code << getValueAsStr(P) << " = " << VS << ';'; } else { - Code << getStore(P, V->getType(), VS, Alignment) + ';'; + Code << getStore(P, V->getType(), VS, Alignment) << ';'; } Type *T = V->getType(); @@ -1198,10 +1235,10 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod break; } case Instruction::PtrToInt: - Code << getAssign(iName, Type::getInt32Ty(I->getContext())) + getPtrAsStr(I->getOperand(0)) + ';'; + Code << getAssign(iName, Type::getInt32Ty(I->getContext())) << getPtrAsStr(I->getOperand(0)) << ';'; break; case Instruction::IntToPtr: - Code << getAssign(iName, Type::getInt32Ty(I->getContext())) + getValueAsStr(I->getOperand(0)) + ";"; + Code << getAssign(iName, Type::getInt32Ty(I->getContext())) << getValueAsStr(I->getOperand(0)) << ";"; break; case Instruction::Trunc: case Instruction::ZExt: @@ -1217,12 +1254,12 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod case Instruction::Trunc: { //unsigned inBits = V->getType()->getIntegerBitWidth(); unsigned outBits = I->getType()->getIntegerBitWidth(); - Code << getValueAsStr(I->getOperand(0)) + "&" + utostr(LSBMask(outBits)); + Code << getValueAsStr(I->getOperand(0)) << "&" << utostr(LSBMask(outBits)); break; } case Instruction::SExt: { std::string bits = utostr(32 - I->getOperand(0)->getType()->getIntegerBitWidth()); - Code << getValueAsStr(I->getOperand(0)) + " << " + bits + " >> " + bits; + Code << getValueAsStr(I->getOperand(0)) << " << " << bits << " >> " << bits; break; } case Instruction::ZExt: Code << getValueAsCastStr(I->getOperand(0), ASM_UNSIGNED); break; @@ -1247,33 +1284,33 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod std::string V = getValueAsStr(I->getOperand(0)); if (InType->isIntegerTy() && OutType->isFloatingPointTy()) { assert(InType->getIntegerBitWidth() == 32); - Code << "(HEAP32[tempDoublePtr>>2]=" + V + "," + "+HEAPF32[tempDoublePtr>>2]);"; + Code << "(HEAP32[tempDoublePtr>>2]=" << V << "," << "+HEAPF32[tempDoublePtr>>2]);"; } else if (OutType->isIntegerTy() && InType->isFloatingPointTy()) { assert(OutType->getIntegerBitWidth() == 32); - Code << "(HEAPF32[tempDoublePtr>>2]=" + V + "," + "HEAP32[tempDoublePtr>>2]|0);"; + Code << "(HEAPF32[tempDoublePtr>>2]=" << V << "," << "HEAP32[tempDoublePtr>>2]|0);"; } else { - Code << V + ";"; + Code << V << ";"; } break; } case Instruction::Call: { const CallInst *CI = cast<CallInst>(I); - Code << handleCall(CI) + ';'; + Code << handleCall(CI) << ';'; break; } case Instruction::Select: { const SelectInst* SI = cast<SelectInst>(I); - Code << getAssign(iName, I->getType()) + getValueAsStr(SI->getCondition()) + " ? " + - getValueAsStr(SI->getTrueValue()) + " : " + - getValueAsStr(SI->getFalseValue()) + ';'; + Code << getAssign(iName, I->getType()) << getValueAsStr(SI->getCondition()) << " ? " << + getValueAsStr(SI->getTrueValue()) << " : " << + getValueAsStr(SI->getFalseValue()) << ';'; break; } case Instruction::AtomicCmpXchg: { std::string Assign = getAssign(iName, I->getType()); const Value *P = I->getOperand(0); - Code << getLoad(Assign, P, I->getType(), 0) + ';' + - "if ((" + getCast(iName, I->getType()) + ") == " + getValueAsCastParenStr(I->getOperand(1)) + ") " + - getStore(P, I->getType(), getValueAsStr(I->getOperand(2)), 0) + ";"; + Code << getLoad(Assign, P, I->getType(), 0) << ';' << + "if ((" << getCast(iName, I->getType()) << ") == " << getValueAsCastParenStr(I->getOperand(1)) << ") " << + getStore(P, I->getType(), getValueAsStr(I->getOperand(2)), 0) << ";"; break; } case Instruction::AtomicRMW: { @@ -1282,7 +1319,7 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod const Value *V = rmwi->getOperand(1); std::string Assign = getAssign(iName, I->getType()); std::string VS = getValueAsStr(V); - Code << getLoad(Assign, P, I->getType(), 0) + ';'; + Code << getLoad(Assign, P, I->getType(), 0) << ';'; // Most bitcasts are no-ops for us. However, the exception is int to float and float to int switch (rmwi->getOperation()) { case AtomicRMWInst::Xchg: Code << getStore(P, I->getType(), VS, 0); break; @@ -1307,7 +1344,7 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod DILocation Loc(N); unsigned Line = Loc.getLineNumber(); StringRef File = Loc.getFilename(); - Code << " //@line " + utostr(Line) + " \"" + (File.size() > 0 ? File.str() : "?") + "\""; + Code << " //@line " << utostr(Line) << " \"" << (File.size() > 0 ? File.str() : "?") << "\""; } } @@ -1466,7 +1503,7 @@ void JSWriter::printFunctionBody(const Function *F) { } // Emit stack entry - Out << " " + getAssign("sp", Type::getInt32Ty(F->getContext())) + "STACKTOP;"; + Out << " " << getAssign("sp", Type::getInt32Ty(F->getContext())) << "STACKTOP;"; // Emit (relooped) code char *buffer = Relooper::GetOutputBuffer(); @@ -1479,7 +1516,7 @@ void JSWriter::printFunctionBody(const Function *F) { if (!LastCurly) LastCurly = buffer; char *FinalReturn = strstr(LastCurly, "return "); if (!FinalReturn) { - Out << " return " + getCast("0", RT, ASM_NONSPECIFIC) + ";\n"; + Out << " return " << getCast("0", RT, ASM_NONSPECIFIC) << ";\n"; } } } @@ -1558,7 +1595,7 @@ void JSWriter::printModuleBody() { } } Out << " function runPostSets() {\n"; - Out << " " + PostSets + "\n"; + Out << " " << PostSets << "\n"; Out << " }\n"; PostSets = ""; Out << "// EMSCRIPTEN_END_FUNCTIONS\n\n"; @@ -1592,7 +1629,7 @@ void JSWriter::printModuleBody() { } else { Out << ", "; } - Out << "\"" + I->getName() + "\""; + Out << "\"" << I->getName() << "\""; } } for (NameSet::iterator I = Declares.begin(), E = Declares.end(); @@ -1602,7 +1639,7 @@ void JSWriter::printModuleBody() { } else { Out << ", "; } - Out << "\"" + *I + "\""; + Out << "\"" << *I << "\""; } Out << "],"; @@ -1615,7 +1652,7 @@ void JSWriter::printModuleBody() { } else { Out << ", "; } - Out << "\"_" << I->first << "\": \"" + I->second + "\""; + Out << "\"_" << I->first << "\": \"" << I->second << "\""; } Out << "},"; @@ -1628,7 +1665,7 @@ void JSWriter::printModuleBody() { } else { Out << ", "; } - Out << "\"" + *I + "\""; + Out << "\"" << *I << "\""; } Out << "],"; @@ -1650,7 +1687,7 @@ void JSWriter::printModuleBody() { Out << "\"tables\": {"; unsigned Num = FunctionTables.size(); for (FunctionTableMap::iterator I = FunctionTables.begin(), E = FunctionTables.end(); I != E; ++I) { - Out << " \"" + I->first + "\": \"var FUNCTION_TABLE_" + I->first + " = ["; + Out << " \"" << I->first << "\": \"var FUNCTION_TABLE_" << I->first << " = ["; FunctionTable &Table = I->second; // ensure power of two unsigned Size = 1; @@ -1674,7 +1711,7 @@ void JSWriter::printModuleBody() { } else { Out << ", "; } - Out << "\"" + GlobalInitializers[i] + "\""; + Out << "\"" << GlobalInitializers[i] << "\""; } Out << "],"; @@ -1690,7 +1727,7 @@ void JSWriter::printModuleBody() { } else { Out << ", "; } - Out << "\"_" << I->first << "\": \"" + utostr(I->second) + "\""; + Out << "\"_" << I->first << "\": \"" << utostr(I->second) << "\""; } Out << "}"; |