@@ -507,6 +507,31 @@ int EncoderMD::EmitMovConstant(Arm64CodeEmitter &Emitter, IR::Instr *instr, _Emi
507507 }
508508}
509509
510+ template <typename _Emitter, typename _Emitter64>
511+ int EncoderMD::EmitMovConstantKnownShift (Arm64CodeEmitter &Emitter, IR::Instr *instr, _Emitter emitter, _Emitter64 emitter64, uint32 shift)
512+ {
513+ IR::Opnd* dst = instr->GetDst ();
514+ IR::Opnd* src1 = instr->GetSrc1 ();
515+ Assert (dst->IsRegOpnd ());
516+ Assert (src1->IsImmediateOpnd ());
517+
518+ int size = dst->GetSize ();
519+ Assert (size == 4 || size == 8 );
520+
521+ IntConstType immediate = src1->GetImmediateValue (instr->m_func );
522+ Assert ((immediate & 0xFFFF ) == immediate);
523+ Assert (shift == 0 || shift == 16 || (size == 8 && (shift == 32 || shift == 48 )));
524+
525+ if (size == 8 )
526+ {
527+ return emitter64 (Emitter, this ->GetRegEncode (dst->AsRegOpnd ()), ULONG (immediate), shift);
528+ }
529+ else
530+ {
531+ return emitter (Emitter, this ->GetRegEncode (dst->AsRegOpnd ()), ULONG (immediate), shift);
532+ }
533+ }
534+
510535template <typename _Emitter, typename _Emitter64>
511536int EncoderMD::EmitBitfield (Arm64CodeEmitter &Emitter, IR::Instr *instr, _Emitter emitter, _Emitter64 emitter64)
512537{
@@ -725,6 +750,7 @@ EncoderMD::GenerateEncoding(IR::Instr* instr, BYTE *pc)
725750 Assert (src1->IsLabelOpnd ());
726751
727752 Assert (dst->GetSize () == 8 );
753+ Assert (!src1->AsLabelOpnd ()->GetLabel ()->isInlineeEntryInstr );
728754 EncodeReloc::New (&m_relocList, RelocTypeLabelAdr, m_pc, src1->AsLabelOpnd ()->GetLabel (), m_encoder->m_tempAlloc );
729755 bytes = EmitAdr (Emitter, this ->GetRegEncode (dst->AsRegOpnd ()), 0 );
730756 break ;
@@ -939,6 +965,38 @@ EncoderMD::GenerateEncoding(IR::Instr* instr, BYTE *pc)
939965 bytes = this ->EmitMovConstant (Emitter, instr, EmitMovz, EmitMovz64);
940966 break ;
941967
968+ case Js::OpCode::MOVK_SHIFT:
969+ {
970+ Assert (instr->GetSrc1 ()->IsLabelOpnd ());
971+ Assert (instr->GetSrc2 ()->IsIntConstOpnd ());
972+ IR::LabelInstr* labelInstr = instr->GetSrc1 ()->AsLabelOpnd ()->GetLabel ();
973+ uint32 shift = instr->GetSrc2 ()->AsIntConstOpnd ()->AsUint32 ();
974+
975+ // We're going to drop src2, set src1 to just the masked bits from the label
976+ // offset (so we don't even need to go into relocation), and emit it.
977+ instr->UnlinkSrc2 ();
978+ uintptr_t fullvalue = labelInstr->GetOffset ();
979+ instr->ReplaceSrc1 (IR::IntConstOpnd::New ((fullvalue & (0xffff << shift)) >> shift, IRType::TyUint16, instr->m_func , true ));
980+ bytes = this ->EmitMovConstantKnownShift (Emitter, instr, EmitMovk, EmitMovk64, shift);
981+ }
982+ break ;
983+
984+ case Js::OpCode::MOVZ_SHIFT:
985+ {
986+ Assert (instr->GetSrc1 ()->IsLabelOpnd ());
987+ Assert (instr->GetSrc2 ()->IsIntConstOpnd ());
988+ IR::LabelInstr* labelInstr = instr->GetSrc1 ()->AsLabelOpnd ()->GetLabel ();
989+ uint32 shift = instr->GetSrc2 ()->AsIntConstOpnd ()->AsUint32 ();
990+
991+ // We're going to drop src2, set src1 to just the masked bits from the label
992+ // offset (so we don't even need to go into relocation), and emit it.
993+ instr->UnlinkSrc2 ();
994+ uintptr_t fullvalue = labelInstr->GetOffset ();
995+ instr->ReplaceSrc1 (IR::IntConstOpnd::New ((fullvalue & (0xffff << shift)) >> shift, IRType::TyUint16, instr->m_func , true ));
996+ bytes = this ->EmitMovConstantKnownShift (Emitter, instr, EmitMovz, EmitMovz64, shift);
997+ }
998+ break ;
999+
9421000 case Js::OpCode::MRS_FPCR:
9431001 dst = instr->GetDst ();
9441002 Assert (dst->IsRegOpnd ());
@@ -1303,7 +1361,7 @@ EncoderMD::Encode(IR::Instr *instr, BYTE *pc, BYTE* beginCodeAddress)
13031361 Assert (encodeResult);
13041362 // We are re-using offset to save the inlineeCallInfo which will be patched in ApplyRelocs
13051363 // This is a cleaner way to patch MOVW\MOVT pair with the right inlineeCallInfo
1306- instr->AsLabelInstr ()->ResetOffset ((uint32 )inlineeCallInfo);
1364+ instr->AsLabelInstr ()->ResetOffset ((uintptr_t )inlineeCallInfo);
13071365 }
13081366 else
13091367 {
@@ -1459,6 +1517,7 @@ EncoderMD::ApplyRelocs(size_t codeBufferAddress, size_t codeSize, uint* bufferCR
14591517 break ;
14601518
14611519 case RelocTypeLabelAdr:
1520+ Assert (!reloc->m_relocInstr ->isInlineeEntryInstr );
14621521 immediate = ULONG_PTR (targetAddress) - ULONG_PTR (relocAddress);
14631522 Assert (IS_CONST_INT21 (immediate));
14641523 *relocAddress = (*relocAddress & ~(3 << 29 )) | ULONG ((immediate & 3 ) << 29 );
0 commit comments