diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td | 276 |
1 files changed, 223 insertions, 53 deletions
diff --git a/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td b/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td index 521e22f..3dba7ce 100644 --- a/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/contrib/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -326,6 +326,14 @@ let AdditionalPredicates = [NotInMicroMips] in { EXT_FM<5>, ISA_MIPS64R2; } +let isCodeGenOnly = 1, AdditionalPredicates = [NotInMicroMips] in { + def DEXT64_32 : InstSE<(outs GPR64Opnd:$rt), + (ins GPR32Opnd:$rs, uimm5_report_uimm6:$pos, + uimm5_plus1:$size), + "dext $rt, $rs, $pos, $size", [], II_EXT, FrmR, "dext">, + EXT_FM<3>, ISA_MIPS64R2; +} + let isCodeGenOnly = 1, rs = 0, shamt = 0 in { def DSLL64_32 : FR<0x00, 0x3c, (outs GPR64:$rd), (ins GPR32:$rt), "dsll\t$rd, $rt, 32", [], II_DSLL>; @@ -356,11 +364,11 @@ class Count1s<string opstr, RegisterOperand RO>: let TwoOperandAliasConstraint = "$rd = $rs"; } -class ExtsCins<string opstr, InstrItinClass itin, - SDPatternOperator Op = null_frag>: - InstSE<(outs GPR64Opnd:$rt), (ins GPR64Opnd:$rs, uimm5:$pos, uimm5:$lenm1), - !strconcat(opstr, " $rt, $rs, $pos, $lenm1"), - [(set GPR64Opnd:$rt, (Op GPR64Opnd:$rs, imm:$pos, imm:$lenm1))], +class ExtsCins<string opstr, InstrItinClass itin, RegisterOperand RO, + PatFrag PosImm, SDPatternOperator Op = null_frag>: + InstSE<(outs RO:$rt), (ins RO:$rs, uimm5:$pos, uimm5:$lenm1), + !strconcat(opstr, "\t$rt, $rs, $pos, $lenm1"), + [(set RO:$rt, (Op RO:$rs, PosImm:$pos, imm:$lenm1))], itin, FrmR, opstr> { let TwoOperandAliasConstraint = "$rt = $rs"; } @@ -424,13 +432,28 @@ def DMUL : ArithLogicR<"dmul", GPR64Opnd, 1, II_DMUL, mul>, let Defs = [HI0, LO0, P0, P1, P2]; } -// Extract a signed bit field /+32 -def EXTS : ExtsCins<"exts", II_EXT>, EXTS_FM<0x3a>, ASE_CNMIPS; -def EXTS32: ExtsCins<"exts32", II_EXT>, EXTS_FM<0x3b>, ASE_CNMIPS; - -// Clear and insert a bit field /+32 -def CINS : ExtsCins<"cins", II_INS>, EXTS_FM<0x32>, ASE_CNMIPS; -def CINS32: ExtsCins<"cins32", II_INS>, EXTS_FM<0x33>, ASE_CNMIPS; +let AdditionalPredicates = [NotInMicroMips] in { + // Extract a signed bit field /+32 + def EXTS : ExtsCins<"exts", II_EXT, GPR64Opnd, immZExt5>, EXTS_FM<0x3a>, + ASE_MIPS64_CNMIPS; + def EXTS32: ExtsCins<"exts32", II_EXT, GPR64Opnd, immZExt5Plus32>, + EXTS_FM<0x3b>, ASE_MIPS64_CNMIPS; + + // Clear and insert a bit field /+32 + def CINS : ExtsCins<"cins", II_INS, GPR64Opnd, immZExt5, MipsCIns>, + EXTS_FM<0x32>, ASE_MIPS64_CNMIPS; + def CINS32: ExtsCins<"cins32", II_INS, GPR64Opnd, immZExt5Plus32, MipsCIns>, + EXTS_FM<0x33>, ASE_MIPS64_CNMIPS; + let isCodeGenOnly = 1 in { + def CINS_i32 : ExtsCins<"cins", II_INS, GPR32Opnd, immZExt5, MipsCIns>, + EXTS_FM<0x32>, ASE_MIPS64_CNMIPS; + def CINS64_32 :InstSE<(outs GPR64Opnd:$rt), + (ins GPR32Opnd:$rs, uimm5:$pos, uimm5:$lenm1), + "cins\t$rt, $rs, $pos, $lenm1", [], II_INS, FrmR, + "cins">, + EXTS_FM<0x32>, ASE_MIPS64_CNMIPS; + } +} // Move to multiplier/product register def MTM0 : MoveToLOHI<"mtm0", GPR64Opnd, [MPL0, P0, P1, P2]>, MTMR_FM<0x08>, @@ -513,41 +536,87 @@ def : MipsPat<(i64 (extloadi16 addr:$src)), (LH64 addr:$src)>; def : MipsPat<(i64 (extloadi32 addr:$src)), (LW64 addr:$src)>; // hi/lo relocs -def : MipsPat<(MipsHi tglobaladdr:$in), (LUi64 tglobaladdr:$in)>; -def : MipsPat<(MipsHi tblockaddress:$in), (LUi64 tblockaddress:$in)>; -def : MipsPat<(MipsHi tjumptable:$in), (LUi64 tjumptable:$in)>; -def : MipsPat<(MipsHi tconstpool:$in), (LUi64 tconstpool:$in)>; -def : MipsPat<(MipsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>; -def : MipsPat<(MipsHi texternalsym:$in), (LUi64 texternalsym:$in)>; +let AdditionalPredicates = [NotInMicroMips] in +defm : MipsHiLoRelocs<LUi64, DADDiu, ZERO_64, GPR64Opnd>, SYM_32; + +def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi64 tglobaladdr:$in)>; +def : MipsPat<(MipsGotHi texternalsym:$in), (LUi64 texternalsym:$in)>; + +multiclass MipsHighestHigherHiLoRelocs<Instruction Lui, Instruction Daddiu> { + def : MipsPat<(MipsJmpLink (i64 texternalsym:$dst)), + (JAL texternalsym:$dst)>; + def : MipsPat<(MipsHighest (i64 tglobaladdr:$in)), + (Lui tglobaladdr:$in)>; + def : MipsPat<(MipsHighest (i64 tblockaddress:$in)), + (Lui tblockaddress:$in)>; + def : MipsPat<(MipsHighest (i64 tjumptable:$in)), + (Lui tjumptable:$in)>; + def : MipsPat<(MipsHighest (i64 tconstpool:$in)), + (Lui tconstpool:$in)>; + def : MipsPat<(MipsHighest (i64 tglobaltlsaddr:$in)), + (Lui tglobaltlsaddr:$in)>; + def : MipsPat<(MipsHighest (i64 texternalsym:$in)), + (Lui texternalsym:$in)>; + + def : MipsPat<(MipsHigher (i64 tglobaladdr:$in)), + (Daddiu ZERO_64, tglobaladdr:$in)>; + def : MipsPat<(MipsHigher (i64 tblockaddress:$in)), + (Daddiu ZERO_64, tblockaddress:$in)>; + def : MipsPat<(MipsHigher (i64 tjumptable:$in)), + (Daddiu ZERO_64, tjumptable:$in)>; + def : MipsPat<(MipsHigher (i64 tconstpool:$in)), + (Daddiu ZERO_64, tconstpool:$in)>; + def : MipsPat<(MipsHigher (i64 tglobaltlsaddr:$in)), + (Daddiu ZERO_64, tglobaltlsaddr:$in)>; + def : MipsPat<(MipsHigher (i64 texternalsym:$in)), + (Daddiu ZERO_64, texternalsym:$in)>; + + def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaladdr:$lo))), + (Daddiu GPR64:$hi, tglobaladdr:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tblockaddress:$lo))), + (Daddiu GPR64:$hi, tblockaddress:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tjumptable:$lo))), + (Daddiu GPR64:$hi, tjumptable:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tconstpool:$lo))), + (Daddiu GPR64:$hi, tconstpool:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaltlsaddr:$lo))), + (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>; + + def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaladdr:$lo))), + (Daddiu GPR64:$hi, tglobaladdr:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tblockaddress:$lo))), + (Daddiu GPR64:$hi, tblockaddress:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tjumptable:$lo))), + (Daddiu GPR64:$hi, tjumptable:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tconstpool:$lo))), + (Daddiu GPR64:$hi, tconstpool:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaltlsaddr:$lo))), + (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>; + + def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaladdr:$lo))), + (Daddiu GPR64:$hi, tglobaladdr:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tblockaddress:$lo))), + (Daddiu GPR64:$hi, tblockaddress:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tjumptable:$lo))), + (Daddiu GPR64:$hi, tjumptable:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tconstpool:$lo))), + (Daddiu GPR64:$hi, tconstpool:$lo)>; + def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaltlsaddr:$lo))), + (Daddiu GPR64:$hi, tglobaltlsaddr:$lo)>; + +} + +// highest/higher/hi/lo relocs +let AdditionalPredicates = [NotInMicroMips] in +defm : MipsHighestHigherHiLoRelocs<LUi64, DADDiu>, SYM_64; + +def : WrapperPat<tglobaladdr, DADDiu, GPR64>; +def : WrapperPat<tconstpool, DADDiu, GPR64>; +def : WrapperPat<texternalsym, DADDiu, GPR64>; +def : WrapperPat<tblockaddress, DADDiu, GPR64>; +def : WrapperPat<tjumptable, DADDiu, GPR64>; +def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>; -let AdditionalPredicates = [NotInMicroMips] in { - def : MipsPat<(MipsLo tglobaladdr:$in), (DADDiu ZERO_64, tglobaladdr:$in)>; - def : MipsPat<(MipsLo tblockaddress:$in), - (DADDiu ZERO_64, tblockaddress:$in)>; - def : MipsPat<(MipsLo tjumptable:$in), (DADDiu ZERO_64, tjumptable:$in)>; - def : MipsPat<(MipsLo tconstpool:$in), (DADDiu ZERO_64, tconstpool:$in)>; - def : MipsPat<(MipsLo tglobaltlsaddr:$in), - (DADDiu ZERO_64, tglobaltlsaddr:$in)>; - def : MipsPat<(MipsLo texternalsym:$in), (DADDiu ZERO_64, texternalsym:$in)>; - - def : MipsPat<(add GPR64:$hi, (MipsLo tglobaladdr:$lo)), - (DADDiu GPR64:$hi, tglobaladdr:$lo)>; - def : MipsPat<(add GPR64:$hi, (MipsLo tblockaddress:$lo)), - (DADDiu GPR64:$hi, tblockaddress:$lo)>; - def : MipsPat<(add GPR64:$hi, (MipsLo tjumptable:$lo)), - (DADDiu GPR64:$hi, tjumptable:$lo)>; - def : MipsPat<(add GPR64:$hi, (MipsLo tconstpool:$lo)), - (DADDiu GPR64:$hi, tconstpool:$lo)>; - def : MipsPat<(add GPR64:$hi, (MipsLo tglobaltlsaddr:$lo)), - (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>; - - def : WrapperPat<tglobaladdr, DADDiu, GPR64>; - def : WrapperPat<tconstpool, DADDiu, GPR64>; - def : WrapperPat<texternalsym, DADDiu, GPR64>; - def : WrapperPat<tblockaddress, DADDiu, GPR64>; - def : WrapperPat<tjumptable, DADDiu, GPR64>; - def : WrapperPat<tglobaltlsaddr, DADDiu, GPR64>; -} defm : BrcondPats<GPR64, BEQ64, BEQ, BNE64, SLT64, SLTu64, SLTi64, SLTiu64, ZERO_64>; @@ -600,6 +669,14 @@ def : MipsPat<(i64 (anyext GPR32:$src)), def : MipsPat<(i64 (zext GPR32:$src)), (DSRL (DSLL64_32 GPR32:$src), 32)>; def : MipsPat<(i64 (sext GPR32:$src)), (SLL64_32 GPR32:$src)>; +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsPat<(i64 (zext GPR32:$src)), (DEXT64_32 GPR32:$src, 0, 32)>, + ISA_MIPS64R2; + def : MipsPat<(i64 (zext (i32 (shl GPR32:$rt, immZExt5:$imm)))), + (CINS64_32 GPR32:$rt, imm:$imm, (immZExt5To31 imm:$imm))>, + ASE_MIPS64_CNMIPS; +} + // Sign extend in register def : MipsPat<(i64 (sext_inreg GPR64:$src, i32)), (SLL64_64 GPR64:$src)>; @@ -661,10 +738,16 @@ let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"daddu $rs, $imm", (DADDiu GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm), 0>, ISA_MIPS3; + + defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi64, GPR64Opnd, imm64>, + GPR_64; + + defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi64, GPR64Opnd, imm64>, + GPR_64; + + defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi64, GPR64Opnd, imm64>, + GPR_64; } -def : MipsInstAlias<"dsll $rd, $rt, $rs", - (DSLLV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, - ISA_MIPS3; let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"dneg $rt, $rs", (DSUB GPR64Opnd:$rt, ZERO_64, GPR64Opnd:$rs), 1>, @@ -707,9 +790,18 @@ def : MipsInstAlias<"dsra $rd, $rt, $rs", (DSRAV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS3; let AdditionalPredicates = [NotInMicroMips] in { + def : MipsInstAlias<"dsll $rd, $rt, $rs", + (DSLLV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, + ISA_MIPS3; def : MipsInstAlias<"dsrl $rd, $rt, $rs", (DSRLV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, ISA_MIPS3; + def : MipsInstAlias<"dsrl $rd, $rt", + (DSRLV GPR64Opnd:$rd, GPR64Opnd:$rd, GPR32Opnd:$rt), 0>, + ISA_MIPS3; + def : MipsInstAlias<"dsll $rd, $rt", + (DSLLV GPR64Opnd:$rd, GPR64Opnd:$rd, GPR32Opnd:$rt), 0>, + ISA_MIPS3; // Two operand (implicit 0 selector) versions: def : MipsInstAlias<"dmtc0 $rt, $rd", @@ -741,21 +833,21 @@ def : MipsInstAlias<"bbit1 $rs, $p, $offset", def : MipsInstAlias<"exts $rt, $rs, $pos, $lenm1", (EXTS32 GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>, - ASE_CNMIPS; + ASE_MIPS64_CNMIPS; def : MipsInstAlias<"exts $rt, $pos, $lenm1", (EXTS32 GPR64Opnd:$rt, GPR64Opnd:$rt, uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>, - ASE_CNMIPS; + ASE_MIPS64_CNMIPS; // cins with $pos 32-63 in converted to cins32 with $pos 0-31 def : MipsInstAlias<"cins $rt, $rs, $pos, $lenm1", (CINS32 GPR64Opnd:$rt, GPR64Opnd:$rs, uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>, - ASE_CNMIPS; + ASE_MIPS64_CNMIPS; def : MipsInstAlias<"cins $rt, $pos, $lenm1", (CINS32 GPR64Opnd:$rt, GPR64Opnd:$rt, uimm5_plus32_normalize:$pos, uimm5:$lenm1), 0>, - ASE_CNMIPS; + ASE_MIPS64_CNMIPS; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions @@ -770,3 +862,81 @@ def LoadAddrReg64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rt), (ins mem:$addr), "dla\t$rt, $addr">; def LoadAddrImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rt), (ins imm64:$imm64), "dla\t$rt, $imm64">; + +def DMULImmMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt, + simm32_relaxed:$imm), + "dmul\t$rs, $rt, $imm">, + ISA_MIPS3_NOT_32R6_64R6; +def DMULOMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt, + GPR64Opnd:$rd), + "dmulo\t$rs, $rt, $rd">, + ISA_MIPS3_NOT_32R6_64R6; +def DMULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt, + GPR64Opnd:$rd), + "dmulou\t$rs, $rt, $rd">, + ISA_MIPS3_NOT_32R6_64R6; + +def DMULMacro : MipsAsmPseudoInst<(outs), (ins GPR64Opnd:$rs, GPR64Opnd:$rt, + GPR64Opnd:$rd), + "dmul\t$rs, $rt, $rd"> { + let InsnPredicates = [HasMips3, NotMips64r6, NotCnMips]; +} + +let AdditionalPredicates = [NotInMicroMips] in { + def DSDivMacro : MipsAsmPseudoInst<(outs GPR64Opnd:$rd), + (ins GPR64Opnd:$rs, GPR64Opnd:$rt), + "ddiv\t$rd, $rs, $rt">, + ISA_MIPS3_NOT_32R6_64R6; + def DSDivIMacro : MipsAsmPseudoInst<(outs GPR64Opnd:$rd), + (ins GPR64Opnd:$rs, imm64:$imm), + "ddiv\t$rd, $rs, $imm">, + ISA_MIPS3_NOT_32R6_64R6; + def DUDivMacro : MipsAsmPseudoInst<(outs GPR64Opnd:$rd), + (ins GPR64Opnd:$rs, GPR64Opnd:$rt), + "ddivu\t$rd, $rs, $rt">, + ISA_MIPS3_NOT_32R6_64R6; + def DUDivIMacro : MipsAsmPseudoInst<(outs GPR64Opnd:$rd), + (ins GPR64Opnd:$rs, imm64:$imm), + "ddivu\t$rd, $rs, $imm">, + ISA_MIPS3_NOT_32R6_64R6; + + // GAS expands 'div' and 'ddiv' differently when the destination + // register is $zero and the instruction is in the two operand + // form. 'ddiv' gets expanded, while 'div' is not expanded. + + def : MipsInstAlias<"ddiv $rs, $rt", (DSDivMacro GPR64Opnd:$rs, + GPR64Opnd:$rs, + GPR64Opnd:$rt), 0>, + ISA_MIPS3_NOT_32R6_64R6; + def : MipsInstAlias<"ddiv $rd, $imm", (DSDivIMacro GPR64Opnd:$rd, + GPR64Opnd:$rd, + imm64:$imm), 0>, + ISA_MIPS3_NOT_32R6_64R6; + + // GAS expands 'divu' and 'ddivu' differently when the destination + // register is $zero and the instruction is in the two operand + // form. 'ddivu' gets expanded, while 'divu' is not expanded. + + def : MipsInstAlias<"ddivu $rt, $rs", (DUDivMacro GPR64Opnd:$rt, + GPR64Opnd:$rt, + GPR64Opnd:$rs), 0>, + ISA_MIPS3_NOT_32R6_64R6; + def : MipsInstAlias<"ddivu $rd, $imm", (DUDivIMacro GPR64Opnd:$rd, + GPR64Opnd:$rd, + imm64:$imm), 0>, + ISA_MIPS3_NOT_32R6_64R6; +} + +def NORImm64 : NORIMM_DESC_BASE<GPR64Opnd, imm64>, GPR_64; +def : MipsInstAlias<"nor\t$rs, $imm", (NORImm64 GPR64Opnd:$rs, GPR64Opnd:$rs, + imm64:$imm)>, GPR_64; +def SLTImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rs), + (ins GPR64Opnd:$rt, imm64:$imm), + "slt\t$rs, $rt, $imm">, GPR_64; +def : MipsInstAlias<"slt\t$rs, $imm", (SLTImm64 GPR64Opnd:$rs, GPR64Opnd:$rs, + imm64:$imm)>, GPR_64; +def SLTUImm64 : MipsAsmPseudoInst<(outs GPR64Opnd:$rs), + (ins GPR64Opnd:$rt, imm64:$imm), + "sltu\t$rs, $rt, $imm">, GPR_64; +def : MipsInstAlias<"sltu\t$rs, $imm", (SLTUImm64 GPR64Opnd:$rs, GPR64Opnd:$rs, + imm64:$imm)>, GPR_64; |