IR::Opnd * StackSym::GetConstOpnd() const { Assert(IsConst()); IR::Instr *defInstr = this->m_instrDef; IR::Opnd *src1 = defInstr->GetSrc1(); if (!src1) { #if defined(_M_IX86) || defined(_M_X64) Assert(defInstr->m_opcode == Js::OpCode::MOVSD_ZERO); #else Assert(UNREACHED); #endif } else if (src1->IsIntConstOpnd()) { Assert(this->IsIntConst()); if (defInstr->m_opcode == Js::OpCode::LdC_A_I4) { src1 = IR::AddrOpnd::NewFromNumber(src1->AsIntConstOpnd()->GetValue(), defInstr->m_func); defInstr->ReplaceSrc1(src1); defInstr->m_opcode = Js::OpCode::Ld_A; } else { Assert(defInstr->m_opcode == Js::OpCode::Ld_I4 || LowererMD::IsAssign(defInstr) || defInstr->m_opcode == Js::OpCode::ArgOut_A_InlineBuiltIn); } } else if (src1->IsFloatConstOpnd()) { Assert(this->IsFloatConst()); Assert(defInstr->m_opcode == Js::OpCode::LdC_A_R8); src1 = src1->AsFloatConstOpnd()->GetAddrOpnd(defInstr->m_func); defInstr->ReplaceSrc1(src1); defInstr->m_opcode = Js::OpCode::Ld_A; } else if (src1->IsAddrOpnd()) { Assert(defInstr->m_opcode == Js::OpCode::Ld_A || LowererMD::IsAssign(defInstr) || defInstr->m_opcode == Js::OpCode::ArgOut_A_InlineBuiltIn); } else if (src1->IsMemRefOpnd()) { Assert(this->IsFloatConst() || this->IsSimd128Const()); } else { AssertMsg(UNREACHED, "Invalid const value"); } return src1; }
Js::Var StackSym::GetFloatConstValueAsVar_PostGlobOpt() const { Assert(this->IsConst()); IR::Instr *defInstr = this->m_instrDef; IR::Opnd *src1 = defInstr->GetSrc1(); StackSym * stackSym = nullptr; if (src1->IsRegOpnd()) { stackSym = src1->AsRegOpnd()->m_sym; Assert(!stackSym->m_isEncodedConstant); if (stackSym->m_isSingleDef) { //In ARM constant load is always legalized. Try to get the constant from src def defInstr = stackSym->m_instrDef; src1 = defInstr->GetSrc1(); } } Assert(this->IsFloatConst() || (stackSym && stackSym->IsFloatConst())); IR::AddrOpnd *addrOpnd; if (src1->IsAddrOpnd()) { Assert(defInstr->m_opcode == Js::OpCode::Ld_A); addrOpnd = src1->AsAddrOpnd(); } else { Assert(src1->IsFloatConstOpnd()); Assert(defInstr->m_opcode == Js::OpCode::LdC_A_R8); addrOpnd = src1->AsFloatConstOpnd()->GetAddrOpnd(defInstr->m_func); // This is just to prevent creating multiple numbers when the sym is used multiple times. We can only do this // post-GlobOpt, as otherwise it violates some invariants assumed in GlobOpt. defInstr->ReplaceSrc1(addrOpnd); defInstr->m_opcode = Js::OpCode::Ld_A; } const Js::Var address = addrOpnd->m_address; Assert(Js::JavascriptNumber::Is(address)); return address; }
intptr_t StackSym::GetLiteralConstValue_PostGlobOpt() const { Assert(this->IsConst()); IR::Instr *defInstr = this->m_instrDef; IR::Opnd *src1 = defInstr->GetSrc1(); StackSym * stackSym = nullptr; if (src1->IsRegOpnd()) { stackSym = src1->AsRegOpnd()->m_sym; if (stackSym->m_isEncodedConstant) { Assert(!stackSym->m_isSingleDef); Assert(LowererMD::IsAssign(defInstr) || defInstr->m_opcode == Js::OpCode::ArgOut_A_InlineBuiltIn); return stackSym->constantValue; } if (stackSym->m_isSingleDef) { //In ARM constant load is always legalized. Try to get the constant from src def defInstr = stackSym->m_instrDef; src1 = defInstr->GetSrc1(); } } if (src1->IsAddrOpnd()) { Assert(defInstr->m_opcode == Js::OpCode::Ld_A || defInstr->m_opcode == Js::OpCode::LdStr || defInstr->m_opcode == Js::OpCode::ArgOut_A_InlineBuiltIn || LowererMD::IsAssign(defInstr)); return reinterpret_cast<intptr_t>(src1->AsAddrOpnd()->m_address); } if (src1->IsIntConstOpnd()) { Assert(this->IsIntConst() || (stackSym && stackSym->IsIntConst())); if (defInstr->m_opcode == Js::OpCode::LdC_A_I4) { IR::AddrOpnd *const addrOpnd = IR::AddrOpnd::NewFromNumber(src1->AsIntConstOpnd()->GetValue(), defInstr->m_func); const Js::Var address = addrOpnd->m_address; // This is just to prevent creating multiple numbers when the sym is used multiple times. We can only do this // post-GlobOpt, as otherwise it violates some invariants assumed in GlobOpt. defInstr->ReplaceSrc1(addrOpnd); defInstr->m_opcode = Js::OpCode::Ld_A; return reinterpret_cast<intptr_t>(address); } Assert(defInstr->m_opcode == Js::OpCode::Ld_I4 || LowererMD::IsAssign(defInstr) || defInstr->m_opcode == Js::OpCode::ArgOut_A_InlineBuiltIn); return src1->AsIntConstOpnd()->GetValue(); } if (src1->IsFloatConstOpnd()) { Assert(this->IsFloatConst() || (stackSym && stackSym->IsFloatConst())); Assert(defInstr->m_opcode == Js::OpCode::LdC_A_R8); IR::AddrOpnd *const addrOpnd = src1->AsFloatConstOpnd()->GetAddrOpnd(defInstr->m_func); const Js::Var address = addrOpnd->m_address; // This is just to prevent creating multiple numbers when the sym is used multiple times. We can only do this // post-GlobOpt, as otherwise it violates some invariants assumed in GlobOpt. defInstr->ReplaceSrc1(addrOpnd); defInstr->m_opcode = Js::OpCode::Ld_A; return reinterpret_cast<intptr_t>(address); } AssertMsg(UNREACHED, "Unknown const value"); return 0; }