diff --git a/llvm/lib/Target/M68k/AsmParser/M68kAsmParser.cpp b/llvm/lib/Target/M68k/AsmParser/M68kAsmParser.cpp index 126176133dc027..31583eba658462 100644 --- a/llvm/lib/Target/M68k/AsmParser/M68kAsmParser.cpp +++ b/llvm/lib/Target/M68k/AsmParser/M68kAsmParser.cpp @@ -258,6 +258,7 @@ static inline unsigned getRegisterIndex(unsigned Register) { // We don't care about the indices of these registers. case M68k::PC: case M68k::CCR: + case M68k::SR: case M68k::FPC: case M68k::FPS: case M68k::FPIAR: @@ -636,10 +637,13 @@ bool M68kAsmParser::parseRegisterName(MCRegister &RegNo, SMLoc Loc, StringRef RegisterName) { auto RegisterNameLower = RegisterName.lower(); - // CCR register + // CCR and SR register if (RegisterNameLower == "ccr") { RegNo = M68k::CCR; return true; + } else if (RegisterNameLower == "sr") { + RegNo = M68k::SR; + return true; } // Parse simple general-purpose registers. diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp index 7f0f737faccd0d..43120d8cdef1ee 100644 --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -111,6 +111,12 @@ static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn, llvm_unreachable("unimplemented"); } +static DecodeStatus DecodeSRCRegisterClass(MCInst &Inst, APInt &Insn, + uint64_t Address, + const void *Decoder) { + llvm_unreachable("unimplemented"); +} + static DecodeStatus DecodeImm32(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder) { Inst.addOperand(MCOperand::createImm(M68k::swapWord(Imm))); diff --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td index dc777a933e2786..5f5cbfbc55ce15 100644 --- a/llvm/lib/Target/M68k/M68kInstrData.td +++ b/llvm/lib/Target/M68k/M68kInstrData.td @@ -365,13 +365,14 @@ def MOVM32mp_P : MxMOVEM_RM_Pseudo; // ons that will be resolved sometime after RA pass. //===----------------------------------------------------------------------===// +/// Move to CCR /// -------------------------------------------------- /// F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 /// -------------------------------------------------- /// | EFFECTIVE ADDRESS /// 0 1 0 0 0 1 0 0 1 1 | MODE | REG /// -------------------------------------------------- -let Defs = [CCR] in +let Defs = [CCR] in { class MxMoveToCCR : MxInst<(outs CCRC:$dst), (ins MEMOp:$src), "move.w\t$src, $dst", []> { let Inst = (ascend @@ -382,6 +383,7 @@ class MxMoveToCCR class MxMoveToCCRPseudo : MxPseudo<(outs CCRC:$dst), (ins MEMOp:$src)>; +} // let Defs = [CCR] let mayLoad = 1 in foreach AM = MxMoveSupportedAMs in { @@ -434,6 +436,64 @@ foreach AM = MxMoveSupportedAMs in { def MOV16dc : MxMoveFromCCR_R; def MOV8dc : MxMoveFromCCRPseudo; +/// Move to SR +/// -------------------------------------------------- +/// F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 +/// -------------------------------------------------- +/// | EFFECTIVE ADDRESS +/// 0 1 0 0 0 1 1 0 1 1 | MODE | REG +/// -------------------------------------------------- +let Defs = [SR] in { +class MxMoveToSR + : MxInst<(outs SRC:$dst), (ins MEMOp:$src), "move.w\t$src, $dst", []> { + let Inst = (ascend + (descend 0b0100011011, SRC_ENC.EA), + SRC_ENC.Supplement + ); +} +} // let Defs = [SR] + +let mayLoad = 1 in +foreach AM = MxMoveSupportedAMs in { + def MOV16s # AM : MxMoveToSR("MxOp16AddrMode_"#AM).Op, + !cast("MxMoveSrcOpEnc_"#AM)>; +} // foreach AM + +def MOV16sd : MxMoveToSR; + +/// Move from SR +/// -------------------------------------------------- +/// F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 +/// -------------------------------------------------- +/// | EFFECTIVE ADDRESS +/// 0 1 0 0 0 0 0 0 1 1 | MODE | REG +/// -------------------------------------------------- +let Uses = [SR] in { +class MxMoveFromSR_R + : MxInst<(outs MxDRD16:$dst), (ins SRC:$src), "move.w\t$src, $dst", []>, + Requires<[ AtLeastM68010 ]> { + let Inst = (descend 0b0100000011, MxEncAddrMode_d<"dst">.EA); +} + +class MxMoveFromSR_M + : MxInst<(outs), (ins MEMOp:$dst, SRC:$src), "move.w\t$src, $dst", []>, + Requires<[ AtLeastM68010 ]> { + let Inst = (ascend + (descend 0b0100000011, DST_ENC.EA), + DST_ENC.Supplement + ); +} +} // let Uses = [SR] + +let mayStore = 1 in +foreach AM = MxMoveSupportedAMs in { + def MOV16 # AM # s + : MxMoveFromSR_M("MxOp16AddrMode_"#AM).Op, + !cast("MxMoveDstOpEnc_"#AM)>; +} // foreach AM + +def MOV16ds : MxMoveFromSR_R; + //===----------------------------------------------------------------------===// // LEA //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/M68k/Data/Classes/MxMoveSR.s b/llvm/test/MC/M68k/Data/Classes/MxMoveSR.s new file mode 100644 index 00000000000000..03189311badb8e --- /dev/null +++ b/llvm/test/MC/M68k/Data/Classes/MxMoveSR.s @@ -0,0 +1,9 @@ +; RUN: llvm-mc -triple=m68k -mcpu=M68000 -show-encoding %s | FileCheck %s + +; CHECK: move.w %d1, %sr +; CHECK-SAME: encoding: [0x46,0xc1] +move.w %d1, %sr + +; CHECK: move.w %sr, %d1 +; CHECK-SAME: encoding: [0x40,0xc1] +move.w %sr, %d1