X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSystemZ%2FSystemZInstrInfo.td;h=7789d614972c99c029d286cb40d25cefe2dc6732;hb=19262ee0725a09b7c621a3d2eb66ba1513ae932a;hp=4670156bb28d899a9f327bbb0ff0492625ee3eff;hpb=eddfaad1ef9a208a8a9ee23c26fac4d980caa99a;p=oota-llvm.git diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 4670156bb28..7789d614972 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -58,22 +58,19 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, R1 = 15 in { // in their raw BRC/BRCL form, with the 4-bit condition-code mask being // the first operand. It seems friendlier to use mnemonic forms like // JE and JLH when writing out the assembly though. -// -// Using a custom inserter for BRC gives us a chance to convert the BRC -// and a preceding compare into a single compare-and-branch instruction. -// The inserter makes no change in cases where a separate branch really -// is needed. -multiclass CondBranches { - let isBranch = 1, isTerminator = 1, Uses = [CC] in { - def "" : InstRI<0xA74, (outs), (ins ccmask:$R1, brtarget16:$I2), short, []>; - def L : InstRIL<0xC04, (outs), (ins ccmask:$R1, brtarget32:$I2), long, []>; +let isBranch = 1, isTerminator = 1, Uses = [CC] in { + let isCodeGenOnly = 1, CCMaskFirst = 1 in { + def BRC : InstRI<0xA74, (outs), (ins cond4:$valid, cond4:$R1, + brtarget16:$I2), "j$R1\t$I2", + [(z_br_ccmask cond4:$valid, cond4:$R1, bb:$I2)]>; + def BRCL : InstRIL<0xC04, (outs), (ins cond4:$valid, cond4:$R1, + brtarget32:$I2), "jg$R1\t$I2", []>; } + def AsmBRC : InstRI<0xA74, (outs), (ins uimm8zx4:$R1, brtarget16:$I2), + "brc\t$R1, $I2", []>; + def AsmBRCL : InstRIL<0xC04, (outs), (ins uimm8zx4:$R1, brtarget32:$I2), + "brcl\t$R1, $I2", []>; } -let isCodeGenOnly = 1, usesCustomInserter = 1 in - defm BRC : CondBranches; -defm AsmBRC : CondBranches; - -def : Pat<(z_br_ccmask cond4:$cond, bb:$dst), (BRC cond4:$cond, bb:$dst)>; // Fused compare-and-branch instructions. As for normal branches, // we handle these instructions internally in their raw CRJ-like form, @@ -107,26 +104,32 @@ defm AsmC : CompareBranches; // (integer or floating-point) multiclass CondExtendedMnemonic ccmask, string name> { let R1 = ccmask in { - def "" : InstRI<0xA74, (outs), (ins brtarget16:$I2), - "j"##name##"\t$I2", []>; - def L : InstRIL<0xC04, (outs), (ins brtarget32:$I2), + def J : InstRI<0xA74, (outs), (ins brtarget16:$I2), + "j"##name##"\t$I2", []>; + def JG : InstRIL<0xC04, (outs), (ins brtarget32:$I2), "jg"##name##"\t$I2", []>; } + def LOCR : FixedCondUnaryRRF<"locr"##name, 0xB9F2, GR32, GR32, ccmask>; + def LOCGR : FixedCondUnaryRRF<"locgr"##name, 0xB9E2, GR64, GR64, ccmask>; + def LOC : FixedCondUnaryRSY<"loc"##name, 0xEBF2, GR32, ccmask, 4>; + def LOCG : FixedCondUnaryRSY<"locg"##name, 0xEBE2, GR64, ccmask, 8>; + def STOC : FixedCondStoreRSY<"stoc"##name, 0xEBF3, GR32, ccmask, 4>; + def STOCG : FixedCondStoreRSY<"stocg"##name, 0xEBE3, GR64, ccmask, 8>; } -defm AsmJO : CondExtendedMnemonic<1, "o">; -defm AsmJH : CondExtendedMnemonic<2, "h">; -defm AsmJNLE : CondExtendedMnemonic<3, "nle">; -defm AsmJL : CondExtendedMnemonic<4, "l">; -defm AsmJNHE : CondExtendedMnemonic<5, "nhe">; -defm AsmJLH : CondExtendedMnemonic<6, "lh">; -defm AsmJNE : CondExtendedMnemonic<7, "ne">; -defm AsmJE : CondExtendedMnemonic<8, "e">; -defm AsmJNLH : CondExtendedMnemonic<9, "nlh">; -defm AsmJHE : CondExtendedMnemonic<10, "he">; -defm AsmJNL : CondExtendedMnemonic<11, "nl">; -defm AsmJLE : CondExtendedMnemonic<12, "le">; -defm AsmJNH : CondExtendedMnemonic<13, "nh">; -defm AsmJNO : CondExtendedMnemonic<14, "no">; +defm AsmO : CondExtendedMnemonic<1, "o">; +defm AsmH : CondExtendedMnemonic<2, "h">; +defm AsmNLE : CondExtendedMnemonic<3, "nle">; +defm AsmL : CondExtendedMnemonic<4, "l">; +defm AsmNHE : CondExtendedMnemonic<5, "nhe">; +defm AsmLH : CondExtendedMnemonic<6, "lh">; +defm AsmNE : CondExtendedMnemonic<7, "ne">; +defm AsmE : CondExtendedMnemonic<8, "e">; +defm AsmNLH : CondExtendedMnemonic<9, "nlh">; +defm AsmHE : CondExtendedMnemonic<10, "he">; +defm AsmNL : CondExtendedMnemonic<11, "nl">; +defm AsmLE : CondExtendedMnemonic<12, "le">; +defm AsmNH : CondExtendedMnemonic<13, "nh">; +defm AsmNO : CondExtendedMnemonic<14, "no">; // Define AsmParser mnemonics for each integer condition-code mask. // This is like the list above, except that condition 3 is not possible @@ -163,6 +166,13 @@ defm AsmJE : IntCondExtendedMnemonic<8, "e", "nlh">; defm AsmJHE : IntCondExtendedMnemonic<10, "he", "nl">; defm AsmJLE : IntCondExtendedMnemonic<12, "le", "nh">; +// Decrement a register and branch if it is nonzero. These don't clobber CC, +// but we might need to split long branches into sequences that do. +let Defs = [CC] in { + def BRCT : BranchUnaryRI<"brct", 0xA76, GR32>; + def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>; +} + //===----------------------------------------------------------------------===// // Select instructions //===----------------------------------------------------------------------===// @@ -192,7 +202,7 @@ defm CondStore64 : CondStores; @@ -220,6 +230,20 @@ let neverHasSideEffects = 1 in { def LR : UnaryRR <"l", 0x18, null_frag, GR32, GR32>; def LGR : UnaryRRE<"lg", 0xB904, null_frag, GR64, GR64>; } +let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in { + def LTR : UnaryRR <"lt", 0x12, null_frag, GR32, GR32>; + def LTGR : UnaryRRE<"ltg", 0xB902, null_frag, GR64, GR64>; +} + +// Move on condition. +let isCodeGenOnly = 1, Uses = [CC] in { + def LOCR : CondUnaryRRF<"loc", 0xB9F2, GR32, GR32>; + def LOCGR : CondUnaryRRF<"locg", 0xB9E2, GR64, GR64>; +} +let Uses = [CC] in { + def AsmLOCR : AsmCondUnaryRRF<"loc", 0xB9F2, GR32, GR32>; + def AsmLOCGR : AsmCondUnaryRRF<"locg", 0xB9E2, GR64, GR64>; +} // Immediate moves. let neverHasSideEffects = 1, isAsCheapAsAMove = 1, isMoveImm = 1, @@ -252,11 +276,26 @@ let canFoldAsLoad = 1, SimpleBDXLoad = 1 in { [(set GR128:$dst, (load bdxaddr20only128:$src))]>; } } +let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in { + def LT : UnaryRXY<"lt", 0xE312, load, GR32, 4>; + def LTG : UnaryRXY<"ltg", 0xE302, load, GR64, 8>; +} + let canFoldAsLoad = 1 in { def LRL : UnaryRILPC<"lrl", 0xC4D, aligned_load, GR32>; def LGRL : UnaryRILPC<"lgrl", 0xC48, aligned_load, GR64>; } +// Load on condition. +let isCodeGenOnly = 1, Uses = [CC] in { + def LOC : CondUnaryRSY<"loc", 0xEBF2, nonvolatile_load, GR32, 4>; + def LOCG : CondUnaryRSY<"locg", 0xEBE2, nonvolatile_load, GR64, 8>; +} +let Uses = [CC] in { + def AsmLOC : AsmCondUnaryRSY<"loc", 0xEBF2, GR32, 4>; + def AsmLOCG : AsmCondUnaryRSY<"locg", 0xEBE2, GR64, 8>; +} + // Register stores. let SimpleBDXStore = 1 in { let isCodeGenOnly = 1 in @@ -274,6 +313,17 @@ let isCodeGenOnly = 1 in def STRL32 : StoreRILPC<"strl", 0xC4F, aligned_store, GR32>; def STGRL : StoreRILPC<"stgrl", 0xC4B, aligned_store, GR64>; +// Store on condition. +let isCodeGenOnly = 1, Uses = [CC] in { + def STOC32 : CondStoreRSY<"stoc", 0xEBF3, GR32, 4>; + def STOC : CondStoreRSY<"stoc", 0xEBF3, GR64, 4>; + def STOCG : CondStoreRSY<"stocg", 0xEBE3, GR64, 8>; +} +let Uses = [CC] in { + def AsmSTOC : AsmCondStoreRSY<"stoc", 0xEBF3, GR32, 4>; + def AsmSTOCG : AsmCondStoreRSY<"stocg", 0xEBE3, GR64, 8>; +} + // 8-bit immediate stores to 8-bit fields. defm MVI : StoreSIPair<"mvi", 0x92, 0xEB52, truncstorei8, imm32zx8trunc>; @@ -284,15 +334,11 @@ def MVGHI : StoreSIL<"mvghi", 0xE548, store, imm64sx16>; // Memory-to-memory moves. let mayLoad = 1, mayStore = 1 in - def MVC : InstSS<0xD2, (outs), (ins bdladdr12onlylen8:$BDL1, - bdaddr12only:$BD2), - "mvc\t$BDL1, $BD2", []>; + defm MVC : MemorySS<"mvc", 0xD2, z_mvc>; -let mayLoad = 1, mayStore = 1, usesCustomInserter = 1 in - def MVCWrapper : Pseudo<(outs), (ins bdaddr12only:$dest, bdaddr12only:$src, - imm32len8:$length), - [(z_mvc bdaddr12only:$dest, bdaddr12only:$src, - imm32len8:$length)]>; +// String moves. +let mayLoad = 1, mayStore = 1, Defs = [CC], Uses = [R0W] in + defm MVST : StringRRE<"mvst", 0xB255, z_stpcpy>; defm LoadStore8_32 : MVCLoadStore; @@ -324,6 +370,8 @@ let neverHasSideEffects = 1 in { def LGHR : UnaryRRE<"lgh", 0xB907, sext16, GR64, GR64>; def LGFR : UnaryRRE<"lgf", 0xB914, sext32, GR64, GR32>; } +let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in + def LTGFR : UnaryRRE<"ltgf", 0xB912, null_frag, GR64, GR64>; // Match 32-to-64-bit sign extensions in which the source is already // in a 64-bit register. @@ -341,6 +389,8 @@ def LGH : UnaryRXY<"lgh", 0xE315, sextloadi16, GR64, 2>; def LGF : UnaryRXY<"lgf", 0xE314, sextloadi32, GR64, 4>; def LGHRL : UnaryRILPC<"lghrl", 0xC44, aligned_sextloadi16, GR64>; def LGFRL : UnaryRILPC<"lgfrl", 0xC4C, aligned_sextloadi32, GR64>; +let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in + def LTGF : UnaryRXY<"ltgf", 0xE332, sextloadi32, GR64, 4>; // If the sign of a load-extend operation doesn't matter, use the signed ones. // There's not really much to choose between the sign and zero extensions, @@ -478,9 +528,12 @@ let neverHasSideEffects = 1, isAsCheapAsAMove = 1, isMoveImm = 1, //===----------------------------------------------------------------------===// let Defs = [CC] in { - def LCR : UnaryRR <"lc", 0x13, ineg, GR32, GR32>; - def LCGR : UnaryRRE<"lcg", 0xB903, ineg, GR64, GR64>; - def LCGFR : UnaryRRE<"lcgf", 0xB913, null_frag, GR64, GR32>; + let CCValues = 0xF, CompareZeroCCMask = 0x8 in { + def LCR : UnaryRR <"lc", 0x13, ineg, GR32, GR32>; + def LCGR : UnaryRRE<"lcg", 0xB903, ineg, GR64, GR64>; + } + let CCValues = 0xE, CompareZeroCCMask = 0xE in + def LCGFR : UnaryRRE<"lcgf", 0xB913, null_frag, GR64, GR32>; } defm : SXU; @@ -532,17 +585,17 @@ def : Pat<(or (zext32 GR32:$src), imm64hf32:$imm), //===----------------------------------------------------------------------===// // Plain addition. -let Defs = [CC] in { +let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0x8 in { // Addition of a register. let isCommutable = 1 in { - def AR : BinaryRR <"a", 0x1A, add, GR32, GR32>; - def AGR : BinaryRRE<"ag", 0xB908, add, GR64, GR64>; + defm AR : BinaryRRAndK<"a", 0x1A, 0xB9F8, add, GR32, GR32>; + defm AGR : BinaryRREAndK<"ag", 0xB908, 0xB9E8, add, GR64, GR64>; } def AGFR : BinaryRRE<"agf", 0xB918, null_frag, GR64, GR32>; // Addition of signed 16-bit immediates. - def AHI : BinaryRI<"ahi", 0xA7A, add, GR32, imm32sx16>; - def AGHI : BinaryRI<"aghi", 0xA7B, add, GR64, imm64sx16>; + defm AHI : BinaryRIAndK<"ahi", 0xA7A, 0xECD8, add, GR32, imm32sx16>; + defm AGHI : BinaryRIAndK<"aghi", 0xA7B, 0xECD9, add, GR64, imm64sx16>; // Addition of signed 32-bit immediates. def AFI : BinaryRIL<"afi", 0xC29, add, GR32, simm32>; @@ -564,11 +617,17 @@ defm : SXB; let Defs = [CC] in { // Addition of a register. let isCommutable = 1 in { - def ALR : BinaryRR <"al", 0x1E, addc, GR32, GR32>; - def ALGR : BinaryRRE<"alg", 0xB90A, addc, GR64, GR64>; + defm ALR : BinaryRRAndK<"al", 0x1E, 0xB9FA, addc, GR32, GR32>; + defm ALGR : BinaryRREAndK<"alg", 0xB90A, 0xB9EA, addc, GR64, GR64>; } def ALGFR : BinaryRRE<"algf", 0xB91A, null_frag, GR64, GR32>; + // Addition of signed 16-bit immediates. + def ALHSIK : BinaryRIE<"alhsik", 0xECDA, addc, GR32, imm32sx16>, + Requires<[FeatureDistinctOps]>; + def ALGHSIK : BinaryRIE<"alghsik", 0xECDB, addc, GR64, imm64sx16>, + Requires<[FeatureDistinctOps]>; + // Addition of unsigned 32-bit immediates. def ALFI : BinaryRIL<"alfi", 0xC2B, addc, GR32, uimm32>; def ALGFI : BinaryRIL<"algfi", 0xC2A, addc, GR64, imm64zx32>; @@ -597,11 +656,11 @@ let Defs = [CC], Uses = [CC] in { // Plain substraction. Although immediate forms exist, we use the // add-immediate instruction instead. -let Defs = [CC] in { +let Defs = [CC], CCValues = 0xF, CompareZeroCCMask = 0x8 in { // Subtraction of a register. - def SR : BinaryRR <"s", 0x1B, sub, GR32, GR32>; + defm SR : BinaryRRAndK<"s", 0x1B, 0xB9F9, sub, GR32, GR32>; def SGFR : BinaryRRE<"sgf", 0xB919, null_frag, GR64, GR32>; - def SGR : BinaryRRE<"sg", 0xB909, sub, GR64, GR64>; + defm SGR : BinaryRREAndK<"sg", 0xB909, 0xB9E9, sub, GR64, GR64>; // Subtraction of memory. defm SH : BinaryRXPair<"sh", 0x4B, 0xE37B, sub, GR32, sextloadi16, 2>; @@ -614,9 +673,9 @@ defm : SXB; // Subtraction producing a carry. let Defs = [CC] in { // Subtraction of a register. - def SLR : BinaryRR <"sl", 0x1F, subc, GR32, GR32>; + defm SLR : BinaryRRAndK<"sl", 0x1F, 0xB9FB, subc, GR32, GR32>; def SLGFR : BinaryRRE<"slgf", 0xB91B, null_frag, GR64, GR32>; - def SLGR : BinaryRRE<"slg", 0xB90B, subc, GR64, GR64>; + defm SLGR : BinaryRREAndK<"slg", 0xB90B, 0xB9EB, subc, GR64, GR64>; // Subtraction of unsigned 32-bit immediates. These don't match // subc because we prefer addc for constants. @@ -647,30 +706,37 @@ let Defs = [CC], Uses = [CC] in { let Defs = [CC] in { // ANDs of a register. - let isCommutable = 1 in { - def NR : BinaryRR <"n", 0x14, and, GR32, GR32>; - def NGR : BinaryRRE<"ng", 0xB980, and, GR64, GR64>; + let isCommutable = 1, CCValues = 0xC, CompareZeroCCMask = 0x8 in { + defm NR : BinaryRRAndK<"n", 0x14, 0xB9F4, and, GR32, GR32>; + defm NGR : BinaryRREAndK<"ng", 0xB980, 0xB9E4, and, GR64, GR64>; } - // ANDs of a 16-bit immediate, leaving other bits unaffected. - let isCodeGenOnly = 1 in { - def NILL32 : BinaryRI<"nill", 0xA57, and, GR32, imm32ll16c>; - def NILH32 : BinaryRI<"nilh", 0xA56, and, GR32, imm32lh16c>; + let isConvertibleToThreeAddress = 1 in { + // ANDs of a 16-bit immediate, leaving other bits unaffected. + // The CC result only reflects the 16-bit field, not the full register. + let isCodeGenOnly = 1 in { + def NILL32 : BinaryRI<"nill", 0xA57, and, GR32, imm32ll16c>; + def NILH32 : BinaryRI<"nilh", 0xA56, and, GR32, imm32lh16c>; + } + def NILL : BinaryRI<"nill", 0xA57, and, GR64, imm64ll16c>; + def NILH : BinaryRI<"nilh", 0xA56, and, GR64, imm64lh16c>; + def NIHL : BinaryRI<"nihl", 0xA55, and, GR64, imm64hl16c>; + def NIHH : BinaryRI<"nihh", 0xA54, and, GR64, imm64hh16c>; + + // ANDs of a 32-bit immediate, leaving other bits unaffected. + // The CC result only reflects the 32-bit field, which means we can + // use it as a zero indicator for i32 operations but not otherwise. + let isCodeGenOnly = 1, CCValues = 0xC, CompareZeroCCMask = 0x8 in + def NILF32 : BinaryRIL<"nilf", 0xC0B, and, GR32, uimm32>; + def NILF : BinaryRIL<"nilf", 0xC0B, and, GR64, imm64lf32c>; + def NIHF : BinaryRIL<"nihf", 0xC0A, and, GR64, imm64hf32c>; } - def NILL : BinaryRI<"nill", 0xA57, and, GR64, imm64ll16c>; - def NILH : BinaryRI<"nilh", 0xA56, and, GR64, imm64lh16c>; - def NIHL : BinaryRI<"nihl", 0xA55, and, GR64, imm64hl16c>; - def NIHH : BinaryRI<"nihh", 0xA54, and, GR64, imm64hh16c>; - - // ANDs of a 32-bit immediate, leaving other bits unaffected. - let isCodeGenOnly = 1 in - def NILF32 : BinaryRIL<"nilf", 0xC0B, and, GR32, uimm32>; - def NILF : BinaryRIL<"nilf", 0xC0B, and, GR64, imm64lf32c>; - def NIHF : BinaryRIL<"nihf", 0xC0A, and, GR64, imm64hf32c>; // ANDs of memory. - defm N : BinaryRXPair<"n", 0x54, 0xE354, and, GR32, load, 4>; - def NG : BinaryRXY<"ng", 0xE380, and, GR64, load, 8>; + let CCValues = 0xC, CompareZeroCCMask = 0x8 in { + defm N : BinaryRXPair<"n", 0x54, 0xE354, and, GR32, load, 4>; + def NG : BinaryRXY<"ng", 0xE380, and, GR64, load, 8>; + } // AND to memory defm NI : BinarySIPair<"ni", 0x94, 0xEB54, null_frag, uimm8>; @@ -684,12 +750,13 @@ defm : RMWIByte; let Defs = [CC] in { // ORs of a register. - let isCommutable = 1 in { - def OR : BinaryRR <"o", 0x16, or, GR32, GR32>; - def OGR : BinaryRRE<"og", 0xB981, or, GR64, GR64>; + let isCommutable = 1, CCValues = 0xC, CompareZeroCCMask = 0x8 in { + defm OR : BinaryRRAndK<"o", 0x16, 0xB9F6, or, GR32, GR32>; + defm OGR : BinaryRREAndK<"og", 0xB981, 0xB9E6, or, GR64, GR64>; } // ORs of a 16-bit immediate, leaving other bits unaffected. + // The CC result only reflects the 16-bit field, not the full register. let isCodeGenOnly = 1 in { def OILL32 : BinaryRI<"oill", 0xA5B, or, GR32, imm32ll16>; def OILH32 : BinaryRI<"oilh", 0xA5A, or, GR32, imm32lh16>; @@ -700,14 +767,18 @@ let Defs = [CC] in { def OIHH : BinaryRI<"oihh", 0xA58, or, GR64, imm64hh16>; // ORs of a 32-bit immediate, leaving other bits unaffected. - let isCodeGenOnly = 1 in + // The CC result only reflects the 32-bit field, which means we can + // use it as a zero indicator for i32 operations but not otherwise. + let isCodeGenOnly = 1, CCValues = 0xC, CompareZeroCCMask = 0x8 in def OILF32 : BinaryRIL<"oilf", 0xC0D, or, GR32, uimm32>; def OILF : BinaryRIL<"oilf", 0xC0D, or, GR64, imm64lf32>; def OIHF : BinaryRIL<"oihf", 0xC0C, or, GR64, imm64hf32>; // ORs of memory. - defm O : BinaryRXPair<"o", 0x56, 0xE356, or, GR32, load, 4>; - def OG : BinaryRXY<"og", 0xE381, or, GR64, load, 8>; + let CCValues = 0xC, CompareZeroCCMask = 0x8 in { + defm O : BinaryRXPair<"o", 0x56, 0xE356, or, GR32, load, 4>; + def OG : BinaryRXY<"og", 0xE381, or, GR64, load, 8>; + } // OR to memory defm OI : BinarySIPair<"oi", 0x96, 0xEB56, null_frag, uimm8>; @@ -721,20 +792,24 @@ defm : RMWIByte; let Defs = [CC] in { // XORs of a register. - let isCommutable = 1 in { - def XR : BinaryRR <"x", 0x17, xor, GR32, GR32>; - def XGR : BinaryRRE<"xg", 0xB982, xor, GR64, GR64>; + let isCommutable = 1, CCValues = 0xC, CompareZeroCCMask = 0x8 in { + defm XR : BinaryRRAndK<"x", 0x17, 0xB9F7, xor, GR32, GR32>; + defm XGR : BinaryRREAndK<"xg", 0xB982, 0xB9E7, xor, GR64, GR64>; } // XORs of a 32-bit immediate, leaving other bits unaffected. - let isCodeGenOnly = 1 in + // The CC result only reflects the 32-bit field, which means we can + // use it as a zero indicator for i32 operations but not otherwise. + let isCodeGenOnly = 1, CCValues = 0xC, CompareZeroCCMask = 0x8 in def XILF32 : BinaryRIL<"xilf", 0xC07, xor, GR32, uimm32>; def XILF : BinaryRIL<"xilf", 0xC07, xor, GR64, imm64lf32>; def XIHF : BinaryRIL<"xihf", 0xC06, xor, GR64, imm64hf32>; // XORs of memory. - defm X : BinaryRXPair<"x",0x57, 0xE357, xor, GR32, load, 4>; - def XG : BinaryRXY<"xg", 0xE382, xor, GR64, load, 8>; + let CCValues = 0xC, CompareZeroCCMask = 0x8 in { + defm X : BinaryRXPair<"x",0x57, 0xE357, xor, GR32, load, 4>; + def XG : BinaryRXY<"xg", 0xE382, xor, GR64, load, 8>; + } // XOR to memory defm XI : BinarySIPair<"xi", 0x97, 0xEB57, null_frag, uimm8>; @@ -807,7 +882,7 @@ let neverHasSideEffects = 1 in { } // Arithmetic shift right. -let Defs = [CC] in { +let Defs = [CC], CCValues = 0xE, CompareZeroCCMask = 0xE in { defm SRA : ShiftRSAndK<"sra", 0x8A, 0xEBDC, sra, GR32>; def SRAG : ShiftRSY<"srag", 0xEB0A, sra, GR64>; } @@ -820,15 +895,27 @@ let neverHasSideEffects = 1 in { // Rotate second operand left and inserted selected bits into first operand. // These can act like 32-bit operands provided that the constant start and -// end bits (operands 2 and 3) are in the range [32, 64) +// end bits (operands 2 and 3) are in the range [32, 64). let Defs = [CC] in { let isCodeGenOnly = 1 in - def RISBG32 : RotateSelectRIEf<"risbg", 0xEC55, GR32, GR32>; - def RISBG : RotateSelectRIEf<"risbg", 0xEC55, GR64, GR64>; + def RISBG32 : RotateSelectRIEf<"risbg", 0xEC55, GR32, GR32>; + let CCValues = 0xE, CompareZeroCCMask = 0xE in + def RISBG : RotateSelectRIEf<"risbg", 0xEC55, GR64, GR64>; } +// Forms of RISBG that only affect one word of the destination register. +// They do not set CC. +let isCodeGenOnly = 1 in + def RISBLG32 : RotateSelectRIEf<"risblg", 0xEC51, GR32, GR32>, + Requires<[FeatureHighWord]>; +def RISBHG : RotateSelectRIEf<"risbhg", 0xEC5D, GR64, GR64>, + Requires<[FeatureHighWord]>; +def RISBLG : RotateSelectRIEf<"risblg", 0xEC51, GR64, GR64>, + Requires<[FeatureHighWord]>; + // Rotate second operand left and perform a logical operation with selected -// bits of the first operand. +// bits of the first operand. The CC result only describes the selected bits, +// so isn't useful for a full comparison against zero. let Defs = [CC] in { def RNSBG : RotateSelectRIEf<"rnsbg", 0xEC54, GR64, GR64>; def ROSBG : RotateSelectRIEf<"rosbg", 0xEC56, GR64, GR64>; @@ -840,7 +927,7 @@ let Defs = [CC] in { //===----------------------------------------------------------------------===// // Signed comparisons. -let Defs = [CC] in { +let Defs = [CC], CCValues = 0xE in { // Comparison with a register. def CR : CompareRR <"c", 0x19, z_cmp, GR32, GR32>; def CGFR : CompareRRE<"cgf", 0xB930, null_frag, GR64, GR32>; @@ -874,7 +961,7 @@ let Defs = [CC] in { defm : SXB; // Unsigned comparisons. -let Defs = [CC] in { +let Defs = [CC], CCValues = 0xE, IsLogical = 1 in { // Comparison with a register. def CLR : CompareRR <"cl", 0x15, z_ucmp, GR32, GR32>; def CLGFR : CompareRRE<"clgf", 0xB931, null_frag, GR64, GR32>; @@ -909,6 +996,14 @@ let Defs = [CC] in { } defm : ZXB; +// Memory-to-memory comparison. +let mayLoad = 1, Defs = [CC] in + defm CLC : MemorySS<"clc", 0xD5, z_clc>; + +// String comparison. +let mayLoad = 1, Defs = [CC], Uses = [R0W] in + defm CLST : StringRRE<"clst", 0xB25D, z_strcmp>; + //===----------------------------------------------------------------------===// // Atomic operations //===----------------------------------------------------------------------===// @@ -1028,6 +1123,10 @@ let Defs = [CC] in { // Miscellaneous Instructions. //===----------------------------------------------------------------------===// +// Extract CC into bits 29 and 28 of a register. +let Uses = [CC] in + def IPM : InherentRRE<"ipm", 0xB222, GR32, (z_ipm)>; + // Read a 32-bit access register into a GR32. As with all GR32 operations, // the upper 32 bits of the enclosing GR64 remain unchanged, which is useful // when a 64-bit address is stored in a pair of access registers. @@ -1064,6 +1163,10 @@ let usesCustomInserter = 1 in { def ZEXT128_64 : Pseudo<(outs GR128:$dst), (ins GR64:$src), []>; } +// Search a block of memory for a character. +let mayLoad = 1, Defs = [CC], Uses = [R0W] in + defm SRST : StringRRE<"srst", 0xb25e, z_search_string>; + //===----------------------------------------------------------------------===// // Peepholes. //===----------------------------------------------------------------------===// @@ -1084,9 +1187,12 @@ def : Pat<(sub GR64:$src1, (zextloadi32 bdxaddr20only:$addr)), // Optimize sign-extended 1/0 selects to -1/0 selects. This is important // for vector legalization. -def : Pat<(sra (shl (i32 (z_select_ccmask 1, 0, imm:$cc)), (i32 31)), (i32 31)), - (Select32 (LHI -1), (LHI 0), imm:$cc)>; -def : Pat<(sra (shl (i64 (anyext (i32 (z_select_ccmask 1, 0, imm:$cc)))), +def : Pat<(sra (shl (i32 (z_select_ccmask 1, 0, uimm8zx4:$valid, uimm8zx4:$cc)), + (i32 31)), + (i32 31)), + (Select32 (LHI -1), (LHI 0), uimm8zx4:$valid, uimm8zx4:$cc)>; +def : Pat<(sra (shl (i64 (anyext (i32 (z_select_ccmask 1, 0, uimm8zx4:$valid, + uimm8zx4:$cc)))), (i32 63)), (i32 63)), - (Select64 (LGHI -1), (LGHI 0), imm:$cc)>; + (Select64 (LGHI -1), (LGHI 0), uimm8zx4:$valid, uimm8zx4:$cc)>;