[llvm] 2a52876 - [AVR] Fix an issue of writing 16-bit ports

Ben Shi via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 17 00:35:49 PDT 2023


Author: Ben Shi
Date: 2023-04-17T15:35:33+08:00
New Revision: 2a528760bf20004066effcf8f91fedaabd261903

URL: https://github.com/llvm/llvm-project/commit/2a528760bf20004066effcf8f91fedaabd261903
DIFF: https://github.com/llvm/llvm-project/commit/2a528760bf20004066effcf8f91fedaabd261903.diff

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

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

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

Reviewed By: aykevl, jacquesguan

Differential Revision: https://reviews.llvm.org/D141752

Added: 
    

Modified: 
    llvm/lib/Target/AVR/AVRDevices.td
    llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
    llvm/lib/Target/AVR/AVRISelLowering.cpp
    llvm/lib/Target/AVR/AVRSubtarget.h
    llvm/test/CodeGen/AVR/PR37143.ll
    llvm/test/CodeGen/AVR/alloca.ll
    llvm/test/CodeGen/AVR/atomics/load16.ll
    llvm/test/CodeGen/AVR/atomics/store.ll
    llvm/test/CodeGen/AVR/atomics/store16.ll
    llvm/test/CodeGen/AVR/call.ll
    llvm/test/CodeGen/AVR/dynalloca.ll
    llvm/test/CodeGen/AVR/lpmx.ll
    llvm/test/CodeGen/AVR/pr43443-ctor-alias.ll
    llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir
    llvm/test/CodeGen/AVR/pseudo/STDWPtrQRr.mir
    llvm/test/CodeGen/AVR/pseudo/STSWKRr.mir
    llvm/test/CodeGen/AVR/pseudo/STWPtrRr.mir
    llvm/test/CodeGen/AVR/shift32.ll
    llvm/test/CodeGen/AVR/store.ll
    llvm/test/CodeGen/AVR/struct.ll
    llvm/test/CodeGen/AVR/varargs.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AVR/AVRDevices.td b/llvm/lib/Target/AVR/AVRDevices.td
index 8ecb0a1e7b12e..f6b36dba7733b 100644
--- a/llvm/lib/Target/AVR/AVRDevices.td
+++ b/llvm/lib/Target/AVR/AVRDevices.td
@@ -120,6 +120,12 @@ def FeatureTinyEncoding
                        "The device has Tiny core specific "
                        "instruction encodings">;
 
+// When writing a 16-bit port or storing a 16-bit word, do the low byte first.
+def FeatureLowByteFirst
+    : SubtargetFeature<"lowbytefirst", "m_hasLowByteFirst", "true",
+                       "Do the low byte first when writing a 16-bit port or "
+                       "storing a 16-bit word">;
+
 // The device has CPU registers mapped in data address space
 def FeatureMMR : SubtargetFeature<"memmappedregs", "m_hasMemMappedGPR", "true",
                                   "The device has CPU registers "
@@ -195,14 +201,15 @@ def FamilyXMEGA3 : Family<"xmega3",
                           [FamilyAVR0, FeatureLPM, FeatureIJMPCALL,
                            FeatureADDSUBIW, FeatureSRAM, FeatureJMPCALL,
                            FeatureMultiplication, FeatureMOVW, FeatureLPMX,
-                           FeatureBREAK]>;
+                           FeatureBREAK, FeatureLowByteFirst]>;
 
 def FamilyXMEGA : Family<"xmega",
                          [FamilyAVR0, FeatureLPM, FeatureIJMPCALL,
                           FeatureADDSUBIW, FeatureSRAM, FeatureJMPCALL,
                           FeatureMultiplication, FeatureMOVW, FeatureLPMX,
                           FeatureSPM, FeatureBREAK, FeatureEIJMPCALL,
-                          FeatureSPMX, FeatureDES, FeatureELPM, FeatureELPMX]>;
+                          FeatureSPMX, FeatureDES, FeatureELPM, FeatureELPMX,
+                          FeatureLowByteFirst]>;
 
 def FamilyXMEGAU : Family<"xmegau", [FamilyXMEGA, FeatureRMW]>;
 

diff  --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 5cdd98da768c9..5b3bb9eed3eee 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -1057,18 +1057,15 @@ bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) {
 
 template <>
 bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
+  const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
   MachineInstr &MI = *MBBI;
   Register SrcLoReg, SrcHiReg;
   Register SrcReg = MI.getOperand(1).getReg();
   bool SrcIsKill = MI.getOperand(1).isKill();
-  unsigned OpLo = AVR::STSKRr;
-  unsigned OpHi = AVR::STSKRr;
   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
 
-  // Write the high byte first in case this address belongs to a special
-  // I/O address with a special temporary register.
-  auto MIBHI = buildMI(MBB, MBBI, OpHi);
-  auto MIBLO = buildMI(MBB, MBBI, OpLo);
+  auto MIB0 = buildMI(MBB, MBBI, AVR::STSKRr);
+  auto MIB1 = buildMI(MBB, MBBI, AVR::STSKRr);
 
   switch (MI.getOperand(0).getType()) {
   case MachineOperand::MO_GlobalAddress: {
@@ -1076,26 +1073,50 @@ bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
     int64_t Offs = MI.getOperand(0).getOffset();
     unsigned TF = MI.getOperand(0).getTargetFlags();
 
-    MIBLO.addGlobalAddress(GV, Offs, TF);
-    MIBHI.addGlobalAddress(GV, Offs + 1, TF);
+    if (STI.hasLowByteFirst()) {
+      // Write the low byte first for XMEGA devices.
+      MIB0.addGlobalAddress(GV, Offs, TF);
+      MIB1.addGlobalAddress(GV, Offs + 1, TF);
+    } else {
+      // Write the high byte first for traditional devices.
+      MIB0.addGlobalAddress(GV, Offs + 1, TF);
+      MIB1.addGlobalAddress(GV, Offs, TF);
+    }
+
     break;
   }
   case MachineOperand::MO_Immediate: {
     unsigned Imm = MI.getOperand(0).getImm();
 
-    MIBLO.addImm(Imm);
-    MIBHI.addImm(Imm + 1);
+    if (STI.hasLowByteFirst()) {
+      // Write the low byte first for XMEGA devices.
+      MIB0.addImm(Imm);
+      MIB1.addImm(Imm + 1);
+    } else {
+      // Write the high byte first for traditional devices.
+      MIB0.addImm(Imm + 1);
+      MIB1.addImm(Imm);
+    }
+
     break;
   }
   default:
     llvm_unreachable("Unknown operand type!");
   }
 
-  MIBLO.addReg(SrcLoReg, getKillRegState(SrcIsKill));
-  MIBHI.addReg(SrcHiReg, getKillRegState(SrcIsKill));
-
-  MIBLO.setMemRefs(MI.memoperands());
-  MIBHI.setMemRefs(MI.memoperands());
+  if (STI.hasLowByteFirst()) {
+    // Write the low byte first for XMEGA devices.
+    MIB0.addReg(SrcLoReg, getKillRegState(SrcIsKill))
+        .setMemRefs(MI.memoperands());
+    MIB1.addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMemRefs(MI.memoperands());
+  } else {
+    // Write the high byte first for traditional devices.
+    MIB0.addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMemRefs(MI.memoperands());
+    MIB1.addReg(SrcLoReg, getKillRegState(SrcIsKill))
+        .setMemRefs(MI.memoperands());
+  }
 
   MI.eraseFromParent();
   return true;
@@ -1126,16 +1147,27 @@ bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
   } else {
     Register SrcLoReg, SrcHiReg;
     TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
-    buildMI(MBB, MBBI, AVR::STPtrRr)
-        .addReg(DstReg, getUndefRegState(DstIsUndef))
-        .addReg(SrcLoReg, getKillRegState(SrcIsKill))
-        .setMemRefs(MI.memoperands());
-
-    buildMI(MBB, MBBI, AVR::STDPtrQRr)
-        .addReg(DstReg, getUndefRegState(DstIsUndef))
-        .addImm(1)
-        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
-        .setMemRefs(MI.memoperands());
+    if (STI.hasLowByteFirst()) {
+      buildMI(MBB, MBBI, AVR::STPtrRr)
+          .addReg(DstReg, getUndefRegState(DstIsUndef))
+          .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+      buildMI(MBB, MBBI, AVR::STDPtrQRr)
+          .addReg(DstReg, getUndefRegState(DstIsUndef))
+          .addImm(1)
+          .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+    } else {
+      buildMI(MBB, MBBI, AVR::STDPtrQRr)
+          .addReg(DstReg, getUndefRegState(DstIsUndef))
+          .addImm(1)
+          .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+      buildMI(MBB, MBBI, AVR::STPtrRr)
+          .addReg(DstReg, getUndefRegState(DstIsUndef))
+          .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+    }
   }
 
   MI.eraseFromParent();
@@ -1252,23 +1284,32 @@ bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
           .addImm(Imm + 2);
     }
   } else {
-    unsigned OpLo = AVR::STDPtrQRr;
-    unsigned OpHi = AVR::STDPtrQRr;
     Register SrcLoReg, SrcHiReg;
     TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
 
-    auto MIBLO = buildMI(MBB, MBBI, OpLo)
-                     .addReg(DstReg)
-                     .addImm(Imm)
-                     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
-
-    auto MIBHI = buildMI(MBB, MBBI, OpHi)
-                     .addReg(DstReg, getKillRegState(DstIsKill))
-                     .addImm(Imm + 1)
-                     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
-
-    MIBLO.setMemRefs(MI.memoperands());
-    MIBHI.setMemRefs(MI.memoperands());
+    if (STI.hasLowByteFirst()) {
+      buildMI(MBB, MBBI, AVR::STDPtrQRr)
+          .addReg(DstReg)
+          .addImm(Imm)
+          .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+      buildMI(MBB, MBBI, AVR::STDPtrQRr)
+          .addReg(DstReg, getKillRegState(DstIsKill))
+          .addImm(Imm + 1)
+          .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+    } else {
+      buildMI(MBB, MBBI, AVR::STDPtrQRr)
+          .addReg(DstReg)
+          .addImm(Imm + 1)
+          .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+      buildMI(MBB, MBBI, AVR::STDPtrQRr)
+          .addReg(DstReg, getKillRegState(DstIsKill))
+          .addImm(Imm)
+          .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+          .setMemRefs(MI.memoperands());
+    }
   }
 
   MI.eraseFromParent();
@@ -1347,27 +1388,28 @@ bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
 
 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));
-
-  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(STI.hasLowByteFirst() ? Imm : Imm + 1)
+                   .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
+                           getKillRegState(SrcIsKill));
+  auto MIBLO = buildMI(MBB, MBBI, AVR::OUTARr)
+                   .addImm(STI.hasLowByteFirst() ? Imm + 1 : Imm)
+                   .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
+                           getKillRegState(SrcIsKill));
 
   MIBLO.setMemRefs(MI.memoperands());
   MIBHI.setMemRefs(MI.memoperands());

diff  --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 3b812750cebc0..06c4382b7edbc 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1128,9 +1128,15 @@ bool AVRTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
       return false;
   } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
     VT = ST->getMemoryVT();
-    if (AVR::isProgramMemoryAccess(ST)) {
+    // We can not store to program memory.
+    if (AVR::isProgramMemoryAccess(ST))
+      return false;
+    // Since the high byte need to be stored first, we can not emit
+    // i16 post increment store like:
+    // st X+, r24
+    // st X+, r25
+    if (VT == MVT::i16 && !Subtarget.hasLowByteFirst())
       return false;
-    }
   } else {
     return false;
   }

diff  --git a/llvm/lib/Target/AVR/AVRSubtarget.h b/llvm/lib/Target/AVR/AVRSubtarget.h
index 78ffb4260de49..cabb95adaa604 100644
--- a/llvm/lib/Target/AVR/AVRSubtarget.h
+++ b/llvm/lib/Target/AVR/AVRSubtarget.h
@@ -81,6 +81,7 @@ class AVRSubtarget : public AVRGenSubtargetInfo {
   bool hasBREAK() const { return m_hasBREAK; }
   bool hasTinyEncoding() const { return m_hasTinyEncoding; }
   bool hasMemMappedGPR() const { return m_hasMemMappedGPR; }
+  bool hasLowByteFirst() const { return m_hasLowByteFirst; }
 
   uint8_t getIORegisterOffset() const { return hasMemMappedGPR() ? 0x20 : 0x0; }
 
@@ -134,6 +135,7 @@ class AVRSubtarget : public AVRGenSubtargetInfo {
   bool m_supportsMultiplication = false;
   bool m_hasBREAK = false;
   bool m_hasTinyEncoding = false;
+  bool m_hasLowByteFirst = false;
   bool m_hasMemMappedGPR = false;
 
   // Dummy member, used by FeatureSet's. We cannot have a SubtargetFeature with

diff  --git a/llvm/test/CodeGen/AVR/PR37143.ll b/llvm/test/CodeGen/AVR/PR37143.ll
index c7cabd3cd0875..fe9529a24973f 100644
--- a/llvm/test/CodeGen/AVR/PR37143.ll
+++ b/llvm/test/CodeGen/AVR/PR37143.ll
@@ -2,8 +2,8 @@
 
 ; CHECK: ld {{r[0-9]+}}, [[PTR:[XYZ]]]
 ; CHECK: ldd {{r[0-9]+}}, [[PTR]]+1
-; CHECK: st [[PTR2:[XYZ]]], {{r[0-9]+}}
-; CHECK: std [[PTR2]]+1, {{r[0-9]+}}
+; CHECK: std [[PTR2:[XYZ]]]+1, {{r[0-9]+}}
+; CHECK: st [[PTR2]], {{r[0-9]+}}
 define void @load_store_16(i16* nocapture %ptr) local_unnamed_addr #1 {
 entry:
   %0 = load i16, i16* %ptr, align 2

diff  --git a/llvm/test/CodeGen/AVR/alloca.ll b/llvm/test/CodeGen/AVR/alloca.ll
index 37c0e62b55fde..30842f8244c61 100644
--- a/llvm/test/CodeGen/AVR/alloca.ll
+++ b/llvm/test/CodeGen/AVR/alloca.ll
@@ -46,12 +46,12 @@ define i16 @alloca_write(i16 %x) {
 entry:
 ; CHECK-LABEL: alloca_write:
 ; Small offset here
-; CHECK: std Y+23, {{.*}}
 ; CHECK: std Y+24, {{.*}}
+; CHECK: std Y+23, {{.*}}
 ; Big offset here
 ; CHECK: adiw r28, 57
-; CHECK: std Y+62, {{.*}}
 ; CHECK: std Y+63, {{.*}}
+; CHECK: std Y+62, {{.*}}
 ; CHECK: sbiw r28, 57
   %p = alloca [15 x i16]
   %k = alloca [14 x i16]
@@ -71,8 +71,8 @@ define void @alloca_write_huge() {
 ; CHECK-LABEL: alloca_write_huge:
 ; CHECK: subi r28, 41
 ; CHECK: sbci r29, 255
-; CHECK: std Y+62, {{.*}}
 ; CHECK: std Y+63, {{.*}}
+; CHECK: std Y+62, {{.*}}
 ; CHECK: subi r28, 215
 ; CHECK: sbci r29, 0
   %k = alloca [140 x i16]

diff  --git a/llvm/test/CodeGen/AVR/atomics/load16.ll b/llvm/test/CodeGen/AVR/atomics/load16.ll
index d019bf3750b8c..5046332688b34 100644
--- a/llvm/test/CodeGen/AVR/atomics/load16.ll
+++ b/llvm/test/CodeGen/AVR/atomics/load16.ll
@@ -33,8 +33,8 @@ define i16 @atomic_load_cmp_swap16(i16* %foo) {
 ; CHECK-NEXT: ldd [[RDH:r[0-9]+]], [[RR]]+1
 ; CHECK-NEXT: add [[RR1L:r[0-9]+]], [[RDL]]
 ; CHECK-NEXT: adc [[RR1H:r[0-9]+]], [[RDH]]
-; CHECK-NEXT: st [[RR]], [[RR1L]]
 ; CHECK-NEXT: std [[RR]]+1, [[RR1H]]
+; CHECK-NEXT: st [[RR]], [[RR1L]]
 ; CHECK-NEXT: out 63, r0
 define i16 @atomic_load_add16(i16* %foo) {
   %val = atomicrmw add i16* %foo, i16 13 seq_cst
@@ -49,8 +49,8 @@ define i16 @atomic_load_add16(i16* %foo) {
 ; CHECK-NEXT: movw [[TMPL:r[0-9]+]], [[RDL]]
 ; CHECK-NEXT: sub [[TMPL]],         [[RR1L:r[0-9]+]]
 ; CHECK-NEXT: sbc [[TMPH:r[0-9]+]], [[RR1H:r[0-9]+]]
-; CHECK-NEXT: st [[RR]], [[TMPL]]
 ; CHECK-NEXT: std [[RR]]+1, [[TMPH]]
+; CHECK-NEXT: st [[RR]], [[TMPL]]
 ; CHECK-NEXT: out 63, r0
 define i16 @atomic_load_sub16(i16* %foo) {
   %val = atomicrmw sub i16* %foo, i16 13 seq_cst
@@ -64,8 +64,8 @@ define i16 @atomic_load_sub16(i16* %foo) {
 ; CHECK-NEXT: ldd [[RDH:r[0-9]+]], [[RR]]+1
 ; CHECK-NEXT: and [[RD1L:r[0-9]+]], [[RDL]]
 ; CHECK-NEXT: and [[RD1H:r[0-9]+]], [[RDH]]
-; CHECK-NEXT: st [[RR]], [[RD1L]]
 ; CHECK-NEXT: std [[RR]]+1, [[RD1H]]
+; CHECK-NEXT: st [[RR]], [[RD1L]]
 ; CHECK-NEXT: out 63, r0
 define i16 @atomic_load_and16(i16* %foo) {
   %val = atomicrmw and i16* %foo, i16 13 seq_cst
@@ -79,8 +79,8 @@ define i16 @atomic_load_and16(i16* %foo) {
 ; CHECK-NEXT: ldd [[RDH:r[0-9]+]], [[RR]]+1
 ; CHECK-NEXT: or [[RD1L:r[0-9]+]], [[RDL]]
 ; CHECK-NEXT: or [[RD1H:r[0-9]+]], [[RDH]]
-; CHECK-NEXT: st [[RR]], [[RD1L]]
 ; CHECK-NEXT: std [[RR]]+1, [[RD1H]]
+; CHECK-NEXT: st [[RR]], [[RD1L]]
 ; CHECK-NEXT: out 63, r0
 define i16 @atomic_load_or16(i16* %foo) {
   %val = atomicrmw or i16* %foo, i16 13 seq_cst
@@ -94,8 +94,8 @@ define i16 @atomic_load_or16(i16* %foo) {
 ; CHECK-NEXT: ldd [[RDH:r[0-9]+]], [[RR]]+1
 ; CHECK-NEXT: eor [[RD1L:r[0-9]+]], [[RDL]]
 ; CHECK-NEXT: eor [[RD1H:r[0-9]+]], [[RDH]]
-; CHECK-NEXT: st [[RR]], [[RD1L]]
 ; CHECK-NEXT: std [[RR]]+1, [[RD1H]]
+; CHECK-NEXT: st [[RR]], [[RD1L]]
 ; CHECK-NEXT: out 63, r0
 define i16 @atomic_load_xor16(i16* %foo) {
   %val = atomicrmw xor i16* %foo, i16 13 seq_cst

diff  --git a/llvm/test/CodeGen/AVR/atomics/store.ll b/llvm/test/CodeGen/AVR/atomics/store.ll
index e1231c21e7d79..0eb6b51b67515 100644
--- a/llvm/test/CodeGen/AVR/atomics/store.ll
+++ b/llvm/test/CodeGen/AVR/atomics/store.ll
@@ -13,8 +13,8 @@ define void @atomic_store8(i8* %foo) {
 ; CHECK-LABEL: atomic_store16
 ; CHECK:      in r0, 63
 ; CHECK-NEXT: cli
-; CHECK-NEXT: st [[RD:(X|Y|Z)]], [[RR:r[0-9]+]]
-; CHECK-NEXT: std [[RD]]+1, [[RR:r[0-9]+]]
+; CHECK-NEXT: std [[RD:(X|Y|Z)]]+1, [[RR:r[0-9]+]]
+; CHECK-NEXT: st [[RD]], [[RR:r[0-9]+]]
 ; CHECK-NEXT: out 63, r0
 define void @atomic_store16(i16* %foo) {
   store atomic i16 1, i16* %foo unordered, align 2

diff  --git a/llvm/test/CodeGen/AVR/atomics/store16.ll b/llvm/test/CodeGen/AVR/atomics/store16.ll
index 610a53fad736d..779ea188be771 100644
--- a/llvm/test/CodeGen/AVR/atomics/store16.ll
+++ b/llvm/test/CodeGen/AVR/atomics/store16.ll
@@ -3,8 +3,8 @@
 ; CHECK-LABEL: atomic_store16
 ; CHECK:      in r0, 63
 ; CHECK-NEXT: cli
-; CHECK-NEXT: st [[RD:(X|Y|Z)]], [[RR:r[0-9]+]]
 ; CHECK-NEXT: std [[RD:(X|Y|Z)]]+1, [[RR:r[0-9]+]]
+; CHECK-NEXT: st [[RD:(X|Y|Z)]], [[RR:r[0-9]+]]
 ; CHECK-NEXT: out 63, r0
 define void @atomic_store16(i16* %foo) {
   store atomic i16 1, i16* %foo unordered, align 2
@@ -14,8 +14,8 @@ define void @atomic_store16(i16* %foo) {
 ; CHECK-LABEL: monotonic
 ; CHECK:      in r0, 63
 ; CHECK-NEXT: cli
-; CHECK-NEXT: st Z, r24
 ; CHECK-NEXT: std Z+1, r25
+; CHECK-NEXT: st Z, r24
 ; CHECK-NEXT: out 63, r0
 define void @monotonic(i16) {
 entry-block:

diff  --git a/llvm/test/CodeGen/AVR/call.ll b/llvm/test/CodeGen/AVR/call.ll
index ec91480163b1e..39382bc6a34b5 100644
--- a/llvm/test/CodeGen/AVR/call.ll
+++ b/llvm/test/CodeGen/AVR/call.ll
@@ -35,8 +35,8 @@ define i8 @calli8_stack() {
 ; CHECK-LABEL: calli8_stack:
 ; CHECK: ldi [[REG1:r[0-9]+]], 10
 ; CHECK: ldi [[REG2:r[0-9]+]], 11
-; CHECK: std Z+1, [[REG1]]
 ; CHECK: std Z+2, [[REG2]]
+; CHECK: std Z+1, [[REG1]]
 ; AVR6:  call foo8_3
 ; AVR2:  rcall foo8_3
     %result1 = call i8 @foo8_3(i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11)
@@ -59,12 +59,12 @@ define i16 @calli16_stack() {
 ; CHECK-LABEL: calli16_stack:
 ; CHECK: ldi [[REG1:r[0-9]+]], 10
 ; CHECK: ldi [[REG2:r[0-9]+]], 2
-; CHECK: std Z+3, [[REG1]]
 ; CHECK: std Z+4, [[REG2]]
+; CHECK: std Z+3, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 9
 ; CHECK: ldi [[REG2:r[0-9]+]], 2
-; CHECK: std Z+1, [[REG1]]
 ; CHECK: std Z+2, [[REG2]]
+; CHECK: std Z+1, [[REG1]]
 ; AVR6:  call foo16_2
 ; AVR2:  rcall foo16_2
     %result1 = call i16 @foo16_2(i16 512, i16 513, i16 514, i16 515, i16 516, i16 517, i16 518, i16 519, i16 520, i16 521, i16 522)
@@ -91,12 +91,12 @@ define i32 @calli32_stack() {
 ; CHECK-LABEL: calli32_stack:
 ; CHECK: ldi [[REG1:r[0-9]+]], 15
 ; CHECK: ldi [[REG2:r[0-9]+]], 2
-; CHECK: std Z+3, [[REG1]]
 ; CHECK: std Z+4, [[REG2]]
+; CHECK: std Z+3, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 64
 ; CHECK: ldi [[REG2:r[0-9]+]], 66
-; CHECK: std Z+1, [[REG1]]
 ; CHECK: std Z+2, [[REG2]]
+; CHECK: std Z+1, [[REG1]]
 ; AVR6:  call foo32_2
 ; AVR2:  rcall foo32_2
     %result1 = call i32 @foo32_2(i32 1, i32 2, i32 3, i32 4, i32 34554432)
@@ -124,20 +124,20 @@ define i64 @calli64_stack() {
 
 ; CHECK: ldi [[REG1:r[0-9]+]], 31
 ; CHECK: ldi [[REG2:r[0-9]+]], 242
-; CHECK: std Z+7, [[REG1]]
 ; CHECK: std Z+8, [[REG2]]
+; CHECK: std Z+7, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 76
 ; CHECK: ldi [[REG2:r[0-9]+]], 73
-; CHECK: std Z+5, [[REG1]]
 ; CHECK: std Z+6, [[REG2]]
+; CHECK: std Z+5, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 155
 ; CHECK: ldi [[REG2:r[0-9]+]], 88
-; CHECK: std Z+3, [[REG1]]
 ; CHECK: std Z+4, [[REG2]]
+; CHECK: std Z+3, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 255
 ; CHECK: ldi [[REG2:r[0-9]+]], 255
-; CHECK: std Z+1, [[REG1]]
 ; CHECK: std Z+2, [[REG2]]
+; CHECK: std Z+1, [[REG1]]
 ; AVR6:  call foo64_2
 ; AVR2:  rcall foo64_2
     %result1 = call i64 @foo64_2(i64 1, i64 2, i64 17446744073709551615)
@@ -157,20 +157,20 @@ define void @testcallprologue() {
 ; CHECK: std Y+9, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 11
 ; CHECK: ldi [[REG2:r[0-9]+]], 10
-; CHECK: std Y+7, [[REG1]]
 ; CHECK: std Y+8, [[REG2]]
+; CHECK: std Y+7, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 13
 ; CHECK: ldi [[REG2:r[0-9]+]], 12
-; CHECK: std Y+5, [[REG1]]
 ; CHECK: std Y+6, [[REG2]]
+; CHECK: std Y+5, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 15
 ; CHECK: ldi [[REG2:r[0-9]+]], 14
-; CHECK: std Y+3, [[REG1]]
 ; CHECK: std Y+4, [[REG2]]
+; CHECK: std Y+3, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 8
 ; CHECK: ldi [[REG2:r[0-9]+]], 9
-; CHECK: std Y+1, [[REG1]]
 ; CHECK: std Y+2, [[REG2]]
+; CHECK: std Y+1, [[REG1]]
 ; CHECK: pop r29
 ; CHECK: pop r28
   %p = alloca [8 x i16]

diff  --git a/llvm/test/CodeGen/AVR/dynalloca.ll b/llvm/test/CodeGen/AVR/dynalloca.ll
index 7f69966159761..28c743c5bdc67 100644
--- a/llvm/test/CodeGen/AVR/dynalloca.ll
+++ b/llvm/test/CodeGen/AVR/dynalloca.ll
@@ -19,8 +19,8 @@ define void @test1(i16 %x) {
 ; CHECK-NEXT: out 63, r0
 ; CHECK-NEXT: out 61, {{.*}}
 ; Test writes
-; CHECK: std Z+12, {{.*}}
 ; CHECK: std Z+13, {{.*}}
+; CHECK: std Z+12, {{.*}}
 ; CHECK: std Z+7, {{.*}}
 ; CHECK-NOT: std
 ; Test SP restore
@@ -66,14 +66,14 @@ define void @dynalloca2(i16 %x) {
 ; Store values on the stack
 ; CHECK: ldi r16, 0
 ; CHECK: ldi r17, 0
-; CHECK: std Z+7, r16
 ; CHECK: std Z+8, r17
-; CHECK: std Z+5, r16
+; CHECK: std Z+7, r16
 ; CHECK: std Z+6, r17
-; CHECK: std Z+3, r16
+; CHECK: std Z+5, r16
 ; CHECK: std Z+4, r17
-; CHECK: std Z+1, r16
+; CHECK: std Z+3, r16
 ; CHECK: std Z+2, r17
+; CHECK: std Z+1, r16
 ; CHECK: call
 ; Call frame restore
 ; CHECK-NEXT: in r30, 61

diff  --git a/llvm/test/CodeGen/AVR/lpmx.ll b/llvm/test/CodeGen/AVR/lpmx.ll
index e84caf40d0709..db8fdb458d01c 100644
--- a/llvm/test/CodeGen/AVR/lpmx.ll
+++ b/llvm/test/CodeGen/AVR/lpmx.ll
@@ -20,8 +20,8 @@ define i16 @foo0(i16 %a) addrspace(1) {
 ; CHECK-O0-NEXT:    out 62, r29
 ; CHECK-O0-NEXT:    out 63, r0
 ; CHECK-O0-NEXT:    out 61, r28
-; CHECK-O0-NEXT:    std Y+1, r24
 ; CHECK-O0-NEXT:    std Y+2, r25
+; CHECK-O0-NEXT:    std Y+1, r24
 ; CHECK-O0-NEXT:    ldd r30, Y+1
 ; CHECK-O0-NEXT:    ldd r31, Y+2
 ; CHECK-O0-NEXT:    lsl r30
@@ -52,8 +52,8 @@ define i16 @foo0(i16 %a) addrspace(1) {
 ; CHECK-O3-NEXT:    out 62, r29
 ; CHECK-O3-NEXT:    out 63, r0
 ; CHECK-O3-NEXT:    out 61, r28
-; CHECK-O3-NEXT:    std Y+1, r24
 ; CHECK-O3-NEXT:    std Y+2, r25
+; CHECK-O3-NEXT:    std Y+1, r24
 ; CHECK-O3-NEXT:    lsl r24
 ; CHECK-O3-NEXT:    rol r25
 ; CHECK-O3-NEXT:    subi r24, lo8(-(arr0))
@@ -92,8 +92,8 @@ define i8 @foo1(i16 %a) addrspace(1) {
 ; CHECK-O0-NEXT:    out 62, r29
 ; CHECK-O0-NEXT:    out 63, r0
 ; CHECK-O0-NEXT:    out 61, r28
-; CHECK-O0-NEXT:    std Y+1, r24
 ; CHECK-O0-NEXT:    std Y+2, r25
+; CHECK-O0-NEXT:    std Y+1, r24
 ; CHECK-O0-NEXT:    ldd r30, Y+1
 ; CHECK-O0-NEXT:    ldd r31, Y+2
 ; CHECK-O0-NEXT:    subi r30, lo8(-(arr1))
@@ -121,8 +121,8 @@ define i8 @foo1(i16 %a) addrspace(1) {
 ; CHECK-O3-NEXT:    out 62, r29
 ; CHECK-O3-NEXT:    out 63, r0
 ; CHECK-O3-NEXT:    out 61, r28
-; CHECK-O3-NEXT:    std Y+1, r24
 ; CHECK-O3-NEXT:    std Y+2, r25
+; CHECK-O3-NEXT:    std Y+1, r24
 ; CHECK-O3-NEXT:    subi r24, lo8(-(arr1))
 ; CHECK-O3-NEXT:    sbci r25, hi8(-(arr1))
 ; CHECK-O3-NEXT:    movw r30, r24

diff  --git a/llvm/test/CodeGen/AVR/pr43443-ctor-alias.ll b/llvm/test/CodeGen/AVR/pr43443-ctor-alias.ll
index 7aa680353b8b7..9175e8c73fe78 100644
--- a/llvm/test/CodeGen/AVR/pr43443-ctor-alias.ll
+++ b/llvm/test/CodeGen/AVR/pr43443-ctor-alias.ll
@@ -30,8 +30,8 @@ define void @_ZN3fooC2Ev(%struct.foo* dereferenceable(1) %this) {
 ; CHECK-NEXT:    out 62, r29
 ; CHECK-NEXT:    out 63, r0
 ; CHECK-NEXT:    out 61, r28
-; CHECK-NEXT:    std Y+1, r24
 ; CHECK-NEXT:    std Y+2, r25
+; CHECK-NEXT:    std Y+1, r24
 ; CHECK-NEXT:    adiw r28, 2
 ; CHECK-NEXT:    in r0, 63
 ; CHECK-NEXT:    cli

diff  --git a/llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir b/llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir
index 3152085cd14e5..8b9c0fdc28f61 100644
--- a/llvm/test/CodeGen/AVR/pseudo/OUTWARr.mir
+++ b/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 @@ body: |
     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
 ...

diff  --git a/llvm/test/CodeGen/AVR/pseudo/STDWPtrQRr.mir b/llvm/test/CodeGen/AVR/pseudo/STDWPtrQRr.mir
index 535296d53b37e..89b124da11833 100644
--- a/llvm/test/CodeGen/AVR/pseudo/STDWPtrQRr.mir
+++ b/llvm/test/CodeGen/AVR/pseudo/STDWPtrQRr.mir
@@ -1,5 +1,8 @@
 # RUN: llc -O0 -run-pass=avr-expand-pseudo -verify-machineinstrs %s -o - | FileCheck %s
-# RUN: llc -O0 -run-pass=avr-expand-pseudo -verify-machineinstrs -mattr=avrtiny %s -o - | FileCheck %s --check-prefix=CHECK-TINY
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -verify-machineinstrs -mattr=avrtiny %s -o - \
+# RUN:     | FileCheck %s --check-prefix=CHECK-TINY
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -verify-machineinstrs -mattr=lowbytefirst %s -o - \
+# RUN:     | FileCheck %s --check-prefix=CHECK-XMEGA
 
 --- |
   target triple = "avr--"
@@ -17,29 +20,37 @@ body: |
     ; CHECK-LABEL: test
 
     ; Small displacement (<63):
-    ; CHECK:      STDPtrQRr $r29r28, 3, $r0
-    ; CHECK-NEXT: STDPtrQRr $r29r28, 4, $r1
-    ; CHECK-TINY:      $r28 = SUBIRdK killed $r28, 253, implicit-def $sreg
-    ; CHECK-TINY-NEXT: $r29 = SBCIRdK killed $r29, 255, implicit-def $sreg, implicit killed $sreg
-    ; CHECK-TINY-NEXT: early-clobber $r29r28 = STPtrPiRr killed $r29r28, $r0, 0
-    ; CHECK-TINY-NEXT: early-clobber $r29r28 = STPtrPiRr killed $r29r28, $r1, 0
-    ; CHECK-TINY-NEXT: $r28 = SUBIRdK killed $r28, 5, implicit-def $sreg
-    ; CHECK-TINY-NEXT: $r29 = SBCIRdK killed $r29, 0, implicit-def $sreg, implicit killed $sreg
+    ; CHECK:            STDPtrQRr $r29r28, 4, $r1
+    ; CHECK-NEXT:       STDPtrQRr $r29r28, 3, $r0
+    ; CHECK-XMEGA:      STDPtrQRr $r29r28, 3, $r0
+    ; CHECK-XMEGA-NEXT: STDPtrQRr $r29r28, 4, $r1
+    ; CHECK-TINY:       $r28 = SUBIRdK killed $r28, 253, implicit-def $sreg
+    ; CHECK-TINY-NEXT:  $r29 = SBCIRdK killed $r29, 255, implicit-def $sreg, implicit killed $sreg
+    ; CHECK-TINY-NEXT:  early-clobber $r29r28 = STPtrPiRr killed $r29r28, $r0, 0
+    ; CHECK-TINY-NEXT:  early-clobber $r29r28 = STPtrPiRr killed $r29r28, $r1, 0
+    ; CHECK-TINY-NEXT:  $r28 = SUBIRdK killed $r28, 5, implicit-def $sreg
+    ; CHECK-TINY-NEXT:  $r29 = SBCIRdK killed $r29, 0, implicit-def $sreg, implicit killed $sreg
     STDWPtrQRr $r29r28, 3, $r1r0
 
     ; Small displacement where the destination register is killed:
-    ; CHECK:      STDPtrQRr $r29r28, 3, $r0
-    ; CHECK-NEXT: STDPtrQRr killed $r29r28, 4, $r1
+    ; CHECK-NEXT:       STDPtrQRr $r29r28, 4, $r1
+    ; CHECK-NEXT:       STDPtrQRr killed $r29r28, 3, $r0
+    ; CHECK-XMEGA-NEXT: STDPtrQRr $r29r28, 3, $r0
+    ; CHECK-XMEGA-NEXT: STDPtrQRr killed $r29r28, 4, $r1
     STDWPtrQRr killed $r29r28, 3, $r1r0
 
     ; Small displacement where the source register is killed:
-    ; CHECK:      STDPtrQRr $r29r28, 3, killed $r0
-    ; CHECK-NEXT: STDPtrQRr $r29r28, 4, killed $r1
+    ; CHECK:            STDPtrQRr $r29r28, 4, killed $r1
+    ; CHECK-NEXT:       STDPtrQRr $r29r28, 3, killed $r0
+    ; CHECK-XMEGA:      STDPtrQRr $r29r28, 3, killed $r0
+    ; CHECK-XMEGA-NEXT: STDPtrQRr $r29r28, 4, killed $r1
     STDWPtrQRr $r29r28, 3, killed $r1r0
 
     ; Small displacement, near the limit (=62):
-    ; CHECK:      STDPtrQRr $r29r28, 62, $r0
-    ; CHECK-NEXT: STDPtrQRr $r29r28, 63, $r1
+    ; CHECK:            STDPtrQRr $r29r28, 63, $r1
+    ; CHECK-NEXT:       STDPtrQRr $r29r28, 62, $r0
+    ; CHECK-XMEGA:      STDPtrQRr $r29r28, 62, $r0
+    ; CHECK-XMEGA-NEXT: STDPtrQRr $r29r28, 63, $r1
     STDWPtrQRr $r29r28, 62, $r1r0
 
     ; Large displacement (>=63):

diff  --git a/llvm/test/CodeGen/AVR/pseudo/STSWKRr.mir b/llvm/test/CodeGen/AVR/pseudo/STSWKRr.mir
index 96a648b5622e2..cd45febd012ae 100644
--- a/llvm/test/CodeGen/AVR/pseudo/STSWKRr.mir
+++ b/llvm/test/CodeGen/AVR/pseudo/STSWKRr.mir
@@ -1,4 +1,6 @@
 # RUN: llc -O0 -run-pass=avr-expand-pseudo %s -o - | FileCheck %s
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mcpu=atxmega64a1 %s -o - \
+# RUN:     | FileCheck --check-prefix=XMEGA %s
 
 # This test checks the expansion of the 16-bit STSWRdK pseudo instruction.
 
@@ -17,9 +19,12 @@ body: |
     liveins: $r31r30
 
     ; CHECK-LABEL: test_stswkrr
+    ; CHECK:       STSKRr 2560, $r31
+    ; CHECK-NEXT:  STSKRr 2559, $r30
 
-    ; CHECK:      STSKRr 2560, $r31
-    ; CHECK-NEXT: STSKRr 2559, $r30
+    ; XMEGA-LABEL: test_stswkrr
+    ; XMEGA:       STSKRr 2559, $r30
+    ; XMEGA-NEXT:  STSKRr 2560, $r31
 
     STSWKRr 2559, $r31r30
 ...

diff  --git a/llvm/test/CodeGen/AVR/pseudo/STWPtrRr.mir b/llvm/test/CodeGen/AVR/pseudo/STWPtrRr.mir
index b6449ae1d438c..3350e6cdf34ef 100644
--- a/llvm/test/CodeGen/AVR/pseudo/STWPtrRr.mir
+++ b/llvm/test/CodeGen/AVR/pseudo/STWPtrRr.mir
@@ -1,5 +1,8 @@
 # RUN: llc -O0 -run-pass=avr-expand-pseudo %s -o - | FileCheck %s
-# RUN: llc -O0 -run-pass=avr-expand-pseudo -mattr=avrtiny %s -o - | FileCheck %s --check-prefix=CHECK-TINY
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mattr=avrtiny %s -o - \
+# RUN:     | FileCheck %s --check-prefix=CHECK-TINY
+# RUN: llc -O0 -run-pass=avr-expand-pseudo -mattr=lowbytefirst %s -o - \
+# RUN:     | FileCheck %s --check-prefix=CHECK-XMEGA
 
 # This test checks the expansion of the 16-bit STSWRdK pseudo instruction.
 
@@ -18,14 +21,18 @@ body: |
     liveins: $r31r30, $r17r16
 
     ; CHECK-LABEL: test_stwptrrr
+    ; CHECK:       STDPtrQRr $r31r30, 1, $r17
+    ; CHECK-NEXT:  STPtrRr $r31r30, $r16
 
-    ; CHECK:      STPtrRr $r31r30, $r16
-    ; CHECK-NEXT: STDPtrQRr $r31r30, 1, $r17
+    ; CHECK-TINY-LABEL: test_stwptrrr
+    ; CHECK-TINY:       $r31r30 = STPtrPiRr killed $r31r30, $r16, 0
+    ; CHECK-TINY-NEXT:  $r31r30 = STPtrPiRr killed $r31r30, $r17, 0
+    ; CHECK-TINY-NEXT:  $r30 = SUBIRdK killed $r30, 2, implicit-def $sreg
+    ; CHECK-TINY-NEXT:  $r31 = SBCIRdK killed $r31, 0, implicit-def $sreg, implicit killed $sreg
 
-    ; CHECK-TINY:      $r31r30 = STPtrPiRr killed $r31r30, $r16, 0
-    ; CHECK-TINY-NEXT: $r31r30 = STPtrPiRr killed $r31r30, $r17, 0
-    ; CHECK-TINY-NEXT: $r30 = SUBIRdK killed $r30, 2, implicit-def $sreg
-    ; CHECK-TINY-NEXT: $r31 = SBCIRdK killed $r31, 0, implicit-def $sreg, implicit killed $sreg
+    ; CHECK-XMEGA-LABEL: test_stwptrrr
+    ; CHECK-XMEGA:       STPtrRr $r31r30, $r16
+    ; CHECK-XMEGA-NEXT:  STDPtrQRr $r31r30, 1, $r17
 
     STWPtrRr $r31r30, $r17r16
 ...

diff  --git a/llvm/test/CodeGen/AVR/shift32.ll b/llvm/test/CodeGen/AVR/shift32.ll
index 820419b037a3c..9e97fac2f8e39 100644
--- a/llvm/test/CodeGen/AVR/shift32.ll
+++ b/llvm/test/CodeGen/AVR/shift32.ll
@@ -208,12 +208,12 @@ define void @shl_i32_16_ptr(i32 %a, ptr %ptr) {
 ; CHECK-LABEL: shl_i32_16_ptr:
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    movw r30, r20
-; CHECK-NEXT:    std Z+2, r22
 ; CHECK-NEXT:    std Z+3, r23
+; CHECK-NEXT:    std Z+2, r22
 ; CHECK-NEXT:    ldi r24, 0
 ; CHECK-NEXT:    ldi r25, 0
-; CHECK-NEXT:    st Z, r24
 ; CHECK-NEXT:    std Z+1, r25
+; CHECK-NEXT:    st Z, r24
 ; CHECK-NEXT:    ret
   %res = shl i32 %a, 16
   store i32 %res, ptr %ptr

diff  --git a/llvm/test/CodeGen/AVR/store.ll b/llvm/test/CodeGen/AVR/store.ll
index 81bad77538745..8bfbcb0934ed1 100644
--- a/llvm/test/CodeGen/AVR/store.ll
+++ b/llvm/test/CodeGen/AVR/store.ll
@@ -9,8 +9,8 @@ define void @store8(i8* %x, i8 %y) {
 
 define void @store16(i16* %x, i16 %y) {
 ; CHECK-LABEL: store16:
-; CHECK: st {{[YZ]}}, r22
 ; CHECK: std {{[YZ]}}+1, r23
+; CHECK: st {{[YZ]}}, r22
   store i16 %y, i16* %x
   ret void
 }
@@ -36,8 +36,8 @@ define void @store8nodisp(i8* %x, i8 %y) {
 
 define void @store16disp(i16* %x, i16 %y) {
 ; CHECK-LABEL: store16disp:
-; CHECK: std {{[YZ]}}+62, r22
 ; CHECK: std {{[YZ]}}+63, r23
+; CHECK: std {{[YZ]}}+62, r22
   %arrayidx = getelementptr inbounds i16, i16* %x, i16 31
   store i16 %y, i16* %arrayidx
   ret void
@@ -48,8 +48,8 @@ define void @store16nodisp(i16* %x, i16 %y) {
 ; CHECK: subi r24, 192
 ; CHECK: sbci r25, 255
 ; CHECK: movw r30, r24
-; CHECK: st {{[YZ]}}, r22
 ; CHECK: std {{[YZ]}}+1, r23
+; CHECK: st {{[YZ]}}, r22
   %arrayidx = getelementptr inbounds i16, i16* %x, i16 32
   store i16 %y, i16* %arrayidx
   ret void
@@ -75,8 +75,8 @@ while.end:                                        ; preds = %while.body, %entry
 
 define void @store16postinc(i16* %x, i16 %y) {
 ; CHECK-LABEL: store16postinc:
-; CHECK: st {{[XYZ]}}+, {{.*}}
-; CHECK: st {{[XYZ]}}+, {{.*}}
+; CHECK: std {{[XYZ]}}+1, {{.*}}
+; CHECK: st  {{[XYZ]}}, {{.*}}
 entry:
   %tobool3 = icmp eq i16 %y, 0
   br i1 %tobool3, label %while.end, label %while.body

diff  --git a/llvm/test/CodeGen/AVR/struct.ll b/llvm/test/CodeGen/AVR/struct.ll
index 3d1eb83253c6f..1064236030e68 100644
--- a/llvm/test/CodeGen/AVR/struct.ll
+++ b/llvm/test/CodeGen/AVR/struct.ll
@@ -11,23 +11,23 @@ define void @foo10(%struct.s10* sret(%struct.s10) %0, i16 %1, i16 %2, i16 %3) ad
 ; CHECKA:       ; %bb.0:
 ; CHECKA-NEXT:    mov r30, r24
 ; CHECKA-NEXT:    mov r31, r25
-; CHECKA-NEXT:    std Z+4, r22
 ; CHECKA-NEXT:    std Z+5, r23
-; CHECKA-NEXT:    std Z+2, r20
+; CHECKA-NEXT:    std Z+4, r22
 ; CHECKA-NEXT:    std Z+3, r21
-; CHECKA-NEXT:    st Z, r18
+; CHECKA-NEXT:    std Z+2, r20
 ; CHECKA-NEXT:    std Z+1, r19
+; CHECKA-NEXT:    st Z, r18
 ; CHECKA-NEXT:    ret
 ;
 ; CHECKB-LABEL: foo10:
 ; CHECKB:       ; %bb.0:
 ; CHECKB-NEXT:    movw r30, r24
-; CHECKB-NEXT:    std Z+4, r22
 ; CHECKB-NEXT:    std Z+5, r23
-; CHECKB-NEXT:    std Z+2, r20
+; CHECKB-NEXT:    std Z+4, r22
 ; CHECKB-NEXT:    std Z+3, r21
-; CHECKB-NEXT:    st Z, r18
+; CHECKB-NEXT:    std Z+2, r20
 ; CHECKB-NEXT:    std Z+1, r19
+; CHECKB-NEXT:    st Z, r18
 ; CHECKB-NEXT:    ret
   %5 = getelementptr inbounds %struct.s10, %struct.s10* %0, i16 0, i32 0
   store i16 %3, i16* %5

diff  --git a/llvm/test/CodeGen/AVR/varargs.ll b/llvm/test/CodeGen/AVR/varargs.ll
index 5bd5cba0a2635..00952af02adb5 100644
--- a/llvm/test/CodeGen/AVR/varargs.ll
+++ b/llvm/test/CodeGen/AVR/varargs.ll
@@ -42,16 +42,16 @@ define void @varargcall() {
 ; CHECK-LABEL: varargcall:
 ; CHECK: ldi [[REG1:r[0-9]+]], 191
 ; CHECK: ldi [[REG2:r[0-9]+]], 223
-; CHECK: std Z+5, [[REG1]]
 ; CHECK: std Z+6, [[REG2]]
+; CHECK: std Z+5, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 189
 ; CHECK: ldi [[REG2:r[0-9]+]], 205
-; CHECK: std Z+3, [[REG1]]
 ; CHECK: std Z+4, [[REG2]]
+; CHECK: std Z+3, [[REG1]]
 ; CHECK: ldi [[REG1:r[0-9]+]], 205
 ; CHECK: ldi [[REG2:r[0-9]+]], 171
-; CHECK: std Z+1, [[REG1]]
 ; CHECK: std Z+2, [[REG2]]
+; CHECK: std Z+1, [[REG1]]
 ; CHECK: call
 ; CHECK: adiw r30, 6
   tail call void (i16, ...) @var1223(i16 -21555, i16 -12867, i16 -8257)


        


More information about the llvm-commits mailing list