[PATCH] D141752: [AVR] Fix an issue of writing 16-bit ports

Ben Shi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 14 00:45:24 PST 2023


benshi001 created this revision.
benshi001 added reviewers: aykevl, dylanmckay.
Herald added subscribers: Jim, hiraditya.
Herald added a project: All.
benshi001 requested review of this revision.
Herald added subscribers: llvm-commits, jacquesguan.
Herald added a project: LLVM.

For 16-bit ports, the normal devices reqiure writing high byte first
and then low byte. But the XMEGA devices require the revsere order.

Fixes https://github.com/llvm/llvm-project/issues/58395


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141752

Files:
  llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
  llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir


Index: llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir
===================================================================
--- llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir
+++ llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir
@@ -1,4 +1,13 @@
-# RUN: llc -O0 -run-pass=avr-expand-pseudo %s -o - | FileCheck %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=attiny11 %s -o - \
+# RUN:     | FileCheck %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=atmega328 %s -o - \
+# RUN:     | FileCheck %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=attiny817 %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=atxmega64a1 %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mtriple=avr -mcpu=atxmega256a3u %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
 
 --- |
   target triple = "avr--"
@@ -15,9 +24,12 @@
     liveins: $r15r14
 
     ; CHECK-LABEL: test
+    ; CHECK:       OUTARr 32, $r15
+    ; CHECK-NEXT:  OUTARr 31, $r14
 
-    ; CHECK:      OUTARr 32, $r15
-    ; CHECK-NEXT: OUTARr 31, $r14
+    ; XMEGA-LABEL: test
+    ; XMEGA:       OUTARr 31, $r14
+    ; XMEGA-NEXT:  OUTARr 32, $r15
 
     OUTWARr 31, $r15r14
 ...
Index: llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
===================================================================
--- llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -17,6 +17,7 @@
 #include "AVRTargetMachine.h"
 #include "MCTargetDesc/AVRMCTargetDesc.h"
 
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -1257,27 +1258,32 @@
 
 template <>
 bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
+  const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
   MachineInstr &MI = *MBBI;
   Register SrcLoReg, SrcHiReg;
   unsigned Imm = MI.getOperand(0).getImm();
   Register SrcReg = MI.getOperand(1).getReg();
   bool SrcIsKill = MI.getOperand(1).isKill();
-  unsigned OpLo = AVR::OUTARr;
-  unsigned OpHi = AVR::OUTARr;
   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
 
   // Since we add 1 to the Imm value for the high byte below, and 63 is the
   // highest Imm value allowed for the instruction, 62 is the limit here.
   assert(Imm <= 62 && "Address is out of range");
 
-  // 16 bit I/O writes need the high byte first
-  auto MIBHI = buildMI(MBB, MBBI, OpHi)
-                   .addImm(Imm + 1)
-                   .addReg(SrcHiReg, getKillRegState(SrcIsKill));
+  unsigned ELFArch = STI.getELFArch();
+  bool XMega =
+      ELF::EF_AVR_ARCH_XMEGA1 <= ELFArch && ELFArch <= ELF::EF_AVR_ARCH_XMEGA7;
 
-  auto MIBLO = buildMI(MBB, MBBI, OpLo)
-                   .addImm(Imm)
-                   .addReg(SrcLoReg, getKillRegState(SrcIsKill));
+  // 16 bit I/O writes need the high byte first on normal AVR devices,
+  // and in reverse order for the XMEGA/XMEGA3/XMEGAU families.
+  auto MIBHI =
+      buildMI(MBB, MBBI, AVR::OUTARr)
+          .addImm(XMega ? Imm : Imm + 1)
+          .addReg(XMega ? SrcLoReg : SrcHiReg, getKillRegState(SrcIsKill));
+  auto MIBLO =
+      buildMI(MBB, MBBI, AVR::OUTARr)
+          .addImm(XMega ? Imm + 1 : Imm)
+          .addReg(XMega ? SrcHiReg : SrcLoReg, getKillRegState(SrcIsKill));
 
   MIBLO.setMemRefs(MI.memoperands());
   MIBHI.setMemRefs(MI.memoperands());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D141752.489206.patch
Type: text/x-patch
Size: 3518 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230114/e144f586/attachment.bin>


More information about the llvm-commits mailing list