[PATCH] D116493: [AVR] Generate ELPM for loading byte/word from extended program memory

Ayke via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 4 15:51:10 PST 2022


aykevl added inline comments.


================
Comment at: llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp:828
+    const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
+    Register TmpReg = scavengeGPR8(MI);
+    int Bank = MI.getOperand(2).getImm();
----------------
aykevl wrote:
> There is actually a much more elegant way to do this: by giving ELPMRdZ (and similar) instructions an extra LD8 input and output register. This makes sure the register allocator allocates a spare register for this instruction. The `scavengeGPR8` method is really just a hack to find an unused register and it can fail if no register is available. In addition, by telling the register allocator you need an LD8 register, you don't need the if/else below.
I recently implemented this, in a work-in-progress change. It looks like this in my case:

```
+let Constraints = "@earlyclobber $scratch" in
 class AtomicLoad<PatFrag Op, RegisterClass DRC,
                  RegisterClass PTRRC> :
-  Pseudo<(outs DRC:$rd), (ins PTRRC:$rr), "atomic_op",
-         [(set DRC:$rd, (Op i16:$rr))]>;
+  Pseudo<(outs DRC:$rd, GPR8:$scratch), (ins PTRRC:$rr), "atomic_op",
+         [(set DRC:$rd, (Op i16:$rr)), (set GPR8:$scratch, SREG)]>;
```

So essentially, this adds a new output with the "earlyclobber" flag set. This scratch register can then be used however you like.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116493/new/

https://reviews.llvm.org/D116493



More information about the llvm-commits mailing list