Index: lib/Target/NDS32/NDS32InstrInfo.td =================================================================== --- lib/Target/NDS32/NDS32InstrInfo.td +++ lib/Target/NDS32/NDS32InstrInfo.td @@ -178,6 +178,38 @@ } +//===----------------------------------------------------------------------===// +// Arithmetic with Shift Immediate Instructions +// + +class ALU_shift subop_encode> : + ALU_1Form<(outs GPR:$Rt), (ins GPR:$Ra, GPR:$Rb, imm5u:$sh), + !strconcat(opstr, "\t$Rt, $Ra, $Rb, $sh"), + [(set GPR:$Rt, (Op GPR:$Ra, (Shift GPR:$Rb, imm5u:$sh)))]> { + bits<5> Rt; + bits<5> Ra; + bits<5> Rb; + bits<5> sh; + let Inst{24-20} = Rt; + let Inst{19-15} = Ra; + let Inst{14-10} = Rb; + let Inst{9-5} = sh; + let Inst{4-0} = subop_encode; +} + +def ADD_SLLI : ALU_shift<"add_slli", add, shl, 0b00000>; +def ADD_SRLI : ALU_shift<"add_srli", add, srl, 0b11100>; +def SUB_SLLI : ALU_shift<"sub_slli", sub, shl, 0b00001>; +def SUB_SRLI : ALU_shift<"sub_srli", sub, srl, 0b11101>; +def AND_SLLI : ALU_shift<"and_slli", and, shl, 0b00010>; +def AND_SRLI : ALU_shift<"and_srli", and, srl, 0b11110>; +def OR_SLLI : ALU_shift<"or_slli" , or, shl, 0b00100>; +def OR_SRLI : ALU_shift<"or_srli" , or, srl, 0b10101>; +def XOR_SLLI : ALU_shift<"xor_slli", xor, shl, 0b00011>; +def XOR_SRLI : ALU_shift<"xor_srli", xor, srl, 0b11111>; + + class JREG_ret pat, bits<2> dt_it> : JREGForm<(outs), (ins), opstr, pat> { let Inst{24-15} = 0; Index: test/CodeGen/NDS32/alu-shift.ll =================================================================== --- /dev/null +++ test/CodeGen/NDS32/alu-shift.ll @@ -0,0 +1,75 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-m:e-p:32:32-i64:64-a:0:32-n32-S64" +target triple = "nds32le---elf" + +; Function Attrs: norecurse nounwind readnone +define i32 @add_slli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shl = shl i32 %b, 5 + %add = add nsw i32 %shl, %a +; CHECK: add_slli $r0, $r0, $r1, 5 + ret i32 %add +} + +; Function Attrs: norecurse nounwind readnone +define i32 @add_srli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shr = lshr i32 %b, 5 + %add = add i32 %shr, %a +; CHECK: add_srli $r0, $r0, $r1, 5 + ret i32 %add +} + +; Function Attrs: norecurse nounwind readnone +define i32 @sub_slli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shl = shl i32 %b, 5 + %sub = sub nsw i32 %a, %shl +; CHECK: sub_slli $r0, $r0, $r1, 5 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind readnone +define i32 @sub_srli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shr = lshr i32 %b, 5 + %sub = sub i32 %a, %shr +; CHECK: sub_srli $r0, $r0, $r1, 5 + ret i32 %sub +} + +; Function Attrs: norecurse nounwind readnone +define i32 @or_slli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shl = shl i32 %b, 5 + %or = or i32 %shl, %a +; CHECK: or_slli $r0, $r0, $r1, 5 + ret i32 %or +} + +; Function Attrs: norecurse nounwind readnone +define i32 @or_srli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shr = lshr i32 %b, 5 + %or = or i32 %shr, %a +; CHECK: or_srli $r0, $r0, $r1, 5 + ret i32 %or +} + +; Function Attrs: norecurse nounwind readnone +define i32 @xor_slli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shl = shl i32 %b, 5 + %xor = xor i32 %shl, %a +; CHECK: xor_slli $r0, $r0, $r1, 5 + ret i32 %xor +} + +; Function Attrs: norecurse nounwind readnone +define i32 @xor_srli(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: + %shr = lshr i32 %b, 5 + %xor = xor i32 %shr, %a +; CHECK: xor_srli $r0, $r0, $r1, 5 + ret i32 %xor +}