| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "Backend.h"
- // PeepsMD::Init
- void
- PeepsMD::Init(Peeps *peeps)
- {
- this->peeps = peeps;
- }
- // PeepsMD::ProcessImplicitRegs
- // Note: only do calls for now
- void
- PeepsMD::ProcessImplicitRegs(IR::Instr *instr)
- {
- if (LowererMD::IsCall(instr))
- {
- #define REGDAT(Name, Listing, Encode, Type, BitVec) \
- if (!((BitVec) & (RA_CALLEESAVE | RA_DONTALLOCATE))) \
- { \
- this->peeps->ClearReg(Reg ## Name); \
- }
- #include "RegList.h"
- }
- else if (instr->m_opcode == Js::OpCode::IMUL)
- {
- this->peeps->ClearReg(RegRDX);
- }
- else if (instr->m_opcode == Js::OpCode::IDIV || instr->m_opcode == Js::OpCode::DIV)
- {
- if (instr->GetDst()->AsRegOpnd()->GetReg() == RegRDX)
- {
- this->peeps->ClearReg(RegRAX);
- }
- else
- {
- Assert(instr->GetDst()->AsRegOpnd()->GetReg() == RegRAX);
- this->peeps->ClearReg(RegRDX);
- }
- }
- else if (instr->m_opcode == Js::OpCode::XCHG)
- {
- // At time of writing, I believe that src1 is always identical to dst, but clear both for robustness.
- // Either of XCHG's operands (but not both) can be a memory address, so only clear registers.
- if (instr->GetSrc1()->IsRegOpnd())
- {
- this->peeps->ClearReg(instr->GetSrc1()->AsRegOpnd()->GetReg());
- }
- if (instr->GetSrc2()->IsRegOpnd())
- {
- this->peeps->ClearReg(instr->GetSrc2()->AsRegOpnd()->GetReg());
- }
- }
- }
- void
- PeepsMD::PeepAssign(IR::Instr *instr)
- {
- IR::Opnd* dst = instr->GetDst();
- IR::Opnd* src = instr->GetSrc1();
- if(dst->IsRegOpnd() && instr->m_opcode == Js::OpCode::MOV && !instr->isInlineeEntryInstr)
- {
- if (src->IsImmediateOpnd() && src->GetImmediateValue(instr->m_func) == 0)
- {
- Assert(instr->GetSrc2() == NULL);
- // 32-bit XOR has a smaller encoding
- if (TySize[dst->GetType()] == MachPtr)
- {
- dst->SetType(TyInt32);
- }
- instr->m_opcode = Js::OpCode::XOR;
- instr->ReplaceSrc1(dst);
- instr->SetSrc2(dst);
- }
- else
- {
- if(src->IsIntConstOpnd() && src->GetSize() <= TySize[TyUint32])
- {
- dst->SetType(TyUint32);
- src->SetType(TyUint32);
- }
- else if(src->IsAddrOpnd() && (((size_t)src->AsAddrOpnd()->m_address >> 32) == 0 ))
- {
- instr->ReplaceSrc1(IR::IntConstOpnd::New(::Math::PointerCastToIntegral<UIntConstType>(src->AsAddrOpnd()->m_address), TyUint32, instr->m_func));
- dst->SetType(TyUint32);
- }
- }
- }
- else if (((instr->m_opcode == Js::OpCode::MOVSD || instr->m_opcode == Js::OpCode::MOVSS)
- && src->IsRegOpnd()
- && dst->IsRegOpnd()
- && (TySize[src->GetType()] == TySize[dst->GetType()]))
- || ((instr->m_opcode == Js::OpCode::MOVUPS)
- && src->IsRegOpnd()
- && dst->IsRegOpnd())
- || (instr->m_opcode == Js::OpCode::MOVAPD))
- {
- // MOVAPS has 1 byte shorter encoding
- instr->m_opcode = Js::OpCode::MOVAPS;
- }
- else if (instr->m_opcode == Js::OpCode::MOVSD_ZERO)
- {
- instr->m_opcode = Js::OpCode::XORPS;
- instr->SetSrc1(dst);
- instr->SetSrc2(dst);
- }
- }
|