diff options
Diffstat (limited to 'lib/Target/MBlaze/MBlazeInstrInfo.td')
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrInfo.td | 927 |
1 files changed, 568 insertions, 359 deletions
diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index e5d1534..7b8f70a 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -13,35 +13,36 @@ include "MBlazeInstrFormats.td" //===----------------------------------------------------------------------===// -// MBlaze profiles and nodes +// MBlaze type profiles //===----------------------------------------------------------------------===// + +// def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>; def SDT_MBlazeRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; -def SDT_MBlazeJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; +def SDT_MBlazeIRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; +def SDT_MBlazeJmpLink : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; +def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; +def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; -// Call -def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink, - [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag]>; +//===----------------------------------------------------------------------===// +// MBlaze specific nodes +//===----------------------------------------------------------------------===// -// Return -def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet, - [SDNPHasChain, SDNPOptInFlag]>; +def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet, + [SDNPHasChain, SDNPOptInGlue]>; +def MBlazeIRet : SDNode<"MBlazeISD::IRet", SDT_MBlazeIRet, + [SDNPHasChain, SDNPOptInGlue]>; -// 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 MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink, + [SDNPHasChain,SDNPOptInGlue,SDNPOutGlue, + SDNPVariadic]>; -def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; -def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; +def MBWrapper : SDNode<"MBlazeISD::Wrap", SDTIntUnaryOp>; -// 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]>; + [SDNPHasChain, SDNPOutGlue]>; -def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>; +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MBCallSeqEnd, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; //===----------------------------------------------------------------------===// // MBlaze Instruction Predicate Definitions. @@ -67,11 +68,22 @@ def HasMMU : Predicate<"Subtarget.hasMMU()">; // MBlaze Operand, Complex Patterns and Transformations Definitions. //===----------------------------------------------------------------------===// +def MBlazeMemAsmOperand : AsmOperandClass { + let Name = "Mem"; + let SuperClasses = []; +} + +def MBlazeFslAsmOperand : AsmOperandClass { + let Name = "Fsl"; + let SuperClasses = []; +} + // Instruction operand types def brtarget : Operand<OtherVT>; def calltarget : Operand<i32>; def simm16 : Operand<i32>; def uimm5 : Operand<i32>; +def uimm15 : Operand<i32>; def fimm : Operand<f32>; // Unsigned Operand @@ -82,31 +94,23 @@ def uimm16 : Operand<i32> { // FSL Operand def fslimm : Operand<i32> { let PrintMethod = "printFSLImm"; + let ParserMatchClass = MBlazeFslAsmOperand; } // Address operand def memri : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops simm16, CPURegs); + let MIOperandInfo = (ops GPR, simm16); + let ParserMatchClass = MBlazeMemAsmOperand; } def memrr : Operand<i32> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops CPURegs, CPURegs); + let MIOperandInfo = (ops GPR, GPR); + let ParserMatchClass = MBlazeMemAsmOperand; } -// Transformation Function - get the lower 16 bits. -def LO16 : SDNodeXForm<imm, [{ - return getI32Imm((unsigned)N->getZExtValue() & 0xFFFF); -}]>; - -// Transformation Function - get the higher 16 bits. -def HI16 : SDNodeXForm<imm, [{ - return getI32Imm((unsigned)N->getZExtValue() >> 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; }]>; @@ -117,19 +121,19 @@ def immSExt16 : PatLeaf<(imm), [{ // 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) ; + return N->getZExtValue() == ((N->getZExtValue()) & 0xf) ; }]>; // shamt field must fit in 5 bits. def immZExt5 : PatLeaf<(imm), [{ - return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ; + return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ; }]>; -// MBlaze Address Mode! SDNode frameindex could possibily be a match +// MBlaze Address Mode. SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def iaddr : ComplexPattern<i32, 2, "SelectAddrRegImm", [frameindex], []>; def xaddr : ComplexPattern<i32, 2, "SelectAddrRegReg", [], []>; @@ -141,28 +145,14 @@ def xaddr : ComplexPattern<i32, 2, "SelectAddrRegReg", [], []>; // 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", + "#ADJCALLSTACKDOWN $amt", [(callseq_start timm:$amt)]>; def ADJCALLSTACKUP : MBlazePseudo<(outs), (ins uimm16:$amt1, simm16:$amt2), - "${:comment} ADJCALLSTACKUP $amt1", + "#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 //===----------------------------------------------------------------------===// @@ -172,47 +162,58 @@ def CPRESTORE : MBlazePseudo<(outs), (ins uimm16:$l), ".cprestore $l\n", []>; //===----------------------------------------------------------------------===// class Arith<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode, InstrItinClass itin> : - TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c), + TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c), !strconcat(instr_asm, " $dst, $b, $c"), - [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>; + [(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], itin>; class ArithI<bits<6> op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type> : - TAI<op, (outs CPURegs:$dst), (ins CPURegs:$b, Od:$c), + TB<op, (outs GPR:$dst), (ins GPR:$b, Od:$c), + !strconcat(instr_asm, " $dst, $b, $c"), + [(set GPR:$dst, (OpNode GPR:$b, imm_type:$c))], IIAlu>; + +class ArithI32<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> : + TB<op, (outs GPR:$dst), (ins GPR:$b, Od:$c), + !strconcat(instr_asm, " $dst, $b, $c"), + [], IIAlu>; + +class ShiftI<bits<6> op, bits<2> flags, string instr_asm, SDNode OpNode, + Operand Od, PatLeaf imm_type> : + SHT<op, flags, (outs GPR:$dst), (ins GPR:$b, Od:$c), !strconcat(instr_asm, " $dst, $b, $c"), - [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>; + [(set GPR:$dst, (OpNode GPR:$b, imm_type:$c))], IIAlu>; class ArithR<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode, InstrItinClass itin> : - TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$c, CPURegs:$b), - !strconcat(instr_asm, " $dst, $c, $b"), - [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>; + TAR<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c), + !strconcat(instr_asm, " $dst, $c, $b"), + [(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], itin>; class ArithRI<bits<6> op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type> : - TAI<op, (outs CPURegs:$dst), (ins Od:$b, CPURegs:$c), + TBR<op, (outs GPR:$dst), (ins Od:$b, GPR:$c), !strconcat(instr_asm, " $dst, $c, $b"), - [(set CPURegs:$dst, (OpNode imm_type:$b, CPURegs:$c))], IIAlu>; + [(set GPR:$dst, (OpNode imm_type:$b, GPR:$c))], IIAlu>; class ArithN<bits<6> op, bits<11> flags, string instr_asm, InstrItinClass itin> : - TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c), + TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c), !strconcat(instr_asm, " $dst, $b, $c"), [], itin>; class ArithNI<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> : - TAI<op, (outs CPURegs:$dst), (ins CPURegs:$b, Od:$c), - !strconcat(instr_asm, " $dst, $b, $c"), - [], IIAlu>; + TB<op, (outs GPR:$dst), (ins GPR:$b, Od:$c), + !strconcat(instr_asm, " $dst, $b, $c"), + [], IIAlu>; class ArithRN<bits<6> op, bits<11> flags, string instr_asm, InstrItinClass itin> : - TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$c, CPURegs:$b), - !strconcat(instr_asm, " $dst, $b, $c"), - [], itin>; + TAR<op, flags, (outs GPR:$dst), (ins GPR:$c, GPR:$b), + !strconcat(instr_asm, " $dst, $b, $c"), + [], itin>; class ArithRNI<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> : - TAI<op, (outs CPURegs:$dst), (ins Od:$c, CPURegs:$b), + TBR<op, (outs GPR:$dst), (ins Od:$c, GPR:$b), !strconcat(instr_asm, " $dst, $b, $c"), [], IIAlu>; @@ -221,135 +222,179 @@ class ArithRNI<bits<6> op, string instr_asm,Operand Od, PatLeaf imm_type> : //===----------------------------------------------------------------------===// class Logic<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode> : - TA<op, flags, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c), + TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c), !strconcat(instr_asm, " $dst, $b, $c"), - [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>; + [(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], IIAlu>; class LogicI<bits<6> op, string instr_asm, SDNode OpNode> : - TAI<op, (outs CPURegs:$dst), (ins CPURegs:$b, uimm16:$c), - !strconcat(instr_asm, " $dst, $b, $c"), - [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt16:$c))], - IIAlu>; - -class EffectiveAddress<string instr_asm> : - TAI<0x08, (outs CPURegs:$dst), (ins memri:$addr), - instr_asm, [(set CPURegs:$dst, iaddr:$addr)], IIAlu>; + TB<op, (outs GPR:$dst), (ins GPR:$b, uimm16:$c), + !strconcat(instr_asm, " $dst, $b, $c"), + [(set GPR:$dst, (OpNode GPR:$b, immZExt16:$c))], + IIAlu>; + +class LogicI32<bits<6> op, string instr_asm> : + TB<op, (outs GPR:$dst), (ins GPR:$b, uimm16:$c), + !strconcat(instr_asm, " $dst, $b, $c"), + [], IIAlu>; + +class PatCmp<bits<6> op, bits<11> flags, string instr_asm> : + TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c), + !strconcat(instr_asm, " $dst, $b, $c"), + [], IIAlu>; //===----------------------------------------------------------------------===// // Memory Access Instructions //===----------------------------------------------------------------------===// -class LoadM<bits<6> op, string instr_asm, PatFrag OpNode> : - TA<op, 0x000, (outs CPURegs:$dst), (ins memrr:$addr), +class LoadM<bits<6> op, bits<11> flags, string instr_asm> : + TA<op, flags, (outs GPR:$dst), (ins memrr:$addr), !strconcat(instr_asm, " $dst, $addr"), - [(set CPURegs:$dst, (OpNode xaddr:$addr))], IILoad>; + [], IILoad>; class LoadMI<bits<6> op, string instr_asm, PatFrag OpNode> : - TAI<op, (outs CPURegs:$dst), (ins memri:$addr), - !strconcat(instr_asm, " $dst, $addr"), - [(set CPURegs:$dst, (OpNode iaddr:$addr))], IILoad>; + TB<op, (outs GPR:$dst), (ins memri:$addr), + !strconcat(instr_asm, " $dst, $addr"), + [(set (i32 GPR:$dst), (OpNode iaddr:$addr))], IILoad>; -class StoreM<bits<6> op, string instr_asm, PatFrag OpNode> : - TA<op, 0x000, (outs), (ins CPURegs:$dst, memrr:$addr), +class StoreM<bits<6> op, bits<11> flags, string instr_asm> : + TA<op, flags, (outs), (ins GPR:$dst, memrr:$addr), !strconcat(instr_asm, " $dst, $addr"), - [(OpNode CPURegs:$dst, xaddr:$addr)], IIStore>; + [], IIStore>; class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> : - TAI<op, (outs), (ins CPURegs:$dst, memri:$addr), - !strconcat(instr_asm, " $dst, $addr"), - [(OpNode CPURegs:$dst, iaddr:$addr)], IIStore>; + TB<op, (outs), (ins GPR:$dst, memri:$addr), + !strconcat(instr_asm, " $dst, $addr"), + [(OpNode (i32 GPR:$dst), iaddr:$addr)], IIStore>; //===----------------------------------------------------------------------===// // Branch Instructions //===----------------------------------------------------------------------===// class Branch<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> : - TBR<op, br, flags, (outs), (ins CPURegs:$target), - !strconcat(instr_asm, " $target"), - [(brind CPURegs:$target)], IIBranch>; + TA<op, flags, (outs), (ins GPR:$target), + !strconcat(instr_asm, " $target"), + [], IIBranch> { + let rd = 0x0; + let ra = br; + let Form = FCCR; +} -class BranchI<bits<6> op, bits<5> brf, string instr_asm> : - TBRI<op, brf, (outs), (ins brtarget:$target), - !strconcat(instr_asm, " $target"), - [(br bb:$target)], IIBranch>; +class BranchI<bits<6> op, bits<5> br, string instr_asm> : + TB<op, (outs), (ins brtarget:$target), + !strconcat(instr_asm, " $target"), + [], IIBranch> { + let rd = 0; + let ra = br; + let Form = FCCI; +} //===----------------------------------------------------------------------===// // Branch and Link Instructions //===----------------------------------------------------------------------===// class BranchL<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> : - TBRL<op, br, flags, (outs), (ins CPURegs:$target), - !strconcat(instr_asm, " r15, $target"), - [], IIBranch>; + TA<op, flags, (outs), (ins GPR:$link, GPR:$target, variable_ops), + !strconcat(instr_asm, " $link, $target"), + [], IIBranch> { + let ra = br; + let Form = FRCR; +} class BranchLI<bits<6> op, bits<5> br, string instr_asm> : - TBRLI<op, br, (outs), (ins calltarget:$target), - !strconcat(instr_asm, " r15, $target"), - [], IIBranch>; + TB<op, (outs), (ins GPR:$link, calltarget:$target, variable_ops), + !strconcat(instr_asm, " $link, $target"), + [], IIBranch> { + let ra = br; + let Form = FRCI; +} //===----------------------------------------------------------------------===// // Conditional Branch Instructions //===----------------------------------------------------------------------===// -class BranchC<bits<6> op, bits<5> br, bits<11> flags, string instr_asm, - PatFrag cond_op> : - TBRC<op, br, flags, (outs), - (ins CPURegs:$a, CPURegs:$b, brtarget:$offset), - !strconcat(instr_asm, " $a, $b, $offset"), - [], IIBranch>; - //(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)], - //IIBranch>; +class BranchC<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> : + TA<op, flags, (outs), + (ins GPR:$a, GPR:$b), + !strconcat(instr_asm, " $a, $b"), + [], IIBranch> { + let rd = br; + let Form = FCRR; +} -class BranchCI<bits<6> op, bits<5> br, string instr_asm, PatFrag cond_op> : - TBRCI<op, br, (outs), (ins CPURegs:$a, brtarget:$offset), - !strconcat(instr_asm, " $a, $offset"), - [], IIBranch>; +class BranchCI<bits<6> op, bits<5> br, string instr_asm> : + TB<op, (outs), (ins GPR:$a, brtarget:$offset), + !strconcat(instr_asm, " $a, $offset"), + [], IIBranch> { + let rd = br; + let Form = FCRI; +} //===----------------------------------------------------------------------===// // 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 ADDK : Arith<0x04, 0x000, "addk ", add, IIAlu>; + def AND : Logic<0x21, 0x000, "and ", and>; + def OR : Logic<0x20, 0x000, "or ", or>; + def XOR : Logic<0x22, 0x000, "xor ", xor>; + def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">; + def PCMPEQ : PatCmp<0x22, 0x400, "pcmpeq ">; + def PCMPNE : PatCmp<0x23, 0x400, "pcmpne ">; + + let Defs = [CARRY] in { + def ADD : Arith<0x00, 0x000, "add ", addc, IIAlu>; + + let Uses = [CARRY] in { + def ADDC : Arith<0x02, 0x000, "addc ", adde, IIAlu>; + } + } + + let Uses = [CARRY] in { 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 ANDN : ArithN<0x23, 0x000, "andn ", IIAlu>; + def CMP : ArithN<0x05, 0x001, "cmp ", IIAlu>; + def CMPU : ArithN<0x05, 0x003, "cmpu ", IIAlu>; + def RSUBK : ArithR<0x05, 0x000, "rsubk ", sub, IIAlu>; + + let Defs = [CARRY] in { + def RSUB : ArithR<0x01, 0x000, "rsub ", subc, IIAlu>; + + let Uses = [CARRY] in { + def RSUBC : ArithR<0x03, 0x000, "rsubc ", sube, IIAlu>; + } + } + + let Uses = [CARRY] in { def RSUBKC : ArithRN<0x07, 0x000, "rsubkc ", IIAlu>; + } } let isCommutable = 1, Predicates=[HasMul] in { - def MUL : Arith<0x10, 0x000, "mul ", mul, IIAlu>; + 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>; + 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>; + 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>; + 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 : ShiftI<0x19, 0x0, "bsrli ", srl, uimm5, immZExt5>; + def BSRAI : ShiftI<0x19, 0x1, "bsrai ", sra, uimm5, immZExt5>; + def BSLLI : ShiftI<0x19, 0x2, "bslli ", shl, uimm5, immZExt5>; } let Predicates=[HasDiv] in { - def IDIV : Arith<0x12, 0x000, "idiv ", sdiv, IIAlu>; - def IDIVU : Arith<0x12, 0x002, "idivu ", udiv, IIAlu>; + def IDIV : ArithR<0x12, 0x000, "idiv ", sdiv, IIAlu>; + def IDIVU : ArithR<0x12, 0x002, "idivu ", udiv, IIAlu>; } //===----------------------------------------------------------------------===// @@ -357,22 +402,31 @@ let Predicates=[HasDiv] in { //===----------------------------------------------------------------------===// 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>; + def ADDIK : ArithI<0x0C, "addik ", add, simm16, immSExt16>; + def RSUBIK : ArithRI<0x0D, "rsubik ", sub, 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 Defs = [CARRY] in { + def ADDI : ArithI<0x08, "addi ", addc, simm16, immSExt16>; + def RSUBI : ArithRI<0x09, "rsubi ", subc, simm16, immSExt16>; + + let Uses = [CARRY] in { + def ADDIC : ArithI<0x0A, "addic ", adde, simm16, immSExt16>; + def RSUBIC : ArithRI<0x0B, "rsubic ", sube, simm16, immSExt16>; + } + } + + let Uses = [CARRY] in { + def ADDIKC : ArithNI<0x0E, "addikc ", simm16, immSExt16>; + def RSUBIKC : ArithRNI<0x0F, "rsubikc", simm16, immSExt16>; + } } let Predicates=[HasMul] in { - def MULI : ArithI<0x18, "muli ", mul, simm16, immSExt16>; + def MULI : ArithI<0x18, "muli ", mul, simm16, immSExt16>; } //===----------------------------------------------------------------------===// @@ -380,290 +434,445 @@ let Predicates=[HasMul] in { //===----------------------------------------------------------------------===// 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 LBU : LoadM<0x30, 0x000, "lbu ">; + def LBUR : LoadM<0x30, 0x200, "lbur ">; + + def LHU : LoadM<0x31, 0x000, "lhu ">; + def LHUR : LoadM<0x31, 0x200, "lhur ">; + + def LW : LoadM<0x32, 0x000, "lw ">; + def LWR : LoadM<0x32, 0x200, "lwr ">; - def LBUI : LoadMI<0x30, "lbui ", zextloadi8>; - def LHUI : LoadMI<0x31, "lhui ", zextloadi16>; - def LWI : LoadMI<0x32, "lwi ", load>; + let Defs = [CARRY] in { + def LWX : LoadM<0x32, 0x400, "lwx ">; + } + + def LBUI : LoadMI<0x38, "lbui ", zextloadi8>; + def LHUI : LoadMI<0x39, "lhui ", zextloadi16>; + def LWI : LoadMI<0x3A, "lwi ", load>; } - def SB : StoreM<0x34, "sb ", truncstorei8>; - def SH : StoreM<0x35, "sh ", truncstorei16>; - def SW : StoreM<0x36, "sw ", store>; +def SB : StoreM<0x34, 0x000, "sb ">; +def SBR : StoreM<0x34, 0x200, "sbr ">; + +def SH : StoreM<0x35, 0x000, "sh ">; +def SHR : StoreM<0x35, 0x200, "shr ">; + +def SW : StoreM<0x36, 0x000, "sw ">; +def SWR : StoreM<0x36, 0x200, "swr ">; - def SBI : StoreMI<0x34, "sbi ", truncstorei8>; - def SHI : StoreMI<0x35, "shi ", truncstorei16>; - def SWI : StoreMI<0x36, "swi ", store>; +let Defs = [CARRY] in { + def SWX : StoreM<0x36, 0x400, "swx ">; +} + +def SBI : StoreMI<0x3C, "sbi ", truncstorei8>; +def SHI : StoreMI<0x3D, "shi ", truncstorei16>; +def SWI : StoreMI<0x3E, "swi ", store>; //===----------------------------------------------------------------------===// // MBlaze branch instructions //===----------------------------------------------------------------------===// +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { + def BRI : BranchI<0x2E, 0x00, "bri ">; + def BRAI : BranchI<0x2E, 0x08, "brai ">; +} + 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>; + def BEQI : BranchCI<0x2F, 0x00, "beqi ">; + def BNEI : BranchCI<0x2F, 0x01, "bnei ">; + def BLTI : BranchCI<0x2F, 0x02, "blti ">; + def BLEI : BranchCI<0x2F, 0x03, "blei ">; + def BGTI : BranchCI<0x2F, 0x04, "bgti ">; + def BGEI : BranchCI<0x2F, 0x05, "bgei ">; +} + +let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1, + isBarrier = 1 in { + def BR : Branch<0x26, 0x00, 0x000, "br ">; + def BRA : Branch<0x26, 0x08, 0x000, "bra ">; } 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>; + def BEQ : BranchC<0x27, 0x00, 0x000, "beq ">; + def BNE : BranchC<0x27, 0x01, 0x000, "bne ">; + def BLT : BranchC<0x27, 0x02, 0x000, "blt ">; + def BLE : BranchC<0x27, 0x03, 0x000, "ble ">; + def BGT : BranchC<0x27, 0x04, 0x000, "bgt ">; + def BGE : BranchC<0x27, 0x05, 0x000, "bge ">; +} + +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1, + isBarrier = 1 in { + def BRID : BranchI<0x2E, 0x10, "brid ">; + def BRAID : BranchI<0x2E, 0x18, "braid ">; } 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>; + def BEQID : BranchCI<0x2F, 0x10, "beqid ">; + def BNEID : BranchCI<0x2F, 0x11, "bneid ">; + def BLTID : BranchCI<0x2F, 0x12, "bltid ">; + def BLEID : BranchCI<0x2F, 0x13, "bleid ">; + def BGTID : BranchCI<0x2F, 0x14, "bgtid ">; + def BGEID : BranchCI<0x2F, 0x15, "bgeid ">; +} + +let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, + hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1 in { + def BRD : Branch<0x26, 0x10, 0x000, "brd ">; + def BRAD : Branch<0x26, 0x18, 0x000, "brad ">; } 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>; + def BEQD : BranchC<0x27, 0x10, 0x000, "beqd ">; + def BNED : BranchC<0x27, 0x11, 0x000, "bned ">; + def BLTD : BranchC<0x27, 0x12, 0x000, "bltd ">; + def BLED : BranchC<0x27, 0x13, 0x000, "bled ">; + def BGTD : BranchC<0x27, 0x14, 0x000, "bgtd ">; + def BGED : BranchC<0x27, 0x15, 0x000, "bged ">; +} + +let isCall =1, hasDelaySlot = 1, + Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,CARRY], + Uses = [R1] in { + def BRLID : BranchLI<0x2E, 0x14, "brlid ">; + def BRALID : BranchLI<0x2E, 0x1C, "bralid ">; +} + +let isCall = 1, hasDelaySlot = 1, + Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,CARRY], + Uses = [R1] in { + def BRLD : BranchL<0x26, 0x14, 0x000, "brld ">; + def BRALD : BranchL<0x26, 0x1C, 0x000, "brald ">; } -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 isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, + rd=0x10, Form=FCRI in { + def RTSD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rtsd $target, $imm", + [], + IIBranch>; } -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 isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, + rd=0x11, Form=FCRI in { + def RTID : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rtid $target, $imm", + [], + IIBranch>; } -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, + rd=0x12, Form=FCRI in { + def RTBD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rtbd $target, $imm", + [], + IIBranch>; } -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>; +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, + rd=0x14, Form=FCRI in { + def RTED : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rted $target, $imm", + [], + IIBranch>; } //===----------------------------------------------------------------------===// // MBlaze misc instructions //===----------------------------------------------------------------------===// -let addr = 0 in { - def NOP : TADDR<0x00, (outs), (ins), "nop ", [], IIAlu>; +let neverHasSideEffects = 1 in { + def NOP : MBlazeInst< 0x20, FC, (outs), (ins), "nop ", [], IIAlu>; } let usesCustomInserter = 1 in { - //class PseudoSelCC<RegisterClass RC, string asmstr>: - // 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<CPURegs, "# MBlazeSelect_CC">; - - def Select_CC : MBlazePseudo<(outs CPURegs:$dst), - (ins CPURegs:$T, CPURegs:$F, CPURegs:$CMP, i32imm:$CC), + def Select_CC : MBlazePseudo<(outs GPR:$dst), + (ins GPR:$T, GPR:$F, GPR:$CMP, i32imm:$CC), // F T reversed "; SELECT_CC PSEUDO!", []>; - def ShiftL : MBlazePseudo<(outs CPURegs:$dst), - (ins CPURegs:$L, CPURegs:$R), + def ShiftL : MBlazePseudo<(outs GPR:$dst), + (ins GPR:$L, GPR:$R), "; ShiftL PSEUDO!", []>; - def ShiftRA : MBlazePseudo<(outs CPURegs:$dst), - (ins CPURegs:$L, CPURegs:$R), + def ShiftRA : MBlazePseudo<(outs GPR:$dst), + (ins GPR:$L, GPR:$R), "; ShiftRA PSEUDO!", []>; - def ShiftRL : MBlazePseudo<(outs CPURegs:$dst), - (ins CPURegs:$L, CPURegs:$R), + def ShiftRL : MBlazePseudo<(outs GPR:$dst), + (ins GPR:$L, GPR:$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 SEXT16 : TA<0x24, 0x061, (outs GPR:$dst), (ins GPR:$src), + "sext16 $dst, $src", [], IIAlu>; + def SEXT8 : TA<0x24, 0x060, (outs GPR:$dst), (ins GPR:$src), + "sext8 $dst, $src", [], IIAlu>; + let Defs = [CARRY] in { + def SRL : TA<0x24, 0x041, (outs GPR:$dst), (ins GPR:$src), + "srl $dst, $src", [], IIAlu>; + def SRA : TA<0x24, 0x001, (outs GPR:$dst), (ins GPR:$src), + "sra $dst, $src", [], IIAlu>; + let Uses = [CARRY] in { + def SRC : TA<0x24, 0x021, (outs GPR:$dst), (ins GPR:$src), + "src $dst, $src", [], IIAlu>; + } + } +} + +let isCodeGenOnly=1 in { + def ADDIK32 : ArithI32<0x08, "addik ", simm16, immSExt16>; + def ORI32 : LogicI32<0x28, "ori ">; + def BRLID32 : BranchLI<0x2E, 0x14, "brlid ">; +} + +//===----------------------------------------------------------------------===// +// Misc. instructions +//===----------------------------------------------------------------------===// +let Form=FRCS in { + def MFS : SPC<0x25, 0x2, (outs GPR:$dst), (ins SPR:$src), + "mfs $dst, $src", [], IIAlu>; +} + +let Form=FCRCS in { + def MTS : SPC<0x25, 0x3, (outs SPR:$dst), (ins GPR:$src), + "mts $dst, $src", [], IIAlu>; +} + +def MSRSET : MSR<0x25, 0x20, (outs GPR:$dst), (ins uimm15:$set), + "msrset $dst, $set", [], IIAlu>; + +def MSRCLR : MSR<0x25, 0x22, (outs GPR:$dst), (ins uimm15:$clr), + "msrclr $dst, $clr", [], IIAlu>; + +let rd=0x0, Form=FCRR in { + def WDC : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b), + "wdc $a, $b", [], IIAlu>; + def WDCF : TA<0x24, 0x74, (outs), (ins GPR:$a, GPR:$b), + "wdc.flush $a, $b", [], IIAlu>; + def WDCC : TA<0x24, 0x66, (outs), (ins GPR:$a, GPR:$b), + "wdc.clear $a, $b", [], IIAlu>; + def WIC : TA<0x24, 0x68, (outs), (ins GPR:$a, GPR:$b), + "wic $a, $b", [], IIAlu>; } -def LEA_ADDI : EffectiveAddress<"addi $dst, ${addr:stackloc}">; +def BRK : BranchL<0x26, 0x0C, 0x000, "brk ">; +def BRKI : BranchLI<0x2E, 0x0C, "brki ">; + +def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm), + "imm $imm", [], IIAlu>; + +//===----------------------------------------------------------------------===// +// Pseudo instructions for atomic operations +//===----------------------------------------------------------------------===// +let usesCustomInserter=1 in { + def CAS32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$cmp, GPR:$swp), + "# atomic compare and swap", + [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$cmp, GPR:$swp))]>; + + def SWP32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$swp), + "# atomic swap", + [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$swp))]>; + + def LAA32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and add", + [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$val))]>; + + def LAS32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and sub", + [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$val))]>; + + def LAD32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and and", + [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$val))]>; + + def LAO32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and or", + [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$val))]>; + + def LAX32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and xor", + [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$val))]>; + + def LAN32 : MBlazePseudo<(outs GPR:$dst), (ins GPR:$ptr, GPR:$val), + "# atomic load and nand", + [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$val))]>; + + def MEMBARRIER : MBlazePseudo<(outs), (ins), + "# memory barrier", + [(membarrier (i32 imm), (i32 imm), (i32 imm), (i32 imm), (i32 imm))]>; +} //===----------------------------------------------------------------------===// // 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)>; +def : Pat<(i32 0), (ADDK (i32 R0), (i32 R0))>; +def : Pat<(i32 immSExt16:$imm), (ADDIK (i32 R0), imm:$imm)>; +def : Pat<(i32 immZExt16:$imm), (ORI (i32 R0), imm:$imm)>; // Arbitrary immediates -def : Pat<(i32 imm:$imm), (ADDI R0, imm:$imm)>; +def : Pat<(i32 imm:$imm), (ADDIK (i32 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)>; +def : Pat<(sext_inreg GPR:$src, i16), (SEXT16 GPR:$src)>; +def : Pat<(sext_inreg GPR:$src, i8), (SEXT8 GPR:$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)>; +def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)), + (BRLID (i32 R15), tglobaladdr:$dst)>; + +def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)), + (BRLID (i32 R15), texternalsym:$dst)>; + +def : Pat<(MBlazeJmpLink GPR:$dst), + (BRALD (i32 R15), GPR:$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)>; +def : Pat<(shl GPR:$L, GPR:$R), (ShiftL GPR:$L, GPR:$R)>; +def : Pat<(sra GPR:$L, GPR:$R), (ShiftRA GPR:$L, GPR:$R)>; +def : Pat<(srl GPR:$L, GPR:$R), (ShiftRL GPR:$L, GPR:$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)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETEQ), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMP GPR:$R, GPR:$L), 1)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETNE), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMP GPR:$R, GPR:$L), 2)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETGT), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMP GPR:$R, GPR:$L), 3)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETLT), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMP GPR:$R, GPR:$L), 4)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETGE), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMP GPR:$R, GPR:$L), 5)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETLE), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMP GPR:$R, GPR:$L), 6)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETUGT), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMPU GPR:$R, GPR:$L), 3)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETULT), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMPU GPR:$R, GPR:$L), 4)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETUGE), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMPU GPR:$R, GPR:$L), 5)>; +def : Pat<(setcc (i32 GPR:$L), (i32 GPR:$R), SETULE), + (Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0), + (CMPU GPR:$R, GPR:$L), 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)>; +def : Pat<(select (i32 GPR:$C), (i32 GPR:$T), (i32 GPR:$F)), + (Select_CC GPR:$T, GPR:$F, GPR:$C, 2)>; + +// SELECT_CC +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETEQ), + (Select_CC GPR:$T, GPR:$F, (CMP GPR:$R, GPR:$L), 1)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETNE), + (Select_CC GPR:$T, GPR:$F, (CMP GPR:$R, GPR:$L), 2)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETGT), + (Select_CC GPR:$T, GPR:$F, (CMP GPR:$R, GPR:$L), 3)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETLT), + (Select_CC GPR:$T, GPR:$F, (CMP GPR:$R, GPR:$L), 4)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETGE), + (Select_CC GPR:$T, GPR:$F, (CMP GPR:$R, GPR:$L), 5)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETLE), + (Select_CC GPR:$T, GPR:$F, (CMP GPR:$R, GPR:$L), 6)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETUGT), + (Select_CC GPR:$T, GPR:$F, (CMPU GPR:$R, GPR:$L), 3)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETULT), + (Select_CC GPR:$T, GPR:$F, (CMPU GPR:$R, GPR:$L), 4)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETUGE), + (Select_CC GPR:$T, GPR:$F, (CMPU GPR:$R, GPR:$L), 5)>; +def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), + (i32 GPR:$T), (i32 GPR:$F), SETULE), + (Select_CC GPR:$T, GPR:$F, (CMPU GPR:$R, GPR:$L), 6)>; + +// Ret instructions +def : Pat<(MBlazeRet GPR:$target), (RTSD GPR:$target, 0x8)>; +def : Pat<(MBlazeIRet GPR:$target), (RTID GPR:$target, 0x0)>; + +// BR instructions +def : Pat<(br bb:$T), (BRID bb:$T)>; +def : Pat<(brind GPR:$T), (BRAD GPR:$T)>; // 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)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETEQ), bb:$T), + (BEQID (CMP GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETNE), bb:$T), + (BNEID (CMP GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETGT), bb:$T), + (BGTID (CMP GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETLT), bb:$T), + (BLTID (CMP GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETGE), bb:$T), + (BGEID (CMP GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETLE), bb:$T), + (BLEID (CMP GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETUGT), bb:$T), + (BGTID (CMPU GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETULT), bb:$T), + (BLTID (CMPU GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETUGE), bb:$T), + (BGEID (CMPU GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (setcc (i32 GPR:$L), (i32 GPR:$R), SETULE), bb:$T), + (BLEID (CMPU GPR:$R, GPR:$L), bb:$T)>; +def : Pat<(brcond (i32 GPR:$C), bb:$T), + (BNEID GPR:$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)>; +def : Pat<(MBWrapper tglobaladdr:$in), (ORI (i32 R0), tglobaladdr:$in)>; +def : Pat<(MBWrapper tjumptable:$in), (ORI (i32 R0), tjumptable:$in)>; +def : Pat<(MBWrapper tconstpool:$in), (ORI (i32 R0), tconstpool:$in)>; // Misc instructions -def : Pat<(and CPURegs:$lh, (not CPURegs:$rh)),(ANDN CPURegs:$lh, CPURegs:$rh)>; +def : Pat<(and (i32 GPR:$lh), (not (i32 GPR:$rh))),(ANDN GPR:$lh, GPR:$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)>; +def : Pat<(add (i32 GPR:$in), imm:$imm),(ADDIK GPR:$in, imm:$imm)>; +def : Pat<(or (i32 GPR:$in), imm:$imm),(ORI GPR:$in, imm:$imm)>; +def : Pat<(xor (i32 GPR:$in), imm:$imm),(XORI GPR:$in, imm:$imm)>; + +// Convert any extend loads into zero extend loads +def : Pat<(extloadi8 iaddr:$src), (i32 (LBUI iaddr:$src))>; +def : Pat<(extloadi16 iaddr:$src), (i32 (LHUI iaddr:$src))>; +def : Pat<(extloadi8 xaddr:$src), (i32 (LBU xaddr:$src))>; +def : Pat<(extloadi16 xaddr:$src), (i32 (LHU xaddr:$src))>; + +// 32-bit load and store +def : Pat<(store (i32 GPR:$dst), xaddr:$addr), (SW GPR:$dst, xaddr:$addr)>; +def : Pat<(load xaddr:$addr), (i32 (LW xaddr:$addr))>; + +// 16-bit load and store +def : Pat<(truncstorei16 (i32 GPR:$dst), xaddr:$addr), (SH GPR:$dst, xaddr:$addr)>; +def : Pat<(zextloadi16 xaddr:$addr), (i32 (LHU xaddr:$addr))>; + +// 8-bit load and store +def : Pat<(truncstorei8 (i32 GPR:$dst), xaddr:$addr), (SB GPR:$dst, xaddr:$addr)>; +def : Pat<(zextloadi8 xaddr:$addr), (i32 (LBU xaddr:$addr))>; + +// Peepholes +def : Pat<(store (i32 0), iaddr:$dst), (SWI (i32 R0), iaddr:$dst)>; //===----------------------------------------------------------------------===// // Floating Point Support |