diff --git a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp --- a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp +++ b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp @@ -162,6 +162,16 @@ return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16rf), MVT::i32, MVT::i16); + case M68k::MOVZXd16q8: + return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dq), MVT::i16, + MVT::i8); + case M68k::MOVZXd32q8: + return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV8dq), MVT::i32, + MVT::i8); + case M68k::MOVZXd32q16: + return TII->ExpandMOVSZX_RM(MIB, false, TII->get(M68k::MOV16dq), MVT::i32, + MVT::i16); + case M68k::MOV8cd: return TII->ExpandCCR(MIB, /*IsToCCR=*/true); case M68k::MOV8dc: diff --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td --- a/llvm/lib/Target/M68k/M68kInstrData.td +++ b/llvm/lib/Target/M68k/M68kInstrData.td @@ -525,6 +525,10 @@ def MOV#EXT#Xd32f8 : MxPseudoMove_RM; def MOV#EXT#Xd32f16 : MxPseudoMove_RM; + def MOV#EXT#Xd16q8 : MxPseudoMove_RM; + def MOV#EXT#Xd32q8 : MxPseudoMove_RM; + def MOV#EXT#Xd32q16 : MxPseudoMove_RM; + } } } @@ -572,18 +576,21 @@ (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>; def: Pat<(MxZExtLoadi16i8 MxCP_ARII:$src), (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>; +def: Pat<(MxZExtLoadi16i8 MxCP_PCD :$src), (MOVZXd16q8 MxPCD8 :$src)>; // i32 <- zext i8 def: Pat<(i32 (zext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>; def: Pat<(MxZExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>; def: Pat<(MxZExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>; def: Pat<(MxZExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>; +def: Pat<(MxZExtLoadi32i8 MxCP_PCD :$src), (MOVZXd32q8 MxPCD8 :$src)>; // i32 <- zext i16 def: Pat<(i32 (zext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>; def: Pat<(MxZExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>; def: Pat<(MxZExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>; def: Pat<(MxZExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>; +def: Pat<(MxZExtLoadi32i16 MxCP_PCD :$src), (MOVZXd32q16 MxPCD16 :$src)>; // i16 <- anyext i8 def: Pat<(i16 (anyext i8:$src)), diff --git a/llvm/test/CodeGen/M68k/load-extend.ll b/llvm/test/CodeGen/M68k/load-extend.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/M68k/load-extend.ll @@ -0,0 +1,43 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s + +@0 = external constant <{ [32 x i8] }> + +define i32 @"test_zext_pcd_i8_to_i32"() { +; CHECK-LABEL: test_zext_pcd_i8_to_i32: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: move.b (__unnamed_1+16,%pc), %d0 +; CHECK-NEXT: and.l #255, %d0 +; CHECK-NEXT: rts + %p = getelementptr inbounds i8, ptr @0, i32 16 + %val = load i8, ptr %p + %val2 = zext i8 %val to i32 + ret i32 %val2 +} + +define i16 @"test_zext_pcd_i8_to_i16"() { +; CHECK-LABEL: test_zext_pcd_i8_to_i16: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: move.b (__unnamed_1+16,%pc), %d0 +; CHECK-NEXT: and.w #255, %d0 +; CHECK-NEXT: rts + %p = getelementptr inbounds i8, ptr @0, i32 16 + %val = load i8, ptr %p + %val2 = zext i8 %val to i16 + ret i16 %val2 +} + +define i32 @"test_zext_pcd_i16_to_i32"() { +; CHECK-LABEL: test_zext_pcd_i16_to_i32: +; CHECK: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: move.w (__unnamed_1+16,%pc), %d0 +; CHECK-NEXT: and.l #65535, %d0 +; CHECK-NEXT: rts + %p = getelementptr inbounds i16, ptr @0, i32 8 + %val = load i16, ptr %p + %val2 = zext i16 %val to i32 + ret i32 %val2 +}