From 24e79e55daa5d2812d2a5ea0a282ebe48ef465e6 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 3 Aug 2012 22:57:02 +0000 Subject: [PATCH] 1. Redo mips16 instructions to avoid multiple opcodes for same instruction. Change these to patterns. 2. Add another 16 instructions. Patch by Reed Kotler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161272 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips16InstrInfo.td | 270 ++++++++++++++++++++----- lib/Target/Mips/Mips16RegisterInfo.cpp | 53 +++++ test/CodeGen/Mips/and1.ll | 17 ++ test/CodeGen/Mips/lb1.ll | 18 ++ test/CodeGen/Mips/lbu1.ll | 19 ++ test/CodeGen/Mips/lh1.ll | 18 ++ test/CodeGen/Mips/lhu1.ll | 19 ++ test/CodeGen/Mips/neg1.ll | 15 ++ test/CodeGen/Mips/not1.ll | 16 ++ test/CodeGen/Mips/or1.ll | 17 ++ test/CodeGen/Mips/sb1.ll | 20 ++ test/CodeGen/Mips/sh1.ll | 20 ++ test/CodeGen/Mips/sll1.ll | 19 ++ test/CodeGen/Mips/sll2.ll | 19 ++ test/CodeGen/Mips/sra1.ll | 15 ++ test/CodeGen/Mips/sra2.ll | 17 ++ test/CodeGen/Mips/srl1.ll | 18 ++ test/CodeGen/Mips/srl2.ll | 20 ++ test/CodeGen/Mips/sub1.ll | 15 ++ test/CodeGen/Mips/sub2.ll | 17 ++ test/CodeGen/Mips/xor1.ll | 17 ++ 21 files changed, 605 insertions(+), 54 deletions(-) create mode 100644 test/CodeGen/Mips/and1.ll create mode 100644 test/CodeGen/Mips/lb1.ll create mode 100644 test/CodeGen/Mips/lbu1.ll create mode 100644 test/CodeGen/Mips/lh1.ll create mode 100644 test/CodeGen/Mips/lhu1.ll create mode 100644 test/CodeGen/Mips/neg1.ll create mode 100644 test/CodeGen/Mips/not1.ll create mode 100644 test/CodeGen/Mips/or1.ll create mode 100644 test/CodeGen/Mips/sb1.ll create mode 100644 test/CodeGen/Mips/sh1.ll create mode 100644 test/CodeGen/Mips/sll1.ll create mode 100644 test/CodeGen/Mips/sll2.ll create mode 100644 test/CodeGen/Mips/sra1.ll create mode 100644 test/CodeGen/Mips/sra2.ll create mode 100644 test/CodeGen/Mips/srl1.ll create mode 100644 test/CodeGen/Mips/srl2.ll create mode 100644 test/CodeGen/Mips/sub1.ll create mode 100644 test/CodeGen/Mips/sub2.ll create mode 100644 test/CodeGen/Mips/xor1.ll diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index 35801952ab1..94cf984769b 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -11,10 +11,6 @@ // //===----------------------------------------------------------------------===// -def uimm5 : Operand { - let DecoderMethod= "DecodeSimm16"; -} - // // RRR-type instruction format // @@ -58,6 +54,20 @@ class FEXT_2RI16_ins _op, string asmstr, // // RR-type instruction format // + +class FRR16_ins f, string asmstr, InstrItinClass itin> : + FRR16 { +} + +class FRxRxRy16_ins f, string asmstr, + InstrItinClass itin> : + FRR16 { + let Constraints = "$rx = $rz"; +} + let rx=0 in class FRR16_JALRC_RA_only_ins nd_, bits<1> l_, string asmstr, InstrItinClass itin>: @@ -73,11 +83,16 @@ class FEXT_RRI16_mem_ins op, string asmstr, Operand MemOpnd, FEXT_RRI16; +class FEXT_RRI16_mem2_ins op, string asmstr, Operand MemOpnd, + InstrItinClass itin>: + FEXT_RRI16; + // // EXT-SHIFT instruction format // class FEXT_SHIFT16_ins _f, string asmstr, InstrItinClass itin>: - FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, uimm5:$sa), + FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, shamt:$sa), !strconcat(asmstr, "\t$rx, $ry, $sa"), [], itin>; // @@ -88,18 +103,28 @@ def mem16 : Operand { let EncoderMethod = "getMemEncoding"; } +// +// Some general instruction class info +// +// + +class ArithLogic16Defs { + bits<5> shamt = 0; + bit isCommutable = isCom; + bit isReMaterializable = 1; + bit neverHasSideEffects = 1; +} + // // Format: ADDIU rx, immediate MIPS16e // Purpose: Add Immediate Unsigned Word (2-Operand, Extended) // To add a constant to a 32-bit integer. // -class AddiuRxImmX16_base: FEXT_RI16_ins<0b01001, "addiu", IIAlu>; -def AddiuRxImmX16: AddiuRxImmX16_base; +def AddiuRxImmX16: FEXT_RI16_ins<0b01001, "addiu", IIAlu>; - -class AddiuRxRxImmX16_base: FEXT_2RI16_ins<0b01001, "addiu", IIAlu>; -def AddiuRxRxImmX16: AddiuRxRxImmX16_base; +def AddiuRxRxImmX16: FEXT_2RI16_ins<0b01001, "addiu", IIAlu>, + ArithLogic16Defs<0>; // @@ -107,16 +132,21 @@ def AddiuRxRxImmX16: AddiuRxRxImmX16_base; // Purpose: Add Immediate Unsigned Word (3-Operand, PC-Relative, Extended) // To add a constant to the program counter. // -class AddiuRxPcImmX16_base : FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>; -def AddiuRxPcImmX16 : AddiuRxPcImmX16_base; +def AddiuRxPcImmX16: FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>; // // Format: ADDU rz, rx, ry MIPS16e // Purpose: Add Unsigned Word (3-Operand) // To add 32-bit integers. // -class AdduRxRyRz16_base: FRRR16_ins<01, "addu", IIAlu>; -def AdduRxRyRz16: AdduRxRyRz16_base; +def AdduRxRyRz16: FRRR16_ins<01, "addu", IIAlu>, ArithLogic16Defs<1>; + +// +// Format: AND rx, ry MIPS16e +// Purpose: AND +// To do a bitwise logical AND. + +def AndRxRxRy16: FRxRxRy16_ins<0b01100, "and", IIAlu>, ArithLogic16Defs<1>; // // Format: JR ra MIPS16e @@ -127,6 +157,34 @@ def AdduRxRyRz16: AdduRxRyRz16_base; def JrRa16: FRR16_JALRC_RA_only_ins<0, 0, "jr", IIAlu>; +// +// Format: LB ry, offset(rx) MIPS16e +// Purpose: Load Byte (Extended) +// To load a byte from memory as a signed value. +// +def LbRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lb", mem16, IIAlu>; + +// +// Format: LBU ry, offset(rx) MIPS16e +// Purpose: Load Byte Unsigned (Extended) +// To load a byte from memory as a unsigned value. +// +def LbuRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lbu", mem16, IIAlu>; + +// +// Format: LH ry, offset(rx) MIPS16e +// Purpose: Load Halfword signed (Extended) +// To load a halfword from memory as a signed value. +// +def LhRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lh", mem16, IIAlu>; + +// +// Format: LHU ry, offset(rx) MIPS16e +// Purpose: Load Halfword unsigned (Extended) +// To load a halfword from memory as an unsigned value. +// +def LhuRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10100, "lhu", mem16, IIAlu>; + // // Format: LI rx, immediate MIPS16e // Purpose: Load Immediate (Extended) @@ -139,8 +197,7 @@ def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIAlu>; // Purpose: Load Word (Extended) // To load a word from memory as a signed value. // -class LwRxRyOffMemX16_base: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IIAlu>; -def LwRxRyOffMemX16: LwRxRyOffMemX16_base; +def LwRxRyOffMemX16: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IIAlu>; // // Format: MOVE r32, rz MIPS16e @@ -148,6 +205,28 @@ def LwRxRyOffMemX16: LwRxRyOffMemX16_base; // To move the contents of a GPR to a GPR. // def Mov32R16: FI8_MOV32R16_ins<"move", IIAlu>; + +// +// Format: NEG rx, ry MIPS16e +// Purpose: Negate +// To negate an integer value. +// +def NegRxRy16: FRR16_ins<0b11101, "neg", IIAlu>; + +// +// Format: NOT rx, ry MIPS16e +// Purpose: Not +// To complement an integer value +// +def NotRxRy16: FRR16_ins<0b01111, "not", IIAlu>; + +// +// Format: OR rx, ry MIPS16e +// Purpose: Or +// To do a bitwise logical OR. +// +def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>; + // // Format: RESTORE {ra,}{s0/s1/s0-1,}{framesize} // (All args are optional) MIPS16e @@ -178,6 +257,20 @@ def SaveRaF16: FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), "save \t$$ra, $frame_size", [], IILoad >; +// +// Format: SB ry, offset(rx) MIPS16e +// Purpose: Store Byte (Extended) +// To store a byte to memory. +// +def SbRxRyOffMemX16: FEXT_RRI16_mem2_ins<0b11000, "sb", mem16, IIAlu>; + +// +// Format: SH ry, offset(rx) MIPS16e +// Purpose: Store Halfword (Extended) +// To store a halfword to memory. +// +def ShRxRyOffMemX16: FEXT_RRI16_mem2_ins<0b11001, "sh", mem16, IIAlu>; + // // Format: SLL rx, ry, sa MIPS16e // Purpose: Shift Word Left Logical (Extended) @@ -185,58 +278,128 @@ def SaveRaF16: // def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>; +// +// Format: SLLV ry, rx MIPS16e +// Purpose: Shift Word Left Logical Variable +// To execute a left-shift of a word by a variable number of bits. +// +def SllvRxRy16 : FRxRxRy16_ins<0b00100, "sllv", IIAlu>; + + +// +// Format: SRAV ry, rx MIPS16e +// Purpose: Shift Word Right Arithmetic Variable +// To execute an arithmetic right-shift of a word by a variable +// number of bits. +// +def SravRxRy16: FRxRxRy16_ins<0b00111, "srav", IIAlu>; + + +// +// Format: SRA rx, ry, sa MIPS16e +// Purpose: Shift Word Right Arithmetic (Extended) +// To execute an arithmetic right-shift of a word by a fixed +// number of bits—1 to 8 bits. +// +def SraX16: FEXT_SHIFT16_ins<0b11, "sra", IIAlu>; + + +// +// Format: SRLV ry, rx MIPS16e +// Purpose: Shift Word Right Logical Variable +// To execute a logical right-shift of a word by a variable +// number of bits. +// +def SrlvRxRy16: FRxRxRy16_ins<0b00110, "srlv", IIAlu>; + + +// +// Format: SRL rx, ry, sa MIPS16e +// Purpose: Shift Word Right Logical (Extended) +// To execute a logical right-shift of a word by a fixed +// number of bits—1 to 31 bits. +// +def SrlX16: FEXT_SHIFT16_ins<0b10, "srl", IIAlu>; + +// +// Format: SUBU rz, rx, ry MIPS16e +// Purpose: Subtract Unsigned Word +// To subtract 32-bit integers +// +def SubuRxRyRz16: FRRR16_ins<0b11, "subu", IIAlu>, ArithLogic16Defs<0>; + // // Format: SW ry, offset(rx) MIPS16e // Purpose: Store Word (Extended) // To store a word to memory. // -class SwRxRyOffMemX16_base: FEXT_RRI16_mem_ins<0b11011, "sw", mem16, IIAlu>; -def SwRxRyOffMemX16: SwRxRyOffMemX16_base; +def SwRxRyOffMemX16: FEXT_RRI16_mem2_ins<0b11011, "sw", mem16, IIAlu>; + +// +// Format: XOR rx, ry MIPS16e +// Purpose: Xor +// To do a bitwise logical XOR. +// +def XorRxRxRy16: FRxRxRy16_ins<0b01110, "xor", IIAlu>, ArithLogic16Defs<1>; class Mips16Pat : Pat { let Predicates = [InMips16Mode]; } -class ArithLogicR16Defs { - dag OutOperandList = (outs CPU16Regs:$rz); - dag InOperandList = (ins CPU16Regs:$rx, CPU16Regs:$ry); - list Pattern = [(set CPU16Regs:$rz, - (OpNode CPU16Regs:$rx, CPU16Regs:$ry))]; -} +// Unary Arith/Logic +// +class ArithLogicU_pat : + Mips16Pat<(OpNode CPU16Regs:$r), + (I CPU16Regs:$r)>; -multiclass ArithLogicR16_base { - def _add: AdduRxRyRz16_base, ArithLogicR16Defs; -} +def: ArithLogicU_pat; +def: ArithLogicU_pat; -defm ArithLogicR16_patt : ArithLogicR16_base; +class ArithLogic16_pat : + Mips16Pat<(OpNode CPU16Regs:$l, CPU16Regs:$r), + (I CPU16Regs:$l, CPU16Regs:$r)>; -class LoadM16Defs { - bit isPseudo = Pseudo; - Operand MemOpnd = _MemOpnd; - dag OutOperandList = (outs CPU16Regs:$ry); - dag InOperandList = (ins MemOpnd:$addr); - list Pattern = [(set CPU16Regs:$ry, (OpNode addr:$addr))]; -} +def: ArithLogic16_pat; +def: ArithLogic16_pat; +def: ArithLogic16_pat; +def: ArithLogic16_pat; +def: ArithLogic16_pat; -multiclass LoadM16_base { - def _LwRxRyOffMemX16: LwRxRyOffMemX16_base, LoadM16Defs; -} +// Arithmetic and logical instructions with 2 register operands. -defm LoadM16: LoadM16_base; +class ArithLogicI16_pat : + Mips16Pat<(OpNode CPU16Regs:$in, imm_type:$imm), + (I CPU16Regs:$in, imm_type:$imm)>; -class StoreM16Defs { - bit isPseudo = Pseudo; - Operand MemOpnd = _MemOpnd; - dag OutOperandList = (outs ); - dag InOperandList = (ins CPU16Regs:$ry, MemOpnd:$addr); - list Pattern = [(OpNode CPU16Regs:$ry, addr:$addr)]; -} +def: ArithLogicI16_pat; +def: ArithLogicI16_pat; +def: ArithLogicI16_pat; +def: ArithLogicI16_pat; -multiclass StoreM16_base { - def _SwRxRyOffMemX16: SwRxRyOffMemX16_base, StoreM16Defs; -} +class shift_rotate_reg16_pat : + Mips16Pat<(OpNode CPU16Regs:$r, CPU16Regs:$ra), + (I CPU16Regs:$r, CPU16Regs:$ra)>; + +def: shift_rotate_reg16_pat; +def: shift_rotate_reg16_pat; +def: shift_rotate_reg16_pat; + +class LoadM16_pat : + Mips16Pat<(OpNode addr:$addr), (I addr:$addr)>; + +def: LoadM16_pat; +def: LoadM16_pat; +def: LoadM16_pat; +def: LoadM16_pat; +def: LoadM16_pat; + +class StoreM16_pat : + Mips16Pat<(OpNode CPU16Regs:$r, addr:$addr), (I CPU16Regs:$r, addr:$addr)>; + +def: StoreM16_pat; +def: StoreM16_pat; +def: StoreM16_pat; -defm StoreM16: StoreM16_base; // Jump and Link (Call) let isCall=1, hasDelaySlot=1 in @@ -250,8 +413,7 @@ let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>; // Small immediates -def : Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>; +def: Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>; - -def : Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)), - (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>; +def: Mips16Pat<(add CPU16Regs:$hi, (MipsLo tglobaladdr:$lo)), + (AddiuRxRxImmX16 CPU16Regs:$hi, tglobaladdr:$lo)>; diff --git a/lib/Target/Mips/Mips16RegisterInfo.cpp b/lib/Target/Mips/Mips16RegisterInfo.cpp index e0c4971f9d4..c15d1bf52e8 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.cpp +++ b/lib/Target/Mips/Mips16RegisterInfo.cpp @@ -55,4 +55,57 @@ void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II, unsigned OpNo, int FrameIndex, uint64_t StackSize, int64_t SPOffset) const { + MachineInstr &MI = *II; + MachineFunction &MF = *MI.getParent()->getParent(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + + const std::vector &CSI = MFI->getCalleeSavedInfo(); + int MinCSFI = 0; + int MaxCSFI = -1; + + if (CSI.size()) { + MinCSFI = CSI[0].getFrameIdx(); + MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); + } + + // The following stack frame objects are always + // referenced relative to $sp: + // 1. Outgoing arguments. + // 2. Pointer to dynamically allocated stack space. + // 3. Locations for callee-saved registers. + // Everything else is referenced relative to whatever register + // getFrameRegister() returns. + unsigned FrameReg; + + if (MipsFI->isOutArgFI(FrameIndex) || + (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)) + FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP; + else + FrameReg = getFrameRegister(MF); + + // Calculate final offset. + // - There is no need to change the offset if the frame object + // is one of the + // following: an outgoing argument, pointer to a dynamically allocated + // stack space or a $gp restore location, + // - If the frame object is any of the following, + // its offset must be adjusted + // by adding the size of the stack: + // incoming argument, callee-saved register location or local variable. + int64_t Offset; + + if (MipsFI->isOutArgFI(FrameIndex)) + Offset = SPOffset; + else + Offset = SPOffset + (int64_t)StackSize; + + Offset += MI.getOperand(OpNo + 1).getImm(); + + DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); + + MI.getOperand(OpNo).ChangeToRegister(FrameReg, false); + MI.getOperand(OpNo + 1).ChangeToImmediate(Offset); + + } diff --git a/test/CodeGen/Mips/and1.ll b/test/CodeGen/Mips/and1.ll new file mode 100644 index 00000000000..4ff1204fe7a --- /dev/null +++ b/test/CodeGen/Mips/and1.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@x = global i32 65504, align 4 +@y = global i32 60929, align 4 +@.str = private unnamed_addr constant [7 x i8] c"%08x \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @x, align 4 + %1 = load i32* @y, align 4 + %and = and i32 %0, %1 +; 16: and ${{[0-9]+}}, ${{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 %and) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/lb1.ll b/test/CodeGen/Mips/lb1.ll new file mode 100644 index 00000000000..aac2767a4e4 --- /dev/null +++ b/test/CodeGen/Mips/lb1.ll @@ -0,0 +1,18 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@c = global i8 -1, align 1 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %i = alloca i32, align 4 + %0 = load i8* @c, align 1 +; 16: lb ${{[0-9]+}}, 0(${{[0-9]+}}) + %conv = sext i8 %0 to i32 + store i32 %conv, i32* %i, align 4 + %1 = load i32* %i, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/lbu1.ll b/test/CodeGen/Mips/lbu1.ll new file mode 100644 index 00000000000..63e0cca1684 --- /dev/null +++ b/test/CodeGen/Mips/lbu1.ll @@ -0,0 +1,19 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@c = global i8 97, align 1 +@.str = private unnamed_addr constant [5 x i8] c"%c \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %i = alloca i32, align 4 + %0 = load i8* @c, align 1 + %conv = zext i8 %0 to i32 +; 16: lbu ${{[0-9]+}}, 0(${{[0-9]+}}) + store i32 %conv, i32* %i, align 4 + %1 = load i8* @c, align 1 + %conv1 = zext i8 %1 to i32 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %conv1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/lh1.ll b/test/CodeGen/Mips/lh1.ll new file mode 100644 index 00000000000..1f95b090346 --- /dev/null +++ b/test/CodeGen/Mips/lh1.ll @@ -0,0 +1,18 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@s = global i16 -1, align 2 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %i = alloca i32, align 4 + %0 = load i16* @s, align 2 + %conv = sext i16 %0 to i32 +; 16: lh ${{[0-9]+}}, 0(${{[0-9]+}}) + store i32 %conv, i32* %i, align 4 + %1 = load i32* %i, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/lhu1.ll b/test/CodeGen/Mips/lhu1.ll new file mode 100644 index 00000000000..0cfcede669e --- /dev/null +++ b/test/CodeGen/Mips/lhu1.ll @@ -0,0 +1,19 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + + +@s = global i16 255, align 2 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %i = alloca i32, align 4 + %0 = load i16* @s, align 2 + %conv = zext i16 %0 to i32 +; 16: lhu ${{[0-9]+}}, 0(${{[0-9]+}}) + store i32 %conv, i32* %i, align 4 + %1 = load i32* %i, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/neg1.ll b/test/CodeGen/Mips/neg1.ll new file mode 100644 index 00000000000..281e6262156 --- /dev/null +++ b/test/CodeGen/Mips/neg1.ll @@ -0,0 +1,15 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 10, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %sub = sub nsw i32 0, %0 +; 16: neg ${{[0-9]+}}, ${{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %sub) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/not1.ll b/test/CodeGen/Mips/not1.ll new file mode 100644 index 00000000000..2163b236c56 --- /dev/null +++ b/test/CodeGen/Mips/not1.ll @@ -0,0 +1,16 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@x = global i32 65504, align 4 +@y = global i32 60929, align 4 +@.str = private unnamed_addr constant [7 x i8] c"%08x \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @x, align 4 + %neg = xor i32 %0, -1 +; 16: not ${{[0-9]+}}, ${{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 %neg) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/or1.ll b/test/CodeGen/Mips/or1.ll new file mode 100644 index 00000000000..b1c36961f92 --- /dev/null +++ b/test/CodeGen/Mips/or1.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@x = global i32 65504, align 4 +@y = global i32 60929, align 4 +@.str = private unnamed_addr constant [7 x i8] c"%08x \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @x, align 4 + %1 = load i32* @y, align 4 + %or = or i32 %0, %1 +; 16: or ${{[0-9]+}}, ${{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 %or) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sb1.ll b/test/CodeGen/Mips/sb1.ll new file mode 100644 index 00000000000..e1a28d45954 --- /dev/null +++ b/test/CodeGen/Mips/sb1.ll @@ -0,0 +1,20 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 97, align 4 +@c = common global i8 0, align 1 +@.str = private unnamed_addr constant [8 x i8] c"%i %c \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %conv = trunc i32 %0 to i8 + store i8 %conv, i8* @c, align 1 + %1 = load i32* @i, align 4 + %2 = load i8* @c, align 1 + %conv1 = sext i8 %2 to i32 +; 16: sb ${{[0-9]+}}, 0(${{[0-9]+}}) + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), i32 %1, i32 %conv1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sh1.ll b/test/CodeGen/Mips/sh1.ll new file mode 100644 index 00000000000..1746ae284f2 --- /dev/null +++ b/test/CodeGen/Mips/sh1.ll @@ -0,0 +1,20 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 97, align 4 +@s = common global i16 0, align 2 +@.str = private unnamed_addr constant [9 x i8] c"%i %hi \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %conv = trunc i32 %0 to i16 + store i16 %conv, i16* @s, align 2 + %1 = load i32* @i, align 4 + %2 = load i16* @s, align 2 + %conv1 = sext i16 %2 to i32 +; 16: sh ${{[0-9]+}}, 0(${{[0-9]+}}) + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i32 %1, i32 %conv1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sll1.ll b/test/CodeGen/Mips/sll1.ll new file mode 100644 index 00000000000..fdcd38c84b3 --- /dev/null +++ b/test/CodeGen/Mips/sll1.ll @@ -0,0 +1,19 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 10, align 4 +@j = global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: +; 16: sll ${{[0-9]+}}, ${{[0-9]+}}, {{[0-9]+}} + %0 = load i32* @i, align 4 + %shl = shl i32 %0, 4 +; 16: sll ${{[0-9]+}}, ${{[0-9]+}}, {{[0-9]+}} + store i32 %shl, i32* @j, align 4 + %1 = load i32* @j, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sll2.ll b/test/CodeGen/Mips/sll2.ll new file mode 100644 index 00000000000..c2af454cc85 --- /dev/null +++ b/test/CodeGen/Mips/sll2.ll @@ -0,0 +1,19 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 10, align 4 +@j = global i32 4, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %1 = load i32* @j, align 4 + %shl = shl i32 %0, %1 +; 16: sllv ${{[0-9]+}}, ${{[0-9]+}} + store i32 %shl, i32* @i, align 4 + %2 = load i32* @j, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %2) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sra1.ll b/test/CodeGen/Mips/sra1.ll new file mode 100644 index 00000000000..15bf8d644ea --- /dev/null +++ b/test/CodeGen/Mips/sra1.ll @@ -0,0 +1,15 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 -354, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %shr = ashr i32 %0, 3 +; 16: sra ${{[0-9]+}}, ${{[0-9]+}}, {{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %shr) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sra2.ll b/test/CodeGen/Mips/sra2.ll new file mode 100644 index 00000000000..26bf19d4402 --- /dev/null +++ b/test/CodeGen/Mips/sra2.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 -354, align 4 +@j = global i32 3, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %1 = load i32* @j, align 4 + %shr = ashr i32 %0, %1 +; 16: srav ${{[0-9]+}}, ${{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %shr) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/srl1.ll b/test/CodeGen/Mips/srl1.ll new file mode 100644 index 00000000000..3474283faef --- /dev/null +++ b/test/CodeGen/Mips/srl1.ll @@ -0,0 +1,18 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 10654, align 4 +@j = global i32 0, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %shr = lshr i32 %0, 4 +; 16: srl ${{[0-9]+}}, ${{[0-9]+}}, {{[0-9]+}} + store i32 %shr, i32* @j, align 4 + %1 = load i32* @j, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %1) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/srl2.ll b/test/CodeGen/Mips/srl2.ll new file mode 100644 index 00000000000..26ec0927a55 --- /dev/null +++ b/test/CodeGen/Mips/srl2.ll @@ -0,0 +1,20 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 10654, align 4 +@j = global i32 0, align 4 +@k = global i32 4, align 4 +@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %1 = load i32* @k, align 4 + %shr = lshr i32 %0, %1 +; 16: srlv ${{[0-9]+}}, ${{[0-9]+}} + store i32 %shr, i32* @j, align 4 + %2 = load i32* @j, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %2) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sub1.ll b/test/CodeGen/Mips/sub1.ll new file mode 100644 index 00000000000..195750b805d --- /dev/null +++ b/test/CodeGen/Mips/sub1.ll @@ -0,0 +1,15 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 10, align 4 +@.str = private unnamed_addr constant [4 x i8] c"%i\0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @i, align 4 + %sub = sub nsw i32 %0, 5 +; 16: addiu ${{[0-9]+}}, -{{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %sub) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/sub2.ll b/test/CodeGen/Mips/sub2.ll new file mode 100644 index 00000000000..4f6bfccec40 --- /dev/null +++ b/test/CodeGen/Mips/sub2.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@i = global i32 10, align 4 +@j = global i32 20, align 4 +@.str = private unnamed_addr constant [4 x i8] c"%i\0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @j, align 4 + %1 = load i32* @i, align 4 + %sub = sub nsw i32 %0, %1 +; 16: subu ${{[0-9]+}}, ${{[0-9]+}}, ${{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %sub) + ret i32 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/xor1.ll b/test/CodeGen/Mips/xor1.ll new file mode 100644 index 00000000000..f2c13169cf7 --- /dev/null +++ b/test/CodeGen/Mips/xor1.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@x = global i32 65504, align 4 +@y = global i32 60929, align 4 +@.str = private unnamed_addr constant [7 x i8] c"%08x \0A\00", align 1 + +define i32 @main() nounwind { +entry: + %0 = load i32* @x, align 4 + %1 = load i32* @y, align 4 + %xor = xor i32 %0, %1 +; 16: xor ${{[0-9]+}}, ${{[0-9]+}} + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 %xor) + ret i32 0 +} + +declare i32 @printf(i8*, ...)