//===- MBlazeInstrInfo.td - MBlaze Instruction defs -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // Instruction format superclass //===----------------------------------------------------------------------===// include "MBlazeInstrFormats.td" //===----------------------------------------------------------------------===// // MBlaze profiles and nodes //===----------------------------------------------------------------------===// def SDT_MBlazeRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def SDT_MBlazeJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; // Call def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink, [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag]>; // Return def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet, [SDNPHasChain, SDNPOptInFlag]>; // Hi and Lo nodes are used to handle global addresses. Used on // MBlazeISelLowering to lower stuff like GlobalAddress, ExternalSymbol // static model. def MBWrapper : SDNode<"MBlazeISD::Wrap", SDTIntUnaryOp>; def MBlazeGPRel : SDNode<"MBlazeISD::GPRel", SDTIntUnaryOp>; def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; // These are target-independent nodes, but have target-specific formats. def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MBCallSeqStart, [SDNPHasChain, SDNPOutFlag]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MBCallSeqEnd, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>; //===----------------------------------------------------------------------===// // MBlaze Instruction Predicate Definitions. //===----------------------------------------------------------------------===// def HasPipe3 : Predicate<"Subtarget.hasPipe3()">; def HasBarrel : Predicate<"Subtarget.hasBarrel()">; def NoBarrel : Predicate<"!Subtarget.hasBarrel()">; def HasDiv : Predicate<"Subtarget.hasDiv()">; def HasMul : Predicate<"Subtarget.hasMul()">; def HasFSL : Predicate<"Subtarget.hasFSL()">; def HasEFSL : Predicate<"Subtarget.hasEFSL()">; def HasMSRSet : Predicate<"Subtarget.hasMSRSet()">; def HasException : Predicate<"Subtarget.hasException()">; def HasPatCmp : Predicate<"Subtarget.hasPatCmp()">; def HasFPU : Predicate<"Subtarget.hasFPU()">; def HasESR : Predicate<"Subtarget.hasESR()">; def HasPVR : Predicate<"Subtarget.hasPVR()">; def HasMul64 : Predicate<"Subtarget.hasMul64()">; def HasSqrt : Predicate<"Subtarget.hasSqrt()">; def HasMMU : Predicate<"Subtarget.hasMMU()">; //===----------------------------------------------------------------------===// // MBlaze Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// // Instruction operand types def brtarget : Operand; def calltarget : Operand; def simm16 : Operand; def uimm5 : Operand; def fimm : Operand; // Unsigned Operand def uimm16 : Operand { let PrintMethod = "printUnsignedImm"; } // FSL Operand def fslimm : Operand { let PrintMethod = "printFSLImm"; } // Address operand def memri : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops simm16, CPURegs); } def memrr : Operand { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops CPURegs, CPURegs); } // Transformation Function - get the lower 16 bits. def LO16 : SDNodeXFormgetZExtValue() & 0xFFFF); }]>; // Transformation Function - get the higher 16 bits. def HI16 : SDNodeXFormgetZExtValue() >> 16); }]>; // Node immediate fits as 16-bit sign extended on target immediate. // e.g. addi, andi def immSExt16 : PatLeaf<(imm), [{ return (N->getZExtValue() >> 16) == 0; }]>; // Node immediate fits as 16-bit zero extended on target immediate. // The LO16 param means that only the lower 16 bits of the node // immediate are caught. // e.g. addiu, sltiu def immZExt16 : PatLeaf<(imm), [{ return (N->getZExtValue() >> 16) == 0; }], LO16>; // FSL immediate field must fit in 4 bits. def immZExt4 : PatLeaf<(imm), [{ return N->getZExtValue() == ((N->getZExtValue()) & 0xf) ; }]>; // shamt field must fit in 5 bits. def immZExt5 : PatLeaf<(imm), [{ return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ; }]>; // MBlaze Address Mode! SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def iaddr : ComplexPattern; def xaddr : ComplexPattern; //===----------------------------------------------------------------------===// // Pseudo instructions //===----------------------------------------------------------------------===// // As stack alignment is always done with addiu, we need a 16-bit immediate let Defs = [R1], Uses = [R1] in { def ADJCALLSTACKDOWN : MBlazePseudo<(outs), (ins simm16:$amt), "${:comment} ADJCALLSTACKDOWN $amt", [(callseq_start timm:$amt)]>; def ADJCALLSTACKUP : MBlazePseudo<(outs), (ins uimm16:$amt1, simm16:$amt2), "${:comment} ADJCALLSTACKUP $amt1", [(callseq_end timm:$amt1, timm:$amt2)]>; } // Some assembly macros need to avoid pseudoinstructions and assembler // automatic reodering, we should reorder ourselves. def MACRO : MBlazePseudo<(outs), (ins), ".set macro", []>; def REORDER : MBlazePseudo<(outs), (ins), ".set reorder", []>; def NOMACRO : MBlazePseudo<(outs), (ins), ".set nomacro", []>; def NOREORDER : MBlazePseudo<(outs), (ins), ".set noreorder", []>; // When handling PIC code the assembler needs .cpload and .cprestore // directives. If the real instructions corresponding these directives // are used, we have the same behavior, but get also a bunch of warnings // from the assembler. def CPLOAD : MBlazePseudo<(outs), (ins CPURegs:$reg), ".cpload $reg", []>; def CPRESTORE : MBlazePseudo<(outs), (ins uimm16:$l), ".cprestore $l\n", []>; //===----------------------------------------------------------------------===// // Instructions specific format //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // Arithmetic Instructions //===----------------------------------------------------------------------===// class Arith op, bits<11> flags, string instr_asm, SDNode OpNode, InstrItinClass itin> : TA; class ArithI op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type> : TAI; class ArithR op, bits<11> flags, string instr_asm, SDNode OpNode, InstrItinClass itin> : TA; class ArithRI op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type> : TAI; class ArithN op, bits<11> flags, string instr_asm, InstrItinClass itin> : TA; class ArithNI op, string instr_asm,Operand Od, PatLeaf imm_type> : TAI; class ArithRN op, bits<11> flags, string instr_asm, InstrItinClass itin> : TA; class ArithRNI op, string instr_asm,Operand Od, PatLeaf imm_type> : TAI; //===----------------------------------------------------------------------===// // Misc Arithmetic Instructions //===----------------------------------------------------------------------===// class Logic op, bits<11> flags, string instr_asm, SDNode OpNode> : TA; class LogicI op, string instr_asm, SDNode OpNode> : TAI; class EffectiveAddress : TAI<0x08, (outs CPURegs:$dst), (ins memri:$addr), instr_asm, [(set CPURegs:$dst, iaddr:$addr)], IIAlu>; //===----------------------------------------------------------------------===// // Memory Access Instructions //===----------------------------------------------------------------------===// class LoadM op, string instr_asm, PatFrag OpNode> : TA; class LoadMI op, string instr_asm, PatFrag OpNode> : TAI; class StoreM op, string instr_asm, PatFrag OpNode> : TA; class StoreMI op, string instr_asm, PatFrag OpNode> : TAI; //===----------------------------------------------------------------------===// // Branch Instructions //===----------------------------------------------------------------------===// class Branch op, bits<5> br, bits<11> flags, string instr_asm> : TBR; class BranchI op, bits<5> brf, string instr_asm> : TBRI; //===----------------------------------------------------------------------===// // Branch and Link Instructions //===----------------------------------------------------------------------===// class BranchL op, bits<5> br, bits<11> flags, string instr_asm> : TBRL; class BranchLI op, bits<5> br, string instr_asm> : TBRLI; //===----------------------------------------------------------------------===// // Conditional Branch Instructions //===----------------------------------------------------------------------===// class BranchC op, bits<5> br, bits<11> flags, string instr_asm, PatFrag cond_op> : TBRC; //(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)], //IIBranch>; class BranchCI op, bits<5> br, string instr_asm, PatFrag cond_op> : TBRCI; //===----------------------------------------------------------------------===// // MBlaze arithmetic instructions //===----------------------------------------------------------------------===// let isCommutable = 1, isAsCheapAsAMove = 1 in { def ADD : Arith<0x00, 0x000, "add ", add, IIAlu>; def ADDC : Arith<0x02, 0x000, "addc ", adde, IIAlu>; def ADDK : Arith<0x04, 0x000, "addk ", addc, IIAlu>; def ADDKC : ArithN<0x06, 0x000, "addkc ", IIAlu>; def AND : Logic<0x21, 0x000, "and ", and>; def OR : Logic<0x20, 0x000, "or ", or>; def XOR : Logic<0x22, 0x000, "xor ", xor>; } let isAsCheapAsAMove = 1 in { def ANDN : ArithN<0x23, 0x000, "andn ", IIAlu>; def CMP : ArithN<0x05, 0x001, "cmp ", IIAlu>; def CMPU : ArithN<0x05, 0x003, "cmpu ", IIAlu>; def RSUB : ArithR<0x01, 0x000, "rsub ", sub, IIAlu>; def RSUBC : ArithR<0x03, 0x000, "rsubc ", sube, IIAlu>; def RSUBK : ArithR<0x05, 0x000, "rsubk ", subc, IIAlu>; def RSUBKC : ArithRN<0x07, 0x000, "rsubkc ", IIAlu>; } let isCommutable = 1, Predicates=[HasMul] in { def MUL : Arith<0x10, 0x000, "mul ", mul, IIAlu>; } let isCommutable = 1, Predicates=[HasMul,HasMul64] in { def MULH : Arith<0x10, 0x001, "mulh ", mulhs, IIAlu>; def MULHU : Arith<0x10, 0x003, "mulhu ", mulhu, IIAlu>; } let Predicates=[HasMul,HasMul64] in { def MULHSU : ArithN<0x10, 0x002, "mulhsu ", IIAlu>; } let Predicates=[HasBarrel] in { def BSRL : Arith<0x11, 0x000, "bsrl ", srl, IIAlu>; def BSRA : Arith<0x11, 0x200, "bsra ", sra, IIAlu>; def BSLL : Arith<0x11, 0x400, "bsll ", shl, IIAlu>; def BSRLI : ArithI<0x11, "bsrli ", srl, uimm5, immZExt5>; def BSRAI : ArithI<0x11, "bsrai ", sra, uimm5, immZExt5>; def BSLLI : ArithI<0x11, "bslli ", shl, uimm5, immZExt5>; } let Predicates=[HasDiv] in { def IDIV : Arith<0x12, 0x000, "idiv ", sdiv, IIAlu>; def IDIVU : Arith<0x12, 0x002, "idivu ", udiv, IIAlu>; } //===----------------------------------------------------------------------===// // MBlaze immediate mode arithmetic instructions //===----------------------------------------------------------------------===// let isAsCheapAsAMove = 1 in { def ADDI : ArithI<0x08, "addi ", add, simm16, immSExt16>; def ADDIC : ArithNI<0x0A, "addic ", simm16, immSExt16>; def ADDIK : ArithNI<0x0C, "addik ", simm16, immSExt16>; def ADDIKC : ArithI<0x0E, "addikc ", addc, simm16, immSExt16>; def RSUBI : ArithRI<0x09, "rsubi ", sub, simm16, immSExt16>; def RSUBIC : ArithRNI<0x0B, "rsubi ", simm16, immSExt16>; def RSUBIK : ArithRNI<0x0E, "rsubic ", simm16, immSExt16>; def RSUBIKC : ArithRI<0x0F, "rsubikc", subc, simm16, immSExt16>; def ANDNI : ArithNI<0x2B, "andni ", uimm16, immZExt16>; def ANDI : LogicI<0x29, "andi ", and>; def ORI : LogicI<0x28, "ori ", or>; def XORI : LogicI<0x2A, "xori ", xor>; } let Predicates=[HasMul] in { def MULI : ArithI<0x18, "muli ", mul, simm16, immSExt16>; } //===----------------------------------------------------------------------===// // MBlaze memory access instructions //===----------------------------------------------------------------------===// let canFoldAsLoad = 1, isReMaterializable = 1 in { def LBU : LoadM<0x30, "lbu ", zextloadi8>; def LHU : LoadM<0x31, "lhu ", zextloadi16>; def LW : LoadM<0x32, "lw ", load>; def LBUI : LoadMI<0x30, "lbui ", zextloadi8>; def LHUI : LoadMI<0x31, "lhui ", zextloadi16>; def LWI : LoadMI<0x32, "lwi ", load>; } def SB : StoreM<0x34, "sb ", truncstorei8>; def SH : StoreM<0x35, "sh ", truncstorei16>; def SW : StoreM<0x36, "sw ", store>; def SBI : StoreMI<0x34, "sbi ", truncstorei8>; def SHI : StoreMI<0x35, "shi ", truncstorei16>; def SWI : StoreMI<0x36, "swi ", store>; //===----------------------------------------------------------------------===// // MBlaze branch instructions //===----------------------------------------------------------------------===// let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { def BRI : BranchI<0x2E, 0x00, "bri ">; def BRAI : BranchI<0x2E, 0x08, "brai ">; def BEQI : BranchCI<0x2F, 0x00, "beqi ", seteq>; def BNEI : BranchCI<0x2F, 0x01, "bnei ", setne>; def BLTI : BranchCI<0x2F, 0x02, "blti ", setlt>; def BLEI : BranchCI<0x2F, 0x03, "blei ", setle>; def BGTI : BranchCI<0x2F, 0x04, "bgti ", setgt>; def BGEI : BranchCI<0x2F, 0x05, "bgei ", setge>; } let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { def BR : Branch<0x26, 0x00, 0x000, "br ">; def BRA : Branch<0x26, 0x08, 0x000, "bra ">; def BEQ : BranchC<0x27, 0x00, 0x000, "beq ", seteq>; def BNE : BranchC<0x27, 0x01, 0x000, "bne ", setne>; def BLT : BranchC<0x27, 0x02, 0x000, "blt ", setlt>; def BLE : BranchC<0x27, 0x03, 0x000, "ble ", setle>; def BGT : BranchC<0x27, 0x04, 0x000, "bgt ", setgt>; def BGE : BranchC<0x27, 0x05, 0x000, "bge ", setge>; } let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1 in { def BRID : BranchI<0x2E, 0x10, "brid ">; def BRAID : BranchI<0x2E, 0x18, "braid ">; def BEQID : BranchCI<0x2F, 0x10, "beqid ", seteq>; def BNEID : BranchCI<0x2F, 0x11, "bneid ", setne>; def BLTID : BranchCI<0x2F, 0x12, "bltid ", setlt>; def BLEID : BranchCI<0x2F, 0x13, "bleid ", setle>; def BGTID : BranchCI<0x2F, 0x14, "bgtid ", setgt>; def BGEID : BranchCI<0x2F, 0x15, "bgeid ", setge>; } let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1 in { def BRD : Branch<0x26, 0x10, 0x000, "brd ">; def BRAD : Branch<0x26, 0x18, 0x000, "brad ">; def BEQD : BranchC<0x27, 0x10, 0x000, "beqd ", seteq>; def BNED : BranchC<0x27, 0x11, 0x000, "bned ", setne>; def BLTD : BranchC<0x27, 0x12, 0x000, "bltd ", setlt>; def BLED : BranchC<0x27, 0x13, 0x000, "bled ", setle>; def BGTD : BranchC<0x27, 0x14, 0x000, "bgtd ", setgt>; def BGED : BranchC<0x27, 0x15, 0x000, "bged ", setge>; } let isCall = 1, hasCtrlDep = 1, isIndirectBranch = 1, Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], Uses = [R1,R5,R6,R7,R8,R9,R10] in { def BRL : BranchL<0x26, 0x04, 0x000, "brl ">; def BRAL : BranchL<0x26, 0x0C, 0x000, "bral ">; } let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], Uses = [R1,R5,R6,R7,R8,R9,R10] in { def BRLID : BranchLI<0x2E, 0x14, "brlid ">; def BRALID : BranchLI<0x2E, 0x1C, "bralid ">; } let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1, Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], Uses = [R1,R5,R6,R7,R8,R9,R10] in { def BRLD : BranchL<0x26, 0x14, 0x000, "brld ">; def BRALD : BranchL<0x26, 0x1C, 0x000, "brald ">; } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, imm16=0x8 in { def RTSD : TRET<0x2D, (outs), (ins CPURegs:$target), "rtsd $target, 8", [(MBlazeRet CPURegs:$target)], IIBranch>; } //===----------------------------------------------------------------------===// // MBlaze misc instructions //===----------------------------------------------------------------------===// let addr = 0 in { def NOP : TADDR<0x00, (outs), (ins), "nop ", [], IIAlu>; } let usesCustomInserter = 1 in { //class PseudoSelCC: // MBlazePseudo<(outs RC:$D), (ins RC:$T, RC:$F, CPURegs:$CMP), asmstr, // [(set RC:$D, (MBlazeSelectCC RC:$T, RC:$F, CPURegs:$CMP))]>; //def Select_CC : PseudoSelCC; def Select_CC : MBlazePseudo<(outs CPURegs:$dst), (ins CPURegs:$T, CPURegs:$F, CPURegs:$CMP, i32imm:$CC), "; SELECT_CC PSEUDO!", []>; def ShiftL : MBlazePseudo<(outs CPURegs:$dst), (ins CPURegs:$L, CPURegs:$R), "; ShiftL PSEUDO!", []>; def ShiftRA : MBlazePseudo<(outs CPURegs:$dst), (ins CPURegs:$L, CPURegs:$R), "; ShiftRA PSEUDO!", []>; def ShiftRL : MBlazePseudo<(outs CPURegs:$dst), (ins CPURegs:$L, CPURegs:$R), "; ShiftRL PSEUDO!", []>; } let rb = 0 in { def SEXT16 : TA<0x24, 0x061, (outs CPURegs:$dst), (ins CPURegs:$src), "sext16 $dst, $src", [], IIAlu>; def SEXT8 : TA<0x24, 0x060, (outs CPURegs:$dst), (ins CPURegs:$src), "sext8 $dst, $src", [], IIAlu>; def SRL : TA<0x24, 0x041, (outs CPURegs:$dst), (ins CPURegs:$src), "srl $dst, $src", [], IIAlu>; def SRA : TA<0x24, 0x001, (outs CPURegs:$dst), (ins CPURegs:$src), "sra $dst, $src", [], IIAlu>; def SRC : TA<0x24, 0x021, (outs CPURegs:$dst), (ins CPURegs:$src), "src $dst, $src", [], IIAlu>; } def LEA_ADDI : EffectiveAddress<"addi $dst, ${addr:stackloc}">; //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// // Small immediates def : Pat<(i32 0), (ADD R0, R0)>; def : Pat<(i32 immSExt16:$imm), (ADDI R0, imm:$imm)>; def : Pat<(i32 immZExt16:$imm), (ORI R0, imm:$imm)>; // Arbitrary immediates def : Pat<(i32 imm:$imm), (ADDI R0, imm:$imm)>; // In register sign extension def : Pat<(sext_inreg CPURegs:$src, i16), (SEXT16 CPURegs:$src)>; def : Pat<(sext_inreg CPURegs:$src, i8), (SEXT8 CPURegs:$src)>; // Call def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)), (BRLID tglobaladdr:$dst)>; def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),(BRLID texternalsym:$dst)>; def : Pat<(MBlazeJmpLink CPURegs:$dst), (BRLD CPURegs:$dst)>; // Shift Instructions def : Pat<(shl CPURegs:$L, CPURegs:$R), (ShiftL CPURegs:$L, CPURegs:$R)>; def : Pat<(sra CPURegs:$L, CPURegs:$R), (ShiftRA CPURegs:$L, CPURegs:$R)>; def : Pat<(srl CPURegs:$L, CPURegs:$R), (ShiftRL CPURegs:$L, CPURegs:$R)>; // SET_CC operations def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETEQ), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMP CPURegs:$L, CPURegs:$R), 1)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETNE), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMP CPURegs:$L, CPURegs:$R), 2)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETGT), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMP CPURegs:$L, CPURegs:$R), 3)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETLT), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMP CPURegs:$L, CPURegs:$R), 4)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETGE), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMP CPURegs:$L, CPURegs:$R), 5)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETLE), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMP CPURegs:$L, CPURegs:$R), 6)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETUGT), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMPU CPURegs:$L, CPURegs:$R), 3)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETULT), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMPU CPURegs:$L, CPURegs:$R), 4)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETUGE), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMPU CPURegs:$L, CPURegs:$R), 5)>; def : Pat<(setcc CPURegs:$L, CPURegs:$R, SETULE), (Select_CC (ADDI R0, 1), (ADDI R0, 0), (CMPU CPURegs:$L, CPURegs:$R), 6)>; // SELECT operations def : Pat<(select CPURegs:$C, CPURegs:$T, CPURegs:$F), (Select_CC CPURegs:$T, CPURegs:$F, CPURegs:$C, 2)>; // SELECT_CC def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETEQ), (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 1)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETNE), (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 2)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETGT), (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 3)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETLT), (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 4)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETGE), (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 5)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETLE), (Select_CC CPURegs:$T, CPURegs:$F, (CMP CPURegs:$L, CPURegs:$R), 6)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETUGT), (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 3)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETULT), (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 4)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETUGE), (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 5)>; def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETULE), (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 6)>; // BRCOND instructions def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETEQ), bb:$T), (BEQID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETNE), bb:$T), (BNEID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETGT), bb:$T), (BGTID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETLT), bb:$T), (BLTID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETGE), bb:$T), (BGEID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETLE), bb:$T), (BLEID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETUGT), bb:$T), (BGTID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETULT), bb:$T), (BLTID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETUGE), bb:$T), (BGEID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETULE), bb:$T), (BLEID (CMPU CPURegs:$R, CPURegs:$L), bb:$T)>; def : Pat<(brcond CPURegs:$C, bb:$T), (BNEID CPURegs:$C, bb:$T)>; // Jump tables, global addresses, and constant pools def : Pat<(MBWrapper tglobaladdr:$in), (ORI R0, tglobaladdr:$in)>; def : Pat<(MBWrapper tjumptable:$in), (ORI R0, tjumptable:$in)>; def : Pat<(MBWrapper tconstpool:$in), (ORI R0, tconstpool:$in)>; // Misc instructions def : Pat<(and CPURegs:$lh, (not CPURegs:$rh)),(ANDN CPURegs:$lh, CPURegs:$rh)>; // Arithmetic with immediates def : Pat<(add CPURegs:$in, imm:$imm),(ADDI CPURegs:$in, imm:$imm)>; def : Pat<(or CPURegs:$in, imm:$imm),(ORI CPURegs:$in, imm:$imm)>; def : Pat<(xor CPURegs:$in, imm:$imm),(XORI CPURegs:$in, imm:$imm)>; // extended load and stores def : Pat<(extloadi1 iaddr:$src), (LBUI iaddr:$src)>; def : Pat<(extloadi8 iaddr:$src), (LBUI iaddr:$src)>; def : Pat<(extloadi16 iaddr:$src), (LHUI iaddr:$src)>; def : Pat<(extloadi1 xaddr:$src), (LBU xaddr:$src)>; def : Pat<(extloadi8 xaddr:$src), (LBU xaddr:$src)>; def : Pat<(extloadi16 xaddr:$src), (LHU xaddr:$src)>; def : Pat<(sextloadi1 iaddr:$src), (SEXT8 (LBUI iaddr:$src))>; def : Pat<(sextloadi8 iaddr:$src), (SEXT8 (LBUI iaddr:$src))>; def : Pat<(sextloadi16 iaddr:$src), (SEXT16 (LHUI iaddr:$src))>; def : Pat<(sextloadi1 xaddr:$src), (SEXT8 (LBU xaddr:$src))>; def : Pat<(sextloadi8 xaddr:$src), (SEXT8 (LBU xaddr:$src))>; def : Pat<(sextloadi16 xaddr:$src), (SEXT16 (LHU xaddr:$src))>; // peepholes def : Pat<(store (i32 0), iaddr:$dst), (SWI R0, iaddr:$dst)>; //===----------------------------------------------------------------------===// // Floating Point Support //===----------------------------------------------------------------------===// include "MBlazeInstrFSL.td" include "MBlazeInstrFPU.td"