Skip to content

Commit 937446d

Browse files
committed
[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
1 parent 1001d6a commit 937446d

File tree

5 files changed

+38
-7
lines changed

5 files changed

+38
-7
lines changed

llvm/lib/Target/M68k/M68kInstrData.td

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,9 @@ class MxMOVEMEncoding<MxEncMemOp opnd_enc, bit size, bit direction,
296296

297297
let mayStore = 1 in
298298
class MxMOVEM_MR<MxType TYPE, bit SIZE_ENC,
299-
MxOperand MEMOp, MxEncMemOp MEM_ENC>
300-
: MxInst<(outs), (ins MEMOp:$dst, MxMoveMask:$mask),
299+
MxOperand MEMOp, MxEncMemOp MEM_ENC,
300+
MxOp MASKOp>
301+
: MxInst<(outs), (ins MEMOp:$dst, MASKOp:$mask),
301302
"movem."#TYPE.Prefix#"\t$mask, $dst", []> {
302303
let Inst = MxMOVEMEncoding<MEM_ENC, SIZE_ENC, MxMOVEM_MR, "mask">.Value;
303304
}
@@ -307,13 +308,15 @@ foreach AM = MxMoveSupportedAMs in {
307308
def MOVM # TYPE.Size # AM # m # TYPE.Postfix
308309
: MxMOVEM_MR<TYPE, !if(!eq(TYPE, MxType16), MxMOVEM_W, MxMOVEM_L),
309310
!cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM).Op,
310-
!cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
311+
!cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM),
312+
!if(!eq(AM, "e"), MxInverseMoveMask, MxMoveMask)>;
311313
} // foreach AM
312314

313315
let mayLoad = 1 in
314316
class MxMOVEM_RM<MxType TYPE, bit SIZE_ENC,
315-
MxOperand MEMOp, MxEncMemOp MEM_ENC>
316-
: MxInst<(outs), (ins MxMoveMask:$mask, MEMOp:$src),
317+
MxOperand MEMOp, MxEncMemOp MEM_ENC,
318+
MxOp MASKOp>
319+
: MxInst<(outs), (ins MASKOp:$mask, MEMOp:$src),
317320
"movem."#TYPE.Prefix#"\t$src, $mask", []> {
318321
let Inst = MxMOVEMEncoding<MEM_ENC, SIZE_ENC, MxMOVEM_RM, "mask">.Value;
319322
}
@@ -323,7 +326,8 @@ foreach AM = MxMoveSupportedAMs in {
323326
def MOVM # TYPE.Size # m # AM # TYPE.Postfix
324327
: MxMOVEM_RM<TYPE, !if(!eq(TYPE, MxType16), MxMOVEM_W, MxMOVEM_L),
325328
!cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#AM).Op,
326-
!cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
329+
!cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM),
330+
!if(!eq(AM, "e"), MxInverseMoveMask, MxMoveMask)>;
327331
} // foreach AM
328332

329333
// Pseudo versions. These a required by virtual register spill/restore since

llvm/lib/Target/M68k/M68kInstrInfo.td

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,19 @@ def MxBrTarget32 : MxBrTargetOperand<32>;
438438

439439
// Used with MOVEM
440440
def MxMoveMaskClass : MxOpClass<"MoveMask">;
441-
def MxMoveMask : MxOp<i16, MxSize16, "m"> {
441+
class MxMoveMaskOp : MxOp<i16, MxSize16, "m"> {
442442
let OperandType = "OPERAND_IMMEDIATE";
443443
let PrintMethod = "printMoveMask";
444444
let ParserMatchClass = MxMoveMaskClass;
445445
}
446446

447+
def MxMoveMask : MxMoveMaskOp;
448+
// The encoding of mask is reversed when the memory operand has an addressing
449+
// mode of 'e', that is, pre-decrement.
450+
def MxInverseMoveMask : MxMoveMaskOp {
451+
let EncoderMethod = "encodeInverseMoveMask";
452+
}
453+
447454
//===----------------------------------------------------------------------===//
448455
// Predicates
449456
//===----------------------------------------------------------------------===//

llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ class M68kMCCodeEmitter : public MCCodeEmitter {
6363
APInt &Value, SmallVectorImpl<MCFixup> &Fixups,
6464
const MCSubtargetInfo &STI) const;
6565

66+
void encodeInverseMoveMask(const MCInst &MI, unsigned OpIdx,
67+
unsigned InsertPos, APInt &Value,
68+
SmallVectorImpl<MCFixup> &Fixups,
69+
const MCSubtargetInfo &STI) const;
70+
6671
public:
6772
M68kMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
6873
: MCII(mcii), Ctx(ctx) {}
@@ -196,6 +201,13 @@ void M68kMCCodeEmitter::encodeFPSYSSelect(const MCInst &MI, unsigned OpIdx,
196201
}
197202
}
198203

204+
void M68kMCCodeEmitter::encodeInverseMoveMask(
205+
const MCInst &MI, unsigned OpIdx, unsigned InsertPos, APInt &Value,
206+
SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
207+
const MCOperand &Op = MI.getOperand(OpIdx);
208+
Value = llvm::reverseBits<uint16_t>((uint16_t)Op.getImm());
209+
}
210+
199211
void M68kMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &Op,
200212
unsigned InsertPos, APInt &Value,
201213
SmallVectorImpl<MCFixup> &Fixups,

llvm/test/MC/M68k/Data/Classes/MxMOVEM_MR.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ movem.l %d0, (%a1)
1313
; CHECK: movem.l %d0-%d1, (%a1)
1414
; CHECK-SAME: encoding: [0x48,0xd1,0x00,0x03]
1515
movem.l %d0-%d1, (%a1)
16+
17+
; CHECK: movem.l %d0-%d7/%a0-%a6, -(%sp)
18+
; CHECK-SAME: encoding: [0x48,0xe7,0xff,0xfe]
19+
movem.l %d0-%d7/%a0-%a6, -(%sp)

llvm/test/MC/M68k/Data/Classes/MxMOVEM_RM.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ movem.l (%a1), %d0
1313
; CHECK: movem.l (%a1), %d0-%d1
1414
; CHECK-SAME: encoding: [0x4c,0xd1,0x00,0x03]
1515
movem.l (%a1), %d0-%d1
16+
17+
; CHECK: movem.l -(%sp), %d0-%d7/%a0-%a6
18+
; CHECK-SAME: encoding: [0x4c,0xe7,0xff,0xfe]
19+
movem.l -(%sp), %d0-%d7/%a0-%a6

0 commit comments

Comments
 (0)