SystemZISelLowering.cpp revision 5fb8d3144fa5da2b8392b56136163809d8df0527
11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZISelLowering.cpp - SystemZ DAG lowering implementation -----===// 21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The LLVM Compiler Infrastructure 41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source 61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details. 71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file implements the SystemZTargetLowering class. 111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define DEBUG_TYPE "systemz-lower" 151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZISelLowering.h" 171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZCallingConv.h" 181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZConstantPoolValue.h" 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZMachineFunctionInfo.h" 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZTargetMachine.h" 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/CallingConvLower.h" 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/MachineInstrBuilder.h" 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/MachineRegisterInfo.h" 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Classify VT as either 32 or 64 bit. 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool is32Bit(EVT VT) { 301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (VT.getSimpleVT().SimpleTy) { 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i32: 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i64: 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported type"); 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return a version of MachineOperand that can be safely used before the 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// final use. 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic MachineOperand earlyUseOperand(MachineOperand Op) { 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op.isReg()) 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.setIsKill(false); 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : TargetLowering(tm, new TargetLoweringObjectFileELF()), 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Subtarget(*tm.getSubtargetImpl()), TM(tm) { 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT PtrVT = getPointerTy(); 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up the register classes. 5455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (Subtarget.hasHighWord()) 5555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford addRegisterClass(MVT::i32, &SystemZ::GRX32BitRegClass); 5655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford else 5755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford addRegisterClass(MVT::i32, &SystemZ::GR32BitRegClass); 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::i64, &SystemZ::GR64BitRegClass); 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::f32, &SystemZ::FP32BitRegClass); 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::f64, &SystemZ::FP64BitRegClass); 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::f128, &SystemZ::FP128BitRegClass); 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Compute derived properties from the register classes 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand computeRegisterProperties(); 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up special registers. 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setExceptionPointerRegister(SystemZ::R6D); 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setExceptionSelectorRegister(SystemZ::R7D); 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setStackPointerRegisterToSaveRestore(SystemZ::R15D); 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // TODO: It may be better to default to latency-oriented scheduling, however 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LLVM's current latency-oriented scheduler can't handle physreg definitions 73dbd8eb26ce1e7de9b69f5c46f45ba011a706c9b9Richard Sandiford // such as SystemZ has with CC, so set this to the register-pressure 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // scheduler, because it can. 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setSchedulingPreference(Sched::RegPressure); 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setBooleanContents(ZeroOrOneBooleanContent); 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Instructions are strings of 2-byte aligned 2-byte values. 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setMinFunctionAlignment(2); 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle operations that are handled in a similar way for all types. 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE; 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I <= MVT::LAST_FP_VALUETYPE; 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++I) { 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT VT = MVT::SimpleValueType(I); 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isTypeLegal(VT)) { 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand SETCC(X, Y, COND) into SELECT_CC(X, Y, 1, 0, COND). 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SETCC, VT, Expand); 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand SELECT(C, A, B) into SELECT_CC(X, 0, A, B, NE). 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SELECT, VT, Expand); 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower SELECT_CC and BR_CC into separate comparisons and branches. 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SELECT_CC, VT, Custom); 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BR_CC, VT, Custom); 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand jump table branches as address arithmetic followed by an 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // indirect jump. 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BR_JT, MVT::Other, Expand); 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand BRCOND into a BR_CC (see above). 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle integer types. 1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE; 1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I <= MVT::LAST_INTEGER_VALUETYPE; 1111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++I) { 1121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT VT = MVT::SimpleValueType(I); 1131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isTypeLegal(VT)) { 1141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand individual DIV and REMs into DIVREMs. 1151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SDIV, VT, Expand); 1161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UDIV, VT, Expand); 1171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SREM, VT, Expand); 1181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UREM, VT, Expand); 1191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SDIVREM, VT, Custom); 1201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UDIVREM, VT, Custom); 1211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand ATOMIC_LOAD and ATOMIC_STORE using ATOMIC_CMP_SWAP. 1231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: probably much too conservative. 1241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD, VT, Expand); 1251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_STORE, VT, Expand); 1261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // No special instructions for these. 1281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTPOP, VT, Expand); 1291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTTZ, VT, Expand); 1301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTTZ_ZERO_UNDEF, VT, Expand); 1311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTLZ_ZERO_UNDEF, VT, Expand); 1321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ROTR, VT, Expand); 1331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 134df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Use *MUL_LOHI where possible instead of MULH*. 1351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::MULHS, VT, Expand); 1361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::MULHU, VT, Expand); 137df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford setOperationAction(ISD::SMUL_LOHI, VT, Custom); 138df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford setOperationAction(ISD::UMUL_LOHI, VT, Custom); 1391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have instructions for signed but not unsigned FP conversion. 1411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FP_TO_UINT, VT, Expand); 1421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Type legalization will convert 8- and 16-bit atomic operations into 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // forms that operate on i32s (but still keeping the original memory VT). 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower them into full i32 operations. 1481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Custom); 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, Custom); 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i32, Custom); 1511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, Custom); 1521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, Custom); 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, Custom); 1541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, Custom); 1551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i32, Custom); 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i32, Custom); 1571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, Custom); 1581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, Custom); 1591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Custom); 1601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have instructions for signed but not unsigned FP conversion. 1621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle unsigned 32-bit types as signed 64-bit types. 1631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); 1641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 1651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have native support for a 64-bit CTLZ, via FLOGR. 1671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTLZ, MVT::i32, Promote); 1681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTLZ, MVT::i64, Legal); 1691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Give LowerOperation the chance to replace 64-bit ORs with subregs. 1711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::OR, MVT::i64, Custom); 1721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: Can we support these natively? 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand); 1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand); 1761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand); 1771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have native instructions for i8, i16 and i32 extensions, but not i1. 1791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 1801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 1811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle the various types of symbolic address. 1851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ConstantPool, PtrVT, Custom); 1861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::GlobalAddress, PtrVT, Custom); 1871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom); 1881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BlockAddress, PtrVT, Custom); 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::JumpTable, PtrVT, Custom); 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We need to handle dynamic allocations specially because of the 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 160-byte area at the bottom of the stack. 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); 1941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use custom expanders so that we can force the function to use 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // a frame pointer. 1971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::STACKSAVE, MVT::Other, Custom); 1981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::STACKRESTORE, MVT::Other, Custom); 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 200a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford // Handle prefetches with PFD or PFDRL. 201a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford setOperationAction(ISD::PREFETCH, MVT::Other, Custom); 202a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford 2031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle floating-point types. 2041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = MVT::FIRST_FP_VALUETYPE; 2051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I <= MVT::LAST_FP_VALUETYPE; 2061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++I) { 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT VT = MVT::SimpleValueType(I); 2081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isTypeLegal(VT)) { 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We can use FI for FRINT. 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FRINT, VT, Legal); 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 212d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford // We can use the extended form of FI for other rounding operations. 213d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford if (Subtarget.hasFPExtension()) { 214d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FNEARBYINT, VT, Legal); 215d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FFLOOR, VT, Legal); 216d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FCEIL, VT, Legal); 217d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FTRUNC, VT, Legal); 218d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FROUND, VT, Legal); 219d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford } 220d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford 2211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // No special instructions for these. 2221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FSIN, VT, Expand); 2231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FCOS, VT, Expand); 2241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FREM, VT, Expand); 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have fused multiply-addition for f32 and f64 but not f128. 2291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FMA, MVT::f32, Legal); 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FMA, MVT::f64, Legal); 2311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FMA, MVT::f128, Expand); 2321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Needed so that we don't try to implement f128 constant loads using 2341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // a load-and-extend of a f80 constant (in cases where the constant 2351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // would fit in an f80). 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::EXTLOAD, MVT::f80, Expand); 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Floating-point truncation and stores need to be done separately. 2391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setTruncStoreAction(MVT::f64, MVT::f32, Expand); 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setTruncStoreAction(MVT::f128, MVT::f32, Expand); 2411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setTruncStoreAction(MVT::f128, MVT::f64, Expand); 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have 64-bit FPR<->GPR moves, but need special handling for 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 32-bit forms. 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BITCAST, MVT::i32, Custom); 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BITCAST, MVT::f32, Custom); 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // VASTART and VACOPY need to deal with the SystemZ-specific varargs 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // structure, but VAEND is a no-op. 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::VASTART, MVT::Other, Custom); 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::VACOPY, MVT::Other, Custom); 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::VAEND, MVT::Other, Expand); 253dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 254dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford // We want to use MVC in preference to even a single load/store pair. 255dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MaxStoresPerMemcpy = 0; 256dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MaxStoresPerMemcpyOptSize = 0; 257f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford 258f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // The main memset sequence is a byte store followed by an MVC. 259f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // Two STC or MV..I stores win over that, but the kind of fused stores 260f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // generated by target-independent code don't when the byte value is 261f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // variable. E.g. "STC <reg>;MHI <reg>,257;STH <reg>" is not better 262f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // than "STC;MVC". Handle the choice in target-specific code instead. 263f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford MaxStoresPerMemset = 0; 264f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford MaxStoresPerMemsetOptSize = 0; 2651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 267e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Linbool 268e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen LinSystemZTargetLowering::isFMAFasterThanFMulAndFAdd(EVT VT) const { 269e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin VT = VT.getScalarType(); 270e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 271e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin if (!VT.isSimple()) 272e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return false; 273e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 274e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin switch (VT.getSimpleVT().SimpleTy) { 275e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin case MVT::f32: 276e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin case MVT::f64: 277e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return true; 278e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin case MVT::f128: 279e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return false; 280e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin default: 281e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin break; 282e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin } 283e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 284e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return false; 285e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin} 286e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 2871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We can load zero using LZ?R and negative zero using LZ?R;LC?BR. 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Imm.isZero() || Imm.isNegZero(); 2901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29214a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandifordbool SystemZTargetLowering::allowsUnalignedMemoryAccesses(EVT VT, 29314a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford bool *Fast) const { 29414a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford // Unaligned accesses should never be slower than the expanded version. 29514a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford // We check specifically for aligned accesses in the few cases where 29614a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford // they are required. 29714a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford if (Fast) 29814a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford *Fast = true; 29914a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford return true; 30014a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford} 30114a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford 30204ded924f3583438c6633823eddb87761fa73cceRichard Sandifordbool SystemZTargetLowering::isLegalAddressingMode(const AddrMode &AM, 30304ded924f3583438c6633823eddb87761fa73cceRichard Sandiford Type *Ty) const { 30404ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // Punt on globals for now, although they can be used in limited 30504ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // RELATIVE LONG cases. 30604ded924f3583438c6633823eddb87761fa73cceRichard Sandiford if (AM.BaseGV) 30704ded924f3583438c6633823eddb87761fa73cceRichard Sandiford return false; 30804ded924f3583438c6633823eddb87761fa73cceRichard Sandiford 30904ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // Require a 20-bit signed offset. 31004ded924f3583438c6633823eddb87761fa73cceRichard Sandiford if (!isInt<20>(AM.BaseOffs)) 31104ded924f3583438c6633823eddb87761fa73cceRichard Sandiford return false; 31204ded924f3583438c6633823eddb87761fa73cceRichard Sandiford 31304ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // Indexing is OK but no scale factor can be applied. 31404ded924f3583438c6633823eddb87761fa73cceRichard Sandiford return AM.Scale == 0 || AM.Scale == 1; 31504ded924f3583438c6633823eddb87761fa73cceRichard Sandiford} 31604ded924f3583438c6633823eddb87761fa73cceRichard Sandiford 31780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::isTruncateFree(Type *FromType, Type *ToType) const { 31880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!FromType->isIntegerTy() || !ToType->isIntegerTy()) 31980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 32080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned FromBits = FromType->getPrimitiveSizeInBits(); 32180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned ToBits = ToType->getPrimitiveSizeInBits(); 32280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return FromBits > ToBits; 32380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 32480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 32580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::isTruncateFree(EVT FromVT, EVT ToVT) const { 32680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!FromVT.isInteger() || !ToVT.isInteger()) 32780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 32880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned FromBits = FromVT.getSizeInBits(); 32980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned ToBits = ToVT.getSizeInBits(); 33080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return FromBits > ToBits; 33180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 33280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 3331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 3341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Inline asm support 3351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandTargetLowering::ConstraintType 3381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::getConstraintType(const std::string &Constraint) const { 3391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Constraint.size() == 1) { 3401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Constraint[0]) { 3411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'a': // Address register 3421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'd': // Data register (equivalent to 'r') 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'f': // Floating-point register 34455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case 'h': // High-part register 3451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'r': // General-purpose register 3461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return C_RegisterClass; 3471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'Q': // Memory with base and unsigned 12-bit displacement 3491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'R': // Likewise, plus an index 3501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'S': // Memory with base and signed 20-bit displacement 3511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'T': // Likewise, plus an index 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'm': // Equivalent to 'T'. 3531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return C_Memory; 3541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'I': // Unsigned 8-bit constant 3561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'J': // Unsigned 12-bit constant 3571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'K': // Signed 16-bit constant 3581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'L': // Signed 20-bit displacement (on all targets we support) 3591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'M': // 0x7fffffff 3601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return C_Other; 3611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 3631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return TargetLowering::getConstraintType(Constraint); 3671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandTargetLowering::ConstraintWeight SystemZTargetLowering:: 3701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandgetSingleConstraintMatchWeight(AsmOperandInfo &info, 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const char *constraint) const { 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ConstraintWeight weight = CW_Invalid; 3731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value *CallOperandVal = info.CallOperandVal; 3741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If we don't have a value, we can't do a match, 3751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // but allow it at the lowest weight. 3761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CallOperandVal == NULL) 3771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return CW_Default; 3781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Type *type = CallOperandVal->getType(); 3791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Look at the constraint type. 3801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (*constraint) { 3811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 3821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); 3831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'a': // Address register 3861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'd': // Data register (equivalent to 'r') 38755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case 'h': // High-part register 3881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'r': // General-purpose register 3891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CallOperandVal->getType()->isIntegerTy()) 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Register; 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'f': // Floating-point register 3941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (type->isFloatingPointTy()) 3951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Register; 3961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'I': // Unsigned 8-bit constant 3991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<8>(C->getZExtValue())) 4011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'J': // Unsigned 12-bit constant 4051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(C->getZExtValue())) 4071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'K': // Signed 16-bit constant 4111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(C->getSExtValue())) 4131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'L': // Signed 20-bit displacement (on all targets we support) 4171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(C->getSExtValue())) 4191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'M': // 0x7fffffff 4231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (C->getZExtValue() == 0x7fffffff) 4251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return weight; 4291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4315e009541973b7935386055066689902aa7134e2dRichard Sandiford// Parse a "{tNNN}" register constraint for which the register type "t" 4325e009541973b7935386055066689902aa7134e2dRichard Sandiford// has already been verified. MC is the class associated with "t" and 4335e009541973b7935386055066689902aa7134e2dRichard Sandiford// Map maps 0-based register numbers to LLVM register numbers. 4345e009541973b7935386055066689902aa7134e2dRichard Sandifordstatic std::pair<unsigned, const TargetRegisterClass *> 4355e009541973b7935386055066689902aa7134e2dRichard SandifordparseRegisterNumber(const std::string &Constraint, 4365e009541973b7935386055066689902aa7134e2dRichard Sandiford const TargetRegisterClass *RC, const unsigned *Map) { 4375e009541973b7935386055066689902aa7134e2dRichard Sandiford assert(*(Constraint.end()-1) == '}' && "Missing '}'"); 4385e009541973b7935386055066689902aa7134e2dRichard Sandiford if (isdigit(Constraint[2])) { 4395e009541973b7935386055066689902aa7134e2dRichard Sandiford std::string Suffix(Constraint.data() + 2, Constraint.size() - 2); 4405e009541973b7935386055066689902aa7134e2dRichard Sandiford unsigned Index = atoi(Suffix.c_str()); 4415e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Index < 16 && Map[Index]) 4425e009541973b7935386055066689902aa7134e2dRichard Sandiford return std::make_pair(Map[Index], RC); 4435e009541973b7935386055066689902aa7134e2dRichard Sandiford } 4445e009541973b7935386055066689902aa7134e2dRichard Sandiford return std::make_pair(0u, static_cast<TargetRegisterClass*>(0)); 4455e009541973b7935386055066689902aa7134e2dRichard Sandiford} 4465e009541973b7935386055066689902aa7134e2dRichard Sandiford 4471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstd::pair<unsigned, const TargetRegisterClass *> SystemZTargetLowering:: 4485b3fca50a08865f0db55fc92ad1c037a04e12177Chad RosiergetRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const { 4491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Constraint.size() == 1) { 4501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // GCC Constraint Letters 4511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Constraint[0]) { 4521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: break; 4531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'd': // Data register (equivalent to 'r') 4541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'r': // General-purpose register 4551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VT == MVT::i64) 4561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::GR64BitRegClass); 4571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VT == MVT::i128) 4581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::GR128BitRegClass); 4591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::GR32BitRegClass); 4601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'a': // Address register 4621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VT == MVT::i64) 4631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::ADDR64BitRegClass); 4641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VT == MVT::i128) 4651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::ADDR128BitRegClass); 4661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::ADDR32BitRegClass); 4671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 46855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case 'h': // High-part register (an LLVM extension) 46955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return std::make_pair(0U, &SystemZ::GRH32BitRegClass); 47055d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 4711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'f': // Floating-point register 4721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VT == MVT::f64) 4731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::FP64BitRegClass); 4741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VT == MVT::f128) 4751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::FP128BitRegClass); 4761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::FP32BitRegClass); 4771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4795e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Constraint[0] == '{') { 4805e009541973b7935386055066689902aa7134e2dRichard Sandiford // We need to override the default register parsing for GPRs and FPRs 4815e009541973b7935386055066689902aa7134e2dRichard Sandiford // because the interpretation depends on VT. The internal names of 4825e009541973b7935386055066689902aa7134e2dRichard Sandiford // the registers are also different from the external names 4835e009541973b7935386055066689902aa7134e2dRichard Sandiford // (F0D and F0S instead of F0, etc.). 4845e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Constraint[1] == 'r') { 4855e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::i32) 4865e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::GR32BitRegClass, 4875e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::GR32Regs); 4885e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::i128) 4895e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::GR128BitRegClass, 4905e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::GR128Regs); 4915e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::GR64BitRegClass, 4925e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::GR64Regs); 4935e009541973b7935386055066689902aa7134e2dRichard Sandiford } 4945e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Constraint[1] == 'f') { 4955e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::f32) 4965e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::FP32BitRegClass, 4975e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::FP32Regs); 4985e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::f128) 4995e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::FP128BitRegClass, 5005e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::FP128Regs); 5015e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::FP64BitRegClass, 5025e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::FP64Regs); 5035e009541973b7935386055066689902aa7134e2dRichard Sandiford } 5045e009541973b7935386055066689902aa7134e2dRichard Sandiford } 5051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 5061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZTargetLowering:: 5091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandLowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, 5101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand std::vector<SDValue> &Ops, 5111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 5121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Only support length 1 constraints for now. 5131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Constraint.length() == 1) { 5141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Constraint[0]) { 5151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'I': // Unsigned 8-bit constant 5161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<8>(C->getZExtValue())) 5181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), 5191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'J': // Unsigned 12-bit constant 5231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(C->getZExtValue())) 5251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), 5261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'K': // Signed 16-bit constant 5301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(C->getSExtValue())) 5321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getSExtValue(), 5331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'L': // Signed 20-bit displacement (on all targets we support) 5371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(C->getSExtValue())) 5391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getSExtValue(), 5401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'M': // 0x7fffffff 5441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (C->getZExtValue() == 0x7fffffff) 5461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), 5471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); 5521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 5551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Calling conventions 5561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 5571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZGenCallingConv.inc" 5591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 56080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::allowTruncateForTailCall(Type *FromType, 56180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Type *ToType) const { 56280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return isTruncateFree(FromType, ToType); 56380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 56480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 56580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { 56680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!CI->isTailCall()) 56780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 56880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return true; 56980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 57080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 5711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Value is a value that has been passed to us in the location described by VA 5721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// (and so has type VA.getLocVT()). Convert Value to VA.getValVT(), chaining 5731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// any loads onto Chain. 574ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue convertLocVTToValVT(SelectionDAG &DAG, SDLoc DL, 5751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA, SDValue Chain, 5761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Value) { 5771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the argument has been promoted from a smaller type, insert an 5781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // assertion to capture this. 5791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocInfo() == CCValAssign::SExt) 5801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Value, 5811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getValueType(VA.getValVT())); 5821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VA.getLocInfo() == CCValAssign::ZExt) 5831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Value, 5841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getValueType(VA.getValVT())); 5851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.isExtInLoc()) 5871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Value); 5881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VA.getLocInfo() == CCValAssign::Indirect) 5891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getLoad(VA.getValVT(), DL, Chain, Value, 5901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(), false, false, false, 0); 5911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 5921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.getLocInfo() == CCValAssign::Full && "Unsupported getLocInfo"); 5931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Value; 5941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Value is a value of type VA.getValVT() that we need to copy into 5971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the location described by VA. Return a copy of Value converted to 5981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// VA.getValVT(). The caller is responsible for handling indirect values. 599ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue convertValVTToLocVT(SelectionDAG &DAG, SDLoc DL, 6001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA, SDValue Value) { 6011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (VA.getLocInfo()) { 6021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::SExt: 6031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Value); 6041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::ZExt: 6051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Value); 6061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::AExt: 6071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Value); 6081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::Full: 6091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Value; 6101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 6111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unhandled getLocInfo()"); 6121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering:: 6161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandLowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 6171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<ISD::InputArg> &Ins, 618ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG, 6191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<SDValue> &InVals) const { 6201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 6211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFI = MF.getFrameInfo(); 6221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 6231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *FuncInfo = 6241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>(); 6251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZFrameLowering *TFL = 6261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand static_cast<const SystemZFrameLowering *>(TM.getFrameLowering()); 6271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Assign locations to all of the incoming arguments. 6291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> ArgLocs; 6301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState CCInfo(CallConv, IsVarArg, MF, TM, ArgLocs, *DAG.getContext()); 6311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCInfo.AnalyzeFormalArguments(Ins, CC_SystemZ); 6321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumFixedGPRs = 0; 6341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumFixedFPRs = 0; 6351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { 6361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgValue; 6371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = ArgLocs[I]; 6381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT LocVT = VA.getLocVT(); 6391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.isRegLoc()) { 6401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Arguments passed in registers 6411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC; 6421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (LocVT.getSimpleVT().SimpleTy) { 6431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 6441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Integers smaller than i64 should be promoted to i64. 6451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected argument type"); 6461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i32: 6471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedGPRs += 1; 6481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::GR32BitRegClass; 6491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i64: 6511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedGPRs += 1; 6521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::GR64BitRegClass; 6531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::f32: 6551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedFPRs += 1; 6561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::FP32BitRegClass; 6571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::f64: 6591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedFPRs += 1; 6601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::FP64BitRegClass; 6611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned VReg = MRI.createVirtualRegister(RC); 6651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.addLiveIn(VA.getLocReg(), VReg); 6661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, LocVT); 6671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 6681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.isMemLoc() && "Argument not register or memory"); 6691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create the frame index object for this incoming parameter. 6711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FI = MFI->CreateFixedObject(LocVT.getSizeInBits() / 8, 6721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand VA.getLocMemOffset(), true); 6731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create the SelectionDAG nodes corresponding to a load 6751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // from this parameter. Unpromoted ints and floats are 6761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // passed as right-justified 8-byte values. 6771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 6781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FIN = DAG.getFrameIndex(FI, PtrVT); 6791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32) 6801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FIN = DAG.getNode(ISD::ADD, DL, PtrVT, FIN, DAG.getIntPtrConstant(4)); 6811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = DAG.getLoad(LocVT, DL, Chain, FIN, 6821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getFixedStack(FI), 6831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, false, 0); 6841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Convert the value of the argument register into the value that's 6871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // being passed. 6881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue)); 6891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsVarArg) { 6921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Save the number of non-varargs registers for later use by va_start, etc. 6931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setVarArgsFirstGPR(NumFixedGPRs); 6941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setVarArgsFirstFPR(NumFixedFPRs); 6951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Likewise the address (in the form of a frame index) of where the 6971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // first stack vararg would be. The 1-byte size here is arbitrary. 6981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t StackSize = CCInfo.getNextStackOffset(); 6991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, StackSize, true)); 7001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ...and a similar frame index for the caller-allocated save area 7021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // that will be used to store the incoming registers. 7031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t RegSaveOffset = TFL->getOffsetOfLocalArea(); 7041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RegSaveIndex = MFI->CreateFixedObject(1, RegSaveOffset, true); 7051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setRegSaveFrameIndex(RegSaveIndex); 7061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Store the FPR varargs in the reserved frame slots. (We store the 7081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // GPRs as part of the prologue.) 7091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NumFixedFPRs < SystemZ::NumArgFPRs) { 7101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue MemOps[SystemZ::NumArgFPRs]; 7111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = NumFixedFPRs; I < SystemZ::NumArgFPRs; ++I) { 7121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = TFL->getRegSpillOffset(SystemZ::ArgFPRs[I]); 7131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FI = MFI->CreateFixedObject(8, RegSaveOffset + Offset, true); 7141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); 7151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned VReg = MF.addLiveIn(SystemZ::ArgFPRs[I], 7161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::FP64BitRegClass); 7171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, MVT::f64); 7181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOps[I] = DAG.getStore(ArgValue.getValue(1), DL, ArgValue, FIN, 7191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getFixedStack(FI), 7201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0); 7211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Join the stores, which are independent of one another. 7241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, 7251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &MemOps[NumFixedFPRs], 7261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::NumArgFPRs - NumFixedFPRs); 7271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Chain; 7311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 7321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 73380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordstatic bool canUseSiblingCall(CCState ArgCCInfo, 73480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford SmallVectorImpl<CCValAssign> &ArgLocs) { 73580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // Punt if there are any indirect or stack arguments, or if the call 73680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // needs the call-saved argument register R6. 73780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { 73880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford CCValAssign &VA = ArgLocs[I]; 73980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (VA.getLocInfo() == CCValAssign::Indirect) 74080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 74180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!VA.isRegLoc()) 74280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 74380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned Reg = VA.getLocReg(); 74455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (Reg == SystemZ::R6H || Reg == SystemZ::R6L || Reg == SystemZ::R6D) 74580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 74680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford } 74780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return true; 74880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 74980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 7501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue 7511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, 7521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<SDValue> &InVals) const { 7531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG = CLI.DAG; 754ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &DL = CLI.DL; 755a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 756a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 757a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 7581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = CLI.Chain; 7591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Callee = CLI.Callee; 76080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford bool &IsTailCall = CLI.IsTailCall; 7611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CallingConv::ID CallConv = CLI.CallConv; 7621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsVarArg = CLI.IsVarArg; 7631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 7641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 7651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Analyze the operands of the call, assigning locations to each operand. 7671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> ArgLocs; 7681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState ArgCCInfo(CallConv, IsVarArg, MF, TM, ArgLocs, *DAG.getContext()); 7691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgCCInfo.AnalyzeCallOperands(Outs, CC_SystemZ); 7701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 77180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // We don't support GuaranteedTailCallOpt, only automatically-detected 77280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // sibling calls. 77380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (IsTailCall && !canUseSiblingCall(ArgCCInfo, ArgLocs)) 77480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford IsTailCall = false; 77580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 7761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get a count of how many bytes are to be pushed on the stack. 7771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumBytes = ArgCCInfo.getNextStackOffset(); 7781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Mark the start of the call. 78080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!IsTailCall) 78180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes, PtrVT, true), 78280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford DL); 7831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy argument values to their designated locations. 7851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<std::pair<unsigned, SDValue>, 9> RegsToPass; 7861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<SDValue, 8> MemOpChains; 7871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue StackPtr; 7881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { 7891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = ArgLocs[I]; 7901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgValue = OutVals[I]; 7911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocInfo() == CCValAssign::Indirect) { 7931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Store the argument in a stack slot and pass its address. 7941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT()); 7951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); 7961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOpChains.push_back(DAG.getStore(Chain, DL, ArgValue, SpillSlot, 7971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getFixedStack(FI), 7981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0)); 7991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = SpillSlot; 8001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 8011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = convertValVTToLocVT(DAG, DL, VA, ArgValue); 8021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.isRegLoc()) 8041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Queue up the argument copies and emit them at the end. 8051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue)); 8061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else { 8071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.isMemLoc() && "Argument not register or memory"); 8081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Work out the address of the stack slot. Unpromoted ints and 8101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // floats are passed as right-justified 8-byte values. 8111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!StackPtr.getNode()) 8121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StackPtr = DAG.getCopyFromReg(Chain, DL, SystemZ::R15D, PtrVT); 8131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = SystemZMC::CallFrameSize + VA.getLocMemOffset(); 8141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32) 8151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset += 4; 8161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, 8171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getIntPtrConstant(Offset)); 8181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Emit the store. 8201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOpChains.push_back(DAG.getStore(Chain, DL, ArgValue, Address, 8211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(), 8221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0)); 8231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 8241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 8251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Join the stores, which are independent of one another. 8271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!MemOpChains.empty()) 8281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, 8291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &MemOpChains[0], MemOpChains.size()); 8301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Accept direct calls by converting symbolic call addresses to the 83280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // associated Target* opcodes. Force %r1 to be used for indirect 83380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // tail calls. 83480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford SDValue Glue; 8351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { 8361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT); 8371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee); 8381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) { 8391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT); 8401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee); 84180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford } else if (IsTailCall) { 84280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R1D, Callee, Glue); 84380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Glue = Chain.getValue(1); 84480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Callee = DAG.getRegister(SystemZ::R1D, Callee.getValueType()); 84580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford } 84680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 84780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // Build a sequence of copy-to-reg nodes, chained and glued together. 84880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) { 84980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[I].first, 85080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford RegsToPass[I].second, Glue); 85180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Glue = Chain.getValue(1); 8521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 8531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The first call operand is the chain and the second is the target address. 8551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<SDValue, 8> Ops; 8561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Chain); 8571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Callee); 8581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add argument registers to the end of the list so that they are 8601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // known live into the call. 8611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) 8621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getRegister(RegsToPass[I].first, 8631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RegsToPass[I].second.getValueType())); 8641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Glue the call to the argument copies, if any. 8661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Glue.getNode()) 8671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Glue); 8681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Emit the call. 8701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 87180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (IsTailCall) 87280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return DAG.getNode(SystemZISD::SIBCALL, DL, NodeTys, &Ops[0], Ops.size()); 8731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getNode(SystemZISD::CALL, DL, NodeTys, &Ops[0], Ops.size()); 8741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = Chain.getValue(1); 8751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Mark the end of the call, which is glued to the call itself. 8771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getCALLSEQ_END(Chain, 8781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(NumBytes, PtrVT, true), 8791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, PtrVT, true), 8806e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick Glue, DL); 8811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = Chain.getValue(1); 8821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Assign locations to each value returned by this call. 8841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> RetLocs; 8851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState RetCCInfo(CallConv, IsVarArg, MF, TM, RetLocs, *DAG.getContext()); 8861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetCCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ); 8871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy all of the result registers out of their specified physreg. 8891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) { 8901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = RetLocs[I]; 8911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy the value out, gluing the copy to the end of the call sequence. 8931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue RetValue = DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), 8941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand VA.getLocVT(), Glue); 8951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = RetValue.getValue(1); 8961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = RetValue.getValue(2); 8971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Convert the value of the return register into the value that's 8991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // being returned. 9001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, RetValue)); 9011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 9021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Chain; 9041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue 9071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::LowerReturn(SDValue Chain, 9081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CallingConv::ID CallConv, bool IsVarArg, 9091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<ISD::OutputArg> &Outs, 9101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<SDValue> &OutVals, 911ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 9121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 9131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Assign locations to each returned value. 9151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> RetLocs; 9161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState RetCCInfo(CallConv, IsVarArg, MF, TM, RetLocs, *DAG.getContext()); 9171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetCCInfo.AnalyzeReturn(Outs, RetCC_SystemZ); 9181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Quick exit for void returns 9201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (RetLocs.empty()) 9211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::RET_FLAG, DL, MVT::Other, Chain); 9221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy the result values into the output registers. 9241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Glue; 9251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<SDValue, 4> RetOps; 9261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.push_back(Chain); 9271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) { 9281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = RetLocs[I]; 9291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue RetValue = OutVals[I]; 9301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make the return register live on exit. 9321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.isRegLoc() && "Can only return in registers!"); 9331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Promote the value as required. 9351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetValue = convertValVTToLocVT(DAG, DL, VA, RetValue); 9361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Chain and glue the copies together. 9381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = VA.getLocReg(); 9391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getCopyToReg(Chain, DL, Reg, RetValue, Glue); 9401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = Chain.getValue(1); 9411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.push_back(DAG.getRegister(Reg, VA.getLocVT())); 9421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 9431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Update chain and glue. 9451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps[0] = Chain; 9461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Glue.getNode()) 9471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.push_back(Glue); 9481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::RET_FLAG, DL, MVT::Other, 9501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.data(), RetOps.size()); 9511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// CC is a comparison that will be implemented using an integer or 9541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// floating-point comparison. Return the condition code mask for 9551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// a branch on true. In the integer case, CCMASK_CMP_UO is set for 9561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// unsigned comparisons and clear for signed ones. In the floating-point 9571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// case, CCMASK_CMP_UO has its normal mask meaning (unordered). 9581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic unsigned CCMaskForCondCode(ISD::CondCode CC) { 9591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define CONV(X) \ 9601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \ 9611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \ 9621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X 9631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (CC) { 9651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 9661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Invalid integer condition!"); 9671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(EQ); 9691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(NE); 9701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(GT); 9711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(GE); 9721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(LT); 9731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(LE); 9741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETO: return SystemZ::CCMASK_CMP_O; 9761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETUO: return SystemZ::CCMASK_CMP_UO; 9771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 9781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#undef CONV 9791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// If a comparison described by IsUnsigned, CCMask, CmpOp0 and CmpOp1 9823237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford// can be converted to a comparison against zero, adjust the operands 9833237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford// as necessary. 9843237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandifordstatic void adjustZeroCmp(SelectionDAG &DAG, bool &IsUnsigned, 9853237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford SDValue &CmpOp0, SDValue &CmpOp1, 9863237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford unsigned &CCMask) { 9873237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford if (IsUnsigned) 9883237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford return; 9893237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford 9903237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford ConstantSDNode *ConstOp1 = dyn_cast<ConstantSDNode>(CmpOp1.getNode()); 9913237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford if (!ConstOp1) 9923237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford return; 9933237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford 9943237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford int64_t Value = ConstOp1->getSExtValue(); 9953237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford if ((Value == -1 && CCMask == SystemZ::CCMASK_CMP_GT) || 9963237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford (Value == -1 && CCMask == SystemZ::CCMASK_CMP_LE) || 9973237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford (Value == 1 && CCMask == SystemZ::CCMASK_CMP_LT) || 9983237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford (Value == 1 && CCMask == SystemZ::CCMASK_CMP_GE)) { 9993237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford CCMask ^= SystemZ::CCMASK_CMP_EQ; 10003237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford CmpOp1 = DAG.getConstant(0, CmpOp1.getValueType()); 10013237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford } 10023237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford} 10033237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford 10043237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford// If a comparison described by IsUnsigned, CCMask, CmpOp0 and CmpOp1 10051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// is suitable for CLI(Y), CHHSI or CLHHSI, adjust the operands as necessary. 10061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void adjustSubwordCmp(SelectionDAG &DAG, bool &IsUnsigned, 10071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue &CmpOp0, SDValue &CmpOp1, 10081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &CCMask) { 10091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // For us to make any changes, it must a comparison between a single-use 10101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // load and a constant. 10111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!CmpOp0.hasOneUse() || 10121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CmpOp0.getOpcode() != ISD::LOAD || 10131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CmpOp1.getOpcode() != ISD::Constant) 10141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We must have an 8- or 16-bit load. 10171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadSDNode *Load = cast<LoadSDNode>(CmpOp0); 10181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumBits = Load->getMemoryVT().getStoreSizeInBits(); 10191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NumBits != 8 && NumBits != 16) 10201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The load must be an extending one and the constant must be within the 10231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // range of the unextended value. 10241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ConstantSDNode *Constant = cast<ConstantSDNode>(CmpOp1); 10251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Value = Constant->getZExtValue(); 10261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Mask = (1 << NumBits) - 1; 10271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Load->getExtensionType() == ISD::SEXTLOAD) { 10281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t SignedValue = Constant->getSExtValue(); 102912cba852f550ae2d2fdb6b6be28d087aae585a76Aaron Ballman if (uint64_t(SignedValue) + (1ULL << (NumBits - 1)) > Mask) 10301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Unsigned comparison between two sign-extended values is equivalent 10321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to unsigned comparison between two zero-extended values. 10331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsUnsigned) 10341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value &= Mask; 10351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (CCMask == SystemZ::CCMASK_CMP_EQ || 10361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCMask == SystemZ::CCMASK_CMP_NE) 10371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Any choice of IsUnsigned is OK for equality comparisons. 10381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We could use either CHHSI or CLHHSI for 16-bit comparisons, 10391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // but since we use CLHHSI for zero extensions, it seems better 10401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to be consistent and do the same here. 10411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value &= Mask, IsUnsigned = true; 10421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (NumBits == 8) { 10431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to treat the comparison as unsigned, so that we can use CLI. 10441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Adjust CCMask and Value as necessary. 10451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Value == 0 && CCMask == SystemZ::CCMASK_CMP_LT) 10461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Test whether the high bit of the byte is set. 10471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = 127, CCMask = SystemZ::CCMASK_CMP_GT, IsUnsigned = true; 10483237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford else if (Value == 0 && CCMask == SystemZ::CCMASK_CMP_GE) 10491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Test whether the high bit of the byte is clear. 10501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = 128, CCMask = SystemZ::CCMASK_CMP_LT, IsUnsigned = true; 10511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 10521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // No instruction exists for this combination. 10531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (Load->getExtensionType() == ISD::ZEXTLOAD) { 10561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Value > Mask) 10571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Signed comparison between two zero-extended values is equivalent 10591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to unsigned comparison. 10601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IsUnsigned = true; 10611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 10621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure that the first operand is an i32 of the right extension type. 10651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ISD::LoadExtType ExtType = IsUnsigned ? ISD::ZEXTLOAD : ISD::SEXTLOAD; 10661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CmpOp0.getValueType() != MVT::i32 || 10671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getExtensionType() != ExtType) 1068ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick CmpOp0 = DAG.getExtLoad(ExtType, SDLoc(Load), MVT::i32, 10691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getChain(), Load->getBasePtr(), 10701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getPointerInfo(), Load->getMemoryVT(), 10711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->isVolatile(), Load->isNonTemporal(), 10721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getAlignment()); 10731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure that the second operand is an i32 with the right value. 10751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CmpOp1.getValueType() != MVT::i32 || 10761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value != Constant->getZExtValue()) 10771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CmpOp1 = DAG.getConstant(Value, MVT::i32); 10781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 10791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1080aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford// Return true if Op is either an unextended load, or a load suitable 1081aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford// for integer register-memory comparisons of type ICmpType. 1082aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandifordstatic bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType) { 108335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford LoadSDNode *Load = dyn_cast<LoadSDNode>(Op.getNode()); 1084aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (Load) { 1085aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // There are no instructions to compare a register with a memory byte. 1086aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (Load->getMemoryVT() == MVT::i8) 1087aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return false; 1088aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // Otherwise decide on extension type. 108935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford switch (Load->getExtensionType()) { 109035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford case ISD::NON_EXTLOAD: 109135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return true; 109235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford case ISD::SEXTLOAD: 1093aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return ICmpType != SystemZICMP::UnsignedOnly; 109435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford case ISD::ZEXTLOAD: 1095aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return ICmpType != SystemZICMP::SignedOnly; 109635c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford default: 109735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford break; 109835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford } 1099aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford } 110035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 110135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford} 110235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 110335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford// Return true if it is better to swap comparison operands Op0 and Op1. 1104aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford// ICmpType is the type of an integer comparison. 110535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandifordstatic bool shouldSwapCmpOperands(SDValue Op0, SDValue Op1, 1106aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford unsigned ICmpType) { 110735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Leave f128 comparisons alone, since they have no memory forms. 110835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (Op0.getValueType() == MVT::f128) 110935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 111035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 111135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Always keep a floating-point constant second, since comparisons with 111235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // zero can use LOAD TEST and comparisons with other constants make a 111335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // natural memory operand. 111435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (isa<ConstantFPSDNode>(Op1)) 111535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 111635c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 111735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Never swap comparisons with zero since there are many ways to optimize 111835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // those later. 111935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford ConstantSDNode *COp1 = dyn_cast<ConstantSDNode>(Op1); 112035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (COp1 && COp1->getZExtValue() == 0) 112135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 112235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 112335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Look for cases where Cmp0 is a single-use load and Cmp1 isn't. 112435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // In that case we generally prefer the memory to be second. 1125aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if ((isNaturalMemoryOperand(Op0, ICmpType) && Op0.hasOneUse()) && 1126aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford !(isNaturalMemoryOperand(Op1, ICmpType) && Op1.hasOneUse())) { 112735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // The only exceptions are when the second operand is a constant and 112835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // we can use things like CHHSI. 112935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (!COp1) 113035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return true; 1131aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // The unsigned memory-immediate instructions can handle 16-bit 1132aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // unsigned integers. 1133aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (ICmpType != SystemZICMP::SignedOnly && 1134aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford isUInt<16>(COp1->getZExtValue())) 1135aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return false; 1136aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // The signed memory-immediate instructions can handle 16-bit 1137aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // signed integers. 1138aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (ICmpType != SystemZICMP::UnsignedOnly && 1139aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford isInt<16>(COp1->getSExtValue())) 1140aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return false; 114135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return true; 114235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford } 114335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 114435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford} 114535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 1146856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// Return true if shift operation N has an in-range constant shift value. 1147856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// Store it in ShiftVal if so. 1148856bf594338567a592086fe782f2f51650e4e294Richard Sandifordstatic bool isSimpleShift(SDValue N, unsigned &ShiftVal) { 1149856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ConstantSDNode *Shift = dyn_cast<ConstantSDNode>(N.getOperand(1)); 1150856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (!Shift) 1151856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return false; 1152856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 1153856bf594338567a592086fe782f2f51650e4e294Richard Sandiford uint64_t Amount = Shift->getZExtValue(); 1154856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (Amount >= N.getValueType().getSizeInBits()) 1155856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return false; 1156856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 1157856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ShiftVal = Amount; 1158856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return true; 1159856bf594338567a592086fe782f2f51650e4e294Richard Sandiford} 1160856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 1161856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// Check whether an AND with Mask is suitable for a TEST UNDER MASK 1162856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// instruction and whether the CC value is descriptive enough to handle 1163856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// a comparison of type Opcode between the AND result and CmpVal. 1164856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// CCMask says which comparison result is being tested and BitSize is 1165856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// the number of bits in the operands. If TEST UNDER MASK can be used, 1166856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// return the corresponding CC mask, otherwise return 0. 1167aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandifordstatic unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, 1168aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford uint64_t Mask, uint64_t CmpVal, 1169aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford unsigned ICmpType) { 11708bce43648be1156fdced590beb81aed3915762f1Richard Sandiford assert(Mask != 0 && "ANDs with zero should have been removed by now"); 11718bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 1172856bf594338567a592086fe782f2f51650e4e294Richard Sandiford // Check whether the mask is suitable for TMHH, TMHL, TMLH or TMLL. 1173856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (!SystemZ::isImmLL(Mask) && !SystemZ::isImmLH(Mask) && 1174856bf594338567a592086fe782f2f51650e4e294Richard Sandiford !SystemZ::isImmHL(Mask) && !SystemZ::isImmHH(Mask)) 1175856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return 0; 1176856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 11778bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Work out the masks for the lowest and highest bits. 11788bce43648be1156fdced590beb81aed3915762f1Richard Sandiford unsigned HighShift = 63 - countLeadingZeros(Mask); 11798bce43648be1156fdced590beb81aed3915762f1Richard Sandiford uint64_t High = uint64_t(1) << HighShift; 11808bce43648be1156fdced590beb81aed3915762f1Richard Sandiford uint64_t Low = uint64_t(1) << countTrailingZeros(Mask); 11818bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 11828bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Signed ordered comparisons are effectively unsigned if the sign 11838bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // bit is dropped. 1184aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford bool EffectivelyUnsigned = (ICmpType != SystemZICMP::SignedOnly); 11858bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 11868bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check for equality comparisons with 0, or the equivalent. 11878bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CmpVal == 0) { 11888bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ) 11898bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_0; 11908bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE) 11918bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_1; 11928bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 11938bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal <= Low) { 11948bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LT) 11958bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_0; 11968bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GE) 11978bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_1; 11988bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 11998bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal < Low) { 12008bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LE) 12018bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_0; 12028bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GT) 12038bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_1; 12048bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12058bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12068bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check for equality comparisons with the mask, or the equivalent. 12078bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CmpVal == Mask) { 12088bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ) 12098bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_1; 12108bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE) 12118bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_0; 12128bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12138bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal >= Mask - Low && CmpVal < Mask) { 12148bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GT) 12158bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_1; 12168bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LE) 12178bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_0; 12188bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12198bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal > Mask - Low && CmpVal <= Mask) { 12208bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GE) 12218bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_1; 12228bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LT) 12238bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_0; 12248bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12258bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12268bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check for ordered comparisons with the top bit. 12278bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal >= Mask - High && CmpVal < High) { 12288bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LE) 12298bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_0; 12308bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GT) 12318bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_1; 12328bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12338bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal > Mask - High && CmpVal <= High) { 12348bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LT) 12358bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_0; 12368bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GE) 12378bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_1; 12388bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12398bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12408bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // If there are just two bits, we can do equality checks for Low and High 12418bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // as well. 12428bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (Mask == Low + High) { 12438bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == Low) 12448bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_0; 12458bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == Low) 12468bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_0 ^ SystemZ::CCMASK_ANY; 12478bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == High) 12488bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_1; 12498bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == High) 12508bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_1 ^ SystemZ::CCMASK_ANY; 12518bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12528bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12538bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Looks like we've exhausted our options. 12548bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return 0; 12558bce43648be1156fdced590beb81aed3915762f1Richard Sandiford} 12568bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 1257299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// See whether the comparison (Opcode CmpOp0, CmpOp1, ICmpType) can be 1258299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// implemented as a TEST UNDER MASK instruction when the condition being 1259299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// tested is as described by CCValid and CCMask. Update the arguments 1260299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// with the TM version if so. 1261856bf594338567a592086fe782f2f51650e4e294Richard Sandifordstatic void adjustForTestUnderMask(SelectionDAG &DAG, unsigned &Opcode, 1262856bf594338567a592086fe782f2f51650e4e294Richard Sandiford SDValue &CmpOp0, SDValue &CmpOp1, 1263856bf594338567a592086fe782f2f51650e4e294Richard Sandiford unsigned &CCValid, unsigned &CCMask, 1264856bf594338567a592086fe782f2f51650e4e294Richard Sandiford unsigned &ICmpType) { 12658bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check that we have a comparison with a constant. 1266477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford ConstantSDNode *ConstCmpOp1 = dyn_cast<ConstantSDNode>(CmpOp1); 12678bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (!ConstCmpOp1) 1268477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return; 1269856bf594338567a592086fe782f2f51650e4e294Richard Sandiford uint64_t CmpVal = ConstCmpOp1->getZExtValue(); 1270477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford 1271477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford // Check whether the nonconstant input is an AND with a constant mask. 1272477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford if (CmpOp0.getOpcode() != ISD::AND) 1273477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return; 1274477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford SDValue AndOp0 = CmpOp0.getOperand(0); 1275477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford SDValue AndOp1 = CmpOp0.getOperand(1); 1276477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(AndOp1.getNode()); 1277477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford if (!Mask) 1278477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return; 1279477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford uint64_t MaskVal = Mask->getZExtValue(); 1280477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford 12818bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check whether the combination of mask, comparison value and comparison 12828bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // type are suitable. 12838bce43648be1156fdced590beb81aed3915762f1Richard Sandiford unsigned BitSize = CmpOp0.getValueType().getSizeInBits(); 1284856bf594338567a592086fe782f2f51650e4e294Richard Sandiford unsigned NewCCMask, ShiftVal; 1285856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (ICmpType != SystemZICMP::SignedOnly && 1286856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0.getOpcode() == ISD::SHL && 1287856bf594338567a592086fe782f2f51650e4e294Richard Sandiford isSimpleShift(AndOp0, ShiftVal) && 1288856bf594338567a592086fe782f2f51650e4e294Richard Sandiford (NewCCMask = getTestUnderMaskCond(BitSize, CCMask, MaskVal >> ShiftVal, 1289856bf594338567a592086fe782f2f51650e4e294Richard Sandiford CmpVal >> ShiftVal, 1290856bf594338567a592086fe782f2f51650e4e294Richard Sandiford SystemZICMP::Any))) { 1291856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0 = AndOp0.getOperand(0); 1292856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp1 = DAG.getConstant(MaskVal >> ShiftVal, AndOp0.getValueType()); 1293856bf594338567a592086fe782f2f51650e4e294Richard Sandiford } else if (ICmpType != SystemZICMP::SignedOnly && 1294856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0.getOpcode() == ISD::SRL && 1295856bf594338567a592086fe782f2f51650e4e294Richard Sandiford isSimpleShift(AndOp0, ShiftVal) && 1296856bf594338567a592086fe782f2f51650e4e294Richard Sandiford (NewCCMask = getTestUnderMaskCond(BitSize, CCMask, 1297856bf594338567a592086fe782f2f51650e4e294Richard Sandiford MaskVal << ShiftVal, 1298856bf594338567a592086fe782f2f51650e4e294Richard Sandiford CmpVal << ShiftVal, 1299856bf594338567a592086fe782f2f51650e4e294Richard Sandiford SystemZICMP::UnsignedOnly))) { 1300856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0 = AndOp0.getOperand(0); 1301856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp1 = DAG.getConstant(MaskVal << ShiftVal, AndOp0.getValueType()); 1302856bf594338567a592086fe782f2f51650e4e294Richard Sandiford } else { 1303856bf594338567a592086fe782f2f51650e4e294Richard Sandiford NewCCMask = getTestUnderMaskCond(BitSize, CCMask, MaskVal, CmpVal, 1304856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ICmpType); 1305856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (!NewCCMask) 1306856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return; 1307856bf594338567a592086fe782f2f51650e4e294Richard Sandiford } 13088bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 1309477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford // Go ahead and make the change. 1310477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford Opcode = SystemZISD::TM; 1311477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford CmpOp0 = AndOp0; 1312477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford CmpOp1 = AndOp1; 1313299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford ICmpType = (bool(NewCCMask & SystemZ::CCMASK_TM_MIXED_MSB_0) != 1314299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford bool(NewCCMask & SystemZ::CCMASK_TM_MIXED_MSB_1)); 1315477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford CCValid = SystemZ::CCMASK_TM; 13168bce43648be1156fdced590beb81aed3915762f1Richard Sandiford CCMask = NewCCMask; 1317477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford} 1318477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford 13196824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// Return a target node that compares CmpOp0 with CmpOp1 and stores a 13206824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// 2-bit result in CC. Set CCValid to the CCMASK_* of all possible 13216824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// 2-bit results and CCMask to the subset of those results that are 13226824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// associated with Cond. 1323aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandifordstatic SDValue emitCmp(const SystemZTargetMachine &TM, SelectionDAG &DAG, 1324aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford SDLoc DL, SDValue CmpOp0, SDValue CmpOp1, 1325aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ISD::CondCode Cond, unsigned &CCValid, 13266824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned &CCMask) { 13271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsUnsigned = false; 13286824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask = CCMaskForCondCode(Cond); 1329aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford unsigned Opcode, ICmpType = 0; 1330aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (CmpOp0.getValueType().isFloatingPoint()) { 13316824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCValid = SystemZ::CCMASK_FCMP; 1332aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford Opcode = SystemZISD::FCMP; 1333aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford } else { 13341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IsUnsigned = CCMask & SystemZ::CCMASK_CMP_UO; 13356824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCValid = SystemZ::CCMASK_ICMP; 13366824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask &= CCValid; 13373237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford adjustZeroCmp(DAG, IsUnsigned, CmpOp0, CmpOp1, CCMask); 13381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand adjustSubwordCmp(DAG, IsUnsigned, CmpOp0, CmpOp1, CCMask); 1339aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford Opcode = SystemZISD::ICMP; 1340aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // Choose the type of comparison. Equality and inequality tests can 1341aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // use either signed or unsigned comparisons. The choice also doesn't 1342aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // matter if both sign bits are known to be clear. In those cases we 1343aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // want to give the main isel code the freedom to choose whichever 1344aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // form fits best. 1345aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ || 1346aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford CCMask == SystemZ::CCMASK_CMP_NE || 1347aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford (DAG.SignBitIsZero(CmpOp0) && DAG.SignBitIsZero(CmpOp1))) 1348aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ICmpType = SystemZICMP::Any; 1349aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford else if (IsUnsigned) 1350aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ICmpType = SystemZICMP::UnsignedOnly; 1351aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford else 1352aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ICmpType = SystemZICMP::SignedOnly; 13531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 13541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1355aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (shouldSwapCmpOperands(CmpOp0, CmpOp1, ICmpType)) { 135635c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford std::swap(CmpOp0, CmpOp1); 135735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford CCMask = ((CCMask & SystemZ::CCMASK_CMP_EQ) | 135835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford (CCMask & SystemZ::CCMASK_CMP_GT ? SystemZ::CCMASK_CMP_LT : 0) | 135935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford (CCMask & SystemZ::CCMASK_CMP_LT ? SystemZ::CCMASK_CMP_GT : 0) | 136035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford (CCMask & SystemZ::CCMASK_CMP_UO)); 136135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford } 136235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 1363856bf594338567a592086fe782f2f51650e4e294Richard Sandiford adjustForTestUnderMask(DAG, Opcode, CmpOp0, CmpOp1, CCValid, CCMask, 1364856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ICmpType); 1365299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford if (Opcode == SystemZISD::ICMP || Opcode == SystemZISD::TM) 1366aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1, 1367aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford DAG.getConstant(ICmpType, MVT::i32)); 1368477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1); 13691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 13701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1371df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford// Implement a 32-bit *MUL_LOHI operation by extending both operands to 1372df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford// 64 bits. Extend is the extension type to use. Store the high part 1373df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford// in Hi and the low part in Lo. 1374df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandifordstatic void lowerMUL_LOHI32(SelectionDAG &DAG, SDLoc DL, 1375df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford unsigned Extend, SDValue Op0, SDValue Op1, 1376df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue &Hi, SDValue &Lo) { 1377df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op0 = DAG.getNode(Extend, DL, MVT::i64, Op0); 1378df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op1 = DAG.getNode(Extend, DL, MVT::i64, Op1); 1379df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue Mul = DAG.getNode(ISD::MUL, DL, MVT::i64, Op0, Op1); 1380df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Hi = DAG.getNode(ISD::SRL, DL, MVT::i64, Mul, DAG.getConstant(32, MVT::i64)); 1381df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Hi); 1382df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Mul); 1383df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford} 1384df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford 13851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Lower a binary operation that produces two VT results, one in each 13861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// half of a GR128 pair. Op0 and Op1 are the VT operands to the operation, 13871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Extend extends Op0 to a GR128, and Opcode performs the GR128 operation 13881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// on the extended Op0 and (unextended) Op1. Store the even register result 13891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// in Even and the odd register result in Odd. 1390ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic void lowerGR128Binary(SelectionDAG &DAG, SDLoc DL, EVT VT, 13911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Extend, unsigned Opcode, 13921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0, SDValue Op1, 13931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue &Even, SDValue &Odd) { 13941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDNode *In128 = DAG.getMachineNode(Extend, DL, MVT::Untyped, Op0); 13951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getNode(Opcode, DL, MVT::Untyped, 13961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue(In128, 0), Op1); 13971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool Is32Bit = is32Bit(VT); 13987c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford Even = DAG.getTargetExtractSubreg(SystemZ::even128(Is32Bit), DL, VT, Result); 13997c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result); 14001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 14031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 14041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 14051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp0 = Op.getOperand(2); 14061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp1 = Op.getOperand(3); 14071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Dest = Op.getOperand(4); 1408ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 14091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14106824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid, CCMask; 1411aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask); 14121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(), 14136824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Chain, DAG.getConstant(CCValid, MVT::i32), 14146824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford DAG.getConstant(CCMask, MVT::i32), Dest, Flags); 14151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op, 14181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 14191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp0 = Op.getOperand(0); 14201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp1 = Op.getOperand(1); 14211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TrueOp = Op.getOperand(2); 14221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FalseOp = Op.getOperand(3); 14231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 1424ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 14251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14266824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid, CCMask; 1427aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask); 14281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14296824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford SmallVector<SDValue, 5> Ops; 14301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(TrueOp); 14311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(FalseOp); 14326824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Ops.push_back(DAG.getConstant(CCValid, MVT::i32)); 14331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getConstant(CCMask, MVT::i32)); 14341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Flags); 14351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 14371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VTs, &Ops[0], Ops.size()); 14381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerGlobalAddress(GlobalAddressSDNode *Node, 14411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1442ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 14431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const GlobalValue *GV = Node->getGlobal(); 14441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset = Node->getOffset(); 14451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 14461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Reloc::Model RM = TM.getRelocationModel(); 14471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CodeModel::Model CM = TM.getCodeModel(); 14481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result; 14501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Subtarget.isPC32DBLSymbol(GV, RM, CM)) { 14518dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford // Assign anchors at 1<<12 byte boundaries. 14528dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford uint64_t Anchor = Offset & ~uint64_t(0xfff); 14538dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor); 14548dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 14558dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford 14568dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford // The offset can be folded into the address if it is aligned to a halfword. 14578dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Offset -= Anchor; 14588dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (Offset != 0 && (Offset & 1) == 0) { 14598dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Full = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor + Offset); 14608dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Result = DAG.getNode(SystemZISD::PCREL_OFFSET, DL, PtrVT, Full, Result); 14611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset = 0; 14621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 14631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 14641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, SystemZII::MO_GOT); 14651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 14661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result, 14671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getGOT(), false, false, false, 0); 14681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 14691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If there was a non-zero offset that we didn't fold, create an explicit 14711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // addition for it. 14721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Offset != 0) 14731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getNode(ISD::ADD, DL, PtrVT, Result, 14741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(Offset, PtrVT)); 14751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Result; 14771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerGlobalTLSAddress(GlobalAddressSDNode *Node, 14801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1481ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 14821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const GlobalValue *GV = Node->getGlobal(); 14831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 14841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TLSModel::Model model = TM.getTLSModel(GV); 14851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (model != TLSModel::LocalExec) 14871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("only local-exec TLS mode supported"); 14881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The high part of the thread pointer is in access register 0. 14901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TPHi = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32, 14911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, MVT::i32)); 14921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TPHi = DAG.getNode(ISD::ANY_EXTEND, DL, PtrVT, TPHi); 14931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The low part of the thread pointer is in access register 1. 14951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TPLo = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32, 14961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(1, MVT::i32)); 14971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TPLo = DAG.getNode(ISD::ZERO_EXTEND, DL, PtrVT, TPLo); 14981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Merge them into a single 64-bit address. 15001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TPHiShifted = DAG.getNode(ISD::SHL, DL, PtrVT, TPHi, 15011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(32, PtrVT)); 15021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TP = DAG.getNode(ISD::OR, DL, PtrVT, TPHiShifted, TPLo); 15031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the offset of GA from the thread pointer. 15051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZConstantPoolValue *CPV = 15061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZConstantPoolValue::Create(GV, SystemZCP::NTPOFF); 15071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Force the offset into the constant pool and load it from there. 15091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CPAddr = DAG.getConstantPool(CPV, PtrVT, 8); 15101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Offset = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), 15111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CPAddr, MachinePointerInfo::getConstantPool(), 15121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, false, 0); 15131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add the base and offset together. 15151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::ADD, DL, PtrVT, TP, Offset); 15161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerBlockAddress(BlockAddressSDNode *Node, 15191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1520ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 15211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const BlockAddress *BA = Node->getBlockAddress(); 15221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset = Node->getOffset(); 15231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 15241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT, Offset); 15261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 15271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Result; 15281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerJumpTable(JumpTableSDNode *JT, 15311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1532ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(JT); 15331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 15341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); 15351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use LARL to load the address of the table. 15371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 15381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerConstantPool(ConstantPoolSDNode *CP, 15411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1542ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(CP); 15431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 15441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result; 15461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CP->isMachineConstantPoolEntry()) 15471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, 15481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CP->getAlignment()); 15491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 15501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, 15511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CP->getAlignment(), CP->getOffset()); 15521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use LARL to load the address of the constant pool entry. 15541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 15551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerBITCAST(SDValue Op, 15581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1559ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 15601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue In = Op.getOperand(0); 15611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT InVT = In.getValueType(); 15621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT ResVT = Op.getValueType(); 15631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (InVT == MVT::i32 && ResVT == MVT::f32) { 15655fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDValue In64; 15665fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford if (Subtarget.hasHighWord()) { 15675fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, 15685fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford MVT::i64); 15695fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL, 15705fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford MVT::i64, SDValue(U64, 0), In); 15715fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford } else { 15725fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford In64 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, In); 15735fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford In64 = DAG.getNode(ISD::SHL, DL, MVT::i64, In64, 15745fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford DAG.getConstant(32, MVT::i64)); 15755fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford } 15765fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::f64, In64); 1577745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return DAG.getTargetExtractSubreg(SystemZ::subreg_h32, 15787c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford DL, MVT::f32, Out64); 15791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 15801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (InVT == MVT::f32 && ResVT == MVT::i32) { 15811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f64); 1582745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford SDValue In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL, 15837c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford MVT::f64, SDValue(U64, 0), In); 15847c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::i64, In64); 15855fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford if (Subtarget.hasHighWord()) 15865fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford return DAG.getTargetExtractSubreg(SystemZ::subreg_h32, DL, 15875fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford MVT::i32, Out64); 15885fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDValue Shift = DAG.getNode(ISD::SRL, DL, MVT::i64, Out64, 15895fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford DAG.getConstant(32, MVT::i64)); 15905fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Shift); 15911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 15921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected bitcast combination"); 15931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerVASTART(SDValue Op, 15961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 15971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 15981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *FuncInfo = 15991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>(); 16001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 16011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 16031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr = Op.getOperand(1); 16041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 1605ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 16061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The initial values of each field. 16081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const unsigned NumFields = 4; 16091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Fields[NumFields] = { 16101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(FuncInfo->getVarArgsFirstGPR(), PtrVT), 16111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(FuncInfo->getVarArgsFirstFPR(), PtrVT), 16121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT), 16131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(), PtrVT) 16141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand }; 16151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Store each field into its respective slot. 16171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue MemOps[NumFields]; 16181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = 0; 16191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0; I < NumFields; ++I) { 16201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FieldAddr = Addr; 16211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Offset != 0) 16221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FieldAddr = DAG.getNode(ISD::ADD, DL, PtrVT, FieldAddr, 16231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getIntPtrConstant(Offset)); 16241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOps[I] = DAG.getStore(Chain, DL, Fields[I], FieldAddr, 16251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(SV, Offset), 16261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0); 16271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset += 8; 16281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 16291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps, NumFields); 16301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 16311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerVACOPY(SDValue Op, 16331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 16341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 16351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue DstPtr = Op.getOperand(1); 16361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue SrcPtr = Op.getOperand(2); 16371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue(); 16381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue(); 1639ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 16401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(32), 16421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand /*Align*/8, /*isVolatile*/false, /*AlwaysInline*/false, 16431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV)); 16441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 16451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering:: 16471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandlowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { 16481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 16491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Size = Op.getOperand(1); 1650ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 16511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SPReg = getStackPointerRegisterToSaveRestore(); 16531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get a reference to the stack pointer. 16551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i64); 16561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the new stack pointer value. 16581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue NewSP = DAG.getNode(ISD::SUB, DL, MVT::i64, OldSP, Size); 16591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy the new stack pointer back. 16611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getCopyToReg(Chain, DL, SPReg, NewSP); 16621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The allocated data lives above the 160 bytes allocated for the standard 16641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // frame, plus any outgoing stack arguments. We don't know how much that 16651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // amounts to yet, so emit a special ADJDYNALLOC placeholder. 16661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgAdjust = DAG.getNode(SystemZISD::ADJDYNALLOC, DL, MVT::i64); 16671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getNode(ISD::ADD, DL, MVT::i64, NewSP, ArgAdjust); 16681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2] = { Result, Chain }; 16701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 16711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 16721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1673df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard SandifordSDValue SystemZTargetLowering::lowerSMUL_LOHI(SDValue Op, 16741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 16751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Op.getValueType(); 1676ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 1677df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue Ops[2]; 1678df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford if (is32Bit(VT)) 1679df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Just do a normal 64-bit multiplication and extract the results. 1680df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // We define this so that it can be used for constant division. 1681df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerMUL_LOHI32(DAG, DL, ISD::SIGN_EXTEND, Op.getOperand(0), 1682df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op.getOperand(1), Ops[1], Ops[0]); 1683df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford else { 1684df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Do a full 128-bit multiplication based on UMUL_LOHI64: 1685df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1686df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // (ll * rl) + ((lh * rl) << 64) + ((ll * rh) << 64) 1687df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1688df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // but using the fact that the upper halves are either all zeros 1689df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // or all ones: 1690df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1691df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // (ll * rl) - ((lh & rl) << 64) - ((ll & rh) << 64) 1692df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1693df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // and grouping the right terms together since they are quicker than the 1694df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // multiplication: 1695df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1696df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // (ll * rl) - (((lh & rl) + (ll & rh)) << 64) 1697df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue C63 = DAG.getConstant(63, MVT::i64); 1698df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue LL = Op.getOperand(0); 1699df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue RL = Op.getOperand(1); 1700df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue LH = DAG.getNode(ISD::SRA, DL, VT, LL, C63); 1701df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue RH = DAG.getNode(ISD::SRA, DL, VT, RL, C63); 1702df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // UMUL_LOHI64 returns the low result in the odd register and the high 1703df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // result in the even register. SMUL_LOHI is defined to return the 1704df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // low half first, so the results are in reverse order. 1705df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, SystemZISD::UMUL_LOHI64, 1706df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford LL, RL, Ops[1], Ops[0]); 1707df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue NegLLTimesRH = DAG.getNode(ISD::AND, DL, VT, LL, RH); 1708df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue NegLHTimesRL = DAG.getNode(ISD::AND, DL, VT, LH, RL); 1709df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue NegSum = DAG.getNode(ISD::ADD, DL, VT, NegLLTimesRH, NegLHTimesRL); 1710df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Ops[1] = DAG.getNode(ISD::SUB, DL, VT, Ops[1], NegSum); 1711df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford } 1712df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford return DAG.getMergeValues(Ops, 2, DL); 1713df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford} 17141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1715df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard SandifordSDValue SystemZTargetLowering::lowerUMUL_LOHI(SDValue Op, 1716df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SelectionDAG &DAG) const { 1717df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford EVT VT = Op.getValueType(); 1718df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDLoc DL(Op); 17191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2]; 1720df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford if (is32Bit(VT)) 1721df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Just do a normal 64-bit multiplication and extract the results. 1722df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // We define this so that it can be used for constant division. 1723df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerMUL_LOHI32(DAG, DL, ISD::ZERO_EXTEND, Op.getOperand(0), 1724df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op.getOperand(1), Ops[1], Ops[0]); 1725df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford else 1726df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // UMUL_LOHI64 returns the low result in the odd register and the high 1727df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // result in the even register. UMUL_LOHI is defined to return the 1728df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // low half first, so the results are in reverse order. 1729df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, SystemZISD::UMUL_LOHI64, 1730df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]); 17311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 17321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 17331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSDIVREM(SDValue Op, 17351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 17361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0 = Op.getOperand(0); 17371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op1 = Op.getOperand(1); 17381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Op.getValueType(); 1739ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 174035b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford unsigned Opcode; 17411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We use DSGF for 32-bit division. 17431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (is32Bit(VT)) { 17441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op0 = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Op0); 174535b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Opcode = SystemZISD::SDIVREM32; 174635b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford } else if (DAG.ComputeNumSignBits(Op1) > 32) { 174735b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Op1 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1); 174835b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Opcode = SystemZISD::SDIVREM32; 174935b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford } else 175035b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Opcode = SystemZISD::SDIVREM64; 17511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // DSG(F) takes a 64-bit dividend, so the even register in the GR128 17531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // input is "don't care". The instruction returns the remainder in 17541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // the even register and the quotient in the odd register. 17551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2]; 175635b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, Opcode, 17571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op0, Op1, Ops[1], Ops[0]); 17581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 17591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 17601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerUDIVREM(SDValue Op, 17621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 17631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Op.getValueType(); 1764ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 17651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // DL(G) uses a double-width dividend, so we need to clear the even 17671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // register in the GR128 input. The instruction returns the remainder 17681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // in the even register and the quotient in the odd register. 17691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2]; 17701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (is32Bit(VT)) 17711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand lowerGR128Binary(DAG, DL, VT, SystemZ::ZEXT128_32, SystemZISD::UDIVREM32, 17721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]); 17731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 17741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand lowerGR128Binary(DAG, DL, VT, SystemZ::ZEXT128_64, SystemZISD::UDIVREM64, 17751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]); 17761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 17771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 17781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerOR(SDValue Op, SelectionDAG &DAG) const { 17801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(Op.getValueType() == MVT::i64 && "Should be 64-bit operation"); 17811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the known-zero masks for each operand. 17831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1) }; 17841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand APInt KnownZero[2], KnownOne[2]; 17851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.ComputeMaskedBits(Ops[0], KnownZero[0], KnownOne[0]); 17861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.ComputeMaskedBits(Ops[1], KnownZero[1], KnownOne[1]); 17871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // See if the upper 32 bits of one operand and the lower 32 bits of the 17891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // other are known zero. They are the low and high operands respectively. 17901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Masks[] = { KnownZero[0].getZExtValue(), 17911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand KnownZero[1].getZExtValue() }; 17921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned High, Low; 17931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff) 17941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand High = 1, Low = 0; 17951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff) 17961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand High = 0, Low = 1; 17971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 17981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 17991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue LowOp = Ops[Low]; 18011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue HighOp = Ops[High]; 18021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the high part is a constant, we're better off using IILH. 18041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (HighOp.getOpcode() == ISD::Constant) 18051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 18061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the low part is a constant that is outside the range of LHI, 18081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // then we're better off using IILF. 18091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (LowOp.getOpcode() == ISD::Constant) { 18101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Value = int32_t(cast<ConstantSDNode>(LowOp)->getZExtValue()); 18111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isInt<16>(Value)) 18121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 18131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 18141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Check whether the high part is an AND that doesn't change the 18161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // high 32 bits and just masks out low bits. We can skip it if so. 18171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (HighOp.getOpcode() == ISD::AND && 18181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand HighOp.getOperand(1).getOpcode() == ISD::Constant) { 18191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ConstantSDNode *MaskNode = cast<ConstantSDNode>(HighOp.getOperand(1)); 18201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Mask = MaskNode->getZExtValue() | Masks[High]; 18211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((Mask >> 32) == 0xffffffff) 18221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand HighOp = HighOp.getOperand(0); 18231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 18241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Take advantage of the fact that all GR32 operations only change the 18261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // low 32 bits by truncating Low to an i32 and inserting it directly 18271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // using a subreg. The interesting cases are those where the truncation 18281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // can be folded. 1829ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 18301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Low32 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, LowOp); 1831745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return DAG.getTargetInsertSubreg(SystemZ::subreg_l32, DL, 18327c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford MVT::i64, HighOp, Low32); 18331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 18341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Op is an 8-, 16-bit or 32-bit ATOMIC_LOAD_* operation. Lower the first 18361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// two into the fullword ATOMIC_LOADW_* operation given by Opcode. 18371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerATOMIC_LOAD(SDValue Op, 18381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG, 18391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode) const { 18401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AtomicSDNode *Node = cast<AtomicSDNode>(Op.getNode()); 18411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 32-bit operations need no code outside the main loop. 18431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT NarrowVT = Node->getMemoryVT(); 18441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT WideVT = MVT::i32; 18451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NarrowVT == WideVT) 18461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 18471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t BitSize = NarrowVT.getSizeInBits(); 18491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ChainIn = Node->getChain(); 18501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr = Node->getBasePtr(); 18511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Src2 = Node->getVal(); 18521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineMemOperand *MMO = Node->getMemOperand(); 1853ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 18541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = Addr.getValueType(); 18551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Convert atomic subtracts of constants into additions. 18571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == SystemZISD::ATOMIC_LOADW_SUB) 18581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(Src2)) { 18591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZISD::ATOMIC_LOADW_ADD; 18601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Src2 = DAG.getConstant(-Const->getSExtValue(), Src2.getValueType()); 18611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 18621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the address of the containing word. 18641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr, 18651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(-4, PtrVT)); 18661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the number of bits that the word must be rotated left in order 18681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to bring the field to the top bits of a GR32. 18691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr, 18701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(3, PtrVT)); 18711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift); 18721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the complementing shift amount, for rotating a field in the top 18741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits back to its proper position. 18751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT, 18761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, WideVT), BitShift); 18771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extend the source operand to 32 bits and prepare it for the inner loop. 18791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ATOMIC_SWAPW uses RISBG to rotate the field left, but all other 18801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // operations require the source to be shifted in advance. (This shift 18811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // can be folded if the source is constant.) For AND and NAND, the lower 18821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits must be set, while for other opcodes they should be left clear. 18831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode != SystemZISD::ATOMIC_SWAPW) 18841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Src2 = DAG.getNode(ISD::SHL, DL, WideVT, Src2, 18851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(32 - BitSize, WideVT)); 18861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == SystemZISD::ATOMIC_LOADW_AND || 18871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode == SystemZISD::ATOMIC_LOADW_NAND) 18881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Src2 = DAG.getNode(ISD::OR, DL, WideVT, Src2, 18891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(uint32_t(-1) >> BitSize, WideVT)); 18901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Construct the ATOMIC_LOADW_* node. 18921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList VTList = DAG.getVTList(WideVT, MVT::Other); 18931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift, 18941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(BitSize, WideVT) }; 18951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AtomicOp = DAG.getMemIntrinsicNode(Opcode, DL, VTList, Ops, 18961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand array_lengthof(Ops), 18971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NarrowVT, MMO); 18981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Rotate the result of the final CS so that the field is in the lower 19001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits of a GR32, then truncate it. 19011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ResultShift = DAG.getNode(ISD::ADD, DL, WideVT, BitShift, 19021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(BitSize, WideVT)); 19031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getNode(ISD::ROTL, DL, WideVT, AtomicOp, ResultShift); 19041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue RetOps[2] = { Result, AtomicOp.getValue(1) }; 19061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(RetOps, 2, DL); 19071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Node is an 8- or 16-bit ATOMIC_CMP_SWAP operation. Lower the first two 19101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// into a fullword ATOMIC_CMP_SWAPW operation. 19111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerATOMIC_CMP_SWAP(SDValue Op, 19121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AtomicSDNode *Node = cast<AtomicSDNode>(Op.getNode()); 19141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have native support for 32-bit compare and swap. 19161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT NarrowVT = Node->getMemoryVT(); 19171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT WideVT = MVT::i32; 19181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NarrowVT == WideVT) 19191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 19201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t BitSize = NarrowVT.getSizeInBits(); 19221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ChainIn = Node->getOperand(0); 19231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr = Node->getOperand(1); 19241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpVal = Node->getOperand(2); 19251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue SwapVal = Node->getOperand(3); 19261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineMemOperand *MMO = Node->getMemOperand(); 1927ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 19281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = Addr.getValueType(); 19291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the address of the containing word. 19311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr, 19321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(-4, PtrVT)); 19331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the number of bits that the word must be rotated left in order 19351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to bring the field to the top bits of a GR32. 19361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr, 19371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(3, PtrVT)); 19381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift); 19391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the complementing shift amount, for rotating a field in the top 19411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits back to its proper position. 19421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT, 19431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, WideVT), BitShift); 19441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Construct the ATOMIC_CMP_SWAPW node. 19461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList VTList = DAG.getVTList(WideVT, MVT::Other); 19471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift, 19481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NegBitShift, DAG.getConstant(BitSize, WideVT) }; 19491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AtomicOp = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_CMP_SWAPW, DL, 19501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand VTList, Ops, array_lengthof(Ops), 19511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NarrowVT, MMO); 19521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return AtomicOp; 19531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSTACKSAVE(SDValue Op, 19561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 19581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true); 1959ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), 19601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::R15D, Op.getValueType()); 19611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op, 19641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 19661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true); 1967ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op), 19681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::R15D, Op.getOperand(1)); 19691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1971a550b51bac50493db75a7b5788a3f2c3b62fd913Richard SandifordSDValue SystemZTargetLowering::lowerPREFETCH(SDValue Op, 1972a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford SelectionDAG &DAG) const { 1973a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford bool IsData = cast<ConstantSDNode>(Op.getOperand(4))->getZExtValue(); 1974a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford if (!IsData) 1975a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford // Just preserve the chain. 1976a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford return Op.getOperand(0); 1977a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford 1978a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford bool IsWrite = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue(); 1979a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford unsigned Code = IsWrite ? SystemZ::PFD_WRITE : SystemZ::PFD_READ; 1980a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford MemIntrinsicSDNode *Node = cast<MemIntrinsicSDNode>(Op.getNode()); 1981a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford SDValue Ops[] = { 1982a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Op.getOperand(0), 1983a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford DAG.getConstant(Code, MVT::i32), 1984a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Op.getOperand(1) 1985a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford }; 1986a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford return DAG.getMemIntrinsicNode(SystemZISD::PREFETCH, SDLoc(Op), 1987a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Node->getVTList(), Ops, array_lengthof(Ops), 1988a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Node->getMemoryVT(), Node->getMemOperand()); 1989a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford} 1990a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford 19911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::LowerOperation(SDValue Op, 19921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Op.getOpcode()) { 19941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::BR_CC: 19951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerBR_CC(Op, DAG); 19961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SELECT_CC: 19971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSELECT_CC(Op, DAG); 19981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::GlobalAddress: 19991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerGlobalAddress(cast<GlobalAddressSDNode>(Op), DAG); 20001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::GlobalTLSAddress: 20011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerGlobalTLSAddress(cast<GlobalAddressSDNode>(Op), DAG); 20021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::BlockAddress: 20031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerBlockAddress(cast<BlockAddressSDNode>(Op), DAG); 20041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::JumpTable: 20051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerJumpTable(cast<JumpTableSDNode>(Op), DAG); 20061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ConstantPool: 20071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG); 20081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::BITCAST: 20091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerBITCAST(Op, DAG); 20101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::VASTART: 20111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerVASTART(Op, DAG); 20121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::VACOPY: 20131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerVACOPY(Op, DAG); 20141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::DYNAMIC_STACKALLOC: 20151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerDYNAMIC_STACKALLOC(Op, DAG); 2016df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford case ISD::SMUL_LOHI: 2017df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford return lowerSMUL_LOHI(Op, DAG); 20181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::UMUL_LOHI: 20191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerUMUL_LOHI(Op, DAG); 20201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SDIVREM: 20211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSDIVREM(Op, DAG); 20221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::UDIVREM: 20231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerUDIVREM(Op, DAG); 20241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::OR: 20251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerOR(Op, DAG); 20261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_SWAP: 20271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_SWAPW); 20281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_ADD: 20291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_ADD); 20301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_SUB: 20311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_SUB); 20321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_AND: 20331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_AND); 20341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_OR: 20351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_OR); 20361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_XOR: 20371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_XOR); 20381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_NAND: 20391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_NAND); 20401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_MIN: 20411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_MIN); 20421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_MAX: 20431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_MAX); 20441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_UMIN: 20451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN); 20461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_UMAX: 20471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX); 20481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_CMP_SWAP: 20491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_CMP_SWAP(Op, DAG); 20501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::STACKSAVE: 20511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSTACKSAVE(Op, DAG); 20521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::STACKRESTORE: 20531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSTACKRESTORE(Op, DAG); 2054a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford case ISD::PREFETCH: 2055a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford return lowerPREFETCH(Op, DAG); 20561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 20571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected node to lower"); 20581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 20591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 20601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 20611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandconst char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { 20621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define OPCODE(NAME) case SystemZISD::NAME: return "SystemZISD::" #NAME 20631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Opcode) { 20641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(RET_FLAG); 20651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(CALL); 206680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford OPCODE(SIBCALL); 20671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(PCREL_WRAPPER); 20688dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford OPCODE(PCREL_OFFSET); 2069aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford OPCODE(ICMP); 2070aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford OPCODE(FCMP); 2071477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford OPCODE(TM); 20721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(BR_CCMASK); 20731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(SELECT_CCMASK); 20741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ADJDYNALLOC); 20751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(EXTRACT_ACCESS); 20761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(UMUL_LOHI64); 20771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(SDIVREM64); 20781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(UDIVREM32); 20791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(UDIVREM64); 2080dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford OPCODE(MVC); 2081842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford OPCODE(MVC_LOOP); 208216277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(NC); 208316277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(NC_LOOP); 208416277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(OC); 208516277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(OC_LOOP); 208616277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(XC); 208716277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(XC_LOOP); 2088e03a56d62fc623e2f72d623b816f91b293d5904bRichard Sandiford OPCODE(CLC); 2089842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford OPCODE(CLC_LOOP); 2090e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford OPCODE(STRCMP); 20914fc7355a21e1fa838406e15459aaf54a58fcf909Richard Sandiford OPCODE(STPCPY); 209219262ee0725a09b7c621a3d2eb66ba1513ae932aRichard Sandiford OPCODE(SEARCH_STRING); 2093ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford OPCODE(IPM); 20941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_SWAPW); 20951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_ADD); 20961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_SUB); 20971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_AND); 20981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_OR); 20991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_XOR); 21001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_NAND); 21011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_MIN); 21021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_MAX); 21031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_UMIN); 21041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_UMAX); 21051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_CMP_SWAPW); 2106a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford OPCODE(PREFETCH); 21071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 21081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return NULL; 21091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#undef OPCODE 21101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 21111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 21131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Custom insertion 21141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 21151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Create a new basic block after MBB. 21171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic MachineBasicBlock *emitBlockAfter(MachineBasicBlock *MBB) { 21181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 21191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *NewMBB = MF.CreateMachineBasicBlock(MBB->getBasicBlock()); 21201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.insert(llvm::next(MachineFunction::iterator(MBB)), NewMBB); 21211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return NewMBB; 21221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 21231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 212447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford// Split MBB after MI and return the new block (the one that contains 212547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford// instructions after MI). 212647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandifordstatic MachineBasicBlock *splitBlockAfter(MachineInstr *MI, 212747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *MBB) { 212847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *NewMBB = emitBlockAfter(MBB); 212947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford NewMBB->splice(NewMBB->begin(), MBB, 213047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford llvm::next(MachineBasicBlock::iterator(MI)), 213147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->end()); 213247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford NewMBB->transferSuccessorsAndUpdatePHIs(MBB); 213347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford return NewMBB; 213447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford} 213547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 2136842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford// Split MBB before MI and return the new block (the one that contains MI). 2137842a1be06c53757e7498c9894abc1431b633a92fRichard Sandifordstatic MachineBasicBlock *splitBlockBefore(MachineInstr *MI, 2138842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *MBB) { 21391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *NewMBB = emitBlockAfter(MBB); 2140842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford NewMBB->splice(NewMBB->begin(), MBB, MI, MBB->end()); 21411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NewMBB->transferSuccessorsAndUpdatePHIs(MBB); 21421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return NewMBB; 21431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 21441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2145842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford// Force base value Base into a register before MI. Return the register. 2146842a1be06c53757e7498c9894abc1431b633a92fRichard Sandifordstatic unsigned forceReg(MachineInstr *MI, MachineOperand &Base, 2147842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford const SystemZInstrInfo *TII) { 2148842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (Base.isReg()) 2149842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford return Base.getReg(); 2150842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2151842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *MBB = MI->getParent(); 2152842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineFunction &MF = *MBB->getParent(); 2153842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineRegisterInfo &MRI = MF.getRegInfo(); 2154842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2155842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass); 2156842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(SystemZ::LA), Reg) 2157842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(Base).addImm(0).addReg(0); 2158842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford return Reg; 2159842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford} 2160842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 21611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo Select* instruction MI. 21621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 21631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitSelect(MachineInstr *MI, 21641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB) const { 21651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 21661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg = MI->getOperand(0).getReg(); 21681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned TrueReg = MI->getOperand(1).getReg(); 21691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned FalseReg = MI->getOperand(2).getReg(); 21706824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = MI->getOperand(3).getImm(); 21716824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = MI->getOperand(4).getImm(); 21721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 21731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2175842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *JoinMBB = splitBlockBefore(MI, MBB); 21761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *FalseMBB = emitBlockAfter(StartMBB); 21771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 2179d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford // BRC CCMask, JoinMBB 21801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fallthrough to FalseMBB 21811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 21826824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 21836824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB); 21841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(JoinMBB); 21851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(FalseMBB); 21861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FalseMBB: 21881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fallthrough to JoinMBB 21891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = FalseMBB; 21901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(JoinMBB); 21911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JoinMBB: 21931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Result = phi [ %FalseReg, FalseMBB ], [ %TrueReg, StartMBB ] 21941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 21951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = JoinMBB; 2196842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, DL, TII->get(SystemZ::PHI), DestReg) 21971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(TrueReg).addMBB(StartMBB) 21981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(FalseReg).addMBB(FalseMBB); 21991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 22001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 22011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return JoinMBB; 22021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 22031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2204722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford// Implement EmitInstrWithCustomInserter for pseudo CondStore* instruction MI. 2205722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford// StoreOpcode is the store to use and Invert says whether the store should 2206b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford// happen when the condition is false rather than true. If a STORE ON 2207b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford// CONDITION is available, STOCOpcode is its opcode, otherwise it is 0. 2208722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard SandifordMachineBasicBlock * 2209722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard SandifordSystemZTargetLowering::emitCondStore(MachineInstr *MI, 2210722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MachineBasicBlock *MBB, 2211b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford unsigned StoreOpcode, unsigned STOCOpcode, 2212b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford bool Invert) const { 2213722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford const SystemZInstrInfo *TII = TM.getInstrInfo(); 2214722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2215b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford unsigned SrcReg = MI->getOperand(0).getReg(); 2216b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford MachineOperand Base = MI->getOperand(1); 2217b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford int64_t Disp = MI->getOperand(2).getImm(); 2218b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford unsigned IndexReg = MI->getOperand(3).getReg(); 22196824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = MI->getOperand(4).getImm(); 22206824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = MI->getOperand(5).getImm(); 2221722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford DebugLoc DL = MI->getDebugLoc(); 2222722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2223722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford StoreOpcode = TII->getOpcodeForOffset(StoreOpcode, Disp); 2224722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2225b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford // Use STOCOpcode if possible. We could use different store patterns in 2226b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford // order to avoid matching the index register, but the performance trade-offs 2227b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford // might be more complicated in that case. 2228b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford if (STOCOpcode && !IndexReg && TM.getSubtargetImpl()->hasLoadStoreOnCond()) { 2229b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford if (Invert) 22306824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask ^= CCValid; 2231b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford BuildMI(*MBB, MI, DL, TII->get(STOCOpcode)) 22328f0ad5ae8f2699f6ab13a229941a0b192273cae8Richard Sandiford .addReg(SrcReg).addOperand(Base).addImm(Disp) 22338f0ad5ae8f2699f6ab13a229941a0b192273cae8Richard Sandiford .addImm(CCValid).addImm(CCMask); 2234b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford MI->eraseFromParent(); 2235b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return MBB; 2236b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford } 2237b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford 2238722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // Get the condition needed to branch around the store. 2239722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford if (!Invert) 22406824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask ^= CCValid; 2241722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2242722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MachineBasicBlock *StartMBB = MBB; 2243842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *JoinMBB = splitBlockBefore(MI, MBB); 2244722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MachineBasicBlock *FalseMBB = emitBlockAfter(StartMBB); 2245722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2246722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // StartMBB: 2247722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // BRC CCMask, JoinMBB 2248722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // # fallthrough to FalseMBB 2249722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB = StartMBB; 22506824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 22516824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB); 2252722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB->addSuccessor(JoinMBB); 2253722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB->addSuccessor(FalseMBB); 2254722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2255722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // FalseMBB: 2256722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // store %SrcReg, %Disp(%Index,%Base) 2257722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // # fallthrough to JoinMBB 2258722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB = FalseMBB; 2259722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford BuildMI(MBB, DL, TII->get(StoreOpcode)) 2260722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford .addReg(SrcReg).addOperand(Base).addImm(Disp).addReg(IndexReg); 2261722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB->addSuccessor(JoinMBB); 2262722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2263722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MI->eraseFromParent(); 2264722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford return JoinMBB; 2265722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford} 2266722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 22671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo ATOMIC_LOAD{,W}_* 22681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// or ATOMIC_SWAP{,W} instruction MI. BinOpcode is the instruction that 22691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// performs the binary operation elided by "*", or 0 for ATOMIC_SWAP{,W}. 22701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// BitSize is the width of the field in bits, or 0 if this is a partword 22711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// ATOMIC_LOADW_* or ATOMIC_SWAPW instruction, in which case the bitsize 22721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// is one of the operands. Invert says whether the field should be 22731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// inverted after performing BinOpcode (e.g. for NAND). 22741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 22751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitAtomicLoadBinary(MachineInstr *MI, 22761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB, 22771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BinOpcode, 22781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitSize, 22791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool Invert) const { 22801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 22811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 22821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 22831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsSubWord = (BitSize < 32); 22841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 22851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract the operands. Base can be a register or a frame index. 22861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Src2 can be a register or immediate. 22871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 22881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Base = earlyUseOperand(MI->getOperand(1)); 22891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp = MI->getOperand(2).getImm(); 22901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Src2 = earlyUseOperand(MI->getOperand(3)); 22911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitShift = (IsSubWord ? MI->getOperand(4).getReg() : 0); 22921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NegBitShift = (IsSubWord ? MI->getOperand(5).getReg() : 0); 22931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 22941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 22951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitSize = MI->getOperand(6).getImm(); 22961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 22971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Subword operations use 32-bit registers. 22981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC = (BitSize <= 32 ? 22991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR32BitRegClass : 23001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR64BitRegClass); 23011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LOpcode = BitSize <= 32 ? SystemZ::L : SystemZ::LG; 23021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG; 23031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the right opcodes for the displacement. 23051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LOpcode = TII->getOpcodeForOffset(LOpcode, Disp); 23061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp); 23071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LOpcode && CSOpcode && "Displacement out of range"); 23081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create virtual registers for temporary results. 23101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigVal = MRI.createVirtualRegister(RC); 23111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldVal = MRI.createVirtualRegister(RC); 23121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewVal = (BinOpcode || IsSubWord ? 23131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.createVirtualRegister(RC) : Src2.getReg()); 23141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal); 23151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal); 23161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Insert a basic block for the main loop. 23181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2319842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 23201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 23211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 23231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 23241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OrigVal = L Disp(%Base) 23251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to LoopMMB 23261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 23271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(LOpcode), OrigVal) 23281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addOperand(Base).addImm(Disp).addReg(0); 23291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 23301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LoopMBB: 23321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OldVal = phi [ %OrigVal, StartMBB ], [ %Dest, LoopMBB ] 23331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedOldVal = RLL %OldVal, 0(%BitShift) 23341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedNewVal = OP %RotatedOldVal, %Src2 23351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %NewVal = RLL %RotatedNewVal, 0(%NegBitShift) 23361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Dest = CS %OldVal, %NewVal, Disp(%Base) 23371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JNE LoopMBB 23381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to DoneMMB 23391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = LoopMBB; 23401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal) 23411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigVal).addMBB(StartMBB) 23421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Dest).addMBB(LoopMBB); 23431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 23441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal) 23451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(BitShift).addImm(0); 23461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Invert) { 23471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Perform the operation normally and then invert every bit of the field. 23481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Tmp = MRI.createVirtualRegister(RC); 23491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(BinOpcode), Tmp) 23501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addOperand(Src2); 23511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (BitSize < 32) 23521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // XILF with the upper BitSize bits set. 2353259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal) 23541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Tmp).addImm(uint32_t(~0 << (32 - BitSize))); 23551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (BitSize == 32) 23561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // XILF with every bit set. 2357259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal) 23581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Tmp).addImm(~uint32_t(0)); 23591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else { 23601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use LCGR and add -1 to the result, which is more compact than 23611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // an XILF, XILH pair. 23621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Tmp2 = MRI.createVirtualRegister(RC); 23631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::LCGR), Tmp2).addReg(Tmp); 23641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::AGHI), RotatedNewVal) 23651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Tmp2).addImm(-1); 23661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 23671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (BinOpcode) 23681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // A simply binary operation. 23691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(BinOpcode), RotatedNewVal) 23701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addOperand(Src2); 23711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (IsSubWord) 23721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use RISBG to rotate Src2 into position and use it to replace the 23731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // field in RotatedOldVal. 23741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedNewVal) 23751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addReg(Src2.getReg()) 23761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addImm(32).addImm(31 + BitSize).addImm(32 - BitSize); 23771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 23781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal) 23791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0); 23801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(CSOpcode), Dest) 23811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp); 23826824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 23836824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); 23841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 23851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 23861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 23881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DoneMBB; 23891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 23901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo 23921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// ATOMIC_LOAD{,W}_{,U}{MIN,MAX} instruction MI. CompareOpcode is the 23931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// instruction that should be used to compare the current field with the 23941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// minimum or maximum value. KeepOldMask is the BRC condition-code mask 23951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// for when the current field should be kept. BitSize is the width of 23961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the field in bits, or 0 if this is a partword ATOMIC_LOADW_* instruction. 23971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 23981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitAtomicLoadMinMax(MachineInstr *MI, 23991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB, 24001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CompareOpcode, 24011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned KeepOldMask, 24021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitSize) const { 24031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 24041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 24051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 24061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsSubWord = (BitSize < 32); 24071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract the operands. Base can be a register or a frame index. 24091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 24101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Base = earlyUseOperand(MI->getOperand(1)); 24111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp = MI->getOperand(2).getImm(); 24121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Src2 = MI->getOperand(3).getReg(); 24131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitShift = (IsSubWord ? MI->getOperand(4).getReg() : 0); 24141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NegBitShift = (IsSubWord ? MI->getOperand(5).getReg() : 0); 24151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 24161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitSize = MI->getOperand(6).getImm(); 24181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Subword operations use 32-bit registers. 24201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC = (BitSize <= 32 ? 24211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR32BitRegClass : 24221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR64BitRegClass); 24231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LOpcode = BitSize <= 32 ? SystemZ::L : SystemZ::LG; 24241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG; 24251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the right opcodes for the displacement. 24271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LOpcode = TII->getOpcodeForOffset(LOpcode, Disp); 24281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp); 24291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LOpcode && CSOpcode && "Displacement out of range"); 24301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create virtual registers for temporary results. 24321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigVal = MRI.createVirtualRegister(RC); 24331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldVal = MRI.createVirtualRegister(RC); 24341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewVal = MRI.createVirtualRegister(RC); 24351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal); 24361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedAltVal = (IsSubWord ? MRI.createVirtualRegister(RC) : Src2); 24371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal); 24381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Insert 3 basic blocks for the loop. 24401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2441842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 24421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 24431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *UseAltMBB = emitBlockAfter(LoopMBB); 24441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *UpdateMBB = emitBlockAfter(UseAltMBB); 24451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 24471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 24481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OrigVal = L Disp(%Base) 24491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to LoopMMB 24501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 24511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(LOpcode), OrigVal) 24521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addOperand(Base).addImm(Disp).addReg(0); 24531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 24541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LoopMBB: 24561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OldVal = phi [ %OrigVal, StartMBB ], [ %Dest, UpdateMBB ] 24571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedOldVal = RLL %OldVal, 0(%BitShift) 24581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // CompareOpcode %RotatedOldVal, %Src2 245944b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford // BRC KeepOldMask, UpdateMBB 24601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = LoopMBB; 24611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal) 24621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigVal).addMBB(StartMBB) 24631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Dest).addMBB(UpdateMBB); 24641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal) 24661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(BitShift).addImm(0); 24670416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(CompareOpcode)) 24680416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford .addReg(RotatedOldVal).addReg(Src2); 24690416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 24706824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(KeepOldMask).addMBB(UpdateMBB); 24711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(UpdateMBB); 24721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(UseAltMBB); 24731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // UseAltMBB: 24751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedAltVal = RISBG %RotatedOldVal, %Src2, 32, 31 + BitSize, 0 24761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to UpdateMMB 24771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = UseAltMBB; 24781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedAltVal) 24801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addReg(Src2) 24811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addImm(32).addImm(31 + BitSize).addImm(0); 24821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(UpdateMBB); 24831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // UpdateMBB: 24851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedNewVal = PHI [ %RotatedOldVal, LoopMBB ], 24861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // [ %RotatedAltVal, UseAltMBB ] 24871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %NewVal = RLL %RotatedNewVal, 0(%NegBitShift) 24881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Dest = CS %OldVal, %NewVal, Disp(%Base) 24891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JNE LoopMBB 24901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to DoneMMB 24911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = UpdateMBB; 24921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), RotatedNewVal) 24931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addMBB(LoopMBB) 24941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedAltVal).addMBB(UseAltMBB); 24951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal) 24971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0); 24981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(CSOpcode), Dest) 24991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp); 25006824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 25016824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); 25021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 25031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 25041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 25061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DoneMBB; 25071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 25081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo ATOMIC_CMP_SWAPW 25101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// instruction MI. 25111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 25121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, 25131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB) const { 25141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 25151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 25161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 25171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract the operands. Base can be a register or a frame index. 25191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 25201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Base = earlyUseOperand(MI->getOperand(1)); 25211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp = MI->getOperand(2).getImm(); 25221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigCmpVal = MI->getOperand(3).getReg(); 25231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigSwapVal = MI->getOperand(4).getReg(); 25241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitShift = MI->getOperand(5).getReg(); 25251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NegBitShift = MI->getOperand(6).getReg(); 25261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t BitSize = MI->getOperand(7).getImm(); 25271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 25281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass; 25301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the right opcodes for the displacement. 25321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LOpcode = TII->getOpcodeForOffset(SystemZ::L, Disp); 25331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp); 25341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LOpcode && CSOpcode && "Displacement out of range"); 25351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create virtual registers for temporary results. 25371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigOldVal = MRI.createVirtualRegister(RC); 25381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldVal = MRI.createVirtualRegister(RC); 25391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CmpVal = MRI.createVirtualRegister(RC); 25401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SwapVal = MRI.createVirtualRegister(RC); 25411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned StoreVal = MRI.createVirtualRegister(RC); 25421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RetryOldVal = MRI.createVirtualRegister(RC); 25431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RetryCmpVal = MRI.createVirtualRegister(RC); 25441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RetrySwapVal = MRI.createVirtualRegister(RC); 25451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Insert 2 basic blocks for the loop. 25471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2548842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 25491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 25501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *SetMBB = emitBlockAfter(LoopMBB); 25511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 25531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 25541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OrigOldVal = L Disp(%Base) 25551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to LoopMMB 25561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 25571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(LOpcode), OrigOldVal) 25581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addOperand(Base).addImm(Disp).addReg(0); 25591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 25601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LoopMBB: 25621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OldVal = phi [ %OrigOldVal, EntryBB ], [ %RetryOldVal, SetMBB ] 25631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %CmpVal = phi [ %OrigCmpVal, EntryBB ], [ %RetryCmpVal, SetMBB ] 25641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %SwapVal = phi [ %OrigSwapVal, EntryBB ], [ %RetrySwapVal, SetMBB ] 25651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Dest = RLL %OldVal, BitSize(%BitShift) 25661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ The low BitSize bits contain the field 25671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // of interest. 25681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RetryCmpVal = RISBG32 %CmpVal, %Dest, 32, 63-BitSize, 0 25691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ Replace the upper 32-BitSize bits of the 25701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // comparison value with those that we loaded, 25711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // so that we can use a full word comparison. 25720416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford // CR %Dest, %RetryCmpVal 25730416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford // JNE DoneMBB 25741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # Fall through to SetMBB 25751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = LoopMBB; 25761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal) 25771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigOldVal).addMBB(StartMBB) 25781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetryOldVal).addMBB(SetMBB); 25791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), CmpVal) 25801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigCmpVal).addMBB(StartMBB) 25811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetryCmpVal).addMBB(SetMBB); 25821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), SwapVal) 25831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigSwapVal).addMBB(StartMBB) 25841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetrySwapVal).addMBB(SetMBB); 25851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), Dest) 25861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(BitShift).addImm(BitSize); 25871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetryCmpVal) 25881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(CmpVal).addReg(Dest).addImm(32).addImm(63 - BitSize).addImm(0); 25890416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::CR)) 25900416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford .addReg(Dest).addReg(RetryCmpVal); 25910416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 25926824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_ICMP) 25936824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CMP_NE).addMBB(DoneMBB); 25941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 25951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(SetMBB); 25961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // SetMBB: 25981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RetrySwapVal = RISBG32 %SwapVal, %Dest, 32, 63-BitSize, 0 25991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ Replace the upper 32-BitSize bits of the new 26001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // value with those that we loaded. 26011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %StoreVal = RLL %RetrySwapVal, -BitSize(%NegBitShift) 26021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ Rotate the new field to its proper position. 26031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RetryOldVal = CS %Dest, %StoreVal, Disp(%Base) 26041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JNE LoopMBB 26051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to ExitMMB 26061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = SetMBB; 26071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetrySwapVal) 26081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SwapVal).addReg(Dest).addImm(32).addImm(63 - BitSize).addImm(0); 26091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), StoreVal) 26101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetrySwapVal).addReg(NegBitShift).addImm(-BitSize); 26111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(CSOpcode), RetryOldVal) 26121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(StoreVal).addOperand(Base).addImm(Disp); 26136824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 26146824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); 26151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 26161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 26171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 26191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DoneMBB; 26201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 26211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Emit an extension from a GR32 or GR64 to a GR128. ClearEven is true 26231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// if the high register of the GR128 value must be cleared or false if 2624745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford// it's "don't care". SubReg is subreg_l32 when extending a GR32 2625745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford// and subreg_l64 when extending a GR64. 26261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 26271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitExt128(MachineInstr *MI, 26281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB, 26291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool ClearEven, unsigned SubReg) const { 26301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 26311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 26321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 26331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 26341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 26361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Src = MI->getOperand(1).getReg(); 26371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned In128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass); 26381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::IMPLICIT_DEF), In128); 26401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ClearEven) { 26411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewIn128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass); 26421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Zero64 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass); 26431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(SystemZ::LLILL), Zero64) 26451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addImm(0); 26461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), NewIn128) 2647745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford .addReg(In128).addReg(Zero64).addImm(SystemZ::subreg_h64); 26481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand In128 = NewIn128; 26491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 26501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), Dest) 26511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(In128).addReg(Src).addImm(SubReg); 26521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 26541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return MBB; 26551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 26561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2657dff0009d0ced62b92cb5900bc2203ec40142ba15Richard SandifordMachineBasicBlock * 2658ac168b8bc8773a083a10902f64e4ae57a925aee4Richard SandifordSystemZTargetLowering::emitMemMemWrapper(MachineInstr *MI, 2659ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford MachineBasicBlock *MBB, 2660ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford unsigned Opcode) const { 2661dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford const SystemZInstrInfo *TII = TM.getInstrInfo(); 2662842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineFunction &MF = *MBB->getParent(); 2663842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineRegisterInfo &MRI = MF.getRegInfo(); 2664dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford DebugLoc DL = MI->getDebugLoc(); 2665dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 2666842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineOperand DestBase = earlyUseOperand(MI->getOperand(0)); 2667dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford uint64_t DestDisp = MI->getOperand(1).getImm(); 2668842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineOperand SrcBase = earlyUseOperand(MI->getOperand(2)); 2669dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford uint64_t SrcDisp = MI->getOperand(3).getImm(); 2670dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford uint64_t Length = MI->getOperand(4).getImm(); 2671dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 267247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // When generating more than one CLC, all but the last will need to 267347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // branch to the end when a difference is found. 267447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *EndMBB = (Length > 256 && Opcode == SystemZ::CLC ? 267547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford splitBlockAfter(MI, MBB) : 0); 267647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 2677842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Check for the loop form, in which operand 5 is the trip count. 2678842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (MI->getNumExplicitOperands() > 5) { 2679842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford bool HaveSingleBase = DestBase.isIdenticalTo(SrcBase); 2680842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2681842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t StartCountReg = MI->getOperand(5).getReg(); 2682842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t StartSrcReg = forceReg(MI, SrcBase, TII); 2683842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t StartDestReg = (HaveSingleBase ? StartSrcReg : 2684842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford forceReg(MI, DestBase, TII)); 2685842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2686842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass; 2687842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisSrcReg = MRI.createVirtualRegister(RC); 2688842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisDestReg = (HaveSingleBase ? ThisSrcReg : 2689842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MRI.createVirtualRegister(RC)); 2690842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t NextSrcReg = MRI.createVirtualRegister(RC); 2691842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t NextDestReg = (HaveSingleBase ? NextSrcReg : 2692842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MRI.createVirtualRegister(RC)); 2693842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2694842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford RC = &SystemZ::GR64BitRegClass; 2695842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisCountReg = MRI.createVirtualRegister(RC); 2696842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t NextCountReg = MRI.createVirtualRegister(RC); 2697842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2698842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *StartMBB = MBB; 2699842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 2700842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 270147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *NextMBB = (EndMBB ? emitBlockAfter(LoopMBB) : LoopMBB); 2702842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2703842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // StartMBB: 2704842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // # fall through to LoopMMB 2705842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB->addSuccessor(LoopMBB); 2706842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2707842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // LoopMBB: 2708842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // %ThisDestReg = phi [ %StartDestReg, StartMBB ], 270947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // [ %NextDestReg, NextMBB ] 2710842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // %ThisSrcReg = phi [ %StartSrcReg, StartMBB ], 271147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // [ %NextSrcReg, NextMBB ] 2712842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // %ThisCountReg = phi [ %StartCountReg, StartMBB ], 271347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // [ %NextCountReg, NextMBB ] 271447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // ( PFD 2, 768+DestDisp(%ThisDestReg) ) 2715842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Opcode DestDisp(256,%ThisDestReg), SrcDisp(%ThisSrcReg) 271647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // ( JLH EndMBB ) 2717842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // 271847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // The prefetch is used only for MVC. The JLH is used only for CLC. 2719842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB = LoopMBB; 2720842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2721842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisDestReg) 2722842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(StartDestReg).addMBB(StartMBB) 272347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(NextDestReg).addMBB(NextMBB); 2724842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!HaveSingleBase) 2725842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisSrcReg) 2726842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(StartSrcReg).addMBB(StartMBB) 272747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(NextSrcReg).addMBB(NextMBB); 2728842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisCountReg) 2729842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(StartCountReg).addMBB(StartMBB) 273047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(NextCountReg).addMBB(NextMBB); 273147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (Opcode == SystemZ::MVC) 273247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PFD)) 273347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addImm(SystemZ::PFD_WRITE) 273447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(ThisDestReg).addImm(DestDisp + 768).addReg(0); 2735842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(Opcode)) 2736842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisDestReg).addImm(DestDisp).addImm(256) 2737842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisSrcReg).addImm(SrcDisp); 273847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (EndMBB) { 273947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 274047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE) 274147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addMBB(EndMBB); 274247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(EndMBB); 274347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(NextMBB); 274447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford } 274547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 274647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // NextMBB: 274747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // %NextDestReg = LA 256(%ThisDestReg) 274847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // %NextSrcReg = LA 256(%ThisSrcReg) 274947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // %NextCountReg = AGHI %ThisCountReg, -1 275047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // CGHI %NextCountReg, 0 275147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // JLH LoopMBB 275247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // # fall through to DoneMMB 275347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // 275447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // The AGHI, CGHI and JLH should be converted to BRCTG by later passes. 275547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB = NextMBB; 275647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 2757842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::LA), NextDestReg) 2758842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisDestReg).addImm(256).addReg(0); 2759842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!HaveSingleBase) 2760842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::LA), NextSrcReg) 2761842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisSrcReg).addImm(256).addReg(0); 2762842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::AGHI), NextCountReg) 2763842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisCountReg).addImm(-1); 2764842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::CGHI)) 2765842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(NextCountReg).addImm(0); 2766842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 2767842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE) 2768842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addMBB(LoopMBB); 2769842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB->addSuccessor(LoopMBB); 2770842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB->addSuccessor(DoneMBB); 2771842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2772842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestBase = MachineOperand::CreateReg(NextDestReg, false); 2773842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcBase = MachineOperand::CreateReg(NextSrcReg, false); 2774842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford Length &= 255; 2775842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB = DoneMBB; 2776842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2777842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Handle any remaining bytes with straight-line code. 2778842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford while (Length > 0) { 2779842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisLength = std::min(Length, uint64_t(256)); 2780842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // The previous iteration might have created out-of-range displacements. 2781842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Apply them using LAY if so. 2782842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!isUInt<12>(DestDisp)) { 2783842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass); 2784842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(SystemZ::LAY), Reg) 2785842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(DestBase).addImm(DestDisp).addReg(0); 2786842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestBase = MachineOperand::CreateReg(Reg, false); 2787842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestDisp = 0; 2788842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2789842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!isUInt<12>(SrcDisp)) { 2790842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass); 2791842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(SystemZ::LAY), Reg) 2792842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(SrcBase).addImm(SrcDisp).addReg(0); 2793842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcBase = MachineOperand::CreateReg(Reg, false); 2794842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcDisp = 0; 2795842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2796842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, DL, TII->get(Opcode)) 2797842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(DestBase).addImm(DestDisp).addImm(ThisLength) 2798842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(SrcBase).addImm(SrcDisp); 2799842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestDisp += ThisLength; 2800842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcDisp += ThisLength; 2801842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford Length -= ThisLength; 280247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // If there's another CLC to go, branch to the end if a difference 280347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // was found. 280447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (EndMBB && Length > 0) { 280547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *NextMBB = splitBlockBefore(MI, MBB); 280647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 280747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE) 280847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addMBB(EndMBB); 280947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(EndMBB); 281047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(NextMBB); 281147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB = NextMBB; 281247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford } 281347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford } 281447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (EndMBB) { 281547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(EndMBB); 281647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB = EndMBB; 281747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addLiveIn(SystemZ::CC); 2818842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2819dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 2820dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MI->eraseFromParent(); 2821dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford return MBB; 2822dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford} 2823dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 2824e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford// Decompose string pseudo-instruction MI into a loop that continually performs 2825e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford// Opcode until CC != 3. 2826e1b2af731e2a45344a7c502232f66c55cd746da0Richard SandifordMachineBasicBlock * 2827e1b2af731e2a45344a7c502232f66c55cd746da0Richard SandifordSystemZTargetLowering::emitStringWrapper(MachineInstr *MI, 2828e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineBasicBlock *MBB, 2829e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford unsigned Opcode) const { 2830e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford const SystemZInstrInfo *TII = TM.getInstrInfo(); 2831e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineFunction &MF = *MBB->getParent(); 2832e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineRegisterInfo &MRI = MF.getRegInfo(); 2833e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford DebugLoc DL = MI->getDebugLoc(); 2834e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2835e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t End1Reg = MI->getOperand(0).getReg(); 2836e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t Start1Reg = MI->getOperand(1).getReg(); 2837e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t Start2Reg = MI->getOperand(2).getReg(); 2838e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t CharReg = MI->getOperand(3).getReg(); 2839e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2840e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass; 2841e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t This1Reg = MRI.createVirtualRegister(RC); 2842e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t This2Reg = MRI.createVirtualRegister(RC); 2843e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t End2Reg = MRI.createVirtualRegister(RC); 2844e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2845e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineBasicBlock *StartMBB = MBB; 2846842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 2847e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 2848e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2849e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // StartMBB: 2850e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // # fall through to LoopMMB 2851e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB->addSuccessor(LoopMBB); 2852e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2853e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // LoopMBB: 2854e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // %This1Reg = phi [ %Start1Reg, StartMBB ], [ %End1Reg, LoopMBB ] 2855e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // %This2Reg = phi [ %Start2Reg, StartMBB ], [ %End2Reg, LoopMBB ] 2856514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford // R0L = %CharReg 2857514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford // %End1Reg, %End2Reg = CLST %This1Reg, %This2Reg -- uses R0L 2858e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // JO LoopMBB 2859e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // # fall through to DoneMMB 28608c20158fb0e1e5d747077f065eb0170c5af1fbfaRichard Sandiford // 2861514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford // The load of R0L can be hoisted by post-RA LICM. 2862e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB = LoopMBB; 2863e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2864e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), This1Reg) 2865e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(Start1Reg).addMBB(StartMBB) 2866e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(End1Reg).addMBB(LoopMBB); 2867e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), This2Reg) 2868e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(Start2Reg).addMBB(StartMBB) 2869e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(End2Reg).addMBB(LoopMBB); 2870514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford BuildMI(MBB, DL, TII->get(TargetOpcode::COPY), SystemZ::R0L).addReg(CharReg); 2871e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(Opcode)) 2872e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(End1Reg, RegState::Define).addReg(End2Reg, RegState::Define) 2873e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(This1Reg).addReg(This2Reg); 2874e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 2875e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addImm(SystemZ::CCMASK_ANY).addImm(SystemZ::CCMASK_3).addMBB(LoopMBB); 2876e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB->addSuccessor(LoopMBB); 2877e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB->addSuccessor(DoneMBB); 2878e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2879e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford DoneMBB->addLiveIn(SystemZ::CC); 2880e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2881e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MI->eraseFromParent(); 2882e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford return DoneMBB; 2883e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford} 2884e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 28851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock *SystemZTargetLowering:: 28861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandEmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const { 28871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 288847086570973e82fe5ea8ace9637ae73c2469e1daRichard Sandiford case SystemZ::Select32Mux: 28891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::Select32: 28901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::SelectF32: 28911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::Select64: 28921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::SelectF64: 28931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::SelectF128: 28941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitSelect(MI, MBB); 28951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2896722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore8: 2897b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STC, 0, false); 2898722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore8Inv: 2899b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STC, 0, true); 2900722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore16: 2901b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STH, 0, false); 2902722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore16Inv: 2903b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STH, 0, true); 2904722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore32: 2905b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, false); 2906722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore32Inv: 2907b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, true); 2908722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore64: 2909b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, false); 2910722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore64Inv: 2911b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, true); 2912722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF32: 2913b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STE, 0, false); 2914722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF32Inv: 2915b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STE, 0, true); 2916722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF64: 2917b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STD, 0, false); 2918722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF64Inv: 2919b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STD, 0, true); 2920722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 29211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::AEXT128_64: 2922745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return emitExt128(MI, MBB, false, SystemZ::subreg_l64); 29231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ZEXT128_32: 2924745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return emitExt128(MI, MBB, true, SystemZ::subreg_l32); 29251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ZEXT128_64: 2926745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return emitExt128(MI, MBB, true, SystemZ::subreg_l64); 29271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_SWAPW: 29291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, 0, 0); 29301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_SWAP_32: 29311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, 0, 32); 29321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_SWAP_64: 29331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, 0, 64); 29341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_AR: 29361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 0); 29371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_AFI: 29381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 0); 29391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AR: 29401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 32); 29411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AHI: 29421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AHI, 32); 29431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AFI: 29441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 32); 29451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AGR: 29461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AGR, 64); 29471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AGHI: 29481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AGHI, 64); 29491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AGFI: 29501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AGFI, 64); 29511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_SR: 29531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 0); 29541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_SR: 29551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 32); 29561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_SGR: 29571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::SGR, 64); 29581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NR: 29601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0); 29611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NILH: 2962259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0); 29631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NR: 29641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32); 29651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILL: 2966259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32); 29671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILH: 2968259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32); 2969259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILF: 2970259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32); 2971259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NGR: 2972259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64); 2973259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILL64: 2974259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64); 2975259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILH64: 2976259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64); 2977b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHL64: 2978b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64); 2979b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHH64: 2980b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64); 2981259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILF64: 2982259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64); 2983b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHF64: 2984b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64); 29851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_OR: 29871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 0); 29881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_OILH: 2989259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 0); 29901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_OR: 29911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 32); 29921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_OILL: 2993259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL, 32); 29941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_OILH: 2995259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 32); 2996259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILF: 2997259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF, 32); 2998259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OGR: 2999259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OGR, 64); 3000259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILL64: 3001259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL64, 64); 3002259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILH64: 3003259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH64, 64); 30041c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::ATOMIC_LOAD_OIHL64: 30051c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHL64, 64); 30061c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::ATOMIC_LOAD_OIHH64: 30071c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHH64, 64); 3008259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILF64: 3009259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF64, 64); 30101c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::ATOMIC_LOAD_OIHF64: 30111c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHF64, 64); 30121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_XR: 30141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 0); 30151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_XILF: 3016259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 0); 30171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_XR: 30181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 32); 3019259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_XILF: 3020259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 32); 30211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_XGR: 30221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::XGR, 64); 3023259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_XILF64: 3024259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF64, 64); 30251ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford case SystemZ::ATOMIC_LOAD_XIHF64: 30261ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XIHF64, 64); 30271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NRi: 30291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0, true); 30301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NILHi: 3031259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0, true); 30321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NRi: 30331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32, true); 30341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILLi: 3035259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32, true); 30361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILHi: 3037259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32, true); 3038259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILFi: 3039259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32, true); 3040259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NGRi: 3041259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64, true); 3042259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILL64i: 3043259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64, true); 3044259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILH64i: 3045259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64, true); 3046b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHL64i: 3047b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64, true); 3048b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHH64i: 3049b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64, true); 3050259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILF64i: 3051259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64, true); 3052b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHF64i: 3053b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64, true); 30541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_MIN: 30561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 0); 30581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MIN_32: 30591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 32); 30611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MIN_64: 30621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR, 30631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 64); 30641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_MAX: 30661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 0); 30681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MAX_32: 30691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 32); 30711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MAX_64: 30721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR, 30731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 64); 30741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_UMIN: 30761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 30771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 0); 30781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMIN_32: 30791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 30801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 32); 30811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMIN_64: 30821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR, 30831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 64); 30841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_UMAX: 30861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 30871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 0); 30881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMAX_32: 30891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 30901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 32); 30911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMAX_64: 30921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR, 30931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 64); 30941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_CMP_SWAPW: 30961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicCmpSwapW(MI, MBB); 3097842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::MVCSequence: 3098842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::MVCLoop: 3099ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::MVC); 310016277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::NCSequence: 310116277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::NCLoop: 310216277c4698f36a756c540fae326874774156aaedRichard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::NC); 310316277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::OCSequence: 310416277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::OCLoop: 310516277c4698f36a756c540fae326874774156aaedRichard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::OC); 310616277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::XCSequence: 310716277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::XCLoop: 310816277c4698f36a756c540fae326874774156aaedRichard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::XC); 3109842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::CLCSequence: 3110842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::CLCLoop: 3111ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::CLC); 3112e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford case SystemZ::CLSTLoop: 3113e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford return emitStringWrapper(MI, MBB, SystemZ::CLST); 31144fc7355a21e1fa838406e15459aaf54a58fcf909Richard Sandiford case SystemZ::MVSTLoop: 31154fc7355a21e1fa838406e15459aaf54a58fcf909Richard Sandiford return emitStringWrapper(MI, MBB, SystemZ::MVST); 311619262ee0725a09b7c621a3d2eb66ba1513ae932aRichard Sandiford case SystemZ::SRSTLoop: 311719262ee0725a09b7c621a3d2eb66ba1513ae932aRichard Sandiford return emitStringWrapper(MI, MBB, SystemZ::SRST); 31181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 31191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected instr type to insert"); 31201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 31211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3122