SystemZInstrInfo.td revision 10c086cd776f94c75e996f8d56165b6bdd439241
1//===- SystemZInstrInfo.td - SystemZ Instruction defs ---------*- tblgen-*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the SystemZ instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// SystemZ Instruction Predicate Definitions. 16def IsZ10 : Predicate<"Subtarget.isZ10()">; 17 18include "SystemZInstrFormats.td" 19 20//===----------------------------------------------------------------------===// 21// Type Constraints. 22//===----------------------------------------------------------------------===// 23class SDTCisI8<int OpNum> : SDTCisVT<OpNum, i8>; 24class SDTCisI16<int OpNum> : SDTCisVT<OpNum, i16>; 25class SDTCisI32<int OpNum> : SDTCisVT<OpNum, i32>; 26class SDTCisI64<int OpNum> : SDTCisVT<OpNum, i64>; 27 28//===----------------------------------------------------------------------===// 29// Type Profiles. 30//===----------------------------------------------------------------------===// 31def SDT_SystemZCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 32def SDT_SystemZCallSeqStart : SDCallSeqStart<[SDTCisI64<0>]>; 33def SDT_SystemZCallSeqEnd : SDCallSeqEnd<[SDTCisI64<0>, SDTCisI64<1>]>; 34def SDT_CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 35def SDT_BrCond : SDTypeProfile<0, 2, 36 [SDTCisVT<0, OtherVT>, 37 SDTCisI8<1>]>; 38def SDT_SelectCC : SDTypeProfile<1, 3, 39 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 40 SDTCisI8<3>]>; 41def SDT_Address : SDTypeProfile<1, 1, 42 [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 43 44//===----------------------------------------------------------------------===// 45// SystemZ Specific Node Definitions. 46//===----------------------------------------------------------------------===// 47def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone, 48 [SDNPHasChain, SDNPOptInFlag]>; 49def SystemZcall : SDNode<"SystemZISD::CALL", SDT_SystemZCall, 50 [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; 51def SystemZcallseq_start : 52 SDNode<"ISD::CALLSEQ_START", SDT_SystemZCallSeqStart, 53 [SDNPHasChain, SDNPOutFlag]>; 54def SystemZcallseq_end : 55 SDNode<"ISD::CALLSEQ_END", SDT_SystemZCallSeqEnd, 56 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 57def SystemZcmp : SDNode<"SystemZISD::CMP", SDT_CmpTest, [SDNPOutFlag]>; 58def SystemZucmp : SDNode<"SystemZISD::UCMP", SDT_CmpTest, [SDNPOutFlag]>; 59def SystemZbrcond : SDNode<"SystemZISD::BRCOND", SDT_BrCond, 60 [SDNPHasChain, SDNPInFlag]>; 61def SystemZselect : SDNode<"SystemZISD::SELECT", SDT_SelectCC, [SDNPInFlag]>; 62def SystemZpcrelwrapper : SDNode<"SystemZISD::PCRelativeWrapper", SDT_Address, []>; 63 64 65include "SystemZOperands.td" 66 67//===----------------------------------------------------------------------===// 68// Instruction list.. 69 70def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt), 71 "#ADJCALLSTACKDOWN", 72 [(SystemZcallseq_start timm:$amt)]>; 73def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2), 74 "#ADJCALLSTACKUP", 75 [(SystemZcallseq_end timm:$amt1, timm:$amt2)]>; 76 77let usesCustomDAGSchedInserter = 1 in { 78 def Select32 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2, i8imm:$cc), 79 "# Select32 PSEUDO", 80 [(set GR32:$dst, 81 (SystemZselect GR32:$src1, GR32:$src2, imm:$cc))]>; 82 def Select64 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2, i8imm:$cc), 83 "# Select64 PSEUDO", 84 [(set GR64:$dst, 85 (SystemZselect GR64:$src1, GR64:$src2, imm:$cc))]>; 86} 87 88 89//===----------------------------------------------------------------------===// 90// Control Flow Instructions... 91// 92 93// FIXME: Provide proper encoding! 94let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in { 95 def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>; 96} 97 98let isBranch = 1, isTerminator = 1 in { 99 let isBarrier = 1 in { 100 def JMP : Pseudo<(outs), (ins brtarget:$dst), "j\t{$dst}", [(br bb:$dst)]>; 101 102 let isIndirectBranch = 1 in 103 def JMPr : Pseudo<(outs), (ins GR64:$dst), "br\t{$dst}", [(brind GR64:$dst)]>; 104 } 105 106 let Uses = [PSW] in { 107 def JO : Pseudo<(outs), (ins brtarget:$dst), 108 "jo\t$dst", 109 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_O)]>; 110 def JH : Pseudo<(outs), (ins brtarget:$dst), 111 "jh\t$dst", 112 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_H)]>; 113 def JNLE: Pseudo<(outs), (ins brtarget:$dst), 114 "jnle\t$dst", 115 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLE)]>; 116 def JL : Pseudo<(outs), (ins brtarget:$dst), 117 "jl\t$dst", 118 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_L)]>; 119 def JNHE: Pseudo<(outs), (ins brtarget:$dst), 120 "jnhe\t$dst", 121 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NHE)]>; 122 def JLH : Pseudo<(outs), (ins brtarget:$dst), 123 "jlh\t$dst", 124 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LH)]>; 125 def JNE : Pseudo<(outs), (ins brtarget:$dst), 126 "jne\t$dst", 127 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NE)]>; 128 def JE : Pseudo<(outs), (ins brtarget:$dst), 129 "je\t$dst", 130 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_E)]>; 131 def JNLH: Pseudo<(outs), (ins brtarget:$dst), 132 "jnlh\t$dst", 133 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NLH)]>; 134 def JHE : Pseudo<(outs), (ins brtarget:$dst), 135 "jhe\t$dst", 136 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_HE)]>; 137 def JNL : Pseudo<(outs), (ins brtarget:$dst), 138 "jnl\t$dst", 139 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NL)]>; 140 def JLE : Pseudo<(outs), (ins brtarget:$dst), 141 "jle\t$dst", 142 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_LE)]>; 143 def JNH : Pseudo<(outs), (ins brtarget:$dst), 144 "jnh\t$dst", 145 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NH)]>; 146 def JNO : Pseudo<(outs), (ins brtarget:$dst), 147 "jno\t$dst", 148 [(SystemZbrcond bb:$dst, SYSTEMZ_COND_NO)]>; 149 } // Uses = [PSW] 150} // isBranch = 1 151 152//===----------------------------------------------------------------------===// 153// Call Instructions... 154// 155 156let isCall = 1 in 157 // All calls clobber the non-callee saved registers. Uses for argument 158 // registers are added manually. 159 let Defs = [R0D, R1D, R2D, R3D, R4D, R5D, R14D] in { 160 def CALLi : Pseudo<(outs), (ins imm_pcrel:$dst, variable_ops), 161 "brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>; 162 def CALLr : Pseudo<(outs), (ins ADDR64:$dst, variable_ops), 163 "basr\t%r14, $dst", [(SystemZcall ADDR64:$dst)]>; 164 } 165 166//===----------------------------------------------------------------------===// 167// Miscellaneous Instructions. 168// 169 170let isReMaterializable = 1 in 171// FIXME: Provide imm12 variant 172// FIXME: Address should be halfword aligned... 173def LA64r : Pseudo<(outs GR64:$dst), (ins laaddr:$src), 174 "lay\t{$dst, $src}", 175 [(set GR64:$dst, laaddr:$src)]>; 176def LA64rm : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 177 "larl\t{$dst, $src}", 178 [(set GR64:$dst, 179 (SystemZpcrelwrapper tglobaladdr:$src))]>; 180 181let neverHasSideEffects = 1 in 182def NOP : Pseudo<(outs), (ins), "# no-op", []>; 183 184//===----------------------------------------------------------------------===// 185// Move Instructions 186 187// FIXME: Provide proper encoding! 188let neverHasSideEffects = 1 in { 189def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src), 190 "lr\t{$dst, $src}", 191 []>; 192def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src), 193 "lgr\t{$dst, $src}", 194 []>; 195def MOV128rr : Pseudo<(outs GR128:$dst), (ins GR128:$src), 196 "# MOV128 PSEUDO!\n" 197 "\tlgr\t${dst:subreg_odd}, ${src:subreg_odd}\n" 198 "\tlgr\t${dst:subreg_even}, ${src:subreg_even}", 199 []>; 200def MOV64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src), 201 "# MOV64P PSEUDO!\n" 202 "\tlr\t${dst:subreg_odd}, ${src:subreg_odd}\n" 203 "\tlr\t${dst:subreg_even}, ${src:subreg_even}", 204 []>; 205} 206 207def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src), 208 "lgfr\t{$dst, $src}", 209 [(set GR64:$dst, (sext GR32:$src))]>; 210def MOVZX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src), 211 "llgfr\t{$dst, $src}", 212 [(set GR64:$dst, (zext GR32:$src))]>; 213 214// FIXME: Provide proper encoding! 215let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 216def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins s16imm:$src), 217 "lhi\t{$dst, $src}", 218 [(set GR32:$dst, immSExt16:$src)]>; 219def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins s16imm64:$src), 220 "lghi\t{$dst, $src}", 221 [(set GR64:$dst, immSExt16:$src)]>; 222 223def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 224 "llill\t{$dst, $src}", 225 [(set GR64:$dst, i64ll16:$src)]>; 226def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 227 "llilh\t{$dst, $src}", 228 [(set GR64:$dst, i64lh16:$src)]>; 229def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 230 "llihl\t{$dst, $src}", 231 [(set GR64:$dst, i64hl16:$src)]>; 232def MOV64rihh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 233 "llihh\t{$dst, $src}", 234 [(set GR64:$dst, i64hh16:$src)]>; 235 236def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins s32imm64:$src), 237 "lgfi\t{$dst, $src}", 238 [(set GR64:$dst, immSExt32:$src)]>; 239def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 240 "llilf\t{$dst, $src}", 241 [(set GR64:$dst, i64lo32:$src)]>; 242def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 243 "llihf\t{$dst, $src}", 244 [(set GR64:$dst, i64hi32:$src)]>; 245} 246 247let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { 248def MOV32rm : Pseudo<(outs GR32:$dst), (ins rriaddr12:$src), 249 "l\t{$dst, $src}", 250 [(set GR32:$dst, (load rriaddr12:$src))]>; 251def MOV32rmy : Pseudo<(outs GR32:$dst), (ins rriaddr:$src), 252 "ly\t{$dst, $src}", 253 [(set GR32:$dst, (load rriaddr:$src))]>; 254def MOV64rm : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), 255 "lg\t{$dst, $src}", 256 [(set GR64:$dst, (load rriaddr:$src))]>; 257 258} 259 260def MOV32mr : Pseudo<(outs), (ins rriaddr12:$dst, GR32:$src), 261 "st\t{$src, $dst}", 262 [(store GR32:$src, rriaddr12:$dst)]>; 263def MOV32mry : Pseudo<(outs), (ins rriaddr:$dst, GR32:$src), 264 "sty\t{$src, $dst}", 265 [(store GR32:$src, rriaddr:$dst)]>; 266def MOV64mr : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src), 267 "stg\t{$src, $dst}", 268 [(store GR64:$src, rriaddr:$dst)]>; 269 270def MOV8mi : Pseudo<(outs), (ins riaddr12:$dst, i32i8imm:$src), 271 "mvi\t{$dst, $src}", 272 [(truncstorei8 (i32 i32immSExt8:$src), riaddr12:$dst)]>; 273def MOV8miy : Pseudo<(outs), (ins riaddr:$dst, i32i8imm:$src), 274 "mviy\t{$dst, $src}", 275 [(truncstorei8 (i32 i32immSExt8:$src), riaddr:$dst)]>; 276 277def MOV16mi : Pseudo<(outs), (ins riaddr12:$dst, s16imm:$src), 278 "mvhhi\t{$dst, $src}", 279 [(truncstorei16 (i32 i32immSExt16:$src), riaddr12:$dst)]>, 280 Requires<[IsZ10]>; 281def MOV32mi16 : Pseudo<(outs), (ins riaddr12:$dst, s32imm:$src), 282 "mvhi\t{$dst, $src}", 283 [(store (i32 immSExt16:$src), riaddr12:$dst)]>, 284 Requires<[IsZ10]>; 285def MOV64mi16 : Pseudo<(outs), (ins riaddr12:$dst, s32imm64:$src), 286 "mvghi\t{$dst, $src}", 287 [(store (i64 immSExt16:$src), riaddr12:$dst)]>, 288 Requires<[IsZ10]>; 289 290// sexts 291def MOVSX32rr8 : Pseudo<(outs GR32:$dst), (ins GR32:$src), 292 "lbr\t{$dst, $src}", 293 [(set GR32:$dst, (sext_inreg GR32:$src, i8))]>; 294def MOVSX64rr8 : Pseudo<(outs GR64:$dst), (ins GR64:$src), 295 "lgbr\t{$dst, $src}", 296 [(set GR64:$dst, (sext_inreg GR64:$src, i8))]>; 297def MOVSX32rr16 : Pseudo<(outs GR32:$dst), (ins GR32:$src), 298 "lhr\t{$dst, $src}", 299 [(set GR32:$dst, (sext_inreg GR32:$src, i16))]>; 300def MOVSX64rr16 : Pseudo<(outs GR64:$dst), (ins GR64:$src), 301 "lghr\t{$dst, $src}", 302 [(set GR64:$dst, (sext_inreg GR64:$src, i16))]>; 303 304// extloads 305def MOVSX32rm8 : Pseudo<(outs GR32:$dst), (ins rriaddr:$src), 306 "lb\t{$dst, $src}", 307 [(set GR32:$dst, (sextloadi32i8 rriaddr:$src))]>; 308def MOVSX32rm16 : Pseudo<(outs GR32:$dst), (ins rriaddr12:$src), 309 "lh\t{$dst, $src}", 310 [(set GR32:$dst, (sextloadi32i16 rriaddr12:$src))]>; 311def MOVSX32rm16y : Pseudo<(outs GR32:$dst), (ins rriaddr:$src), 312 "lhy\t{$dst, $src}", 313 [(set GR32:$dst, (sextloadi32i16 rriaddr:$src))]>; 314def MOVSX64rm8 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), 315 "lgb\t{$dst, $src}", 316 [(set GR64:$dst, (sextloadi64i8 rriaddr:$src))]>; 317def MOVSX64rm16 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), 318 "lgh\t{$dst, $src}", 319 [(set GR64:$dst, (sextloadi64i16 rriaddr:$src))]>; 320def MOVSX64rm32 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), 321 "lgf\t{$dst, $src}", 322 [(set GR64:$dst, (sextloadi64i32 rriaddr:$src))]>; 323 324def MOVZX32rm8 : Pseudo<(outs GR32:$dst), (ins rriaddr:$src), 325 "llc\t{$dst, $src}", 326 [(set GR32:$dst, (zextloadi32i8 rriaddr:$src))]>; 327def MOVZX32rm16 : Pseudo<(outs GR32:$dst), (ins rriaddr:$src), 328 "llh\t{$dst, $src}", 329 [(set GR32:$dst, (zextloadi32i16 rriaddr:$src))]>; 330def MOVZX64rm8 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), 331 "llgc\t{$dst, $src}", 332 [(set GR64:$dst, (zextloadi64i8 rriaddr:$src))]>; 333def MOVZX64rm16 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), 334 "llgh\t{$dst, $src}", 335 [(set GR64:$dst, (zextloadi64i16 rriaddr:$src))]>; 336def MOVZX64rm32 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), 337 "llgf\t{$dst, $src}", 338 [(set GR64:$dst, (zextloadi64i32 rriaddr:$src))]>; 339 340// truncstores 341def MOV32m8r : Pseudo<(outs), (ins rriaddr12:$dst, GR32:$src), 342 "stc\t{$src, $dst}", 343 [(truncstorei8 GR32:$src, rriaddr12:$dst)]>; 344 345def MOV32m8ry : Pseudo<(outs), (ins rriaddr:$dst, GR32:$src), 346 "stcy\t{$src, $dst}", 347 [(truncstorei8 GR32:$src, rriaddr:$dst)]>; 348 349def MOV32m16r : Pseudo<(outs), (ins rriaddr12:$dst, GR32:$src), 350 "sth\t{$src, $dst}", 351 [(truncstorei16 GR32:$src, rriaddr12:$dst)]>; 352 353def MOV32m16ry : Pseudo<(outs), (ins rriaddr:$dst, GR32:$src), 354 "sthy\t{$src, $dst}", 355 [(truncstorei16 GR32:$src, rriaddr:$dst)]>; 356 357def MOV64m8r : Pseudo<(outs), (ins rriaddr12:$dst, GR64:$src), 358 "stc\t{$src, $dst}", 359 [(truncstorei8 GR64:$src, rriaddr12:$dst)]>; 360 361def MOV64m8ry : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src), 362 "stcy\t{$src, $dst}", 363 [(truncstorei8 GR64:$src, rriaddr:$dst)]>; 364 365def MOV64m16r : Pseudo<(outs), (ins rriaddr12:$dst, GR64:$src), 366 "sth\t{$src, $dst}", 367 [(truncstorei16 GR64:$src, rriaddr12:$dst)]>; 368 369def MOV64m16ry : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src), 370 "sthy\t{$src, $dst}", 371 [(truncstorei16 GR64:$src, rriaddr:$dst)]>; 372 373def MOV64m32r : Pseudo<(outs), (ins rriaddr12:$dst, GR64:$src), 374 "st\t{$src, $dst}", 375 [(truncstorei32 GR64:$src, rriaddr12:$dst)]>; 376 377def MOV64m32ry : Pseudo<(outs), (ins rriaddr:$dst, GR64:$src), 378 "sty\t{$src, $dst}", 379 [(truncstorei32 GR64:$src, rriaddr:$dst)]>; 380 381// multiple regs moves 382// FIXME: should we use multiple arg nodes? 383def MOV32mrm : Pseudo<(outs), (ins riaddr:$dst, GR32:$from, GR32:$to), 384 "stmy\t{$from, $to, $dst}", 385 []>; 386def MOV64mrm : Pseudo<(outs), (ins riaddr:$dst, GR64:$from, GR64:$to), 387 "stmg\t{$from, $to, $dst}", 388 []>; 389def MOV32rmm : Pseudo<(outs GR32:$from, GR32:$to), (ins riaddr:$dst), 390 "lmy\t{$from, $to, $dst}", 391 []>; 392def MOV64rmm : Pseudo<(outs GR64:$from, GR64:$to), (ins riaddr:$dst), 393 "lmg\t{$from, $to, $dst}", 394 []>; 395 396let isReMaterializable = 1, isAsCheapAsAMove = 1, isTwoAddress = 1 in { 397def MOV64Pr0_even : Pseudo<(outs GR64P:$dst), (ins GR64P:$src), 398 "lhi\t${dst:subreg_even}, 0", 399 []>; 400def MOV128r0_even : Pseudo<(outs GR128:$dst), (ins GR128:$src), 401 "lghi\t${dst:subreg_even}, 0", 402 []>; 403} 404 405//===----------------------------------------------------------------------===// 406// Arithmetic Instructions 407 408let Defs = [PSW] in { 409def NEG32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src), 410 "lcr\t{$dst, $src}", 411 [(set GR32:$dst, (ineg GR32:$src)), 412 (implicit PSW)]>; 413def NEG64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src), 414 "lcgr\t{$dst, $src}", 415 [(set GR64:$dst, (ineg GR64:$src)), 416 (implicit PSW)]>; 417def NEG64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src), 418 "lcgfr\t{$dst, $src}", 419 [(set GR64:$dst, (ineg (sext GR32:$src))), 420 (implicit PSW)]>; 421} 422 423let isTwoAddress = 1 in { 424 425let Defs = [PSW] in { 426 427let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y 428// FIXME: Provide proper encoding! 429def ADD32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 430 "ar\t{$dst, $src2}", 431 [(set GR32:$dst, (add GR32:$src1, GR32:$src2)), 432 (implicit PSW)]>; 433def ADD64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 434 "agr\t{$dst, $src2}", 435 [(set GR64:$dst, (add GR64:$src1, GR64:$src2)), 436 (implicit PSW)]>; 437} 438 439// FIXME: Provide proper encoding! 440def ADD32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, s16imm:$src2), 441 "ahi\t{$dst, $src2}", 442 [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)), 443 (implicit PSW)]>; 444def ADD32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, s32imm:$src2), 445 "afi\t{$dst, $src2}", 446 [(set GR32:$dst, (add GR32:$src1, imm:$src2)), 447 (implicit PSW)]>; 448def ADD64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, s16imm64:$src2), 449 "aghi\t{$dst, $src2}", 450 [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)), 451 (implicit PSW)]>; 452def ADD64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2), 453 "agfi\t{$dst, $src2}", 454 [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)), 455 (implicit PSW)]>; 456 457let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y 458// FIXME: Provide proper encoding! 459def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 460 "nr\t{$dst, $src2}", 461 [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>; 462def AND64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 463 "ngr\t{$dst, $src2}", 464 [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>; 465} 466 467// FIXME: Provide proper encoding! 468// FIXME: Compute masked bits properly! 469def AND32rill16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 470 "nill\t{$dst, $src2}", 471 [(set GR32:$dst, (and GR32:$src1, i32ll16c:$src2))]>; 472def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 473 "nill\t{$dst, $src2}", 474 [(set GR64:$dst, (and GR64:$src1, i64ll16c:$src2))]>; 475 476def AND32rilh16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 477 "nilh\t{$dst, $src2}", 478 [(set GR32:$dst, (and GR32:$src1, i32lh16c:$src2))]>; 479def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 480 "nilh\t{$dst, $src2}", 481 [(set GR64:$dst, (and GR64:$src1, i64lh16c:$src2))]>; 482 483def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 484 "nihl\t{$dst, $src2}", 485 [(set GR64:$dst, (and GR64:$src1, i64hl16c:$src2))]>; 486def AND64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 487 "nihh\t{$dst, $src2}", 488 [(set GR64:$dst, (and GR64:$src1, i64hh16c:$src2))]>; 489 490def AND32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 491 "nilf\t{$dst, $src2}", 492 [(set GR32:$dst, (and GR32:$src1, imm:$src2))]>; 493def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 494 "nilf\t{$dst, $src2}", 495 [(set GR64:$dst, (and GR64:$src1, i64lo32c:$src2))]>; 496def AND64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 497 "nihf\t{$dst, $src2}", 498 [(set GR64:$dst, (and GR64:$src1, i64hi32c:$src2))]>; 499 500let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y 501// FIXME: Provide proper encoding! 502def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 503 "or\t{$dst, $src2}", 504 [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>; 505def OR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 506 "ogr\t{$dst, $src2}", 507 [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>; 508} 509 510def OR32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 511 "oill\t{$dst, $src2}", 512 [(set GR32:$dst, (or GR32:$src1, i32ll16:$src2))]>; 513def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 514 "oilh\t{$dst, $src2}", 515 [(set GR32:$dst, (or GR32:$src1, i32lh16:$src2))]>; 516def OR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 517 "oilf\t{$dst, $src2}", 518 [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>; 519 520def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 521 "oill\t{$dst, $src2}", 522 [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>; 523def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 524 "oilh\t{$dst, $src2}", 525 [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>; 526def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 527 "oihl\t{$dst, $src2}", 528 [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>; 529def OR64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 530 "oihh\t{$dst, $src2}", 531 [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>; 532 533def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 534 "oilf\t{$dst, $src2}", 535 [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>; 536def OR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 537 "oihf\t{$dst, $src2}", 538 [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>; 539 540// FIXME: Provide proper encoding! 541def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 542 "sr\t{$dst, $src2}", 543 [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>; 544def SUB64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 545 "sgr\t{$dst, $src2}", 546 [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>; 547 548 549let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y 550// FIXME: Provide proper encoding! 551def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 552 "xr\t{$dst, $src2}", 553 [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>; 554def XOR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 555 "xgr\t{$dst, $src2}", 556 [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>; 557} 558 559def XOR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 560 "xilf\t{$dst, $src2}", 561 [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>; 562 563} // Defs = [PSW] 564 565let isCommutable = 1 in { // X = MUL Y, Z == X = MUL Z, Y 566def MUL32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 567 "msr\t{$dst, $src2}", 568 [(set GR32:$dst, (mul GR32:$src1, GR32:$src2))]>; 569def MUL64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 570 "msgr\t{$dst, $src2}", 571 [(set GR64:$dst, (mul GR64:$src1, GR64:$src2))]>; 572} 573 574def MUL64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2), 575 "mr\t{$dst, $src2}", 576 []>; 577def UMUL64rrP : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2), 578 "mlr\t{$dst, $src2}", 579 []>; 580def UMUL128rrP : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2), 581 "mlgr\t{$dst, $src2}", 582 []>; 583 584def MUL32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, s16imm:$src2), 585 "mhi\t{$dst, $src2}", 586 [(set GR32:$dst, (mul GR32:$src1, i32immSExt16:$src2))]>; 587def MUL64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, s16imm64:$src2), 588 "mghi\t{$dst, $src2}", 589 [(set GR64:$dst, (mul GR64:$src1, immSExt16:$src2))]>; 590 591def MUL32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, s32imm:$src2), 592 "msfi\t{$dst, $src2}", 593 [(set GR32:$dst, (mul GR32:$src1, imm:$src2))]>, 594 Requires<[IsZ10]>; 595def MUL64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, s32imm64:$src2), 596 "msgfi\t{$dst, $src2}", 597 [(set GR64:$dst, (mul GR64:$src1, i64immSExt32:$src2))]>, 598 Requires<[IsZ10]>; 599 600def MUL32rm : Pseudo<(outs GR32:$dst), (ins GR32:$src1, rriaddr12:$src2), 601 "ms\t{$dst, $src2}", 602 [(set GR32:$dst, (mul GR32:$src1, (load rriaddr12:$src2)))]>; 603def MUL32rmy : Pseudo<(outs GR32:$dst), (ins GR32:$src1, rriaddr:$src2), 604 "msy\t{$dst, $src2}", 605 [(set GR32:$dst, (mul GR32:$src1, (load rriaddr:$src2)))]>; 606def MUL64rm : Pseudo<(outs GR64:$dst), (ins GR64:$src1, rriaddr:$src2), 607 "msg\t{$dst, $src2}", 608 [(set GR64:$dst, (mul GR64:$src1, (load rriaddr:$src2)))]>; 609 610def MULSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR32:$src2), 611 "msgfr\t{$dst, $src2}", 612 [(set GR64:$dst, (mul GR64:$src1, (sext GR32:$src2)))]>; 613 614def SDIVREM32r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR32:$src2), 615 "dsgfr\t{$dst, $src2}", 616 []>; 617def SDIVREM64r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2), 618 "dsgr\t{$dst, $src2}", 619 []>; 620 621def UDIVREM32r : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, GR32:$src2), 622 "dlr\t{$dst, $src2}", 623 []>; 624def UDIVREM64r : Pseudo<(outs GR128:$dst), (ins GR128:$src1, GR64:$src2), 625 "dlgr\t{$dst, $src2}", 626 []>; 627let mayLoad = 1 in { 628def SDIVREM32m : Pseudo<(outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2), 629 "dsgf\t{$dst, $src2}", 630 []>; 631def SDIVREM64m : Pseudo<(outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2), 632 "dsg\t{$dst, $src2}", 633 []>; 634 635def UDIVREM32m : Pseudo<(outs GR64P:$dst), (ins GR64P:$src1, rriaddr:$src2), 636 "dl\t{$dst, $src2}", 637 []>; 638def UDIVREM64m : Pseudo<(outs GR128:$dst), (ins GR128:$src1, rriaddr:$src2), 639 "dlg\t{$dst, $src2}", 640 []>; 641} // mayLoad 642} // isTwoAddress = 1 643 644//===----------------------------------------------------------------------===// 645// Shifts 646 647let isTwoAddress = 1 in 648def SRL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt), 649 "srl\t{$src, $amt}", 650 [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>; 651def SRL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt), 652 "srlg\t{$dst, $src, $amt}", 653 [(set GR64:$dst, (srl GR64:$src, riaddr:$amt))]>; 654 655let isTwoAddress = 1 in 656def SHL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt), 657 "sll\t{$src, $amt}", 658 [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>; 659def SHL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt), 660 "sllg\t{$dst, $src, $amt}", 661 [(set GR64:$dst, (shl GR64:$src, riaddr:$amt))]>; 662 663let Defs = [PSW] in { 664let isTwoAddress = 1 in 665def SRA32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt), 666 "sra\t{$src, $amt}", 667 [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)), 668 (implicit PSW)]>; 669 670def SRA64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt), 671 "srag\t{$dst, $src, $amt}", 672 [(set GR64:$dst, (sra GR64:$src, riaddr:$amt)), 673 (implicit PSW)]>; 674} // Defs = [PSW] 675 676def ROTL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt), 677 "rll\t{$dst, $src, $amt}", 678 [(set GR32:$dst, (rotl GR32:$src, riaddr32:$amt))]>; 679def ROTL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt), 680 "rllg\t{$dst, $src, $amt}", 681 [(set GR64:$dst, (rotl GR64:$src, riaddr:$amt))]>; 682 683//===----------------------------------------------------------------------===// 684// Test instructions (like AND but do not produce any result) 685 686// Integer comparisons 687let Defs = [PSW] in { 688def CMP32rr : Pseudo<(outs), (ins GR32:$src1, GR32:$src2), 689 "cr\t$src1, $src2", 690 [(SystemZcmp GR32:$src1, GR32:$src2), (implicit PSW)]>; 691def CMP64rr : Pseudo<(outs), (ins GR64:$src1, GR64:$src2), 692 "cgr\t$src1, $src2", 693 [(SystemZcmp GR64:$src1, GR64:$src2), (implicit PSW)]>; 694 695def CMP32ri : Pseudo<(outs), (ins GR32:$src1, s32imm:$src2), 696 "cfi\t$src1, $src2", 697 [(SystemZcmp GR32:$src1, imm:$src2), (implicit PSW)]>; 698def CMP64ri32 : Pseudo<(outs), (ins GR64:$src1, s32imm64:$src2), 699 "cgfi\t$src1, $src2", 700 [(SystemZcmp GR64:$src1, i64immSExt32:$src2), 701 (implicit PSW)]>; 702 703def CMP32rm : Pseudo<(outs), (ins GR32:$src1, rriaddr12:$src2), 704 "c\t$src1, $src2", 705 [(SystemZcmp GR32:$src1, (load rriaddr12:$src2)), 706 (implicit PSW)]>; 707def CMP32rmy : Pseudo<(outs), (ins GR32:$src1, rriaddr:$src2), 708 "cy\t$src1, $src2", 709 [(SystemZcmp GR32:$src1, (load rriaddr:$src2)), 710 (implicit PSW)]>; 711def CMP64rm : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2), 712 "cg\t$src1, $src2", 713 [(SystemZcmp GR64:$src1, (load rriaddr:$src2)), 714 (implicit PSW)]>; 715 716def UCMP32rr : Pseudo<(outs), (ins GR32:$src1, GR32:$src2), 717 "clr\t$src1, $src2", 718 [(SystemZucmp GR32:$src1, GR32:$src2), (implicit PSW)]>; 719def UCMP64rr : Pseudo<(outs), (ins GR64:$src1, GR64:$src2), 720 "clgr\t$src1, $src2", 721 [(SystemZucmp GR64:$src1, GR64:$src2), (implicit PSW)]>; 722 723def UCMP32ri : Pseudo<(outs), (ins GR32:$src1, i32imm:$src2), 724 "clfi\t$src1, $src2", 725 [(SystemZucmp GR32:$src1, imm:$src2), (implicit PSW)]>; 726def UCMP64ri32 : Pseudo<(outs), (ins GR64:$src1, i64i32imm:$src2), 727 "clgfi\t$src1, $src2", 728 [(SystemZucmp GR64:$src1, i64immZExt32:$src2), 729 (implicit PSW)]>; 730 731def UCMP32rm : Pseudo<(outs), (ins GR32:$src1, rriaddr12:$src2), 732 "cl\t$src1, $src2", 733 [(SystemZucmp GR32:$src1, (load rriaddr12:$src2)), 734 (implicit PSW)]>; 735def UCMP32rmy : Pseudo<(outs), (ins GR32:$src1, rriaddr:$src2), 736 "cly\t$src1, $src2", 737 [(SystemZucmp GR32:$src1, (load rriaddr:$src2)), 738 (implicit PSW)]>; 739def UCMP64rm : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2), 740 "clg\t$src1, $src2", 741 [(SystemZucmp GR64:$src1, (load rriaddr:$src2)), 742 (implicit PSW)]>; 743 744def CMPSX64rr32 : Pseudo<(outs), (ins GR64:$src1, GR32:$src2), 745 "cgfr\t$src1, $src2", 746 [(SystemZucmp GR64:$src1, (sext GR32:$src2)), 747 (implicit PSW)]>; 748def UCMPZX64rr32 : Pseudo<(outs), (ins GR64:$src1, GR32:$src2), 749 "clgfr\t$src1, $src2", 750 [(SystemZucmp GR64:$src1, (zext GR32:$src2)), 751 (implicit PSW)]>; 752 753def CMPSX64rm32 : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2), 754 "cgf\t$src1, $src2", 755 [(SystemZucmp GR64:$src1, (sextloadi64i32 rriaddr:$src2)), 756 (implicit PSW)]>; 757def UCMPZX64rm32 : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2), 758 "clgf\t$src1, $src2", 759 [(SystemZucmp GR64:$src1, (zextloadi64i32 rriaddr:$src2)), 760 (implicit PSW)]>; 761 762// FIXME: Add other crazy ucmp forms 763 764} // Defs = [PSW] 765 766//===----------------------------------------------------------------------===// 767// Non-Instruction Patterns. 768//===----------------------------------------------------------------------===// 769 770// ConstPools, JumpTables 771def : Pat<(SystemZpcrelwrapper tjumptable:$src), (LA64rm tjumptable:$src)>; 772def : Pat<(SystemZpcrelwrapper tconstpool:$src), (LA64rm tconstpool:$src)>; 773 774// anyext 775def : Pat<(i64 (anyext GR32:$src)), 776 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>; 777 778// calls 779def : Pat<(SystemZcall (i64 tglobaladdr:$dst)), (CALLi tglobaladdr:$dst)>; 780def : Pat<(SystemZcall (i64 texternalsym:$dst)), (CALLi texternalsym:$dst)>; 781 782//===----------------------------------------------------------------------===// 783// Peepholes. 784//===----------------------------------------------------------------------===// 785 786// FIXME: use add/sub tricks with 32678/-32768 787 788// Arbitrary immediate support. Implement in terms of LLIHF/OILF. 789def : Pat<(i64 imm:$imm), 790 (OR64rilo32 (MOV64rihi32 (HI32 imm:$imm)), (LO32 imm:$imm))>; 791 792// trunc patterns 793def : Pat<(i32 (trunc GR64:$src)), 794 (EXTRACT_SUBREG GR64:$src, subreg_32bit)>; 795 796// sext_inreg patterns 797def : Pat<(sext_inreg GR64:$src, i32), 798 (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>; 799 800// extload patterns 801def : Pat<(extloadi32i8 rriaddr:$src), (MOVZX32rm8 rriaddr:$src)>; 802def : Pat<(extloadi32i16 rriaddr:$src), (MOVZX32rm16 rriaddr:$src)>; 803def : Pat<(extloadi64i8 rriaddr:$src), (MOVZX64rm8 rriaddr:$src)>; 804def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>; 805def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>; 806 807// muls 808def : Pat<(mulhs GR32:$src1, GR32:$src2), 809 (EXTRACT_SUBREG (MUL64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 810 GR32:$src1, subreg_odd32), 811 GR32:$src2), 812 subreg_even32)>; 813 814def : Pat<(mulhu GR32:$src1, GR32:$src2), 815 (EXTRACT_SUBREG (UMUL64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 816 GR32:$src1, subreg_odd32), 817 GR32:$src2), 818 subreg_even32)>; 819def : Pat<(mulhu GR64:$src1, GR64:$src2), 820 (EXTRACT_SUBREG (UMUL128rrP (INSERT_SUBREG (i128 (IMPLICIT_DEF)), 821 GR64:$src1, subreg_odd), 822 GR64:$src2), 823 subreg_even)>; 824 825def : Pat<(i32 imm:$src), 826 (EXTRACT_SUBREG (MOV64ri32 (i64 imm:$src)), subreg_32bit)>; 827