MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const {
- unsigned Opc = 0, ZeroReg = 0;
+ unsigned Opc = 0;
+
+ if (Mips::CPU16RegsRegClass.contains(DestReg) &&
+ Mips::CPURegsRegClass.contains(SrcReg))
+ Opc = Mips::MoveR3216;
+ else if (Mips::CPURegsRegClass.contains(DestReg) &&
+ Mips::CPU16RegsRegClass.contains(SrcReg))
+ Opc = Mips::Move32R16;
+ else if ((SrcReg == Mips::HI) &&
+ (Mips::CPU16RegsRegClass.contains(DestReg)))
+ Opc = Mips::Mfhi16, SrcReg = 0;
+
+ else if ((SrcReg == Mips::LO) &&
+ (Mips::CPU16RegsRegClass.contains(DestReg)))
+ Opc = Mips::Mflo16, SrcReg = 0;
- if (Mips::CPURegsRegClass.contains(DestReg)) { // Copy to CPU Reg.
- if (Mips::CPURegsRegClass.contains(SrcReg))
- Opc = Mips::Move32R16;
- }
assert(Opc && "Cannot copy registers");
if (DestReg)
MIB.addReg(DestReg, RegState::Define);
- if (ZeroReg)
- MIB.addReg(ZeroReg);
-
if (SrcReg)
MIB.addReg(SrcReg, getKillRegState(KillSrc));
}
FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
}
+
+//
+// maybe refactor but need a $zero as a dummy first parameter
+//
+class FRR16_div_ins<bits<5> f, string asmstr, InstrItinClass itin> :
+ FRR16<f, (outs ), (ins CPU16Regs:$rx, CPU16Regs:$ry),
+ !strconcat(asmstr, "\t$$zero, $rx, $ry"), [], itin> ;
+
class FRR16_M_ins<bits<5> f, string asmstr,
InstrItinClass itin> :
FRR16<f, (outs CPU16Regs:$rx), (ins),
// To do a bitwise logical AND.
def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIAlu>, ArithLogic16Defs<1>;
+//
+// Format: DIV rx, ry MIPS16e
+// Purpose: Divide Word
+// To divide 32-bit signed integers.
+//
+def DivRxRy16: FRR16_div_ins<0b11010, "div", IIAlu> {
+ let Defs = [HI, LO];
+}
+
+//
+// Format: DIVU rx, ry MIPS16e
+// Purpose: Divide Unsigned Word
+// To divide 32-bit unsigned integers.
+//
+def DivuRxRy16: FRR16_div_ins<0b11011, "divu", IIAlu> {
+ let Defs = [HI, LO];
+}
+
//
// Format: JR ra MIPS16e
// Small immediates
def: Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>;
+//
+// MipsDivRem
+//
+def: Mips16Pat
+ <(MipsDivRem CPU16Regs:$rx, CPU16Regs:$ry),
+ (DivRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
+
+//
+// MipsDivRemU
+//
+def: Mips16Pat
+ <(MipsDivRemU CPU16Regs:$rx, CPU16Regs:$ry),
+ (DivuRxRy16 CPU16Regs:$rx, CPU16Regs:$ry)>;
+
+
def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)),
(AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>;
--- /dev/null
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i32 100, align 4
+@jjjj = global i32 -4, align 4
+@kkkk = common global i32 0, align 4
+
+define void @test() nounwind {
+entry:
+ %0 = load i32* @iiii, align 4
+ %1 = load i32* @jjjj, align 4
+ %div = sdiv i32 %0, %1
+; 16: div $zero, ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+ store i32 %div, i32* @kkkk, align 4
+ ret void
+}
+
+
--- /dev/null
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i32 103, align 4
+@jjjj = global i32 -4, align 4
+@kkkk = common global i32 0, align 4
+@llll = common global i32 0, align 4
+
+define void @test() nounwind {
+entry:
+ %0 = load i32* @iiii, align 4
+ %1 = load i32* @jjjj, align 4
+ %div = sdiv i32 %0, %1
+ store i32 %div, i32* @kkkk, align 4
+ %rem = srem i32 %0, %1
+; 16: div $zero, ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+; 16: mfhi ${{[0-9]+}}
+ store i32 %rem, i32* @llll, align 4
+ ret void
+}
+
--- /dev/null
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i32 100, align 4
+@jjjj = global i32 4, align 4
+@kkkk = common global i32 0, align 4
+
+define void @test() nounwind {
+entry:
+ %0 = load i32* @iiii, align 4
+ %1 = load i32* @jjjj, align 4
+ %div = udiv i32 %0, %1
+; 16: divu $zero, ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+ store i32 %div, i32* @kkkk, align 4
+ ret void
+}
+
+
--- /dev/null
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i32 103, align 4
+@jjjj = global i32 4, align 4
+@kkkk = common global i32 0, align 4
+@llll = common global i32 0, align 4
+
+
+define void @test() nounwind {
+entry:
+ %0 = load i32* @iiii, align 4
+ %1 = load i32* @jjjj, align 4
+ %div = udiv i32 %0, %1
+ store i32 %div, i32* @kkkk, align 4
+ %rem = urem i32 %0, %1
+; 16: divu $zero, ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mflo ${{[0-9]+}}
+; 16: mfhi ${{[0-9]+}}
+ store i32 %rem, i32* @llll, align 4
+ ret void
+}
+
+
--- /dev/null
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i32 103, align 4
+@jjjj = global i32 -4, align 4
+@kkkk = common global i32 0, align 4
+
+
+define void @test() nounwind {
+entry:
+ %0 = load i32* @iiii, align 4
+ %1 = load i32* @jjjj, align 4
+ %rem = srem i32 %0, %1
+; 16: div $zero, ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mfhi ${{[0-9]+}}
+ store i32 %rem, i32* @kkkk, align 4
+ ret void
+}
+
+
--- /dev/null
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
+
+@iiii = global i32 103, align 4
+@jjjj = global i32 4, align 4
+@kkkk = common global i32 0, align 4
+@.str = private unnamed_addr constant [15 x i8] c"%u = %u %% %u\0A\00", align 1
+
+define void @test() nounwind {
+entry:
+ %0 = load i32* @iiii, align 4
+ %1 = load i32* @jjjj, align 4
+ %rem = urem i32 %0, %1
+; 16: divu $zero, ${{[0-9]+}}, ${{[0-9]+}}
+; 16: mfhi ${{[0-9]+}}
+ store i32 %rem, i32* @kkkk, align 4
+ ret void
+}
+