LegalizeMD.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. #pragma once
  6. enum LegalForms
  7. {
  8. L_None = 0,
  9. L_Reg = 1,
  10. L_RegMask = L_Reg,
  11. L_ImmLog12 = 0x10,
  12. L_ImmU12 = 0x20,
  13. L_ImmU12Lsl12 = 0x40,
  14. L_ImmU6 = 0x80,
  15. L_ImmU16 = 0x100,
  16. L_Imm = 0x200,
  17. L_ImmU6U6 = 0x400,
  18. L_ImmMask = (L_ImmLog12 | L_ImmU12 | L_ImmU12Lsl12 | L_ImmU6 | L_ImmU16 | L_Imm | L_ImmU6U6),
  19. L_IndirSU12I9 = 0x1000,
  20. L_IndirSI7 = 0x2000,
  21. L_IndirU12 = 0x4000,
  22. L_IndirU12Lsl12=0x8000,
  23. L_IndirMask = (L_IndirSU12I9 | L_IndirSI7 | L_IndirU12 | L_IndirU12Lsl12),
  24. L_SymSU12I9 = 0x10000,
  25. L_SymSI7 = 0x20000,
  26. L_SymU12 = 0x40000,
  27. L_SymU12Lsl12 =0x80000,
  28. L_SymMask = (L_SymSU12I9 | L_SymSI7 | L_SymU12 | L_SymU12Lsl12),
  29. L_Lab20 = 0x100000,
  30. L_Label = 0x200000,
  31. L_RegBV = 0x1000000,
  32. };
  33. struct LegalInstrForms
  34. {
  35. LegalForms dst, src[2];
  36. };
  37. #define LEGAL_NONE { L_None, { L_None, L_None } }
  38. // Used for opcodes that should be converted before legalizer kicks in
  39. #define LEGAL_PSEUDO LEGAL_NONE
  40. #define LEGAL_ADDSUB { L_Reg, { L_Reg, (LegalForms)(L_Reg | L_ImmU12 | L_ImmU12Lsl12) } }
  41. #define LEGAL_ALU2 { L_Reg, { (LegalForms)(L_Reg | L_ImmLog12), L_None } }
  42. #define LEGAL_ALU3 { L_Reg, { L_Reg, (LegalForms)(L_Reg | L_ImmLog12) } }
  43. #define LEGAL_SHIFT { L_Reg, { L_Reg, (LegalForms)(L_Reg | L_ImmU6) } }
  44. #define LEGAL_BITFIELD { L_Reg, { L_Reg, L_ImmU6U6 } }
  45. #define LEGAL_BLAB LEGAL_NONE
  46. #define LEGAL_CALL { L_Reg, { L_Lab20 , L_None } } // Not currently generated, offset check is missing
  47. #define LEGAL_CBZ { L_None, { L_Reg } }
  48. #define LEGAL_LABEL { L_Reg, { L_Label } }
  49. #define LEGAL_LDIMM { L_Reg, { L_Imm, L_None } }
  50. #define LEGAL_LDIMM_S { L_Reg, { (LegalForms)(L_ImmU16 | L_Label), L_ImmU6 } }
  51. #define LEGAL_LEA { L_Reg, { (LegalForms)(L_IndirU12Lsl12 | L_SymU12Lsl12), L_None } }
  52. #define LEGAL_LOAD { L_Reg, { (LegalForms)(L_IndirSU12I9 | L_SymSU12I9), L_None } }
  53. #define LEGAL_LOADP { L_Reg, { (LegalForms)(L_IndirSI7 | L_SymSI7), L_Reg } }
  54. #define LEGAL_PLD { L_None, { (LegalForms)(L_IndirSU12I9 | L_SymSU12I9), L_None } }
  55. #define LEGAL_REG1 { L_Reg, { L_None, L_None } }
  56. #define LEGAL_REG2 { L_Reg, { L_Reg, L_None } }
  57. #define LEGAL_REG2_ND { L_None, { L_Reg, L_None } }
  58. #define LEGAL_REG3 { L_Reg, { L_Reg, L_Reg } }
  59. #define LEGAL_REG3_ND { L_None, { L_Reg, L_Reg } }
  60. #define LEGAL_STORE { (LegalForms)(L_IndirSU12I9 | L_SymSU12I9), { L_Reg, L_None } }
  61. #define LEGAL_STOREP { (LegalForms)(L_IndirSI7 | L_SymSI7), { L_Reg, L_Reg } }
  62. #define LEGAL_TBZ { L_None, { L_Reg, L_ImmU6 } }
  63. class LegalizeMD
  64. {
  65. public:
  66. static void LegalizeInstr(IR::Instr * instr);
  67. static void LegalizeDst(IR::Instr * instr);
  68. static void LegalizeSrc(IR::Instr * instr, IR::Opnd * opnd, uint opndNum);
  69. static bool LegalizeDirectBranch(IR::BranchInstr *instr, uintptr_t branchOffset);
  70. static bool LegalizeAdrOffset(IR::Instr *instr, uintptr_t instrOffset);
  71. static bool LegalizeDataAdr(IR::Instr *instr, uintptr_t dataOffset);
  72. private:
  73. static RegNum GetScratchReg(IR::Instr * instr);
  74. static void LegalizeRegOpnd(IR::Instr* instr, IR::Opnd* opnd);
  75. static IR::Instr *LegalizeStore(IR::Instr *instr, LegalForms forms);
  76. static IR::Instr *LegalizeLoad(IR::Instr *instr, uint opndNum, LegalForms forms);
  77. static void LegalizeIndirOffset(IR::Instr * instr, IR::IndirOpnd * indirOpnd, LegalForms forms);
  78. static void LegalizeSymOffset(IR::Instr * instr, IR::SymOpnd * indirOpnd, LegalForms forms);
  79. static void LegalizeImmed(IR::Instr * instr, IR::Opnd * opnd, uint opndNum, IntConstType immed, LegalForms forms);
  80. static void LegalizeLabelOpnd(IR::Instr * instr, IR::Opnd * opnd, uint opndNum);
  81. static inline uint32 ShiftTo16(UIntConstType* immed)
  82. {
  83. uint32 shift = 0;
  84. while (((*immed) & 0xffff) != *immed)
  85. {
  86. (*immed) >>= 16;
  87. shift += 16;
  88. }
  89. Assert(shift == 0 || shift == 16 || shift == 32 || shift == 48);
  90. return shift;
  91. }
  92. static void LegalizeLDIMM(IR::Instr * instr, IntConstType immed);
  93. static void LegalizeLdLabel(IR::Instr * instr, IR::Opnd * opnd);
  94. static IR::Instr * GenerateLDIMM(IR::Instr * instr, uint opndNum, RegNum scratchReg);
  95. static IR::Instr * GenerateHoistSrc(IR::Instr * instr, uint opndNum, Js::OpCode op, RegNum scratchReg);
  96. static void ObfuscateLDIMM(IR::Instr * instrMov, IR::Instr * instrMovt);
  97. static void EmitRandomNopBefore(IR::Instr * instrMov, UINT_PTR rand, RegNum targetReg);
  98. #ifdef DBG
  99. static void IllegalInstr(IR::Instr * instr, const char16 * msg, ...);
  100. #endif
  101. };