SystemZInstrInfo.td revision 9e4816e09f50e3c4ef7368a188966944b8167ab4
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 14include "SystemZInstrFormats.td" 15 16//===----------------------------------------------------------------------===// 17// SystemZ Specific Node Definitions. 18//===----------------------------------------------------------------------===// 19def SystemZretflag : SDNode<"SystemZISD::RET_FLAG", SDTNone, 20 [SDNPHasChain, SDNPOptInFlag]>; 21 22let neverHasSideEffects = 1 in 23def NOP : Pseudo<(outs), (ins), "# no-op", []>; 24 25//===----------------------------------------------------------------------===// 26// Instruction Pattern Stuff. 27//===----------------------------------------------------------------------===// 28def LL16 : SDNodeXForm<imm, [{ 29 // Transformation function: return low 16 bits. 30 return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL); 31}]>; 32 33def LH16 : SDNodeXForm<imm, [{ 34 // Transformation function: return bits 16-31. 35 return getI16Imm((N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16); 36}]>; 37 38def HL16 : SDNodeXForm<imm, [{ 39 // Transformation function: return bits 32-47. 40 return getI16Imm((N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32); 41}]>; 42 43def HH16 : SDNodeXForm<imm, [{ 44 // Transformation function: return bits 48-63. 45 return getI16Imm((N->getZExtValue() & 0xFFFF000000000000ULL) >> 48); 46}]>; 47 48def LO32 : SDNodeXForm<imm, [{ 49 // Transformation function: return low 32 bits. 50 return getI32Imm(N->getZExtValue() & 0x00000000FFFFFFFFULL); 51}]>; 52 53def HI32 : SDNodeXForm<imm, [{ 54 // Transformation function: return bits 32-63. 55 return getI32Imm(N->getZExtValue() >> 32); 56}]>; 57 58def i64ll16 : PatLeaf<(imm), [{ 59 // i64ll16 predicate - true if the 64-bit immediate has only rightmost 16 60 // bits set. 61 return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue()); 62}], LL16>; 63 64def i64lh16 : PatLeaf<(imm), [{ 65 // i64lh16 predicate - true if the 64-bit immediate has only bits 16-31 set. 66 return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue()); 67}], LH16>; 68 69def i64hl16 : PatLeaf<(i64 imm), [{ 70 // i64hl16 predicate - true if the 64-bit immediate has only bits 32-47 set. 71 return ((N->getZExtValue() & 0x0000FFFF00000000ULL) == N->getZExtValue()); 72}], HL16>; 73 74def i64hh16 : PatLeaf<(i64 imm), [{ 75 // i64hh16 predicate - true if the 64-bit immediate has only bits 48-63 set. 76 return ((N->getZExtValue() & 0xFFFF000000000000ULL) == N->getZExtValue()); 77}], HH16>; 78 79def immSExt16 : PatLeaf<(imm), [{ 80 // immSExt16 predicate - true if the immediate fits in a 16-bit sign extended 81 // field. 82 if (N->getValueType(0) == MVT::i64) { 83 uint64_t val = N->getZExtValue(); 84 return ((int64_t)val == (int16_t)val); 85 } else if (N->getValueType(0) == MVT::i32) { 86 uint32_t val = N->getZExtValue(); 87 return ((int32_t)val == (int16_t)val); 88 } 89 90 return false; 91}]>; 92 93def immSExt32 : PatLeaf<(i64 imm), [{ 94 // immSExt32 predicate - true if the immediate fits in a 32-bit sign extended 95 // field. 96 uint64_t val = N->getZExtValue(); 97 return ((int64_t)val == (int32_t)val); 98}]>; 99 100def i64lo32 : PatLeaf<(i64 imm), [{ 101 // i64lo32 predicate - true if the 64-bit immediate has only rightmost 32 102 // bits set. 103 return ((N->getZExtValue() & 0x00000000FFFFFFFFULL) == N->getZExtValue()); 104}], LO32>; 105 106def i64hi32 : PatLeaf<(i64 imm), [{ 107 // i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set. 108 return ((N->getZExtValue() & 0xFFFFFFFF00000000ULL) == N->getZExtValue()); 109}], HI32>; 110 111//===----------------------------------------------------------------------===// 112// SystemZ Operand Definitions. 113//===----------------------------------------------------------------------===// 114 115// Address operands 116 117// riaddr := reg + imm 118def riaddr32 : Operand<i32>, 119 ComplexPattern<i32, 2, "SelectAddrRI", []> { 120 let PrintMethod = "printRIAddrOperand"; 121 let MIOperandInfo = (ops ADDR32:$base, i32imm:$disp); 122} 123 124def riaddr : Operand<i64>, 125 ComplexPattern<i64, 2, "SelectAddrRI", []> { 126 let PrintMethod = "printRIAddrOperand"; 127 let MIOperandInfo = (ops ADDR64:$base, i32imm:$disp); 128} 129 130//===----------------------------------------------------------------------===// 131 132//===----------------------------------------------------------------------===// 133// Control Flow Instructions... 134// 135 136// FIXME: Provide proper encoding! 137let isReturn = 1, isTerminator = 1 in { 138 def RET : Pseudo<(outs), (ins), "br\t%r14", [(SystemZretflag)]>; 139} 140 141//===----------------------------------------------------------------------===// 142// Move Instructions 143 144// FIXME: Provide proper encoding! 145let neverHasSideEffects = 1 in { 146def MOV32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src), 147 "lr\t{$dst, $src}", 148 []>; 149def MOV64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src), 150 "lgr\t{$dst, $src}", 151 []>; 152} 153 154def MOVSX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src), 155 "lgfr\t{$dst, $src}", 156 [(set GR64:$dst, (sext GR32:$src))]>; 157def MOVZX64rr32 : Pseudo<(outs GR64:$dst), (ins GR32:$src), 158 "llgfr\t{$dst, $src}", 159 [(set GR64:$dst, (zext GR32:$src))]>; 160 161// FIXME: Provide proper encoding! 162let isReMaterializable = 1, isAsCheapAsAMove = 1 in { 163def MOV32ri16 : Pseudo<(outs GR32:$dst), (ins i32imm:$src), 164 "lhi\t{$dst, $src}", 165 [(set GR32:$dst, immSExt16:$src)]>; 166def MOV64ri16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 167 "lghi\t{$dst, $src}", 168 [(set GR64:$dst, immSExt16:$src)]>; 169 170def MOV64rill16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 171 "llill\t{$dst, $src}", 172 [(set GR64:$dst, i64ll16:$src)]>; 173def MOV64rilh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 174 "llilh\t{$dst, $src}", 175 [(set GR64:$dst, i64lh16:$src)]>; 176def MOV64rihl16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 177 "llihl\t{$dst, $src}", 178 [(set GR64:$dst, i64hl16:$src)]>; 179def MOV64rihh16 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 180 "llihh\t{$dst, $src}", 181 [(set GR64:$dst, i64hh16:$src)]>; 182// FIXME: these 3 instructions seem to require extimm facility 183def MOV64ri32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 184 "lgfi\t{$dst, $src}", 185 [(set GR64:$dst, immSExt32:$src)]>; 186def MOV64rilo32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 187 "llilf\t{$dst, $src}", 188 [(set GR64:$dst, i64lo32:$src)]>; 189def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), 190 "llihf\t{$dst, $src}", 191 [(set GR64:$dst, i64hi32:$src)]>; 192} 193 194//===----------------------------------------------------------------------===// 195// Arithmetic Instructions 196 197let isTwoAddress = 1 in { 198 199let Defs = [PSW] in { 200 201let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y 202// FIXME: Provide proper encoding! 203def ADD32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 204 "ar\t{$dst, $src2}", 205 [(set GR32:$dst, (add GR32:$src1, GR32:$src2)), 206 (implicit PSW)]>; 207def ADD64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 208 "agr\t{$dst, $src2}", 209 [(set GR64:$dst, (add GR64:$src1, GR64:$src2)), 210 (implicit PSW)]>; 211} 212 213// FIXME: Provide proper encoding! 214def ADD32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 215 "ahi\t{$dst, $src2}", 216 [(set GR32:$dst, (add GR32:$src1, immSExt16:$src2)), 217 (implicit PSW)]>; 218def ADD32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 219 "afi\t{$dst, $src2}", 220 [(set GR32:$dst, (add GR32:$src1, imm:$src2)), 221 (implicit PSW)]>; 222def ADD64ri16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 223 "aghi\t{$dst, $src2}", 224 [(set GR64:$dst, (add GR64:$src1, immSExt16:$src2)), 225 (implicit PSW)]>; 226def ADD64ri32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 227 "agfi\t{$dst, $src2}", 228 [(set GR64:$dst, (add GR64:$src1, immSExt32:$src2)), 229 (implicit PSW)]>; 230 231let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y 232// FIXME: Provide proper encoding! 233def AND32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 234 "nr\t{$dst, $src2}", 235 [(set GR32:$dst, (and GR32:$src1, GR32:$src2))]>; 236def AND64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 237 "ngr\t{$dst, $src2}", 238 [(set GR64:$dst, (and GR64:$src1, GR64:$src2))]>; 239} 240 241// FIXME: Provide proper encoding! 242def AND64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 243 "nill\t{$dst, $src2}", 244 [(set GR64:$dst, (and GR64:$src1, i64ll16:$src2))]>; 245def AND64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 246 "nilh\t{$dst, $src2}", 247 [(set GR64:$dst, (and GR64:$src1, i64lh16:$src2))]>; 248def AND64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 249 "nihl\t{$dst, $src2}", 250 [(set GR64:$dst, (and GR64:$src1, i64hl16:$src2))]>; 251def AND64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 252 "nihh\t{$dst, $src2}", 253 [(set GR64:$dst, (and GR64:$src1, i64hh16:$src2))]>; 254// FIXME: these 2 instructions seem to require extimm facility 255def AND64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 256 "nilf\t{$dst, $src2}", 257 [(set GR64:$dst, (and GR64:$src1, i64lo32:$src2))]>; 258def AND64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 259 "nihf\t{$dst, $src2}", 260 [(set GR64:$dst, (and GR64:$src1, i64hi32:$src2))]>; 261 262let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y 263// FIXME: Provide proper encoding! 264def OR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 265 "or\t{$dst, $src2}", 266 [(set GR32:$dst, (or GR32:$src1, GR32:$src2))]>; 267def OR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 268 "ogr\t{$dst, $src2}", 269 [(set GR64:$dst, (or GR64:$src1, GR64:$src2))]>; 270} 271 272def OR32ri16 : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2), 273 "oill\t{$dst, $src2}", 274 [(set GR32:$dst, (or GR32:$src1, i64ll16:$src2))]>; 275def OR32ri16h : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i16imm:$src2), 276 "oilh\t{$dst, $src2}", 277 [(set GR32:$dst, (or GR32:$src1, i64lh16:$src2))]>; 278def OR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 279 "oilf\t{$dst, $src2}", 280 [(set GR32:$dst, (or GR32:$src1, imm:$src2))]>; 281 282def OR64rill16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 283 "oill\t{$dst, $src2}", 284 [(set GR64:$dst, (or GR64:$src1, i64ll16:$src2))]>; 285def OR64rilh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 286 "oilh\t{$dst, $src2}", 287 [(set GR64:$dst, (or GR64:$src1, i64lh16:$src2))]>; 288def OR64rihl16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 289 "oihl\t{$dst, $src2}", 290 [(set GR64:$dst, (or GR64:$src1, i64hl16:$src2))]>; 291def OR64rihh16 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 292 "oihh\t{$dst, $src2}", 293 [(set GR64:$dst, (or GR64:$src1, i64hh16:$src2))]>; 294// FIXME: these 2 instructions seem to require extimm facility 295def OR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 296 "oilf\t{$dst, $src2}", 297 [(set GR64:$dst, (or GR64:$src1, i64lo32:$src2))]>; 298def OR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 299 "oihf\t{$dst, $src2}", 300 [(set GR64:$dst, (or GR64:$src1, i64hi32:$src2))]>; 301 302// FIXME: Provide proper encoding! 303def SUB32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 304 "sr\t{$dst, $src2}", 305 [(set GR32:$dst, (sub GR32:$src1, GR32:$src2))]>; 306def SUB64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 307 "sgr\t{$dst, $src2}", 308 [(set GR64:$dst, (sub GR64:$src1, GR64:$src2))]>; 309 310 311let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y 312// FIXME: Provide proper encoding! 313def XOR32rr : Pseudo<(outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 314 "xr\t{$dst, $src2}", 315 [(set GR32:$dst, (xor GR32:$src1, GR32:$src2))]>; 316def XOR64rr : Pseudo<(outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 317 "xgr\t{$dst, $src2}", 318 [(set GR64:$dst, (xor GR64:$src1, GR64:$src2))]>; 319} 320 321def XOR32ri : Pseudo<(outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 322 "xilf\t{$dst, $src2}", 323 [(set GR32:$dst, (xor GR32:$src1, imm:$src2))]>; 324 325// FIXME: these 2 instructions seem to require extimm facility 326def XOR64rilo32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 327 "xilf\t{$dst, $src2}", 328 [(set GR64:$dst, (xor GR64:$src1, i64lo32:$src2))]>; 329def XOR64rihi32 : Pseudo<(outs GR64:$dst), (ins GR64:$src1, i64imm:$src2), 330 "xihf\t{$dst, $src2}", 331 [(set GR64:$dst, (xor GR64:$src1, i64hi32:$src2))]>; 332 333} // Defs = [PSW] 334} // isTwoAddress = 1 335 336//===----------------------------------------------------------------------===// 337// Shifts 338 339let isTwoAddress = 1 in 340def SRL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt), 341 "srl\t{$src, $amt}", 342 [(set GR32:$dst, (srl GR32:$src, riaddr32:$amt))]>; 343def SRL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt), 344 "srlg\t{$dst, $src, $amt}", 345 [(set GR64:$dst, (srl GR64:$src, (i32 (trunc riaddr:$amt))))]>; 346def SRLA64ri : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt), 347 "srlg\t{$dst, $src, $amt}", 348 [(set GR64:$dst, (srl GR64:$src, (i32 imm:$amt)))]>; 349 350let isTwoAddress = 1 in 351def SHL32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt), 352 "sll\t{$src, $amt}", 353 [(set GR32:$dst, (shl GR32:$src, riaddr32:$amt))]>; 354def SHL64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt), 355 "sllg\t{$dst, $src, $amt}", 356 [(set GR64:$dst, (shl GR64:$src, (i32 (trunc riaddr:$amt))))]>; 357def SHL64ri : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt), 358 "sllg\t{$dst, $src, $amt}", 359 [(set GR64:$dst, (shl GR64:$src, (i32 imm:$amt)))]>; 360 361 362let Defs = [PSW] in { 363let isTwoAddress = 1 in 364def SRA32rri : Pseudo<(outs GR32:$dst), (ins GR32:$src, riaddr32:$amt), 365 "sra\t{$src, $amt}", 366 [(set GR32:$dst, (sra GR32:$src, riaddr32:$amt)), 367 (implicit PSW)]>; 368def SRA64rri : Pseudo<(outs GR64:$dst), (ins GR64:$src, riaddr:$amt), 369 "srag\t{$dst, $src, $amt}", 370 [(set GR64:$dst, (sra GR64:$src, (i32 (trunc riaddr:$amt)))), 371 (implicit PSW)]>; 372def SRA64ri : Pseudo<(outs GR64:$dst), (ins GR64:$src, i32imm:$amt), 373 "srag\t{$dst, $src, $amt}", 374 [(set GR64:$dst, (sra GR64:$src, (i32 imm:$amt))), 375 (implicit PSW)]>; 376} // Defs = [PSW] 377 378//===----------------------------------------------------------------------===// 379// Non-Instruction Patterns. 380//===----------------------------------------------------------------------===// 381 382// anyext 383def : Pat<(i64 (anyext GR32:$src)), 384 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>; 385 386//===----------------------------------------------------------------------===// 387// Peepholes. 388//===----------------------------------------------------------------------===// 389 390// FIXME: use add/sub tricks with 32678/-32768 391 392// trunc patterns 393def : Pat<(i32 (trunc GR64:$src)), 394 (EXTRACT_SUBREG GR64:$src, subreg_32bit)>; 395 396// sext_inreg patterns 397def : Pat<(sext_inreg GR64:$src, i32), 398 (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>; 399