| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- //-------------------------------------------------------------------------------------------------------
- // 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"
- #include "PrologEncoderMD.h"
- unsigned __int8 PrologEncoderMD::GetRequiredNodeCountForAlloca(size_t size)
- {
- Assert(size);
- Assert(size % 8 == 0);
- if (size <= 0x80)
- return 1;
- else if (size <= 0x7FF8)
- return 2;
- else
- return 3;
- }
- unsigned __int8 PrologEncoderMD::GetOp(IR::Instr *instr)
- {
- switch (instr->m_opcode)
- {
- case Js::OpCode::PUSH:
- Assert(instr->GetSrc1()->IsRegOpnd());
- return UWOP_PUSH_NONVOL;
- case Js::OpCode::MOVAPD:
- case Js::OpCode::MOVAPS:
- Assert(instr->GetSrc1()->IsRegOpnd() && REGNUM_ISXMMXREG(instr->GetSrc1()->AsRegOpnd()->GetReg()));
- return UWOP_SAVE_XMM128;
- case Js::OpCode::MOV:
- // MOV rbp, rsp (or)
- // MOV rax, imm
- Assert(instr->GetDst() && instr->GetSrc1());
- return UWOP_IGNORE;
- case Js::OpCode::SUB:
- Assert(instr->GetSrc1() && instr->GetSrc2());
- Assert(instr->GetSrc1()->AsRegOpnd()->GetReg() == RegRSP &&
- instr->GetSrc2()->IsIntConstOpnd());
- if (instr->GetSrc2()->AsIntConstOpnd()->GetValue() <= 128)
- return UWOP_ALLOC_SMALL;
- else
- return UWOP_ALLOC_LARGE;
- case Js::OpCode::CALL:
- // TODO: call target could also be a stack overflow check.
- // Assert(instr->GetSrc1()->AsHelperCallOpnd()->m_fnHelper == IR::HelperCRT_chkstk);
- Assert(instr->GetSrc1()->IsRegOpnd());
- return UWOP_IGNORE;
- default:
- AssertMsg(false, "Unsupported opcode in prolog.");
- }
- return UWOP_IGNORE;
- }
- unsigned __int8 PrologEncoderMD::GetNonVolRegToSave(IR::Instr *instr)
- {
- Assert(instr->m_opcode == Js::OpCode::PUSH);
- return (instr->GetSrc1()->AsRegOpnd()->GetReg() - 1) & 0xFF;
- }
- unsigned __int8 PrologEncoderMD::GetXmmRegToSave(IR::Instr *instr, unsigned __int16 *scaledOffset)
- {
- Assert(scaledOffset);
- Assert(instr->m_opcode == Js::OpCode::MOVAPD || instr->m_opcode == Js::OpCode::MOVAPS);
- Assert(instr->GetDst() && instr->GetDst()->IsIndirOpnd());
- unsigned __int8 reg = ((instr->GetSrc1()->AsRegOpnd()->GetReg() - FIRST_XMM_REG) & 0xFF);
- unsigned __int32 offsetFromInstr = instr->GetDst()->AsIndirOpnd()->GetOffset();
- // The offset in the instruction is relative to the stack pointer before the saved reg size and stack args size were
- // subtracted, but the offset in the unwind info needs to be relative to the final stack pointer value
- // (see LowererMDArch::LowerEntryInstr), so adjust for that
- Assert(instr->GetDst()->AsIndirOpnd()->GetBaseOpnd()->GetReg() == LowererMDArch::GetRegStackPointer());
- Func *const topFunc = instr->m_func->GetTopFunc();
- offsetFromInstr += topFunc->GetArgsSize() + topFunc->GetSavedRegSize();
- // Can only encode nonnegative 16-byte-aligned offsets in the unwind info
- Assert(static_cast<int32>(offsetFromInstr) >= 0);
- Assert(::Math::Align(offsetFromInstr, static_cast<unsigned __int32>(MachDouble * 2)) == offsetFromInstr);
- // Stored offset is scaled by 16
- offsetFromInstr /= MachDouble * 2;
- // We currently don't allow a total stack size greater than 1 MB. If we start allowing that, we will need to handle offsets
- // greater than (1 MB - 16) in the unwind info as well, for which a FAR version of the op-code is necessary.
- Assert(IS_UINT16(offsetFromInstr));
- *scaledOffset = TO_UINT16(offsetFromInstr);
- return reg;
- }
- size_t PrologEncoderMD::GetAllocaSize(IR::Instr *instr)
- {
- Assert(instr->m_opcode == Js::OpCode::SUB);
- Assert(instr->GetSrc1() && instr->GetSrc2());
- Assert(instr->GetSrc1()->AsRegOpnd()->GetReg() == RegRSP &&
- instr->GetSrc2()->IsIntConstOpnd());
- Assert(instr->GetSrc2()->AsIntConstOpnd()->GetValue() % 8 == 0);
- return instr->GetSrc2()->AsIntConstOpnd()->GetValue();
- }
- unsigned __int8 PrologEncoderMD::GetFPReg()
- {
- return RegRBP - 1;
- }
|