[llvm] c23a780 - [M68k][test](6/8) Add all of the tests
Min-Yih Hsu via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 8 12:33:54 PST 2021
Author: Min-Yih Hsu
Date: 2021-03-08T12:30:57-08:00
New Revision: c23a780c306c410008ab127009cda26c7d9e5966
URL: https://github.com/llvm/llvm-project/commit/c23a780c306c410008ab127009cda26c7d9e5966
DIFF: https://github.com/llvm/llvm-project/commit/c23a780c306c410008ab127009cda26c7d9e5966.diff
LOG: [M68k][test](6/8) Add all of the tests
And a small utilities -- extract-section.py -- that helps extracting
specific object file section and printing in textual format. This
utility is just a workaround for tests inside `Encoding`. Hopefully in
the future we can replace dependencies in those tests with existing tools
(e.g. llvm-readobj). Please refer to this bug for more context:
https://bugs.llvm.org/show_bug.cgi?id=49245
Note that since we don't have AsmParser for now, we are testing the MC
part using MIR as input and put those tests under the `Encoding` folder.
In the future when AsmParser (and disassembler) is finished, those tests
will be moved to `test/MC/M68k`.
Authors: myhsu, m4yers, glaubitz
Differential Revision: https://reviews.llvm.org/D88392
Added:
llvm/test/CodeGen/M68k/Alloc/dyn_alloca_aligned.ll
llvm/test/CodeGen/M68k/Arith/add-with-overflow.ll
llvm/test/CodeGen/M68k/Arith/add.ll
llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
llvm/test/CodeGen/M68k/Arith/imul-neg.ll
llvm/test/CodeGen/M68k/Arith/imul.ll
llvm/test/CodeGen/M68k/Arith/lshr.ll
llvm/test/CodeGen/M68k/Arith/mul64.ll
llvm/test/CodeGen/M68k/Arith/sdiv-exact.ll
llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
llvm/test/CodeGen/M68k/Arith/sub-with-overflow.ll
llvm/test/CodeGen/M68k/Arith/sub.ll
llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
llvm/test/CodeGen/M68k/CConv/c-args-inreg.ll
llvm/test/CodeGen/M68k/CConv/c-args.ll
llvm/test/CodeGen/M68k/CConv/c-call.ll
llvm/test/CodeGen/M68k/CConv/fastcc-args.ll
llvm/test/CodeGen/M68k/CConv/fastcc-call.ll
llvm/test/CodeGen/M68k/CodeModel/medium-pic.ll
llvm/test/CodeGen/M68k/CodeModel/medium-pie-global-access.ll
llvm/test/CodeGen/M68k/CodeModel/medium-pie.ll
llvm/test/CodeGen/M68k/CodeModel/medium-static.ll
llvm/test/CodeGen/M68k/CodeModel/small-pic.ll
llvm/test/CodeGen/M68k/CodeModel/small-pie-global-access.ll
llvm/test/CodeGen/M68k/CodeModel/small-pie.ll
llvm/test/CodeGen/M68k/CodeModel/small-static.ll
llvm/test/CodeGen/M68k/CollapseMOVEM.mir
llvm/test/CodeGen/M68k/Control/cmp.ll
llvm/test/CodeGen/M68k/Control/long-setcc.ll
llvm/test/CodeGen/M68k/Control/setcc.ll
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMI.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMR.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI_xEA.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRM.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRRF.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_EAd.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_xEA.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_BI.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_MI.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RI.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RM.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RR.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxDiMu.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxExt.mir
llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxNEG.mir
llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MI.mir
llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MR.mir
llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RI.mir
llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RR.mir
llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBRA.mir
llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBcc.mir
llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxCALL.mir
llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxJMP.mir
llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxNOP.mir
llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxRTS.mir
llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxScc.mir
llvm/test/CodeGen/M68k/Encoding/Control/branch-pc-rel.mir
llvm/test/CodeGen/M68k/Encoding/Control/call-pc-rel.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxLEA.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_MR.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_RM.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMoveCCR.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MI.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MM.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MR.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RI.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RM.mir
llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RR.mir
llvm/test/CodeGen/M68k/Encoding/README.md
llvm/test/CodeGen/M68k/Encoding/Relaxations/branch.mir
llvm/test/CodeGen/M68k/Encoding/Relocations/data-abs.mir
llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotoff.mir
llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotpcrel.mir
llvm/test/CodeGen/M68k/Encoding/Relocations/data-pc-rel.mir
llvm/test/CodeGen/M68k/Encoding/Relocations/text-plt.mir
llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DD.mir
llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DI.mir
llvm/test/CodeGen/M68k/lit.local.cfg
llvm/test/CodeGen/M68k/varargs.ll
llvm/utils/extract-section.py
Modified:
llvm/utils/UpdateTestChecks/asm.py
Removed:
################################################################################
diff --git a/llvm/test/CodeGen/M68k/Alloc/dyn_alloca_aligned.ll b/llvm/test/CodeGen/M68k/Alloc/dyn_alloca_aligned.ll
new file mode 100644
index 000000000000..7b0724c2f69a
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Alloc/dyn_alloca_aligned.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux-gnu -verify-machineinstrs | FileCheck %s
+define i32 @A(i32 %Size) {
+; CHECK-LABEL: A:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l %a6, -(%sp)
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: .cfi_offset %a6, -8
+; CHECK-NEXT: move.l %sp, %a6
+; CHECK-NEXT: .cfi_def_cfa_register %a6
+; CHECK-NEXT: move.l %sp, %d0
+; CHECK-NEXT: and.l #-128, %d0
+; CHECK-NEXT: move.l %d0, %sp
+; CHECK-NEXT: sub.l #128, %sp
+; CHECK-NEXT: move.l %sp, %a4
+; CHECK-NEXT: movem.l %a4, (116,%a4) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l (8,%a6), %d1
+; CHECK-NEXT: add.l #7, %d1
+; CHECK-NEXT: and.l #-8, %d1
+; CHECK-NEXT: move.l %sp, %d0
+; CHECK-NEXT: sub.l %d1, %d0
+; CHECK-NEXT: and.l #-128, %d0
+; CHECK-NEXT: move.l %d0, %sp
+; CHECK-NEXT: movem.l (116,%a4), %a4 ; 8-byte Folded Reload
+; CHECK-NEXT: move.l %a6, %sp
+; CHECK-NEXT: move.l (%sp)+, %a6
+; CHECK-NEXT: rts
+ %A = alloca i8, i32 %Size, align 128
+ %A_addr = ptrtoint i8* %A to i32
+ ret i32 %A_addr
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/add-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/add-with-overflow.ll
new file mode 100644
index 000000000000..0fd32b6c12ad
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/add-with-overflow.ll
@@ -0,0 +1,75 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)
+declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
+
+define fastcc i32 @test5(i32 %v1, i32 %v2, i32* %X) nounwind {
+; CHECK-LABEL: test5:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: add.l %d1, %d0
+; CHECK-NEXT: bvs .LBB0_2
+; CHECK-NEXT: ; %bb.1: ; %normal
+; CHECK-NEXT: move.l #0, (%a0)
+; CHECK-NEXT: .LBB0_2: ; %overflow
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %overflow, label %normal
+
+normal:
+ store i32 0, i32* %X
+ br label %overflow
+
+overflow:
+ ret i32 %sum
+}
+
+define fastcc i1 @test6(i32 %v1, i32 %v2, i32* %X) nounwind {
+; CHECK-LABEL: test6:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: add.l %d1, %d0
+; CHECK-NEXT: bcs .LBB1_2
+; CHECK-NEXT: ; %bb.1: ; %normal
+; CHECK-NEXT: move.l #0, (%a0)
+; CHECK-NEXT: .LBB1_2: ; %carry
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %carry, label %normal
+
+normal:
+ store i32 0, i32* %X
+ br label %carry
+
+carry:
+ ret i1 false
+}
+
+define {i32, i1} @test7(i32 %v1, i32 %v2) nounwind {
+; CHECK-LABEL: test7:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: add.l (8,%sp), %d0
+; CHECK-NEXT: scs %d1
+; CHECK-NEXT: rts
+ %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
+ ret {i32, i1} %t
+}
+
+define fastcc i1 @test10(i32 %x) nounwind {
+; CHECK-LABEL: test10:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: add.l #1, %d0
+; CHECK-NEXT: svs %d0
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
+ %obit = extractvalue {i32, i1} %t, 1
+ ret i1 %obit
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/add.ll b/llvm/test/CodeGen/M68k/Arith/add.ll
new file mode 100644
index 000000000000..75c560f9b4b0
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/add.ll
@@ -0,0 +1,95 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+define i64 @test1(i64 %A, i32 %B) nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l (12,%sp), %d0
+; CHECK-NEXT: add.l (4,%sp), %d0
+; CHECK-NEXT: move.l (8,%sp), %d1
+; CHECK-NEXT: rts
+ %tmp12 = zext i32 %B to i64
+ %tmp3 = shl i64 %tmp12, 32
+ %tmp5 = add i64 %tmp3, %A
+ ret i64 %tmp5
+}
+
+define void @test2(i32* inreg %a) nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l %d0, %a0
+; CHECK-NEXT: add.l #128, (%a0)
+; CHECK-NEXT: rts
+ %aa = load i32, i32* %a
+ %b = add i32 %aa, 128
+ store i32 %b, i32* %a
+ ret void
+}
+
+define fastcc void @test2_fast(i32* inreg %a) nounwind {
+; CHECK-LABEL: test2_fast:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: add.l #128, (%a0)
+; CHECK-NEXT: rts
+ %aa = load i32, i32* %a
+ %b = add i32 %aa, 128
+ store i32 %b, i32* %a
+ ret void
+}
+
+define fastcc void @test3(i64* inreg %a) nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: move.l #0, %d1
+; CHECK-NEXT: move.l #-2147483648, %d2
+; CHECK-NEXT: add.l (4,%a0), %d2
+; CHECK-NEXT: addx.l %d0, %d1
+; CHECK-NEXT: move.l %d2, (4,%a0)
+; CHECK-NEXT: move.l %d1, (%a0)
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+ %aa = load i64, i64* %a
+ %b = add i64 %aa, 2147483648
+ store i64 %b, i64* %a
+ ret void
+}
+
+define fastcc void @test4(i64* inreg %a) nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: move.l #0, %d1
+; CHECK-NEXT: move.l #128, %d2
+; CHECK-NEXT: add.l (4,%a0), %d2
+; CHECK-NEXT: addx.l %d0, %d1
+; CHECK-NEXT: move.l %d2, (4,%a0)
+; CHECK-NEXT: move.l %d1, (%a0)
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+ %aa = load i64, i64* %a
+ %b = add i64 %aa, 128
+ store i64 %b, i64* %a
+ ret void
+}
+
+define fastcc i32 @test9(i32 %x, i32 %y) nounwind readnone {
+; CHECK-LABEL: test9:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #10, %d0
+; CHECK-NEXT: seq %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: sub.l %d0, %d1
+; CHECK-NEXT: move.l %d1, %d0
+; CHECK-NEXT: rts
+ %cmp = icmp eq i32 %x, 10
+ %sub = sext i1 %cmp to i32
+ %cond = add i32 %sub, %y
+ ret i32 %cond
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll b/llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
new file mode 100644
index 000000000000..04114d97e457
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
@@ -0,0 +1,216 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+; TODO fold the shifts
+define zeroext i16 @test1(i16 zeroext %x) nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.w (6,%sp), %d0
+; CHECK-NEXT: mulu #-1985, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.w #5, %d0
+; CHECK-NEXT: and.l #65535, %d0
+; CHECK-NEXT: rts
+entry:
+ %div = udiv i16 %x, 33
+ ret i16 %div
+}
+
+define zeroext i16 @test2(i8 signext %x, i16 zeroext %c) {
+; CHECK-LABEL: test2:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.w (10,%sp), %d0
+; CHECK-NEXT: mulu #-21845, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.w #1, %d0
+; CHECK-NEXT: and.l #65535, %d0
+; CHECK-NEXT: rts
+entry:
+ %div = udiv i16 %c, 3
+ ret i16 %div
+}
+
+define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) {
+; CHECK-LABEL: test3:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.b (11,%sp), %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: mulu #-21845, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.w #1, %d0
+; CHECK-NEXT: and.l #65535, %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: rts
+entry:
+ %div = udiv i8 %c, 3
+ ret i8 %div
+}
+
+define signext i16 @test4(i16 signext %x) nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.w (10,%sp), %d0
+; CHECK-NEXT: muls #1986, %d0
+; CHECK-NEXT: asr.l #8, %d0
+; CHECK-NEXT: asr.l #8, %d0
+; CHECK-NEXT: move.w #15, %d1
+; CHECK-NEXT: move.w %d0, %d2
+; CHECK-NEXT: lsr.w %d1, %d2
+; CHECK-NEXT: add.w %d0, %d2
+; CHECK-NEXT: move.l %d2, %d0
+; CHECK-NEXT: ext.l %d0
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %div = sdiv i16 %x, 33 ; <i32> [#uses=1]
+ ret i16 %div
+}
+
+define i32 @test5(i32 %A) nounwind {
+; CHECK-LABEL: test5:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: move.l #1577682821, (4,%sp)
+; CHECK-NEXT: move.l (16,%sp), (%sp)
+; CHECK-NEXT: jsr __udivsi3
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+ %tmp1 = udiv i32 %A, 1577682821 ; <i32> [#uses=1]
+ ret i32 %tmp1
+}
+
+; TODO fold shift
+define signext i16 @test6(i16 signext %x) nounwind {
+; CHECK-LABEL: test6:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.w (10,%sp), %d0
+; CHECK-NEXT: muls #26215, %d0
+; CHECK-NEXT: asr.l #8, %d0
+; CHECK-NEXT: asr.l #8, %d0
+; CHECK-NEXT: move.w #15, %d1
+; CHECK-NEXT: move.w %d0, %d2
+; CHECK-NEXT: lsr.w %d1, %d2
+; CHECK-NEXT: asr.w #2, %d0
+; CHECK-NEXT: add.w %d2, %d0
+; CHECK-NEXT: ext.l %d0
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %div = sdiv i16 %x, 10
+ ret i16 %div
+}
+
+define i32 @test7(i32 %x) nounwind {
+; CHECK-LABEL: test7:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: move.l #28, (4,%sp)
+; CHECK-NEXT: move.l (16,%sp), (%sp)
+; CHECK-NEXT: jsr __udivsi3
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+ %div = udiv i32 %x, 28
+ ret i32 %div
+}
+
+define i8 @test8(i8 %x) nounwind {
+; CHECK-LABEL: test8:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.b (7,%sp), %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: lsr.w #1, %d0
+; CHECK-NEXT: mulu #26887, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.w #4, %d0
+; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $d0
+; CHECK-NEXT: rts
+ %div = udiv i8 %x, 78
+ ret i8 %div
+}
+
+define i8 @test9(i8 %x) nounwind {
+; CHECK-LABEL: test9:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.b (7,%sp), %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: mulu #18079, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.l #8, %d0
+; CHECK-NEXT: lsr.w #5, %d0
+; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $d0
+; CHECK-NEXT: rts
+ %div = udiv i8 %x, 116
+ ret i8 %div
+}
+
+define i32 @testsize1(i32 %x) minsize nounwind {
+; CHECK-LABEL: testsize1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l #31, %d1
+; CHECK-NEXT: move.l (8,%sp), %d2
+; CHECK-NEXT: move.l %d2, %d0
+; CHECK-NEXT: asr.l %d1, %d0
+; CHECK-NEXT: move.l #27, %d1
+; CHECK-NEXT: lsr.l %d1, %d0
+; CHECK-NEXT: add.l %d2, %d0
+; CHECK-NEXT: asr.l #5, %d0
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %div = sdiv i32 %x, 32
+ ret i32 %div
+}
+
+define i32 @testsize2(i32 %x) minsize nounwind {
+; CHECK-LABEL: testsize2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: move.l #33, (4,%sp)
+; CHECK-NEXT: move.l (16,%sp), (%sp)
+; CHECK-NEXT: jsr __divsi3
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+entry:
+ %div = sdiv i32 %x, 33
+ ret i32 %div
+}
+
+define i32 @testsize3(i32 %x) minsize nounwind {
+; CHECK-LABEL: testsize3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsr.l #5, %d0
+; CHECK-NEXT: rts
+entry:
+ %div = udiv i32 %x, 32
+ ret i32 %div
+}
+
+define i32 @testsize4(i32 %x) minsize nounwind {
+; CHECK-LABEL: testsize4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: move.l #33, (4,%sp)
+; CHECK-NEXT: move.l (16,%sp), (%sp)
+; CHECK-NEXT: jsr __udivsi3
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+entry:
+ %div = udiv i32 %x, 33
+ ret i32 %div
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/imul-neg.ll b/llvm/test/CodeGen/M68k/Arith/imul-neg.ll
new file mode 100644
index 000000000000..63b96309c1a6
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/imul-neg.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux | FileCheck %s
+; FIXME: When using SelectionDAGISel, the following cases use
+; `sub` rather than the expected `neg`
+
+define i32 @mul4294967295_32(i32 %A) {
+; CHECK-LABEL: mul4294967295_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: sub.l (4,%sp), %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 4294967295
+ ret i32 %mul
+}
+
+; NOTE: If returning a 64-bit integer, d0 will be the higher 32-bit!
+define i64 @mul18446744073709551615_64(i64 %A) {
+; CHECK-LABEL: mul18446744073709551615_64:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: move.l #0, %d1
+; CHECK-NEXT: sub.l (8,%sp), %d1
+; CHECK-NEXT: negx.l %d0
+; CHECK-NEXT: rts
+ %mul = mul i64 %A, 18446744073709551615
+ ret i64 %mul
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/imul.ll b/llvm/test/CodeGen/M68k/Arith/imul.ll
new file mode 100644
index 000000000000..2ded4c6eb935
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/imul.ll
@@ -0,0 +1,265 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux | FileCheck %s
+
+define i32 @mul4_32(i32 %A) {
+; CHECK-LABEL: mul4_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 4
+ ret i32 %mul
+}
+
+define i64 @mul4_64(i64 %A) {
+; CHECK-LABEL: mul4_64:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l #30, %d0
+; CHECK-NEXT: move.l (12,%sp), %d1
+; CHECK-NEXT: move.l %d1, %d2
+; CHECK-NEXT: lsr.l %d0, %d2
+; CHECK-NEXT: move.l (8,%sp), %d0
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: or.l %d2, %d0
+; CHECK-NEXT: lsl.l #2, %d1
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+ %mul = mul i64 %A, 4
+ ret i64 %mul
+}
+
+define i32 @mul4096_32(i32 %A) {
+; CHECK-LABEL: mul4096_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l #12, %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsl.l %d1, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 4096
+ ret i32 %mul
+}
+
+define i64 @mul4096_64(i64 %A) {
+; CHECK-LABEL: mul4096_64:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #8, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -12
+; CHECK-NEXT: movem.l %d2-%d3, (0,%sp) ; 12-byte Folded Spill
+; CHECK-NEXT: move.l #20, %d0
+; CHECK-NEXT: move.l (16,%sp), %d1
+; CHECK-NEXT: move.l %d1, %d2
+; CHECK-NEXT: lsr.l %d0, %d2
+; CHECK-NEXT: move.l #12, %d3
+; CHECK-NEXT: move.l (12,%sp), %d0
+; CHECK-NEXT: lsl.l %d3, %d0
+; CHECK-NEXT: or.l %d2, %d0
+; CHECK-NEXT: lsl.l %d3, %d1
+; CHECK-NEXT: movem.l (0,%sp), %d2-%d3 ; 12-byte Folded Reload
+; CHECK-NEXT: add.l #8, %sp
+; CHECK-NEXT: rts
+ %mul = mul i64 %A, 4096
+ ret i64 %mul
+}
+
+define i32 @mulmin4096_32(i32 %A) {
+; CHECK-LABEL: mulmin4096_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l #12, %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsl.l %d1, %d0
+; CHECK-NEXT: neg.l %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, -4096
+ ret i32 %mul
+}
+
+define i64 @mulmin4096_64(i64 %A) {
+; CHECK-LABEL: mulmin4096_64:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #8, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -12
+; CHECK-NEXT: movem.l %d2-%d3, (0,%sp) ; 12-byte Folded Spill
+; CHECK-NEXT: move.l #20, %d0
+; CHECK-NEXT: move.l (16,%sp), %d1
+; CHECK-NEXT: move.l %d1, %d2
+; CHECK-NEXT: lsr.l %d0, %d2
+; CHECK-NEXT: move.l #12, %d3
+; CHECK-NEXT: move.l (12,%sp), %d0
+; CHECK-NEXT: lsl.l %d3, %d0
+; CHECK-NEXT: or.l %d2, %d0
+; CHECK-NEXT: lsl.l %d3, %d1
+; CHECK-NEXT: neg.l %d1
+; CHECK-NEXT: negx.l %d0
+; CHECK-NEXT: movem.l (0,%sp), %d2-%d3 ; 12-byte Folded Reload
+; CHECK-NEXT: add.l #8, %sp
+; CHECK-NEXT: rts
+ %mul = mul i64 %A, -4096
+ ret i64 %mul
+}
+
+; No i32 multiply for M68000
+define i32 @mul_32(i32 %a, i32 %b) {
+; CHECK-LABEL: mul_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -16
+; CHECK-NEXT: move.l (20,%sp), (4,%sp)
+; CHECK-NEXT: move.l (16,%sp), (%sp)
+; CHECK-NEXT: jsr __mulsi3
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+ %mul = mul i32 %a, %b
+ ret i32 %mul
+}
+
+; Lower to shift and add if we can
+define i32 @mul3_32(i32 %A) {
+; CHECK-LABEL: mul3_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d1
+; CHECK-NEXT: move.l %d1, %d0
+; CHECK-NEXT: lsl.l #1, %d0
+; CHECK-NEXT: add.l %d1, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 3
+ ret i32 %mul
+}
+
+define i32 @mul40_32(i32 %A) {
+; CHECK-LABEL: mul40_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: lsl.l #3, %d1
+; CHECK-NEXT: lsl.l #5, %d0
+; CHECK-NEXT: add.l %d1, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 40
+ ret i32 %mul
+}
+
+; No i64 multiply for M68000
+define i64 @mul_64(i64 %a, i64 %b) {
+; CHECK-LABEL: mul_64:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -24
+; CHECK-NEXT: move.l (36,%sp), (12,%sp)
+; CHECK-NEXT: move.l (32,%sp), (8,%sp)
+; CHECK-NEXT: move.l (28,%sp), (4,%sp)
+; CHECK-NEXT: move.l (24,%sp), (%sp)
+; CHECK-NEXT: jsr __muldi3
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+ %mul = mul i64 %a, %b
+ ret i64 %mul
+}
+
+define i64 @mul3_64(i64 %A) {
+; CHECK-LABEL: mul3_64:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -24
+; CHECK-NEXT: move.l #3, (12,%sp)
+; CHECK-NEXT: move.l #0, (8,%sp)
+; CHECK-NEXT: move.l (28,%sp), (4,%sp)
+; CHECK-NEXT: move.l (24,%sp), (%sp)
+; CHECK-NEXT: jsr __muldi3
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+ %mul = mul i64 %A, 3
+ ret i64 %mul
+}
+
+define i64 @mul40_64(i64 %A) {
+; CHECK-LABEL: mul40_64:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -24
+; CHECK-NEXT: move.l #40, (12,%sp)
+; CHECK-NEXT: move.l #0, (8,%sp)
+; CHECK-NEXT: move.l (28,%sp), (4,%sp)
+; CHECK-NEXT: move.l (24,%sp), (%sp)
+; CHECK-NEXT: jsr __muldi3
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+ %mul = mul i64 %A, 40
+ ret i64 %mul
+}
+
+define i32 @mul4_32_minsize(i32 %A) minsize {
+; CHECK-LABEL: mul4_32_minsize:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 4
+ ret i32 %mul
+}
+
+define i32 @mul40_32_minsize(i32 %A) minsize {
+; CHECK-LABEL: mul40_32_minsize:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: lsl.l #3, %d1
+; CHECK-NEXT: lsl.l #5, %d0
+; CHECK-NEXT: add.l %d1, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 40
+ ret i32 %mul
+}
+
+define i32 @mul33_32(i32 %A) {
+; CHECK-LABEL: mul33_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d1
+; CHECK-NEXT: move.l %d1, %d0
+; CHECK-NEXT: lsl.l #5, %d0
+; CHECK-NEXT: add.l %d1, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 33
+ ret i32 %mul
+}
+
+define i32 @mul31_32(i32 %A) {
+; CHECK-LABEL: mul31_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d1
+; CHECK-NEXT: move.l %d1, %d0
+; CHECK-NEXT: lsl.l #5, %d0
+; CHECK-NEXT: sub.l %d1, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 31
+ ret i32 %mul
+}
+
+define i32 @mul0_32(i32 %A) {
+; CHECK-LABEL: mul0_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, 0
+ ret i32 %mul
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/lshr.ll b/llvm/test/CodeGen/M68k/Arith/lshr.ll
new file mode 100644
index 000000000000..1877cdfb8673
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/lshr.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux | FileCheck %s
+
+; Function Attrs: norecurse nounwind readnone
+define zeroext i1 @c_isspace(i32 %c) local_unnamed_addr #0 {
+; CHECK-LABEL: c_isspace:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d1
+; CHECK-NEXT: add.l #-9, %d1
+; CHECK-NEXT: and.l #16777215, %d1
+; CHECK-NEXT: move.l #8388639, %d0
+; CHECK-NEXT: lsr.l %d1, %d0
+; CHECK-NEXT: and.l #1, %d0
+; CHECK-NEXT: rts
+entry:
+ %switch.tableidx = add i32 %c, -9
+ %switch.cast = trunc i32 %switch.tableidx to i24
+ %switch.downshift = lshr i24 -8388577, %switch.cast
+ %0 = and i24 %switch.downshift, 1
+ %switch.masked = icmp ne i24 %0, 0
+ ret i1 %switch.masked
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/mul64.ll b/llvm/test/CodeGen/M68k/Arith/mul64.ll
new file mode 100644
index 000000000000..e21e17226a5d
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/mul64.ll
@@ -0,0 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+; Currenlty making the libcall is ok, x20 supports i32 mul/div which
+; yields saner expansion for i64 mul
+define i64 @foo(i64 %t, i64 %u) nounwind {
+; CHECK-LABEL: foo:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: move.l (36,%sp), (12,%sp)
+; CHECK-NEXT: move.l (32,%sp), (8,%sp)
+; CHECK-NEXT: move.l (28,%sp), (4,%sp)
+; CHECK-NEXT: move.l (24,%sp), (%sp)
+; CHECK-NEXT: jsr __muldi3
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+ %k = mul i64 %t, %u
+ ret i64 %k
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/sdiv-exact.ll b/llvm/test/CodeGen/M68k/Arith/sdiv-exact.ll
new file mode 100644
index 000000000000..e7e83c898df7
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/sdiv-exact.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=m68k-linux -verify-machineinstrs < %s | FileCheck %s
+
+define i32 @test1(i32 %x) {
+; CHECK-LABEL: test1:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -16
+; CHECK-NEXT: move.l #-1030792151, (4,%sp)
+; CHECK-NEXT: move.l (16,%sp), (%sp)
+; CHECK-NEXT: jsr __mulsi3
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+ %div = sdiv exact i32 %x, 25
+ ret i32 %div
+}
+
+define i32 @test2(i32 %x) {
+; CHECK-LABEL: test2:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -16
+; CHECK-NEXT: move.l (16,%sp), %d0
+; CHECK-NEXT: asr.l #3, %d0
+; CHECK-NEXT: move.l %d0, (%sp)
+; CHECK-NEXT: move.l #-1431655765, (4,%sp)
+; CHECK-NEXT: jsr __mulsi3
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+ %div = sdiv exact i32 %x, 24
+ ret i32 %div
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
new file mode 100644
index 000000000000..d3f54dfb2585
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
@@ -0,0 +1,139 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+declare i32 @printf(i8*, ...) nounwind
+declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
+declare { i63, i1 } @llvm.smul.with.overflow.i63(i63, i63)
+
+ at ok = internal constant [4 x i8] c"%d\0A\00"
+ at no = internal constant [4 x i8] c"no\0A\00"
+
+define fastcc i1 @test1(i32 %v1, i32 %v2) nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #28, %sp
+; CHECK-NEXT: movem.l %d2-%d3, (20,%sp) ; 12-byte Folded Spill
+; CHECK-NEXT: move.l %d1, (12,%sp)
+; CHECK-NEXT: move.l #31, %d2
+; CHECK-NEXT: asr.l %d2, %d1
+; CHECK-NEXT: move.l %d1, (8,%sp)
+; CHECK-NEXT: move.l %d0, (4,%sp)
+; CHECK-NEXT: asr.l %d2, %d0
+; CHECK-NEXT: move.l %d0, (%sp)
+; CHECK-NEXT: jsr __muldi3
+; CHECK-NEXT: move.l %d1, %d3
+; CHECK-NEXT: asr.l %d2, %d3
+; CHECK-NEXT: sub.l %d3, %d0
+; CHECK-NEXT: sne %d0
+; CHECK-NEXT: cmpi.b #0, %d0
+; CHECK-NEXT: beq .LBB0_1
+; CHECK-NEXT: ; %bb.2: ; %overflow
+; CHECK-NEXT: lea (no,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: bra .LBB0_3
+; CHECK-NEXT: .LBB0_1: ; %normal
+; CHECK-NEXT: move.l %d1, (4,%sp)
+; CHECK-NEXT: lea (ok,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #1, %d0
+; CHECK-NEXT: .LBB0_3: ; %overflow
+; CHECK-NEXT: movem.l (20,%sp), %d2-%d3 ; 12-byte Folded Reload
+; CHECK-NEXT: add.l #28, %sp
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %overflow, label %normal
+
+normal:
+ %t1 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
+ ret i1 true
+
+overflow:
+ %t2 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @no, i32 0, i32 0) ) nounwind
+ ret i1 false
+}
+
+define fastcc i1 @test2(i32 %v1, i32 %v2) nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #28, %sp
+; CHECK-NEXT: movem.l %d2-%d3, (20,%sp) ; 12-byte Folded Spill
+; CHECK-NEXT: move.l %d1, (12,%sp)
+; CHECK-NEXT: move.l #31, %d2
+; CHECK-NEXT: asr.l %d2, %d1
+; CHECK-NEXT: move.l %d1, (8,%sp)
+; CHECK-NEXT: move.l %d0, (4,%sp)
+; CHECK-NEXT: asr.l %d2, %d0
+; CHECK-NEXT: move.l %d0, (%sp)
+; CHECK-NEXT: jsr __muldi3
+; CHECK-NEXT: move.l %d1, %d3
+; CHECK-NEXT: asr.l %d2, %d3
+; CHECK-NEXT: sub.l %d3, %d0
+; CHECK-NEXT: sne %d0
+; CHECK-NEXT: sub.b #1, %d0
+; CHECK-NEXT: bne .LBB1_3
+; CHECK-NEXT: ; %bb.1: ; %overflow
+; CHECK-NEXT: lea (no,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: bra .LBB1_2
+; CHECK-NEXT: .LBB1_3: ; %normal
+; CHECK-NEXT: move.l %d1, (4,%sp)
+; CHECK-NEXT: lea (ok,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #1, %d0
+; CHECK-NEXT: .LBB1_2: ; %overflow
+; CHECK-NEXT: movem.l (20,%sp), %d2-%d3 ; 12-byte Folded Reload
+; CHECK-NEXT: add.l #28, %sp
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %overflow, label %normal
+
+overflow:
+ %t2 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @no, i32 0, i32 0) ) nounwind
+ ret i1 false
+
+normal:
+ %t1 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
+ ret i1 true
+}
+
+define i32 @test3(i32 %a, i32 %b) nounwind readnone {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (8,%sp), %d0
+; CHECK-NEXT: add.l (4,%sp), %d0
+; CHECK-NEXT: add.l %d0, %d0
+; CHECK-NEXT: rts
+entry:
+ %tmp0 = add i32 %b, %a
+ %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 2)
+ %tmp2 = extractvalue { i32, i1 } %tmp1, 0
+ ret i32 %tmp2
+}
+
+; Same as umul-with-overflow, we shouldn't fallback to
+; builtin here
+define i32 @test4(i32 %a, i32 %b) nounwind readnone {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (8,%sp), %d0
+; CHECK-NEXT: add.l (4,%sp), %d0
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: rts
+entry:
+ %tmp0 = add i32 %b, %a
+ %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 4)
+ %tmp2 = extractvalue { i32, i1 } %tmp1, 0
+ ret i32 %tmp2
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/sub-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/sub-with-overflow.ll
new file mode 100644
index 000000000000..5cd7458c357d
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/sub-with-overflow.ll
@@ -0,0 +1,96 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+declare i32 @printf(i8*, ...) nounwind
+declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32)
+declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32)
+
+ at ok = internal constant [4 x i8] c"%d\0A\00"
+ at no = internal constant [4 x i8] c"no\0A\00"
+
+define i1 @func1(i32 %v1, i32 %v2) nounwind {
+; CHECK-LABEL: func1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: move.l (16,%sp), %d0
+; CHECK-NEXT: sub.l (20,%sp), %d0
+; CHECK-NEXT: bvc .LBB0_1
+; CHECK-NEXT: ; %bb.2: ; %overflow
+; CHECK-NEXT: lea (no,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB0_1: ; %normal
+; CHECK-NEXT: move.l %d0, (4,%sp)
+; CHECK-NEXT: lea (ok,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #1, %d0
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %overflow, label %normal
+
+normal:
+ %t1 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
+ ret i1 true
+
+overflow:
+ %t2 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @no, i32 0, i32 0) ) nounwind
+ ret i1 false
+}
+
+define i1 @func2(i32 %v1, i32 %v2) nounwind {
+; CHECK-LABEL: func2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: move.l (16,%sp), %d0
+; CHECK-NEXT: sub.l (20,%sp), %d0
+; CHECK-NEXT: bcc .LBB1_1
+; CHECK-NEXT: ; %bb.2: ; %carry
+; CHECK-NEXT: lea (no,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB1_1: ; %normal
+; CHECK-NEXT: move.l %d0, (4,%sp)
+; CHECK-NEXT: lea (ok,%pc), %a0
+; CHECK-NEXT: move.l %a0, (%sp)
+; CHECK-NEXT: jsr printf
+; CHECK-NEXT: move.b #1, %d0
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
+ %sum = extractvalue {i32, i1} %t, 0
+ %obit = extractvalue {i32, i1} %t, 1
+ br i1 %obit, label %carry, label %normal
+
+normal:
+ %t1 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
+ ret i1 true
+
+carry:
+ %t2 = tail call i32 (i8*, ...) @printf( i8* getelementptr ([4 x i8], [4 x i8]* @no, i32 0, i32 0) ) nounwind
+ ret i1 false
+}
+
+define i1 @func3(i32 %x) nounwind {
+; CHECK-LABEL: func3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #-1, %d0
+; CHECK-NEXT: add.l (4,%sp), %d0
+; CHECK-NEXT: svs %d0
+; CHECK-NEXT: rts
+entry:
+ %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %x, i32 1)
+ %obit = extractvalue {i32, i1} %t, 1
+ ret i1 %obit
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/sub.ll b/llvm/test/CodeGen/M68k/Arith/sub.ll
new file mode 100644
index 000000000000..fff3601000df
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/sub.ll
@@ -0,0 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=m68k-linux < %s -verify-machineinstrs | FileCheck %s
+
+define i32 @test1(i32 %x) {
+; CHECK-LABEL: test1:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d1
+; CHECK-NEXT: eori.l #31, %d1
+; CHECK-NEXT: move.l #32, %d0
+; CHECK-NEXT: sub.l %d1, %d0
+; CHECK-NEXT: rts
+ %xor = xor i32 %x, 31
+ %sub = sub i32 32, %xor
+ ret i32 %sub
+}
diff --git a/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll b/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
new file mode 100644
index 000000000000..98f43e2a9385
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/umul-with-overflow.ll
@@ -0,0 +1,52 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux-gnu -verify-machineinstrs | FileCheck %s
+
+declare {i32, i1} @llvm.umul.with.overflow.i32(i32 %a, i32 %b)
+
+define i1 @a(i32 %x) nounwind {
+; CHECK-LABEL: a:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: move.l #3, (12,%sp)
+; CHECK-NEXT: move.l #0, (8,%sp)
+; CHECK-NEXT: move.l (24,%sp), (4,%sp)
+; CHECK-NEXT: move.l #0, (%sp)
+; CHECK-NEXT: jsr __muldi3
+; CHECK-NEXT: cmpi.l #0, %d0
+; CHECK-NEXT: sne %d0
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+ %res = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %x, i32 3)
+ %obil = extractvalue {i32, i1} %res, 1
+ ret i1 %obil
+}
+
+define i32 @test2(i32 %a, i32 %b) nounwind readnone {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (8,%sp), %d0
+; CHECK-NEXT: add.l (4,%sp), %d0
+; CHECK-NEXT: add.l %d0, %d0
+; CHECK-NEXT: rts
+entry:
+ %tmp0 = add i32 %b, %a
+ %tmp1 = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %tmp0, i32 2)
+ %tmp2 = extractvalue { i32, i1 } %tmp1, 0
+ ret i32 %tmp2
+}
+
+; It shouldn't fallback to builtin in this scenario
+; Since we don't need the overflow bit here
+define i32 @test3(i32 %a, i32 %b) nounwind readnone {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (8,%sp), %d0
+; CHECK-NEXT: add.l (4,%sp), %d0
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: rts
+entry:
+ %tmp0 = add i32 %b, %a
+ %tmp1 = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %tmp0, i32 4)
+ %tmp2 = extractvalue { i32, i1 } %tmp1, 0
+ ret i32 %tmp2
+}
diff --git a/llvm/test/CodeGen/M68k/CConv/c-args-inreg.ll b/llvm/test/CodeGen/M68k/CConv/c-args-inreg.ll
new file mode 100644
index 000000000000..5eee426462cf
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CConv/c-args-inreg.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-pc-linux -relocation-model=pic -verify-machineinstrs | FileCheck %s
+
+;
+; Pass first two arguments in registers %d0 and %d1
+
+define void @foo_inreg(i32* nocapture inreg %out, i32 inreg %in) nounwind {
+; CHECK-LABEL: foo_inreg:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l %d0, %a0
+; CHECK-NEXT: move.l %d1, (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32 %in, i32* %out, align 4
+ ret void
+}
+
+define void @bar_inreg(i32* nocapture inreg %pOut, i32* nocapture inreg %pIn) nounwind {
+; CHECK-LABEL: bar_inreg:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l %d1, %a0
+; CHECK-NEXT: move.l %d0, %a1
+; CHECK-NEXT: move.l (%a0), (%a1)
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* %pIn, align 4
+ store i32 %0, i32* %pOut, align 4
+ ret void
+}
diff --git a/llvm/test/CodeGen/M68k/CConv/c-args.ll b/llvm/test/CodeGen/M68k/CConv/c-args.ll
new file mode 100644
index 000000000000..c5477e2812ca
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CConv/c-args.ll
@@ -0,0 +1,73 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-pc-linux -relocation-model=pic -verify-machineinstrs | FileCheck %s
+
+;
+; C Call passes all arguments on stack ...
+
+define void @test1(i32* nocapture %out, i32 %in) nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %a0
+; CHECK-NEXT: move.l (8,%sp), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32 %in, i32* %out, align 4
+ ret void
+}
+
+define void @test2(i32* nocapture %pOut, i32* nocapture %pIn) nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (8,%sp), %a0
+; CHECK-NEXT: move.l (4,%sp), %a1
+; CHECK-NEXT: move.l (%a0), (%a1)
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* %pIn, align 4
+ store i32 %0, i32* %pOut, align 4
+ ret void
+}
+
+define void @test3(i8* nocapture %out, i8 %in) nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %a0
+; CHECK-NEXT: move.b (11,%sp), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i8 %in, i8* %out, align 1
+ ret void
+}
+
+define void @test4(i16* nocapture %out, i16 %in) nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %a0
+; CHECK-NEXT: move.w (10,%sp), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i16 %in, i16* %out, align 2
+ ret void
+}
+
+define i8 @test5(i8 %a, i8 %b) nounwind {
+; CHECK-LABEL: test5:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.b (7,%sp), %d0
+; CHECK-NEXT: add.b (11,%sp), %d0
+; CHECK-NEXT: rts
+entry:
+ %add = add i8 %a, %b
+ ret i8 %add
+}
+
+define i16 @test6(i16 %a, i16 %b) nounwind {
+; CHECK-LABEL: test6:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.w (6,%sp), %d0
+; CHECK-NEXT: add.w (10,%sp), %d0
+; CHECK-NEXT: rts
+entry:
+ %add = add i16 %a, %b
+ ret i16 %add
+}
diff --git a/llvm/test/CodeGen/M68k/CConv/c-call.ll b/llvm/test/CodeGen/M68k/CConv/c-call.ll
new file mode 100644
index 000000000000..a97f96c3ca90
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CConv/c-call.ll
@@ -0,0 +1,65 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-pc-linux -relocation-model=pic -verify-machineinstrs | FileCheck %s
+
+;
+; Pass all arguments on the stack in reverse order
+
+define i32 @test1() nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: move.l #5, (16,%sp)
+; CHECK-NEXT: move.l #4, (12,%sp)
+; CHECK-NEXT: move.l #3, (8,%sp)
+; CHECK-NEXT: move.l #2, (4,%sp)
+; CHECK-NEXT: move.l #1, (%sp)
+; CHECK-NEXT: jsr (test1_callee at PLT,%pc)
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+entry:
+ call void @test1_callee(i32 1, i32 2, i32 3, i32 4, i32 5) nounwind
+ ret i32 0
+}
+
+declare void @test1_callee(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e);
+
+define i16 @test2() nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: move.l #5, (16,%sp)
+; CHECK-NEXT: move.l #4, (12,%sp)
+; CHECK-NEXT: move.l #3, (8,%sp)
+; CHECK-NEXT: move.l #2, (4,%sp)
+; CHECK-NEXT: move.l #1, (%sp)
+; CHECK-NEXT: jsr (test2_callee at PLT,%pc)
+; CHECK-NEXT: move.w #0, %d0
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+entry:
+ call void @test2_callee(i16 1, i16 2, i16 3, i16 4, i16 5) nounwind
+ ret i16 0
+}
+
+declare void @test2_callee(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e);
+
+define i8 @test3() nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: move.l #5, (16,%sp)
+; CHECK-NEXT: move.l #4, (12,%sp)
+; CHECK-NEXT: move.l #3, (8,%sp)
+; CHECK-NEXT: move.l #2, (4,%sp)
+; CHECK-NEXT: move.l #1, (%sp)
+; CHECK-NEXT: jsr (test3_callee at PLT,%pc)
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+entry:
+ call void @test3_callee(i8 1, i8 2, i8 3, i8 4, i8 5) nounwind
+ ret i8 0
+}
+
+declare void @test3_callee(i8 %a, i8 %b, i8 %c, i8 %d, i8 %e);
diff --git a/llvm/test/CodeGen/M68k/CConv/fastcc-args.ll b/llvm/test/CodeGen/M68k/CConv/fastcc-args.ll
new file mode 100644
index 000000000000..55c0b9f449e7
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CConv/fastcc-args.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-pc-linux -relocation-model=pic -verify-machineinstrs | FileCheck %s
+
+;
+; C Call passes all arguments on stack ...
+define fastcc void @test1(i32* nocapture %out, i32 %in) nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l %d0, (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32 %in, i32* %out, align 4
+ ret void
+}
+
+define fastcc void @test2(i32* nocapture %pOut, i32* nocapture %pIn) nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (%a1), (%a0)
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* %pIn, align 4
+ store i32 %0, i32* %pOut, align 4
+ ret void
+}
+
+define fastcc i32 @test3(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: add.l %d1, %d0
+; CHECK-NEXT: add.l %a0, %d0
+; CHECK-NEXT: add.l %a1, %d0
+; CHECK-NEXT: add.l (4,%sp), %d0
+; CHECK-NEXT: rts
+ %1 = add i32 %a, %b
+ %2 = add i32 %1, %c
+ %3 = add i32 %2, %d
+ %4 = add i32 %3, %e
+ ret i32 %4
+}
diff --git a/llvm/test/CodeGen/M68k/CConv/fastcc-call.ll b/llvm/test/CodeGen/M68k/CConv/fastcc-call.ll
new file mode 100644
index 000000000000..42f105cc6b08
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CConv/fastcc-call.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-pc-linux -relocation-model=pic -verify-machineinstrs | FileCheck %s
+
+;
+; Pass first 4 arguments in registers %d0,%d1,%a0,%a1 the rest goes onto stack
+
+define i32 @foo1() nounwind uwtable {
+; CHECK-LABEL: foo1:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: move.l #5, (%sp)
+; CHECK-NEXT: move.l #1, %d0
+; CHECK-NEXT: move.l #2, %d1
+; CHECK-NEXT: move.l #3, %a0
+; CHECK-NEXT: move.l #4, %a1
+; CHECK-NEXT: jsr (bar1 at PLT,%pc)
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ call fastcc void @bar1(i32 1, i32 2, i32 3, i32 4, i32 5) nounwind
+ ret i32 0
+}
+
+declare fastcc void @bar1(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e);
+;
+; Pass pointers in %a registers if there are any free left
+define i32 @foo2() nounwind uwtable {
+; CHECK-LABEL: foo2:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #12, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -16
+; CHECK-NEXT: lea (8,%sp), %a0
+; CHECK-NEXT: move.l #2, %d0
+; CHECK-NEXT: lea (4,%sp), %a1
+; CHECK-NEXT: move.l #4, %d1
+; CHECK-NEXT: jsr (bar2 at PLT,%pc)
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: add.l #12, %sp
+; CHECK-NEXT: rts
+entry:
+ %a = alloca i32, align 4
+ %b = alloca i32, align 4
+ call fastcc void @bar2(i32* %a, i32 2, i32* %b, i32 4) nounwind
+ ret i32 0
+}
+
+declare fastcc void @bar2(i32* %a, i32 %b, i32* %c, i32 %d);
diff --git a/llvm/test/CodeGen/M68k/CodeModel/medium-pic.ll b/llvm/test/CodeGen/M68k/CodeModel/medium-pic.ll
new file mode 100644
index 000000000000..2a7cdea33bcb
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/medium-pic.ll
@@ -0,0 +1,195 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O2 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=medium -relocation-model=pic \
+; RUN: | FileCheck %s
+
+ at ptr = external global i32*
+ at dst = external global i32
+ at src = external global i32
+
+define void @test0() nounwind {
+; CHECK-LABEL: test0:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (dst at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (ptr at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l (%a1), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst, i32** @ptr
+ %tmp.s = load i32, i32* @src
+ store i32 %tmp.s, i32* @dst
+ ret void
+}
+
+ at ptr2 = global i32* null
+ at dst2 = global i32 0
+ at src2 = global i32 0
+
+define void @test1() nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (dst2 at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (ptr2 at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src2 at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l (%a1), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst2, i32** @ptr2
+ %tmp.s = load i32, i32* @src2
+ store i32 %tmp.s, i32* @dst2
+ ret void
+}
+
+declare i8* @malloc(i32)
+
+define void @test2() nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: move.l #40, (%sp)
+; CHECK-NEXT: jsr (malloc at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %ptr = call i8* @malloc(i32 40)
+ ret void
+}
+
+ at pfoo = external global void(...)*
+declare void(...)* @afoo(...)
+
+define void @test3() nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr (afoo at PLT,%pc)
+; CHECK-NEXT: move.l %d0, %a0
+; CHECK-NEXT: move.l (pfoo at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: jsr (%a0)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %tmp = call void(...)*(...) @afoo()
+ store void(...)* %tmp, void(...)** @pfoo
+ %tmp1 = load void(...)*, void(...)** @pfoo
+ call void(...) %tmp1()
+ ret void
+}
+
+declare void @foo(...)
+
+define void @test4() nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr (foo at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ call void(...) @foo()
+ ret void
+}
+
+ at ptr6 = internal global i32* null
+ at dst6 = internal global i32 0
+ at src6 = internal global i32 0
+
+define void @test5() nounwind {
+; CHECK-LABEL: test5:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (_GLOBAL_OFFSET_TABLE_ at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l %a0, %a1
+; CHECK-NEXT: add.l #dst6 at GOTOFF, %a1
+; CHECK-NEXT: move.l #ptr6 at GOTOFF, %d0
+; CHECK-NEXT: move.l %a1, (0,%a0,%d0)
+; CHECK-NEXT: move.l #src6 at GOTOFF, %d0
+; CHECK-NEXT: move.l #dst6 at GOTOFF, %d1
+; CHECK-NEXT: move.l (0,%a0,%d0), (0,%a0,%d1)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst6, i32** @ptr6
+ %tmp.s = load i32, i32* @src6
+ store i32 %tmp.s, i32* @dst6
+ ret void
+}
+
+define void @test7(i32 %n.u) nounwind {
+; CHECK-LABEL: test7:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: add.l #-1, %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: sub.l #12, %d1
+; CHECK-NEXT: bhi .LBB6_12
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: lea (_GLOBAL_OFFSET_TABLE_ at GOTPCREL,%pc), %a0
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: move.l %a0, %a1
+; CHECK-NEXT: add.l #.LJTI6_0 at GOTOFF, %a1
+; CHECK-NEXT: add.l (0,%a1,%d0), %a0
+; CHECK-NEXT: jmp (%a0)
+; CHECK-NEXT: .LBB6_12: ; %bb2
+; CHECK-NEXT: bra foo6 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_3: ; %bb6
+; CHECK-NEXT: bra foo1 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_8: ; %bb1
+; CHECK-NEXT: bra foo2 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_9: ; %bb3
+; CHECK-NEXT: bra foo3 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_10: ; %bb4
+; CHECK-NEXT: bra foo4 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_14: ; %bb11
+; CHECK-NEXT: bra foo5 at PLT ; TAILCALL
+entry:
+ switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]
+bb:
+ tail call void(...) @foo1()
+ ret void
+bb1:
+ tail call void(...) @foo2()
+ ret void
+bb2:
+ tail call void(...) @foo6()
+ ret void
+bb3:
+ tail call void(...) @foo3()
+ ret void
+bb4:
+ tail call void(...) @foo4()
+ ret void
+bb5:
+ tail call void(...) @foo5()
+ ret void
+bb6:
+ tail call void(...) @foo1()
+ ret void
+bb7:
+ tail call void(...) @foo2()
+ ret void
+bb8:
+ tail call void(...) @foo6()
+ ret void
+bb9:
+ tail call void(...) @foo3()
+ ret void
+bb10:
+ tail call void(...) @foo4()
+ ret void
+bb11:
+ tail call void(...) @foo5()
+ ret void
+bb12:
+ tail call void(...) @foo6()
+ ret void
+}
+
+declare void @foo1(...)
+declare void @foo2(...)
+declare void @foo6(...)
+declare void @foo3(...)
+declare void @foo4(...)
+declare void @foo5(...)
diff --git a/llvm/test/CodeGen/M68k/CodeModel/medium-pie-global-access.ll b/llvm/test/CodeGen/M68k/CodeModel/medium-pie-global-access.ll
new file mode 100644
index 000000000000..38a65105ffaa
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/medium-pie-global-access.ll
@@ -0,0 +1,131 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O2 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=medium -relocation-model=pic \
+; RUN: | FileCheck %s
+
+; External Linkage
+ at a = global i32 0, align 4
+
+define i32 @my_access_global_a() #0 {
+; CHECK-LABEL: my_access_global_a:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (a at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @a, align 4
+ ret i32 %0
+}
+
+; WeakAny Linkage
+ at b = weak global i32 0, align 4
+
+define i32 @my_access_global_b() #0 {
+; CHECK-LABEL: my_access_global_b:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (b at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @b, align 4
+ ret i32 %0
+}
+
+; Internal Linkage
+ at c = internal global i32 0, align 4
+
+define i32 @my_access_global_c() #0 {
+; CHECK-LABEL: my_access_global_c:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (_GLOBAL_OFFSET_TABLE_ at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l #c at GOTOFF, %d0
+; CHECK-NEXT: move.l (0,%a0,%d0), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @c, align 4
+ ret i32 %0
+}
+
+; External Linkage, only declaration.
+ at d = external global i32, align 4
+
+define i32 @my_access_global_load_d() #0 {
+; CHECK-LABEL: my_access_global_load_d:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (d at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @d, align 4
+ ret i32 %0
+}
+
+; External Linkage, only declaration, store a value.
+define i32 @my_access_global_store_d() #0 {
+; CHECK-LABEL: my_access_global_store_d:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (d at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l #2, (%a0)
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+entry:
+ store i32 2, i32* @d, align 4
+ ret i32 0
+}
+
+; External Linkage, function pointer access.
+declare i32 @access_fp(i32 ()*)
+declare i32 @foo()
+
+define i32 @my_access_fp_foo() #0 {
+; CHECK-LABEL: my_access_fp_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: move.l (foo at GOTPCREL,%pc), (%sp)
+; CHECK-NEXT: jsr (access_fp at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %call = call i32 @access_fp(i32 ()* @foo)
+ ret i32 %call
+}
+
+; LinkOnceODR Linkage, function pointer access.
+
+$bar = comdat any
+
+define linkonce_odr i32 @bar() comdat {
+; CHECK-LABEL: bar:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+entry:
+ ret i32 0
+}
+
+define i32 @my_access_fp_bar() #0 {
+; CHECK-LABEL: my_access_fp_bar:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: move.l (bar at GOTPCREL,%pc), (%sp)
+; CHECK-NEXT: jsr (access_fp at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %call = call i32 @access_fp(i32 ()* @bar)
+ ret i32 %call
+}
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"PIC Level", i32 1}
+!1 = !{i32 1, !"PIE Level", i32 1}
diff --git a/llvm/test/CodeGen/M68k/CodeModel/medium-pie.ll b/llvm/test/CodeGen/M68k/CodeModel/medium-pie.ll
new file mode 100644
index 000000000000..ee5301618cf4
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/medium-pie.ll
@@ -0,0 +1,66 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O0 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=medium -relocation-model=pic \
+; RUN: | FileCheck %s
+
+define weak void @weak_foo() {
+; CHECK-LABEL: weak_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+define weak_odr void @weak_odr_foo() {
+; CHECK-LABEL: weak_odr_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+define internal void @internal_foo() {
+; CHECK-LABEL: internal_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+declare i32 @ext_baz()
+
+define void @foo() {
+; CHECK-LABEL: foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+define void @bar() {
+; CHECK-LABEL: bar:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: jsr (foo at PLT,%pc)
+; CHECK-NEXT: jsr (weak_odr_foo at PLT,%pc)
+; CHECK-NEXT: jsr (weak_foo at PLT,%pc)
+; CHECK-NEXT: jsr (internal_foo,%pc)
+; CHECK-NEXT: jsr (ext_baz at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ call void @foo()
+ call void @weak_odr_foo()
+ call void @weak_foo()
+ call void @internal_foo()
+ call i32 @ext_baz()
+ ret void
+}
+
+; -fpie for local global data tests should be added here
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"PIC Level", i32 1}
+!1 = !{i32 1, !"PIE Level", i32 1}
diff --git a/llvm/test/CodeGen/M68k/CodeModel/medium-static.ll b/llvm/test/CodeGen/M68k/CodeModel/medium-static.ll
new file mode 100644
index 000000000000..695fa94ca09b
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/medium-static.ll
@@ -0,0 +1,181 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O2 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=medium -relocation-model=static \
+; RUN: | FileCheck %s
+
+ at ptr = external global i32*
+ at dst = external global i32
+ at src = external global i32
+
+define void @test0() nounwind {
+; CHECK-LABEL: test0:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #dst, ptr
+; CHECK-NEXT: move.l src, dst
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst, i32** @ptr
+ %tmp.s = load i32, i32* @src
+ store i32 %tmp.s, i32* @dst
+ ret void
+}
+
+ at ptr2 = global i32* null
+ at dst2 = global i32 0
+ at src2 = global i32 0
+
+define void @test1() nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #dst2, ptr2
+; CHECK-NEXT: move.l src2, dst2
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst2, i32** @ptr2
+ %tmp.s = load i32, i32* @src2
+ store i32 %tmp.s, i32* @dst2
+ ret void
+}
+
+declare i8* @malloc(i32)
+
+define void @test2() nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: move.l #40, (%sp)
+; CHECK-NEXT: jsr malloc at PLT
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %ptr = call i8* @malloc(i32 40)
+ ret void
+}
+
+ at pfoo = external global void(...)*
+declare void(...)* @afoo(...)
+
+
+define void @test3() nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr afoo at PLT
+; CHECK-NEXT: move.l %d0, %a0
+; CHECK-NEXT: move.l %a0, pfoo
+; CHECK-NEXT: jsr (%a0)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %tmp = call void(...)*(...) @afoo()
+ store void(...)* %tmp, void(...)** @pfoo
+ %tmp1 = load void(...)*, void(...)** @pfoo
+ call void(...) %tmp1()
+ ret void
+}
+
+declare void @foo(...)
+
+define void @test4() nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr foo at PLT
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ call void(...) @foo()
+ ret void
+}
+
+ at ptr6 = internal global i32* null
+ at dst6 = internal global i32 0
+ at src6 = internal global i32 0
+
+define void @test5() nounwind {
+; CHECK-LABEL: test5:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #dst6, ptr6
+; CHECK-NEXT: move.l src6, dst6
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst6, i32** @ptr6
+ %tmp.s = load i32, i32* @src6
+ store i32 %tmp.s, i32* @dst6
+ ret void
+}
+
+define void @test7(i32 %n.u) nounwind {
+; CHECK-LABEL: test7:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: add.l #-1, %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: sub.l #12, %d1
+; CHECK-NEXT: bhi .LBB6_12
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: move.l #.LJTI6_0, %a0
+; CHECK-NEXT: move.l (0,%a0,%d0), %a0
+; CHECK-NEXT: jmp (%a0)
+; CHECK-NEXT: .LBB6_12: ; %bb2
+; CHECK-NEXT: bra foo6 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_3: ; %bb6
+; CHECK-NEXT: bra foo1 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_8: ; %bb1
+; CHECK-NEXT: bra foo2 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_9: ; %bb3
+; CHECK-NEXT: bra foo3 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_10: ; %bb4
+; CHECK-NEXT: bra foo4 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_14: ; %bb11
+; CHECK-NEXT: bra foo5 at PLT ; TAILCALL
+entry:
+ switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]
+bb:
+ tail call void(...) @foo1()
+ ret void
+bb1:
+ tail call void(...) @foo2()
+ ret void
+bb2:
+ tail call void(...) @foo6()
+ ret void
+bb3:
+ tail call void(...) @foo3()
+ ret void
+bb4:
+ tail call void(...) @foo4()
+ ret void
+bb5:
+ tail call void(...) @foo5()
+ ret void
+bb6:
+ tail call void(...) @foo1()
+ ret void
+bb7:
+ tail call void(...) @foo2()
+ ret void
+bb8:
+ tail call void(...) @foo6()
+ ret void
+bb9:
+ tail call void(...) @foo3()
+ ret void
+bb10:
+ tail call void(...) @foo4()
+ ret void
+bb11:
+ tail call void(...) @foo5()
+ ret void
+bb12:
+ tail call void(...) @foo6()
+ ret void
+}
+
+declare void @foo1(...)
+declare void @foo2(...)
+declare void @foo6(...)
+declare void @foo3(...)
+declare void @foo4(...)
+declare void @foo5(...)
diff --git a/llvm/test/CodeGen/M68k/CodeModel/small-pic.ll b/llvm/test/CodeGen/M68k/CodeModel/small-pic.ll
new file mode 100644
index 000000000000..a479abcdf57c
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/small-pic.ll
@@ -0,0 +1,189 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O2 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=small -relocation-model=pic \
+; RUN: | FileCheck %s
+
+ at ptr = external global i32*
+ at dst = external global i32
+ at src = external global i32
+
+define void @test0() nounwind {
+; CHECK-LABEL: test0:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (dst at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (ptr at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l (%a1), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst, i32** @ptr
+ %tmp.s = load i32, i32* @src
+ store i32 %tmp.s, i32* @dst
+ ret void
+}
+
+ at ptr2 = global i32* null
+ at dst2 = global i32 0
+ at src2 = global i32 0
+
+define void @test1() nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (dst2 at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (ptr2 at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src2 at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l (%a1), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst2, i32** @ptr2
+ %tmp.s = load i32, i32* @src2
+ store i32 %tmp.s, i32* @dst2
+ ret void
+}
+
+declare i8* @malloc(i32)
+
+define void @test2() nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: move.l #40, (%sp)
+; CHECK-NEXT: jsr (malloc at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %ptr = call i8* @malloc(i32 40)
+ ret void
+}
+
+ at pfoo = external global void(...)*
+declare void(...)* @afoo(...)
+
+define void @test3() nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr (afoo at PLT,%pc)
+; CHECK-NEXT: move.l %d0, %a0
+; CHECK-NEXT: move.l (pfoo at GOTPCREL,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: jsr (%a0)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %tmp = call void(...)*(...) @afoo()
+ store void(...)* %tmp, void(...)** @pfoo
+ %tmp1 = load void(...)*, void(...)** @pfoo
+ call void(...) %tmp1()
+ ret void
+}
+
+declare void @foo(...)
+
+define void @test4() nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr (foo at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ call void(...) @foo()
+ ret void
+}
+
+ at ptr6 = internal global i32* null
+ at dst6 = internal global i32 0
+ at src6 = internal global i32 0
+
+define void @test5() nounwind {
+; CHECK-LABEL: test5:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (dst6,%pc), %a0
+; CHECK-NEXT: lea (ptr6,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src6,%pc), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst6, i32** @ptr6
+ %tmp.s = load i32, i32* @src6
+ store i32 %tmp.s, i32* @dst6
+ ret void
+}
+
+define void @test7(i32 %n.u) nounwind {
+; CHECK-LABEL: test7:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: add.l #-1, %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: sub.l #12, %d1
+; CHECK-NEXT: bhi .LBB6_12
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: lea (.LJTI6_0,%pc), %a0
+; CHECK-NEXT: add.l (0,%a0,%d0), %a0
+; CHECK-NEXT: jmp (%a0)
+; CHECK-NEXT: .LBB6_12: ; %bb2
+; CHECK-NEXT: bra foo6 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_3: ; %bb6
+; CHECK-NEXT: bra foo1 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_8: ; %bb1
+; CHECK-NEXT: bra foo2 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_9: ; %bb3
+; CHECK-NEXT: bra foo3 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_10: ; %bb4
+; CHECK-NEXT: bra foo4 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_14: ; %bb11
+; CHECK-NEXT: bra foo5 at PLT ; TAILCALL
+entry:
+ switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]
+bb:
+ tail call void(...) @foo1()
+ ret void
+bb1:
+ tail call void(...) @foo2()
+ ret void
+bb2:
+ tail call void(...) @foo6()
+ ret void
+bb3:
+ tail call void(...) @foo3()
+ ret void
+bb4:
+ tail call void(...) @foo4()
+ ret void
+bb5:
+ tail call void(...) @foo5()
+ ret void
+bb6:
+ tail call void(...) @foo1()
+ ret void
+bb7:
+ tail call void(...) @foo2()
+ ret void
+bb8:
+ tail call void(...) @foo6()
+ ret void
+bb9:
+ tail call void(...) @foo3()
+ ret void
+bb10:
+ tail call void(...) @foo4()
+ ret void
+bb11:
+ tail call void(...) @foo5()
+ ret void
+bb12:
+ tail call void(...) @foo6()
+ ret void
+}
+
+declare void @foo1(...)
+declare void @foo2(...)
+declare void @foo6(...)
+declare void @foo3(...)
+declare void @foo4(...)
+declare void @foo5(...)
diff --git a/llvm/test/CodeGen/M68k/CodeModel/small-pie-global-access.ll b/llvm/test/CodeGen/M68k/CodeModel/small-pie-global-access.ll
new file mode 100644
index 000000000000..21fc9676f1d0
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/small-pie-global-access.ll
@@ -0,0 +1,129 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O2 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=small -relocation-model=pic \
+; RUN: | FileCheck %s
+
+; External Linkage
+ at a = global i32 0, align 4
+
+define i32 @my_access_global_a() #0 {
+; CHECK-LABEL: my_access_global_a:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (a at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @a, align 4
+ ret i32 %0
+}
+
+; WeakAny Linkage
+ at b = weak global i32 0, align 4
+
+define i32 @my_access_global_b() #0 {
+; CHECK-LABEL: my_access_global_b:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (b at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @b, align 4
+ ret i32 %0
+}
+
+; Internal Linkage
+ at c = internal global i32 0, align 4
+
+define i32 @my_access_global_c() #0 {
+; CHECK-LABEL: my_access_global_c:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (c,%pc), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @c, align 4
+ ret i32 %0
+}
+
+; External Linkage, only declaration.
+ at d = external global i32, align 4
+
+define i32 @my_access_global_load_d() #0 {
+; CHECK-LABEL: my_access_global_load_d:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (d at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = load i32, i32* @d, align 4
+ ret i32 %0
+}
+
+; External Linkage, only declaration, store a value.
+define i32 @my_access_global_store_d() #0 {
+; CHECK-LABEL: my_access_global_store_d:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (d at GOTPCREL,%pc), %a0
+; CHECK-NEXT: move.l #2, (%a0)
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+entry:
+ store i32 2, i32* @d, align 4
+ ret i32 0
+}
+
+; External Linkage, function pointer access.
+declare i32 @access_fp(i32 ()*)
+declare i32 @foo()
+
+define i32 @my_access_fp_foo() #0 {
+; CHECK-LABEL: my_access_fp_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: move.l (foo at GOTPCREL,%pc), (%sp)
+; CHECK-NEXT: jsr (access_fp at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %call = call i32 @access_fp(i32 ()* @foo)
+ ret i32 %call
+}
+
+; LinkOnceODR Linkage, function pointer access.
+
+$bar = comdat any
+
+define linkonce_odr i32 @bar() comdat {
+; CHECK-LABEL: bar:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+entry:
+ ret i32 0
+}
+
+define i32 @my_access_fp_bar() #0 {
+; CHECK-LABEL: my_access_fp_bar:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: move.l (bar at GOTPCREL,%pc), (%sp)
+; CHECK-NEXT: jsr (access_fp at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %call = call i32 @access_fp(i32 ()* @bar)
+ ret i32 %call
+}
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"PIC Level", i32 1}
+!1 = !{i32 1, !"PIE Level", i32 1}
diff --git a/llvm/test/CodeGen/M68k/CodeModel/small-pie.ll b/llvm/test/CodeGen/M68k/CodeModel/small-pie.ll
new file mode 100644
index 000000000000..b1fc4ffb78a1
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/small-pie.ll
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O0 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=small -relocation-model=pic \
+; RUN: | FileCheck %s
+
+define weak void @weak_foo() {
+; CHECK-LABEL: weak_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+define weak_odr void @weak_odr_foo() {
+; CHECK-LABEL: weak_odr_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+define internal void @internal_foo() {
+; CHECK-LABEL: internal_foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+declare i32 @ext_baz()
+
+define void @foo() {
+; CHECK-LABEL: foo:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: rts
+ ret void
+}
+
+
+define void @bar() {
+; CHECK-LABEL: bar:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: jsr (foo at PLT,%pc)
+; CHECK-NEXT: jsr (weak_odr_foo at PLT,%pc)
+; CHECK-NEXT: jsr (weak_foo at PLT,%pc)
+; CHECK-NEXT: jsr (internal_foo,%pc)
+; CHECK-NEXT: jsr (ext_baz at PLT,%pc)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ call void @foo()
+ call void @weak_odr_foo()
+ call void @weak_foo()
+ call void @internal_foo()
+ call i32 @ext_baz()
+ ret void
+}
+
+; -fpie for local global data tests should be added here
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"PIC Level", i32 1}
+!1 = !{i32 1, !"PIE Level", i32 1}
diff --git a/llvm/test/CodeGen/M68k/CodeModel/small-static.ll b/llvm/test/CodeGen/M68k/CodeModel/small-static.ll
new file mode 100644
index 000000000000..affbfc565321
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CodeModel/small-static.ll
@@ -0,0 +1,187 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O2 -mtriple=m68k-linux-gnu -verify-machineinstrs \
+; RUN: -code-model=small -relocation-model=static \
+; RUN: | FileCheck %s
+
+ at ptr = external global i32*
+ at dst = external global i32
+ at src = external global i32
+
+define void @test0() nounwind {
+; CHECK-LABEL: test0:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (dst,%pc), %a0
+; CHECK-NEXT: lea (ptr,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src,%pc), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst, i32** @ptr
+ %tmp.s = load i32, i32* @src
+ store i32 %tmp.s, i32* @dst
+ ret void
+}
+
+ at ptr2 = global i32* null
+ at dst2 = global i32 0
+ at src2 = global i32 0
+
+define void @test1() nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (dst2,%pc), %a0
+; CHECK-NEXT: lea (ptr2,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src2,%pc), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst2, i32** @ptr2
+ %tmp.s = load i32, i32* @src2
+ store i32 %tmp.s, i32* @dst2
+ ret void
+}
+
+declare i8* @malloc(i32)
+
+define void @test2() nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: move.l #40, (%sp)
+; CHECK-NEXT: jsr malloc at PLT
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %ptr = call i8* @malloc(i32 40)
+ ret void
+}
+
+ at pfoo = external global void(...)*
+declare void(...)* @afoo(...)
+
+define void @test3() nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr afoo at PLT
+; CHECK-NEXT: move.l %d0, %a0
+; CHECK-NEXT: lea (pfoo,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: jsr (%a0)
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %tmp = call void(...)*(...) @afoo()
+ store void(...)* %tmp, void(...)** @pfoo
+ %tmp1 = load void(...)*, void(...)** @pfoo
+ call void(...) %tmp1()
+ ret void
+}
+
+declare void @foo(...)
+
+define void @test4() nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: jsr foo at PLT
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ call void(...) @foo()
+ ret void
+}
+
+ at ptr6 = internal global i32* null
+ at dst6 = internal global i32 0
+ at src6 = internal global i32 0
+
+define void @test5() nounwind {
+; CHECK-LABEL: test5:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (dst6,%pc), %a0
+; CHECK-NEXT: lea (ptr6,%pc), %a1
+; CHECK-NEXT: move.l %a0, (%a1)
+; CHECK-NEXT: move.l (src6,%pc), (%a0)
+; CHECK-NEXT: rts
+entry:
+ store i32* @dst6, i32** @ptr6
+ %tmp.s = load i32, i32* @src6
+ store i32 %tmp.s, i32* @dst6
+ ret void
+}
+
+define void @test7(i32 %n.u) nounwind {
+; CHECK-LABEL: test7:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: add.l #-1, %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: sub.l #12, %d1
+; CHECK-NEXT: bhi .LBB6_12
+; CHECK-NEXT: ; %bb.1: ; %entry
+; CHECK-NEXT: lsl.l #2, %d0
+; CHECK-NEXT: lea (.LJTI6_0,%pc), %a0
+; CHECK-NEXT: move.l (0,%a0,%d0), %a0
+; CHECK-NEXT: jmp (%a0)
+; CHECK-NEXT: .LBB6_12: ; %bb2
+; CHECK-NEXT: bra foo6 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_3: ; %bb6
+; CHECK-NEXT: bra foo1 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_8: ; %bb1
+; CHECK-NEXT: bra foo2 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_9: ; %bb3
+; CHECK-NEXT: bra foo3 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_10: ; %bb4
+; CHECK-NEXT: bra foo4 at PLT ; TAILCALL
+; CHECK-NEXT: .LBB6_14: ; %bb11
+; CHECK-NEXT: bra foo5 at PLT ; TAILCALL
+entry:
+ switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ]
+bb:
+ tail call void(...) @foo1()
+ ret void
+bb1:
+ tail call void(...) @foo2()
+ ret void
+bb2:
+ tail call void(...) @foo6()
+ ret void
+bb3:
+ tail call void(...) @foo3()
+ ret void
+bb4:
+ tail call void(...) @foo4()
+ ret void
+bb5:
+ tail call void(...) @foo5()
+ ret void
+bb6:
+ tail call void(...) @foo1()
+ ret void
+bb7:
+ tail call void(...) @foo2()
+ ret void
+bb8:
+ tail call void(...) @foo6()
+ ret void
+bb9:
+ tail call void(...) @foo3()
+ ret void
+bb10:
+ tail call void(...) @foo4()
+ ret void
+bb11:
+ tail call void(...) @foo5()
+ ret void
+bb12:
+ tail call void(...) @foo6()
+ ret void
+}
+
+declare void @foo1(...)
+declare void @foo2(...)
+declare void @foo6(...)
+declare void @foo3(...)
+declare void @foo4(...)
+declare void @foo5(...)
diff --git a/llvm/test/CodeGen/M68k/CollapseMOVEM.mir b/llvm/test/CodeGen/M68k/CollapseMOVEM.mir
new file mode 100644
index 000000000000..99e06cb94d7b
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/CollapseMOVEM.mir
@@ -0,0 +1,163 @@
+# NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=asm -o - \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# CollapseMOVEM pass finds sequences of MOVEM instructions and collapse them
+# into a single instruciton with merged masks. This only works with stack data
+#------------------------------------------------------------------------------
+
+--- # CollapseMOVEM_RM
+#
+# CHECK-LABEL: CollapseMOVEM_RM
+# CHECK: movem.l (0,%sp), %d0-%d2,%d7,%a1-%a3,%a5
+name: CollapseMOVEM_RM
+body: |
+ bb.0:
+ MOVM32mp 1, 0, $sp
+ MOVM32mp 2, 4, $sp
+ MOVM32mp 4, 8, $sp
+ MOVM32mp 128, 12, $sp
+ MOVM32mp 512, 16, $sp
+ MOVM32mp 1024, 20, $sp
+ MOVM32mp 2048, 24, $sp
+ MOVM32mp 8192, 28, $sp
+
+...
+#
+# CHECK-LABEL: CollapseMOVEM_RM_Reversed
+# CHECK: movem.l (0,%sp), %d0-%d2,%d7,%a1-%a3,%a5
+name: CollapseMOVEM_RM_Reversed
+body: |
+ bb.0:
+ MOVM32mp 8192, 28, $sp
+ MOVM32mp 2048, 24, $sp
+ MOVM32mp 1024, 20, $sp
+ MOVM32mp 512, 16, $sp
+ MOVM32mp 128, 12, $sp
+ MOVM32mp 4, 8, $sp
+ MOVM32mp 2, 4, $sp
+ MOVM32mp 1, 0, $sp
+
+...
+# This async reg/mem order is impossible to store with MOVEM
+# CHECK-LABEL: CollapseMOVEM_RM_ReversedStoreOrder
+# CHECK: movem.l (0,%sp), %a5
+# CHECK: movem.l (4,%sp), %a3
+# CHECK: movem.l (8,%sp), %a2
+# CHECK: movem.l (12,%sp), %a1
+# CHECK: movem.l (16,%sp), %d7
+# CHECK: movem.l (20,%sp), %d2
+# CHECK: movem.l (24,%sp), %d1
+# CHECK: movem.l (28,%sp), %d0
+name: CollapseMOVEM_RM_ReversedStoreOrder
+body: |
+ bb.0:
+ MOVM32mp 8192, 0, $sp
+ MOVM32mp 2048, 4, $sp
+ MOVM32mp 1024, 8, $sp
+ MOVM32mp 512, 12, $sp
+ MOVM32mp 128, 16, $sp
+ MOVM32mp 4, 20, $sp
+ MOVM32mp 2, 24, $sp
+ MOVM32mp 1, 28, $sp
+
+...
+--- # CollapseMOVEM_MR
+#
+# CHECK-LABEL: CollapseMOVEM_MR
+# CHECK: movem.l %d0-%d2,%d7,%a1-%a3,%a5, (0,%sp)
+name: CollapseMOVEM_MR
+body: |
+ bb.0:
+ MOVM32pm 0, $sp, 1
+ MOVM32pm 4, $sp, 2
+ MOVM32pm 8, $sp, 4
+ MOVM32pm 12, $sp, 128
+ MOVM32pm 16, $sp, 512
+ MOVM32pm 20, $sp, 1024
+ MOVM32pm 24, $sp, 2048
+ MOVM32pm 28, $sp, 8192
+
+...
+--- # CollapseMOVEM_Mixed
+#
+# CHECK-LABEL: CollapseMOVEM_Mixed
+# CHECK: movem.l %d0-%d1, (0,%sp)
+# CHECK: movem.l (8,%sp), %d2,%d7
+# CHECK: movem.l %a1-%a2, (16,%sp)
+# CHECK: movem.l (24,%sp), %a3
+# CHECK: movem.l %a5, (28,%sp)
+name: CollapseMOVEM_Mixed
+body: |
+ bb.0:
+ MOVM32pm 0, $sp, 1
+ MOVM32pm 4, $sp, 2
+ MOVM32mp 4, 8, $sp
+ MOVM32mp 128, 12, $sp
+ MOVM32pm 16, $sp, 512
+ MOVM32pm 20, $sp, 1024
+ MOVM32mp 2048, 24, $sp
+ MOVM32pm 28, $sp, 8192
+
+...
+--- # CollapseMOVEM_Zero
+#
+# CHECK-LABEL: CollapseMOVEM_Zero
+# CHECK: movem.l %d0-%d4, (-8,%sp)
+name: CollapseMOVEM_Zero
+body: |
+ bb.0:
+ MOVM32pm -8, $sp, 1
+ MOVM32pm -4, $sp, 2
+ MOVM32pm 0, $sp, 4
+ MOVM32pm 4, $sp, 8
+ MOVM32pm 8, $sp, 16
+
+...
+#
+# CHECK-LABEL: CollapseMOVEM_Zero_Mixed
+# CHECK: movem.l %d3, (4,%sp)
+# CHECK: movem.l %d0-%d2, (-8,%sp)
+# CHECK: movem.l %d4, (8,%sp)
+name: CollapseMOVEM_Zero_Mixed
+body: |
+ bb.0:
+ MOVM32pm 4, $sp, 8
+ MOVM32pm -4, $sp, 2
+ MOVM32pm -8, $sp, 1
+ MOVM32pm 0, $sp, 4
+ MOVM32pm 8, $sp, 16
+
+...
+--- # CollapseMOVEM_Zero_Reversed
+#
+# CHECK-LABEL: CollapseMOVEM_Zero_Reversed
+# CHECK: movem.l %d0-%d4, (-8,%sp)
+name: CollapseMOVEM_Zero_Reversed
+body: |
+ bb.0:
+ MOVM32pm 8, $sp, 16
+ MOVM32pm 4, $sp, 8
+ MOVM32pm 0, $sp, 4
+ MOVM32pm -4, $sp, 2
+ MOVM32pm -8, $sp, 1
+
+...
+#
+# CHECK-LABEL: CollapseMOVEM_Zero_ReversedStoreOrder
+# CHECK: movem.l %d0, (8,%sp)
+# CHECK: movem.l %d1, (4,%sp)
+# CHECK: movem.l %d2, (0,%sp)
+# CHECK: movem.l %d3, (-4,%sp)
+# CHECK: movem.l %d4, (-8,%sp)
+name: CollapseMOVEM_Zero_ReversedStoreOrder
+body: |
+ bb.0:
+ MOVM32pm 8, $sp, 1
+ MOVM32pm 4, $sp, 2
+ MOVM32pm 0, $sp, 4
+ MOVM32pm -4, $sp, 8
+ MOVM32pm -8, $sp, 16
+
+...
diff --git a/llvm/test/CodeGen/M68k/Control/cmp.ll b/llvm/test/CodeGen/M68k/Control/cmp.ll
new file mode 100644
index 000000000000..122e514e9a7a
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Control/cmp.ll
@@ -0,0 +1,321 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux-gnu -verify-machineinstrs | FileCheck %s
+
+define i32 @test1(i32* %y) nounwind {
+; CHECK-LABEL: test1:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %a0
+; CHECK-NEXT: cmpi.l #0, (%a0)
+; CHECK-NEXT: beq .LBB0_2
+; CHECK-NEXT: ; %bb.1: ; %cond_false
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB0_2: ; %cond_true
+; CHECK-NEXT: move.l #1, %d0
+; CHECK-NEXT: rts
+ %tmp = load i32, i32* %y ; <i32> [#uses=1]
+ %tmp.upgrd.1 = icmp eq i32 %tmp, 0 ; <i1> [#uses=1]
+ br i1 %tmp.upgrd.1, label %cond_true, label %cond_false
+
+cond_false: ; preds = %0
+ ret i32 0
+
+cond_true: ; preds = %0
+ ret i32 1
+}
+
+define i32 @test2(i32* %y) nounwind {
+; CHECK-LABEL: test2:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: and.l #536870911, %d0
+; CHECK-NEXT: cmpi.l #0, %d0
+; CHECK-NEXT: beq .LBB1_2
+; CHECK-NEXT: ; %bb.1: ; %cond_false
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB1_2: ; %cond_true
+; CHECK-NEXT: move.l #1, %d0
+; CHECK-NEXT: rts
+ %tmp = load i32, i32* %y ; <i32> [#uses=1]
+ %tmp1 = shl i32 %tmp, 3 ; <i32> [#uses=1]
+ %tmp1.upgrd.2 = icmp eq i32 %tmp1, 0 ; <i1> [#uses=1]
+ br i1 %tmp1.upgrd.2, label %cond_true, label %cond_false
+
+cond_false: ; preds = %0
+ ret i32 0
+
+cond_true: ; preds = %0
+ ret i32 1
+}
+
+define i8 @test2b(i8* %y) nounwind {
+; CHECK-LABEL: test2b:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %a0
+; CHECK-NEXT: move.b (%a0), %d0
+; CHECK-NEXT: and.b #31, %d0
+; CHECK-NEXT: cmpi.b #0, %d0
+; CHECK-NEXT: beq .LBB2_2
+; CHECK-NEXT: ; %bb.1: ; %cond_false
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB2_2: ; %cond_true
+; CHECK-NEXT: move.b #1, %d0
+; CHECK-NEXT: rts
+ %tmp = load i8, i8* %y ; <i8> [#uses=1]
+ %tmp1 = shl i8 %tmp, 3 ; <i8> [#uses=1]
+ %tmp1.upgrd.2 = icmp eq i8 %tmp1, 0 ; <i1> [#uses=1]
+ br i1 %tmp1.upgrd.2, label %cond_true, label %cond_false
+
+cond_false: ; preds = %0
+ ret i8 0
+
+cond_true: ; preds = %0
+ ret i8 1
+}
+
+define i64 @test3(i64 %x) nounwind {
+; CHECK-LABEL: test3:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l (8,%sp), %d0
+; CHECK-NEXT: or.l (4,%sp), %d0
+; CHECK-NEXT: seq %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: and.l #255, %d1
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: rts
+ %t = icmp eq i64 %x, 0
+ %r = zext i1 %t to i64
+ ret i64 %r
+}
+
+define i64 @test4(i64 %x) nounwind {
+; CHECK-LABEL: test4:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l (8,%sp), %d1
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: move.l (12,%sp), %d2
+; CHECK-NEXT: sub.l #1, %d2
+; CHECK-NEXT: subx.l %d0, %d1
+; CHECK-NEXT: slt %d1
+; CHECK-NEXT: and.l #255, %d1
+; CHECK-NEXT: and.l #1, %d1
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+ %t = icmp slt i64 %x, 1
+ %r = zext i1 %t to i64
+ ret i64 %r
+}
+
+define i32 @test6() nounwind align 2 {
+; CHECK-LABEL: test6:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: sub.l #20, %sp
+; CHECK-NEXT: move.l (12,%sp), %d0
+; CHECK-NEXT: or.l (8,%sp), %d0
+; CHECK-NEXT: beq .LBB5_1
+; CHECK-NEXT: ; %bb.2: ; %F
+; CHECK-NEXT: move.l #0, %d0
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB5_1: ; %T
+; CHECK-NEXT: move.l #1, %d0
+; CHECK-NEXT: add.l #20, %sp
+; CHECK-NEXT: rts
+ %A = alloca {i64, i64}, align 8
+ %B = getelementptr inbounds {i64, i64}, {i64, i64}* %A, i64 0, i32 1
+ %C = load i64, i64* %B
+ %D = icmp eq i64 %C, 0
+ br i1 %D, label %T, label %F
+T:
+ ret i32 1
+
+F:
+ ret i32 0
+}
+
+define i32 @test7(i64 %res) nounwind {
+; CHECK-LABEL: test7:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: cmpi.l #0, (4,%sp)
+; CHECK-NEXT: seq %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: rts
+entry:
+ %lnot = icmp ult i64 %res, 4294967296
+ %lnot.ext = zext i1 %lnot to i32
+ ret i32 %lnot.ext
+}
+
+define i32 @test8(i64 %res) nounwind {
+; CHECK-LABEL: test8:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: sub.l #3, %d0
+; CHECK-NEXT: scs %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: rts
+entry:
+ %lnot = icmp ult i64 %res, 12884901888
+ %lnot.ext = zext i1 %lnot to i32
+ ret i32 %lnot.ext
+}
+
+define i32 @test11(i64 %l) nounwind {
+; CHECK-LABEL: test11:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: and.l #-32768, %d0
+; CHECK-NEXT: eori.l #32768, %d0
+; CHECK-NEXT: seq %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: rts
+entry:
+ %shr.mask = and i64 %l, -140737488355328
+ %cmp = icmp eq i64 %shr.mask, 140737488355328
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+define i32 @test13(i32 %mask, i32 %base, i32 %intra) {
+; CHECK-LABEL: test13:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.b (7,%sp), %d0
+; CHECK-NEXT: and.b #8, %d0
+; CHECK-NEXT: cmpi.b #0, %d0
+; CHECK-NEXT: bne .LBB9_1
+; CHECK-NEXT: ; %bb.2:
+; CHECK-NEXT: lea (8,%sp), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB9_1:
+; CHECK-NEXT: lea (12,%sp), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+ %and = and i32 %mask, 8
+ %tobool = icmp ne i32 %and, 0
+ %cond = select i1 %tobool, i32 %intra, i32 %base
+ ret i32 %cond
+}
+
+define i32 @test14(i32 %mask, i32 %base, i32 %intra) #0 {
+; CHECK-LABEL: test14:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsr.l #7, %d0
+; CHECK-NEXT: cmpi.l #0, %d0
+; CHECK-NEXT: bpl .LBB10_1
+; CHECK-NEXT: ; %bb.2:
+; CHECK-NEXT: lea (8,%sp), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+; CHECK-NEXT: .LBB10_1:
+; CHECK-NEXT: lea (12,%sp), %a0
+; CHECK-NEXT: move.l (%a0), %d0
+; CHECK-NEXT: rts
+ %s = lshr i32 %mask, 7
+ %tobool = icmp sgt i32 %s, -1
+ %cond = select i1 %tobool, i32 %intra, i32 %base
+ ret i32 %cond
+}
+
+define zeroext i1 @test15(i32 %bf.load, i32 %n) {
+; CHECK-LABEL: test15:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l #16, %d0
+; CHECK-NEXT: move.l (4,%sp), %d1
+; CHECK-NEXT: lsr.l %d0, %d1
+; CHECK-NEXT: move.l %d1, %d0
+; CHECK-NEXT: sub.l (8,%sp), %d0
+; CHECK-NEXT: scc %d0
+; CHECK-NEXT: cmpi.l #0, %d1
+; CHECK-NEXT: seq %d1
+; CHECK-NEXT: or.b %d0, %d1
+; CHECK-NEXT: move.l %d1, %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: rts
+ %bf.lshr = lshr i32 %bf.load, 16
+ %cmp2 = icmp eq i32 %bf.lshr, 0
+ %cmp5 = icmp uge i32 %bf.lshr, %n
+ %.cmp5 = or i1 %cmp2, %cmp5
+ ret i1 %.cmp5
+}
+
+define i8 @test16(i16 signext %L) {
+; CHECK-LABEL: test16:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.w #15, %d1
+; CHECK-NEXT: move.w (6,%sp), %d0
+; CHECK-NEXT: lsr.w %d1, %d0
+; CHECK-NEXT: eori.b #1, %d0
+; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $wd0
+; CHECK-NEXT: rts
+ %lshr = lshr i16 %L, 15
+ %trunc = trunc i16 %lshr to i8
+ %not = xor i8 %trunc, 1
+ ret i8 %not
+}
+
+define i8 @test18(i64 %L) {
+; CHECK-LABEL: test18:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l #31, %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsr.l %d1, %d0
+; CHECK-NEXT: eori.b #1, %d0
+; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $d0
+; CHECK-NEXT: rts
+ %lshr = lshr i64 %L, 63
+ %trunc = trunc i64 %lshr to i8
+ %not = xor i8 %trunc, 1
+ ret i8 %not
+}
+
+ at d = global i8 0, align 1
+
+define void @test20(i32 %bf.load, i8 %x1, i8* %b_addr) {
+; CHECK-LABEL: test20:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l #16777215, %d0
+; CHECK-NEXT: and.l (8,%sp), %d0
+; CHECK-NEXT: sne %d1
+; CHECK-NEXT: and.l #255, %d1
+; CHECK-NEXT: move.l (16,%sp), %a0
+; CHECK-NEXT: move.b (15,%sp), %d2
+; CHECK-NEXT: and.l #255, %d2
+; CHECK-NEXT: add.l %d1, %d2
+; CHECK-NEXT: sne (%a0)
+; CHECK-NEXT: cmpi.l #0, %d0
+; CHECK-NEXT: lea (d,%pc), %a0
+; CHECK-NEXT: sne (%a0)
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+ %bf.shl = shl i32 %bf.load, 8
+ %bf.ashr = ashr exact i32 %bf.shl, 8
+ %tobool4 = icmp ne i32 %bf.ashr, 0
+ %conv = zext i1 %tobool4 to i32
+ %conv6 = zext i8 %x1 to i32
+ %add = add nuw nsw i32 %conv, %conv6
+ %tobool7 = icmp ne i32 %add, 0
+ %frombool = zext i1 %tobool7 to i8
+ store i8 %frombool, i8* %b_addr, align 1
+ %tobool14 = icmp ne i32 %bf.shl, 0
+ %frombool15 = zext i1 %tobool14 to i8
+ store i8 %frombool15, i8* @d, align 1
+ ret void
+}
diff --git a/llvm/test/CodeGen/M68k/Control/long-setcc.ll b/llvm/test/CodeGen/M68k/Control/long-setcc.ll
new file mode 100644
index 000000000000..b089af5f2ae8
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Control/long-setcc.ll
@@ -0,0 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+define i1 @t1(i64 %x) nounwind {
+; CHECK-LABEL: t1:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.l #31, %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsr.l %d1, %d0
+; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $d0
+; CHECK-NEXT: rts
+ %B = icmp slt i64 %x, 0
+ ret i1 %B
+}
+
+define i1 @t2(i64 %x) nounwind {
+; CHECK-LABEL: t2:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: cmpi.l #0, (4,%sp)
+; CHECK-NEXT: seq %d0
+; CHECK-NEXT: rts
+ %tmp = icmp ult i64 %x, 4294967296
+ ret i1 %tmp
+}
+
+define i1 @t3(i32 %x) nounwind {
+; CHECK-LABEL: t3:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: move.b #0, %d0
+; CHECK-NEXT: rts
+ %tmp = icmp ugt i32 %x, -1
+ ret i1 %tmp
+}
diff --git a/llvm/test/CodeGen/M68k/Control/setcc.ll b/llvm/test/CodeGen/M68k/Control/setcc.ll
new file mode 100644
index 000000000000..1e301bb1bda6
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Control/setcc.ll
@@ -0,0 +1,102 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+;; TODO All these can be improved
+
+define zeroext i16 @t1(i16 zeroext %x) nounwind readnone ssp {
+; CHECK-LABEL: t1:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.w (6,%sp), %d0
+; CHECK-NEXT: and.l #65535, %d0
+; CHECK-NEXT: sub.l #26, %d0
+; CHECK-NEXT: shi %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: lsl.l #5, %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = icmp ugt i16 %x, 26 ; <i1> [#uses=1]
+ %iftmp.1.0 = select i1 %0, i16 32, i16 0 ; <i16> [#uses=1]
+ ret i16 %iftmp.1.0
+}
+
+define zeroext i16 @t2(i16 zeroext %x) nounwind readnone ssp {
+; CHECK-LABEL: t2:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: move.w (6,%sp), %d0
+; CHECK-NEXT: and.l #65535, %d0
+; CHECK-NEXT: sub.l #26, %d0
+; CHECK-NEXT: scs %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: lsl.l #5, %d0
+; CHECK-NEXT: rts
+entry:
+ %0 = icmp ult i16 %x, 26 ; <i1> [#uses=1]
+ %iftmp.0.0 = select i1 %0, i16 32, i16 0 ; <i16> [#uses=1]
+ ret i16 %iftmp.0.0
+}
+
+define fastcc i64 @t3(i64 %x) nounwind readnone ssp {
+; CHECK-LABEL: t3:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: sub.l #4, %sp
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: move.l #0, %d2
+; CHECK-NEXT: sub.l #18, %d1
+; CHECK-NEXT: subx.l %d2, %d0
+; CHECK-NEXT: scs %d0
+; CHECK-NEXT: move.l %d0, %d1
+; CHECK-NEXT: and.l #255, %d1
+; CHECK-NEXT: and.l #1, %d1
+; CHECK-NEXT: lsl.l #6, %d1
+; CHECK-NEXT: move.l %d2, %d0
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: add.l #4, %sp
+; CHECK-NEXT: rts
+entry:
+ %0 = icmp ult i64 %x, 18 ; <i1> [#uses=1]
+ %iftmp.2.0 = select i1 %0, i64 64, i64 0 ; <i64> [#uses=1]
+ ret i64 %iftmp.2.0
+}
+
+define i8 @t5(i32 %a) {
+; CHECK-LABEL: t5:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #31, %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: lsr.l %d1, %d0
+; CHECK-NEXT: eori.b #1, %d0
+; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $d0
+; CHECK-NEXT: rts
+entry:
+ %.lobit = lshr i32 %a, 31
+ %trunc = trunc i32 %.lobit to i8
+ %.not = xor i8 %trunc, 1
+ ret i8 %.not
+}
+
+
+;
+; TODO: Should it be like this?
+; cmp.l
+; smi
+; since we are intereseted in sign bit only
+; and.l in the end is superfluous
+
+define zeroext i1 @t6(i32 %a) {
+; CHECK-LABEL: t6:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: move.l #31, %d0
+; CHECK-NEXT: move.l (4,%sp), %d1
+; CHECK-NEXT: lsr.l %d0, %d1
+; CHECK-NEXT: eori.b #1, %d1
+; CHECK-NEXT: move.l %d1, %d0
+; CHECK-NEXT: and.l #255, %d0
+; CHECK-NEXT: rts
+entry:
+ %.lobit = lshr i32 %a, 31
+ %trunc = trunc i32 %.lobit to i1
+ %.not = xor i1 %trunc, 1
+ ret i1 %.not
+}
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMI.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMI.mir
new file mode 100644
index 000000000000..eef4958f86b2
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMI.mir
@@ -0,0 +1,88 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ADD8FI,ADD32FI,ADD8PI,ADD32PI,ADD8JI,ADD32JI
+
+#------------------------------------------------------------------------------
+# MxBiArOp_FMI class used for binary arithmetic operations and operates on
+# memory and immediate data. It uses MxArithImmEncoding class.
+#------------------------------------------------------------------------------
+
+
+--- # ARII
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD x x x x x x x x | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# ADD8FI: 0 0 0 0 0 1 1 0 . 0 0 1 1 0 0 0 0
+# ADD8FI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# ADD8FI-SAME: 0 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------------------------------
+# ADD8FI-SAME: 0 0 0 0 0 1 1 0 . 0 0 1 1 0 0 1 1
+# ADD8FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ADD8FI-SAME: 1 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------------------------------
+# ADD32FI-SAME: 0 0 0 0 0 1 1 0 . 1 0 1 1 0 0 1 0
+# ADD32FI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ADD32FI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ADD32FI-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 1 1 0 1
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBiArOp_FMI_ARII
+body: |
+ bb.0:
+ ADD8fi 0, $a0, $d0, -1, implicit-def $ccr
+ ADD8fi -1, $a3, $a1, 0, implicit-def $ccr
+ ADD32fi 13, $a2, $d1, -1, implicit-def $ccr
+
+...
+--- # ARID
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD x x x x x x x x | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# ADD8PI-SAME: 0 0 0 0 0 1 1 0 . 0 0 1 0 1 0 0 0
+# ADD8PI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# ADD8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------------------------------
+# ADD8PI-SAME: 0 0 0 0 0 1 1 0 . 0 0 1 0 1 0 1 1
+# ADD8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ADD8PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------------------------------
+# ADD32PI-SAME: 0 0 0 0 0 1 1 0 . 1 0 1 0 1 0 1 0
+# ADD32PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ADD32PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ADD32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 1 1 0 1
+name: MxBiArOp_FMI_ARID
+body: |
+ bb.0:
+ ADD8pi 0, $a0, -1, implicit-def $ccr
+ ADD8pi -1, $a3, 0, implicit-def $ccr
+ ADD32pi 13, $a2, -1, implicit-def $ccr
+
+...
+--- # ARI
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD x x x x x x x x | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# ADD8JI-SAME: 0 0 0 0 0 1 1 0 . 0 0 0 1 0 0 0 0
+# ADD8JI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------------------------------
+# ADD8JI-SAME: 0 0 0 0 0 1 1 0 . 0 0 0 1 0 0 1 1
+# ADD8JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------------------------------
+# ADD32JI-SAME: 0 0 0 0 0 1 1 0 . 1 0 0 1 0 0 1 0
+# ADD32JI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ADD32JI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxBiArOp_FMI_ARI
+body: |
+ bb.0:
+ ADD8ji $a0, -1, implicit-def $ccr
+ ADD8ji $a3, 0, implicit-def $ccr
+ ADD32ji $a2, -1, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMR.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMR.mir
new file mode 100644
index 000000000000..e7cf7f8b2ae6
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_FMR.mir
@@ -0,0 +1,73 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ADD8FD,ADD32FD,ADD8PD,ADD32PD,ADD8JD,ADD32JD
+
+#------------------------------------------------------------------------------
+# MxBiArOp_FMR class used for binary arithmetic operations and operates on
+# register and memory; the result is store to memory. It uses MxArithEncoding
+# encoding class and MxOpModeEAd opmode class.
+#------------------------------------------------------------------------------
+
+--- # ARII
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8FD: 1 1 0 1 0 0 0 1 . 0 0 1 1 0 0 0 0
+# ADD8FD-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD8FD-SAME: 1 1 0 1 0 0 0 1 . 0 0 1 1 0 0 0 0
+# ADD8FD-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# ADD32FD-SAME: 1 1 0 1 0 0 0 1 . 1 0 1 1 0 0 0 1
+# ADD32FD-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32FD-SAME: 1 1 0 1 0 0 1 1 . 1 0 1 1 0 0 1 0
+# ADD32FD-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBiArOp_FMR_ARII
+body: |
+ bb.0:
+ ADD8fd 0, $a0, $d1, $bd0, implicit-def $ccr
+ ADD8fd -1, $a0, $d1, $bd0, implicit-def $ccr
+ ADD32fd 0, $a1, $d1, $d0, implicit-def $ccr
+ ADD32fd 0, $a2, $a2, $d1, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8PD-SAME: 1 1 0 1 0 0 0 1 . 0 0 1 0 1 0 0 0
+# ADD8PD-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32PD-SAME: 1 1 0 1 0 0 0 1 . 1 0 1 0 1 0 0 1
+# ADD32PD-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxBiArOp_FMR_ARID
+body: |
+ bb.0:
+ ADD8pd 0, $a0, $bd0, implicit-def $ccr
+ ADD32pd -1, $a1, $d0, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8JD-SAME: 1 1 0 1 0 0 0 1 . 0 0 0 1 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32JD-SAME: 1 1 0 1 0 1 1 1 . 1 0 0 1 0 0 0 1
+name: MxBiArOp_FMR_ARI
+body: |
+ bb.0:
+ ADD8jd $a0, $bd0, implicit-def $ccr
+ ADD32jd $a1, $d3, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI.mir
new file mode 100644
index 000000000000..e0548c0c9843
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI.mir
@@ -0,0 +1,41 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=XOR16DI,XOR32DI
+
+#------------------------------------------------------------------------------
+# MxBiArOp_RFRI class used for binary arithmetic operations and operates on
+# register and immediate data. It uses MxArithImmEncoding class. This is special
+# case for XOR.
+#------------------------------------------------------------------------------
+
+
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# x x x x x x x x | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# XOR16DI: 0 0 0 0 1 0 1 0 . 0 1 0 0 0 0 0 0
+# XOR16DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------------------------------
+# XOR16DI-SAME: 0 0 0 0 1 0 1 0 . 0 1 0 0 0 0 1 1
+# XOR16DI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------------------------------
+# XOR32DI-SAME: 0 0 0 0 1 0 1 0 . 1 0 0 0 0 0 0 0
+# XOR32DI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# XOR32DI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------------------------------
+# XOR32DI-SAME: 0 0 0 0 1 0 1 0 . 1 0 0 0 0 0 0 0
+# XOR32DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# XOR32DI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------------------------------
+# XOR32DI-SAME: 0 0 0 0 1 0 1 0 . 1 0 0 0 0 1 1 1
+# XOR32DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 1 1 1
+# XOR32DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxBiArOp_RFRI
+body: |
+ bb.0:
+ $wd0 = XOR16di $wd0, 0, implicit-def $ccr
+ $wd3 = XOR16di $wd3, -1, implicit-def $ccr
+ $d0 = XOR32di $d0, -1, implicit-def $ccr
+ $d0 = XOR32di $d0, 131071, implicit-def $ccr
+ $d7 = XOR32di $d7, 458752, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI_xEA.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI_xEA.mir
new file mode 100644
index 000000000000..09e06e0072b6
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRI_xEA.mir
@@ -0,0 +1,45 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ADD16DI,ADD32RI
+
+#------------------------------------------------------------------------------
+# MxBiArOp_RFRI_xEA class used for binary arithmetic operations and operates on
+# register and immediate data. It uses MxArithEncoding(yes for immediates) class
+# and either MxOpModeNdEA or MxOpmodeNrEA opmode classes.
+#------------------------------------------------------------------------------
+
+
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# x x x x | REG | OPMODE | MODE | REG
+# ADD16DI: 1 1 0 1 0 0 0 0 . 0 1 1 1 1 1 0 0
+# ADD16DI: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------+-----------+-----------+-----------+-----------
+# ADD16DI-SAME: 1 1 0 1 0 1 1 0 . 0 1 1 1 1 1 0 0
+# ADD16DI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------+-----------+-----------+-----------+-----------
+# ADD32RI-SAME: 1 1 0 1 0 0 0 0 . 1 0 1 1 1 1 0 0
+# ADD32RI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ADD32RI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------+-----------+-----------+-----------+-----------
+# ADD32RI-SAME: 1 1 0 1 0 0 0 0 . 1 0 1 1 1 1 0 0
+# ADD32RI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# ADD32RI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------+-----------+-----------+-----------+-----------
+# ADD32RI-SAME: 1 1 0 1 1 1 1 0 . 1 0 1 1 1 1 0 0
+# ADD32RI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 1 1 1
+# ADD32RI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------+-----------+-----------+-----------+-----------
+# ADD32RI-SAME: 1 1 0 1 0 0 0 1 . 1 1 1 1 1 1 0 0
+# ADD32RI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ADD32RI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxBiArOp_RFRI_xEA
+body: |
+ bb.0:
+ $wd0 = ADD16di $wd0, 0, implicit-def $ccr
+ $wd3 = ADD16di $wd3, -1, implicit-def $ccr
+ $d0 = ADD32ri $d0, -1, implicit-def $ccr
+ $d0 = ADD32ri $d0, 131071, implicit-def $ccr
+ $d7 = ADD32ri $d7, 458752, implicit-def $ccr
+ $a0 = ADD32ri $a0, 0, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRM.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRM.mir
new file mode 100644
index 000000000000..28946f91bd36
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRM.mir
@@ -0,0 +1,123 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ADD8DK,ADD32RK,ADD8DQ,ADD32RQ,ADD8DF,ADD32RF
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ADD8DP,ADD32RP,ADD8DJ,ADD32RJ
+
+#------------------------------------------------------------------------------
+# MxBiArOp_RFRM class used for binary arithmetic operations and operates on
+# register and memory. It uses MxArithEncoding encoding class and either
+# MxOpModeNdEA or MxOpModeNrEA opmode classes.
+#------------------------------------------------------------------------------
+
+--- # PCI
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8DK: 1 1 0 1 0 0 0 0 . 0 0 1 1 1 0 1 1
+# ADD8DK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD8DK-SAME: 1 1 0 1 0 0 0 0 . 0 0 1 1 1 0 1 1
+# ADD8DK-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# ADD32RK-SAME: 1 1 0 1 0 0 0 0 . 1 0 1 1 1 0 1 1
+# ADD32RK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32RK-SAME: 1 1 0 1 0 0 1 1 . 1 1 1 1 1 0 1 1
+# ADD32RK-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBiArOp_RFRM_PCI
+body: |
+ bb.0:
+ $bd0 = ADD8dk $bd0, 0, $d1, implicit-def $ccr
+ $bd0 = ADD8dk $bd0, -1, $d1, implicit-def $ccr
+ $d0 = ADD32rk $d0, 0, $d1, implicit-def $ccr
+ $a1 = ADD32rk $a1, 0, $a2, implicit-def $ccr
+
+...
+--- # PCD
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8DQ-SAME: 1 1 0 1 0 0 0 0 . 0 0 1 1 1 0 1 0
+# ADD8DQ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32RQ-SAME: 1 1 0 1 0 0 0 0 . 1 0 1 1 1 0 1 0
+# ADD32RQ-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxBiArOp_RFRM_PCD
+body: |
+ bb.0:
+ $bd0 = ADD8dq $bd0, 0, implicit-def $ccr
+ $d0 = ADD32rq $d0, -1, implicit-def $ccr
+
+...
+--- # ARII
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8DF-SAME: 1 1 0 1 0 0 0 0 . 0 0 1 1 0 0 0 0
+# ADD8DF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD8DF-SAME: 1 1 0 1 0 0 0 0 . 0 0 1 1 0 0 0 0
+# ADD8DF-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# ADD32RF-SAME: 1 1 0 1 0 0 0 0 . 1 0 1 1 0 0 0 1
+# ADD32RF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32RF-SAME: 1 1 0 1 0 0 1 1 . 1 1 1 1 0 0 1 0
+# ADD32RF-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBiArOp_RFRM_ARII
+body: |
+ bb.0:
+ $bd0 = ADD8df $bd0, 0, $a0, $d1, implicit-def $ccr
+ $bd0 = ADD8df $bd0, -1, $a0, $d1, implicit-def $ccr
+ $d0 = ADD32rf $d0, 0, $a1, $d1, implicit-def $ccr
+ $a1 = ADD32rf $a1, 0, $a2, $a2, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8DP: 1 1 0 1 0 0 0 0 . 0 0 1 0 1 0 0 0
+# ADD8DP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32RP-SAME: 1 1 0 1 0 0 0 0 . 1 0 1 0 1 0 0 1
+# ADD32RP-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxBiArOp_RFRM_ARID
+body: |
+ bb.0:
+ $bd0 = ADD8dp $bd0, 0, $a0, implicit-def $ccr
+ $d0 = ADD32rp $d0, -1, $a1, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# ADD8DJ-SAME: 1 1 0 1 0 0 0 0 . 0 0 0 1 0 0 0 0
+# ---------------------------------------------------------------
+# ADD32RJ-SAME: 1 1 0 1 0 1 1 1 . 1 1 0 1 0 0 0 1
+name: MxBiArOp_RFRM_ARI
+body: |
+ bb.0:
+ $bd0 = ADD8dj $bd0, $a0, implicit-def $ccr
+ $a3 = ADD32rj $a3, $a1, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRRF.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRRF.mir
new file mode 100644
index 000000000000..0d9e6c314d25
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRRF.mir
@@ -0,0 +1,27 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ADDX16DD,ADDX32DD
+
+#------------------------------------------------------------------------------
+# MxBiArOp_RFRRF class used for carry-aware binary arithmetic operations and
+# operates on both data and address registers only. It uses MxArithXEncoding
+# encoding class and either MxOpModeNdEA or MxOpModeNrEA opmode classes.
+#------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------
+# 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
+# ---------------+-----------+---+-------+-------+---+-----------
+# ADDX16DD: 1 1 0 1 0 0 0 1 . 0 1 0 0 0 0 0 1
+# ADDX16DD-SAME: 1 1 0 1 0 1 1 1 . 0 1 0 0 0 0 1 0
+# ADDX32DD-SAME: 1 1 0 1 0 0 0 1 . 1 0 0 0 0 0 0 1
+# ADDX32DD-SAME: 1 1 0 1 1 1 1 1 . 1 0 0 0 0 0 0 1
+name: MxBiArOp_RFRRF
+body: |
+ bb.0:
+ $wd0 = ADDX16dd $wd0, $wd1, implicit $ccr, implicit-def $ccr
+ $wd3 = ADDX16dd $wd3, $wd2, implicit $ccr, implicit-def $ccr
+ $d0 = ADDX32dd $d0, $d1, implicit $ccr, implicit-def $ccr
+ $d7 = ADDX32dd $d7, $d1, implicit $ccr, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_EAd.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_EAd.mir
new file mode 100644
index 000000000000..c2835de44279
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_EAd.mir
@@ -0,0 +1,26 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=XOR16DD,XOR32DD
+
+#------------------------------------------------------------------------------
+# MxBiArOp_RFRR_EAd class used for binary arithmetic operations and operates on
+# both data and address registers only. It uses MxArithEncoding encoding class
+# and MxOpModeEAd opmode class. This is a special case for XOR(EOR).
+#------------------------------------------------------------------------------
+
+
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# x x x x | REG | OPMODE | MODE | REG
+# XOR16DD: 1 0 1 1 0 0 1 1 . 0 1 0 0 0 0 0 0
+# XOR16DD-SAME: 1 0 1 1 0 1 0 1 . 0 1 0 0 0 0 1 1
+# XOR32DD-SAME: 1 0 1 1 0 0 1 1 . 1 0 0 0 0 0 0 0
+# XOR32DD-SAME: 1 0 1 1 0 0 1 1 . 1 0 0 0 0 1 1 1
+name: MxBiArOp_RFRR_EAd
+body: |
+ bb.0:
+ $wd0 = XOR16dd $wd0, $wd1, implicit-def $ccr
+ $wd3 = XOR16dd $wd3, $wd2, implicit-def $ccr
+ $d0 = XOR32dd $d0, $d1, implicit-def $ccr
+ $d7 = XOR32dd $d7, $d1, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_xEA.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_xEA.mir
new file mode 100644
index 000000000000..41c49e71f761
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxBiArOp_RFRR_xEA.mir
@@ -0,0 +1,30 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ADD16DD,ADD32RR
+
+#------------------------------------------------------------------------------
+# MxBiArOp_RFRR_xEA class used for binary arithmetic operations and operates on
+# both data and address registers only. It uses MxArithEncoding encoding class
+# and either MxOpModeNdEA or MxOpmodeNrEA opmode classes.
+#------------------------------------------------------------------------------
+
+
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# x x x x | REG | OPMODE | MODE | REG
+# ADD16DD: 1 1 0 1 0 0 0 0 . 0 1 0 0 0 0 0 1
+# ADD16DD-SAME: 1 1 0 1 0 1 1 0 . 0 1 0 0 0 0 1 0
+# ADD32RR-SAME: 1 1 0 1 0 0 0 0 . 1 0 0 0 0 0 0 1
+# ADD32RR-SAME: 1 1 0 1 0 0 0 0 . 1 0 0 0 1 0 0 1
+# ADD32RR-SAME: 1 1 0 1 1 1 1 0 . 1 0 0 0 1 0 0 1
+# ADD32RR-SAME: 1 1 0 1 0 0 0 1 . 1 1 0 0 0 0 0 1
+name: MxBiArOp_RFRR_xEA
+body: |
+ bb.0:
+ $wd0 = ADD16dd $wd0, $wd1, implicit-def $ccr
+ $wd3 = ADD16dd $wd3, $wd2, implicit-def $ccr
+ $d0 = ADD32rr $d0, $d1, implicit-def $ccr
+ $d0 = ADD32rr $d0, $a1, implicit-def $ccr
+ $d7 = ADD32rr $d7, $a1, implicit-def $ccr
+ $a0 = ADD32rr $a0, $d1, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_BI.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_BI.mir
new file mode 100644
index 000000000000..635bf4477451
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_BI.mir
@@ -0,0 +1,44 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CMP8BI,CMP32BI
+
+#------------------------------------------------------------------------------
+# MxCMP_BI class used for compare operations and operates on absolute memory
+# locations and immediate data. It uses MxArithImmEncoding encoding class.
+# NOTE: CMP is calculated by subtracting LHS(Imm) from RHS(ABS)
+#------------------------------------------------------------------------------
+
+
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD 0 0 0 0 1 1 0 0 | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# CMP8BI: 0 0 0 0 1 1 0 0 . 0 0 1 1 1 0 0 1
+# CMP8BI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP8BI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP8BI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP8BI-SAME: 0 0 0 0 1 1 0 0 . 0 0 1 1 1 0 0 1
+# CMP8BI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# CMP8BI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP8BI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32BI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 1 0 0 1
+# CMP32BI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32BI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32BI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32BI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32BI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 1 0 0 1
+# CMP32BI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32BI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# CMP32BI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32BI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxCMP_BI
+body: |
+ bb.0:
+ CMP8bi 0, -1, implicit-def $ccr
+ CMP8bi -1, 0, implicit-def $ccr
+ CMP32bi -1, 0, implicit-def $ccr
+ CMP32bi 42, -1, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_MI.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_MI.mir
new file mode 100644
index 000000000000..77037b22231a
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_MI.mir
@@ -0,0 +1,174 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CMP8KI,CMP32KI,CMP8QI,CMP32QI,CMP8FI,CMP32FI
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CMP8PI,CMP32PI,CMP8JI,CMP32JI
+
+#------------------------------------------------------------------------------
+# MxCMP_MI class used for compare operations and operates on memory data and
+# immediate data. It uses MxArithImmEncoding encoding class.
+# NOTE: CMP is calculated by subtracting LHS(Imm) from RHS(Mem)
+#------------------------------------------------------------------------------
+
+
+--- # PCI
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD 0 0 0 0 1 1 0 0 | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# CMP8KI: 0 0 0 0 1 1 0 0 . 0 0 1 1 1 0 1 1
+# CMP8KI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP8KI-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP8KI-SAME: 0 0 0 0 1 1 0 0 . 0 0 1 1 1 0 1 1
+# CMP8KI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# CMP8KI-SAME: 0 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32KI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 1 0 1 1
+# CMP32KI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32KI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32KI-SAME: 0 1 1 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32KI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 1 0 1 1
+# CMP32KI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32KI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# CMP32KI-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxCMP_MI_PCI
+body: |
+ bb.0:
+ CMP8ki 0, -1, $d1, implicit-def $ccr
+ CMP8ki -1, 0, $d0, implicit-def $ccr
+ CMP32ki -1, 0, $d7, implicit-def $ccr
+ CMP32ki 42, -1, $d1, implicit-def $ccr
+
+...
+--- # PCD
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD 0 0 0 0 1 1 0 0 | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# CMP8QI-SAME: 0 0 0 0 1 1 0 0 . 0 0 1 1 1 0 1 0
+# CMP8QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP8QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP8QI-SAME: 0 0 0 0 1 1 0 0 . 0 0 1 1 1 0 1 0
+# CMP8QI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# CMP8QI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP32QI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 1 0 1 0
+# CMP32QI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32QI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32QI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 1 0 1 0
+# CMP32QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# CMP32QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxCMP_MI_PCD
+body: |
+ bb.0:
+ CMP8qi 0, 0, implicit-def $ccr
+ CMP8qi -1, -1, implicit-def $ccr
+ CMP32qi -1, 0, implicit-def $ccr
+ CMP32qi 42, 0, implicit-def $ccr
+
+...
+--- # ARII
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD 0 0 0 0 1 1 0 0 | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# CMP8FI-SAME: 0 0 0 0 1 1 0 0 . 0 0 1 1 0 0 0 1
+# CMP8FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP8FI-SAME: 1 0 0 0 1 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP8FI-SAME: 0 0 0 0 1 1 0 0 . 0 0 1 1 0 0 0 0
+# CMP8FI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# CMP8FI-SAME: 1 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32FI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 0 1 1 0
+# CMP32FI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32FI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32FI-SAME: 1 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32FI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 1 0 0 0 1
+# CMP32FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# CMP32FI-SAME: 1 0 0 0 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxCMP_MI_ARII
+body: |
+ bb.0:
+ CMP8fi 0, -1, $a1, $a0, implicit-def $ccr
+ CMP8fi -1, 0, $a0, $a0, implicit-def $ccr
+ CMP32fi -1, 0, $a6, $a0, implicit-def $ccr
+ CMP32fi 42, -1, $a1, $a0, implicit-def $ccr
+
+...
+--- # ARID
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD 0 0 0 0 1 1 0 0 | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# CMP8PI: 0 0 0 0 1 1 0 0 . 0 0 1 0 1 0 0 1
+# CMP8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP8PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP8PI-SAME: 0 0 0 0 1 1 0 0 . 0 0 1 0 1 0 0 0
+# CMP8PI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# CMP8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32PI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 0 1 1 1 0
+# CMP32PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CMP32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP32PI-SAME: 0 0 0 0 1 1 0 0 . 1 0 1 0 1 0 0 1
+# CMP32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# CMP32PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxCMP_MI_ARID
+body: |
+ bb.0:
+ CMP8pi 0, -1, $a1, implicit-def $ccr
+ CMP8pi -1, 0, $a0, implicit-def $ccr
+ CMP32pi -1, 0, $a6, implicit-def $ccr
+ CMP32pi 42, -1, $a1, implicit-def $ccr
+
+...
+--- # ARI
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# OPWORD 0 0 0 0 1 1 0 0 | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# CMP8JI-SAME: 0 0 0 0 1 1 0 0 . 0 0 0 1 0 0 0 1
+# CMP8JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP8JI-SAME: 0 0 0 0 1 1 0 0 . 0 0 0 1 0 0 0 0
+# CMP8JI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP32JI-SAME: 0 0 0 0 1 1 0 0 . 1 0 0 1 0 1 1 0
+# CMP32JI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP32JI-SAME: 0 0 0 0 1 1 0 0 . 1 0 0 1 0 0 0 1
+# CMP32JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+name: MxCMP_MI_ARI
+body: |
+ bb.0:
+ CMP8ji 0, $a1, implicit-def $ccr
+ CMP8ji -1, $a0, implicit-def $ccr
+ CMP32ji -1, $a6, implicit-def $ccr
+ CMP32ji 42, $a1, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RI.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RI.mir
new file mode 100644
index 000000000000..a3e40de348cc
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RI.mir
@@ -0,0 +1,36 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CMP8DI,CMP32DI
+
+#------------------------------------------------------------------------------
+# MxCMP_RI class used for compare operations and operates on data registers and
+# immediate data. It uses MxArithImmEncoding encoding class.
+# NOTE: CMP is calculated by subtracting LHS(Imm) from RHS(Dn)
+#------------------------------------------------------------------------------
+
+
+# -------------------------------+-------+-----------+-----------
+# F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# -------------------------------+-------+-----------+-----------
+# 0 0 0 0 1 1 0 0 | SIZE | MODE | REG
+# -------------------------------+-------+-----------+-----------
+# CMP8DI: 0 0 0 0 1 1 0 0 . 0 0 0 0 0 0 0 1
+# CMP8DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# CMP8DI-SAME: 0 0 0 0 1 1 0 0 . 0 0 0 0 0 0 0 0
+# CMP8DI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# CMP32DI-SAME: 0 0 0 0 1 1 0 0 . 1 0 0 0 0 1 1 1
+# CMP32DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 1 1 0 1
+# -------------------------------+-------+-----------+-----------
+# CMP32DI-SAME: 0 0 0 0 1 1 0 0 . 1 0 0 0 0 0 0 1
+# CMP32DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CMP32DI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+name: MxCMP_RI
+body: |
+ bb.0:
+ CMP8di 0, $bd1, implicit-def $ccr
+ CMP8di -1, $bd0, implicit-def $ccr
+ CMP32di 13, $d7, implicit-def $ccr
+ CMP32di 42, $d1, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RM.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RM.mir
new file mode 100644
index 000000000000..27b13099c81d
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RM.mir
@@ -0,0 +1,125 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CMP8DF,CMP32DF
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CMP8DP,CMP32DP,CMP8DJ,CMP32DJ
+
+#------------------------------------------------------------------------------
+# MxCMP_RM class used for compare operations and operates on memory data and
+# register. It uses MxArithEncoding encoding class.
+# NOTE: CMP is calculated by subtracting LHS(Mem) from RHS(Reg)
+#------------------------------------------------------------------------------
+
+--- # PCI
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# CMP8DK: 1 0 1 1 0 0 0 0 . 0 0 1 1 1 0 1 1
+# CMP8DK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# CMP8DK-SAME: 1 0 1 1 0 0 0 0 . 0 0 1 1 1 0 1 1
+# CMP8DK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# CMP32DK-SAME: 1 0 1 1 0 0 0 0 . 1 0 1 1 1 0 1 1
+# CMP32DK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+#
+# NOTE Immediates for pc-rel instructions use relocations and addendum is encoded
+# inside the relocation record thus there are 0s instead of the value.
+name: MxBiArOp_RFRM_PCI
+body: |
+ bb.0:
+ CMP8dk $bd0, 0, $d1, implicit-def $ccr
+ CMP8dk $bd0, -1, $d1, implicit-def $ccr
+ CMP32dk $d0, 0, $d1, implicit-def $ccr
+
+...
+--- # PCD
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# CMP8DQ-SAME: 1 0 1 1 0 0 0 0 . 0 0 1 1 1 0 1 0
+# CMP8DQ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# CMP32DQ-SAME: 1 0 1 1 0 0 0 0 . 1 0 1 1 1 0 1 0
+# CMP32DQ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+#
+# NOTE Immediates for pc-rel instructions use relocations and addendum is encoded
+# inside the relocation record thus there are 0s instead of the value.
+name: MxBiArOp_RFRM_PCD
+body: |
+ bb.0:
+ CMP8dq $bd0, 0, implicit-def $ccr
+ CMP32dq $d0, -1, implicit-def $ccr
+
+...
+--- # ARII
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# CMP8DF: 1 0 1 1 0 0 0 0 . 0 0 1 1 0 0 0 0
+# CMP8DF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# CMP8DF-SAME: 1 0 1 1 0 0 0 0 . 0 0 1 1 0 0 0 0
+# CMP8DF-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# CMP32DF-SAME: 1 0 1 1 0 0 0 0 . 1 0 1 1 0 0 0 1
+# CMP32DF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# CMP32DF-SAME: 1 0 1 1 0 0 1 0 . 1 0 1 1 0 0 1 0
+# CMP32DF-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxCMP_RM_ARII
+body: |
+ bb.0:
+ CMP8df $bd0, 0, $a0, $d1, implicit-def $ccr
+ CMP8df $bd0, -1, $a0, $d1, implicit-def $ccr
+ CMP32df $d0, 0, $a1, $d1, implicit-def $ccr
+ CMP32df $d1, 0, $a2, $a2, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# CMP8DP: 1 0 1 1 0 0 0 0 . 0 0 1 0 1 0 0 0
+# CMP8DP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# CMP32DP-SAME: 1 0 1 1 0 0 0 0 . 1 0 1 0 1 0 0 1
+# CMP32DP-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxCMP_RM_ARID
+body: |
+ bb.0:
+ CMP8dp $bd0, 0, $a0, implicit-def $ccr
+ CMP32dp $d0, -1, $a1, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# OPWORD x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# CMP8DJ-SAME: 1 0 1 1 0 0 0 0 . 0 0 0 1 0 0 0 0
+# ---------------------------------------------------------------
+# CMP32DJ-SAME: 1 0 1 1 0 1 1 0 . 1 0 0 1 0 0 0 1
+name: MxCMP_RM_ARI
+body: |
+ bb.0:
+ CMP8dj $bd0, $a0, implicit-def $ccr
+ CMP32dj $d3, $a1, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RR.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RR.mir
new file mode 100644
index 000000000000..61e12e230762
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxCMP_RR.mir
@@ -0,0 +1,27 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CMP8DD,CMP32DD
+
+#------------------------------------------------------------------------------
+# MxCMP_RR class used for compare operations and operates on data registers only.
+# It uses MxArithEncoding encoding class and MxOpModeNdEA opmode class.
+# NOTE: CMP is calculated by subtracting LHS(EA) from RHS(Dn)
+#------------------------------------------------------------------------------
+
+
+# ---------------+-----------+-----------+-----------+-----------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------+-----------+-----------+-----------+-----------
+# x x x x | REG | OPMODE | MODE | REG
+# ---------------+-----------+-----------+-----------+-----------
+# CMP8DD: 1 0 1 1 0 0 1 0 . 0 0 0 0 0 0 0 0
+# CMP8DD-SAME: 1 0 1 1 0 1 0 0 . 0 0 0 0 0 0 1 1
+# CMP32DD-SAME: 1 0 1 1 0 0 1 0 . 1 0 0 0 0 0 0 0
+# CMP32DD-SAME: 1 0 1 1 0 0 1 0 . 1 0 0 0 0 1 1 1
+name: MxCMP_RR
+body: |
+ bb.0:
+ CMP8dd $bd0, $bd1, implicit-def $ccr
+ CMP8dd $bd3, $bd2, implicit-def $ccr
+ CMP32dd $d0, $d1, implicit-def $ccr
+ CMP32dd $d7, $d1, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxDiMu.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxDiMu.mir
new file mode 100644
index 000000000000..4382cb3a03c4
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxDiMu.mir
@@ -0,0 +1,48 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SDIVD32D16,UDIVD32D16,SMULD32D16,UMULD32D16
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SDIVD32I16,UDIVD32I16,SMULD32I16,UMULD32I16
+
+#------------------------------------------------------------------------------
+# MxDiMu is used for sign/unsigned division/multiply of word size data
+#------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------
+# F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0
+# ---------------------------------------------------------------
+# x x x x | REG | OPMODE | MODE | REG
+# ---------------------------------------------------------------
+# SDIVD32D16: 1 0 0 0 0 0 0 1 . 1 1 0 0 0 0 0 1
+# ---------------------------------------------------------------
+# UDIVD32D16-SAME: 1 0 0 0 0 0 0 0 . 1 1 0 0 0 0 0 1
+# ---------------------------------------------------------------
+# SDIVD32I16: 1 0 0 0 0 0 0 1 . 1 1 1 1 1 1 0 0
+# SDIVD32I16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# UDIVD32I16-SAME: 1 0 0 0 0 0 0 0 . 1 1 1 1 1 1 0 0
+# UDIVD32I16-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# SMULD32D16-SAME: 1 1 0 0 0 0 0 1 . 1 1 0 0 0 0 0 1
+# ---------------------------------------------------------------
+# UMULD32D16-SAME: 1 1 0 0 0 0 0 0 . 1 1 0 0 0 0 0 1
+# ---------------------------------------------------------------
+# SMULD32I16-SAME: 1 1 0 0 0 0 0 1 . 1 1 1 1 1 1 0 0
+# SMULD32I16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# UMULD32I16-SAME: 1 1 0 0 0 0 0 0 . 1 1 1 1 1 1 0 0
+# UMULD32I16-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+name: MxDiMu
+body: |
+ bb.0:
+ $d0 = SDIVd32d16 $d0, $wd1, implicit-def $ccr
+ $d0 = UDIVd32d16 $d0, $wd1, implicit-def $ccr
+ $d0 = SDIVd32i16 $d0, 0, implicit-def $ccr
+ $d0 = UDIVd32i16 $d0, -1, implicit-def $ccr
+ $d0 = SMULd32d16 $d0, $wd1, implicit-def $ccr
+ $d0 = UMULd32d16 $d0, $wd1, implicit-def $ccr
+ $d0 = SMULd32i16 $d0, 0, implicit-def $ccr
+ $d0 = UMULd32i16 $d0, -1, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxExt.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxExt.mir
new file mode 100644
index 000000000000..06d055365e4d
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxExt.mir
@@ -0,0 +1,25 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=EXT16,EXT32
+
+#------------------------------------------------------------------------------
+# MxExt sign extends data inside a register
+#------------------------------------------------------------------------------
+
+
+# ---------------------------------------------------------------
+# 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
+# ---------------------------------------------------------------
+# EXT16: 0 1 0 0 1 0 0 0 . 1 0 0 0 0 0 0 0
+# EXT16-SAME: 0 1 0 0 1 0 0 0 . 1 0 0 0 0 0 1 1
+# EXT32-SAME: 0 1 0 0 1 0 0 0 . 1 1 0 0 0 0 0 0
+# EXT32-SAME: 0 1 0 0 1 0 0 0 . 1 1 0 0 0 1 1 1
+name: MxEXT
+body: |
+ bb.0:
+ $wd0 = EXT16 $wd0, implicit-def $ccr
+ $wd3 = EXT16 $wd3, implicit-def $ccr
+ $d0 = EXT32 $d0, implicit-def $ccr
+ $d7 = EXT32 $d7, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxNEG.mir b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxNEG.mir
new file mode 100644
index 000000000000..d40f7141118e
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Arith/Classes/MxNEG.mir
@@ -0,0 +1,39 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=NEG8D,NEG32D,NEGX8D,NEGX32D
+
+#------------------------------------------------------------------------------
+# MxNEG is used to negate a number
+#------------------------------------------------------------------------------
+
+
+--- # NEG
+# ---------------+---------------+-------+-----------+-----------
+# F E D C | B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# ---------------+---------------+-------+-----------------------
+# 0 1 0 0 | x x x x | SIZE | MODE | REG
+# ---------------+---------------+-------+-----------+-----------
+# NEG8D: 0 1 0 0 0 1 0 0 . 0 0 0 0 0 0 0 0
+# NEG32D-SAME: 0 1 0 0 0 1 0 0 . 1 0 0 0 0 0 0 0
+name: MxNEG
+body: |
+ bb.0:
+ $bd0 = NEG8d $bd0, implicit-def $ccr
+ $d0 = NEG32d $d0, implicit-def $ccr
+
+...
+--- # NEGX
+# ---------------+---------------+-------+-----------+-----------
+# F E D C | B A 9 8 | 7 6 | 5 4 3 | 2 1 0
+# ---------------+---------------+-------+-----------------------
+# 0 1 0 0 | x x x x | SIZE | MODE | REG
+# ---------------+---------------+-------+-----------+-----------
+# NEGX8D-SAME: 0 1 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# NEGX32D-SAME: 0 1 0 0 0 0 0 0 . 1 0 0 0 0 0 0 0
+name: MxNEGX
+body: |
+ bb.0:
+ $bd0 = NEGX8d $bd0, implicit $ccr, implicit-def $ccr
+ $d0 = NEGX32d $d0, implicit $ccr, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MI.mir b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MI.mir
new file mode 100644
index 000000000000..7baf3b2bbb7b
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MI.mir
@@ -0,0 +1,115 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BTST8KI,BTST8QI,BTST8FI,BTST8PI,BTST8JI
+
+#------------------------------------------------------------------------------
+# MxBTST_MI class used for BTST operations, the source is locate in memory and
+# the bit number is immediate value. This instruciton can only operate on 8 bits.
+#------------------------------------------------------------------------------
+
+
+--- # PCI
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# BTST8KI: 0 0 0 0 1 0 0 0 . 0 0 1 1 1 0 1 1
+# BTST8KI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# BTST8KI-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# BTST8KI-SAME: 0 0 0 0 1 0 0 0 . 0 0 1 1 1 0 1 1
+# BTST8KI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# BTST8KI-SAME: 0 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBTST_MI_PCI
+body: |
+ bb.0:
+ BTST8ki -1, $d1, 0, implicit-def $ccr
+ BTST8ki 0, $d0, 1, implicit-def $ccr
+
+...
+--- # PCD
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# BTST8QI-SAME: 0 0 0 0 1 0 0 0 . 0 0 1 1 1 0 1 0
+# BTST8QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# BTST8QI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# BTST8QI-SAME: 0 0 0 0 1 0 0 0 . 0 0 1 1 1 0 1 0
+# BTST8QI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# BTST8QI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+name: MxBTST_MI_PCD
+body: |
+ bb.0:
+ BTST8qi 0, 0, implicit-def $ccr
+ BTST8qi -1, -1, implicit-def $ccr
+
+...
+--- # ARII
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# BTST8FI-SAME: 0 0 0 0 1 0 0 0 . 0 0 1 1 0 0 0 1
+# BTST8FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# BTST8FI-SAME: 1 0 0 0 1 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# BTST8FI-SAME: 0 0 0 0 1 0 0 0 . 0 0 1 1 0 0 0 0
+# BTST8FI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# BTST8FI-SAME: 1 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBTST_MI_ARII
+body: |
+ bb.0:
+ BTST8fi -1, $a1, $a0, 0, implicit-def $ccr
+ BTST8fi 0, $a0, $a0, -1, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# BTST8PI-SAME: 0 0 0 0 1 0 0 0 . 0 0 1 0 1 0 0 1
+# BTST8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# BTST8PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# BTST8PI-SAME: 0 0 0 0 1 0 0 0 . 0 0 1 0 1 0 0 0
+# BTST8PI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# BTST8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxBTST_MI_ARID
+body: |
+ bb.0:
+ BTST8pi -1, $a1, 0, implicit-def $ccr
+ BTST8pi 0, $a0, -1, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# BTST8JI-SAME: 0 0 0 0 1 0 0 0 . 0 0 0 1 0 0 0 1
+# BTST8JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# BTST8JI-SAME: 0 0 0 0 1 0 0 0 . 0 0 0 1 0 0 0 0
+# BTST8JI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+name: MxBTST_MI_ARI
+body: |
+ bb.0:
+ BTST8ji $a1, 0, implicit-def $ccr
+ BTST8ji $a0, -1, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MR.mir b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MR.mir
new file mode 100644
index 000000000000..aa2fb21a162b
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_MR.mir
@@ -0,0 +1,104 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BTST8KD,BTST8QD,BTST8FD,BTST8PD,BTST8JD
+
+#------------------------------------------------------------------------------
+# MxBTST_MR class used for BTST operations, the source is locate in memory and
+# the bit number is in register. This instruciton can only operate on 8 bits.
+#------------------------------------------------------------------------------
+
+
+--- # PCI
+# ---------------+-----------+-----------+-----------+-----------
+# 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
+# ---------------+-----------+-----------+-----------+-----------
+# BTST8KD: 0 0 0 0 0 0 0 1 . 0 0 1 1 1 0 1 1
+# BTST8KD-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# BTST8KD-SAME: 0 0 0 0 0 0 1 1 . 0 0 1 1 1 0 1 1
+# BTST8KD-SAME: 0 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBTST_MR_PCI
+body: |
+ bb.0:
+ BTST8kd -1, $d1, $bd0, implicit-def $ccr
+ BTST8kd 0, $d0, $bd1, implicit-def $ccr
+
+...
+--- # PCD
+# ---------------+-----------+-----------+-----------+-----------
+# 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
+# ---------------+-----------+-----------+-----------+-----------
+# BTST8QD-SAME: 0 0 0 0 0 0 0 1 . 0 0 1 1 1 0 1 0
+# BTST8QD-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------+-----------+-----------
+# BTST8QD-SAME: 0 0 0 0 0 0 1 1 . 0 0 1 1 1 0 1 0
+# BTST8QD-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+name: MxBTST_MR_PCD
+body: |
+ bb.0:
+ BTST8qd 0, $bd0, implicit-def $ccr
+ BTST8qd -1, $bd1, implicit-def $ccr
+
+...
+--- # ARII
+# ---------------+-----------+-----------+-----------+-----------
+# 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
+# ---------------+-----------+-----------+-----------+-----------
+# BTST8FD-SAME: 0 0 0 0 0 0 0 1 . 0 0 1 1 0 0 0 1
+# BTST8FD-SAME: 1 0 0 0 1 0 0 0 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# BTST8FD-SAME: 0 0 0 0 0 0 1 1 . 0 0 1 1 0 0 0 0
+# BTST8FD-SAME: 1 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxBTST_MR_ARII
+body: |
+ bb.0:
+ BTST8fd -1, $a1, $a0, $bd0, implicit-def $ccr
+ BTST8fd 0, $a0, $a0, $bd1, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------+-----------+-----------+-----------+-----------
+# 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
+# ---------------+-----------+-----------+-----------+-----------
+# BTST8PD-SAME: 0 0 0 0 0 0 0 1 . 0 0 1 0 1 0 0 1
+# BTST8PD-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# -------------------------------+-------+-----------+-----------
+# BTST8PD-SAME: 0 0 0 0 0 0 1 1 . 0 0 1 0 1 0 0 0
+# BTST8PD-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxBTST_MR_ARID
+body: |
+ bb.0:
+ BTST8pd -1, $a1, $bd0, implicit-def $ccr
+ BTST8pd 0, $a0, $bd1, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------+-----------+-----------+-----------+-----------
+# 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
+# ---------------+-----------+-----------+-----------+-----------
+# BTST8JD-SAME: 0 0 0 0 0 0 0 1 . 0 0 0 1 0 0 0 1
+# BTST8JD-SAME: 0 0 0 0 0 0 1 1 . 0 0 0 1 0 0 0 0
+name: MxBTST_MR_ARI
+body: |
+ bb.0:
+ BTST8jd $a1, $bd0, implicit-def $ccr
+ BTST8jd $a0, $bd1, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RI.mir b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RI.mir
new file mode 100644
index 000000000000..69dcfac9cbef
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RI.mir
@@ -0,0 +1,25 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BTST32DI
+
+#------------------------------------------------------------------------------
+# MxBTST_RI class used for BTST operations, the source is in a data register and
+# the bit number is a immediate. This instruction can only operate on 32 bits
+#------------------------------------------------------------------------------
+
+
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# BTST32DI: 0 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# BTST32DI: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# ---------------------------------------------------------------
+# BTST32DI: 0 0 0 0 1 0 0 0 . 0 0 0 0 0 0 1 1
+# BTST32DI: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxBTST_RI
+body: |
+ bb.0:
+ BTST32di $d0, 1, implicit-def $ccr
+ BTST32di $d3, 0, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RR.mir b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RR.mir
new file mode 100644
index 000000000000..75ca79e53d22
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Bits/Classes/MxBTST_RR.mir
@@ -0,0 +1,22 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BTST32DD
+
+#------------------------------------------------------------------------------
+# MxBTST_RR class used for BTST operations, where both the source and bit number
+# are in registers. This instruction can only operate on 32 bits
+#------------------------------------------------------------------------------
+
+
+# ---------------+-----------+-----------+-----------+-----------
+# 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
+# ---------------+-----------+-----------+-----------+-----------
+# BTST32DD: 0 0 0 0 0 0 1 1 . 0 0 0 0 0 0 0 0
+# BTST32DD: 0 0 0 0 0 0 0 1 . 0 0 0 0 0 0 1 1
+name: MxBTST_RR
+body: |
+ bb.0:
+ BTST32dd $d0, $d1, implicit-def $ccr
+ BTST32dd $d3, $d0, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBRA.mir b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBRA.mir
new file mode 100644
index 000000000000..55f0b37b52a9
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBRA.mir
@@ -0,0 +1,49 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BRA8,BRA16
+
+#------------------------------------------------------------------------------
+# MxBRA unconditionally branches somewhere
+#------------------------------------------------------------------------------
+
+--- # MxBRA8
+# -------------------------------+-------------------------------
+# 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
+# -------------------------------+-------------------------------
+# BRA8: 0 1 1 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# BRA8-SAME: 0 1 1 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+#
+# NOTE MxBRA branches cannot encode 0 displacement, 0 in displacement instructs
+# to use additional word. Also it cannot encode -1 since all 1s instruct to use
+# two additional words to encode 32bit offset(since M68020).
+name: MxBRA8
+body: |
+ bb.0:
+ BRA8 1, implicit $ccr
+ BRA8 42, implicit $ccr
+
+...
+--- # MxBRA16
+# -------------------------------+-------------------------------
+# F E D C B A 9 8 | 7 6 5 4 3 2 1 0
+# -------------------------------+-------------------------------
+# 0 1 1 0 0 0 0 0 | 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BRA16-SAME: 0 1 1 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# BRA16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# -------------------------------+-------------------------------
+# BRA16-SAME: 0 1 1 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# BRA16-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# BRA16-SAME: 0 1 1 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# BRA16-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+name: MxBRA16
+body: |
+ bb.0:
+ BRA16 0, implicit $ccr
+ BRA16 -1, implicit $ccr
+ BRA16 42, implicit $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBcc.mir b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBcc.mir
new file mode 100644
index 000000000000..ef75e35aaf44
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxBcc.mir
@@ -0,0 +1,126 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BCC8,BLS8,BLT8,BEQ8,BMI8,BNE8,BGE8,BCS8,BPL8
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BPL8,BGT8,BHI8,BVC8,BLE8,BVS8,BCC16,BLS16
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BLT16,BEQ16,BMI16,BNE16,BGE16,BCS16,BPL16
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=BGT16,BHI16,BVC16,BLE16,BVS16
+
+#------------------------------------------------------------------------------
+# MxScc branches if the condition is True
+#------------------------------------------------------------------------------
+
+--- # MxBcc8
+# ---------------+---------------+-------------------------------
+# F E D C | B A 9 8 | 7 6 5 4 3 2 1 0
+# ---------------+---------------+-------------------------------
+# 0 1 1 0 | CONDITION | 8-BIT DISPLACEMENT
+# ---------------+---------------+-------------------------------
+# BHI8: 0 1 1 0 0 0 1 0 . 0 0 0 0 0 0 0 1
+# BLS8: 0 1 1 0 0 0 1 1 . 0 0 1 0 1 0 1 0
+# BCC8-SAME: 0 1 1 0 0 1 0 0 . 0 0 0 0 0 0 0 1
+# BCS8-SAME: 0 1 1 0 0 1 0 1 . 0 0 0 0 0 0 0 1
+# BNE8-SAME: 0 1 1 0 0 1 1 0 . 0 0 0 0 0 0 0 1
+# BEQ8-SAME: 0 1 1 0 0 1 1 1 . 0 0 0 0 0 0 0 1
+# BVC8-SAME: 0 1 1 0 1 0 0 0 . 0 0 0 0 0 0 0 1
+# BVS8-SAME: 0 1 1 0 1 0 0 1 . 0 0 0 0 0 0 0 1
+# BPL8-SAME: 0 1 1 0 1 0 1 0 . 0 0 0 0 0 0 0 1
+# BMI8-SAME: 0 1 1 0 1 0 1 1 . 0 0 0 0 0 0 0 1
+# BGE8-SAME: 0 1 1 0 1 1 0 0 . 0 0 0 0 0 0 0 1
+# BLT8-SAME: 0 1 1 0 1 1 0 1 . 0 0 0 0 0 0 0 1
+# BGT8-SAME: 0 1 1 0 1 1 1 0 . 0 0 0 0 0 0 0 1
+# BLE8-SAME: 0 1 1 0 1 1 1 1 . 0 0 0 0 0 0 0 1
+#
+# NOTE MxBCC8 branches cannot encode 0 displacement, 0 in displacement instructs
+# to use additional word. Also it cannot encode -1 since all 1s instruct to use
+# two additional words to encode 32bit offset(since M68020).
+name: MxBcc8
+body: |
+ bb.0:
+ Bhi8 1, implicit $ccr
+ Bls8 42, implicit $ccr
+ Bcc8 1, implicit $ccr
+ Bcs8 1, implicit $ccr
+ Bne8 1, implicit $ccr
+ Beq8 1, implicit $ccr
+ Bvc8 1, implicit $ccr
+ Bvs8 1, implicit $ccr
+ Bpl8 1, implicit $ccr
+ Bmi8 1, implicit $ccr
+ Bge8 1, implicit $ccr
+ Blt8 1, implicit $ccr
+ Bgt8 1, implicit $ccr
+ Ble8 1, implicit $ccr
+
+...
+--- # MxBcc16
+# ---------------+---------------+-------------------------------
+# F E D C | B A 9 8 | 7 6 5 4 3 2 1 0
+# ---------------+---------------+-------------------------------
+# 0 1 1 0 | CONDITION | 0 0 0 0 0 0 0 0
+# ---------------+---------------+-------------------------------
+# BHI16: 0 1 1 0 0 0 1 0 . 0 0 0 0 0 0 0 0
+# BHI16-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# BLS16-SAME: 0 1 1 0 0 0 1 1 . 0 0 0 0 0 0 0 0
+# BLS16-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# ---------------------------------------------------------------
+# BCC16-SAME: 0 1 1 0 0 1 0 0 . 0 0 0 0 0 0 0 0
+# BCC16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BCS16: 0 1 1 0 0 1 0 1 . 0 0 0 0 0 0 0 0
+# BCS16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BNE16-SAME: 0 1 1 0 0 1 1 0 . 0 0 0 0 0 0 0 0
+# BNE16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BEQ16-SAME: 0 1 1 0 0 1 1 1 . 0 0 0 0 0 0 0 0
+# BGE16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BVC16-SAME: 0 1 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# BVC16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BVS16-SAME: 0 1 1 0 1 0 0 1 . 0 0 0 0 0 0 0 0
+# BVS16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BPL16-SAME: 0 1 1 0 1 0 1 0 . 0 0 0 0 0 0 0 0
+# BPL16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BMI16-SAME: 0 1 1 0 1 0 1 1 . 0 0 0 0 0 0 0 0
+# BMI16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BGE16-SAME: 0 1 1 0 1 1 0 0 . 0 0 0 0 0 0 0 0
+# BLE16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BLT16-SAME: 0 1 1 0 1 1 0 1 . 0 0 0 0 0 0 0 0
+# BLT16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BGT16-SAME: 0 1 1 0 1 1 1 0 . 0 0 0 0 0 0 0 0
+# BGT16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# BLE16-SAME: 0 1 1 0 1 1 1 1 . 0 0 0 0 0 0 0 0
+# BLE16-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxBcc16
+body: |
+ bb.0:
+ Bhi16 -1, implicit $ccr
+ Bls16 42, implicit $ccr
+ Bcc16 0, implicit $ccr
+ Bcs16 0, implicit $ccr
+ Bne16 0, implicit $ccr
+ Beq16 0, implicit $ccr
+ Bvc16 0, implicit $ccr
+ Bvs16 0, implicit $ccr
+ Bpl16 0, implicit $ccr
+ Bmi16 0, implicit $ccr
+ Bge16 0, implicit $ccr
+ Blt16 0, implicit $ccr
+ Bgt16 0, implicit $ccr
+ Ble16 0, implicit $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxCALL.mir b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxCALL.mir
new file mode 100644
index 000000000000..bc941237cc79
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxCALL.mir
@@ -0,0 +1,88 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=CALLK,CALLQ,CALLB,CALLJ
+
+#------------------------------------------------------------------------------
+# MxCALL pushes address of the next instruction and jumps to the location
+#------------------------------------------------------------------------------
+
+--- # MxCALL_PCI
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# CALLK: 0 1 0 0 1 1 1 0 . 1 0 1 1 1 0 1 1
+# CALLK-SAME: 1 0 0 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------+-----------+-----------
+# CALLK-SAME: 0 1 0 0 1 1 1 0 . 1 0 1 1 1 0 1 1
+# CALLK-SAME: 1 0 0 0 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------+-----------+-----------
+# CALLK-SAME: 0 1 0 0 1 1 1 0 . 1 0 1 1 1 0 1 1
+# CALLK-SAME: 1 0 0 0 1 0 0 0 . 0 0 1 0 1 0 1 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxCALL_PCI
+body: |
+ bb.0:
+ CALLk 0, $a0
+ CALLk -1, $a0
+ CALLk 42, $a0
+
+...
+--- # MxCALL_PCD
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# CALLQ-SAME: 0 1 0 0 1 1 1 0 . 1 0 1 1 1 0 1 0
+# CALLQ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------+-----------+-----------
+# CALLQ-SAME: 0 1 0 0 1 1 1 0 . 1 0 1 1 1 0 1 0
+# CALLQ-SAME: 0 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxCALL_PCD
+body: |
+ bb.0:
+ CALLq 0
+ CALLq 32767
+
+...
+--- # MxCALL_ABS
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# CALLB-SAME: 0 1 0 0 1 1 1 0 . 1 0 1 1 1 0 0 1
+# CALLB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# CALLB-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# ---------------------------------------+-----------+-----------
+# CALLB-SAME: 0 1 0 0 1 1 1 0 . 1 0 1 1 1 0 0 1
+# CALLB-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# CALLB-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxCALL_ABS
+body: |
+ bb.0:
+ CALLb 42
+ CALLb -1
+
+...
+--- # MxCALL_ARI
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# CALLJ-SAME: 0 1 0 0 1 1 1 0 . 1 0 0 1 0 0 0 0
+# CALLJ-SAME: 0 1 0 0 1 1 1 0 . 1 0 0 1 0 0 0 1
+# CALLJ-SAME: 0 1 0 0 1 1 1 0 . 1 0 0 1 0 0 1 0
+name: MxCALL_ARI
+body: |
+ bb.0:
+ CALLj $a0
+ CALLj $a1
+ CALLj $a2
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxJMP.mir b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxJMP.mir
new file mode 100644
index 000000000000..8f03fc31d601
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxJMP.mir
@@ -0,0 +1,21 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=JMP32J
+
+#------------------------------------------------------------------------------
+# MxJMP encodes unconditional jump
+#------------------------------------------------------------------------------
+
+--- # MxJMP_ARI
+# ---------------------------------------+-----------+-----------
+# 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
+# ---------------------------------------+-----------+-----------
+# JMP32J: 0 1 0 0 1 1 1 0 . 1 1 0 1 0 0 0 0
+name: MxJMP_ARI
+body: |
+ bb.0:
+ JMP32j $a0
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxNOP.mir b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxNOP.mir
new file mode 100644
index 000000000000..790a1faabc02
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxNOP.mir
@@ -0,0 +1,16 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=NOP
+
+#------------------------------------------------------------------------------
+# MxNOP
+#------------------------------------------------------------------------------
+
+# ---------------------------------------------------------------
+# F E D C B A 9 8 7 6 5 4 3 2 1 0
+# ---------------------------------------------------------------
+# NOP: 0 1 0 0 1 1 1 0 . 0 1 1 1 0 0 0 1
+name: MxNOP
+body: |
+ bb.0:
+ NOP
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxRTS.mir b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxRTS.mir
new file mode 100644
index 000000000000..f7a2027ac104
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxRTS.mir
@@ -0,0 +1,16 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=RTS
+
+#------------------------------------------------------------------------------
+# MxRTS pops return address from the stack and jumps there
+#------------------------------------------------------------------------------
+
+# ---------------------------------------------------------------
+# F E D C B A 9 8 7 6 5 4 3 2 1 0
+# ---------------------------------------------------------------
+# RTS: 0 1 0 0 1 1 1 0 . 0 1 1 1 0 1 0 1
+name: MxRTS
+body: |
+ bb.0:
+ RTS
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxScc.mir b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxScc.mir
new file mode 100644
index 000000000000..9c06906d0fdd
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/Classes/MxScc.mir
@@ -0,0 +1,140 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SETD8CC,SETD8LS,SETD8LT,SETD8EQ,SETD8MI,SETD8F
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SETD8NE,SETD8GE,SETD8CS,SETD8PL,SETD8GT,SETD8T
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SETD8HI,SETD8VC,SETD8LE,SETD8VS,SETP8CC,SETP8LS
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SETP8LT,SETP8EQ,SETP8MI,SETP8F,SETP8NE,SETP8GE
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SETP8CS,SETP8PL,SETP8GT,SETP8T,SETP8HI,SETP8VC
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SETP8LE,SETP8VS
+
+#------------------------------------------------------------------------------
+# MxScc sets byte filled with 1s or 0s based on cc condition
+#------------------------------------------------------------------------------
+
+--- # MxScc_D
+# ---------------+---------------+-------+-----------+-----------
+# 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
+# ---------------+---------------+-------+-----------+-----------
+# SETD8T: 0 1 0 1 0 0 0 0 . 1 1 0 0 0 0 0 0
+# SETD8F: 0 1 0 1 0 0 0 1 . 1 1 0 0 0 0 0 1
+# SETD8HI: 0 1 0 1 0 0 1 0 . 1 1 0 0 0 0 1 0
+# SETD8LS-SAME: 0 1 0 1 0 0 1 1 . 1 1 0 0 0 0 1 1
+# SETD8CC: 0 1 0 1 0 1 0 0 . 1 1 0 0 0 1 0 0
+# SETD8CS-SAME: 0 1 0 1 0 1 0 1 . 1 1 0 0 0 1 0 1
+# SETD8NE-SAME: 0 1 0 1 0 1 1 0 . 1 1 0 0 0 1 1 0
+# SETD8EQ-SAME: 0 1 0 1 0 1 1 1 . 1 1 0 0 0 1 1 1
+# SETD8VC-SAME: 0 1 0 1 1 0 0 0 . 1 1 0 0 0 0 0 0
+# SETD8VS-SAME: 0 1 0 1 1 0 0 1 . 1 1 0 0 0 0 0 0
+# SETD8PL-SAME: 0 1 0 1 1 0 1 0 . 1 1 0 0 0 0 0 0
+# SETD8MI-SAME: 0 1 0 1 1 0 1 1 . 1 1 0 0 0 0 0 0
+# SETD8GE-SAME: 0 1 0 1 1 1 0 0 . 1 1 0 0 0 0 0 0
+# SETD8LT-SAME: 0 1 0 1 1 1 0 1 . 1 1 0 0 0 0 0 0
+# SETD8GT-SAME: 0 1 0 1 1 1 1 0 . 1 1 0 0 0 0 0 0
+# SETD8LE-SAME: 0 1 0 1 1 1 1 1 . 1 1 0 0 0 0 0 0
+name: MxScc_D
+body: |
+ bb.0:
+ $bd0 = SETd8t implicit $ccr
+ $bd1 = SETd8f implicit $ccr
+ $bd2 = SETd8hi implicit $ccr
+ $bd3 = SETd8ls implicit $ccr
+ $bd4 = SETd8cc implicit $ccr
+ $bd5 = SETd8cs implicit $ccr
+ $bd6 = SETd8ne implicit $ccr
+ $bd7 = SETd8eq implicit $ccr
+ $bd0 = SETd8vc implicit $ccr
+ $bd0 = SETd8vs implicit $ccr
+ $bd0 = SETd8pl implicit $ccr
+ $bd0 = SETd8mi implicit $ccr
+ $bd0 = SETd8ge implicit $ccr
+ $bd0 = SETd8lt implicit $ccr
+ $bd0 = SETd8gt implicit $ccr
+ $bd0 = SETd8le implicit $ccr
+
+...
+--- # MxScc_ARID
+# ---------------+---------------+-------+-----------+-----------
+# 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
+# ---------------+---------------+-------+-----------+-----------
+# SETP8T: 0 1 0 1 0 0 0 0 . 1 1 1 0 1 0 0 0
+# SETP8T-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# SETP8F: 0 1 0 1 0 0 0 1 . 1 1 1 0 1 0 0 1
+# SETP8F-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# ---------------------------------------------------------------
+# SETP8HI-SAME: 0 1 0 1 0 0 1 0 . 1 1 1 0 1 0 1 0
+# SETP8HI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8LS-SAME: 0 1 0 1 0 0 1 1 . 1 1 1 0 1 0 1 1
+# SETP8LS-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8CC-SAME: 0 1 0 1 0 1 0 0 . 1 1 1 0 1 1 0 0
+# SETP8CC-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8CS: 0 1 0 1 0 1 0 1 . 1 1 1 0 1 1 0 1
+# SETP8CS-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8NE-SAME: 0 1 0 1 0 1 1 0 . 1 1 1 0 1 1 1 0
+# SETP8NE-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8EQ-SAME: 0 1 0 1 0 1 1 1 . 1 1 1 0 1 0 0 0
+# SETP8EQ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8VC-SAME: 0 1 0 1 1 0 0 0 . 1 1 1 0 1 0 0 0
+# SETP8VC-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8VS: 0 1 0 1 1 0 0 1 . 1 1 1 0 1 0 0 0
+# SETP8VS-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8PL-SAME: 0 1 0 1 1 0 1 0 . 1 1 1 0 1 0 0 0
+# SETP8PL-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8MI-SAME: 0 1 0 1 1 0 1 1 . 1 1 1 0 1 0 0 0
+# SETP8MI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8GE-SAME: 0 1 0 1 1 1 0 0 . 1 1 1 0 1 0 0 0
+# SETP8GE-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8LT: 0 1 0 1 1 1 0 1 . 1 1 1 0 1 0 0 0
+# SETP8LT-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8GT-SAME: 0 1 0 1 1 1 1 0 . 1 1 1 0 1 0 0 0
+# SETP8GT-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# SETP8LE: 0 1 0 1 1 1 1 1 . 1 1 1 0 1 0 0 0
+# SETP8LE-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxScc_ARID
+body: |
+ bb.0:
+ SETp8t -1, $a0, implicit $ccr
+ SETp8f 42, $a1, implicit $ccr
+ SETp8hi 0, $a2, implicit $ccr
+ SETp8ls 0, $a3, implicit $ccr
+ SETp8cc 0, $a4, implicit $ccr
+ SETp8cs 0, $a5, implicit $ccr
+ SETp8ne 0, $a6, implicit $ccr
+ SETp8eq 0, $a0, implicit $ccr
+ SETp8vc 0, $a0, implicit $ccr
+ SETp8vs 0, $a0, implicit $ccr
+ SETp8pl 0, $a0, implicit $ccr
+ SETp8mi 0, $a0, implicit $ccr
+ SETp8ge 0, $a0, implicit $ccr
+ SETp8lt 0, $a0, implicit $ccr
+ SETp8gt 0, $a0, implicit $ccr
+ SETp8le 0, $a0, implicit $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/branch-pc-rel.mir b/llvm/test/CodeGen/M68k/Encoding/Control/branch-pc-rel.mir
new file mode 100644
index 000000000000..fff41ffd087b
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/branch-pc-rel.mir
@@ -0,0 +1,31 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | extract-section .text -h \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# This test checks whether branches have correct offset
+#------------------------------------------------------------------------------
+
+--- # TEXT
+# 0 CHECK: 6702
+# 2 CHECK-SAME: 6008
+# 4 CHECK-SAME: d0bc 0000 0000
+# A CHECK-SAME: 4e75
+# C CHECK-SAME: d0bc 0000 0001
+# 12 CHECK-SAME: 4e75
+name: TEXT
+body: |
+ bb.0:
+ successors: %bb.2,%bb.1
+
+ Beq8 %bb.1, implicit $ccr
+ BRA8 %bb.2
+ bb.1:
+ $d0 = ADD32ri $d0, 0, implicit-def $ccr
+ RET 0, $d0
+ bb.2:
+ $d0 = ADD32ri $d0, 1, implicit-def $ccr
+ RET 0, $d0
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Control/call-pc-rel.mir b/llvm/test/CodeGen/M68k/Encoding/Control/call-pc-rel.mir
new file mode 100644
index 000000000000..d4ea2dc76c24
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Control/call-pc-rel.mir
@@ -0,0 +1,66 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | extract-section .text -h \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# Tests PC-Relative Calls' offsets. The rest requires relocation and tested
+# appropriately elsewhere.
+#------------------------------------------------------------------------------
+
+#
+# <BACKWARD>
+# 00 CHECK: 4e71
+# 02 CHECK-SAME: 4e75
+#
+# <PCI>
+# 04 CHECK-SAME: 4ebb 08fa
+# 08 CHECK-SAME: 4ebb 080a
+#
+# <PCD>
+# 0c CHECK-SAME: 4eba fff2
+# 10 CHECK-SAME: 4eba 0002
+#
+# <FORWARD>
+# 14 CHECK-SAME: 4e71
+# 16 CHECK-SAME: 4e75
+--- |
+
+ define dso_local void @BACKWARD() { entry: ret void }
+ define dso_local void @PCI() { entry: ret void }
+ define dso_local void @PCD() { entry: ret void }
+ define dso_local void @FORWARD() { entry: ret void }
+
+...
+--- # BACKWARD
+name: BACKWARD
+body: |
+ bb.0:
+ NOP
+ RTS
+
+...
+--- # PCI
+name: PCI
+body: |
+ bb.0:
+ CALLk @BACKWARD, $d0
+ CALLk @FORWARD, $d0
+
+...
+--- # PCD
+name: PCD
+body: |
+ bb.0:
+ CALLq @BACKWARD
+ CALLq @FORWARD
+
+...
+--- # FORWARD
+name: FORWARD
+body: |
+ bb.0:
+ NOP
+ RTS
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxLEA.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxLEA.mir
new file mode 100644
index 000000000000..fca013669d7d
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxLEA.mir
@@ -0,0 +1,65 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=LEA32Q,LEA32F,LEA32P
+
+#------------------------------------------------------------------------------
+# MxLEA is used to calculate effective address and load it into a address reg
+#------------------------------------------------------------------------------
+
+--- # PCD
+# ---------------------------------------------------------------
+# 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
+# ---------------------------------------------------------------
+# LEA32Q: 0 1 0 0 0 0 0 1 . 1 1 1 1 1 0 1 0
+# LEA32Q-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# LEA32Q-SAME: 0 1 0 0 0 0 0 1 . 1 1 1 1 1 0 1 0
+# LEA32Q-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxLEA_PCD
+body: |
+ bb.0:
+ $a0 = LEA32q 0, implicit-def $ccr
+ $a0 = LEA32q -1, implicit-def $ccr
+
+...
+--- # ARII
+# ---------------------------------------------------------------
+# 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
+# ---------------------------------------------------------------
+# LEA32F-SAME: 0 1 0 0 0 0 0 1 . 1 1 1 1 0 0 0 1
+# LEA32F-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# LEA32F-SAME: 0 1 0 0 0 0 1 1 . 1 1 1 1 0 0 1 0
+# LEA32F-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxLEA_ARII
+body: |
+ bb.0:
+ $a0 = LEA32f 0, $a1, $d1, implicit-def $ccr
+ $a1 = LEA32f 0, $a2, $a2, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------------------------------------------------------
+# 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
+# ---------------------------------------------------------------
+# LEA32P-SAME: 0 1 0 0 0 0 0 1 . 1 1 1 0 1 0 0 1
+# LEA32P-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# LEA32P-SAME: 0 1 0 0 0 0 0 1 . 1 1 1 0 1 0 0 1
+# LEA32P-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxLEA_ARID
+body: |
+ bb.0:
+ $a0 = LEA32p -1, $a1, implicit-def $ccr
+ $a0 = LEA32p -1, $a1, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_MR.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_MR.mir
new file mode 100644
index 000000000000..6581a71313bd
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_MR.mir
@@ -0,0 +1,52 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOVM32PM,MOVM32JM
+
+#------------------------------------------------------------------------------
+# MxMOVEM_MR is used to store a list of register sequentially into a memory
+# location
+#------------------------------------------------------------------------------
+
+--- # ARID
+# -------------------+---+-----------+---+-----------+-----------
+# 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
+# ---------------------------------------------------------------
+# MOVM32PM: 0 1 0 0 1 0 0 0 . 1 1 1 0 1 0 0 1
+# MOVM32PM-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# MOVM32PM-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOVM32PM-SAME: 0 1 0 0 1 0 0 0 . 1 1 1 0 1 0 0 1
+# MOVM32PM-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 1 1
+# MOVM32PM-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMOVEM_MR_ARID
+body: |
+ bb.0:
+ MOVM32pm 0, $a1, 1
+ MOVM32pm -1, $a1, 3
+
+...
+--- # ARI
+# -------------------+---+-----------+---+-----------+-----------
+# 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
+# -------------------+---+-----------+---+-----------+-----------
+# MOVM32JM-SAME: 0 1 0 0 1 0 0 0 . 1 1 0 1 0 0 0 1
+# MOVM32JM-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# ---------------------------------------------------------------
+# MOVM32JM-SAME: 0 1 0 0 1 0 0 0 . 1 1 0 1 0 0 0 1
+# MOVM32JM-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 1 1
+# ---------------------------------------------------------------
+# REGISTER LIST MASK
+# ---------------------------------------------------------------
+name: MxMOVEM_MR_ARI
+body: |
+ bb.0:
+ MOVM32jm $a1, 1
+ MOVM32jm $a1, 3
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_RM.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_RM.mir
new file mode 100644
index 000000000000..e29b6c9d08c8
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMOVEM_RM.mir
@@ -0,0 +1,52 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOVM32MP,MOVM32MJ
+
+#------------------------------------------------------------------------------
+# MxMOVEM_RM is used to load a list of registers sequentially from a memory
+# location
+#------------------------------------------------------------------------------
+
+--- # ARID
+# -------------------+---+-----------+---+-----------+-----------
+# 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
+# ---------------------------------------------------------------
+# MOVM32MP: 0 1 0 0 1 1 0 0 . 1 1 1 0 1 0 0 1
+# MOVM32MP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# MOVM32MP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOVM32MP-SAME: 0 1 0 0 1 1 0 0 . 1 1 1 0 1 0 0 1
+# MOVM32MP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 1 1
+# MOVM32MP-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMOVEM_RM_ARID
+body: |
+ bb.0:
+ MOVM32mp 1, 0, $a1
+ MOVM32mp 3, -1, $a1
+
+...
+--- # ARI
+# -------------------+---+-----------+---+-----------+-----------
+# 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
+# -------------------+---+-----------+---+-----------+-----------
+# MOVM32MJ-SAME: 0 1 0 0 1 1 0 0 . 1 1 0 1 0 0 0 1
+# MOVM32MJ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 1
+# ---------------------------------------------------------------
+# MOVM32MJ-SAME: 0 1 0 0 1 1 0 0 . 1 1 0 1 0 0 0 1
+# MOVM32MJ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 1 1
+# ---------------------------------------------------------------
+# REGISTER LIST MASK
+# ---------------------------------------------------------------
+name: MxMOVEM_RM_ARI
+body: |
+ bb.0:
+ MOVM32mj 1, $a1
+ MOVM32mj 3, $a1
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMoveCCR.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMoveCCR.mir
new file mode 100644
index 000000000000..c276d3c5fa31
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMoveCCR.mir
@@ -0,0 +1,34 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV16CD,MOV16DC
+
+#------------------------------------------------------------------------------
+# MxMoveToCCR and MxMoveFromCCR load/store condition flag register
+#------------------------------------------------------------------------------
+
+--- # To CCR
+# ---------------------------------------+-----------+-----------
+# F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0
+# ---------------------------------------+-----------+-----------
+# 0 1 0 0 0 1 0 0 1 1 | MODE | REG
+# ---------------------------------------+-----------+-----------
+# MOV16CD: 0 1 0 0 0 1 0 0 . 1 1 0 0 0 0 0 1
+name: MxMoveToCCR
+body: |
+ bb.0:
+ $ccr = MOV16cd $wd1, implicit-def $ccr
+
+...
+--- # From CCR
+# ---------------------------------------+-----------+-----------
+# F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0
+# ---------------------------------------+-----------+-----------
+# 0 1 0 0 0 0 1 0 1 1 | MODE | REG
+# ---------------------------------------+-----------+-----------
+# MOV16DC-SAME: 0 1 0 0 0 0 1 0 . 1 1 0 0 0 0 0 1
+name: MxMoveFromCCR
+body: |
+ bb.0:
+ $wd1 = MOV16dc $ccr, implicit $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MI.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MI.mir
new file mode 100644
index 000000000000..db24b521456f
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MI.mir
@@ -0,0 +1,97 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8FI,MOV32FI,MOV8PI,MOV32PI,MOV8JI,MOV32JI
+
+#------------------------------------------------------------------------------
+# MxMove_MI is used for moving immediate to memory
+#------------------------------------------------------------------------------
+
+--- # ARII
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8FI: 0 0 0 1 0 0 0 1 . 1 0 1 1 1 1 0 0
+# MOV8FI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# MOV8FI-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV8FI-SAME: 0 0 0 1 0 0 0 1 . 1 0 1 1 1 1 0 0
+# MOV8FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# MOV8FI-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32FI-SAME: 0 0 1 0 0 0 1 1 . 1 0 1 1 1 1 0 0
+# MOV32FI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV32FI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV32FI-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32FI-SAME: 0 0 1 0 0 1 0 1 . 1 0 1 1 1 1 0 0
+# MOV32FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32FI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32FI-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxMove_MI_ARII
+body: |
+ bb.0:
+ MOV8fi 0, $a0, $d1, -1, implicit-def $ccr
+ MOV8fi -1, $a0, $d1, 42, implicit-def $ccr
+ MOV32fi 0, $a1, $d1, -1, implicit-def $ccr
+ MOV32fi 0, $a2, $a2, 0, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8PI-SAME: 0 0 0 1 0 0 0 1 . 0 1 1 1 1 1 0 0
+# MOV8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV8PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32PI-SAME: 0 0 1 0 0 0 1 1 . 0 1 1 1 1 1 0 0
+# MOV32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32PI-SAME: 0 0 1 0 0 0 1 1 . 0 1 1 1 1 1 0 0
+# MOV32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32PI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32PI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMove_MI_ARID
+body: |
+ bb.0:
+ MOV8pi 0, $a0, 0, implicit-def $ccr
+ MOV32pi -1, $a1, 0, implicit-def $ccr
+ MOV32pi -1, $a1, 0, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8JI-SAME: 0 0 0 1 0 0 0 0 . 1 0 1 1 1 1 0 0
+# MOV8JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32JI-SAME: 0 0 1 0 0 0 1 0 . 1 0 1 1 1 1 0 0
+# MOV32JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32JI-SAME: 0 0 1 0 0 0 1 0 . 1 0 1 1 1 1 0 0
+# MOV32JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32JI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxMove_MI_ARI
+body: |
+ bb.0:
+ MOV8ji $a0, 0, implicit-def $ccr
+ MOV32ji $a1, 0, implicit-def $ccr
+ MOV32ji $a1, 0, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MM.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MM.mir
new file mode 100644
index 000000000000..60e01f1ad5e6
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MM.mir
@@ -0,0 +1,217 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8JK,MOV32JK,MOV8JQ,MOV32JQ,MOV8FF,MOV32FF
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8PP,MOV32PP,MOV8JJ,MOV32JJ,MOV8OO,MOV32OO
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8EE,MOV32EE,MOV8BB,MOV32BB
+
+#------------------------------------------------------------------------------
+# MxMove_MM is used for moving data from memory to memory
+#------------------------------------------------------------------------------
+
+--- # ARI <- PCI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8JK: 0 0 0 1 0 0 0 0 . 1 0 1 1 1 0 1 1
+# MOV8JK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV8JK-SAME: 0 0 0 1 0 0 0 0 . 1 0 1 1 1 0 1 1
+# MOV8JK-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32JK-SAME: 0 0 1 0 0 0 0 0 . 1 0 1 1 1 0 1 1
+# MOV32JK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32JK-SAME: 0 0 1 0 0 0 1 0 . 1 0 1 1 1 0 1 1
+# MOV32JK-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxMove_RM_ARI_PCI
+body: |
+ bb.0:
+ MOV8jk $a0, 0, $d1, implicit-def $ccr
+ MOV8jk $a0, -1, $d1, implicit-def $ccr
+ MOV32jk $a0, 0, $d1, implicit-def $ccr
+ MOV32jk $a1, 0, $a2, implicit-def $ccr
+
+...
+--- # ARI <- PCD
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8JQ-SAME: 0 0 0 1 0 0 0 0 . 1 0 1 1 1 0 1 0
+# MOV8JQ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32JQ-SAME: 0 0 1 0 0 0 0 0 . 1 0 1 1 1 0 1 0
+# MOV32JQ-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32JQ-SAME: 0 0 1 0 0 0 0 0 . 1 0 1 1 1 0 1 0
+# MOV32JQ-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMove_RM_PCD
+body: |
+ bb.0:
+ MOV8jq $a0, 0, implicit-def $ccr
+ MOV32jq $a0, -1, implicit-def $ccr
+ MOV32jq $a0, -1, implicit-def $ccr
+
+...
+--- # ARII <- ARII
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8FF: 0 0 0 1 0 0 0 1 . 1 0 1 1 0 0 0 0
+# MOV8FF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV8FF-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV8FF-SAME: 0 0 0 1 0 0 0 1 . 1 0 1 1 0 0 0 0
+# MOV8FF-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# MOV8FF-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32FF-SAME: 0 0 1 0 0 0 1 1 . 1 0 1 1 0 0 0 1
+# MOV32FF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32FF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32FF-SAME: 0 0 1 0 0 1 0 1 . 1 0 1 1 0 0 1 0
+# MOV32FF-SAME: 1 0 1 0 1 0 0 0 . 0 0 1 0 1 0 1 0
+# MOV32FF-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxMove_RM_ARII_ARII
+body: |
+ bb.0:
+ MOV8ff -1, $a0, $d1, 0, $a0, $d1, implicit-def $ccr
+ MOV8ff -1, $a0, $d1, -1, $a0, $d1, implicit-def $ccr
+ MOV32ff 0, $a1, $d1, 0, $a1, $d1, implicit-def $ccr
+ MOV32ff 0, $a2, $a2, 42, $a2, $a2, implicit-def $ccr
+
+...
+--- # ARID <- ARID
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8PP: 0 0 0 1 0 0 0 1 . 0 1 1 0 1 0 0 0
+# MOV8PP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV8PP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32PP-SAME: 0 0 1 0 0 0 1 1 . 0 1 1 0 1 0 0 1
+# MOV32PP-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV32PP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32PP-SAME: 0 0 1 0 0 0 1 1 . 0 1 1 0 1 0 0 1
+# MOV32PP-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# MOV32PP-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMove_RM_ARID
+body: |
+ bb.0:
+ MOV8pp 0, $a0, 0, $a0, implicit-def $ccr
+ MOV32pp 0, $a1, -1, $a1, implicit-def $ccr
+ MOV32pp -1, $a1, 42, $a1, implicit-def $ccr
+
+...
+--- # ARIPD <- ARIPD
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8EE: 0 0 0 1 0 0 0 1 . 0 0 1 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32EE-SAME: 0 0 1 0 0 0 1 1 . 0 0 1 0 0 0 0 1
+# ---------------------------------------------------------------
+# MOV32EE-SAME: 0 0 1 0 0 0 1 1 . 0 0 1 0 0 0 0 1
+name: MxMove_RM_ARIPD
+body: |
+ bb.0:
+ MOV8ee $a0, $a0, implicit-def $ccr
+ MOV32ee $a1, $a1, implicit-def $ccr
+ MOV32ee $a1, $a1, implicit-def $ccr
+
+...
+--- # ARIPI <- ARIPI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8OO-SAME: 0 0 0 1 0 0 0 0 . 1 1 0 1 1 0 0 0
+# ---------------------------------------------------------------
+# MOV32OO-SAME: 0 0 1 0 0 0 1 0 . 1 1 0 1 1 0 0 1
+# ---------------------------------------------------------------
+# MOV32OO-SAME: 0 0 1 0 0 0 1 0 . 1 1 0 1 1 0 0 1
+name: MxMove_RM_ARIPI
+body: |
+ bb.0:
+ MOV8oo $a0, $a0, implicit-def $ccr
+ MOV32oo $a1, $a1, implicit-def $ccr
+ MOV32oo $a1, $a1, implicit-def $ccr
+
+...
+--- # ARI <- ARI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8JJ-SAME: 0 0 0 1 0 0 0 0 . 1 0 0 1 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32JJ-SAME: 0 0 1 0 0 0 1 0 . 1 0 0 1 0 0 0 1
+# ---------------------------------------------------------------
+# MOV32JJ-SAME: 0 0 1 0 0 0 1 0 . 1 0 0 1 0 0 0 1
+name: MxMove_RM_ARI
+body: |
+ bb.0:
+ MOV8jj $a0, $a0, implicit-def $ccr
+ MOV32jj $a1, $a1, implicit-def $ccr
+ MOV32jj $a1, $a1, implicit-def $ccr
+
+...
+--- # ABS <- ABS
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8BB-SAME: 0 0 0 1 0 0 1 1 . 1 1 1 1 1 0 0 1
+# MOV8BB-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV8BB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32BB-SAME: 0 0 1 0 0 0 1 1 . 1 1 1 1 1 0 0 1
+# MOV32BB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32BB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32BB-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV32BB-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32BB-SAME: 0 0 1 0 0 0 1 1 . 1 1 1 1 1 0 0 1
+# MOV32BB-SAME: 0 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV32BB-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV32BB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32BB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxMove_RM_ABS
+body: |
+ bb.0:
+ MOV8bb 0, -1, implicit-def $ccr
+ MOV32bb -1, 0, implicit-def $ccr
+ MOV32bb 0, 2147483647, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MR.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MR.mir
new file mode 100644
index 000000000000..bb269a35a09e
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_MR.mir
@@ -0,0 +1,81 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8FD,MOV32FR,MOV8PD,MOV32PR,MOV8JD,MOV32JR
+
+#------------------------------------------------------------------------------
+# MxMove_MR is used for moving data from register to memory
+#------------------------------------------------------------------------------
+
+--- # ARII
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8FD: 0 0 0 1 0 0 0 1 . 1 0 0 0 0 0 0 0
+# MOV8FD-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV8FD-SAME: 0 0 0 1 0 0 0 1 . 1 0 0 0 0 0 0 0
+# MOV8FD-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32FR-SAME: 0 0 1 0 0 0 1 1 . 1 0 0 0 0 0 0 0
+# MOV32FR-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32FR-SAME: 0 0 1 0 0 1 0 1 . 1 0 0 0 0 0 0 1
+# MOV32FR-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxMove_MR_ARII
+body: |
+ bb.0:
+ MOV8fd 0, $a0, $d1, $bd0, implicit-def $ccr
+ MOV8fd -1, $a0, $d1, $bd0, implicit-def $ccr
+ MOV32fr 0, $a1, $d1, $d0, implicit-def $ccr
+ MOV32fr 0, $a2, $a2, $d1, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8PD-SAME: 0 0 0 1 0 0 0 1 . 0 1 0 0 0 0 0 0
+# MOV8PD-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32PR-SAME: 0 0 1 0 0 0 1 1 . 0 1 0 0 0 0 0 0
+# MOV32PR-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32PR-SAME: 0 0 1 0 0 0 1 1 . 0 1 0 0 1 0 0 0
+# MOV32PR-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMove_MR_ARID
+body: |
+ bb.0:
+ MOV8pd 0, $a0, $bd0, implicit-def $ccr
+ MOV32pr -1, $a1, $d0, implicit-def $ccr
+ MOV32pr -1, $a1, $a0, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8JD-SAME: 0 0 0 1 0 0 0 0 . 1 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32JR-SAME: 0 0 1 0 0 0 1 0 . 1 0 0 0 0 0 1 1
+# ---------------------------------------------------------------
+# MOV32JR-SAME: 0 0 1 0 0 0 1 0 . 1 0 0 0 1 1 0 0
+name: MxMove_MR_ARI
+body: |
+ bb.0:
+ MOV8jd $a0, $bd0, implicit-def $ccr
+ MOV32jr $a1, $d3, implicit-def $ccr
+ MOV32jr $a1, $a4, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RI.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RI.mir
new file mode 100644
index 000000000000..17341ab6539a
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RI.mir
@@ -0,0 +1,31 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8DI,MOV32RI
+
+#------------------------------------------------------------------------------
+# MxMove_RI is used for moving immediate to register
+#------------------------------------------------------------------------------
+
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DI: 0 0 0 1 0 0 0 0 . 0 0 1 1 1 1 0 0
+# MOV8DI-SAME: 0 0 0 0 0 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32RI-SAME: 0 0 1 0 0 0 1 0 . 0 1 1 1 1 1 0 0
+# MOV32RI-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32RI-SAME: 0 0 0 0 0 0 0 0 . 0 0 1 0 1 0 1 0
+# ---------------------------------------------------------------
+# MOV32RI-SAME: 0 0 1 0 0 0 1 0 . 0 1 1 1 1 1 0 0
+# MOV32RI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# MOV32RI-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMove_RI
+body: |
+ bb.0:
+ $bd0 = MOV8di -1, implicit-def $ccr
+ $a1 = MOV32ri 42, implicit-def $ccr
+ $a1 = MOV32ri -1, implicit-def $ccr
+
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RM.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RM.mir
new file mode 100644
index 000000000000..648db14fff39
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RM.mir
@@ -0,0 +1,205 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8DK,MOV32RK,MOV8DQ,MOV32RQ,MOV8DF,MOV32RF
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8DP,MOV32RP,MOV8DJ,MOV32RJ,MOV8DO,MOV32RO
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8DE,MOV32RE,MOV8DB,MOV32RB
+
+#------------------------------------------------------------------------------
+# MxMove_RM is used for moving data from memory to register
+#------------------------------------------------------------------------------
+
+--- # PCI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DK: 0 0 0 1 0 0 0 0 . 0 0 1 1 1 0 1 1
+# MOV8DK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV8DK-SAME: 0 0 0 1 0 0 0 0 . 0 0 1 1 1 0 1 1
+# MOV8DK-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32RK-SAME: 0 0 1 0 0 0 0 0 . 0 0 1 1 1 0 1 1
+# MOV32RK-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RK-SAME: 0 0 1 0 0 0 1 0 . 0 0 1 1 1 0 1 1
+# MOV32RK-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxMove_RM_PCI
+body: |
+ bb.0:
+ $bd0 = MOV8dk 0, $d1, implicit-def $ccr
+ $bd0 = MOV8dk -1, $d1, implicit-def $ccr
+ $d0 = MOV32rk 0, $d1, implicit-def $ccr
+ $d1 = MOV32rk 0, $a2, implicit-def $ccr
+
+...
+--- # PCD
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DQ-SAME: 0 0 0 1 0 0 0 0 . 0 0 1 1 1 0 1 0
+# MOV8DQ-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RQ-SAME: 0 0 1 0 0 0 0 0 . 0 0 1 1 1 0 1 0
+# MOV32RQ-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32RQ-SAME: 0 0 1 0 0 0 0 0 . 0 1 1 1 1 0 1 0
+# MOV32RQ-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMove_RM_PCD
+body: |
+ bb.0:
+ $bd0 = MOV8dq 0, implicit-def $ccr
+ $d0 = MOV32rq -1, implicit-def $ccr
+ $a0 = MOV32rq -1, implicit-def $ccr
+
+...
+--- # ARII
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DF: 0 0 0 1 0 0 0 0 . 0 0 1 1 0 0 0 0
+# MOV8DF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV8DF-SAME: 0 0 0 1 0 0 0 0 . 0 0 1 1 0 0 0 0
+# MOV8DF-SAME: 0 0 0 1 1 0 0 0 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32RF-SAME: 0 0 1 0 0 0 0 0 . 0 0 1 1 0 0 0 1
+# MOV32RF-SAME: 0 0 0 1 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RF-SAME: 0 0 1 0 0 0 1 0 . 0 0 1 1 0 0 1 0
+# MOV32RF-SAME: 1 0 1 0 1 0 0 0 . 0 0 0 0 0 0 0 0
+# ---+-----------+---+-------+---+-------------------------------
+# BRIEF DA | REG | L | SCALE | 0 | DISPLACEMENT
+# ---+-----------+---+-------+---+-------------------------------
+name: MxMove_RM_ARII
+body: |
+ bb.0:
+ $bd0 = MOV8df 0, $a0, $d1, implicit-def $ccr
+ $bd0 = MOV8df -1, $a0, $d1, implicit-def $ccr
+ $d0 = MOV32rf 0, $a1, $d1, implicit-def $ccr
+ $d1 = MOV32rf 0, $a2, $a2, implicit-def $ccr
+
+...
+--- # ARID
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DP: 0 0 0 1 0 0 0 0 . 0 0 1 0 1 0 0 0
+# MOV8DP-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RP-SAME: 0 0 1 0 0 0 0 0 . 0 0 1 0 1 0 0 1
+# MOV32RP-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+# ---------------------------------------------------------------
+# MOV32RP-SAME: 0 0 1 0 0 0 0 0 . 0 1 1 0 1 0 0 1
+# MOV32RP-SAME: 1 1 1 1 1 1 1 1 . 1 1 1 1 1 1 1 1
+name: MxMove_RM_ARID
+body: |
+ bb.0:
+ $bd0 = MOV8dp 0, $a0, implicit-def $ccr
+ $d0 = MOV32rp -1, $a1, implicit-def $ccr
+ $a0 = MOV32rp -1, $a1, implicit-def $ccr
+
+...
+--- # ARIPD
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DE: 0 0 0 1 0 0 0 0 . 0 0 1 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RE-SAME: 0 0 1 0 0 1 1 0 . 0 0 1 0 0 0 0 1
+# ---------------------------------------------------------------
+# MOV32RE-SAME: 0 0 1 0 1 0 0 0 . 0 1 1 0 0 0 0 1
+name: MxMove_RM_ARIPD
+body: |
+ bb.0:
+ $bd0 = MOV8de $a0, implicit-def $ccr
+ $d3 = MOV32re $a1, implicit-def $ccr
+ $a4 = MOV32re $a1, implicit-def $ccr
+
+...
+--- # ARIPI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DO-SAME: 0 0 0 1 0 0 0 0 . 0 0 0 1 1 0 0 0
+# ---------------------------------------------------------------
+# MOV32RO-SAME: 0 0 1 0 0 1 1 0 . 0 0 0 1 1 0 0 1
+# ---------------------------------------------------------------
+# MOV32RO-SAME: 0 0 1 0 1 0 0 0 . 0 1 0 1 1 0 0 1
+name: MxMove_RM_ARIPI
+body: |
+ bb.0:
+ $bd0 = MOV8do $a0, implicit-def $ccr
+ $d3 = MOV32ro $a1, implicit-def $ccr
+ $a4 = MOV32ro $a1, implicit-def $ccr
+
+...
+--- # ARI
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DJ-SAME: 0 0 0 1 0 0 0 0 . 0 0 0 1 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RJ-SAME: 0 0 1 0 0 1 1 0 . 0 0 0 1 0 0 0 1
+# ---------------------------------------------------------------
+# MOV32RJ-SAME: 0 0 1 0 1 0 0 0 . 0 1 0 1 0 0 0 1
+name: MxMove_RM_ARI
+body: |
+ bb.0:
+ $bd0 = MOV8dj $a0, implicit-def $ccr
+ $d3 = MOV32rj $a1, implicit-def $ccr
+ $a4 = MOV32rj $a1, implicit-def $ccr
+
+...
+--- # ABS
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DB-SAME: 0 0 0 1 0 0 0 0 . 0 0 1 1 1 0 0 1
+# MOV8DB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RB-SAME: 0 0 1 0 0 1 1 0 . 0 0 1 1 1 0 0 1
+# MOV32RB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32RB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# ---------------------------------------------------------------
+# MOV32RB-SAME: 0 0 1 0 1 0 0 0 . 0 1 1 1 1 0 0 1
+# MOV32RB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+# MOV32RB-SAME: 0 0 0 0 0 0 0 0 . 0 0 0 0 0 0 0 0
+name: MxMove_RM_ABS
+body: |
+ bb.0:
+ $bd0 = MOV8db 0, implicit-def $ccr
+ $d3 = MOV32rb 0, implicit-def $ccr
+ $a4 = MOV32rb 0, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RR.mir b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RR.mir
new file mode 100644
index 000000000000..a71dea90f1e6
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Data/Classes/MxMove_RR.mir
@@ -0,0 +1,30 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=MOV8DD,MOV16RA,MOV32RR
+
+#------------------------------------------------------------------------------
+# MxMove_RR moves data from register to register
+#------------------------------------------------------------------------------
+
+
+# ---------------------------+-----------+-----------+-----------
+# 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
+# -------+-------+-----------+-----------+-----------+-----------
+# MOV8DD: 0 0 0 1 0 0 1 0 . 0 0 0 0 0 0 0 0
+# MOV16RA-SAME: 0 0 1 1 0 1 1 0 . 0 0 0 0 1 0 1 0
+# MOV16RA-SAME: 0 0 1 1 1 1 0 0 . 0 1 0 0 1 0 1 0
+# MOV16RA-SAME: 0 0 1 1 0 0 1 0 . 0 0 0 0 1 0 1 0
+# MOV32RR-SAME: 0 0 1 0 0 0 1 0 . 0 0 0 0 0 0 1 0
+# MOV32RR-SAME: 0 0 1 0 0 0 1 0 . 0 1 0 0 1 0 1 0
+name: MxMove_RR
+body: |
+ bb.0:
+ $bd1 = MOV8dd $bd0, implicit-def $ccr
+ $wd3 = MOV16ra $wa2, implicit-def $ccr
+ $wa6 = MOV16ra $wa2, implicit-def $ccr
+ $wd1 = MOV16ra $wa2, implicit-def $ccr
+ $d1 = MOV32rr $d2, implicit-def $ccr
+ $a1 = MOV32rr $a2, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/README.md b/llvm/test/CodeGen/M68k/Encoding/README.md
new file mode 100644
index 000000000000..d6c50b813b32
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/README.md
@@ -0,0 +1,16 @@
+# OBJECT CODE TESTS
+NOTE: This folder will be moved to llvm/test/MC/M68k when the integrated assembler
+is finished (currently the AsmParser is not implemented yet).
+
+## Purpose
+These test snippets are to test object code generation features, specifically
+lowering of MxBean encoding, Relocations and specific commands encoding classes.
+
+### MxBean
+TODO
+
+### Relocations
+TODO
+
+### Encoding Classes
+TODO
diff --git a/llvm/test/CodeGen/M68k/Encoding/Relaxations/branch.mir b/llvm/test/CodeGen/M68k/Encoding/Relaxations/branch.mir
new file mode 100644
index 000000000000..c05d4c51a95c
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Relaxations/branch.mir
@@ -0,0 +1,114 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | extract-section .text -h \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# Test branch relaxation. By default codegen choses smallest branch instruction,
+# during object code generation it might get clear that offset does not fit and
+# bigger instruction is required.
+#------------------------------------------------------------------------------
+
+
+--- # TIGHT
+# The offset for the small branch is from the PC value, which points to the
+# next instruction, because there is no extension word here.
+# 000 CHECK: 6078
+# 002 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 00C CHECK-SAME: 23f9 0000 0000 0000 0000
+# 016 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 020 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 02A CHECK-SAME: 23f9 0000 0000 0000 0000
+# 034 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 03E CHECK-SAME: 23f9 0000 0000 0000 0000
+# 048 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 052 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 05C CHECK-SAME: 23f9 0000 0000 0000 0000
+# 066 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 070 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 07A CHECK-SAME: d0bc 0000 0000
+# 080 CHECK-SAME: 4e75
+name: TIGHT
+body: |
+ bb.0:
+ successors: %bb.2
+
+ BRA8 %bb.2
+ bb.1:
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ bb.2:
+ $d0 = ADD32ri $d0, 0, implicit-def $ccr
+ RET 0, $d0
+
+...
+--- # RELAXED
+# 084 CHECK-SAME 6000 0084
+# 088 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 092 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 09C CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0A6 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0B0 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0BA CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0C4 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0CE CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0D8 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0E2 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0EC CHECK-SAME: 23f9 0000 0000 0000 0000
+# 0F6 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 100 CHECK-SAME: 23f9 0000 0000 0000 0000
+# 10A CHECK-SAME: d0bc 0000 0000
+# 110 CHECK-SAME: 4e75
+name: RELAXED
+body: |
+ bb.0:
+ successors: %bb.2
+
+ BRA8 %bb.2
+ bb.1:
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ MOV32bb 0, 0, implicit-def $ccr
+ bb.2:
+ $d0 = ADD32ri $d0, 0, implicit-def $ccr
+ RET 0, $d0
+
+...
+--- # ZERO
+# Because of the way M68k encodes branches it is not possible to encode 0
+# offset with the smallest insruction(0 in the offset field means exension word
+# is used) thus we switch to the wider instruction.
+# 114 CHECK-SAME: 6000 0002
+# 118 CHECK-SAME: d0bc 0000 0000
+# 11E CHECK-SAME: 4e75
+name: ZERO
+body: |
+ bb.0:
+ successors: %bb.1
+
+ BRA8 %bb.1
+ bb.1:
+ $d0 = ADD32ri $d0, 0, implicit-def $ccr
+ RET 0, $d0
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Relocations/data-abs.mir b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-abs.mir
new file mode 100644
index 000000000000..5024e99d2993
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-abs.mir
@@ -0,0 +1,24 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | llvm-readobj -relocations -elf-output-style=GNU - \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# Test ABS relocation
+#------------------------------------------------------------------------------
+
+--- |
+
+ @dst = external global i32
+
+ define void @DATA() { entry: ret void }
+...
+--- # DATA
+# Offset Info Type Sym. Value Sym S Addend
+# CHECK: 00000002 {{[0-9a-f]+}} R_68K_32 {{[0-9]*}} dst + 0
+name: DATA
+body: |
+ bb.0:
+ $d0 = MOV32rb @dst, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotoff.mir b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotoff.mir
new file mode 100644
index 000000000000..52859e36c212
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotoff.mir
@@ -0,0 +1,28 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | llvm-readobj -relocations -elf-output-style=GNU - \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# Test GOTOFF relocation
+#------------------------------------------------------------------------------
+
+--- |
+
+ @dst = external global i32
+
+ define void @DATA() { entry: ret void }
+...
+--- # DATA
+# Offset Info Type Sym. Value Sym S Addend
+# CHECK: 00000002 {{[0-9a-f]+}} R_68K_GOTPCREL16 {{[0-9]*}} _GLOBAL_OFFSET_TABLE_ + 0
+# CHECK: 00000007 {{[0-9a-f]+}} R_68K_GOTOFF8 {{[0-9]*}} dst + 0
+# CHECK: 0000000a {{[0-9a-f]+}} R_68K_GOTOFF16 {{[0-9]*}} dst + 0
+name: DATA
+body: |
+ bb.0:
+ $a5 = LEA32q target-flags(m68k-gotpcrel) &_GLOBAL_OFFSET_TABLE_
+ $d0 = MOV32rf target-flags(m68k-gotoff) @dst, $a5, $d0, implicit-def $ccr
+ $d0 = MOV32rp target-flags(m68k-gotoff) @dst, $a5, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotpcrel.mir b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotpcrel.mir
new file mode 100644
index 000000000000..7c8648d78f03
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-gotpcrel.mir
@@ -0,0 +1,26 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | llvm-readobj -relocations -elf-output-style=GNU - \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# Test GOTPCREL relocation
+#------------------------------------------------------------------------------
+
+--- |
+
+ @dst = external global i32
+
+ define void @DATA() { entry: ret void }
+...
+--- # DATA
+# Offset Info Type Sym. Value Sym S Addend
+# CHECK: 00000003 {{[0-9]+}} R_68K_GOTPCREL8 {{[0-9]*}} dst + 1
+# CHECK: 00000006 {{[0-9]+}} R_68K_GOTPCREL16 {{[0-9]*}} dst + 0
+name: DATA
+body: |
+ bb.0:
+ $a0 = MOV32rk target-flags(m68k-gotpcrel) @dst, $d0, implicit-def $ccr
+ $a0 = MOV32rq target-flags(m68k-gotpcrel) @dst, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Relocations/data-pc-rel.mir b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-pc-rel.mir
new file mode 100644
index 000000000000..e570aa5b3214
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Relocations/data-pc-rel.mir
@@ -0,0 +1,29 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | llvm-readobj -relocations -elf-output-style=GNU - \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# Tests PC-Relative data relocations
+#------------------------------------------------------------------------------
+
+--- |
+
+ @dst = external global i32
+
+ define void @DATA() { entry: ret void }
+...
+--- # DATA
+# Offset Info Type Sym. Value Sym S Addend
+# CHECK: 00000003 {{[0-9]+}} R_68K_PC8 {{[0-9]*}} dst + 1
+# CHECK: 00000006 {{[0-9]+}} R_68K_PC16 {{[0-9]*}} dst + 0
+# No need for relocation here
+# CHECK-NOT: 0000000a {{[0-9]+}} R_68K_PC16 0
+name: DATA
+body: |
+ bb.0:
+ $a0 = MOV32rk @dst, $a0, implicit-def $ccr
+ $a0 = MOV32rq @dst, implicit-def $ccr
+ $a0 = MOV32rq 0, implicit-def $ccr
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/Relocations/text-plt.mir b/llvm/test/CodeGen/M68k/Encoding/Relocations/text-plt.mir
new file mode 100644
index 000000000000..2cb48933c1f8
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/Relocations/text-plt.mir
@@ -0,0 +1,23 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj \
+# RUN: -code-model=small -relocation-model=pic -o - \
+# RUN: | llvm-readobj -relocations -elf-output-style=GNU - \
+# RUN: | FileCheck %s
+
+#------------------------------------------------------------------------------
+# Test PLT relocation
+#------------------------------------------------------------------------------
+
+--- |
+
+ declare void @TARGET()
+ define void @TEXT() { entry: ret void }
+...
+--- # TEXT
+# Offset Info Type Sym. Value Sym S Addend
+# CHECK: 00000002 {{[0-9a-f]+}} R_68K_PLT16 {{[0-9]*}} TARGET + 0
+name: TEXT
+body: |
+ bb.0:
+ CALLq target-flags(m68k-plt) @TARGET
+
+...
diff --git a/llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DD.mir b/llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DD.mir
new file mode 100644
index 000000000000..9a4f8954debe
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DD.mir
@@ -0,0 +1,43 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SHL8DD,SHL32DD,LSR8DD,LSR32DD,ASR8DD,ASR32DD
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ROL8DD,ROL32DD,ROR8DD,ROR32DD
+
+#------------------------------------------------------------------------------
+# MxSR_DD encodes shift or rotate instructions; shift count is in register
+#------------------------------------------------------------------------------
+
+# ---------------+-----------+---+-------+---+-------+-----------
+# F E D C | B A 9 | 8 | 7 6 | 5 | 4 3 | 2 1 0
+# ---------------+-----------+---+-------+---+-------+-----------
+# 1 1 1 0 | Dx | D | SIZE | 1 | OP | Dy
+# ---------------+-----------+---+-------+---+-------+-----------
+# SHL8DD: 1 1 1 0 0 0 0 1 . 0 0 1 0 1 0 0 1
+# SHL32DD-SAME: 1 1 1 0 0 0 1 1 . 1 0 1 0 1 0 1 0
+# ---------------+-----------+---+-------+---+-------+-----------
+# LSR8DD-SAME: 1 1 1 0 0 1 0 0 . 0 0 1 0 1 0 1 1
+# LSR32DD-SAME: 1 1 1 0 0 1 1 0 . 1 0 1 0 1 1 0 0
+# ---------------+-----------+---+-------+---+-------+-----------
+# ASR8DD-SAME: 1 1 1 0 1 0 0 0 . 0 0 1 0 0 1 0 1
+# ASR32DD-SAME: 1 1 1 0 1 0 1 0 . 1 0 1 0 0 1 1 0
+# ---------------+-----------+---+-------+---+-------+-----------
+# ROL8DD: 1 1 1 0 1 1 0 1 . 0 0 1 1 1 1 1 1
+# ROL32DD-SAME: 1 1 1 0 1 1 1 1 . 1 0 1 1 1 0 0 1
+# ---------------+-----------+---+-------+---+-------+-----------
+# ROR8DD-SAME: 1 1 1 0 0 0 0 0 . 0 0 1 1 1 0 0 1
+# ROR32DD-SAME: 1 1 1 0 0 0 0 0 . 1 0 1 1 1 0 0 1
+name: MxSR_DD
+body: |
+ bb.0:
+ $bd1 = SHL8dd $bd1, $bd0, implicit-def $ccr
+ $d2 = SHL32dd $d2, $d1, implicit-def $ccr
+ $bd3 = LSR8dd $bd3, $bd2, implicit-def $ccr
+ $d4 = LSR32dd $d4, $d3, implicit-def $ccr
+ $bd5 = ASR8dd $bd5, $bd4, implicit-def $ccr
+ $d6 = ASR32dd $d6, $d5, implicit-def $ccr
+ $bd7 = ROL8dd $bd7, $bd6, implicit-def $ccr
+ $d1 = ROL32dd $d1, $d7, implicit-def $ccr
+ $bd1 = ROR8dd $bd1, $bd0, implicit-def $ccr
+ $d1 = ROR32dd $d1, $d0, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DI.mir b/llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DI.mir
new file mode 100644
index 000000000000..9d9de3981f37
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Encoding/ShiftRotate/Classes/MxSR_DI.mir
@@ -0,0 +1,58 @@
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=SHL8DI,SHL32DI,LSR8DI,LSR32DI,ASR8DI,ASR32DI
+# RUN: llc %s -mtriple=m68k -start-after=prologepilog -O0 -filetype=obj -o - \
+# RUN: | extract-section .text \
+# RUN: | FileCheck %s -check-prefixes=ROL8DI,ROL32DI,ROR8DI,ROR32DI
+
+#------------------------------------------------------------------------------
+# MxSR_DI encodes shift or rotate instructions; shift count is encoded into
+# the instruction
+#------------------------------------------------------------------------------
+
+# ---------------+-----------+---+-------+---+-------+-----------
+# F E D C | B A 9 | 8 | 7 6 | 5 | 4 3 | 2 1 0
+# ---------------+-----------+---+-------+---+-------+-----------
+# 1 1 1 0 | Dx | D | SIZE | 0 | OP | Dy
+# ---------------+-----------+---+-------+---+-------+-----------
+# SHL8DI: 1 1 1 0 0 0 1 1 . 0 0 0 0 1 0 0 1
+# SHL32DI-SAME: 1 1 1 0 0 0 1 1 . 1 0 0 0 1 0 0 1
+# ---------------+-----------+---+-------+---+-------+-----------
+# LSR8DI-SAME: 1 1 1 0 0 0 1 0 . 0 0 0 0 1 0 0 1
+# LSR32DI-SAME: 1 1 1 0 0 0 1 0 . 1 0 0 0 1 0 0 1
+# ---------------+-----------+---+-------+---+-------+-----------
+# ASR8DI-SAME: 1 1 1 0 0 0 1 0 . 0 0 0 0 0 0 0 1
+# ASR32DI-SAME: 1 1 1 0 0 0 1 0 . 1 0 0 0 0 0 0 1
+# ---------------+-----------+---+-------+---+-------+-----------
+# ROL8DI: 1 1 1 0 0 0 1 1 . 0 0 0 1 1 0 0 1
+# ROL32DI-SAME: 1 1 1 0 0 0 1 1 . 1 0 0 1 1 0 0 1
+# ---------------+-----------+---+-------+---+-------+-----------
+# ROR8DI-SAME: 1 1 1 0 0 0 1 0 . 0 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 0 0 1 0 . 1 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 0 1 0 0 . 1 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 0 1 1 0 . 1 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 1 0 0 0 . 1 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 1 0 1 0 . 1 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 1 1 0 0 . 1 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 1 1 1 0 . 1 0 0 1 1 0 0 1
+# ROR32DI-SAME: 1 1 1 0 0 0 0 0 . 1 0 0 1 1 0 0 1
+name: MxSR_DI
+body: |
+ bb.0:
+ $bd1 = SHL8di $bd1, 1, implicit-def $ccr
+ $d1 = SHL32di $d1, 1, implicit-def $ccr
+ $bd1 = LSR8di $bd1, 1, implicit-def $ccr
+ $d1 = LSR32di $d1, 1, implicit-def $ccr
+ $bd1 = ASR8di $bd1, 1, implicit-def $ccr
+ $d1 = ASR32di $d1, 1, implicit-def $ccr
+ $bd1 = ROL8di $bd1, 1, implicit-def $ccr
+ $d1 = ROL32di $d1, 1, implicit-def $ccr
+ $bd1 = ROR8di $bd1, 1, implicit-def $ccr
+ $d1 = ROR32di $d1, 1, implicit-def $ccr
+ $d1 = ROR32di $d1, 2, implicit-def $ccr
+ $d1 = ROR32di $d1, 3, implicit-def $ccr
+ $d1 = ROR32di $d1, 4, implicit-def $ccr
+ $d1 = ROR32di $d1, 5, implicit-def $ccr
+ $d1 = ROR32di $d1, 6, implicit-def $ccr
+ $d1 = ROR32di $d1, 7, implicit-def $ccr
+ $d1 = ROR32di $d1, 8, implicit-def $ccr
diff --git a/llvm/test/CodeGen/M68k/lit.local.cfg b/llvm/test/CodeGen/M68k/lit.local.cfg
new file mode 100644
index 000000000000..8e4684705573
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/lit.local.cfg
@@ -0,0 +1,13 @@
+import os
+
+config.suffixes = ['.ll', '.mir', '.test', '.txt']
+
+extract_section_path = os.path.join(config.llvm_src_root,
+ 'utils', 'extract-section.py')
+
+config.substitutions.append(('extract-section',
+ extract_section_path + ' --byte-indicator --hex-width=2'))
+
+if not 'M68k' in config.root.targets:
+ config.unsupported = True
+
diff --git a/llvm/test/CodeGen/M68k/varargs.ll b/llvm/test/CodeGen/M68k/varargs.ll
new file mode 100644
index 000000000000..4557707e491e
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/varargs.ll
@@ -0,0 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+%struct.va_list = type { i8* }
+
+; CHECK-LABEL test:
+define i32 @test(i32 %X, ...) {
+ ; Initialize variable argument processing
+; CHECK-LABEL: test:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: sub.l #8, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -12
+; CHECK-NEXT: lea (16,%sp), %a0
+; CHECK-NEXT: add.l #4, %a0
+; CHECK-NEXT: move.l %a0, (4,%sp)
+; CHECK-NEXT: move.l %a0, (0,%sp)
+; CHECK-NEXT: move.l (16,%sp), %d0
+; CHECK-NEXT: add.l #8, %sp
+; CHECK-NEXT: rts
+ %ap = alloca %struct.va_list
+ %ap2 = bitcast %struct.va_list* %ap to i8*
+ call void @llvm.va_start(i8* %ap2)
+
+ ; Read a single integer argument
+ %tmp = va_arg i8* %ap2, i32
+
+ ; Demonstrate usage of llvm.va_copy and llvm.va_end
+ %aq = alloca i8*
+ %aq2 = bitcast i8** %aq to i8*
+ call void @llvm.va_copy(i8* %aq2, i8* %ap2)
+ call void @llvm.va_end(i8* %aq2)
+
+ ; Stop processing of arguments.
+ call void @llvm.va_end(i8* %ap2)
+ ret i32 %tmp
+}
+
+declare void @llvm.va_start(i8*)
+declare void @llvm.va_copy(i8*, i8*)
+declare void @llvm.va_end(i8*)
diff --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py
index 6390ace4eaed..3cbedfeaccf2 100644
--- a/llvm/utils/UpdateTestChecks/asm.py
+++ b/llvm/utils/UpdateTestChecks/asm.py
@@ -51,6 +51,12 @@ class string:
r'.Lfunc_end[0-9]+:\n',
flags=(re.M | re.S))
+ASM_FUNCTION_M68K_RE = re.compile(
+ r'^_?(?P<func>[^:]+):[ \t]*;[ \t]*@"?(?P=func)"?\n'
+ r'(?P<body>.*?)\s*' # (body of the function)
+ r'.Lfunc_end[0-9]+:\n',
+ flags=(re.M | re.S))
+
ASM_FUNCTION_MIPS_RE = re.compile(
r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n[^:]*?' # f: (name of func)
r'(?:^[ \t]+\.(frame|f?mask|set).*?\n)+' # Mips+LLVM standard asm prologue
@@ -247,6 +253,16 @@ def scrub_asm_powerpc(asm, args):
asm = common.SCRUB_TAILING_COMMENT_TOKEN_RE.sub(r'', asm)
return asm
+def scrub_asm_m68k(asm, args):
+ # Scrub runs of whitespace out of the assembly, but leave the leading
+ # whitespace in place.
+ asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
+ # Expand the tabs used for indentation.
+ asm = string.expandtabs(asm, 2)
+ # Strip trailing whitespace.
+ asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
+ return asm
+
def scrub_asm_mips(asm, args):
# Scrub runs of whitespace out of the assembly, but leave the leading
# whitespace in place.
@@ -361,6 +377,7 @@ def get_run_handler(triple):
'thumb-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
'thumbv5-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
'thumbv7-apple-ios' : (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
+ 'm68k': (scrub_asm_m68k, ASM_FUNCTION_M68K_RE),
'mips': (scrub_asm_mips, ASM_FUNCTION_MIPS_RE),
'msp430': (scrub_asm_msp430, ASM_FUNCTION_MSP430_RE),
'avr': (scrub_asm_avr, ASM_FUNCTION_AVR_RE),
diff --git a/llvm/utils/extract-section.py b/llvm/utils/extract-section.py
new file mode 100755
index 000000000000..ab475516af95
--- /dev/null
+++ b/llvm/utils/extract-section.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+from __future__ import print_function
+'''
+Helper script to print out the raw content of an ELF section.
+Example usages:
+```
+# print out as bits by default
+extract-section.py .text --input-file=foo.o
+```
+```
+# read from stdin and print out in hex
+cat foo.o | extract-section.py -h .text
+```
+This is merely a wrapper around `llvm-readobj` that focuses on the binary
+content as well as providing more formatting options.
+'''
+
+# Unfortunately reading binary from stdin is not so trivial in Python...
+def read_raw_stdin():
+ import sys
+ if sys.version_info >= (3, 0):
+ reading_source = sys.stdin.buffer
+ else:
+ # Windows will always read as string so we need some
+ # special handling
+ if sys.platform == 'win32':
+ import os, msvcrt
+ msvcrt.setformat(sys.stdin.fileno(), os.O_BINARY)
+ reading_source = sys.stdin
+ return reading_source.read()
+
+def get_raw_section_dump(readobj_path, section_name, input_file):
+ import subprocess
+ cmd = [readobj_path, '-elf-output-style=GNU', '--hex-dump={}'.format(section_name),
+ input_file]
+ proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+ universal_newlines=True)
+
+ if input_file == '-':
+ # From stdin
+ out,_ = proc.communicate(input=read_raw_stdin())
+ else:
+ out,_ = proc.communicate()
+
+ return out.decode('utf-8') if type(out) is not str else out
+
+if __name__ == '__main__':
+ import argparse
+ # The default '-h' (--help) will conflict with our '-h' (hex) format
+ arg_parser = argparse.ArgumentParser(add_help=False)
+ arg_parser.add_argument('--readobj-path', metavar='<executable path>', type=str,
+ help='Path to llvm-readobj')
+ arg_parser.add_argument('--input-file', metavar='<file>', type=str,
+ help='Input object file, or \'-\' to read from stdin')
+ arg_parser.add_argument('section', metavar='<name>', type=str,
+ help='Name of the section to extract')
+ # Output format
+ format_group = arg_parser.add_mutually_exclusive_group()
+ format_group.add_argument('-b', dest='format', action='store_const', const='bits',
+ help='Print out in bits')
+ arg_parser.add_argument('--byte-indicator', action='store_true',
+ help='Whether to print a \'.\' every 8 bits in bits printing mode')
+ format_group.add_argument('-h', dest='format', action='store_const', const='hex',
+ help='Print out in hexadecimal')
+ arg_parser.add_argument('--hex-width', metavar='<# of bytes>', type=int,
+ help='The width (in byte) of every element in hex printing mode')
+
+ arg_parser.add_argument('--help', action='help')
+ arg_parser.set_defaults(format='bits', tool_path='llvm-readobj', input_file='-',
+ byte_indicator=False, hex_width=4)
+ args = arg_parser.parse_args()
+
+ raw_section = get_raw_section_dump(args.tool_path, args.section, args.input_file)
+
+ results = []
+ for line in raw_section.splitlines(False):
+ if line.startswith('Hex dump'):
+ continue
+ parts = line.strip().split(' ')[1:]
+ for part in parts[:4]:
+ # exclude any non-hex dump string
+ try:
+ val = int(part, 16)
+ if args.format == 'bits':
+ # divided into bytes first
+ for byte in [(val >> off) & 0xFF for off in (24,16,8,0)]:
+ for bit in [(byte >> off) & 1 for off in range(7, -1, -1)]:
+ results.append(str(bit))
+ if args.byte_indicator:
+ results.append('.')
+ elif args.format == 'hex':
+ assert args.hex_width <= 4 and args.hex_width > 0
+ width_bits = args.hex_width * 8
+ offsets = [off for off in range(32 - width_bits, -1, -width_bits)]
+ mask = (1 << width_bits) - 1
+ format_str = "{:0" + str(args.hex_width * 2) + "x}"
+ for word in [(val >> i) & mask for i in offsets]:
+ results.append(format_str.format(word))
+ except:
+ break
+ print(' '.join(results), end='')
More information about the llvm-commits
mailing list