EncoderMD.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "ARMEncode.h"
  6. #include "LegalizeMD.h"
  7. class Encoder;
  8. enum RelocType {
  9. RelocTypeBranch20,
  10. RelocTypeBranch24,
  11. RelocTypeDataLabelLow,
  12. RelocTypeLabelLow,
  13. RelocTypeLabelHigh,
  14. RelocTypeLabel
  15. };
  16. enum InstructionType {
  17. None = 0,
  18. Thumb = 2,
  19. Vfp = 3,
  20. Thumb2 = 4,
  21. };
  22. ///---------------------------------------------------------------------------
  23. ///
  24. /// class EncoderReloc
  25. ///
  26. ///---------------------------------------------------------------------------
  27. class EncodeReloc
  28. {
  29. public:
  30. static void New(EncodeReloc **pHead, RelocType relocType, BYTE *offset, IR::Instr *relocInstr, ArenaAllocator *alloc);
  31. public:
  32. EncodeReloc * m_next;
  33. RelocType m_relocType;
  34. BYTE * m_consumerOffset; // offset in instruction stream
  35. IR::Instr * m_relocInstr;
  36. };
  37. ///---------------------------------------------------------------------------
  38. ///
  39. /// class EncoderMD
  40. ///
  41. ///---------------------------------------------------------------------------
  42. class EncoderMD
  43. {
  44. public:
  45. EncoderMD(Func * func) : m_func(func), consecutiveThumbInstrCount(0) { }
  46. ptrdiff_t Encode(IR::Instr * instr, BYTE *pc, BYTE* beginCodeAddress = nullptr);
  47. void Init(Encoder *encoder);
  48. void ApplyRelocs(uint32 codeBufferAddress, size_t codeSize, uint* bufferCRC, BOOL isBrShorteningSucceeded, bool isFinalBufferValidation = false);
  49. static bool TryConstFold(IR::Instr *instr, IR::RegOpnd *regOpnd);
  50. static bool TryFold(IR::Instr *instr, IR::RegOpnd *regOpnd);
  51. const BYTE GetRegEncode(IR::RegOpnd *regOpnd);
  52. const BYTE GetFloatRegEncode(IR::RegOpnd *regOpnd);
  53. static const BYTE GetRegEncode(RegNum reg);
  54. static uint32 GetOpdope(IR::Instr *instr);
  55. static uint32 GetOpdope(Js::OpCode op);
  56. static bool IsLoad(IR::Instr *instr)
  57. {
  58. return ISLOAD(instr->m_opcode);
  59. }
  60. static bool IsStore(IR::Instr *instr)
  61. {
  62. return ISSTORE(instr->m_opcode);
  63. }
  64. static bool IsShifterUpdate(IR::Instr *instr)
  65. {
  66. return ISSHIFTERUPDATE(instr->m_opcode);
  67. }
  68. static bool IsShifterSub(IR::Instr *instr)
  69. {
  70. return ISSHIFTERSUB(instr->m_opcode);
  71. }
  72. static bool IsShifterPost(IR::Instr *instr)
  73. {
  74. return ISSHIFTERPOST(instr->m_opcode);
  75. }
  76. static bool SetsSBit(IR::Instr *instr)
  77. {
  78. return SETS_SBIT(instr->m_opcode);
  79. }
  80. void AddLabelReloc(BYTE* relocAddress);
  81. static bool CanEncodeModConst12(DWORD constant);
  82. static bool CanEncodeLoadStoreOffset(int32 offset) { return IS_CONST_UINT12(offset); }
  83. static void BaseAndOffsetFromSym(IR::SymOpnd *symOpnd, RegNum *pBaseReg, int32 *pOffset, Func * func);
  84. static bool EncodeImmediate16(int32 constant, DWORD * result);
  85. static ENCODE_32 BranchOffset_T2_24(int x);
  86. void EncodeInlineeCallInfo(IR::Instr *instr, uint32 offset);
  87. private:
  88. Func * m_func;
  89. Encoder * m_encoder;
  90. BYTE * m_pc;
  91. EncodeReloc * m_relocList;
  92. uint consecutiveThumbInstrCount; //Count of consecutive 16 bit thumb instructions.
  93. private:
  94. int GetForm(IR::Instr *instr, int32 size);
  95. ENCODE_32 GenerateEncoding(IR::Instr* instr, IFORM iform, BYTE *pc, int32 size, InstructionType intrType);
  96. InstructionType CanonicalizeInstr(IR::Instr *instr);
  97. InstructionType CanonicalizeAdd(IR::Instr * instr);
  98. InstructionType CanonicalizeSub(IR::Instr * instr);
  99. InstructionType CanonicalizeMov(IR::Instr * instr);
  100. InstructionType CanonicalizeLoad(IR::Instr * instr);
  101. InstructionType CanonicalizeStore(IR::Instr * instr);
  102. InstructionType CanonicalizeLea(IR::Instr * instr);
  103. InstructionType CmpEncodeType(IR::Instr * instr);
  104. InstructionType CmnEncodeType(IR::Instr * instr);
  105. InstructionType PushPopEncodeType(IR::IndirOpnd *target, IR::RegBVOpnd * opnd);
  106. InstructionType Alu2EncodeType(IR::Opnd *opnd1, IR::Opnd *opnd2);
  107. InstructionType Alu3EncodeType(IR::Instr * instr);
  108. InstructionType ShiftEncodeType(IR::Instr * instr);
  109. bool IsWideMemInstr(IR::Opnd * memOpnd, IR::RegOpnd * regOpnd);
  110. bool IsWideAddSub(IR::Instr * instr);
  111. static ENCODE_32 EncodeT2Immediate12(ENCODE_32 encode, int32 constant);
  112. static bool EncodeModConst12(DWORD constant, DWORD * result);
  113. static ENCODE_32 EncodeT2Offset(ENCODE_32 encode, IR::Instr *instr, int offset, int bitOffset);
  114. #ifdef SOFTWARE_FIXFOR_HARDWARE_BUGWIN8_502326
  115. static bool CheckBranchInstrCriteria(IR::Instr* instr);
  116. static bool IsBuggyHardware();
  117. #endif
  118. ENCODE_32 BranchOffset_T2_20(int x);
  119. ENCODE_32 CallOffset(int x);
  120. int IndirForm(int form, int *pOpnnum, RegNum baseReg, IR::Opnd *indexOpnd);
  121. };