Index: lib/Target/NDS32/NDS32ISelLowering.cpp =================================================================== --- lib/Target/NDS32/NDS32ISelLowering.cpp +++ lib/Target/NDS32/NDS32ISelLowering.cpp @@ -56,6 +56,8 @@ setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); } + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); + // Post increment load/store are legal in NDS32 ISA setIndexedLoadAction(ISD::POST_INC, MVT::i32, Legal); setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); Index: lib/Target/NDS32/NDS32Instr16Bit.td =================================================================== --- lib/Target/NDS32/NDS32Instr16Bit.td +++ lib/Target/NDS32/NDS32Instr16Bit.td @@ -71,6 +71,17 @@ [(set lGPR:$Rt, (not lGPR:$Ra))], 0b011>, Requires<[Has16Bit]>; +class BFMI333_sextend subop_encode> : + BFMI333Form<(outs lGPR:$Rt), (ins lGPR:$Ra), + !strconcat(opstr, "\t$Rt, $Ra"), + [(set lGPR:$Rt, (Op lGPR:$Ra, vt))], + subop_encode>, + Requires<[Has16Bit]>; + +def SEB33 : BFMI333_sextend< "seb33", sext_inreg, i8, 0b010>; +def SEH33 : BFMI333_sextend< "seh33", sext_inreg, i16, 0b011>; + //===----------------------------------------------------------------------===// // Load/Store Instructions Index: lib/Target/NDS32/NDS32Instr16Formats.td =================================================================== --- lib/Target/NDS32/NDS32Instr16Formats.td +++ lib/Target/NDS32/NDS32Instr16Formats.td @@ -132,6 +132,16 @@ let Inst{2-0} = subop_encode; } +class BFMI333Form pattern, + bits<3> subop_encode> + : 16BitInst6BitOpcode<0b001011, outs, ins, asmstr, pattern> { + bits<3> Rt; + bits<3> Ra; + let Inst{8-6} = Rt; + let Inst{5-3} = Ra; + let Inst{2-0} = subop_encode; +} + class LBI333Form pattern> : 16BitInst6BitOpcode<0b010011, outs, ins, asmstr, pattern> { bits<3> Rt; Index: lib/Target/NDS32/NDS32InstrInfo.td =================================================================== --- lib/Target/NDS32/NDS32InstrInfo.td +++ lib/Target/NDS32/NDS32InstrInfo.td @@ -244,6 +244,27 @@ //===----------------------------------------------------------------------===// +// Sign Extension Instructions +// + +class ALU_1_sextend subop_encode> : + ALU_1Form<(outs GPR:$Rt), (ins GPR:$Ra), + !strconcat(opstr, "\t$Rt, $Ra"), + [(set GPR:$Rt, (Op GPR:$Ra, vt))]> { + bits<5> Rt; + bits<5> Ra; + let Inst{24-20} = Rt; + let Inst{19-15} = Ra; + let Inst{14-5} = 0; + let Inst{4-0} = subop_encode; +} + +def SEB : ALU_1_sextend< "seb", sext_inreg, i8, 0b10000>; +def SEH : ALU_1_sextend< "seh", sext_inreg, i16, 0b10001>; + + +//===----------------------------------------------------------------------===// // Division Instructions // // In NDS32 ISA, quotient and remainder register set to same register Index: test/CodeGen/NDS32/sign-extend.ll =================================================================== --- /dev/null +++ test/CodeGen/NDS32/sign-extend.ll @@ -0,0 +1,37 @@ +; RUN: llc -mattr=+no-16bit < %s | FileCheck %s +; RUN: llc < %s | FileCheck --check-prefix=CHECK-16BIT %s +target datalayout = "e-m:e-p:32:32-i64:64-a:0:32-n32-S64" +target triple = "nds32le---elf" + +@sign_extend.lastn = internal unnamed_addr global i32 0, align 4 + +; Function Attrs: norecurse nounwind +define i32 @sign_extend(i32 %n, i32 %c) local_unnamed_addr #0 { +entry: + %shl = shl i32 %n, 3 + %xor = xor i32 %shl, -1 + %sext = shl i32 %xor, 24 +; CHECK: seb $r3, $r2 +; CHECK-16BIT: seb33 $r3, $r2 + %conv1 = ashr exact i32 %sext, 24 + %cmp = icmp eq i32 %conv1, %c + br i1 %cmp, label %if.end, label %return + +if.end: ; preds = %entry + %sext13 = shl i32 %xor, 16 + %conv6 = ashr exact i32 %sext13, 16 +; CHECK: seh $r2, $r2 +; CHECK-16BIT: seh33 $r2, $r2 + %cmp7 = icmp eq i32 %conv6, %c + br i1 %cmp7, label %if.end10, label %return + +if.end10: ; preds = %if.end + %0 = load i32, i32* @sign_extend.lastn, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* @sign_extend.lastn, align 4 + br label %return + +return: ; preds = %if.end, %entry, %if.end10 + %retval.0 = phi i32 [ undef, %if.end10 ], [ 1, %entry ], [ 2, %if.end ] + ret i32 %retval.0 +}