Index: lib/Target/NDS32/NDS32InstrFormats.td =================================================================== --- lib/Target/NDS32/NDS32InstrFormats.td +++ lib/Target/NDS32/NDS32InstrFormats.td @@ -34,6 +34,22 @@ let Inst{30-25} = opcode; } +class SETHIForm pattern> + : 32BitInst<0b100011, outs, ins, asmstr, pattern> { + bits<5> Rt; + bits<20> imm; + let Inst{24-20} = Rt; + let Inst{19-0} = imm; +} + +class MOVIForm pattern> + : 32BitInst<0b100010, outs, ins, asmstr, pattern> { + bits<5> Rt; + bits<20> imm; + let Inst{24-20} = Rt; + let Inst{19-0} = imm; +} + class ALU_1Form pattern> : 32BitInst<0b100000, outs, ins, asmstr, pattern>; Index: lib/Target/NDS32/NDS32InstrInfo.td =================================================================== --- lib/Target/NDS32/NDS32InstrInfo.td +++ lib/Target/NDS32/NDS32InstrInfo.td @@ -52,6 +52,19 @@ //===----------------------------------------------------------------------===// +// Move Instructions +// + +def SETHI : SETHIForm<(outs GPR:$Rt), (ins imm20u:$imm), + "sethi\t$Rt, $imm", []>; + +let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in +def MOVI : MOVIForm<(outs GPR:$Rt), (ins imm20s:$imm), + "movi\t$Rt, $imm", + [(set GPR:$Rt, (imm20s:$imm))]>; + + +//===----------------------------------------------------------------------===// // Arithmetic Instructions // @@ -311,9 +324,12 @@ // Pattern Transformation //===----------------------------------------------------------------------===// +// Arbitrary immediates +def : Pat<(i32 imm:$imm), + (ORI (SETHI (HI20 imm:$imm)), (LO12 imm:$imm))>; + // division patterns def : Pat<(NDS32sdivrem i32:$Ra, i32:$Rb), (SDIVREM i32:$Ra, i32:$Rb)>; def : Pat<(NDS32udivrem i32:$Ra, i32:$Rb), (UDIVREM i32:$Ra, i32:$Rb)>; - Index: lib/Target/NDS32/NDS32Predicate.td =================================================================== --- lib/Target/NDS32/NDS32Predicate.td +++ lib/Target/NDS32/NDS32Predicate.td @@ -15,6 +15,16 @@ // Immediate Operand Predicates // +// Transformation Function - get the lower 12 bits. +def LO12 : SDNodeXFormgetZExtValue() & 0xFFF); +}]>; + +// Transformation Function - get the higher 20 bits. +def HI20 : SDNodeXFormgetZExtValue() >> 12) & 0xFFFFF); +}]>; + class ImmAsmOperand : AsmOperandClass { let RenderMethod = "addImmOperands"; } /// imm15s predicate - Immediate in the range [-(1 << 14) , (1 << 14)]. @@ -58,6 +68,16 @@ }]> { } +/// imm20u predicate - Immediate in the range [0 , (1 << 20)]. +def Imm20uAsmOperand: ImmAsmOperand { + let Name = "Imm20u"; + let DiagnosticType = "ImmRange20u"; +} +def imm20u : Operand, ImmLeaf= 0 && Imm < (1 << 20); +}]> { +} + //===----------------------------------------------------------------------===// // Load/Store Operands Predicates Index: test/CodeGen/NDS32/move-imm.ll =================================================================== --- /dev/null +++ test/CodeGen/NDS32/move-imm.ll @@ -0,0 +1,18 @@ +; 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: noinline nounwind +define i32 @movi() #0 { +entry: + ret i32 123456 +; CHECK: movi $r0, 123456 +} + +; Function Attrs: noinline nounwind +define i32 @sethi_ori() #0 { +entry: + ret i32 1234567 +; CHECK: sethi $r0, 301 +; CHECK: ori $r0, $r0, 1671 +}