[llvm] 937446d - [M68k] Fix incorrect move mask encoding with pre-decrement operand

Min Hsu via llvm-commits llvm-commits at lists.llvm.org
Thu May 15 23:56:34 PDT 2025


Author: Min Hsu
Date: 2025-05-15T23:55:51-07:00
New Revision: 937446d433b1c0bb3e4194847b3e620f308b0fbb

URL: https://github.com/llvm/llvm-project/commit/937446d433b1c0bb3e4194847b3e620f308b0fbb
DIFF: https://github.com/llvm/llvm-project/commit/937446d433b1c0bb3e4194847b3e620f308b0fbb.diff

LOG: [M68k] Fix incorrect move mask encoding with pre-decrement operand

When the memory operand of MOVEM instruction has an addressing mode of
pre-decrement, the move mask should be reversed.
This patch fixes it by creating a new asm operand with a different
encoding method.

Reported by @petmac

Added: 
    

Modified: 
    llvm/lib/Target/M68k/M68kInstrData.td
    llvm/lib/Target/M68k/M68kInstrInfo.td
    llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
    llvm/test/MC/M68k/Data/Classes/MxMOVEM_MR.s
    llvm/test/MC/M68k/Data/Classes/MxMOVEM_RM.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
index 398c55fa6da4a..f4ed62720ff99 100644
--- a/llvm/lib/Target/M68k/M68kInstrData.td
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -296,8 +296,9 @@ class MxMOVEMEncoding<MxEncMemOp opnd_enc, bit size, bit direction,
 
 let mayStore = 1 in
 class MxMOVEM_MR<MxType TYPE, bit SIZE_ENC,
-                 MxOperand MEMOp, MxEncMemOp MEM_ENC>
-    : MxInst<(outs), (ins MEMOp:$dst, MxMoveMask:$mask),
+                 MxOperand MEMOp, MxEncMemOp MEM_ENC,
+                 MxOp MASKOp>
+    : MxInst<(outs), (ins MEMOp:$dst, MASKOp:$mask),
              "movem."#TYPE.Prefix#"\t$mask, $dst", []> {
   let Inst = MxMOVEMEncoding<MEM_ENC, SIZE_ENC, MxMOVEM_MR, "mask">.Value;
 }
@@ -307,13 +308,15 @@ foreach AM = MxMoveSupportedAMs in {
   def MOVM # TYPE.Size # AM # m # TYPE.Postfix
       : MxMOVEM_MR<TYPE, !if(!eq(TYPE, MxType16), MxMOVEM_W, MxMOVEM_L),
                    !cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM).Op,
-                   !cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
+                   !cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM),
+                   !if(!eq(AM, "e"), MxInverseMoveMask, MxMoveMask)>;
 } // foreach AM
 
 let mayLoad = 1 in
 class MxMOVEM_RM<MxType TYPE, bit SIZE_ENC,
-                 MxOperand MEMOp, MxEncMemOp MEM_ENC>
-    : MxInst<(outs), (ins MxMoveMask:$mask, MEMOp:$src),
+                 MxOperand MEMOp, MxEncMemOp MEM_ENC,
+                 MxOp MASKOp>
+    : MxInst<(outs), (ins MASKOp:$mask, MEMOp:$src),
              "movem."#TYPE.Prefix#"\t$src, $mask", []> {
   let Inst = MxMOVEMEncoding<MEM_ENC, SIZE_ENC, MxMOVEM_RM, "mask">.Value;
 }
@@ -323,7 +326,8 @@ foreach AM = MxMoveSupportedAMs in {
   def MOVM # TYPE.Size # m # AM # TYPE.Postfix
       : MxMOVEM_RM<TYPE, !if(!eq(TYPE, MxType16), MxMOVEM_W, MxMOVEM_L),
                    !cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM).Op,
-                   !cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
+                   !cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM),
+                   !if(!eq(AM, "e"), MxInverseMoveMask, MxMoveMask)>;
 } // foreach AM
 
 // Pseudo versions. These a required by virtual register spill/restore since

diff  --git a/llvm/lib/Target/M68k/M68kInstrInfo.td b/llvm/lib/Target/M68k/M68kInstrInfo.td
index e9213f20c68e7..1200c493f9fca 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.td
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.td
@@ -438,12 +438,19 @@ def MxBrTarget32 : MxBrTargetOperand<32>;
 
 // Used with MOVEM
 def MxMoveMaskClass : MxOpClass<"MoveMask">;
-def MxMoveMask : MxOp<i16, MxSize16, "m"> {
+class MxMoveMaskOp : MxOp<i16, MxSize16, "m"> {
   let OperandType = "OPERAND_IMMEDIATE";
   let PrintMethod = "printMoveMask";
   let ParserMatchClass = MxMoveMaskClass;
 }
 
+def MxMoveMask : MxMoveMaskOp;
+// The encoding of mask is reversed when the memory operand has an addressing
+// mode of 'e', that is, pre-decrement.
+def MxInverseMoveMask : MxMoveMaskOp {
+  let EncoderMethod = "encodeInverseMoveMask";
+}
+
 //===----------------------------------------------------------------------===//
 // Predicates
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
index 78783084ee59a..3bd1d0d7dcaeb 100644
--- a/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
@@ -63,6 +63,11 @@ class M68kMCCodeEmitter : public MCCodeEmitter {
                          APInt &Value, SmallVectorImpl<MCFixup> &Fixups,
                          const MCSubtargetInfo &STI) const;
 
+  void encodeInverseMoveMask(const MCInst &MI, unsigned OpIdx,
+                             unsigned InsertPos, APInt &Value,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
 public:
   M68kMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
       : MCII(mcii), Ctx(ctx) {}
@@ -196,6 +201,13 @@ void M68kMCCodeEmitter::encodeFPSYSSelect(const MCInst &MI, unsigned OpIdx,
   }
 }
 
+void M68kMCCodeEmitter::encodeInverseMoveMask(
+    const MCInst &MI, unsigned OpIdx, unsigned InsertPos, APInt &Value,
+    SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
+  const MCOperand &Op = MI.getOperand(OpIdx);
+  Value = llvm::reverseBits<uint16_t>((uint16_t)Op.getImm());
+}
+
 void M68kMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &Op,
                                           unsigned InsertPos, APInt &Value,
                                           SmallVectorImpl<MCFixup> &Fixups,

diff  --git a/llvm/test/MC/M68k/Data/Classes/MxMOVEM_MR.s b/llvm/test/MC/M68k/Data/Classes/MxMOVEM_MR.s
index a99bf117e450d..1df1b67c63f97 100644
--- a/llvm/test/MC/M68k/Data/Classes/MxMOVEM_MR.s
+++ b/llvm/test/MC/M68k/Data/Classes/MxMOVEM_MR.s
@@ -13,3 +13,7 @@ movem.l	%d0, (%a1)
 ; CHECK:      movem.l  %d0-%d1, (%a1)
 ; CHECK-SAME: encoding: [0x48,0xd1,0x00,0x03]
 movem.l	%d0-%d1, (%a1)
+
+; CHECK:      movem.l  %d0-%d7/%a0-%a6, -(%sp)
+; CHECK-SAME: encoding: [0x48,0xe7,0xff,0xfe]
+movem.l %d0-%d7/%a0-%a6, -(%sp)

diff  --git a/llvm/test/MC/M68k/Data/Classes/MxMOVEM_RM.s b/llvm/test/MC/M68k/Data/Classes/MxMOVEM_RM.s
index 3cc067b6df995..2b31f30eaa326 100644
--- a/llvm/test/MC/M68k/Data/Classes/MxMOVEM_RM.s
+++ b/llvm/test/MC/M68k/Data/Classes/MxMOVEM_RM.s
@@ -13,3 +13,7 @@ movem.l	(%a1), %d0
 ; CHECK:      movem.l  (%a1), %d0-%d1
 ; CHECK-SAME: encoding: [0x4c,0xd1,0x00,0x03]
 movem.l	(%a1), %d0-%d1
+
+; CHECK:      movem.l  -(%sp), %d0-%d7/%a0-%a6
+; CHECK-SAME: encoding: [0x4c,0xe7,0xff,0xfe]
+movem.l -(%sp), %d0-%d7/%a0-%a6


        


More information about the llvm-commits mailing list