|
8 | 8 | #include "../Target.h" |
9 | 9 | #include "AArch64.h" |
10 | 10 | #include "AArch64RegisterInfo.h" |
| 11 | +#include "llvm/CodeGen/MachineInstrBuilder.h" |
11 | 12 |
|
12 | 13 | #if defined(__aarch64__) && defined(__linux__) |
13 | 14 | #include <sys/prctl.h> // For PR_PAC_* constants |
@@ -109,6 +110,10 @@ static MCInst loadFPImmediate(MCRegister Reg, unsigned RegBitWidth, |
109 | 110 |
|
110 | 111 | namespace { |
111 | 112 |
|
| 113 | +// Use X19 as the loop counter register since it's a callee-saved register |
| 114 | +// that's available for temporary use. |
| 115 | +constexpr const MCPhysReg kDefaultLoopCounterReg = AArch64::X19; |
| 116 | + |
112 | 117 | class ExegesisAArch64Target : public ExegesisTarget { |
113 | 118 | public: |
114 | 119 | ExegesisAArch64Target() |
@@ -141,6 +146,31 @@ class ExegesisAArch64Target : public ExegesisTarget { |
141 | 146 | errs() << "setRegTo is not implemented, results will be unreliable\n"; |
142 | 147 | return {}; |
143 | 148 | } |
| 149 | + MCRegister getDefaultLoopCounterRegister(const Triple &) const override { |
| 150 | + return kDefaultLoopCounterReg; |
| 151 | + } |
| 152 | + |
| 153 | + void decrementLoopCounterAndJump(MachineBasicBlock &MBB, |
| 154 | + MachineBasicBlock &TargetMBB, |
| 155 | + const MCInstrInfo &MII, |
| 156 | + MCRegister LoopRegister) const override { |
| 157 | + // subs LoopRegister, LoopRegister, #1 |
| 158 | + BuildMI(&MBB, DebugLoc(), MII.get(AArch64::SUBSXri)) |
| 159 | + .addDef(LoopRegister) |
| 160 | + .addUse(LoopRegister) |
| 161 | + .addImm(1) // Subtract 1 |
| 162 | + .addImm(0); // No shift amount |
| 163 | + // b.ne TargetMBB |
| 164 | + BuildMI(&MBB, DebugLoc(), MII.get(AArch64::Bcc)) |
| 165 | + .addImm(AArch64CC::NE) |
| 166 | + .addMBB(&TargetMBB); |
| 167 | + } |
| 168 | + |
| 169 | + // Registers that should not be selected for use in snippets. |
| 170 | + const MCPhysReg UnavailableRegisters[1] = {kDefaultLoopCounterReg}; |
| 171 | + ArrayRef<MCPhysReg> getUnavailableRegisters() const override { |
| 172 | + return UnavailableRegisters; |
| 173 | + } |
144 | 174 |
|
145 | 175 | bool matchesArch(Triple::ArchType Arch) const override { |
146 | 176 | return Arch == Triple::aarch64 || Arch == Triple::aarch64_be; |
|
0 commit comments