[llvm] bec7b16 - [M68k](3/8) Skeleton and target description files

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 8 12:33:46 PST 2021


Author: Min-Yih Hsu
Date: 2021-03-08T12:30:57-08:00
New Revision: bec7b166923bbaf0882ff4665224d7a8a7320aa0

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

LOG: [M68k](3/8) Skeleton and target description files

 - Infrastructure for the target (i.e. build files, target triple etc.)
 - All of the target description TableGen file

Authors: myhsu, m4yers, glaubitz

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

Added: 
    llvm/lib/Target/M68k/CMakeLists.txt
    llvm/lib/Target/M68k/M68k.td
    llvm/lib/Target/M68k/M68kCallingConv.td
    llvm/lib/Target/M68k/M68kInstrArithmetic.td
    llvm/lib/Target/M68k/M68kInstrBits.td
    llvm/lib/Target/M68k/M68kInstrCompiler.td
    llvm/lib/Target/M68k/M68kInstrControl.td
    llvm/lib/Target/M68k/M68kInstrData.td
    llvm/lib/Target/M68k/M68kInstrFormats.td
    llvm/lib/Target/M68k/M68kInstrInfo.td
    llvm/lib/Target/M68k/M68kInstrShiftRotate.td
    llvm/lib/Target/M68k/M68kRegisterInfo.td
    llvm/lib/Target/M68k/M68kSchedule.td
    llvm/lib/Target/M68k/M68kTargetMachine.cpp
    llvm/lib/Target/M68k/MCTargetDesc/CMakeLists.txt
    llvm/lib/Target/M68k/MCTargetDesc/M68kMCTargetDesc.cpp
    llvm/lib/Target/M68k/TargetInfo/CMakeLists.txt
    llvm/lib/Target/M68k/TargetInfo/M68kTargetInfo.cpp

Modified: 
    llvm/cmake/config-ix.cmake
    llvm/include/llvm/ADT/Triple.h
    llvm/lib/Support/Triple.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index 7473599f7513..fa250b917f6f 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -452,6 +452,8 @@ elseif (LLVM_NATIVE_ARCH MATCHES "riscv32")
   set(LLVM_NATIVE_ARCH RISCV)
 elseif (LLVM_NATIVE_ARCH MATCHES "riscv64")
   set(LLVM_NATIVE_ARCH RISCV)
+elseif (LLVM_NATIVE_ARCH STREQUAL "m68k")
+  set(LLVM_NATIVE_ARCH M68k)
 else ()
   message(FATAL_ERROR "Unknown architecture ${LLVM_NATIVE_ARCH}")
 endif ()

diff  --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
index eed315c929ad..3b351b732e9a 100644
--- a/llvm/include/llvm/ADT/Triple.h
+++ b/llvm/include/llvm/ADT/Triple.h
@@ -58,6 +58,7 @@ class Triple {
     bpfeb,          // eBPF or extended BPF or 64-bit BPF (big endian)
     csky,           // CSKY: csky
     hexagon,        // Hexagon: hexagon
+    m68k,           // M68k: Motorola 680x0 family
     mips,           // MIPS: mips, mipsallegrex, mipsr6
     mipsel,         // MIPSEL: mipsel, mipsallegrexe, mipsr6el
     mips64,         // MIPS64: mips64, mips64r6, mipsn32, mipsn32r6

diff  --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
index 2ec123fcca73..e5dd32fb5827 100644
--- a/llvm/lib/Support/Triple.cpp
+++ b/llvm/lib/Support/Triple.cpp
@@ -44,6 +44,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
   case lanai:          return "lanai";
   case le32:           return "le32";
   case le64:           return "le64";
+  case m68k:           return "m68k";
   case mips64:         return "mips64";
   case mips64el:       return "mips64el";
   case mips:           return "mips";
@@ -105,6 +106,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
   case ppc:
   case ppcle:       return "ppc";
 
+  case m68k:        return "m68k";
+
   case mips:
   case mipsel:
   case mips64:
@@ -281,6 +284,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
     .Case("armeb", armeb)
     .Case("avr", avr)
     .StartsWith("bpf", BPFArch)
+    .Case("m68k", m68k)
     .Case("mips", mips)
     .Case("mipsel", mipsel)
     .Case("mips64", mips64)
@@ -419,6 +423,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
     .Case("thumb", Triple::thumb)
     .Case("thumbeb", Triple::thumbeb)
     .Case("avr", Triple::avr)
+    .Case("m68k", Triple::m68k)
     .Case("msp430", Triple::msp430)
     .Cases("mips", "mipseb", "mipsallegrex", "mipsisa32r6",
            "mipsr6", Triple::mips)
@@ -704,6 +709,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
   case Triple::lanai:
   case Triple::le32:
   case Triple::le64:
+  case Triple::m68k:
   case Triple::mips64:
   case Triple::mips64el:
   case Triple::mips:
@@ -1277,6 +1283,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
   case llvm::Triple::kalimba:
   case llvm::Triple::lanai:
   case llvm::Triple::le32:
+  case llvm::Triple::m68k:
   case llvm::Triple::mips:
   case llvm::Triple::mipsel:
   case llvm::Triple::nvptx:
@@ -1361,6 +1368,7 @@ Triple Triple::get32BitArchVariant() const {
   case Triple::kalimba:
   case Triple::lanai:
   case Triple::le32:
+  case Triple::m68k:
   case Triple::mips:
   case Triple::mipsel:
   case Triple::nvptx:
@@ -1413,6 +1421,7 @@ Triple Triple::get64BitArchVariant() const {
   case Triple::hexagon:
   case Triple::kalimba:
   case Triple::lanai:
+  case Triple::m68k:
   case Triple::msp430:
   case Triple::r600:
   case Triple::shave:
@@ -1537,6 +1546,7 @@ Triple Triple::getLittleEndianArchVariant() const {
   case Triple::lanai:
   case Triple::sparcv9:
   case Triple::systemz:
+  case Triple::m68k:
 
   // ARM is intentionally unsupported here, changing the architecture would
   // drop any arch suffixes.

diff  --git a/llvm/lib/Target/M68k/CMakeLists.txt b/llvm/lib/Target/M68k/CMakeLists.txt
new file mode 100644
index 000000000000..1bd78445f572
--- /dev/null
+++ b/llvm/lib/Target/M68k/CMakeLists.txt
@@ -0,0 +1,36 @@
+add_llvm_component_group(M68k)
+
+set(LLVM_TARGET_DEFINITIONS M68k.td)
+
+tablegen(LLVM M68kGenRegisterInfo.inc     -gen-register-info)
+tablegen(LLVM M68kGenInstrInfo.inc        -gen-instr-info)
+tablegen(LLVM M68kGenSubtargetInfo.inc    -gen-subtarget)
+tablegen(LLVM M68kGenMCCodeBeads.inc      -gen-code-beads)
+tablegen(LLVM M68kGenMCPseudoLowering.inc -gen-pseudo-lowering)
+tablegen(LLVM M68kGenDAGISel.inc          -gen-dag-isel)
+tablegen(LLVM M68kGenCallingConv.inc      -gen-callingconv)
+tablegen(LLVM M68kGenAsmWriter.inc        -gen-asm-writer)
+
+add_public_tablegen_target(M68kCommonTableGen)
+
+add_llvm_target(M68kCodeGen
+  M68kTargetMachine.cpp
+
+  LINK_COMPONENTS
+  Analysis
+  AsmPrinter
+  CodeGen
+  Core
+  MC
+  SelectionDAG
+  Support
+  Target
+  M68kDesc
+  M68kInfo
+
+  ADD_TO_COMPONENT
+  M68k
+)
+
+add_subdirectory(TargetInfo)
+add_subdirectory(MCTargetDesc)

diff  --git a/llvm/lib/Target/M68k/M68k.td b/llvm/lib/Target/M68k/M68k.td
new file mode 100644
index 000000000000..f308a6d6387d
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68k.td
@@ -0,0 +1,93 @@
+//===-- M68k.td - Motorola 680x0 target definitions ------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This is a target description file for the Motorola 680x0 family, referred
+/// to here as the "M68k" architecture.
+///
+//===----------------------------------------------------------------------===//
+
+include "llvm/Target/Target.td"
+
+//===----------------------------------------------------------------------===//
+// M68k Subtarget features
+//===----------------------------------------------------------------------===//
+
+def FeatureISA00
+  : SubtargetFeature<"isa-68000", "SubtargetKind", "M00",
+                     "Is M68000 ISA supported">;
+
+def FeatureISA10
+  : SubtargetFeature<"isa-68010", "SubtargetKind", "M10",
+                     "Is M68010 ISA supported",
+                     [ FeatureISA00 ]>;
+
+def FeatureISA20
+  : SubtargetFeature<"isa-68020", "SubtargetKind", "M20",
+                     "Is M68020 ISA supported",
+                     [ FeatureISA10 ]>;
+
+def FeatureISA30
+  : SubtargetFeature<"isa-68030", "SubtargetKind", "M30",
+                     "Is M68030 ISA supported",
+                     [ FeatureISA20 ]>;
+
+def FeatureISA40
+  : SubtargetFeature<"isa-68040", "SubtargetKind", "M40",
+                     "Is M68040 ISA supported",
+                     [ FeatureISA30 ]>;
+
+def FeatureISA60
+  : SubtargetFeature<"isa-68060", "SubtargetKind", "M60",
+                     "Is M68060 ISA supported",
+                     [ FeatureISA40 ]>;
+
+//===----------------------------------------------------------------------===//
+// M68k processors supported.
+//===----------------------------------------------------------------------===//
+
+include "M68kSchedule.td"
+
+class Proc<string Name, list<SubtargetFeature> Features>
+    : ProcessorModel<Name, GenericM68kModel, Features>;
+
+def : Proc<"generic", [ FeatureISA00 ]>;
+def : Proc<"M68000",  [ FeatureISA00 ]>;
+def : Proc<"M68010",  [ FeatureISA10 ]>;
+def : Proc<"M68020",  [ FeatureISA20 ]>;
+def : Proc<"M68030",  [ FeatureISA30 ]>;
+def : Proc<"M68040",  [ FeatureISA40 ]>;
+def : Proc<"M68060",  [ FeatureISA60 ]>;
+
+//===----------------------------------------------------------------------===//
+// Register File Description
+//===----------------------------------------------------------------------===//
+
+include "M68kRegisterInfo.td"
+
+//===----------------------------------------------------------------------===//
+// Instruction Descriptions
+//===----------------------------------------------------------------------===//
+
+include "M68kInstrInfo.td"
+
+def M68kInstrInfo : InstrInfo;
+
+//===----------------------------------------------------------------------===//
+// Calling Conventions
+//===----------------------------------------------------------------------===//
+
+include "M68kCallingConv.td"
+
+//===----------------------------------------------------------------------===//
+// Target
+//===----------------------------------------------------------------------===//
+
+def M68k : Target {
+  let InstructionSet = M68kInstrInfo;
+}

diff  --git a/llvm/lib/Target/M68k/M68kCallingConv.td b/llvm/lib/Target/M68k/M68kCallingConv.td
new file mode 100644
index 000000000000..360f2199cf6f
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kCallingConv.td
@@ -0,0 +1,119 @@
+//===-- M68kCallingConv.td - Calling Conventions for M68k --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This describes the calling conventions for the M68k architectures. These
+/// conventions assume Int to be 4 bytes and 4 byte aligned.
+///
+//===----------------------------------------------------------------------===//
+
+// TODO Verify C convention follows SysV M68K ABI
+
+class CCIfSubtarget<string F, CCAction A>
+    : CCIf<!strconcat("static_cast<const M68kSubtarget &>"
+                      "(State.getMachineFunction().getSubtarget()).", F), A>;
+
+//===----------------------------------------------------------------------===//
+// Return Value Calling Conventions
+//===----------------------------------------------------------------------===//
+
+/// Return-value conventions common to all M68k CC's.
+def RetCC_M68kCommon : CallingConv<[
+]>;
+
+/// M68k C return convention.
+/// TODO: Return via address register
+def RetCC_M68k_C : CallingConv<[
+  CCIfType<[i1],   CCPromoteToType<i8>>,
+  CCIfType<[i8],   CCAssignToReg<[BD0, BD1]>>,
+  CCIfType<[i16],  CCAssignToReg<[WD0, WD1]>>,
+  CCIfType<[i32],  CCAssignToReg<[D0, D1]>>,
+  CCDelegateTo<RetCC_M68kCommon>
+]>;
+
+/// M68k fastcc return convention.
+/// This convention allows to return up to 16 bytes in registers which can be
+/// split among 16 1-byte values or used for a single 16-byte value.
+/// TODO: Verify its functionality and write tests
+def RetCC_M68k_Fast : CallingConv<[
+  CCIfType<[i1],   CCPromoteToType<i8>>,
+  CCIfType<[i8],   CCAssignToReg<[BD0, BD1]>>,
+  CCIfType<[i16],  CCAssignToReg<[WD0, WD1, WA0, WA1]>>,
+  CCIfType<[i32],  CCAssignToReg<[D0, D1, A0, A1]>>,
+  CCDelegateTo<RetCC_M68kCommon>
+]>;
+
+/// This is the root return-value convention for the M68k backend.
+def RetCC_M68k : CallingConv<[
+  CCIfCC<"CallingConv::Fast", CCDelegateTo<RetCC_M68k_Fast>>,
+  CCDelegateTo<RetCC_M68k_C>
+]>;
+
+//===----------------------------------------------------------------------===//
+// M68k C Calling Convention
+//===----------------------------------------------------------------------===//
+
+/// CC_M68k_Common - In all M68k calling conventions, extra integers and FP
+/// values are spilled on the stack.
+def CC_M68k_Common : CallingConv<[
+  /// Handles byval parameters.
+  CCIfByVal<CCPassByVal<4, 4>>,
+
+  /// Integer values get stored in stack slots that are 4 bytes in
+  /// size and 4-byte aligned.
+  CCIfType<[i32],  CCAssignToStack<4, 4>>
+]>;
+
+def CC_M68k_Fast : CallingConv<[
+  /// Promote i1/i8/i16 arguments to i32.
+  CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
+
+  /// The 'nest' parameter, if any, is passed in A1.
+  CCIfNest<CCAssignToReg<[A1]>>, // FIXME verify if this is correct
+
+  /// Since M68k uses %An for pointers and we want them be passed in regs
+  /// too we have to use custom function.
+  CCIfType<[i32], CCCustom<"CC_M68k_Any_AssignToReg">>,
+
+  /// Otherwise, same as everything else.
+  CCDelegateTo<CC_M68k_Common>
+]>;
+
+def CC_M68k_C : CallingConv<[
+  /// Promote i1/i8/i16 arguments to i32.
+  CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
+
+  /// The 'nest' parameter, if any, is passed in A1.
+  CCIfNest<CCAssignToReg<[A1]>>, // FIXME verify if this is correct
+
+  /// Use registers only if 'inreg' used and the call is not vararg
+  CCIfNotVarArg<CCIfInReg<CCIfType<[i32], CCAssignToReg<[D0, D1]>>>>,
+
+  // TODO: Support for 'sret'
+
+  /// Otherwise, same as everything else.
+  CCDelegateTo<CC_M68k_Common>
+]>;
+
+/// This is the root argument convention for the M68k backend.
+def CC_M68k : CallingConv<[
+  CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_M68k_Fast>>,
+  CCDelegateTo<CC_M68k_C>
+]>;
+
+//===----------------------------------------------------------------------===//
+// Callee-saved Registers.
+//===----------------------------------------------------------------------===//
+
+def CSR_NoRegs : CalleeSavedRegs<(add)>;
+
+// A5 - BP
+// A6 - FP
+def CSR_STD : CalleeSavedRegs<(add D2, D3, D4, D5, D6, D7,
+                                   A2, A3, A4, A5, A6)>;
+

diff  --git a/llvm/lib/Target/M68k/M68kInstrArithmetic.td b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
new file mode 100644
index 000000000000..f4714d2534bd
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
@@ -0,0 +1,886 @@
+//===-- M68kInstrArithmetic.td - Integer Arith Instrs ------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the integer arithmetic instructions in the M68k
+/// architecture. Here is the current status of the file:
+///
+///  Machine:
+///
+///    ADD       [~]   ADDA      [~]   ADDI        [~]   ADDQ [ ]   ADDX [~]
+///    CLR       [ ]   CMP       [~]   CMPA        [~]   CMPI [~]   CMPM [ ]
+///    CMP2      [ ]   DIVS/DIVU [~]   DIVSL/DIVUL [ ]   EXT  [~]   EXTB [ ]
+///    MULS/MULU [~]   NEG       [~]   NEGX        [~]   SUB  [~]   SUBA [~]
+///    SUBI      [~]   SUBQ      [ ]   SUBX        [~]
+///
+///  Map:
+///
+///   [ ] - was not touched at all
+///   [!] - requires extarnal stuff implemented
+///   [~] - functional implementation
+///   [X] - complete implementation
+///
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Encoding
+//===----------------------------------------------------------------------===//
+
+/// Encoding for Normal forms
+/// ----------------------------------------------------
+///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
+/// ----------------------------------------------------
+///             |         |         | EFFECTIVE ADDRESS
+///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG
+/// ----------------------------------------------------
+class MxArithEncoding<MxBead4Bits CMD, MxEncOpMode OPMODE, MxBeadReg REG,
+                      MxEncEA EA, MxEncExt EXT>
+    : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE.B0, OPMODE.B1, OPMODE.B2, REG,
+                 CMD,EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
+
+/// Encoding for Extended forms
+/// ------------------------------------------------------
+///  F  E  D  C | B  A  9 | 8 | 7  6 | 5  4 | 3 | 2  1  0
+/// ------------------------------------------------------
+///  x  x  x  x |  REG Rx | 1 | SIZE | 0  0 | M |  REG Ry
+/// ------------------------------------------------------
+/// Rx - destination
+/// Ry - source
+/// M  - address mode switch
+class MxArithXEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxBead1Bit MODE,
+                       MxBeadReg SRC, MxBeadReg DST>
+    : MxEncoding<SRC, MODE, MxBead2Bits<0b00>, SIZE, MxBead1Bit<0b1>, DST, CMD>;
+
+/// Encoding for Immediate forms
+/// ---------------------------------------------------
+///  F  E  D  C  B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
+/// ---------------------------------------------------
+///                         |      | EFFECTIVE ADDRESS
+///  x  x  x  x  x  x  x  x | SIZE |   MODE  |   REG
+/// ---------------------------------------------------
+///     16-BIT WORD DATA    |     8-BIT BYTE DATA
+/// ---------------------------------------------------
+///                 32-BIT LONG DATA
+/// ---------------------------------------------------
+/// NOTE It is used to store an immediate to memory, imm-to-reg are handled with
+/// normal version
+class MxArithImmEncoding<MxBead4Bits CMD, MxEncSize SIZE,
+                         MxEncEA DST_EA, MxEncExt DST_EXT, MxEncExt SRC_EXT>
+    : MxEncoding<DST_EA.Reg, DST_EA.DA, DST_EA.Mode, SIZE, CMD, MxBead4Bits<0>,
+                 // Source
+                 SRC_EXT.Imm, SRC_EXT.B8, SRC_EXT.Scale,
+                 SRC_EXT.WL, SRC_EXT.DAReg,
+                 // Destination
+                 DST_EXT.Imm, DST_EXT.B8, DST_EXT.Scale,
+                 DST_EXT.WL, DST_EXT.DAReg>;
+
+
+//===----------------------------------------------------------------------===//
+// Add/Sub
+//===----------------------------------------------------------------------===//
+
+let Defs = [CCR] in {
+let Constraints = "$src = $dst" in {
+
+// $reg, $ccr <- $reg op $reg
+class MxBiArOp_RFRR_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
+           MN#"."#TYPE.Prefix#"\t$opd, $dst",
+           [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))],
+           MxArithEncoding<MxBead4Bits<CMD>,
+                           !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
+                           MxBeadReg<0>,
+                           !cast<MxEncEA>("MxEncEA"#TYPE.RLet#"_2"),
+                           MxExtEmpty>>;
+
+/// This Op is similar to the one above except it uses reversed opmode, some
+/// commands(e.g. eor) do not support dEA or rEA modes and require EAd for
+/// register only operations.
+/// NOTE when using dd commands it is irrelevant which opmode to use(as it seems)
+/// but some opcodes support address register and some do not which creates this
+/// mess.
+class MxBiArOp_RFRR_EAd<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
+           MN#"."#TYPE.Prefix#"\t$opd, $dst",
+           [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))],
+           MxArithEncoding<MxBead4Bits<CMD>,
+                           !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EAd"),
+                           MxBeadReg<2>, MxEncEAd_0, MxExtEmpty>>;
+
+// $reg <- $reg op $imm
+class MxBiArOp_RFRI_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
+              MN#"."#TYPE.Prefix#"\t$opd, $dst",
+              [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))],
+              MxArithEncoding<MxBead4Bits<CMD>,
+                              !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
+                              MxBeadReg<0>, MxEncEAi,
+                              !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>;
+
+// Again, there are two ways to write an immediate to Dn register either dEA
+// opmode or using *I encoding, and again some instrucitons also support address
+// registers some do not.
+class MxBiArOp_RFRI<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd),
+              MN#"i."#TYPE.Prefix#"\t$opd, $dst",
+              [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))],
+              MxArithImmEncoding<MxBead4Bits<CMD>, !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                   !cast<MxEncEA>("MxEncEA"#TYPE.RLet#"_0"), MxExtEmpty,
+                   !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>;
+
+let mayLoad = 1 in
+class MxBiArOp_RFRM<string MN, SDNode NODE, MxType TYPE, MxOperand OPD, ComplexPattern PAT,
+                    bits<4> CMD, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, OPD:$opd),
+           MN#"."#TYPE.Prefix#"\t$opd, $dst",
+           [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, (TYPE.Load PAT:$opd)))],
+           MxArithEncoding<MxBead4Bits<CMD>,
+                           !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"),
+                           MxBeadReg<0>, EA, EXT>>;
+
+} // Constraints
+
+let mayLoad = 1, mayStore = 1 in {
+
+// FIXME MxBiArOp_FMR/FMI cannot consume CCR from MxAdd/MxSub which leads for
+// MxAdd to survive the match and subsequent mismatch.
+class MxBiArOp_FMR<string MN, SDNode NODE, MxType TYPE,
+                   MxOperand MEMOpd, ComplexPattern MEMPat,
+                   bits<4> CMD, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.ROp:$opd),
+        MN#"."#TYPE.Prefix#"\t$opd, $dst",
+        [],
+        MxArithEncoding<MxBead4Bits<CMD>,
+                        !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EA"#TYPE.RLet),
+                        MxBeadReg<1>, EA, EXT>>;
+
+class MxBiArOp_FMI<string MN, SDNode NODE, MxType TYPE,
+                   MxOperand MEMOpd, ComplexPattern MEMPat,
+                   bits<4> CMD, MxEncEA MEMEA, MxEncExt MEMExt>
+    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.IOp:$opd),
+        MN#"."#TYPE.Prefix#"\t$opd, $dst",
+        [],
+        MxArithImmEncoding<MxBead4Bits<CMD>,
+                            !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                            MEMEA, MEMExt,
+                            !cast<MxEncExt>("MxExtI"#TYPE.Size#"_1")>>;
+} // mayLoad, mayStore
+} // Defs = [CCR]
+
+multiclass MxBiArOp_DF<string MN, SDNode NODE, bit isComm,
+                       bits<4> CMD, bits<4> CMDI> {
+
+  // op $mem, $reg
+  def NAME#"8dk"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.KOp,  MxType8.KPat,
+                                  CMD, MxEncEAk, MxExtBrief_2>;
+  def NAME#"16dk" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.KOp, MxType16.KPat,
+                                  CMD, MxEncEAk, MxExtBrief_2>;
+  def NAME#"32dk" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.KOp, MxType32.KPat,
+                                  CMD, MxEncEAk, MxExtBrief_2>;
+
+  def NAME#"8dq"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.QOp,  MxType8.QPat,
+                                  CMD, MxEncEAq, MxExtI16_2>;
+  def NAME#"16dq" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.QOp, MxType16.QPat,
+                                  CMD, MxEncEAq, MxExtI16_2>;
+  def NAME#"32dq" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.QOp, MxType32.QPat,
+                                  CMD, MxEncEAq, MxExtI16_2>;
+
+  def NAME#"8dp"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.POp,  MxType8.PPat,
+                                  CMD, MxEncEAp_2, MxExtI16_2>;
+  def NAME#"16dp" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.POp, MxType16.PPat,
+                                  CMD, MxEncEAp_2, MxExtI16_2>;
+  def NAME#"32dp" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.POp, MxType32.PPat,
+                                  CMD, MxEncEAp_2, MxExtI16_2>;
+
+  def NAME#"8df"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.FOp,  MxType8.FPat,
+                                  CMD, MxEncEAf_2, MxExtBrief_2>;
+  def NAME#"16df" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.FOp, MxType16.FPat,
+                                  CMD, MxEncEAf_2, MxExtBrief_2>;
+  def NAME#"32df" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.FOp, MxType32.FPat,
+                                  CMD, MxEncEAf_2, MxExtBrief_2>;
+
+  def NAME#"8dj"  : MxBiArOp_RFRM<MN, NODE, MxType8d,  MxType8.JOp,  MxType8.JPat,
+                                  CMD, MxEncEAj_2, MxExtEmpty>;
+  def NAME#"16dj" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.JOp, MxType16.JPat,
+                                  CMD, MxEncEAj_2, MxExtEmpty>;
+  def NAME#"32dj" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.JOp, MxType32.JPat,
+                                  CMD, MxEncEAj_2, MxExtEmpty>;
+
+  // op $imm, $reg
+  def NAME#"8di"  : MxBiArOp_RFRI_xEA<MN, NODE, MxType8d,  CMD>;
+  def NAME#"16di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType16d, CMD>;
+  def NAME#"32di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32d, CMD>;
+
+  // op $reg, $mem
+  def NAME#"8pd"  : MxBiArOp_FMR<MN, NODE, MxType8d,  MxType8.POp,  MxType8.PPat,
+                                 CMD, MxEncEAp_0, MxExtI16_0>;
+  def NAME#"16pd" : MxBiArOp_FMR<MN, NODE, MxType16d, MxType16.POp, MxType16.PPat,
+                                 CMD, MxEncEAp_0, MxExtI16_0>;
+  def NAME#"32pd" : MxBiArOp_FMR<MN, NODE, MxType32d, MxType32.POp, MxType32.PPat,
+                                 CMD, MxEncEAp_0, MxExtI16_0>;
+
+  def NAME#"8fd"  : MxBiArOp_FMR<MN, NODE, MxType8d,  MxType8.FOp,  MxType8.FPat,
+                                 CMD, MxEncEAf_0, MxExtBrief_0>;
+  def NAME#"16fd" : MxBiArOp_FMR<MN, NODE, MxType16d, MxType16.FOp, MxType16.FPat,
+                                 CMD, MxEncEAf_0, MxExtBrief_0>;
+  def NAME#"32fd" : MxBiArOp_FMR<MN, NODE, MxType32d, MxType32.FOp, MxType32.FPat,
+                                 CMD, MxEncEAf_0, MxExtBrief_0>;
+
+  def NAME#"8jd"  : MxBiArOp_FMR<MN, NODE, MxType8d,  MxType8.JOp,  MxType8.JPat,
+                                 CMD, MxEncEAj_0, MxExtEmpty>;
+  def NAME#"16jd" : MxBiArOp_FMR<MN, NODE, MxType16d, MxType16.JOp, MxType16.JPat,
+                                 CMD, MxEncEAj_0, MxExtEmpty>;
+  def NAME#"32jd" : MxBiArOp_FMR<MN, NODE, MxType32d, MxType32.JOp, MxType32.JPat,
+                                 CMD, MxEncEAj_0, MxExtEmpty>;
+
+  // op $imm, $mem
+  def NAME#"8pi"  : MxBiArOp_FMI<MN, NODE, MxType8,  MxType8.POp,  MxType8.PPat,
+                                 CMDI, MxEncEAp_0, MxExtI16_0>;
+  def NAME#"16pi" : MxBiArOp_FMI<MN, NODE, MxType16, MxType16.POp, MxType16.PPat,
+                                 CMDI, MxEncEAp_0, MxExtI16_0>;
+  def NAME#"32pi" : MxBiArOp_FMI<MN, NODE, MxType32, MxType32.POp, MxType32.PPat,
+                                 CMDI, MxEncEAp_0, MxExtI16_0>;
+
+  def NAME#"8fi"  : MxBiArOp_FMI<MN, NODE, MxType8,  MxType8.FOp,  MxType8.FPat,
+                                 CMDI, MxEncEAf_0, MxExtBrief_0>;
+  def NAME#"16fi" : MxBiArOp_FMI<MN, NODE, MxType16, MxType16.FOp, MxType16.FPat,
+                                 CMDI, MxEncEAf_0, MxExtBrief_0>;
+  def NAME#"32fi" : MxBiArOp_FMI<MN, NODE, MxType32, MxType32.FOp, MxType32.FPat,
+                                 CMDI, MxEncEAf_0, MxExtBrief_0>;
+
+  def NAME#"8ji"  : MxBiArOp_FMI<MN, NODE, MxType8,  MxType8.JOp,  MxType8.JPat,
+                                 CMDI, MxEncEAj_0, MxExtEmpty>;
+  def NAME#"16ji" : MxBiArOp_FMI<MN, NODE, MxType16, MxType16.JOp, MxType16.JPat,
+                                 CMDI, MxEncEAj_0, MxExtEmpty>;
+  def NAME#"32ji" : MxBiArOp_FMI<MN, NODE, MxType32, MxType32.JOp, MxType32.JPat,
+                                 CMDI, MxEncEAj_0, MxExtEmpty>;
+
+  let isCommutable = isComm in {
+
+    def NAME#"8dd"  : MxBiArOp_RFRR_xEA<MN, NODE, MxType8d,  CMD>;
+    def NAME#"16dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, CMD>;
+    def NAME#"32dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, CMD>;
+
+  } // isComm
+
+} // MxBiArOp_DF
+
+
+// These special snowflakes allowed to match address registers but since *A
+// operations do not produce CCR we should not match them against Mx nodes that
+// produce it.
+let Pattern = [(null_frag)] in
+multiclass MxBiArOp_AF<string MN, SDNode NODE, bit isComm,
+                       bits<4> CMD, bits<4> CMDI> {
+
+  def NAME#"32rk" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.KOp, MxType32.KPat,
+                                  CMD, MxEncEAk, MxExtBrief_2>;
+  def NAME#"32rq" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.QOp, MxType32.QPat,
+                                  CMD, MxEncEAq, MxExtI16_2>;
+  def NAME#"32rf" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.FOp, MxType32.FPat,
+                                  CMD, MxEncEAf_2, MxExtBrief_2>;
+  def NAME#"32rp" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.POp, MxType32.PPat,
+                                  CMD, MxEncEAp_2, MxExtI16_2>;
+  def NAME#"32rj" : MxBiArOp_RFRM<MN, NODE, MxType32r, MxType32.JOp, MxType32.JPat,
+                                  CMD, MxEncEAj_2, MxExtEmpty>;
+  def NAME#"32ri" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32r, CMD>;
+
+  let isCommutable = isComm in
+  def NAME#"32rr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32r, CMD>;
+
+} // MxBiArOp_AF
+
+// NOTE These naturally produce CCR
+
+defm ADD : MxBiArOp_DF<"add", MxAdd, 1, 0xD, 0x6>;
+defm ADD : MxBiArOp_AF<"add", MxAdd, 1, 0xD, 0x6>;
+defm SUB : MxBiArOp_DF<"sub", MxSub, 0, 0x9, 0x4>;
+defm SUB : MxBiArOp_AF<"sub", MxSub, 0, 0x9, 0x4>;
+
+
+let Uses = [CCR], Defs = [CCR] in {
+let Constraints = "$src = $dst" in {
+
+// $reg, ccr <- $reg op $reg op ccr
+class MxBiArOp_RFRRF<string MN, SDNode NODE, MxType TYPE, bits<4> CMD>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
+             MN#"."#TYPE.Prefix#"\t$opd, $dst",
+             [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd, CCR))],
+             MxArithXEncoding<MxBead4Bits<CMD>,
+                              !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                              MxBead1Bit<0>, MxBeadReg<2>, MxBeadReg<0>>>;
+
+} // Constraints
+} // Uses, Defs
+
+multiclass MxBiArOp_RFF<string MN, SDNode NODE, bit isComm, bits<4> CMD> {
+
+let isCommutable = isComm in {
+
+  def NAME#"8dd"  : MxBiArOp_RFRRF<MN, NODE, MxType8d,  CMD>;
+  def NAME#"16dd" : MxBiArOp_RFRRF<MN, NODE, MxType16d, CMD>;
+  def NAME#"32dd" : MxBiArOp_RFRRF<MN, NODE, MxType32d, CMD>;
+
+} // isComm
+
+} // MxBiArOp_RFF
+
+// NOTE These consume and produce CCR
+defm ADDX : MxBiArOp_RFF<"addx", MxAddX, 1, 0xD>;
+defm SUBX : MxBiArOp_RFF<"subx", MxSubX, 0, 0x9>;
+
+
+//===----------------------------------------------------------------------===//
+// And/Xor/Or
+//===----------------------------------------------------------------------===//
+
+defm AND : MxBiArOp_DF<"and", MxAnd, 1, 0xC, 0x2>;
+defm OR  : MxBiArOp_DF<"or",  MxOr,  1, 0x8, 0x0>;
+
+multiclass MxBiArOp_DF_EAd<string MN, SDNode NODE, bits<4> CMD, bits<4> CMDI> {
+
+  let isCommutable = 1 in {
+
+  def NAME#"8dd"  : MxBiArOp_RFRR_EAd<MN, NODE, MxType8d,  CMD>;
+  def NAME#"16dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType16d, CMD>;
+  def NAME#"32dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType32d, CMD>;
+
+  } // isCommutable = 1
+
+  def NAME#"8di"  : MxBiArOp_RFRI<MN, NODE,  MxType8d, CMDI>;
+  def NAME#"16di" : MxBiArOp_RFRI<MN, NODE, MxType16d, CMDI>;
+  def NAME#"32di" : MxBiArOp_RFRI<MN, NODE, MxType32d, CMDI>;
+
+} // MxBiArOp_DF_EAd
+
+defm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>;
+
+
+//===----------------------------------------------------------------------===//
+// CMP
+//===----------------------------------------------------------------------===//
+
+let Defs = [CCR] in {
+class MxCmp_RR<MxType TYPE>
+    : MxInst<(outs), (ins TYPE.ROp:$lhs, TYPE.ROp:$rhs),
+             "cmp."#TYPE.Prefix#"\t$lhs, $rhs",
+             [(set CCR, (MxCmp TYPE.VT:$lhs, TYPE.VT:$rhs))],
+             MxArithEncoding<MxBead4Bits<0xB>,
+                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"dEA"),
+                             MxBeadReg<1>, MxEncEAd_0, MxExtEmpty>>;
+
+class MxCmp_RI<MxType TYPE>
+    : MxInst<(outs), (ins TYPE.IOp:$imm, TYPE.ROp:$reg),
+             "cmpi."#TYPE.Prefix#"\t$imm, $reg",
+             [(set CCR, (MxCmp TYPE.IPat:$imm, TYPE.VT:$reg))],
+             MxArithImmEncoding<MxBead4Bits<0xC>,
+                                !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                                MxEncEAd_1, MxExtEmpty,
+                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
+
+let mayLoad = 1 in {
+
+class MxCmp_MI<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
+               MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins TYPE.IOp:$imm, MEMOpd:$mem),
+             "cmpi."#TYPE.Prefix#"\t$imm, $mem",
+             [(set CCR, (MxCmp TYPE.IPat:$imm, (load MEMPat:$mem)))],
+             MxArithImmEncoding<MxBead4Bits<0xC>,
+                                !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                                EA, EXT,
+                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
+
+class MxCmp_BI<MxType TYPE>
+    : MxInst<(outs), (ins TYPE.IOp:$imm, MxAL32:$abs),
+             "cmpi."#TYPE.Prefix#"\t$imm, $abs",
+             [(set CCR, (MxCmp TYPE.IPat:$imm,
+                               (load (i32 (MxWrapper tglobaladdr:$abs)))))],
+             MxArithImmEncoding<MxBead4Bits<0xC>,
+                                !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                                MxEncEAb, MxExtI32_1,
+                                !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>;
+
+class MxCmp_RM<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
+               MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins TYPE.ROp:$reg, MEMOpd:$mem),
+             "cmp."#TYPE.Prefix#"\t$mem, $reg",
+             [(set CCR, (MxCmp (load MEMPat:$mem), TYPE.ROp:$reg))],
+             MxArithEncoding<MxBead4Bits<0xB>,
+                             !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"dEA"),
+                             MxBeadReg<0>, EA, EXT>>;
+} // let mayLoad = 1
+
+} // let Defs = [CCR]
+
+multiclass MMxCmp_RM<MxType TYPE> {
+  def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
+                                      MxExtBrief_1>;
+  def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
+                                      MxExtI16_1>;
+  def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
+                                      MxExtI16_1>;
+  def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
+                                      MxExtBrief_1>;
+  def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
+                                      MxExtEmpty>;
+}
+
+multiclass MMxCmp_MI<MxType TYPE> {
+  def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk,
+                                          MxExtBrief_1>;
+  def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq,
+                                          MxExtI16_1>;
+  def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1,
+                                          MxExtI16_1>;
+  def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1,
+                                          MxExtBrief_1>;
+  def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1,
+                                          MxExtEmpty>;
+}
+
+foreach S = [8, 16, 32] in {
+  def CMP#S#dd : MxCmp_RR<!cast<MxType>("MxType"#S#"d")>;
+  def CMP#S#di : MxCmp_RI<!cast<MxType>("MxType"#S#"d")>;
+  def CMP#S#bi : MxCmp_BI<!cast<MxType>("MxType"#S#"d")>;
+} // foreach
+
+// cmp mem, Dn
+defm CMP8d  : MMxCmp_RM<MxType8d>;
+defm CMP16d : MMxCmp_RM<MxType16d>;
+defm CMP32d : MMxCmp_RM<MxType32d>;
+
+// cmp #imm, mem
+defm CMP8  : MMxCmp_MI<MxType8d>;
+defm CMP16 : MMxCmp_MI<MxType16d>;
+defm CMP32 : MMxCmp_MI<MxType32d>;
+
+
+//===----------------------------------------------------------------------===//
+// EXT
+//===----------------------------------------------------------------------===//
+
+def MxExtOpmode_wb : MxBead3Bits<0b010>;
+def MxExtOpmode_lw : MxBead3Bits<0b011>;
+def MxExtOpmode_lb : MxBead3Bits<0b111>;
+
+/// ---------------------------------------------------
+///  F  E  D  C  B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
+/// ---------------------------------------------------
+///  0  1  0  0  1  0  0 |  OPMODE | 0  0  0 |   REG
+/// ---------------------------------------------------
+class MxExtEncoding<MxBead3Bits OPMODE>
+    : MxEncoding<MxBeadReg<0>, MxBead3Bits<0b000>, OPMODE,
+                 MxBead3Bits<0b100>, MxBead4Bits<0b0100>>;
+
+let Defs = [CCR] in
+let Constraints = "$src = $dst" in
+class MxExt<MxType TO, MxType FROM>
+    : MxInst<(outs TO.ROp:$dst), (ins TO.ROp:$src),
+              "ext."#TO.Prefix#"\t$src", [],
+              MxExtEncoding<!cast<MxBead3Bits>("MxExtOpmode_"#TO.Prefix#FROM.Prefix)>>;
+
+def EXT16 : MxExt<MxType16d, MxType8d>;
+def EXT32 : MxExt<MxType32d, MxType16d>;
+
+def : Pat<(sext_inreg i16:$src, i8),  (EXT16 $src)>;
+def : Pat<(sext_inreg i32:$src, i16), (EXT32 $src)>;
+def : Pat<(sext_inreg i32:$src, i8),
+          (EXT32 (MOVXd32d16 (EXT16 (EXTRACT_SUBREG $src, MxSubRegIndex16Lo))))>;
+
+
+//===----------------------------------------------------------------------===//
+// DIV/MUL
+//===----------------------------------------------------------------------===//
+
+def MxSDiMuOpmode : MxBead3Bits<0b111>;
+def MxUDiMuOpmode : MxBead3Bits<0b011>;
+
+/// Word operation:
+/// ----------------------------------------------------
+///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
+/// ----------------------------------------------------
+///             |         |         | EFFECTIVE ADDRESS
+///  x  x  x  x |   REG   | OP MODE |   MODE  |   REG
+/// ----------------------------------------------------
+class MxDiMuEncoding<MxBead4Bits CMD, MxBead3Bits OPMODE, MxEncEA EA, MxEncExt EXT>
+    : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE, MxBeadReg<0>, CMD,
+                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
+
+let Defs = [CCR] in {
+let Constraints = "$src = $dst" in {
+// $reg <- $reg op $reg
+class MxDiMuOp_DD<string MN, bits<4> CMD, MxBead3Bits OPMODE,
+                  MxOperand DST, MxOperand OPD>
+    : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", [],
+             MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAd_2, MxExtEmpty>>;
+
+// $reg <- $reg op $imm
+class MxDiMuOp_DI<string MN, bits<4> CMD, MxBead3Bits OPMODE,
+                  MxOperand DST, MxOperand OPD>
+    : MxInst<(outs DST:$dst), (ins DST:$src, unknown:$opd), MN#"\t$opd, $dst", [],
+             MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAi, MxExtI16_2>>;
+} // let Constraints
+} // Defs = [CCR]
+
+multiclass MxDiMuOp<string MN, bits<4> CMD, bit isComm = 0> {
+
+  let isCommutable = isComm in {
+    def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
+                                        MxDRD16>;
+    def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
+                                        MxDRD16>;
+  }
+
+  def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, MxSDiMuOpmode, MxDRD32,
+                                      Mxi16imm>;
+  def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, MxUDiMuOpmode, MxDRD32,
+                                      Mxi16imm>;
+
+}
+
+defm DIV : MxDiMuOp<"div", 0x8>;
+
+// RR i8
+def : Pat<(sdiv i8:$dst, i8:$opd),
+          (EXTRACT_SUBREG
+            (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)),
+             MxSubRegIndex8Lo)>;
+
+def : Pat<(udiv i8:$dst, i8:$opd),
+          (EXTRACT_SUBREG
+            (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)),
+             MxSubRegIndex8Lo)>;
+
+def : Pat<(srem i8:$dst, i8:$opd),
+          (EXTRACT_SUBREG
+            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)), 8), 8),
+             MxSubRegIndex8Lo)>;
+
+def : Pat<(urem i8:$dst, i8:$opd),
+          (EXTRACT_SUBREG
+            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)), 8), 8),
+             MxSubRegIndex8Lo)>;
+
+// RR i16
+def : Pat<(sdiv i16:$dst, i16:$opd),
+          (EXTRACT_SUBREG
+            (SDIVd32d16 (MOVSXd32d16 $dst), $opd),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(udiv i16:$dst, i16:$opd),
+          (EXTRACT_SUBREG
+            (UDIVd32d16 (MOVZXd32d16 $dst), $opd),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(srem i16:$dst, i16:$opd),
+          (EXTRACT_SUBREG
+            (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d16 $dst), $opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(urem i16:$dst, i16:$opd),
+          (EXTRACT_SUBREG
+            (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d16 $dst), $opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+
+// RI i8
+def : Pat<(sdiv i8:$dst, MximmSExt8:$opd),
+          (EXTRACT_SUBREG
+            (SDIVd32i16 (MOVSXd32d8 $dst), imm:$opd),
+             MxSubRegIndex8Lo)>;
+
+def : Pat<(udiv i8:$dst, MximmSExt8:$opd),
+          (EXTRACT_SUBREG
+            (UDIVd32i16 (MOVZXd32d8 $dst), imm:$opd),
+             MxSubRegIndex8Lo)>;
+
+def : Pat<(srem i8:$dst, MximmSExt8:$opd),
+          (EXTRACT_SUBREG
+            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d8 $dst), imm:$opd), 8), 8),
+             MxSubRegIndex8Lo)>;
+
+def : Pat<(urem i8:$dst, MximmSExt8:$opd),
+          (EXTRACT_SUBREG
+            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d8 $dst), imm:$opd), 8), 8),
+             MxSubRegIndex8Lo)>;
+
+// RI i16
+def : Pat<(sdiv i16:$dst, MximmSExt16:$opd),
+          (EXTRACT_SUBREG
+            (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(udiv i16:$dst, MximmSExt16:$opd),
+          (EXTRACT_SUBREG
+            (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(srem i16:$dst, MximmSExt16:$opd),
+          (EXTRACT_SUBREG
+            (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(urem i16:$dst, MximmSExt16:$opd),
+          (EXTRACT_SUBREG
+            (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+
+defm MUL : MxDiMuOp<"mul", 0xC, 1>;
+
+// RR
+def : Pat<(mul i16:$dst, i16:$opd),
+          (EXTRACT_SUBREG
+            (SMULd32d16 (MOVXd32d16 $dst), $opd),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(mulhs i16:$dst, i16:$opd),
+          (EXTRACT_SUBREG
+            (ASR32di (ASR32di (SMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(mulhu i16:$dst, i16:$opd),
+          (EXTRACT_SUBREG
+            (LSR32di (LSR32di (UMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+
+// RI
+def : Pat<(mul i16:$dst, MximmSExt16:$opd),
+          (EXTRACT_SUBREG
+            (SMULd32i16 (MOVXd32d16 $dst), imm:$opd),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(mulhs i16:$dst, MximmSExt16:$opd),
+          (EXTRACT_SUBREG
+            (ASR32di (ASR32di (SMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+def : Pat<(mulhu i16:$dst, MximmSExt16:$opd),
+          (EXTRACT_SUBREG
+            (LSR32di (LSR32di (UMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8),
+             MxSubRegIndex16Lo)>;
+
+
+//===----------------------------------------------------------------------===//
+// NEG/NEGX
+//===----------------------------------------------------------------------===//
+
+/// ------------+------------+------+---------+---------
+///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
+/// ------------+------------+------+-------------------
+///             |            |      | EFFECTIVE ADDRESS
+///  0  1  0  0 | x  x  x  x | SIZE |   MODE  |   REG
+/// ------------+------------+------+---------+---------
+class MxNEGEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxEncEA EA, MxEncExt EXT>
+    : MxEncoding<EA.Reg, EA.DA, EA.Mode, SIZE, CMD, MxBead4Bits<0b0100>,
+                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
+
+let Defs = [CCR] in {
+let Constraints = "$src = $dst" in {
+
+class MxNeg_D<MxType TYPE>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
+             "neg."#TYPE.Prefix#"\t$dst",
+             [(set TYPE.VT:$dst, (ineg TYPE.VT:$src))],
+             MxNEGEncoding<MxBead4Bits<0x4>,
+                           !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                           MxEncEAd_0, MxExtEmpty>>;
+
+let Uses = [CCR] in {
+class MxNegX_D<MxType TYPE>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
+             "negx."#TYPE.Prefix#"\t$dst",
+             [(set TYPE.VT:$dst, (MxSubX 0, TYPE.VT:$src, CCR))],
+             MxNEGEncoding<MxBead4Bits<0x0>,
+                           !cast<MxEncSize>("MxEncSize"#TYPE.Size),
+                           MxEncEAd_0, MxExtEmpty>>;
+}
+
+} // let Constraints
+} // let Defs = [CCR]
+
+foreach S = [8, 16, 32] in {
+  def NEG#S#d  : MxNeg_D<!cast<MxType>("MxType"#S#"d")>;
+  def NEGX#S#d : MxNegX_D<!cast<MxType>("MxType"#S#"d")>;
+}
+
+def : Pat<(MxSub 0, i8 :$src), (NEG8d  MxDRD8 :$src)>;
+def : Pat<(MxSub 0, i16:$src), (NEG16d MxDRD16:$src)>;
+def : Pat<(MxSub 0, i32:$src), (NEG32d MxDRD32:$src)>;
+
+//===----------------------------------------------------------------------===//
+// no-CCR Patterns
+//===----------------------------------------------------------------------===//
+
+/// Basically the reason for this stuff is that add and addc share the same
+/// operand types constraints for whatever reasons and I had to define a common
+/// MxAdd and MxSub instructions that produce CCR and then pattern-map add and addc
+/// to it.
+/// NOTE On the other hand I see no reason why I cannot just drop explicit CCR
+/// result. Anyway works for now, hopefully I will better understand how this stuff
+/// is designed later
+foreach N = ["add", "addc"] in {
+
+  // add reg, reg
+  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),
+            (ADD8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
+  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),
+            (ADD16dd MxDRD16:$src, MxDRD16:$opd)>;
+  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),
+            (ADD32rr MxXRD32:$src, MxXRD32:$opd)>;
+
+  // add (An), reg
+  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),
+            (ADD8dj MxDRD8:$src, MxType8.JOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),
+            (ADD16dj MxDRD16:$src, MxType16.JOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),
+            (ADD32rj MxXRD32:$src, MxType32.JOp:$opd)>;
+
+  // add (i,An), reg
+  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),
+            (ADD8dp MxDRD8:$src, MxType8.POp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),
+            (ADD16dp MxDRD16:$src, MxType16.POp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),
+            (ADD32rp MxXRD32:$src, MxType32.POp:$opd)>;
+
+  // add (i,An,Xn), reg
+  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),
+            (ADD8df MxDRD8:$src, MxType8.FOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),
+            (ADD16df MxDRD16:$src, MxType16.FOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),
+            (ADD32rf MxXRD32:$src, MxType32.FOp:$opd)>;
+
+  // add reg, imm
+  def : Pat<(!cast<SDNode>(N) i8: $src, MximmSExt8:$opd),
+            (ADD8di  MxDRD8 :$src, imm:$opd)>;
+  def : Pat<(!cast<SDNode>(N) i16:$src, MximmSExt16:$opd),
+            (ADD16di MxDRD16:$src, imm:$opd)>;
+
+  // LEAp is more complex and thus will be selected over normal ADD32ri but it cannot
+  // be used with data registers, here by adding complexity to a simple ADD32ri insts
+  // we make sure it will be selected over LEAp
+  let AddedComplexity = 15 in {
+  def : Pat<(!cast<SDNode>(N) i32:$src, MximmSExt32:$opd),
+            (ADD32ri MxXRD32:$src, imm:$opd)>;
+  } // AddedComplexity = 15
+
+  // add imm, (An)
+  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
+                    MxType8.JPat:$dst),
+            (ADD8ji MxType8.JOp:$dst, imm:$opd)>;
+  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
+                    MxType16.JPat:$dst),
+            (ADD16ji MxType16.JOp:$dst, imm:$opd)>;
+  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
+                    MxType32.JPat:$dst),
+            (ADD32ji MxType32.JOp:$dst, imm:$opd)>;
+
+} // foreach add, addc
+
+def : Pat<(adde i8 :$src, i8 :$opd), (ADDX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
+def : Pat<(adde i16:$src, i16:$opd), (ADDX16dd MxDRD16:$src, MxDRD16:$opd)>;
+def : Pat<(adde i32:$src, i32:$opd), (ADDX32dd MxDRD32:$src, MxDRD32:$opd)>;
+
+
+
+foreach N = ["sub", "subc"] in {
+
+  // sub reg, reg
+  def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd),
+            (SUB8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
+  def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd),
+            (SUB16dd MxDRD16:$src, MxDRD16:$opd)>;
+  def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd),
+            (SUB32rr MxXRD32:$src, MxXRD32:$opd)>;
+
+
+  // sub (An), reg
+  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)),
+            (SUB8dj MxDRD8:$src, MxType8.JOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)),
+            (SUB16dj MxDRD16:$src, MxType16.JOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)),
+            (SUB32rj MxXRD32:$src, MxType32.JOp:$opd)>;
+
+  // sub (i,An), reg
+  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)),
+            (SUB8dp MxDRD8:$src, MxType8.POp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)),
+            (SUB16dp MxDRD16:$src, MxType16.POp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)),
+            (SUB32rp MxXRD32:$src, MxType32.POp:$opd)>;
+
+  // sub (i,An,Xn), reg
+  def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)),
+            (SUB8df MxDRD8:$src, MxType8.FOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)),
+            (SUB16df MxDRD16:$src, MxType16.FOp:$opd)>;
+  def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)),
+            (SUB32rf MxXRD32:$src, MxType32.FOp:$opd)>;
+
+  // sub reg, imm
+  def : Pat<(!cast<SDNode>(N) i8 :$src, MximmSExt8 :$opd),
+            (SUB8di  MxDRD8 :$src, imm:$opd)>;
+  def : Pat<(!cast<SDNode>(N) i16:$src, MximmSExt16:$opd),
+            (SUB16di MxDRD16:$src, imm:$opd)>;
+  def : Pat<(!cast<SDNode>(N) i32:$src, MximmSExt32:$opd),
+            (SUB32ri MxXRD32:$src, imm:$opd)>;
+
+  // sub imm, (An)
+  def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd),
+                   MxType8.JPat:$dst),
+            (SUB8ji MxType8.JOp:$dst, imm:$opd)>;
+  def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd),
+                   MxType16.JPat:$dst),
+            (SUB16ji MxType16.JOp:$dst, imm:$opd)>;
+  def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd),
+                   MxType32.JPat:$dst),
+            (SUB32ji MxType32.JOp:$dst, imm:$opd)>;
+
+} // foreach sub, subx
+
+def : Pat<(sube i8 :$src, i8 :$opd), (SUBX8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
+def : Pat<(sube i16:$src, i16:$opd), (SUBX16dd MxDRD16:$src, MxDRD16:$opd)>;
+def : Pat<(sube i32:$src, i32:$opd), (SUBX32dd MxDRD32:$src, MxDRD32:$opd)>;
+
+
+// and reg, reg
+def : Pat<(and i8 :$src, i8 :$opd), (AND8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
+def : Pat<(and i16:$src, i16:$opd), (AND16dd MxDRD16:$src, MxDRD16:$opd)>;
+def : Pat<(and i32:$src, i32:$opd), (AND32dd MxDRD32:$src, MxDRD32:$opd)>;
+
+// and reg, imm
+def : Pat<(and i8: $src, MximmSExt8 :$opd), (AND8di  MxDRD8 :$src, imm:$opd)>;
+def : Pat<(and i16:$src, MximmSExt16:$opd), (AND16di MxDRD16:$src, imm:$opd)>;
+def : Pat<(and i32:$src, MximmSExt32:$opd), (AND32di MxDRD32:$src, imm:$opd)>;
+
+
+// xor reg,reg
+def : Pat<(xor i8 :$src, i8 :$opd), (XOR8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
+def : Pat<(xor i16:$src, i16:$opd), (XOR16dd MxDRD16:$src, MxDRD16:$opd)>;
+def : Pat<(xor i32:$src, i32:$opd), (XOR32dd MxDRD32:$src, MxDRD32:$opd)>;
+
+// xor reg, imm
+def : Pat<(xor i8: $src, MximmSExt8 :$opd), (XOR8di  MxDRD8 :$src, imm:$opd)>;
+def : Pat<(xor i16:$src, MximmSExt16:$opd), (XOR16di MxDRD16:$src, imm:$opd)>;
+def : Pat<(xor i32:$src, MximmSExt32:$opd), (XOR32di MxDRD32:$src, imm:$opd)>;
+
+
+// or reg, reg
+def : Pat<(or i8 :$src, i8 :$opd), (OR8dd  MxDRD8 :$src, MxDRD8 :$opd)>;
+def : Pat<(or i16:$src, i16:$opd), (OR16dd MxDRD16:$src, MxDRD16:$opd)>;
+def : Pat<(or i32:$src, i32:$opd), (OR32dd MxDRD32:$src, MxDRD32:$opd)>;
+
+// or reg, imm
+def : Pat<(or i8: $src, MximmSExt8 :$opd), (OR8di  MxDRD8 :$src, imm:$opd)>;
+def : Pat<(or i16:$src, MximmSExt16:$opd), (OR16di MxDRD16:$src, imm:$opd)>;
+def : Pat<(or i32:$src, MximmSExt32:$opd), (OR32di MxDRD32:$src, imm:$opd)>;

diff  --git a/llvm/lib/Target/M68k/M68kInstrBits.td b/llvm/lib/Target/M68k/M68kInstrBits.td
new file mode 100644
index 000000000000..96d536520939
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrBits.td
@@ -0,0 +1,100 @@
+//===------- M68kInstrBits.td - Bit Manipulation Instrs --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the bit manipulation instructions in the M68k
+/// architecture. Here is the current status of the file:
+///
+///  Machine:
+///
+///    BCNG    [ ]   BCLR    [ ]   BSET     [ ]   BTST     [~]
+///
+///  Map:
+///
+///   [ ] - was not touched at all
+///   [!] - requires extarnal stuff implemented
+///   [~] - in progress but usable
+///   [x] - done
+///
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// BTST
+//===----------------------------------------------------------------------===//
+
+/// ------------+---------+---------+---------+---------
+///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
+/// ------------+---------+---------+---------+---------
+///  0  0  0  0 |   REG   | 1  0  0 |   MODE  |   REG
+/// ------------+---------+---------+---------+---------
+class MxBTSTEnc_R<MxBeadReg REG, MxEncEA EA, MxEncExt EXT>
+    : MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead3Bits<0b100>, REG, MxBead4Bits<0b0000>,
+                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
+
+/// -------------------------------+---------+---------
+///  F  E  D  C  B  A  9  8 . 7  6 | 5  4  3 | 2  1  0
+/// -------------------------------+---------+---------
+///  0  0  0  0  1  0  0  0 . 0  0 |   MODE  |   REG
+/// ------------------------+------+---------+---------
+///  0  0  0  0  0  0  0  0 |        BIT NUMBER
+/// ------------------------+--------------------------
+class MxBTSTEnc_I<MxBead8Imm IMM, MxEncEA EA, MxEncExt EXT>
+    : MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead2Bits<0b00>,
+                 MxBead4Bits<0b1000>, MxBead4Bits<0b0000>, IMM,
+                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
+
+let Defs = [CCR] in {
+class MxBTST_RR<MxType TYPE>
+    : MxInst<(outs), (ins TYPE.ROp:$dst, TYPE.ROp:$bitno), "btst\t$bitno, $dst",
+             [(set CCR, (MxBt TYPE.VT:$dst, TYPE.VT:$bitno))],
+             MxBTSTEnc_R<MxBeadReg<1>, MxEncEAd_0, MxExtEmpty>>;
+
+class MxBTST_RI<MxType TYPE>
+    : MxInst<(outs), (ins TYPE.ROp:$dst, TYPE.IOp:$bitno), "btst\t$bitno, $dst",
+             [(set CCR, (MxBt TYPE.VT:$dst, TYPE.IPat:$bitno))],
+             MxBTSTEnc_I<MxBead8Imm<1>, MxEncEAd_0, MxExtEmpty>>;
+
+class MxBTST_MR<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
+                MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.ROp:$bitno), "btst\t$bitno, $dst",
+             [(set CCR, (MxBt (TYPE.Load MEMPat:$dst), TYPE.VT:$bitno))],
+             MxBTSTEnc_R<MxBeadReg<1>, EA, EXT>>;
+
+class MxBTST_MI<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat,
+                MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins MEMOpd:$dst, TYPE.IOp:$bitno), "btst\t$bitno, $dst",
+             [(set CCR, (MxBt (TYPE.Load MEMPat:$dst), TYPE.IPat:$bitno))],
+             MxBTSTEnc_I<MxBead8Imm<1>, EA, EXT>>;
+} // Defs = [CCR]
+
+// Register BTST limited to 32 bits only
+def BTST32dd : MxBTST_RR<MxType32d>;
+def BTST32di : MxBTST_RI<MxType32d>;
+
+// Memory BTST limited to 8 bits only
+def BTST8jd : MxBTST_MR<MxType8d, MxType8.JOp, MxType8.JPat,
+                        MxEncEAj_0, MxExtEmpty>;
+def BTST8pd : MxBTST_MR<MxType8d, MxType8.POp, MxType8.PPat,
+                        MxEncEAp_0, MxExtI16_0>;
+def BTST8fd : MxBTST_MR<MxType8d, MxType8.FOp, MxType8.FPat,
+                        MxEncEAf_0, MxExtBrief_0>;
+def BTST8qd : MxBTST_MR<MxType8d, MxType8.QOp, MxType8.QPat,
+                        MxEncEAq,   MxExtI16_0>;
+def BTST8kd : MxBTST_MR<MxType8d, MxType8.KOp, MxType8.KPat,
+                        MxEncEAk,   MxExtBrief_0>;
+
+def BTST8ji : MxBTST_MI<MxType8d, MxType8.JOp, MxType8.JPat,
+                        MxEncEAj_0, MxExtEmpty>;
+def BTST8pi : MxBTST_MI<MxType8d, MxType8.POp, MxType8.PPat,
+                        MxEncEAp_0, MxExtI16_0>;
+def BTST8fi : MxBTST_MI<MxType8d, MxType8.FOp, MxType8.FPat,
+                        MxEncEAf_0, MxExtBrief_0>;
+def BTST8qi : MxBTST_MI<MxType8d, MxType8.QOp, MxType8.QPat,
+                        MxEncEAq,   MxExtI16_0>;
+def BTST8ki : MxBTST_MI<MxType8d, MxType8.KOp, MxType8.KPat,
+                        MxEncEAk,   MxExtBrief_0>;

diff  --git a/llvm/lib/Target/M68k/M68kInstrCompiler.td b/llvm/lib/Target/M68k/M68kInstrCompiler.td
new file mode 100644
index 000000000000..4d1d20745158
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrCompiler.td
@@ -0,0 +1,128 @@
+//===-- M68kInstrCompiler.td - Pseudos and Patterns ------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the various pseudo instructions used by the compiler,
+/// as well as Pat patterns used during instruction selection.
+///
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// ConstantPool, GlobalAddress, ExternalSymbol, and JumpTable
+//===----------------------------------------------------------------------===//
+
+def : Pat<(i32 (MxWrapper tconstpool    :$src)), (MOV32ri tconstpool    :$src)>;
+def : Pat<(i32 (MxWrapper tglobaladdr   :$src)), (MOV32ri tglobaladdr   :$src)>;
+def : Pat<(i32 (MxWrapper texternalsym  :$src)), (MOV32ri texternalsym  :$src)>;
+def : Pat<(i32 (MxWrapper tjumptable    :$src)), (MOV32ri tjumptable    :$src)>;
+def : Pat<(i32 (MxWrapper tblockaddress :$src)), (MOV32ri tblockaddress :$src)>;
+
+def : Pat<(add MxDRD32:$src, (MxWrapper tconstpool:$opd)),
+          (ADD32ri MxDRD32:$src, tconstpool:$opd)>;
+def : Pat<(add MxARD32:$src, (MxWrapper tjumptable:$opd)),
+          (ADD32ri MxARD32:$src, tjumptable:$opd)>;
+def : Pat<(add MxARD32:$src, (MxWrapper tglobaladdr :$opd)),
+          (ADD32ri MxARD32:$src, tglobaladdr:$opd)>;
+def : Pat<(add MxARD32:$src, (MxWrapper texternalsym:$opd)),
+          (ADD32ri MxARD32:$src, texternalsym:$opd)>;
+def : Pat<(add MxARD32:$src, (MxWrapper tblockaddress:$opd)),
+          (ADD32ri MxARD32:$src, tblockaddress:$opd)>;
+
+def : Pat<(store (i32 (MxWrapper tglobaladdr:$src)), iPTR:$dst),
+          (MOV32ji MxARI32:$dst, tglobaladdr:$src)>;
+def : Pat<(store (i32 (MxWrapper texternalsym:$src)), iPTR:$dst),
+          (MOV32ji MxARI32:$dst, texternalsym:$src)>;
+def : Pat<(store (i32 (MxWrapper tblockaddress:$src)), iPTR:$dst),
+          (MOV32ji MxARI32:$dst, tblockaddress:$src)>;
+
+def : Pat<(i32 (MxWrapperPC tconstpool    :$src)), (LEA32q tconstpool    :$src)>;
+def : Pat<(i32 (MxWrapperPC tglobaladdr   :$src)), (LEA32q tglobaladdr   :$src)>;
+def : Pat<(i32 (MxWrapperPC texternalsym  :$src)), (LEA32q texternalsym  :$src)>;
+def : Pat<(i32 (MxWrapperPC tjumptable    :$src)), (LEA32q tjumptable    :$src)>;
+def : Pat<(i32 (MxWrapperPC tblockaddress :$src)), (LEA32q tblockaddress :$src)>;
+
+
+//===----------------------------------------------------------------------===//
+// Conditional Move Pseudo Instructions
+//
+// CMOV* - Used to implement the SELECT DAG operation. Expanded after
+// instruction selection into a branch sequence.
+//===----------------------------------------------------------------------===//
+
+let usesCustomInserter = 1, Uses = [CCR] in
+class MxCMove<MxType TYPE>
+    : MxPseudo<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$t, TYPE.ROp:$f, i8imm:$cond),
+               "",
+               [(set TYPE.VT:$dst,
+                     (TYPE.VT (MxCmov TYPE.VT:$t, TYPE.VT:$f, imm:$cond, CCR)))]>;
+
+def CMOV8d  : MxCMove<MxType8d>;
+def CMOV16d : MxCMove<MxType16d>;
+def CMOV32r : MxCMove<MxType32r>;
+
+
+//===----------------------------------------------------------------------===//
+// Calls
+//===----------------------------------------------------------------------===//
+
+// ADJCALLSTACKDOWN/UP implicitly use/def %SP because they may be expanded into
+// a stack adjustment and the codegen must know that they may modify the stack
+// pointer before prolog-epilog rewriting occurs.
+// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
+// sub / add which can clobber CCR.
+let Defs = [SP, CCR], Uses = [SP] in {
+
+  def ADJCALLSTACKDOWN
+    : MxPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), "#ADJCALLSTACKDOWN",
+               [(MxCallSeqStart timm:$amt1, timm:$amt2)]>;
+
+  def ADJCALLSTACKUP
+    : MxPseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), "#ADJCALLSTACKUP",
+               [(MxCallSeqEnd timm:$amt1, timm:$amt2)]>;
+
+} // Defs
+
+//===----------------------------------------------------------------------===//
+// Tail Call
+//===----------------------------------------------------------------------===//
+
+// Tailcall stuff. The TCRETURN instructions execute after the epilog, so they
+// can never use callee-saved registers. That is the purpose of the XR32_TC
+// register classes.
+
+// FIXME TC is disabled for PIC mode because the global base
+// register which is part of the address mode may be assigned a
+// callee-saved register.
+def : Pat<(MxTCRet (load MxCP_ARII:$dst), imm:$adj),
+          (TCRETURNj (MOV32af_TC MxARII32:$dst), imm:$adj)>,
+      Requires<[IsNotPIC]>;
+
+def : Pat<(MxTCRet AR32_TC:$dst, imm:$adj),
+          (TCRETURNj MxARI32_TC:$dst, imm:$adj)>;
+
+def : Pat<(MxTCRet (i32 tglobaladdr:$dst), imm:$adj),
+          (TCRETURNq MxPCD32:$dst, imm:$adj)>;
+
+def : Pat<(MxTCRet (i32 texternalsym:$dst), imm:$adj),
+          (TCRETURNq MxPCD32:$dst, imm:$adj)>;
+
+
+//===----------------------------------------------------------------------===//
+// Segmented Stack
+//
+// When using segmented stacks these are lowered into instructions which first
+// check if the current stacklet has enough free memory. If it does, memory is
+// allocated by bumping the stack pointer. Otherwise memory is allocated from
+// the heap.
+//===----------------------------------------------------------------------===//
+
+let Defs = [SP, CCR], Uses = [SP] in
+let usesCustomInserter = 1 in
+def SALLOCA : MxPseudo<(outs MxARD32:$dst), (ins MxARD32:$size),
+                       "# variable sized alloca for segmented stacks",
+                       [(set iPTR:$dst, (MxSegAlloca iPTR:$size))]>;

diff  --git a/llvm/lib/Target/M68k/M68kInstrControl.td b/llvm/lib/Target/M68k/M68kInstrControl.td
new file mode 100644
index 000000000000..567e6b0427fb
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrControl.td
@@ -0,0 +1,317 @@
+//===-- M68kInstrControl.td - Control Flow Instructions --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the M68k jump, return, call, and related instructions.
+/// Here is the current status of the file:
+///
+///  Machine:
+///
+///       BRA   [x]     BSR  [ ]     Bcc [ ]     DBcc [ ]     FBcc [ ]
+///       FDBcc [ ]     FNOP [ ]     FPn [ ]     FScc [ ]     FTST [ ]
+///       JMP   [~]     JSR  [x]     NOP [x]     RTD  [!]     RTR  [ ]
+///       RTS   [x]     Scc  [x]     TST [ ]
+///
+///  Pseudo:
+///
+///          RET [x]
+///    TCRETURNj [x]   TCRETURNq [x]
+///     TAILJMPj [x]    TAILJMPq [x]
+///
+///  Map:
+///
+///   [ ] - was not touched at all
+///   [!] - requires extarnal stuff implemented
+///   [~] - in progress but usable
+///   [x] - done
+///
+///
+///                                   NOTE
+///      Though branch and jump instructions are using memory operands they
+///      DO NOT read the jump address from memory, they just calculate EA
+///      and jump there.
+///
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// NOP
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0 in {
+  def NOP : MxInst<(outs), (ins), "nop", [], MxEncFixed<0x4E71>>;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Conditions
+//===----------------------------------------------------------------------===//
+
+/// CC—Carry clear      GE—Greater than or equal
+/// LS—Lower or same    PL—Plus
+/// CS—Carry set        GT—Greater than
+/// LT—Less than        T—Always true*
+/// EQ—Equal            HI—Higher
+/// MI—Minus            VC—Overflow clear
+/// F—Never true*       LE—Less than or equal
+/// NE—Not equal        VS—Overflow set
+///
+/// *Not applicable to the Bcc instructions.
+def MxCCt  : MxBead4Bits<0b0000>;
+def MxCCf  : MxBead4Bits<0b0001>;
+def MxCChi : MxBead4Bits<0b0010>;
+def MxCCls : MxBead4Bits<0b0011>;
+def MxCCcc : MxBead4Bits<0b0100>;
+def MxCCcs : MxBead4Bits<0b0101>;
+def MxCCne : MxBead4Bits<0b0110>;
+def MxCCeq : MxBead4Bits<0b0111>;
+def MxCCvc : MxBead4Bits<0b1000>;
+def MxCCvs : MxBead4Bits<0b1001>;
+def MxCCpl : MxBead4Bits<0b1010>;
+def MxCCmi : MxBead4Bits<0b1011>;
+def MxCCge : MxBead4Bits<0b1100>;
+def MxCClt : MxBead4Bits<0b1101>;
+def MxCCgt : MxBead4Bits<0b1110>;
+def MxCCle : MxBead4Bits<0b1111>;
+
+/// --------------------------------+---------+---------
+///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
+/// --------------------------------+---------+---------
+///  0  1  0  1 | CONDITION  | 1  1 |   MODE  |   REG
+/// ----------------------------------------------------
+class MxSccEncoding<MxEncEA EA, MxEncExt EXT, MxBead4Bits CC>
+    : MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead2Bits<0b11>, CC, MxBead4Bits<0b0101>,
+                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
+
+let Uses = [CCR] in {
+class MxSccR<string CC>
+    : MxInst<(outs MxDRD8:$dst), (ins), "s"#CC#"\t$dst",
+             [(set i8:$dst, (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR))],
+             MxSccEncoding<MxEncEAd_0, MxExtEmpty,
+                           !cast<MxBead4Bits>("MxCC"#CC)>>;
+
+class MxSccM<string CC, MxOperand MEMOpd, ComplexPattern MEMPat,
+             MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins MEMOpd:$dst), "s"#CC#"\t$dst",
+             [(store (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR), MEMPat:$dst)],
+             MxSccEncoding<EA, EXT, !cast<MxBead4Bits>("MxCC"#CC)>>;
+}
+
+foreach cc = [ "cc", "ls", "lt", "eq", "mi", "f", "ne", "ge",
+               "cs", "pl", "gt", "t", "hi", "vc", "le", "vs"] in {
+def SET#"d8"#cc : MxSccR<cc>;
+def SET#"j8"#cc : MxSccM<cc, MxType8.JOp, MxType8.JPat, MxEncEAj_0, MxExtEmpty>;
+def SET#"p8"#cc : MxSccM<cc, MxType8.POp, MxType8.PPat, MxEncEAp_0, MxExtI16_0>;
+}
+
+//===----------------------------------------------------------------------===//
+// Jumps
+//===----------------------------------------------------------------------===//
+
+///------------------------------+---------+---------
+/// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
+///------------------------------+---------+---------
+/// 0  1  0  0  1  1  1  0  1  1 |  MODE   |   REG
+///------------------------------+---------+---------
+let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
+class MxJMP<MxOperand LOCOp, ComplexPattern LOCPat, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins LOCOp:$dst), "jmp\t$dst", [(brind iPTR:$dst)],
+             MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead2Bits<0b11>,
+                        MxBead4Bits<0b1110>, MxBead4Bits<0b0100>,
+                        EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
+
+def JMP32j : MxJMP<MxARI32, MxCP_ARI, MxEncEAj_0, MxExtEmpty>;
+
+
+// FIXME Support 16 bit indirect jump.
+// Currently M68k does not allow 16 bit indirect jumps use sext operands
+// def JMP16r     : MxInst<(outs), (ins M68k_ARI16:$dst),
+//                             "jmp\t$dst",
+//                             [(brind AR16:$dst)]>;
+
+//===----------------------------------------------------------------------===//
+// Branches
+//===----------------------------------------------------------------------===//
+
+/// --------------------------------------------------
+///  F  E  D  C | B  A  9  8 | 7  6  5  4  3  2  1  0
+/// --------------------------------------------------
+///  0  1  1  0 | CONDITION |   8-BIT DISPLACEMENT
+/// --------------------------------------------------
+///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00
+/// --------------------------------------------------
+///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF
+/// --------------------------------------------------
+let isBranch = 1, isTerminator = 1, Uses = [CCR] in
+class MxBcc<string cc, Operand TARGET, MxType TYPE, MxEncoding ENC = MxEncEmpty>
+    : MxInst<(outs), (ins TARGET:$dst), "b"#cc#"\t$dst", [], ENC>;
+
+foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
+               "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {
+  def B#cc#"8"
+    : MxBcc<cc, MxBrTarget8, MxType8,
+            MxEncoding<MxBead8Disp<0>,
+                       !cast<MxBead4Bits>("MxCC"#cc), MxBead4Bits<0x6>>>;
+  def B#cc#"16"
+    : MxBcc<cc, MxBrTarget16, MxType16,
+            MxEncoding<MxBead4Bits<0x0>,
+                       MxBead4Bits<0x0>, !cast<MxBead4Bits>("MxCC"#cc),
+                       MxBead4Bits<0x6>, MxBead16Imm<0>>>;
+}
+
+foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
+               "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {
+def : Pat<(MxBrCond bb:$target, !cast<PatLeaf>("MxCOND"#cc), CCR),
+          (!cast<Instruction>("B"#cc#"8") MxBrTarget8:$target)>;
+}
+
+/// -------------------------------------------------
+///  F  E  D  C  B  A  9  8 | 7  6  5  4  3  2  1  0
+/// -------------------------------------------------
+///  0  1  1  0  0  0  0  0 |   8-BIT DISPLACEMENT
+/// -------------------------------------------------
+///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00
+/// -------------------------------------------------
+///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF
+/// -------------------------------------------------
+let isBranch = 1, isTerminator = 1, isBarrier=1 in
+class MxBra<Operand TARGET, MxType TYPE, MxEncoding ENC = MxEncEmpty>
+    : MxInst<(outs), (ins TARGET:$dst), "bra\t$dst", [], ENC>;
+
+def BRA8  : MxBra<MxBrTarget8, MxType8,
+                  MxEncoding<MxBead8Disp<0>, MxBead4Bits<0x0>,
+                             MxBead4Bits<0x6>>>;
+def BRA16 : MxBra<MxBrTarget16, MxType16,
+                  MxEncoding<MxBead4Bits<0x0>, MxBead4Bits<0x0>,
+                             MxBead4Bits<0x0>, MxBead4Bits<0x6>,
+                             MxBead16Imm<0>>>;
+
+def : Pat<(br bb:$target), (BRA8 MxBrTarget8:$target)>;
+
+
+//===----------------------------------------------------------------------===//
+// Call
+//===----------------------------------------------------------------------===//
+
+// All calls clobber the non-callee saved registers. %SP is marked as
+// a use to prevent stack-pointer assignments that appear immediately
+// before calls from potentially appearing dead. Uses for argument
+// registers are added manually.
+let Uses = [SP] in
+let isCall = 1 in
+///------------------------------+---------+---------
+/// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
+///------------------------------+---------+---------
+/// 0  1  0  0  1  1  1  0  1  0 |  MODE   |   REG
+///------------------------------+---------+---------
+class MxCall<MxOperand LOCOp, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins LOCOp:$dst), "jsr\t$dst", [],
+             MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead2Bits<0b10>,
+                        MxBead4Bits<0b1110>, MxBead4Bits<0b0100>,
+                        EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
+
+def CALLk : MxCall<MxPCI32, MxEncEAk,   MxExtBrief_0>;
+def CALLq : MxCall<MxPCD32, MxEncEAq,   MxExtI16_0>;
+def CALLb : MxCall<MxAL32,  MxEncEAb,   MxExtI32_0>;
+def CALLj : MxCall<MxARI32, MxEncEAj_0, MxExtEmpty>;
+
+multiclass CallPat<MxCall callOp, Predicate pred> {
+  let Predicates = [pred] in {
+    def : Pat<(MxCall (i32 tglobaladdr:$dst)),  (callOp tglobaladdr:$dst)>;
+    def : Pat<(MxCall (i32 texternalsym:$dst)), (callOp texternalsym:$dst)>;
+    def : Pat<(MxCall (i32 imm:$dst)),          (callOp imm:$dst)>;
+  }
+}
+
+defm : CallPat<CALLq, IsPIC>;
+defm : CallPat<CALLb, IsNotPIC>;
+
+def : Pat<(MxCall iPTR:$dst), (CALLj MxARI32:$dst)>;
+
+//===----------------------------------------------------------------------===//
+// Tail Call
+//===----------------------------------------------------------------------===//
+
+let isCodeGenOnly = 1 in {
+let Uses = [SP] in {
+let isCall = 1, isTerminator = 1, isBarrier = 1 in {
+
+let isReturn = 1 in
+def TCRETURNq : MxPseudo<(outs), (ins MxPCD32:$dst,    i32imm:$adj)>;
+def TAILJMPq  : MxPseudo<(outs), (ins MxPCD32:$dst)>;
+
+// NOTE j does not mean load and jump M68k jmp just calculates EA and jumps
+// and it is using Mem form like (An) thus j letter.
+let isReturn = 1 in
+def TCRETURNj : MxPseudo<(outs), (ins MxARI32_TC:$dst, i32imm:$adj)>;
+def TAILJMPj  : MxPseudo<(outs), (ins MxARI32_TC:$dst)>;
+} // isCall = 1, isTerminator = 1, isBarrier = 1
+} // Uses = [SP]
+} // isCodeGenOnly = 1
+
+//===----------------------------------------------------------------------===//
+// Return
+//===----------------------------------------------------------------------===//
+
+// TODO Implement LINK/UNLK
+
+let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
+
+def RTS : MxInst<(outs), (ins), "rts", [], MxEncFixed<0x4E75>>;
+
+let isCodeGenOnly = 1 in
+def RET : MxPseudo<(outs), (ins i32imm:$adj, variable_ops), "",
+                   [(MxRet timm:$adj)]>;
+} // isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1
+
+//===----------------------------------------------------------------------===//
+// SETCC_C Patterns
+//===----------------------------------------------------------------------===//
+
+// Use subx to materialize carry bit.
+let Uses = [CCR], Defs = [CCR], isPseudo = 1 in {
+// FIXME These are pseudo ops that should be replaced with Pat<> patterns.
+// However, Pat<> can't replicate the destination reg into the inputs of the
+// result.
+def SETCS_C8d : MxPseudo<(outs MxDRD8:$dst), (ins), "",
+                         [(set MxDRD8:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
+def SETCS_C16d : MxPseudo<(outs MxDRD16:$dst), (ins), "",
+                          [(set MxDRD16:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
+def SETCS_C32d : MxPseudo<(outs MxXRD32:$dst), (ins), "",
+                          [(set MxXRD32:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
+} // Uses = [CCR], Defs = [CCR], isPseudo = 1
+
+
+def : Pat<(i16 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;
+def : Pat<(i32 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;
+
+def : Pat<(i16 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;
+def : Pat<(i32 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;
+
+// We canonicalize 'scs' to "(and (subx reg,reg), 1)" on the hope that the and
+// will be eliminated and that the subx can be extended up to a wider type.  When
+// this happens, it is great.  However, if we are left with an 8-bit subx and an
+// and, we might as well just match it as a setb.
+def : Pat<(and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), (SETd8cs)>;
+
+// (add OP, SETB) -> (addx OP, (move 0))
+def : Pat<(add (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), MxDRD8:$op),
+          (ADDX8dd MxDRD8:$op, (MOV8di 0))>;
+def : Pat<(add (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1), MxXRD32:$op),
+          (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;
+
+// (sub OP, SETB) -> (subx OP, (move 0))
+def : Pat<(sub MxDRD8:$op, (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1)),
+          (SUBX8dd MxDRD8:$op, (MOV8di 0))>;
+def : Pat<(sub MxXRD32:$op, (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1)),
+          (SUBX32dd MxDRD32:$op, (MOV32ri 0))>;
+
+// (sub OP, SETCC_CARRY) -> (addx OP, (move 0))
+def : Pat<(sub MxDRD8:$op, (i8 (MxSetCC_C MxCONDcs, CCR))),
+          (ADDX8dd MxDRD8:$op, (MOV8di 0))>;
+def : Pat<(sub MxXRD32:$op, (i32 (MxSetCC_C MxCONDcs, CCR))),
+          (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;

diff  --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
new file mode 100644
index 000000000000..74db3a3daca5
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -0,0 +1,712 @@
+//== M68kInstrData.td - M68k Data Movement Instructions -*- tablegen --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the Motorola 680x0 data movement instructions which are
+/// the basic means of transferring and storing addresses and data. Here is the
+/// current status of the file:
+///
+///  Machine:
+///
+///     EXG   [ ]     FMOVE [ ]     FSMOVE [ ]     FDMOVE [ ]     FMOVEM [ ]
+///     LEA   [~]     PEA   [ ]     MOVE   [~]     MOVE16 [ ]     MOVEA  [ ]
+///     MOVEM [ ]     MOVEP [ ]     MOVEQ  [ ]     LINK   [ ]     UNLK   [ ]
+///
+///  Pseudo:
+///
+///     MOVSX [x]     MOVZX [x]     MOVX   [x]
+///
+///  Map:
+///
+///   [ ] - was not touched at all
+///   [!] - requires extarnal stuff implemented
+///   [~] - in progress but usable
+///   [x] - done
+///
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// MOVE
+//===----------------------------------------------------------------------===//
+
+/// -----------------------------------------------------
+///  F  E | D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
+/// -----------------------------------------------------
+///       |      |    DESTINATION    |       SOURCE
+///  0  0 | SIZE |   REG   |   MODE  |   MODE  |   REG
+/// -----------------------------------------------------
+///
+/// NOTE Move requires EA X version for direct register destination(0)
+class MxMoveEncoding<MxBead2Bits size,
+                     MxEncEA srcEA, MxEncExt srcExt,
+                     MxEncEA dstEA, MxEncExt dstExt>
+    : MxEncoding<srcEA.Reg, srcEA.DA, srcEA.Mode, dstEA.DA, dstEA.Mode, dstEA.Reg,
+                 size, MxBead2Bits<0b00>,
+                 srcExt.Imm, srcExt.B8, srcExt.Scale, srcExt.WL, srcExt.DAReg,
+                 dstExt.Imm, dstExt.B8, dstExt.Scale, dstExt.WL, dstExt.DAReg>;
+
+/// MOVE has alternate size encoding
+class MxMoveSize<bits<2> value> : MxBead2Bits<value>;
+def MxMoveSize8  : MxMoveSize<0b01>;
+def MxMoveSize16 : MxMoveSize<0b11>;
+def MxMoveSize32 : MxMoveSize<0b10>;
+
+let Defs = [CCR] in
+class MxMove<string size, dag outs, dag ins, list<dag> pattern, MxEncoding enc>
+    : MxInst<outs, ins, "move."#size#"\t$src, $dst", pattern, enc>;
+
+class MxMove_RR<MxType DST, MxType SRC, MxMoveEncoding ENC>
+    : MxMove<DST.Prefix, (outs DST.ROp:$dst), (ins SRC.ROp:$src),
+             [(null_frag)], ENC>;
+
+let mayStore = 1 in {
+class MxMove_MR<MxOperand MEMOpd, ComplexPattern MEMPat, MxType REG,
+                MxMoveEncoding ENC>
+    : MxMove<REG.Prefix, (outs), (ins MEMOpd:$dst, REG.ROp:$src),
+             [(store REG.VT:$src, MEMPat:$dst)], ENC>;
+
+class MxMove_MI<MxOperand MEMOpd, ComplexPattern MEMPat, MxType TYPE,
+                MxMoveEncoding ENC>
+    : MxMove<TYPE.Prefix, (outs), (ins MEMOpd:$dst, TYPE.IOp:$src),
+             [(store TYPE.IPat:$src, MEMPat:$dst)], ENC>;
+} // let mayStore = 1
+
+class MxMove_RI<MxType DST, MxMoveEncoding ENC>
+    : MxMove<DST.Prefix, (outs DST.ROp:$dst), (ins DST.IOp:$src),
+              [(set DST.VT:$dst, DST.IPat:$src)], ENC>;
+
+
+let mayLoad = 1 in
+class MxMove_RM<MxType REG, MxOperand MEMOpd, ComplexPattern MEMPat,
+                MxBead2Bits SIZE,
+                MxEncEA SRCEA, MxEncExt SRCEXT,
+                MxEncEA DSTEA, MxEncExt DSTEXT>
+    : MxMove<REG.Prefix, (outs REG.ROp:$dst), (ins MEMOpd:$src),
+             [(set REG.VT:$dst, (REG.Load MEMPat:$src))],
+             MxMoveEncoding<SIZE, SRCEA, SRCEXT, DSTEA, DSTEXT>>;
+
+multiclass MMxMove_RM<MxType REG, MxMoveSize SIZE, MxEncEA EA_0> {
+
+  // REG <- (An)+
+  def NAME#REG.OOp.Letter#REG.Postfix : MxMove_RM<REG, REG.OOp, REG.OPat,
+      SIZE, MxEncEAo_1, MxExtEmpty, EA_0, MxExtEmpty>;
+
+  // REG <- -(An)
+  def NAME#REG.EOp.Letter#REG.Postfix : MxMove_RM<REG, REG.EOp, REG.EPat,
+      SIZE, MxEncEAe_1, MxExtEmpty, EA_0, MxExtEmpty>;
+
+  // REG <- (i,PC,Xn)
+  def NAME#REG.KOp.Letter#REG.Postfix : MxMove_RM<REG, REG.KOp, REG.KPat,
+      SIZE, MxEncEAk, MxExtBrief_1, EA_0, MxExtEmpty>;
+
+  // REG <- (i,PC)
+  def NAME#REG.QOp.Letter#REG.Postfix : MxMove_RM<REG, REG.QOp, REG.QPat,
+      SIZE, MxEncEAq, MxExtI16_1, EA_0, MxExtEmpty>;
+
+  // REG <- (i,An,Xn)
+  def NAME#REG.FOp.Letter#REG.Postfix : MxMove_RM<REG, REG.FOp, REG.FPat,
+      SIZE, MxEncEAf_1, MxExtBrief_1, EA_0, MxExtEmpty>;
+
+  // REG <- (i,An)
+  def NAME#REG.POp.Letter#REG.Postfix : MxMove_RM<REG, REG.POp, REG.PPat,
+      SIZE, MxEncEAp_1, MxExtI16_1, EA_0, MxExtEmpty>;
+
+  // REG <- (ABS)
+  def NAME#REG.BOp.Letter#REG.Postfix : MxMove_RM<REG, REG.BOp, REG.BPat,
+      SIZE, MxEncEAb, MxExtI32_1, EA_0, MxExtEmpty>;
+
+  // REG <- (An)
+  def NAME#REG.JOp.Letter#REG.Postfix : MxMove_RM<REG, REG.JOp, REG.JPat,
+      SIZE, MxEncEAj_1, MxExtEmpty, EA_0, MxExtEmpty>;
+}
+
+let mayLoad = 1, mayStore = 1 in {
+class MxMove_MM<string SIZE, PatFrag LOAD,
+                MxOperand DSTOpd, ComplexPattern DSTPat,
+                MxOperand SRCOpd, ComplexPattern SRCPat,
+                MxBead2Bits ESIZE,
+                MxEncEA SRCEA, MxEncExt SRCEXT,
+                MxEncEA DSTEA, MxEncExt DSTEXT>
+    : MxMove<SIZE, (outs), (ins DSTOpd:$dst, SRCOpd:$src),
+             [(store (LOAD SRCPat:$src), DSTPat:$dst)],
+             MxMoveEncoding<ESIZE, SRCEA, SRCEXT, DSTEA, DSTEXT>>;
+} // let mayLoad = 1, mayStore = 1
+
+multiclass MMxMove_MM<MxType TYPE, MxOperand DSTOpd, ComplexPattern DSTPat,
+                      MxMoveSize SIZE, MxEncEA EA_0, MxEncExt EXT_0> {
+
+  // MEM <- (An)+
+  def NAME#TYPE.OOp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.OOp, TYPE.OPat,
+                SIZE, MxEncEAo_1, MxExtEmpty, EA_0, EXT_0>;
+
+  // MEM <- -(An)
+  def NAME#TYPE.EOp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.EOp, TYPE.EPat,
+                SIZE, MxEncEAe_1, MxExtEmpty, EA_0, EXT_0>;
+
+  // MEM <- (i,An)
+  def NAME#TYPE.POp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.POp, TYPE.PPat,
+                SIZE, MxEncEAp_1, MxExtI16_1, EA_0, EXT_0>;
+
+  // MEM <- (i,An,Xn)
+  def NAME#TYPE.FOp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.FOp, TYPE.FPat,
+                SIZE, MxEncEAf_1, MxExtBrief_1, EA_0, EXT_0>;
+
+  // MEM <- (i,PC,Xn)
+  def NAME#TYPE.KOp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.KOp, TYPE.KPat,
+                SIZE, MxEncEAk, MxExtBrief_1, EA_0, EXT_0>;
+
+  // MEM <- (i,PC)
+  def NAME#TYPE.QOp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.QOp, TYPE.QPat,
+                SIZE, MxEncEAq, MxExtI16_1, EA_0, EXT_0>;
+
+  // MEM <- (ABS)
+  def NAME#TYPE.BOp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.BOp, TYPE.BPat,
+                SIZE, MxEncEAb, MxExtI32_1, EA_0, EXT_0>;
+
+  // MEM <- (An)
+  def NAME#TYPE.JOp.Letter#TYPE.Postfix
+    : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.JOp, TYPE.JPat,
+                SIZE, MxEncEAj_1, MxExtEmpty, EA_0, EXT_0>;
+}
+
+def MOV8dd
+  : MxMove_RR<MxType8d, MxType8d,
+    MxMoveEncoding<MxMoveSize8, MxEncEAd_1, MxExtEmpty, MxEncEAd_0, MxExtEmpty>>;
+
+// M <- R
+def MOV8fd : MxMove_MR<MxType8.FOp, MxType8.FPat, MxType8d,
+                       MxMoveEncoding<MxMoveSize8,
+                            /*src*/   MxEncEAd_1, MxExtEmpty,
+                            /*dst*/   MxEncEAf_0, MxExtBrief_0>>;
+
+def MOV8pd : MxMove_MR<MxType8.POp, MxType8.PPat, MxType8d,
+                       MxMoveEncoding<MxMoveSize8,
+                            /*src*/   MxEncEAd_1, MxExtEmpty,
+                            /*dst*/   MxEncEAp_0, MxExtI16_0>>;
+
+def MOV8ed : MxMove_MR<MxType8.EOp, MxType8.EPat, MxType8d,
+                       MxMoveEncoding<MxMoveSize8,
+                            /*src*/   MxEncEAd_1, MxExtEmpty,
+                            /*dst*/   MxEncEAe_0, MxExtEmpty>>;
+
+def MOV8od : MxMove_MR<MxType8.OOp, MxType8.OPat, MxType8d,
+                       MxMoveEncoding<MxMoveSize8,
+                            /*src*/   MxEncEAd_1, MxExtEmpty,
+                            /*dst*/   MxEncEAo_0, MxExtEmpty>>;
+
+def MOV8bd : MxMove_MR<MxType8.BOp, MxType8.BPat, MxType8d,
+                       MxMoveEncoding<MxMoveSize8,
+                            /*src*/   MxEncEAd_1, MxExtEmpty,
+                            /*dst*/   MxEncEAb,   MxExtI32_0>>;
+
+def MOV8jd : MxMove_MR<MxType8.JOp, MxType8.JPat, MxType8d,
+                       MxMoveEncoding<MxMoveSize8,
+                            /*src*/   MxEncEAd_1, MxExtEmpty,
+                            /*dst*/   MxEncEAj_0, MxExtEmpty>>;
+
+
+// R <- I
+def MOV8di : MxMove_RI<MxType8d,
+    MxMoveEncoding<MxMoveSize8, MxEncEAi, MxExtI8_1, MxEncEAd_0, MxExtEmpty>>;
+
+foreach S = [16, 32] in {
+  foreach D = [ "r", "a" ] in {
+
+    foreach O = [ "r", "a" ] in {
+      def MOV#S#D#O : MxMove_RR<
+        !cast<MxType>("MxType"#S#D),
+        !cast<MxType>("MxType"#S#O),
+        MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                       !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
+                       !cast<MxEncEA>("MxEncEA"#D#"_0_reflected"), MxExtEmpty>>;
+    }
+
+    // M <- R
+    def MOV#S#"f"#D : MxMove_MR<
+      !cast<MxType>("MxType"#S).FOp,
+      !cast<MxType>("MxType"#S).FPat,
+      !cast<MxType>("MxType"#S#D),
+      MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                     !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
+                     MxEncEAf_0, MxExtBrief_0>>;
+
+    def MOV#S#"p"#D : MxMove_MR<
+      !cast<MxType>("MxType"#S).POp,
+      !cast<MxType>("MxType"#S).PPat,
+      !cast<MxType>("MxType"#S#D),
+      MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                     !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
+                     MxEncEAp_0, MxExtI16_0>>;
+
+    def MOV#S#"e"#D : MxMove_MR<
+      !cast<MxType>("MxType"#S).EOp,
+      !cast<MxType>("MxType"#S).EPat,
+      !cast<MxType>("MxType"#S#D),
+      MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                     !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
+                     MxEncEAe_0, MxExtEmpty>>;
+
+    def MOV#S#"o"#D : MxMove_MR<
+      !cast<MxType>("MxType"#S).OOp,
+      !cast<MxType>("MxType"#S).OPat,
+      !cast<MxType>("MxType"#S#D),
+      MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                     !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
+                     MxEncEAo_0, MxExtEmpty>>;
+
+    def MOV#S#"b"#D : MxMove_MR<
+      !cast<MxType>("MxType"#S).BOp,
+      !cast<MxType>("MxType"#S).BPat,
+      !cast<MxType>("MxType"#S#D),
+      MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                     !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
+                     MxEncEAb, MxExtI32_0>>;
+
+    def MOV#S#"j"#D : MxMove_MR<
+      !cast<MxType>("MxType"#S).JOp,
+      !cast<MxType>("MxType"#S).JPat,
+      !cast<MxType>("MxType"#S#D),
+      MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                     !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty,
+                     MxEncEAj_0, MxExtEmpty>>;
+
+
+    // R <- I
+    def MOV#S#D#"i" : MxMove_RI<
+      !cast<MxType>("MxType"#S#D),
+      MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                     MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
+                     !cast<MxEncEA>("MxEncEA"#D#"_0_reflected"), MxExtEmpty>>;
+  }
+}
+
+// M <- I
+foreach S = [8, 16, 32] in {
+  def MOV#S#"f"#"i" : MxMove_MI<
+    !cast<MxType>("MxType"#S).FOp,
+    !cast<MxType>("MxType"#S).FPat,
+    !cast<MxType>("MxType"#S),
+    MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                   MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
+                   MxEncEAf_0, MxExtBrief_0>>;
+
+  def MOV#S#"p"#"i" : MxMove_MI<
+    !cast<MxType>("MxType"#S).POp,
+    !cast<MxType>("MxType"#S).PPat,
+    !cast<MxType>("MxType"#S),
+    MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                   MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
+                   MxEncEAp_0, MxExtI16_0>>;
+
+  def MOV#S#"b"#"i" : MxMove_MI<
+    !cast<MxType>("MxType"#S).BOp,
+    !cast<MxType>("MxType"#S).BPat,
+    !cast<MxType>("MxType"#S),
+    MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                   MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
+                   MxEncEAb, MxExtI32_0>>;
+
+  def MOV#S#"j"#"i" : MxMove_MI<
+    !cast<MxType>("MxType"#S).JOp,
+    !cast<MxType>("MxType"#S).JPat,
+    !cast<MxType>("MxType"#S),
+    MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S),
+                   MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"),
+                   MxEncEAj_0, MxExtEmpty>>;
+}
+
+// Store ABS(basically pointer) as Immdiate to Mem
+def : Pat<(store   MxType32.BPat :$src, MxType32.PPat :$dst),
+          (MOV32pi MxType32.POp  :$dst, MxType32.IOp  :$src)>;
+
+def : Pat<(store   MxType32.BPat :$src, MxType32.FPat :$dst),
+          (MOV32fi MxType32.FOp  :$dst, MxType32.IOp  :$src)>;
+
+def : Pat<(store   MxType32.BPat :$src, MxType32.BPat :$dst),
+          (MOV32bi MxType32.BOp  :$dst, MxType32.IOp  :$src)>;
+
+def : Pat<(store   MxType32.BPat :$src, MxType32.JPat :$dst),
+          (MOV32ji MxType32.JOp  :$dst, MxType32.IOp  :$src)>;
+
+// R <- M
+defm MOV8d  : MMxMove_RM<MxType8d, MxMoveSize8, MxEncEAd_0>;
+
+defm MOV16r : MMxMove_RM<MxType16r, MxMoveSize16, MxEncEAr_0_reflected>;
+defm MOV16a : MMxMove_RM<MxType16a, MxMoveSize16, MxEncEAa_0>;
+
+defm MOV32r : MMxMove_RM<MxType32r, MxMoveSize32, MxEncEAr_0_reflected>;
+defm MOV32a : MMxMove_RM<MxType32a, MxMoveSize32, MxEncEAa_0>;
+
+let Pattern = [(null_frag)] in {
+defm MOV16r : MMxMove_RM<MxType16r_TC, MxMoveSize16, MxEncEAr_0_reflected>;
+defm MOV16a : MMxMove_RM<MxType16a_TC, MxMoveSize16, MxEncEAa_0>;
+
+defm MOV32r : MMxMove_RM<MxType32r_TC, MxMoveSize32, MxEncEAr_0_reflected>;
+defm MOV32a : MMxMove_RM<MxType32a_TC, MxMoveSize32, MxEncEAa_0>;
+} // Pattern
+
+// M <- M
+defm MOV8p  : MMxMove_MM<MxType8,      MxType8.POp,  MxType8.PPat,
+                         MxMoveSize8,  MxEncEAp_0,   MxExtI16_0>;
+defm MOV16p : MMxMove_MM<MxType16,     MxType16.POp, MxType16.PPat,
+                         MxMoveSize16, MxEncEAp_0,   MxExtI16_0>;
+defm MOV32p : MMxMove_MM<MxType32,     MxType32.POp, MxType32.PPat,
+                         MxMoveSize32, MxEncEAp_0,   MxExtI16_0>;
+
+defm MOV8f  : MMxMove_MM<MxType8,      MxType8.FOp,  MxType8.FPat,
+                         MxMoveSize8,  MxEncEAf_0,   MxExtBrief_0>;
+defm MOV16f : MMxMove_MM<MxType16,     MxType16.FOp, MxType16.FPat,
+                         MxMoveSize16, MxEncEAf_0,   MxExtBrief_0>;
+defm MOV32f : MMxMove_MM<MxType32,     MxType32.FOp, MxType32.FPat,
+                         MxMoveSize32, MxEncEAf_0,   MxExtBrief_0>;
+
+defm MOV8b  : MMxMove_MM<MxType8,      MxType8.BOp,  MxType8.BPat,
+                         MxMoveSize8,  MxEncEAb,     MxExtI32_0>;
+defm MOV16b : MMxMove_MM<MxType16,     MxType16.BOp, MxType16.BPat,
+                         MxMoveSize16, MxEncEAb,     MxExtI32_0>;
+defm MOV32b : MMxMove_MM<MxType32,     MxType32.BOp, MxType32.BPat,
+                         MxMoveSize32, MxEncEAb,     MxExtI32_0>;
+
+defm MOV8e  : MMxMove_MM<MxType8,      MxType8.EOp,  MxType8.EPat,
+                         MxMoveSize8,  MxEncEAe_0,   MxExtEmpty>;
+defm MOV16e : MMxMove_MM<MxType16,     MxType16.EOp, MxType16.EPat,
+                         MxMoveSize16, MxEncEAe_0,   MxExtEmpty>;
+defm MOV32e : MMxMove_MM<MxType32,     MxType32.EOp, MxType32.EPat,
+                         MxMoveSize32, MxEncEAe_0,   MxExtEmpty>;
+
+defm MOV8o  : MMxMove_MM<MxType8,      MxType8.OOp,  MxType8.OPat,
+                         MxMoveSize8,  MxEncEAo_0,   MxExtEmpty>;
+defm MOV16o : MMxMove_MM<MxType16,     MxType16.OOp, MxType16.OPat,
+                         MxMoveSize16, MxEncEAo_0,   MxExtEmpty>;
+defm MOV32o : MMxMove_MM<MxType32,     MxType32.OOp, MxType32.OPat,
+                         MxMoveSize32, MxEncEAo_0,   MxExtEmpty>;
+
+defm MOV8j  : MMxMove_MM<MxType8,      MxType8.JOp,  MxType8.JPat,
+                         MxMoveSize8,  MxEncEAj_0,   MxExtEmpty>;
+defm MOV16j : MMxMove_MM<MxType16,     MxType16.JOp, MxType16.JPat,
+                         MxMoveSize16, MxEncEAj_0,   MxExtEmpty>;
+defm MOV32j : MMxMove_MM<MxType32,     MxType32.JOp, MxType32.JPat,
+                         MxMoveSize32, MxEncEAj_0,   MxExtEmpty>;
+
+//===----------------------------------------------------------------------===//
+// MOVEM
+//
+// The mask is already pre-processed by the save/restore spill hook
+//===----------------------------------------------------------------------===//
+
+// Direction
+def MxMOVEM_MR : MxBead1Bit<0>;
+def MxMOVEM_RM : MxBead1Bit<1>;
+
+// Size
+def MxMOVEM_W  : MxBead1Bit<0>;
+def MxMOVEM_L  : MxBead1Bit<1>;
+
+/// ---------------+-------------+-------------+---------
+///  F  E  D  C  B | A | 9  8  7 | 6 | 5  4  3 | 2  1  0
+/// ---------------+---+---------+---+---------+---------
+///  0  1  0  0  1 | D | 0  0  1 | S |   MODE  |   REG
+/// ---------------+---+---------+---+---------+---------
+///                  REGISTER LIST MASK
+/// -----------------------------------------------------
+/// D - direction(RM,MR)
+/// S - size(W,L)
+class MxMOVEMEncoding<MxEncEA EA, MxEncExt EXT, MxBead1Bit SIZE, MxBead1Bit DIR,
+                      MxBead16Imm IMM>
+    : MxEncoding<EA.Reg, EA.DA, EA.Mode, SIZE, MxBead3Bits<0b001>, DIR,
+                 MxBead1Bit<1>, MxBead4Bits<0b0100>, IMM,
+                 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
+
+let mayStore = 1 in
+class MxMOVEM_MR<MxType TYPE, MxBead1Bit SIZE,
+                 MxOperand MEMOp, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins MEMOp:$dst, MxMoveMask:$mask),
+             "movem."#TYPE.Prefix#"\t$mask, $dst", [],
+             MxMOVEMEncoding<EA, EXT, SIZE, MxMOVEM_MR, MxBead16Imm<1>>>;
+
+let mayLoad = 1 in
+class MxMOVEM_RM<MxType TYPE, MxBead1Bit SIZE,
+                 MxOperand MEMOp, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs), (ins MxMoveMask:$mask, MEMOp:$src),
+             "movem."#TYPE.Prefix#"\t$src, $mask", [],
+             MxMOVEMEncoding<EA, EXT, SIZE, MxMOVEM_RM, MxBead16Imm<0>>>;
+
+def MOVM32jm : MxMOVEM_MR<MxType32, MxMOVEM_L, MxType32.JOp, MxEncEAj_0, MxExtEmpty>;
+def MOVM32pm : MxMOVEM_MR<MxType32, MxMOVEM_L, MxType32.POp, MxEncEAp_0, MxExtI16_0>;
+
+def MOVM32mj : MxMOVEM_RM<MxType32, MxMOVEM_L, MxType32.JOp, MxEncEAj_1, MxExtEmpty>;
+def MOVM32mp : MxMOVEM_RM<MxType32, MxMOVEM_L, MxType32.POp, MxEncEAp_1, MxExtI16_1>;
+
+// Pseudo versions. These a required by virtual register spill/restore since
+// the mask requires real register to encode. These instruction will be expanded
+// into real MOVEM after RA finishes.
+let mayStore = 1 in
+class MxMOVEM_MR_Pseudo<MxType TYPE, MxOperand MEMOp>
+    : MxPseudo<(outs), (ins MEMOp:$dst, TYPE.ROp:$reg)>;
+let mayLoad = 1 in
+class MxMOVEM_RM_Pseudo<MxType TYPE, MxOperand MEMOp>
+    : MxPseudo<(outs TYPE.ROp:$dst), (ins MEMOp:$src)>;
+
+// Mem <- Reg
+def MOVM8jm_P  : MxMOVEM_MR_Pseudo<MxType8d,  MxType8.JOp>;
+def MOVM16jm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.JOp>;
+def MOVM32jm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.JOp>;
+
+def MOVM8pm_P  : MxMOVEM_MR_Pseudo<MxType8d,  MxType8.POp>;
+def MOVM16pm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.POp>;
+def MOVM32pm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.POp>;
+
+// Reg <- Mem
+def MOVM8mj_P  : MxMOVEM_RM_Pseudo<MxType8d,  MxType8.JOp>;
+def MOVM16mj_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.JOp>;
+def MOVM32mj_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.JOp>;
+
+def MOVM8mp_P  : MxMOVEM_RM_Pseudo<MxType8d,  MxType8.POp>;
+def MOVM16mp_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.POp>;
+def MOVM32mp_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.POp>;
+
+
+//===----------------------------------------------------------------------===//
+// MOVE to/from SR/CCR
+//
+// A special care must be taken working with to/from CCR since it is basically
+// word-size SR register truncated for user mode thus it only supports word-size
+// instructions. Plus the original M68000 does not support moves from CCR. So in
+// order to use CCR effectively one MUST use proper byte-size pseudo instructi-
+// ons that will be resolved sometime after RA pass.
+//===----------------------------------------------------------------------===//
+
+/// --------------------------------------------------
+///  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
+class MxMoveToCCR<dag INS, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs CCRC:$dst), INS, "move.w\t$src, $dst", [],
+             MxEncoding<EA.Reg, EA.DA, EA.Mode,
+                        MxBead4Bits<0b0011>, MxBead4Bits<0b0001>, MxBead2Bits<0b01>,
+                        EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
+
+class MxMoveToCCRPseudo<dag INS> : MxPseudo<(outs CCRC:$dst), INS>;
+
+let mayLoad = 1 in {
+def MOV16cp : MxMoveToCCR<(ins MxType16d.POp:$src), MxEncEAp_1, MxExtI16_1>;
+def  MOV8cp : MxMoveToCCRPseudo<(ins MxType8d.POp:$src)>;
+} // let mayLoad = 1
+
+def MOV16cd : MxMoveToCCR<(ins MxType16d.ROp:$src), MxEncEAd_1, MxExtEmpty>;
+def  MOV8cd : MxMoveToCCRPseudo<(ins MxType8d.ROp:$src)>;
+
+/// Move from CCR
+/// --------------------------------------------------
+///  F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
+/// --------------------------------------------------
+///                               | EFFECTIVE ADDRESS
+///  0  1  0  0  0  0  1  0  1  1 |   MODE  |   REG
+/// --------------------------------------------------
+let Uses = [CCR] in
+class MxMoveFromCCR<dag OUTS, dag INS, MxEncEA EA, MxEncExt EXT>
+    : MxInst<OUTS, INS, "move.w\t$src, $dst", [],
+             MxEncoding<EA.Reg, EA.DA, EA.Mode,
+                        MxBead4Bits<0b1011>, MxBead4Bits<0b0000>, MxBead2Bits<0b01>,
+                        EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>,
+      Requires<[ IsM68010 ]>;
+
+class MxMoveFromCCRPseudo<dag INS> : MxPseudo<(outs), INS>;
+
+let mayStore = 1 in {
+def MOV16pc
+  : MxMoveFromCCR<(outs), (ins MxType16d.POp:$dst, CCRC:$src), MxEncEAp_0, MxExtI16_0>;
+def MOV8pc : MxMoveFromCCRPseudo<(ins MxType8d.POp:$dst, CCRC:$src)>;
+} // let mayStore = 1
+
+def MOV16dc
+  : MxMoveFromCCR<(outs MxType16d.ROp:$dst), (ins CCRC:$src), MxEncEAd_0, MxExtEmpty>;
+
+def MOV8dc : MxMoveFromCCRPseudo<(ins MxType8d.ROp:$dst, CCRC:$src)>;
+
+
+//===----------------------------------------------------------------------===//
+// LEA
+//===----------------------------------------------------------------------===//
+
+/// ----------------------------------------------------
+///  F  E  D  C | B  A  9 | 8  7  6 | 5  4  3 | 2  1  0
+/// ----------------------------------------------------
+///  0  1  0  0 | DST REG | 1  1  1 |   MODE  |   REG
+/// ----------------------------------------------------
+class MxLEA<MxOperand SRCOpd, ComplexPattern SRCPat, MxEncEA EA, MxEncExt EXT>
+    : MxInst<(outs MxARD32:$dst), (ins SRCOpd:$src),
+             "lea\t$src, $dst", [(set i32:$dst, SRCPat:$src)],
+             MxEncoding<EA.Reg, EA.DA, EA.Mode,
+                        MxBead3Bits<0b111>, MxBeadReg<0>, MxBead4Bits<0x4>,
+                        EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
+
+def LEA32p : MxLEA<MxARID32, MxCP_ARID, MxEncEAp_1, MxExtI16_1>;
+def LEA32f : MxLEA<MxARII32, MxCP_ARII, MxEncEAf_1, MxExtBrief_1>;
+def LEA32q : MxLEA<MxPCD32,  MxCP_PCD,  MxEncEAq,   MxExtI16_1>;
+def LEA32b : MxLEA<MxAL32,   MxCP_AL,   MxEncEAb,   MxExtI32_1>;
+
+
+//===----------------------------------------------------------------------===//
+// Pseudos
+//===----------------------------------------------------------------------===//
+
+/// Pushe/Pop to/from SP for simplicity
+let Uses = [SP], Defs = [SP], hasSideEffects = 0 in {
+
+// SP <- SP - <size>; (SP) <- Dn
+let mayStore = 1 in {
+def PUSH8d  : MxPseudo<(outs), (ins DR8:$reg)>;
+def PUSH16d : MxPseudo<(outs), (ins DR16:$reg)>;
+def PUSH32r : MxPseudo<(outs), (ins XR32:$reg)>;
+} // let mayStore = 1
+
+// Dn <- (SP); SP <- SP + <size>
+let mayLoad = 1 in {
+def POP8d  : MxPseudo<(outs DR8:$reg),  (ins)>;
+def POP16d : MxPseudo<(outs DR16:$reg), (ins)>;
+def POP32r : MxPseudo<(outs XR32:$reg), (ins)>;
+} // let mayLoad = 1
+
+} // let Uses/Defs = [SP], hasSideEffects = 0
+
+
+let Defs = [CCR] in {
+class MxPseudoMove_RR<MxType DST, MxType SRC, list<dag> PAT = []>
+    : MxPseudo<(outs DST.ROp:$dst), (ins SRC.ROp:$src), "", PAT>;
+
+class MxPseudoMove_RM<MxType DST, MxOperand SRCOpd, list<dag> PAT = []>
+    : MxPseudo<(outs DST.ROp:$dst), (ins SRCOpd:$src), "", PAT>;
+}
+
+/// This group of Pseudos is analogues to the real x86 extending moves, but
+/// since M68k does not have those we need to emulate. These instructions
+/// will be expanded right after RA completed because we need to know precisely
+/// what registers are allocated for the operands and if they overlap we just
+/// extend the value if the registers are completely 
diff erent we need to move
+/// first.
+foreach EXT = ["S", "Z"] in {
+  let hasSideEffects = 0 in {
+
+    def MOV#EXT#Xd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
+    def MOV#EXT#Xd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
+    def MOV#EXT#Xd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>;
+
+    let mayLoad = 1 in {
+
+      def MOV#EXT#Xd16j8   : MxPseudoMove_RM<MxType16d,  MxType8.JOp>;
+      def MOV#EXT#Xd32j8   : MxPseudoMove_RM<MxType32d,  MxType8.JOp>;
+      def MOV#EXT#Xd32j16  : MxPseudoMove_RM<MxType32d, MxType16.JOp>;
+
+      def MOV#EXT#Xd16p8   : MxPseudoMove_RM<MxType16d,  MxType8.POp>;
+      def MOV#EXT#Xd32p8   : MxPseudoMove_RM<MxType32d,  MxType8.POp>;
+      def MOV#EXT#Xd32p16  : MxPseudoMove_RM<MxType32d, MxType16.POp>;
+
+      def MOV#EXT#Xd16f8   : MxPseudoMove_RM<MxType16d,  MxType8.FOp>;
+      def MOV#EXT#Xd32f8   : MxPseudoMove_RM<MxType32d,  MxType8.FOp>;
+      def MOV#EXT#Xd32f16  : MxPseudoMove_RM<MxType32d, MxType16.FOp>;
+
+    }
+  }
+}
+
+/// This group of instructions is similar to the group above but DOES NOT do
+/// any value extension, they just load a smaller register into the lower part
+/// of another register if operands' real registers are 
diff erent or does
+/// nothing if they are the same.
+def MOVXd16d8  : MxPseudoMove_RR<MxType16d,  MxType8d>;
+def MOVXd32d8  : MxPseudoMove_RR<MxType32d,  MxType8d>;
+def MOVXd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>;
+
+//===----------------------------------------------------------------------===//
+// Extend/Truncate Patterns
+//===----------------------------------------------------------------------===//
+
+// i16 <- sext i8
+def: Pat<(i16 (sext i8:$src)),
+          (EXTRACT_SUBREG (MOVSXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxSExtLoadi16i8 MxCP_ARI:$src),
+          (EXTRACT_SUBREG (MOVSXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxSExtLoadi16i8 MxCP_ARID:$src),
+          (EXTRACT_SUBREG (MOVSXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxSExtLoadi16i8 MxCP_ARII:$src),
+          (EXTRACT_SUBREG (MOVSXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
+
+// i32 <- sext i8
+def: Pat<(i32 (sext i8:$src)), (MOVSXd32d8 MxDRD8:$src)>;
+def: Pat<(MxSExtLoadi32i8 MxCP_ARI :$src), (MOVSXd32j8 MxARI8 :$src)>;
+def: Pat<(MxSExtLoadi32i8 MxCP_ARID:$src), (MOVSXd32p8 MxARID8:$src)>;
+def: Pat<(MxSExtLoadi32i8 MxCP_ARII:$src), (MOVSXd32f8 MxARII8:$src)>;
+
+// i32 <- sext i16
+def: Pat<(i32 (sext i16:$src)), (MOVSXd32d16 MxDRD16:$src)>;
+def: Pat<(MxSExtLoadi32i16 MxCP_ARI :$src), (MOVSXd32j16 MxARI16 :$src)>;
+def: Pat<(MxSExtLoadi32i16 MxCP_ARID:$src), (MOVSXd32p16 MxARID16:$src)>;
+def: Pat<(MxSExtLoadi32i16 MxCP_ARII:$src), (MOVSXd32f16 MxARII16:$src)>;
+
+// i16 <- zext i8
+def: Pat<(i16 (zext i8:$src)),
+          (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxZExtLoadi16i8 MxCP_ARI:$src),
+          (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxZExtLoadi16i8 MxCP_ARID:$src),
+          (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxZExtLoadi16i8 MxCP_ARII:$src),
+          (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
+
+// i32 <- zext i8
+def: Pat<(i32 (zext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>;
+def: Pat<(MxZExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>;
+def: Pat<(MxZExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>;
+def: Pat<(MxZExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>;
+
+// i32 <- zext i16
+def: Pat<(i32 (zext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>;
+def: Pat<(MxZExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>;
+def: Pat<(MxZExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>;
+def: Pat<(MxZExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>;
+
+// i16 <- anyext i8
+def: Pat<(i16 (anyext i8:$src)),
+          (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxExtLoadi16i8 MxCP_ARI:$src),
+          (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxExtLoadi16i8 MxCP_ARID:$src),
+          (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>;
+def: Pat<(MxExtLoadi16i8 MxCP_ARII:$src),
+          (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>;
+
+// i32 <- anyext i8
+def: Pat<(i32 (anyext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>;
+def: Pat<(MxExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>;
+def: Pat<(MxExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>;
+def: Pat<(MxExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>;
+
+// i32 <- anyext i16
+def: Pat<(i32 (anyext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>;
+def: Pat<(MxExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>;
+def: Pat<(MxExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>;
+def: Pat<(MxExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>;
+
+// trunc patterns
+def : Pat<(i16 (trunc i32:$src)),
+          (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex16Lo)>;
+def : Pat<(i8  (trunc i32:$src)),
+          (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex8Lo)>;
+def : Pat<(i8  (trunc i16:$src)),
+          (EXTRACT_SUBREG MxXRD16:$src, MxSubRegIndex8Lo)>;

diff  --git a/llvm/lib/Target/M68k/M68kInstrFormats.td b/llvm/lib/Target/M68k/M68kInstrFormats.td
new file mode 100644
index 000000000000..b00db4915df2
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrFormats.td
@@ -0,0 +1,370 @@
+//=== M68kInstrFormats.td - M68k Instruction Formats ---*- tablegen -*-===//
+//                     The LLVM Compiler Infrastructure
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains M68k instruction formats.
+///
+/// Since M68k has quite a lot memory addressing modes there are more
+/// instruction prefixes than just i, r and m:
+/// TSF  Since     Form                     Letter  Description
+///  00   M68000    Dn or An                 r       any register
+///  01   M68000    Dn                       d       data register direct
+///  02   M68000    An                       a       address register direct
+///  03   M68000    (An)                     j       address register indirect
+///  04   M68000    (An)+                    o       address register indirect with postincrement
+///  05   M68000    -(An)                    e       address register indirect with predecrement
+///  06   M68000    (i,An)                   p       address register indirect with displacement
+///  10   M68000    (i,An,Xn.L)              f       address register indirect with index and scale = 1
+///  07   M68000    (i,An,Xn.W)              F       address register indirect with index and scale = 1
+///  12   M68020    (i,An,Xn.L,SCALE)        g       address register indirect with index
+///  11   M68020    (i,An,Xn.W,SCALE)        G       address register indirect with index
+///  14   M68020    ([bd,An],Xn.L,SCALE,od)  u       memory indirect postindexed mode
+///  13   M68020    ([bd,An],Xn.W,SCALE,od)  U       memory indirect postindexed mode
+///  16   M68020    ([bd,An,Xn.L,SCALE],od)  v       memory indirect preindexed mode
+///  15   M68020    ([bd,An,Xn.W,SCALE],od)  V       memory indirect preindexed mode
+///  20   M68000    abs.L                    b       absolute long address
+///  17   M68000    abs.W                    B       absolute short address
+///  21   M68000    (i,PC)                   q       program counter with displacement
+///  23   M68000    (i,PC,Xn.L)              k       program counter with index and scale = 1
+///  22   M68000    (i,PC,Xn.W)              K       program counter with index and scale = 1
+///  25   M68020    (i,PC,Xn.L,SCALE)        l       program counter with index
+///  24   M68020    (i,PC,Xn.W,SCALE)        L       program counter with index
+///  27   M68020    ([bd,PC],Xn.L,SCALE,od)  x       program counter memory indirect postindexed mode
+///  26   M68020    ([bd,PC],Xn.W,SCALE,od)  X       program counter memory indirect postindexed mode
+///  31   M68020    ([bd,PC,Xn.L,SCALE],od)  y       program counter memory indirect preindexed mode
+///  30   M68020    ([bd,PC,Xn.W,SCALE],od)  Y       program counter memory indirect preindexed mode
+///  32   M68000    #immediate               i       immediate data
+///
+/// NOTE that long form is always lowercase, word variants are capitalized
+///
+/// Operand can be qualified with size where appropriate to force a particular
+/// instruction encoding, e.g.:
+///    (i8,An,Xn.W)             f8      1 extension word
+///    (i16,An,Xn.W)            f16     2 extension words
+///    (i32,An,Xn.W)            f32     3 extension words
+///
+/// Form without size qualifier will adapt to operand size automatically, e.g.:
+///    (i,An,Xn.W)              f       1, 2 or 3 extension words
+///
+/// Some forms already imply a particular size of their operands, e.g.:
+///    (i,An)                   p       1 extension word and i is 16bit
+///
+/// Operand order follows x86 Intel order(destination before source), e.g.:
+///    MOV8df                   MOVE (4,A0,D0), D1
+///
+/// Number after instruction mnemonics determines the size of the data
+///
+//===----------------------------------------------------------------------===//
+
+/// ??? Is it possible to use this stuff for disassembling?
+/// NOTE 1: In case of conditional beads(DA, DAReg), cond part is able to
+/// consume any bit, though a more general instructions must be chosen, e.g.
+/// d -> r, a -> r
+
+//===----------------------------------------------------------------------===//
+// Encoding primitives
+//===----------------------------------------------------------------------===//
+
+class MxBead<bits<4> type, bit b4 = 0, bit b5 = 0, bit b6 = 0, bit b7 = 0> {
+  bits<8> Value = 0b00000000;
+  let Value{3-0} = type;
+  let Value{4} = b4;
+  let Value{5} = b5;
+  let Value{6} = b6;
+  let Value{7} = b7;
+}
+
+/// System beads, allow to control beading flow
+def   MxBeadTerm   : MxBead<0x0, 0, 0, 0, 0>;
+def   MxBeadIgnore : MxBead<0x0, 1, 0, 0, 0>;
+
+/// Add plain bit to the instruction
+class MxBead1Bit  <bits<1> b> : MxBead<0x1, b>;
+class MxBead2Bits <bits<2> b> : MxBead<0x2, b{0}, b{1}>;
+class MxBead3Bits <bits<3> b> : MxBead<0x3, b{0}, b{1}, b{2}>;
+class MxBead4Bits <bits<4> b> : MxBead<0x4, b{0}, b{1}, b{2}, b{3}>;
+
+/// bits<3> o - operand number
+/// bit a     - use alternative, used to select index register or
+///             outer displacement/immediate
+/// suffix NP means non-padded
+class MxBeadDAReg  <bits<3> o, bit a = 0> : MxBead<0x5, o{0}, o{1}, o{2}, a>;
+class MxBeadDA     <bits<3> o, bit a = 0> : MxBead<0x6, o{0}, o{1}, o{2}, a>;
+class MxBeadReg    <bits<3> o, bit a = 0> : MxBead<0x7, o{0}, o{1}, o{2}, a>;
+class MxBead8Disp  <bits<3> o, bit a = 0> : MxBead<0x8, o{0}, o{1}, o{2}, a>;
+
+/// Add Immediate to the instruction. 8-bit version is padded with zeros to fit
+/// the word.
+class MxBead8Imm   <bits<3> o, bit a = 0> : MxBead<0x9, o{0}, o{1}, o{2}, a>;
+class MxBead16Imm  <bits<3> o, bit a = 0> : MxBead<0xA, o{0}, o{1}, o{2}, a>;
+class MxBead32Imm  <bits<3> o, bit a = 0> : MxBead<0xB, o{0}, o{1}, o{2}, a>;
+
+/// Encodes an immediate 0-7(alt. 1-8) into 3 bit field
+class MxBead3Imm   <bits<3> o, bit a = 0> : MxBead<0xC, o{0}, o{1}, o{2}, a>;
+
+
+class MxEncoding<MxBead n0  = MxBeadTerm, MxBead n1  = MxBeadTerm,
+                 MxBead n2  = MxBeadTerm, MxBead n3  = MxBeadTerm,
+                 MxBead n4  = MxBeadTerm, MxBead n5  = MxBeadTerm,
+                 MxBead n6  = MxBeadTerm, MxBead n7  = MxBeadTerm,
+                 MxBead n8  = MxBeadTerm, MxBead n9  = MxBeadTerm,
+                 MxBead n10 = MxBeadTerm, MxBead n11 = MxBeadTerm,
+                 MxBead n12 = MxBeadTerm, MxBead n13 = MxBeadTerm,
+                 MxBead n14 = MxBeadTerm, MxBead n15 = MxBeadTerm,
+                 MxBead n16 = MxBeadTerm, MxBead n17 = MxBeadTerm,
+                 MxBead n18 = MxBeadTerm, MxBead n19 = MxBeadTerm,
+                 MxBead n20 = MxBeadTerm, MxBead n21 = MxBeadTerm,
+                 MxBead n22 = MxBeadTerm, MxBead n23 = MxBeadTerm> {
+  bits <192> Value;
+  let Value{7-0}     = n0.Value;
+  let Value{15-8}    = n1.Value;
+  let Value{23-16}   = n2.Value;
+  let Value{31-24}   = n3.Value;
+  let Value{39-32}   = n4.Value;
+  let Value{47-40}   = n5.Value;
+  let Value{55-48}   = n6.Value;
+  let Value{63-56}   = n7.Value;
+  let Value{71-64}   = n8.Value;
+  let Value{79-72}   = n9.Value;
+  let Value{87-80}   = n10.Value;
+  let Value{95-88}   = n11.Value;
+  let Value{103-96}  = n12.Value;
+  let Value{111-104} = n13.Value;
+  let Value{119-112} = n14.Value;
+  let Value{127-120} = n15.Value;
+  let Value{135-128} = n16.Value;
+  let Value{143-136} = n17.Value;
+  let Value{151-144} = n18.Value;
+  let Value{159-152} = n19.Value;
+  let Value{167-160} = n20.Value;
+  let Value{175-168} = n21.Value;
+  let Value{183-176} = n22.Value;
+  let Value{191-184} = n23.Value;
+}
+
+class MxEncFixed<bits<16> value> : MxEncoding {
+  let Value{7-0}   = MxBead4Bits<value{3-0}>.Value;
+  let Value{15-8}  = MxBead4Bits<value{7-4}>.Value;
+  let Value{23-16} = MxBead4Bits<value{11-8}>.Value;
+  let Value{31-24} = MxBead4Bits<value{15-12}>.Value;
+}
+
+//===----------------------------------------------------------------------===//
+// Encoding composites
+//
+// These must be lowered to MxEncoding by instr specific wrappers
+//
+// HERE BE DRAGONS...
+//===----------------------------------------------------------------------===//
+
+class MxEncByte<bits<8> value> : MxEncoding {
+  MxBead4Bits LO = MxBead4Bits<value{3-0}>;
+  MxBead4Bits HI = MxBead4Bits<value{7-4}>;
+}
+
+def MxEncEmpty : MxEncoding;
+
+
+/// M68k Standard Effective Address layout:
+///
+/// :-------------------:
+/// | 5  4  3 | 2  1  0 |
+/// |   mode  |   reg   |
+/// :-------------------:
+///
+/// If the EA is a direct register mode, bits 4 and 5 are 0, and the register
+/// number will be encoded in bit 0 - 3. Since the first address register's
+/// (A0) register number is 8, we can easily tell data registers from
+/// address registers by only inspecting bit 3 (i.e. if bit 3 is set, it's an
+/// address register).
+///
+///
+/// But MOVE instruction uses reversed layout for destination EA:
+///
+/// :-------------------:
+/// | 5  4  3 | 2  1  0 |
+/// |   reg   |  mode   |
+/// :-------------------:
+///
+/// And this complicates things a bit because the DA bit is now separated from
+/// the register and we have to encode those separately using MxBeadDA<opN>
+///
+class MxEncEA<MxBead reg, MxBead mode, MxBead da = MxBeadIgnore> {
+  MxBead Reg = reg;
+  MxBead Mode = mode;
+  MxBead DA = da;
+}
+
+// FIXME: Is there a way to factorize the addressing mode suffix (i.e.
+// 'r', 'd', 'a' etc.) and use something like multiclass to replace?
+def MxEncEAr_0: MxEncEA<MxBeadDAReg<0>, MxBead2Bits<0b00>>;
+def MxEncEAd_0: MxEncEA<MxBeadReg<0>, MxBead2Bits<0b00>, MxBead1Bit<0>>;
+def MxEncEAa_0: MxEncEA<MxBeadReg<0>, MxBead2Bits<0b00>, MxBead1Bit<1>>;
+def MxEncEAj_0: MxEncEA<MxBeadReg<0>, MxBead2Bits<0b01>, MxBead1Bit<0>>;
+def MxEncEAo_0: MxEncEA<MxBeadReg<0>, MxBead2Bits<0b01>, MxBead1Bit<1>>;
+def MxEncEAe_0: MxEncEA<MxBeadReg<0>, MxBead2Bits<0b10>, MxBead1Bit<0>>;
+def MxEncEAp_0: MxEncEA<MxBeadReg<0>, MxBead2Bits<0b10>, MxBead1Bit<1>>;
+def MxEncEAf_0: MxEncEA<MxBeadReg<0>, MxBead2Bits<0b11>, MxBead1Bit<0>>;
+
+def MxEncEAa_0_reflected : MxEncEA<MxBeadReg<0>, MxBead3Bits<0b001>>;
+def MxEncEAr_0_reflected : MxEncEA<MxBeadReg<0>, MxBead2Bits<0b00>, MxBeadDA<0>>;
+
+def MxEncEAr_1: MxEncEA<MxBeadDAReg<1>, MxBead2Bits<0b00>>;
+def MxEncEAd_1: MxEncEA<MxBeadReg<1>, MxBead2Bits<0b00>, MxBead1Bit<0>>;
+def MxEncEAa_1: MxEncEA<MxBeadReg<1>, MxBead2Bits<0b00>, MxBead1Bit<1>>;
+def MxEncEAj_1: MxEncEA<MxBeadReg<1>, MxBead2Bits<0b01>, MxBead1Bit<0>>;
+def MxEncEAo_1: MxEncEA<MxBeadReg<1>, MxBead2Bits<0b01>, MxBead1Bit<1>>;
+def MxEncEAe_1: MxEncEA<MxBeadReg<1>, MxBead2Bits<0b10>, MxBead1Bit<0>>;
+def MxEncEAp_1: MxEncEA<MxBeadReg<1>, MxBead2Bits<0b10>, MxBead1Bit<1>>;
+def MxEncEAf_1: MxEncEA<MxBeadReg<1>, MxBead2Bits<0b11>, MxBead1Bit<0>>;
+
+def MxEncEAr_2: MxEncEA<MxBeadDAReg<2>, MxBead2Bits<0b00>>;
+def MxEncEAd_2: MxEncEA<MxBeadReg<2>, MxBead2Bits<0b00>, MxBead1Bit<0>>;
+def MxEncEAa_2: MxEncEA<MxBeadReg<2>, MxBead2Bits<0b00>, MxBead1Bit<1>>;
+def MxEncEAj_2: MxEncEA<MxBeadReg<2>, MxBead2Bits<0b01>, MxBead1Bit<0>>;
+def MxEncEAo_2: MxEncEA<MxBeadReg<2>, MxBead2Bits<0b01>, MxBead1Bit<1>>;
+def MxEncEAe_2: MxEncEA<MxBeadReg<2>, MxBead2Bits<0b10>, MxBead1Bit<0>>;
+def MxEncEAp_2: MxEncEA<MxBeadReg<2>, MxBead2Bits<0b10>, MxBead1Bit<1>>;
+def MxEncEAf_2: MxEncEA<MxBeadReg<2>, MxBead2Bits<0b11>, MxBead1Bit<0>>;
+
+def MxEncEAb : MxEncEA<MxBead3Bits<0b001>, MxBead2Bits<0b11>, MxBead1Bit<1>>;
+def MxEncEAq : MxEncEA<MxBead3Bits<0b010>, MxBead2Bits<0b11>, MxBead1Bit<1>>;
+def MxEncEAk : MxEncEA<MxBead3Bits<0b011>, MxBead2Bits<0b11>, MxBead1Bit<1>>;
+def MxEncEAi : MxEncEA<MxBead3Bits<0b100>, MxBead2Bits<0b11>, MxBead1Bit<1>>;
+
+// Allows you to specify each bit of opcode
+class MxEncOpMode<MxBead b0, MxBead b1 = MxBeadIgnore, MxBead b2 = MxBeadIgnore> {
+  MxBead B0 = b0;
+  MxBead B1 = b1;
+  MxBead B2 = b2;
+}
+
+// op EA, Dn
+def MxOpMode8dEA  : MxEncOpMode<MxBead3Bits<0b000>>;
+def MxOpMode16dEA : MxEncOpMode<MxBead3Bits<0b001>>;
+def MxOpMode32dEA : MxEncOpMode<MxBead3Bits<0b010>>;
+
+// op EA, An
+def MxOpMode16aEA : MxEncOpMode<MxBead3Bits<0b110>>;
+def MxOpMode32aEA : MxEncOpMode<MxBead3Bits<0b111>>;
+
+// op EA, Rn
+// As you might noticed this guy is special... Since M68k 
diff erentiates
+// between Data and Address registers we required to use 
diff erent OPMODE codes
+// for Address registers DST operands. One way of dealing with it is to use
+// separate tablegen instructions, but in this case it would force Register
+// Allocator to use specific Register Classes and eventually will lead to
+// superfluous moves. Another approach is to use reg-variadic encoding which will
+// change OPMODE base on Register Class used. Luckily, all the bits that 
diff er go
+// from 0 to 1 and can be encoded with MxBeadDA.
+// Basically, if the register used is of Data type these encodings will be
+// the same as MxOpMode{16,32}dEA above and used with regular instructions(e.g. ADD,
+// SUB), but if the register is of Address type the appropriate bits will flip and
+// the instructions become of *A type(e.g ADDA, SUBA).
+def MxOpMode16rEA : MxEncOpMode<MxBead1Bit<1>, MxBeadDA<0>, MxBead1Bit<0>>;
+def MxOpMode32rEA : MxEncOpMode<MxBeadDA<0>, MxBead1Bit<1>, MxBeadDA<0>>;
+
+// op Dn, EA
+def MxOpMode8EAd : MxEncOpMode<MxBead3Bits<0b100>>;
+def MxOpMode16EAd : MxEncOpMode<MxBead3Bits<0b101>>;
+def MxOpMode32EAd : MxEncOpMode<MxBead3Bits<0b110>>;
+
+
+// Represents two types of extension word:
+//   - Imm extension word
+//   - Brief extension word
+class MxEncExt<MxBead imm   = MxBeadIgnore,   MxBead b8 = MxBeadIgnore,
+               MxBead scale = MxBeadIgnore, MxBead wl = MxBeadIgnore,
+               MxBead daReg = MxBeadIgnore> {
+  MxBead Imm = imm;
+  MxBead B8 = b8;
+  MxBead Scale = scale;
+  MxBead WL = wl;
+  MxBead DAReg = daReg;
+}
+
+def MxExtEmpty : MxEncExt;
+
+// These handle encoding of displacement fields, absolute addresses and
+// immediate values, since encoding for these categories is mainly the same,
+// with exception of some weird immediates.
+def  MxExtI8_0 : MxEncExt<MxBead8Imm<0>>;
+def MxExtI16_0 : MxEncExt<MxBead16Imm<0>>;
+def MxExtI32_0 : MxEncExt<MxBead32Imm<0>>;
+
+def  MxExtI8_1 : MxEncExt<MxBead8Imm<1>>;
+def MxExtI16_1 : MxEncExt<MxBead16Imm<1>>;
+def MxExtI32_1 : MxEncExt<MxBead32Imm<1>>;
+
+def  MxExtI8_2 : MxEncExt<MxBead8Imm<2>>;
+def MxExtI16_2 : MxEncExt<MxBead16Imm<2>>;
+def MxExtI32_2 : MxEncExt<MxBead32Imm<2>>;
+
+// NOTE They are all using Long Xn
+def MxExtBrief_0 : MxEncExt<MxBead8Disp<0>, MxBead1Bit<0b0>,
+                            MxBead2Bits<0b00>, MxBead1Bit<1>,
+                            MxBeadDAReg<0, 1>>;
+
+def MxExtBrief_1 : MxEncExt<MxBead8Disp<1>, MxBead1Bit<0b0>,
+                            MxBead2Bits<0b00>, MxBead1Bit<1>,
+                            MxBeadDAReg<1, 1>>;
+
+def MxExtBrief_2 : MxEncExt<MxBead8Disp<2>, MxBead1Bit<0b0>,
+                            MxBead2Bits<0b00>, MxBead1Bit<1>,
+                            MxBeadDAReg<2, 1>>;
+
+def MxExtBrief_3 : MxEncExt<MxBead8Disp<3>, MxBead1Bit<0b0>,
+                            MxBead2Bits<0b00>, MxBead1Bit<1>,
+                            MxBeadDAReg<3, 1>>;
+
+def MxExtBrief_4 : MxEncExt<MxBead8Disp<4>, MxBead1Bit<0b0>,
+                            MxBead2Bits<0b00>, MxBead1Bit<1>,
+                            MxBeadDAReg<4, 1>>;
+
+class MxEncSize<bits<2> value> : MxBead2Bits<value>;
+def MxEncSize8  : MxEncSize<0b00>;
+def MxEncSize16 : MxEncSize<0b01>;
+def MxEncSize32 : MxEncSize<0b10>;
+def MxEncSize64 : MxEncSize<0b11>;
+
+// M68k INSTRUCTION. Most instructions specify the location of an operand by
+// using the effective address field in the operation word. The effective address
+// is composed of two 3-bit fields: the mode field and the register field. The
+// value in the mode field selects the 
diff erent address modes. The register
+// field contains the number of a register.  The effective address field may
+// require additional information to fully specify the operand. This additional
+// information, called the effective address extension, is contained in the
+// following word or words and is considered part of the instruction. The
+// effective address modes are grouped into three categories: register direct,
+// memory addressing, and special.
+class MxInst<dag outs, dag ins,
+             string asmStr = "",
+             list<dag> pattern = [],
+             MxEncoding beads = MxEncEmpty,
+             InstrItinClass itin = NoItinerary>
+    : Instruction {
+  let Namespace      = "M68k";
+  let OutOperandList = outs;
+  let InOperandList  = ins;
+  let AsmString      = asmStr;
+  let Pattern        = pattern;
+  let Itinerary      = itin;
+
+  // Byte stream
+  field bits<192> Beads = beads.Value;
+
+  // Number of bytes
+  let Size = 0;
+
+  let UseLogicalOperandMappings = 1;
+}
+
+// M68k PSEUDO INSTRUCTION
+class MxPseudo<dag outs, dag ins, string asmStr = "", list<dag> pattern = []>
+    : MxInst<outs, ins, asmStr, pattern> {
+  let isPseudo = 1;
+}

diff  --git a/llvm/lib/Target/M68k/M68kInstrInfo.td b/llvm/lib/Target/M68k/M68kInstrInfo.td
new file mode 100644
index 000000000000..e5d6783022ce
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.td
@@ -0,0 +1,665 @@
+//== M68kInstrInfo.td - Main M68k Instruction Definition -*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the M68k instruction set, defining the instructions
+/// and properties of the instructions which are needed for code generation,
+/// machine code emission, and analysis.
+///
+//===----------------------------------------------------------------------===//
+
+include "M68kInstrFormats.td"
+
+//===----------------------------------------------------------------------===//
+// Profiles
+//===----------------------------------------------------------------------===//
+
+def MxSDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
+def MxSDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
+
+def MxSDT_Call    : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
+
+def MxSDT_Ret     : SDTypeProfile<0, -1, [
+  /* ADJ */ SDTCisVT<0, i32>
+]>;
+
+def MxSDT_TCRet   : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
+
+def MxSDT_Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
+
+def MxSDT_UnArithCCROut : SDTypeProfile<2, 1, [
+  /* RES */ SDTCisInt<0>,
+  /* CCR */ SDTCisVT<1, i8>,
+  /* OPD */ SDTCisSameAs<0, 2>
+]>;
+
+// RES, CCR <- op LHS, RHS
+def MxSDT_BiArithCCROut : SDTypeProfile<2, 2, [
+  /* RES */ SDTCisInt<0>,
+  /* CCR */ SDTCisVT<1, i8>,
+  /* LHS */ SDTCisSameAs<0, 2>,
+  /* RHS */ SDTCisSameAs<0, 3>
+]>;
+
+// RES, CCR <- op LHS, RHS, CCR
+def MxSDT_BiArithCCRInOut : SDTypeProfile<2, 3, [
+  /* RES 1 */ SDTCisInt<0>,
+  /*   CCR */ SDTCisVT<1, i8>,
+  /*   LHS */ SDTCisSameAs<0, 2>,
+  /*   RHS */ SDTCisSameAs<0, 3>,
+  /*   CCR */ SDTCisSameAs<1, 4>
+]>;
+
+// RES1, RES2, CCR <- op LHS, RHS
+def MxSDT_2BiArithCCROut : SDTypeProfile<3, 2, [
+  /* RES 1 */ SDTCisInt<0>,
+  /* RES 2 */ SDTCisSameAs<0, 1>,
+  /*   CCR */ SDTCisVT<1, i8>,
+  /*   LHS */ SDTCisSameAs<0, 2>,
+  /*   RHS */ SDTCisSameAs<0, 3>
+]>;
+
+def MxSDT_CmpTest : SDTypeProfile<1, 2, [
+   /* CCR */ SDTCisVT<0, i8>,
+   /* Ops */ SDTCisSameAs<1, 2>
+]>;
+
+def MxSDT_Cmov : SDTypeProfile<1, 4, [
+  /*  ARG */ SDTCisSameAs<0, 1>,
+  /*  ARG */ SDTCisSameAs<1, 2>,
+  /* Cond */ SDTCisVT<3, i8>,
+  /*  CCR */ SDTCisVT<4, i8>
+]>;
+
+def MxSDT_BrCond : SDTypeProfile<0, 3, [
+  /* Dest */ SDTCisVT<0, OtherVT>,
+  /* Cond */ SDTCisVT<1, i8>,
+  /*  CCR */ SDTCisVT<2, i8>
+]>;
+
+def MxSDT_SetCC : SDTypeProfile<1, 2, [
+  /* BOOL */ SDTCisVT<0, i8>,
+  /* Cond */ SDTCisVT<1, i8>,
+  /*  CCR */ SDTCisVT<2, i8>
+]>;
+
+def MxSDT_SetCC_C : SDTypeProfile<1, 2, [
+  /* BOOL */ SDTCisInt<0>,
+  /* Cond */ SDTCisVT<1, i8>,
+  /*  CCR */ SDTCisVT<2, i8>
+]>;
+
+
+def MxSDT_SEG_ALLOCA : SDTypeProfile<1, 1,[
+  /*  MEM */ SDTCisVT<0, iPTR>,
+  /* SIZE */ SDTCisVT<1, iPTR>
+]>;
+
+
+//===----------------------------------------------------------------------===//
+// Nodes
+//===----------------------------------------------------------------------===//
+
+def MxCallSeqStart : SDNode<"ISD::CALLSEQ_START", MxSDT_CallSeqStart,
+                            [SDNPHasChain, SDNPOutGlue]>;
+
+def MxCallSeqEnd   : SDNode<"ISD::CALLSEQ_END", MxSDT_CallSeqEnd,
+                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
+
+def MxCall         : SDNode<"M68kISD::CALL", MxSDT_Call,
+                            [SDNPHasChain, SDNPOutGlue,
+                             SDNPOptInGlue, SDNPVariadic]>;
+
+def MxRet   : SDNode<"M68kISD::RET", MxSDT_Ret,
+                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+
+def MxTCRet : SDNode<"M68kISD::TC_RETURN", MxSDT_TCRet,
+                     [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
+
+def MxWrapper   : SDNode<"M68kISD::Wrapper",   MxSDT_Wrapper>;
+def MxWrapperPC : SDNode<"M68kISD::WrapperPC", MxSDT_Wrapper>;
+
+def MxAdd  : SDNode<"M68kISD::ADD",  MxSDT_BiArithCCROut, [SDNPCommutative]>;
+def MxSub  : SDNode<"M68kISD::SUB",  MxSDT_BiArithCCROut>;
+def MxOr   : SDNode<"M68kISD::OR",   MxSDT_BiArithCCROut, [SDNPCommutative]>;
+def MxXor  : SDNode<"M68kISD::XOR",  MxSDT_BiArithCCROut, [SDNPCommutative]>;
+def MxAnd  : SDNode<"M68kISD::AND",  MxSDT_BiArithCCROut, [SDNPCommutative]>;
+
+def MxAddX : SDNode<"M68kISD::ADDX", MxSDT_BiArithCCRInOut>;
+def MxSubX : SDNode<"M68kISD::SUBX", MxSDT_BiArithCCRInOut>;
+
+def MxSMul : SDNode<"M68kISD::SMUL", MxSDT_BiArithCCROut, [SDNPCommutative]>;
+def MxUMul : SDNode<"M68kISD::UMUL", MxSDT_2BiArithCCROut, [SDNPCommutative]>;
+
+def MxCmp     : SDNode<"M68kISD::CMP", MxSDT_CmpTest>;
+def MxBt      : SDNode<"M68kISD::BT",  MxSDT_CmpTest>;
+
+def MxCmov    : SDNode<"M68kISD::CMOV",        MxSDT_Cmov>;
+def MxBrCond  : SDNode<"M68kISD::BRCOND",      MxSDT_BrCond, [SDNPHasChain]>;
+def MxSetCC   : SDNode<"M68kISD::SETCC",       MxSDT_SetCC>;
+def MxSetCC_C : SDNode<"M68kISD::SETCC_CARRY", MxSDT_SetCC_C>;
+
+
+def MxSegAlloca : SDNode<"M68kISD::SEG_ALLOCA", MxSDT_SEG_ALLOCA,
+                         [SDNPHasChain]>;
+
+
+//===----------------------------------------------------------------------===//
+// Operands
+//===----------------------------------------------------------------------===//
+
+/// Size is the size of the data, either bits of a register or number of bits
+/// addressed in memory. Size id is a letter that identifies size.
+class MxSize<int num, string id, string full> {
+  int Num = num;
+  string Id = id;
+  string Full = full;
+}
+
+def MxSize8  : MxSize<8,  "b", "byte">;
+def MxSize16 : MxSize<16, "w", "word">;
+def MxSize32 : MxSize<32, "l", "long">;
+
+class MxOperand<ValueType vt, MxSize size, string letter, RegisterClass rc, dag pat = (null_frag)> {
+  ValueType VT = vt;
+  string Letter = letter;
+  MxSize Size = size;
+  RegisterClass RC = rc;
+  dag Pat = pat;
+}
+
+class MxRegOp<ValueType vt,
+              RegisterClass rc,
+              MxSize size,
+              string letter,
+              string pm = "printOperand">
+    : RegisterOperand<rc, pm>,
+      MxOperand<vt, size, letter, rc>;
+
+// REGISTER DIRECT. The operand is in the data register specified by
+// the effective address register field.
+def MxXRD16 : MxRegOp<i16, XR16, MxSize16, "r">;
+def MxXRD32 : MxRegOp<i32, XR32, MxSize32, "r">;
+
+def MxXRD16_TC : MxRegOp<i16, XR16_TC, MxSize16, "r">;
+def MxXRD32_TC : MxRegOp<i32, XR32_TC, MxSize32, "r">;
+
+// DATA REGISTER DIRECT. The operand is in the data register specified by
+// the effective address register field.
+def MxDRD8  : MxRegOp<i8,  DR8,  MxSize8,  "d">;
+def MxDRD16 : MxRegOp<i16, DR16, MxSize16, "d">;
+def MxDRD32 : MxRegOp<i32, DR32, MxSize32, "d">;
+
+def MxDRD16_TC : MxRegOp<i16, DR16_TC, MxSize16, "d">;
+def MxDRD32_TC : MxRegOp<i32, DR32_TC, MxSize32, "d">;
+
+// ADDRESS REGISTER DIRECT. The operand is in the address register specified by
+// the effective address register field.
+def MxARD16 : MxRegOp<i16, AR16, MxSize16, "a">;
+def MxARD32 : MxRegOp<i32, AR32, MxSize32, "a">;
+
+def MxARD16_TC : MxRegOp<i16, AR16_TC, MxSize16, "a">;
+def MxARD32_TC : MxRegOp<i32, AR32_TC, MxSize32, "a">;
+
+// TODO finish parser wiring
+def MxMemAsmOperand : AsmOperandClass {
+ let Name = "MxMemOp";
+}
+
+class MxMemOp<dag ops, MxSize size, string letter,
+              string printMethod = "printOperand",
+              AsmOperandClass parserMatchClass = MxMemAsmOperand>
+    : Operand<iPTR>, MxOperand<iPTR, size, letter, ?> {
+  let PrintMethod = printMethod;
+  let MIOperandInfo = ops;
+  let ParserMatchClass = parserMatchClass;
+  let OperandType = "OPERAND_MEMORY";
+}
+
+// ADDRESS REGISTER INDIRECT. The address of the operand is in the address
+// register specified by the register field. The reference is classified as
+// a data reference with the exception of the jump and jump-to-subroutine
+// instructions.
+def MxARI8        : MxMemOp<(ops AR32), MxSize8,  "j", "printARI8Mem">;
+def MxARI16       : MxMemOp<(ops AR32), MxSize16, "j", "printARI16Mem">;
+def MxARI32       : MxMemOp<(ops AR32), MxSize32, "j", "printARI32Mem">;
+
+def MxARI8_TC     : MxMemOp<(ops AR32_TC), MxSize8,  "j", "printARI8Mem">;
+def MxARI16_TC    : MxMemOp<(ops AR32_TC), MxSize16, "j", "printARI16Mem">;
+def MxARI32_TC    : MxMemOp<(ops AR32_TC), MxSize32, "j", "printARI32Mem">;
+
+// ADDRESS REGISTER INDIRECT WITH POSTINCREMENT. The address of the operand is
+// in the address register specified by the register field. After the operand
+// address is used, it is incremented by one, two, or four depending upon whether
+// the size of the operand is byte, word, or long word. If the address register
+// is the stack pointer and the operand size is byte, the address is incremented
+// by two rather than one to keep the stack pointer on a word boundary.
+// The reference is classified as a data reference.
+def MxARIPI8      : MxMemOp<(ops AR32), MxSize8,  "o", "printARIPI8Mem">;
+def MxARIPI16     : MxMemOp<(ops AR32), MxSize16, "o", "printARIPI16Mem">;
+def MxARIPI32     : MxMemOp<(ops AR32), MxSize32, "o", "printARIPI32Mem">;
+
+def MxARIPI8_TC   : MxMemOp<(ops AR32_TC), MxSize8,  "o", "printARIPI8Mem">;
+def MxARIPI16_TC  : MxMemOp<(ops AR32_TC), MxSize16, "o", "printARIPI16Mem">;
+def MxARIPI32_TC  : MxMemOp<(ops AR32_TC), MxSize32, "o", "printARIPI32Mem">;
+
+// ADDRESS REGISTER INDIRECT WITH PREDECREMENT. The address of the operand is in
+// the address register specified by the register field. Before the operand
+// address is used, it is decremented by one, two, or four depending upon whether
+// the operand size is byte, word, or long word. If the address register is
+// the stack pointer and the operand size is byte, the address is decremented by
+// two rather than one to keep the stack pointer on a word boundary.
+// The reference is classified as a data reference.
+def MxARIPD8      : MxMemOp<(ops AR32), MxSize8,  "e", "printARIPD8Mem">;
+def MxARIPD16     : MxMemOp<(ops AR32), MxSize16, "e", "printARIPD16Mem">;
+def MxARIPD32     : MxMemOp<(ops AR32), MxSize32, "e", "printARIPD32Mem">;
+
+def MxARIPD8_TC   : MxMemOp<(ops AR32_TC), MxSize8,  "e", "printARIPD8Mem">;
+def MxARIPD16_TC  : MxMemOp<(ops AR32_TC), MxSize16, "e", "printARIPD16Mem">;
+def MxARIPD32_TC  : MxMemOp<(ops AR32_TC), MxSize32, "e", "printARIPD32Mem">;
+
+// ADDRESS REGISTER INDIRECT WITH DISPLACEMENT. This addressing mode requires one
+// word of extension. The address of the operand is the sum of the address in
+// the address register and the sign-extended 16-bit displacement integer in the
+// extension word. The reference is classified as a data reference with the
+// exception of the jump and jump-to-subroutine instructions.
+def MxARID8       : MxMemOp<(ops i16imm, AR32), MxSize8,  "p", "printARID8Mem">;
+def MxARID16      : MxMemOp<(ops i16imm, AR32), MxSize16, "p", "printARID16Mem">;
+def MxARID32      : MxMemOp<(ops i16imm, AR32), MxSize32, "p", "printARID32Mem">;
+
+def MxARID8_TC    : MxMemOp<(ops i16imm, AR32_TC), MxSize8,  "p", "printARID8Mem">;
+def MxARID16_TC   : MxMemOp<(ops i16imm, AR32_TC), MxSize16, "p", "printARID16Mem">;
+def MxARID32_TC   : MxMemOp<(ops i16imm, AR32_TC), MxSize32, "p", "printARID32Mem">;
+
+// ADDRESS REGISTER INDIRECT WITH INDEX. This addressing mode requires one word
+// of extension. The address of the operand is the sum of the address in the
+// address register, the signextended displacement integer in the low order eight
+// bits of the extension word, and the contents of the index register.
+// The reference is classified as a data reference with the exception of the
+// jump and jump-to-subroutine instructions
+def MxARII8      : MxMemOp<(ops i8imm, AR32, XR32), MxSize8,  "f", "printARII8Mem">;
+def MxARII16     : MxMemOp<(ops i8imm, AR32, XR32), MxSize16, "f", "printARII16Mem">;
+def MxARII32     : MxMemOp<(ops i8imm, AR32, XR32), MxSize32, "f", "printARII32Mem">;
+
+def MxARII8_TC   : MxMemOp<(ops i8imm, AR32_TC, XR32_TC), MxSize8,  "f", "printARII8Mem">;
+def MxARII16_TC  : MxMemOp<(ops i8imm, AR32_TC, XR32_TC), MxSize16, "f", "printARII16Mem">;
+def MxARII32_TC  : MxMemOp<(ops i8imm, AR32_TC, XR32_TC), MxSize32, "f", "printARII32Mem">;
+
+// ABSOLUTE SHORT ADDRESS. This addressing mode requires one word of extension.
+// The address of the operand is the extension word. The 16-bit address is sign
+// extended before it is used.  The reference is classified as a data reference
+// with the exception of the jump and jump-tosubroutine instructions.
+def MxAS8      : MxMemOp<(ops OtherVT), MxSize8,  "B", "printAS8Mem">;
+def MxAS16     : MxMemOp<(ops OtherVT), MxSize16, "B", "printAS16Mem">;
+def MxAS32     : MxMemOp<(ops OtherVT), MxSize32, "B", "printAS32Mem">;
+
+// ABSOLUTE LONG ADDRESS. This addressing mode requires two words of extension.
+// The address of the operand is developed by the concatenation of the extension
+// words. The high order part of the address is the first extension word; the low
+// order part of the address is the second extension word. The reference is
+// classified as a data reference with the exception of the jump and jump
+// to-subroutine instructions.
+def MxAL8      : MxMemOp<(ops OtherVT), MxSize8,  "b", "printAL8Mem">;
+def MxAL16     : MxMemOp<(ops OtherVT), MxSize16, "b", "printAL16Mem">;
+def MxAL32     : MxMemOp<(ops OtherVT), MxSize32, "b", "printAL32Mem">;
+
+let OperandType = "OPERAND_PCREL" in {
+// PROGRAM COUNTER WITH DISPLACEMENT. This addressing mode requires one word of
+// extension. The address of the operand is the sum of the address in the program
+// counter and the Sign-extended 16-bit displacement integer in the extension
+// word. The value in the program counter is the address of the extension word.
+// The reference is classified as a program reference.
+def MxPCD8     : MxMemOp<(ops i16imm), MxSize8,  "q", "printPCD8Mem">;
+def MxPCD16    : MxMemOp<(ops i16imm), MxSize16, "q", "printPCD16Mem">;
+def MxPCD32    : MxMemOp<(ops i16imm), MxSize32, "q", "printPCD32Mem">;
+
+// PROGRAM COUNTER WITH INDEX. This addressing mode requires one word of
+// extension. The address is the sum of the address in the program counter, the
+// sign-extended displacement integer in the lower eight bits of the extension
+// word, and the contents of the index register.  The value in the program
+// counter is the address of the extension word. This reference is classified as
+// a program reference.
+def MxPCI8   : MxMemOp<(ops i8imm, XR32), MxSize8,  "k", "printPCI8Mem">;
+def MxPCI16  : MxMemOp<(ops i8imm, XR32), MxSize16, "k", "printPCI16Mem">;
+def MxPCI32  : MxMemOp<(ops i8imm, XR32), MxSize32, "k", "printPCI32Mem">;
+} // OPERAND_PCREL
+
+class MxOp<ValueType vt, MxSize size, string letter>
+    : Operand<vt>,
+      MxOperand<vt, size, letter, ?>;
+
+let OperandType = "OPERAND_IMMEDIATE",
+    PrintMethod = "printImmediate" in {
+// IMMEDIATE DATA. This addressing mode requires either one or two words of
+// extension depending on the size of the operation.
+//     Byte Operation - operand is low order byte of extension word
+//     Word Operation - operand is extension word
+//     Long Word Operation - operand is in the two extension words,
+//                           high order 16 bits are in the first
+//                           extension word, low order 16 bits are
+//                           in the second extension word.
+def Mxi8imm  : MxOp<i8,  MxSize8,  "i">;
+def Mxi16imm : MxOp<i16, MxSize16, "i">;
+def Mxi32imm : MxOp<i32, MxSize32, "i">;
+} // OPERAND_IMMEDIATE
+
+let OperandType = "OPERAND_PCREL",
+    PrintMethod = "printPCRelImm" in {
+
+// Branch targets have OtherVT type and print as pc-relative values.
+def MxBrTarget8  : Operand<OtherVT>;
+def MxBrTarget16 : Operand<OtherVT>;
+def MxBrTarget32 : Operand<OtherVT>;
+
+} // OPERAND_PCREL
+
+// Used with MOVEM
+def MxMoveMask : MxOp<i16, MxSize16, "m"> {
+  let OperandType = "OPERAND_IMMEDIATE";
+  let PrintMethod = "printMoveMask";
+}
+
+
+//===----------------------------------------------------------------------===//
+// Predicates
+//===----------------------------------------------------------------------===//
+
+def SmallCode    : Predicate<"TM.getCodeModel() == CodeModel::Small">;
+def KernelCode   : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
+def FarData      : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
+                             "TM.getCodeModel() != CodeModel::Kernel">;
+def NearData     : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
+                             "TM.getCodeModel() == CodeModel::Kernel">;
+def IsPIC        : Predicate<"TM.isPositionIndependent()">;
+def IsNotPIC     : Predicate<"!TM.isPositionIndependent()">;
+def IsM68000     : Predicate<"Subtarget.IsM68000()">;
+def IsM68010     : Predicate<"Subtarget.IsM68010()">;
+def IsM68020     : Predicate<"Subtarget.IsM68020()">;
+def IsM68030     : Predicate<"Subtarget.IsM68030()">;
+def IsM68040     : Predicate<"Subtarget.IsM68040()">;
+
+
+//===----------------------------------------------------------------------===//
+// Condition Codes
+//
+// These MUST be kept in sync with codes enum in M68kInstrInfo.h
+//===----------------------------------------------------------------------===//
+
+def MxCONDt   : PatLeaf<(i8 0)>;  // True
+def MxCONDf   : PatLeaf<(i8 1)>;  // False
+def MxCONDhi  : PatLeaf<(i8 2)>;  // High
+def MxCONDls  : PatLeaf<(i8 3)>;  // Less or Same
+def MxCONDcc  : PatLeaf<(i8 4)>;  // Carry Clear
+def MxCONDcs  : PatLeaf<(i8 5)>;  // Carry Set
+def MxCONDne  : PatLeaf<(i8 6)>;  // Not Equal
+def MxCONDeq  : PatLeaf<(i8 7)>;  // Equal
+def MxCONDvc  : PatLeaf<(i8 8)>;  // Overflow Clear
+def MxCONDvs  : PatLeaf<(i8 9)>;  // Overflow Set
+def MxCONDpl  : PatLeaf<(i8 10)>; // Plus
+def MxCONDmi  : PatLeaf<(i8 11)>; // Minus
+def MxCONDge  : PatLeaf<(i8 12)>; // Greater or Equal
+def MxCONDlt  : PatLeaf<(i8 13)>; // Less Than
+def MxCONDgt  : PatLeaf<(i8 14)>; // Greater Than
+def MxCONDle  : PatLeaf<(i8 15)>; // Less or Equal
+
+
+//===----------------------------------------------------------------------===//
+// Complex Patterns
+//===----------------------------------------------------------------------===//
+
+// NOTE Though this CP is not strictly necessarily it will simplify instruciton
+// definitions
+def MxCP_ARI   : ComplexPattern<iPTR, 1, "SelectARI",
+                                [], [SDNPWantParent]>;
+
+def MxCP_ARIPI : ComplexPattern<iPTR, 1, "SelectARIPI",
+                                [], [SDNPWantParent]>;
+
+def MxCP_ARIPD : ComplexPattern<iPTR, 1, "SelectARIPD",
+                                [], [SDNPWantParent]>;
+
+def MxCP_ARID  : ComplexPattern<iPTR, 2, "SelectARID",
+                                [add, sub, mul, or, shl, frameindex],
+                                [SDNPWantParent]>;
+
+def MxCP_ARII  : ComplexPattern<iPTR, 3, "SelectARII",
+                                [add, sub, mul, or, shl, frameindex],
+                                [SDNPWantParent]>;
+
+def MxCP_AL    : ComplexPattern<iPTR, 1, "SelectAL",
+                                [add, sub, mul, or, shl],
+                                [SDNPWantParent]>;
+
+def MxCP_PCD   : ComplexPattern<iPTR, 1, "SelectPCD",
+                                [add, sub, mul, or, shl],
+                                [SDNPWantParent]>;
+
+def MxCP_PCI   : ComplexPattern<iPTR, 2, "SelectPCI",
+                                [add, sub, mul, or, shl], [SDNPWantParent]>;
+
+
+//===----------------------------------------------------------------------===//
+// Pattern Fragments
+//===----------------------------------------------------------------------===//
+
+def MximmSExt8  : PatLeaf<(i8  imm)>;
+def MximmSExt16 : PatLeaf<(i16 imm)>;
+def MximmSExt32 : PatLeaf<(i32 imm)>;
+
+// Used for Shifts and Rotations, since M68k immediates in these instructions
+// are 1 <= i <= 8. Generally, if immediate is bigger than 8 it will be moved
+// to a register and then an operation is performed.
+//
+// TODO Need to evaluate whether splitting one big shift(or rotate)
+// into a few smaller is faster than doing a move, if so do custom lowering
+def Mximm8_1to8   : ImmLeaf<i8,  [{ return Imm >= 1 && Imm <= 8; }]>;
+def Mximm16_1to8  : ImmLeaf<i16, [{ return Imm >= 1 && Imm <= 8; }]>;
+def Mximm32_1to8  : ImmLeaf<i32, [{ return Imm >= 1 && Imm <= 8; }]>;
+
+// Helper fragments for loads.
+// It's always safe to treat a anyext i16 load as a i32 load if the i16 is
+// known to be 32-bit aligned or better. Ditto for i8 to i16.
+def Mxloadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{
+  LoadSDNode *LD = cast<LoadSDNode>(N);
+  ISD::LoadExtType ExtType = LD->getExtensionType();
+  if (ExtType == ISD::NON_EXTLOAD)
+    return true;
+  if (ExtType == ISD::EXTLOAD)
+    return LD->getAlignment() >= 2 && !LD->isSimple();
+  return false;
+}]>;
+
+def Mxloadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{
+  LoadSDNode *LD = cast<LoadSDNode>(N);
+  ISD::LoadExtType ExtType = LD->getExtensionType();
+  if (ExtType == ISD::NON_EXTLOAD)
+    return true;
+  if (ExtType == ISD::EXTLOAD)
+    return LD->getAlignment() >= 4 && !LD->isSimple();
+  return false;
+}]>;
+
+def Mxloadi8         : PatFrag<(ops node:$ptr), (i8  (load node:$ptr))>;
+
+def MxSExtLoadi16i8  : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;
+def MxSExtLoadi32i8  : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
+def MxSExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
+
+def MxZExtLoadi8i1   : PatFrag<(ops node:$ptr), (i8  (zextloadi1 node:$ptr))>;
+def MxZExtLoadi16i1  : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;
+def MxZExtLoadi32i1  : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;
+def MxZExtLoadi16i8  : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;
+def MxZExtLoadi32i8  : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
+def MxZExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
+
+def MxExtLoadi8i1    : PatFrag<(ops node:$ptr), (i8  (extloadi1 node:$ptr))>;
+def MxExtLoadi16i1   : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;
+def MxExtLoadi32i1   : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;
+def MxExtLoadi16i8   : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;
+def MxExtLoadi32i8   : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
+def MxExtLoadi32i16  : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
+
+
+//===----------------------------------------------------------------------===//
+// Type Fixtures
+//
+// Type Fixtures are ValueType related information sets that usually go together
+//===----------------------------------------------------------------------===//
+
+// TODO make it folded like MxType8.F.Op nad MxType8.F.Pat
+// TODO move strings into META subclass
+// vt: Type of data this fixture refers to
+// prefix: Prefix used to identify type
+// postfix: Prefix used to qualify type
+class MxType<ValueType vt, string prefix, string postfix,
+             // rLet: Register letter
+             // rOp:  Supported any register operand
+             string rLet, MxOperand rOp,
+             // jOp:  Supported ARI operand
+             // jPat: What ARI pattern to use
+             MxOperand jOp, ComplexPattern jPat,
+             // oOp:  Supported ARIPI operand
+             // oPat: What ARIPI pattern is used
+             MxOperand oOp, ComplexPattern oPat,
+             // eOp:  Supported ARIPD operand
+             // ePat: What ARIPD pattern is used
+             MxOperand eOp, ComplexPattern ePat,
+             // pOp:  Supported ARID operand
+             // pPat: What ARID pattern is used
+             MxOperand pOp, ComplexPattern pPat,
+             // fOp:  Supported ARII operand
+             // fPat: What ARII pattern is used
+             MxOperand fOp, ComplexPattern fPat,
+             // bOp:  Supported absolute operand
+             // bPat: What absolute pattern is used
+             MxOperand bOp, ComplexPattern bPat,
+             // qOp:  Supported PCD operand
+             // qPat: What PCD pattern is used
+             MxOperand qOp, ComplexPattern qPat,
+             // kOp:  Supported PCD operand
+             // kPat: What PCD pattern is used
+             MxOperand kOp, ComplexPattern kPat,
+             // iOp:  Supported immediate operand
+             // iPat: What immediate pattern is used
+             MxOperand iOp, PatFrag iPat,
+             // load: What load operation is used with MEM
+             PatFrag load> {
+  int Size = vt.Size;
+  ValueType VT = vt;
+  string Prefix = prefix;
+  string Postfix = postfix;
+
+  string RLet = rLet;
+  MxOperand ROp = rOp;
+
+  MxOperand JOp = jOp;
+  ComplexPattern JPat = jPat;
+
+  MxOperand OOp = oOp;
+  ComplexPattern OPat = oPat;
+
+  MxOperand EOp = eOp;
+  ComplexPattern EPat = ePat;
+
+  MxOperand POp = pOp;
+  ComplexPattern PPat = pPat;
+
+  MxOperand FOp = fOp;
+  ComplexPattern FPat = fPat;
+
+  MxOperand BOp = bOp;
+  ComplexPattern BPat = bPat;
+
+  MxOperand QOp = qOp;
+  ComplexPattern QPat = qPat;
+
+  MxOperand KOp = kOp;
+  ComplexPattern KPat = kPat;
+
+  MxOperand IOp = iOp;
+  PatFrag IPat = iPat;
+
+  PatFrag Load = load;
+}
+
+class MxType8Class<string rLet, MxOperand reg>
+    : MxType<i8, "b", "", rLet, reg,
+             MxARI8,   MxCP_ARI,
+             MxARIPI8, MxCP_ARIPI,
+             MxARIPD8, MxCP_ARIPD,
+             MxARID8,  MxCP_ARID,
+             MxARII8,  MxCP_ARII,
+             MxAL8,    MxCP_AL,
+             MxPCD8,   MxCP_PCD,
+             MxPCI8,   MxCP_PCI,
+             Mxi8imm,  MximmSExt8,
+             Mxloadi8>;
+
+def MxType8 : MxType8Class<?,?>;
+
+class MxType16Class<string rLet, MxOperand reg>
+    : MxType<i16, "w", "", rLet, reg,
+             MxARI16,   MxCP_ARI,
+             MxARIPI16, MxCP_ARIPI,
+             MxARIPD16, MxCP_ARIPD,
+             MxARID16,  MxCP_ARID,
+             MxARII16,  MxCP_ARII,
+             MxAL16,    MxCP_AL,
+             MxPCD16,   MxCP_PCD,
+             MxPCI16,   MxCP_PCI,
+             Mxi16imm,  MximmSExt16,
+             Mxloadi16>;
+
+def MxType16 : MxType16Class<?,?>;
+
+class MxType32Class<string rLet, MxOperand reg>
+    : MxType<i32, "l", "", rLet, reg,
+             MxARI32,   MxCP_ARI,
+             MxARIPI32, MxCP_ARIPI,
+             MxARIPD32, MxCP_ARIPD,
+             MxARID32,  MxCP_ARID,
+             MxARII32,  MxCP_ARII,
+             MxAL32,    MxCP_AL,
+             MxPCD32,   MxCP_PCD,
+             MxPCI32,   MxCP_PCI,
+             Mxi32imm,  MximmSExt32,
+             Mxloadi32>;
+
+def MxType32 : MxType32Class<?,?>;
+
+
+def MxType8d : MxType8Class<"d", MxDRD8>;
+
+def MxType16d : MxType16Class<"d", MxDRD16>;
+def MxType16a : MxType16Class<"a", MxARD16>;
+def MxType16r : MxType16Class<"r", MxXRD16>;
+def MxType32d : MxType32Class<"d", MxDRD32>;
+def MxType32a : MxType32Class<"a", MxARD32>;
+def MxType32r : MxType32Class<"r", MxXRD32>;
+
+let Postfix = "_TC" in {
+def MxType16d_TC : MxType16Class<"d", MxDRD16_TC>;
+def MxType16a_TC : MxType16Class<"a", MxARD16_TC>;
+def MxType16r_TC : MxType16Class<"r", MxXRD16_TC>;
+def MxType32d_TC : MxType32Class<"d", MxDRD32_TC>;
+def MxType32a_TC : MxType32Class<"a", MxARD32_TC>;
+def MxType32r_TC : MxType32Class<"r", MxXRD32_TC>;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Subsystems
+//===----------------------------------------------------------------------===//
+
+include "M68kInstrData.td"
+include "M68kInstrShiftRotate.td"
+include "M68kInstrBits.td"
+include "M68kInstrArithmetic.td"
+include "M68kInstrControl.td"
+
+include "M68kInstrCompiler.td"

diff  --git a/llvm/lib/Target/M68k/M68kInstrShiftRotate.td b/llvm/lib/Target/M68k/M68kInstrShiftRotate.td
new file mode 100644
index 000000000000..f777a5d33e21
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kInstrShiftRotate.td
@@ -0,0 +1,92 @@
+//===------ M68kInstrShiftRotate.td - Logical Instrs -----*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the logical instructions in the M68k architecture.
+/// Here is the current status of the file:
+///
+///  Machine:
+///
+///    SHL     [~]   ASR     [~]   LSR      [~]   SWAP     [ ]
+///    ROL     [~]   ROR     [~]   ROXL     [ ]   ROXR     [ ]
+///
+///  Map:
+///
+///   [ ] - was not touched at all
+///   [!] - requires extarnal stuff implemented
+///   [~] - in progress but usable
+///   [x] - done
+///
+//===----------------------------------------------------------------------===//
+
+def MxRODI_R : MxBead1Bit<0>;
+def MxRODI_L : MxBead1Bit<1>;
+
+def MxROOP_AS  : MxBead2Bits<0b00>;
+def MxROOP_LS  : MxBead2Bits<0b01>;
+def MxROOP_ROX : MxBead2Bits<0b10>;
+def MxROOP_RO  : MxBead2Bits<0b11>;
+
+/// ------------+---------+---+------+---+------+---------
+///  F  E  D  C | B  A  9 | 8 | 7  6 | 5 | 4  3 | 2  1  0
+/// ------------+---------+---+------+---+------+---------
+///  1  1  1  0 | REG/IMM | D | SIZE |R/I|  OP  |   REG
+/// ------------+---------+---+------+---+------+---------
+class MxSREncoding_R<MxBead1Bit DIRECTION, MxBead2Bits ROOP, MxEncSize SIZE>
+    : MxEncoding<MxBeadReg<0>, ROOP, MxBead1Bit<1>, SIZE, DIRECTION,
+                 MxBeadReg<2>, MxBead4Bits<0b1110>>;
+
+class MxSREncoding_I<MxBead1Bit DIRECTION, MxBead2Bits ROOP, MxEncSize SIZE>
+    : MxEncoding<MxBeadReg<0>, ROOP, MxBead1Bit<0>, SIZE, DIRECTION,
+                 MxBead3Imm<2, 1>, MxBead4Bits<0b1110>>;
+
+// $reg <- $reg op $reg
+class MxSR_DD<string MN, MxType TYPE, SDNode NODE,
+              MxBead1Bit RODI, MxBead2Bits ROOP>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd),
+             MN#"."#TYPE.Prefix#"\t$opd, $dst",
+             [(set TYPE.VT:$dst, (NODE TYPE.VT:$src, TYPE.VT:$opd))],
+             MxSREncoding_R<RODI, ROOP,
+                            !cast<MxEncSize>("MxEncSize"#TYPE.Size)>>;
+
+// $reg <- $reg op $imm
+class MxSR_DI<string MN, MxType TYPE, SDNode NODE,
+              MxBead1Bit RODI, MxBead2Bits ROOP>
+    : MxInst<(outs TYPE.ROp:$dst),
+             (ins TYPE.ROp:$src, !cast<Operand>("Mxi"#TYPE.Size#"imm"):$opd),
+             MN#"."#TYPE.Prefix#"\t$opd, $dst",
+             [(set TYPE.VT:$dst,
+                   (NODE TYPE.VT:$src,
+                         !cast<ImmLeaf>("Mximm"#TYPE.Size#"_1to8"):$opd))],
+             MxSREncoding_I<RODI, ROOP,
+                            !cast<MxEncSize>("MxEncSize"#TYPE.Size)>>;
+
+multiclass MxSROp<string MN, SDNode NODE, MxBead1Bit RODI, MxBead2Bits ROOP> {
+
+  let Defs = [CCR] in {
+  let Constraints = "$src = $dst" in {
+
+  def NAME#"8dd"  : MxSR_DD<MN, MxType8d,  NODE, RODI, ROOP>;
+  def NAME#"16dd" : MxSR_DD<MN, MxType16d, NODE, RODI, ROOP>;
+  def NAME#"32dd" : MxSR_DD<MN, MxType32d, NODE, RODI, ROOP>;
+
+  def NAME#"8di"  : MxSR_DI<MN, MxType8d,  NODE, RODI, ROOP>;
+  def NAME#"16di" : MxSR_DI<MN, MxType16d, NODE, RODI, ROOP>;
+  def NAME#"32di" : MxSR_DI<MN, MxType32d, NODE, RODI, ROOP>;
+
+  } // $src = $dst
+  } // Defs = [CCR]
+
+} // MxBiArOp_RF
+
+defm SHL : MxSROp<"lsl", shl, MxRODI_L, MxROOP_LS>;
+defm LSR : MxSROp<"lsr", srl, MxRODI_R, MxROOP_LS>;
+defm ASR : MxSROp<"asr", sra, MxRODI_R, MxROOP_AS>;
+
+defm ROL : MxSROp<"rol", rotl, MxRODI_L, MxROOP_RO>;
+defm ROR : MxSROp<"ror", rotr, MxRODI_R, MxROOP_RO>;

diff  --git a/llvm/lib/Target/M68k/M68kRegisterInfo.td b/llvm/lib/Target/M68k/M68kRegisterInfo.td
new file mode 100644
index 000000000000..76e762c718b0
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kRegisterInfo.td
@@ -0,0 +1,130 @@
+//== M68kRegisterInfo.td - M68k register definitions ----*- tablegen -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes the M68k Register file, defining the registers
+/// aliases between the registers, and the register classes built out of the
+/// registers.
+///
+//===----------------------------------------------------------------------===//
+
+class MxReg<string N, bits<16> ENC,
+            list<Register> SUBREGS = [], list<SubRegIndex> SUBIDX,
+            list<int> DWREGS = []>
+    : Register<N>, DwarfRegNum<DWREGS> {
+  let Namespace     = "M68k";
+  let HWEncoding    = ENC;
+  let SubRegs       = SUBREGS;
+  let SubRegIndices = SUBIDX;
+}
+
+// Subregister indices.
+let Namespace = "M68k" in {
+  def MxSubRegIndex8Lo  : SubRegIndex<8, 0>;
+  def MxSubRegIndex16Lo : SubRegIndex<16, 0>;
+}
+
+// Generate Data registers and theirs smaller variants
+foreach Index = 0-7 in {
+  def "BD"#Index : MxReg<"d"#Index, Index, [], [], [Index]>;
+
+  def "WD"#Index
+    : MxReg<"d"#Index, Index,
+            [!cast<Register>("BD"#Index)], [MxSubRegIndex8Lo],
+            [Index]>;
+
+  def "D"#Index
+    : MxReg<"d"#Index, Index,
+            [!cast<Register>("WD"#Index)], [MxSubRegIndex16Lo],
+            [Index]>;
+
+} // foreach
+
+// Generate Address registers and theirs smaller variants
+foreach Index = 0-7 in {
+  def "WA"#Index
+     : MxReg<"a"#Index, Index, [], [], [!add(8,Index)]>;
+
+  def "A"#Index
+     : MxReg<"a"#Index, Index,
+             [!cast<Register>("WA"#Index)], [MxSubRegIndex16Lo],
+             [!add(8,Index)]>;
+}
+
+// Alias Registers
+class MxAliasReg<string N, MxReg REG>
+    : MxReg<N, REG.HWEncoding, [], [], REG.DwarfNumbers> {
+  let Aliases = [REG];
+}
+
+def BP  : MxAliasReg<"bp",  A5>;
+def FP  : MxAliasReg<"fp",  A6>;
+def SP : MxAliasReg<"sp", A7>;
+
+def USP : MxAliasReg<"usp", A7>;
+def SSP : MxAliasReg<"ssp", A7>;
+def ISP : MxAliasReg<"isp", A7>;
+
+// Pseudo Registers
+class MxPseudoReg<string N, list<Register> SUBREGS = [], list<SubRegIndex> SUBIDX = []>
+    : MxReg<N, 0, SUBREGS, SUBIDX>;
+
+def CCR : MxPseudoReg<"ccr">;
+def SR  : MxPseudoReg<"sr">;
+
+def PC  : MxPseudoReg<"pc">;
+
+//===----------------------------------------------------------------------===//
+// Register Classes
+//===----------------------------------------------------------------------===//
+
+class MxRegClass<list<ValueType> regTypes, int alignment, dag regList>
+    : RegisterClass<"M68k", regTypes, alignment, regList>;
+
+// Data Registers
+def DR8  : MxRegClass<[i8],  16, (sequence "BD%u", 0, 7)>;
+def DR16 : MxRegClass<[i16], 16, (sequence "WD%u", 0, 7)>;
+def DR32 : MxRegClass<[i32], 32, (sequence "D%u",  0, 7)>;
+
+// Address Registers
+def AR16 : MxRegClass<[i16], 16, (sequence "WA%u", 0, 6)>;
+def AR32 : MxRegClass<[i32], 32, (add (sequence "A%u", 0, 6), SP)>;
+
+def AR32_NOSP : MxRegClass<[i32], 32, (add (sequence "A%u", 0, 6))>;
+
+// Index Register Classes
+// FIXME try alternative ordering like `D0, D1, A0, A1, ...`
+def XR16 : MxRegClass<[i16], 16, (add DR16, AR16)>;
+def XR32 : MxRegClass<[i32], 32, (add DR32, AR32)>;
+
+def SPC  : MxRegClass<[i32], 32, (add SP)>;
+
+let CopyCost = -1 in {
+  def CCRC : MxRegClass<[i8],  16, (add CCR)>;
+  def SRC  : MxRegClass<[i16], 16, (add SR)>;
+}
+
+let isAllocatable = 0 in {
+  def PCC  : MxRegClass<[i32], 32, (add PC)>;
+}
+
+// Register used with tail call
+def DR16_TC : MxRegClass<[i16], 16, (add D0, D1)>;
+def DR32_TC : MxRegClass<[i32], 32, (add D0, D1)>;
+
+def AR16_TC : MxRegClass<[i16], 16, (add A0, A1)>;
+def AR32_TC : MxRegClass<[i32], 32, (add A0, A1)>;
+
+def XR16_TC : MxRegClass<[i16], 16, (add DR16_TC, AR16_TC)>;
+def XR32_TC : MxRegClass<[i32], 32, (add DR32_TC, AR32_TC)>;
+
+// These classes provide spill/restore order if used with MOVEM instruction
+def SPILL   : MxRegClass<[i32], 32, (add (add (sequence "D%u", 0, 7),
+                                              (sequence "A%u", 0, 6)), SP)>;
+def SPILL_R : MxRegClass<[i32], 32, (add SP, (add (sequence "A%u", 6, 0),
+                                                  (sequence "D%u", 7, 0)))>;

diff  --git a/llvm/lib/Target/M68k/M68kSchedule.td b/llvm/lib/Target/M68k/M68kSchedule.td
new file mode 100644
index 000000000000..a94cd8f31e2e
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kSchedule.td
@@ -0,0 +1,23 @@
+//===-- M68kSchedule.td - M68k Scheduling Definitions --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains M68k scheduler definitions.
+///
+//===----------------------------------------------------------------------===//
+
+/// This is a very general M68k Scheduling Model and best suited for the very
+/// first M68000 CPU, other model must override these characteristics
+class M68kSchedModel : SchedMachineModel {
+  let LoadLatency = 4;  // Word (Rn)
+  let HighLatency = 16; // Long ABS
+  let PostRAScheduler = 0;
+  let CompleteModel = 0;
+}
+
+def GenericM68kModel : M68kSchedModel;

diff  --git a/llvm/lib/Target/M68k/M68kTargetMachine.cpp b/llvm/lib/Target/M68k/M68kTargetMachine.cpp
new file mode 100644
index 000000000000..a40ae10a832b
--- /dev/null
+++ b/llvm/lib/Target/M68k/M68kTargetMachine.cpp
@@ -0,0 +1,17 @@
+//===-- M68kTargetMachine.cpp - M68k target machine ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains implementation for M68k target machine.
+///
+//===----------------------------------------------------------------------===//
+
+/// This is just a placeholder to make current
+/// commit buildable. Body of this function will
+/// be filled in later commits
+extern "C" void LLVMInitializeM68kTarget() {}

diff  --git a/llvm/lib/Target/M68k/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/M68k/MCTargetDesc/CMakeLists.txt
new file mode 100644
index 000000000000..dadb6919d928
--- /dev/null
+++ b/llvm/lib/Target/M68k/MCTargetDesc/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_llvm_component_library(LLVMM68kDesc
+  M68kMCTargetDesc.cpp
+
+  LINK_COMPONENTS
+  MC
+  MCDisassembler
+  Support
+  M68kInfo
+
+  ADD_TO_COMPONENT
+  M68k
+)

diff  --git a/llvm/lib/Target/M68k/MCTargetDesc/M68kMCTargetDesc.cpp b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCTargetDesc.cpp
new file mode 100644
index 000000000000..7a1fe4580148
--- /dev/null
+++ b/llvm/lib/Target/M68k/MCTargetDesc/M68kMCTargetDesc.cpp
@@ -0,0 +1,17 @@
+//===-- M68kMCTargetDesc.cpp - M68k Target Descriptions -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file provides M68k target specific descriptions.
+///
+//===----------------------------------------------------------------------===//
+
+/// This is just a placeholder to make current
+/// commit buildable. Body of this function will
+/// be filled in later commits
+extern "C" void LLVMInitializeM68kTargetMC() {}

diff  --git a/llvm/lib/Target/M68k/TargetInfo/CMakeLists.txt b/llvm/lib/Target/M68k/TargetInfo/CMakeLists.txt
new file mode 100644
index 000000000000..d376dcd7d12b
--- /dev/null
+++ b/llvm/lib/Target/M68k/TargetInfo/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_llvm_component_library(LLVMM68kInfo
+  M68kTargetInfo.cpp
+
+  LINK_COMPONENTS
+  Support
+
+  ADD_TO_COMPONENT
+  M68k
+)

diff  --git a/llvm/lib/Target/M68k/TargetInfo/M68kTargetInfo.cpp b/llvm/lib/Target/M68k/TargetInfo/M68kTargetInfo.cpp
new file mode 100644
index 000000000000..faedeb1deadd
--- /dev/null
+++ b/llvm/lib/Target/M68k/TargetInfo/M68kTargetInfo.cpp
@@ -0,0 +1,17 @@
+//===-- M68kTargetInfo.cpp - M68k Target Implementation -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains M68k target initializer.
+///
+//===----------------------------------------------------------------------===//
+
+/// This is just a placeholder to make current
+/// commit buildable. Body of this function will
+/// be filled in later commits
+extern "C" void LLVMInitializeM68kTargetInfo() {}


        


More information about the llvm-commits mailing list