LegalizeMD.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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_ImmModC12 = 0x10,
  12. L_ImmU12 = 0x20,
  13. L_ImmU5 = 0x40,
  14. L_ImmU16 = 0x80,
  15. L_Imm = 0x100,
  16. L_ImmMask = (L_ImmModC12 | L_ImmU12 | L_ImmU5 | L_ImmU16 | L_Imm),
  17. L_IndirI8 = 0x1000,
  18. L_IndirU12I8 = 0x2000,
  19. L_IndirU12 = 0x4000,
  20. L_VIndirI11 = 0x8000,
  21. L_IndirMask = (L_IndirI8 | L_IndirU12I8 | L_IndirU12 | L_VIndirI11),
  22. L_SymU12I8 = 0x10000,
  23. L_SymU12 = 0x20000,
  24. L_VSymI11 = 0x40000,
  25. L_SymMask = (L_SymU12I8 | L_SymU12 | L_VSymI11),
  26. L_Lab20 = 0x100000,
  27. L_RegBV = 0x1000000,
  28. };
  29. struct LegalInstrForms
  30. {
  31. LegalForms dst, src[2];
  32. };
  33. #define LEGAL_NONE { L_None, { L_None, L_None } }
  34. #define LEGAL_ADDSUB { L_Reg, { L_Reg, (LegalForms)(L_Reg | L_ImmModC12 | L_ImmU12) } }
  35. #define LEGAL_ADDSUBW { L_Reg, { L_Reg, (LegalForms)(L_Reg | L_ImmU12) } }
  36. #define LEGAL_ALU2 { L_Reg, { (LegalForms)(L_Reg | L_ImmModC12), L_None } }
  37. #define LEGAL_ALU3 { L_Reg, { L_Reg, (LegalForms)(L_Reg | L_ImmModC12) } }
  38. #define LEGAL_SHIFT { L_Reg, { L_Reg, (LegalForms)(L_Reg | L_ImmU5) } }
  39. #define LEGAL_BLAB LEGAL_NONE
  40. #define LEGAL_BREG { L_None, { L_Reg, L_None } }
  41. #define LEGAL_CALL { L_Reg, { L_Lab20 , L_None } } // Not currently generated, offset check is missing
  42. #define LEGAL_CALLREG { L_Reg, { L_Reg, L_None } }
  43. #define LEGAL_CMP { L_None, { L_Reg, (LegalForms)(L_Reg | L_ImmModC12) } }
  44. #define LEGAL_CMP_SH { L_None, { L_Reg, L_Reg } }
  45. #define LEGAL_CMP1 { L_None, { L_Reg, L_None } }
  46. #define LEGAL_CMN { L_None, { L_Reg, (LegalForms)(L_Reg | L_ImmModC12) } }
  47. #define LEGAL_LDIMM { L_Reg, { L_Imm, L_None } }
  48. #define LEGAL_LEA { L_Reg, { (LegalForms)(L_SymU12 | L_IndirU12), L_None } }
  49. #define LEGAL_LOAD { L_Reg, { (LegalForms)(L_IndirU12I8 | L_SymU12I8), L_None } }
  50. #define LEGAL_MOVIMM16 { L_Reg, { L_ImmU16, L_None } }
  51. #define LEGAL_PUSHPOP { L_IndirI8, { L_RegBV, L_None } }
  52. #define LEGAL_REG1 { L_Reg, { L_None, L_None } }
  53. #define LEGAL_REG2 { L_Reg, { L_Reg, L_None } }
  54. #define LEGAL_REG3 { L_Reg, { L_Reg, L_Reg } }
  55. #define LEGAL_STORE { (LegalForms)(L_IndirU12I8 | L_SymU12I8), { L_Reg, L_None } }
  56. #define LEGAL_VSTORE { (LegalForms)(L_VSymI11 | L_VIndirI11), { L_Reg, L_None } }
  57. #define LEGAL_VLOAD { L_Reg, { (LegalForms)(L_VSymI11 | L_VIndirI11), L_None } }
  58. #define LEGAL_VPUSHPOP { L_IndirI8, { L_RegBV, L_None } }
  59. class LegalizeMD
  60. {
  61. public:
  62. static void LegalizeInstr(IR::Instr * instr, bool fPostRegAlloc);
  63. static void LegalizeDst(IR::Instr * instr, bool fPostRegAlloc);
  64. static void LegalizeSrc(IR::Instr * instr, IR::Opnd * opnd, uint opndNum, bool fPostRegAlloc);
  65. static bool LegalizeDirectBranch(IR::BranchInstr *instr, uint32 branchOffset); // DirectBranch has no src & dst operands.
  66. //Returns IndexOpnd which is removed from VFP indirect operand
  67. static void LegalizeIndirOpndForVFP(IR::Instr* insertInstr, IR::IndirOpnd *indirOpnd, bool fPostRegAlloc);
  68. private:
  69. static IR::Instr *LegalizeStore(IR::Instr *instr, LegalForms forms, bool fPostRegAlloc);
  70. static IR::Instr *LegalizeLoad(IR::Instr *instr, uint opndNum, LegalForms forms, bool fPostRegAlloc);
  71. static void LegalizeIndirOffset(IR::Instr * instr, IR::IndirOpnd * indirOpnd, LegalForms forms, bool fPostRegAlloc);
  72. static void LegalizeSymOffset(IR::Instr * instr, IR::SymOpnd * indirOpnd, LegalForms forms, bool fPostRegAlloc);
  73. static void LegalizeImmed(IR::Instr * instr, IR::Opnd * opnd, uint opndNum, IntConstType immed, LegalForms forms, bool fPostRegAlloc);
  74. static void LegalizeLabelOpnd(IR::Instr * instr, IR::Opnd * opnd, uint opndNum, bool fPostRegAlloc);
  75. static void LegalizeLDIMM(IR::Instr * instr, IntConstType immed);
  76. static void LegalizeLdLabel(IR::Instr * instr, IR::Opnd * opnd);
  77. static IR::Instr * GenerateLDIMM(IR::Instr * instr, uint opndNum, RegNum scratchReg);
  78. static void ObfuscateLDIMM(IR::Instr * instrMov, IR::Instr * instrMovt);
  79. static void EmitRandomNopBefore(IR::Instr * instrMov, UINT_PTR rand, RegNum targetReg);
  80. #ifdef DBG
  81. static void IllegalInstr(IR::Instr * instr, const wchar_t * msg, ...);
  82. #endif
  83. };