Target.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //===-- Target.cpp ----------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. // The PowerPC ExegesisTarget.
  8. //===----------------------------------------------------------------------===//
  9. #include "../Target.h"
  10. #include "PPC.h"
  11. #include "PPCRegisterInfo.h"
  12. namespace llvm {
  13. namespace exegesis {
  14. // Helper to fill a memory operand with a value.
  15. static void setMemOp(InstructionTemplate &IT, int OpIdx,
  16. const MCOperand &OpVal) {
  17. const auto Op = IT.getInstr().Operands[OpIdx];
  18. assert(Op.isExplicit() && "invalid memory pattern");
  19. IT.getValueFor(Op) = OpVal;
  20. }
  21. #include "PPCGenExegesis.inc"
  22. namespace {
  23. class ExegesisPowerPCTarget : public ExegesisTarget {
  24. public:
  25. ExegesisPowerPCTarget() : ExegesisTarget(PPCCpuPfmCounters) {}
  26. private:
  27. std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
  28. const APInt &Value) const override;
  29. bool matchesArch(Triple::ArchType Arch) const override {
  30. return Arch == Triple::ppc64le;
  31. }
  32. unsigned getScratchMemoryRegister(const Triple &) const override;
  33. void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
  34. unsigned Offset) const override;
  35. };
  36. } // end anonymous namespace
  37. static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
  38. switch (RegBitWidth) {
  39. case 32:
  40. return PPC::LI;
  41. case 64:
  42. return PPC::LI8;
  43. }
  44. llvm_unreachable("Invalid Value Width");
  45. }
  46. // Generates instruction to load an immediate value into a register.
  47. static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
  48. const APInt &Value) {
  49. if (Value.getBitWidth() > RegBitWidth)
  50. llvm_unreachable("Value must fit in the Register");
  51. // We don't really care the value in reg, ignore the 16 bit
  52. // restriction for now.
  53. // TODO: make sure we get the exact value in reg if needed.
  54. return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
  55. .addReg(Reg)
  56. .addImm(Value.getZExtValue());
  57. }
  58. unsigned
  59. ExegesisPowerPCTarget::getScratchMemoryRegister(const Triple &TT) const {
  60. // R13 is reserved as Thread Pointer, we won't use threading in benchmark, so
  61. // use it as scratch memory register
  62. return TT.isArch64Bit() ? PPC::X13 : PPC::R13;
  63. }
  64. void ExegesisPowerPCTarget::fillMemoryOperands(InstructionTemplate &IT,
  65. unsigned Reg,
  66. unsigned Offset) const {
  67. int MemOpIdx = 0;
  68. if (IT.getInstr().hasTiedRegisters())
  69. MemOpIdx = 1;
  70. int DispOpIdx = MemOpIdx + 1;
  71. const auto DispOp = IT.getInstr().Operands[DispOpIdx];
  72. if (DispOp.isReg())
  73. // We don't really care about the real address in snippets,
  74. // So hardcode X1 for X-form Memory Operations for simplicity.
  75. // TODO: materialize the offset into a reggister
  76. setMemOp(IT, DispOpIdx, MCOperand::createReg(PPC::X1));
  77. else
  78. setMemOp(IT, DispOpIdx, MCOperand::createImm(Offset)); // Disp
  79. setMemOp(IT, MemOpIdx + 2, MCOperand::createReg(Reg)); // BaseReg
  80. }
  81. std::vector<MCInst> ExegesisPowerPCTarget::setRegTo(const MCSubtargetInfo &STI,
  82. unsigned Reg,
  83. const APInt &Value) const {
  84. // X11 is optional use in function linkage, should be the least used one
  85. // Use it as scratch reg to load immediate.
  86. unsigned ScratchImmReg = PPC::X11;
  87. if (PPC::GPRCRegClass.contains(Reg))
  88. return {loadImmediate(Reg, 32, Value)};
  89. if (PPC::G8RCRegClass.contains(Reg))
  90. return {loadImmediate(Reg, 64, Value)};
  91. if (PPC::F4RCRegClass.contains(Reg))
  92. return {loadImmediate(ScratchImmReg, 64, Value),
  93. MCInstBuilder(PPC::MTVSRD).addReg(Reg).addReg(ScratchImmReg)};
  94. // We don't care the real value in reg, so set 64 bits or duplicate 64 bits
  95. // for simplicity.
  96. // TODO: update these if we need a accurate 128 values in registers.
  97. if (PPC::VRRCRegClass.contains(Reg))
  98. return {loadImmediate(ScratchImmReg, 64, Value),
  99. MCInstBuilder(PPC::MTVRD).addReg(Reg).addReg(ScratchImmReg)};
  100. if (PPC::VSRCRegClass.contains(Reg))
  101. return {loadImmediate(ScratchImmReg, 64, Value),
  102. MCInstBuilder(PPC::MTVSRDD)
  103. .addReg(Reg)
  104. .addReg(ScratchImmReg)
  105. .addReg(ScratchImmReg)};
  106. if (PPC::VFRCRegClass.contains(Reg))
  107. return {loadImmediate(ScratchImmReg, 64, Value),
  108. MCInstBuilder(PPC::MTVSRD).addReg(Reg).addReg(ScratchImmReg)};
  109. // SPE not supported yet
  110. if (PPC::SPERCRegClass.contains(Reg)) {
  111. errs() << "Unsupported SPE Reg:" << Reg << "\n";
  112. return {};
  113. }
  114. errs() << "setRegTo is not implemented, results will be unreliable:" << Reg
  115. << "\n";
  116. return {};
  117. }
  118. static ExegesisTarget *getTheExegesisPowerPCTarget() {
  119. static ExegesisPowerPCTarget Target;
  120. return &Target;
  121. }
  122. void InitializePowerPCExegesisTarget() {
  123. ExegesisTarget::registerTarget(getTheExegesisPowerPCTarget());
  124. }
  125. } // namespace exegesis
  126. } // namespace llvm