mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
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
This commit is contained in:
parent
dcc4436cdd
commit
24e79e55da
@ -11,10 +11,6 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def uimm5 : Operand<i8> {
|
||||
let DecoderMethod= "DecodeSimm16";
|
||||
}
|
||||
|
||||
//
|
||||
// RRR-type instruction format
|
||||
//
|
||||
@ -58,6 +54,20 @@ class FEXT_2RI16_ins<bits<5> _op, string asmstr,
|
||||
//
|
||||
// RR-type instruction format
|
||||
//
|
||||
|
||||
class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
|
||||
FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
|
||||
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
|
||||
}
|
||||
|
||||
class FRxRxRy16_ins<bits<5> f, string asmstr,
|
||||
InstrItinClass itin> :
|
||||
FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
|
||||
!strconcat(asmstr, "\t$rz, $ry"),
|
||||
[], itin> {
|
||||
let Constraints = "$rx = $rz";
|
||||
}
|
||||
|
||||
let rx=0 in
|
||||
class FRR16_JALRC_RA_only_ins<bits<1> nd_, bits<1> l_,
|
||||
string asmstr, InstrItinClass itin>:
|
||||
@ -73,11 +83,16 @@ class FEXT_RRI16_mem_ins<bits<5> op, string asmstr, Operand MemOpnd,
|
||||
FEXT_RRI16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr),
|
||||
!strconcat(asmstr, "\t$ry, $addr"), [], itin>;
|
||||
|
||||
class FEXT_RRI16_mem2_ins<bits<5> op, string asmstr, Operand MemOpnd,
|
||||
InstrItinClass itin>:
|
||||
FEXT_RRI16<op, (outs ), (ins CPU16Regs:$ry, MemOpnd:$addr),
|
||||
!strconcat(asmstr, "\t$ry, $addr"), [], itin>;
|
||||
|
||||
//
|
||||
// EXT-SHIFT instruction format
|
||||
//
|
||||
class FEXT_SHIFT16_ins<bits<2> _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<i32> {
|
||||
let EncoderMethod = "getMemEncoding";
|
||||
}
|
||||
|
||||
//
|
||||
// Some general instruction class info
|
||||
//
|
||||
//
|
||||
|
||||
class ArithLogic16Defs<bit isCom=0> {
|
||||
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<dag pattern, dag result> : Pat<pattern, result> {
|
||||
let Predicates = [InMips16Mode];
|
||||
}
|
||||
|
||||
class ArithLogicR16Defs<SDNode OpNode, bit isComm = 0> {
|
||||
dag OutOperandList = (outs CPU16Regs:$rz);
|
||||
dag InOperandList = (ins CPU16Regs:$rx, CPU16Regs:$ry);
|
||||
list<dag> Pattern = [(set CPU16Regs:$rz,
|
||||
(OpNode CPU16Regs:$rx, CPU16Regs:$ry))];
|
||||
}
|
||||
// Unary Arith/Logic
|
||||
//
|
||||
class ArithLogicU_pat<PatFrag OpNode, Instruction I> :
|
||||
Mips16Pat<(OpNode CPU16Regs:$r),
|
||||
(I CPU16Regs:$r)>;
|
||||
|
||||
multiclass ArithLogicR16_base {
|
||||
def _add: AdduRxRyRz16_base, ArithLogicR16Defs<add, 1>;
|
||||
}
|
||||
def: ArithLogicU_pat<not, NotRxRy16>;
|
||||
def: ArithLogicU_pat<ineg, NegRxRy16>;
|
||||
|
||||
defm ArithLogicR16_patt : ArithLogicR16_base;
|
||||
class ArithLogic16_pat<SDNode OpNode, Instruction I> :
|
||||
Mips16Pat<(OpNode CPU16Regs:$l, CPU16Regs:$r),
|
||||
(I CPU16Regs:$l, CPU16Regs:$r)>;
|
||||
|
||||
class LoadM16Defs<PatFrag OpNode, Operand _MemOpnd, bit Pseudo=0> {
|
||||
bit isPseudo = Pseudo;
|
||||
Operand MemOpnd = _MemOpnd;
|
||||
dag OutOperandList = (outs CPU16Regs:$ry);
|
||||
dag InOperandList = (ins MemOpnd:$addr);
|
||||
list<dag> Pattern = [(set CPU16Regs:$ry, (OpNode addr:$addr))];
|
||||
}
|
||||
def: ArithLogic16_pat<add, AdduRxRyRz16>;
|
||||
def: ArithLogic16_pat<and, AndRxRxRy16>;
|
||||
def: ArithLogic16_pat<or, OrRxRxRy16>;
|
||||
def: ArithLogic16_pat<sub, SubuRxRyRz16>;
|
||||
def: ArithLogic16_pat<xor, XorRxRxRy16>;
|
||||
|
||||
multiclass LoadM16_base {
|
||||
def _LwRxRyOffMemX16: LwRxRyOffMemX16_base, LoadM16Defs<load_a, mem16>;
|
||||
}
|
||||
// Arithmetic and logical instructions with 2 register operands.
|
||||
|
||||
defm LoadM16: LoadM16_base;
|
||||
class ArithLogicI16_pat<SDNode OpNode, PatFrag imm_type, Instruction I> :
|
||||
Mips16Pat<(OpNode CPU16Regs:$in, imm_type:$imm),
|
||||
(I CPU16Regs:$in, imm_type:$imm)>;
|
||||
|
||||
class StoreM16Defs<PatFrag OpNode, Operand _MemOpnd, bit Pseudo=0> {
|
||||
bit isPseudo = Pseudo;
|
||||
Operand MemOpnd = _MemOpnd;
|
||||
dag OutOperandList = (outs );
|
||||
dag InOperandList = (ins CPU16Regs:$ry, MemOpnd:$addr);
|
||||
list<dag> Pattern = [(OpNode CPU16Regs:$ry, addr:$addr)];
|
||||
}
|
||||
def: ArithLogicI16_pat<add, immSExt16, AddiuRxRxImmX16>;
|
||||
def: ArithLogicI16_pat<shl, immZExt5, SllX16>;
|
||||
def: ArithLogicI16_pat<srl, immZExt5, SrlX16>;
|
||||
def: ArithLogicI16_pat<sra, immZExt5, SraX16>;
|
||||
|
||||
multiclass StoreM16_base {
|
||||
def _SwRxRyOffMemX16: SwRxRyOffMemX16_base, StoreM16Defs<store_a, mem16>;
|
||||
}
|
||||
class shift_rotate_reg16_pat<SDNode OpNode, Instruction I> :
|
||||
Mips16Pat<(OpNode CPU16Regs:$r, CPU16Regs:$ra),
|
||||
(I CPU16Regs:$r, CPU16Regs:$ra)>;
|
||||
|
||||
def: shift_rotate_reg16_pat<shl, SllvRxRy16>;
|
||||
def: shift_rotate_reg16_pat<sra, SravRxRy16>;
|
||||
def: shift_rotate_reg16_pat<srl, SrlvRxRy16>;
|
||||
|
||||
class LoadM16_pat<PatFrag OpNode, Instruction I> :
|
||||
Mips16Pat<(OpNode addr:$addr), (I addr:$addr)>;
|
||||
|
||||
def: LoadM16_pat<sextloadi8, LbRxRyOffMemX16>;
|
||||
def: LoadM16_pat<zextloadi8, LbuRxRyOffMemX16>;
|
||||
def: LoadM16_pat<sextloadi16_a, LhRxRyOffMemX16>;
|
||||
def: LoadM16_pat<zextloadi16_a, LhuRxRyOffMemX16>;
|
||||
def: LoadM16_pat<load_a, LwRxRyOffMemX16>;
|
||||
|
||||
class StoreM16_pat<PatFrag OpNode, Instruction I> :
|
||||
Mips16Pat<(OpNode CPU16Regs:$r, addr:$addr), (I CPU16Regs:$r, addr:$addr)>;
|
||||
|
||||
def: StoreM16_pat<truncstorei8, SbRxRyOffMemX16>;
|
||||
def: StoreM16_pat<truncstorei16_a, ShRxRyOffMemX16>;
|
||||
def: StoreM16_pat<store_a, SwRxRyOffMemX16>;
|
||||
|
||||
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)>;
|
||||
|
@ -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<MipsFunctionInfo>();
|
||||
|
||||
const std::vector<CalleeSavedInfo> &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);
|
||||
|
||||
|
||||
}
|
||||
|
17
test/CodeGen/Mips/and1.ll
Normal file
17
test/CodeGen/Mips/and1.ll
Normal file
@ -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*, ...)
|
18
test/CodeGen/Mips/lb1.ll
Normal file
18
test/CodeGen/Mips/lb1.ll
Normal file
@ -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*, ...)
|
19
test/CodeGen/Mips/lbu1.ll
Normal file
19
test/CodeGen/Mips/lbu1.ll
Normal file
@ -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*, ...)
|
18
test/CodeGen/Mips/lh1.ll
Normal file
18
test/CodeGen/Mips/lh1.ll
Normal file
@ -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*, ...)
|
19
test/CodeGen/Mips/lhu1.ll
Normal file
19
test/CodeGen/Mips/lhu1.ll
Normal file
@ -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*, ...)
|
15
test/CodeGen/Mips/neg1.ll
Normal file
15
test/CodeGen/Mips/neg1.ll
Normal file
@ -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*, ...)
|
16
test/CodeGen/Mips/not1.ll
Normal file
16
test/CodeGen/Mips/not1.ll
Normal file
@ -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*, ...)
|
17
test/CodeGen/Mips/or1.ll
Normal file
17
test/CodeGen/Mips/or1.ll
Normal file
@ -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*, ...)
|
20
test/CodeGen/Mips/sb1.ll
Normal file
20
test/CodeGen/Mips/sb1.ll
Normal file
@ -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*, ...)
|
20
test/CodeGen/Mips/sh1.ll
Normal file
20
test/CodeGen/Mips/sh1.ll
Normal file
@ -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*, ...)
|
19
test/CodeGen/Mips/sll1.ll
Normal file
19
test/CodeGen/Mips/sll1.ll
Normal file
@ -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*, ...)
|
19
test/CodeGen/Mips/sll2.ll
Normal file
19
test/CodeGen/Mips/sll2.ll
Normal file
@ -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*, ...)
|
15
test/CodeGen/Mips/sra1.ll
Normal file
15
test/CodeGen/Mips/sra1.ll
Normal file
@ -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*, ...)
|
17
test/CodeGen/Mips/sra2.ll
Normal file
17
test/CodeGen/Mips/sra2.ll
Normal file
@ -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*, ...)
|
18
test/CodeGen/Mips/srl1.ll
Normal file
18
test/CodeGen/Mips/srl1.ll
Normal file
@ -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*, ...)
|
20
test/CodeGen/Mips/srl2.ll
Normal file
20
test/CodeGen/Mips/srl2.ll
Normal file
@ -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*, ...)
|
15
test/CodeGen/Mips/sub1.ll
Normal file
15
test/CodeGen/Mips/sub1.ll
Normal file
@ -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*, ...)
|
17
test/CodeGen/Mips/sub2.ll
Normal file
17
test/CodeGen/Mips/sub2.ll
Normal file
@ -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*, ...)
|
17
test/CodeGen/Mips/xor1.ll
Normal file
17
test/CodeGen/Mips/xor1.ll
Normal file
@ -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*, ...)
|
Loading…
Reference in New Issue
Block a user