SystemZISelLowering.cpp revision e3ba15c794839abe076e3e2bdf6c626396a19d4d
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 26e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz#include <cctype> 27e3ba15c794839abe076e3e2bdf6c626396a19d4dWill Dietz 281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Classify VT as either 32 or 64 bit. 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic bool is32Bit(EVT VT) { 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (VT.getSimpleVT().SimpleTy) { 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i32: 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i64: 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported type"); 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return a version of MachineOperand that can be safely used before the 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// final use. 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic MachineOperand earlyUseOperand(MachineOperand Op) { 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Op.isReg()) 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.setIsKill(false); 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : TargetLowering(tm, new TargetLoweringObjectFileELF()), 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Subtarget(*tm.getSubtargetImpl()), TM(tm) { 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT PtrVT = getPointerTy(); 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up the register classes. 5655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (Subtarget.hasHighWord()) 5755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford addRegisterClass(MVT::i32, &SystemZ::GRX32BitRegClass); 5855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford else 5955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford addRegisterClass(MVT::i32, &SystemZ::GR32BitRegClass); 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::i64, &SystemZ::GR64BitRegClass); 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::f32, &SystemZ::FP32BitRegClass); 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::f64, &SystemZ::FP64BitRegClass); 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addRegisterClass(MVT::f128, &SystemZ::FP128BitRegClass); 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Compute derived properties from the register classes 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand computeRegisterProperties(); 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up special registers. 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setExceptionPointerRegister(SystemZ::R6D); 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setExceptionSelectorRegister(SystemZ::R7D); 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setStackPointerRegisterToSaveRestore(SystemZ::R15D); 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // TODO: It may be better to default to latency-oriented scheduling, however 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LLVM's current latency-oriented scheduler can't handle physreg definitions 75dbd8eb26ce1e7de9b69f5c46f45ba011a706c9b9Richard Sandiford // such as SystemZ has with CC, so set this to the register-pressure 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // scheduler, because it can. 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setSchedulingPreference(Sched::RegPressure); 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setBooleanContents(ZeroOrOneBooleanContent); 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Instructions are strings of 2-byte aligned 2-byte values. 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setMinFunctionAlignment(2); 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle operations that are handled in a similar way for all types. 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE; 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I <= MVT::LAST_FP_VALUETYPE; 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++I) { 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT VT = MVT::SimpleValueType(I); 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isTypeLegal(VT)) { 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand SETCC(X, Y, COND) into SELECT_CC(X, Y, 1, 0, COND). 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SETCC, VT, Expand); 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand SELECT(C, A, B) into SELECT_CC(X, 0, A, B, NE). 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SELECT, VT, Expand); 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower SELECT_CC and BR_CC into separate comparisons and branches. 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SELECT_CC, VT, Custom); 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BR_CC, VT, Custom); 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand jump table branches as address arithmetic followed by an 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // indirect jump. 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BR_JT, MVT::Other, Expand); 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand BRCOND into a BR_CC (see above). 1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle integer types. 1111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = MVT::FIRST_INTEGER_VALUETYPE; 1121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I <= MVT::LAST_INTEGER_VALUETYPE; 1131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++I) { 1141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT VT = MVT::SimpleValueType(I); 1151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isTypeLegal(VT)) { 1161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand individual DIV and REMs into DIVREMs. 1171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SDIV, VT, Expand); 1181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UDIV, VT, Expand); 1191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SREM, VT, Expand); 1201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UREM, VT, Expand); 1211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SDIVREM, VT, Custom); 1221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UDIVREM, VT, Custom); 1231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Expand ATOMIC_LOAD and ATOMIC_STORE using ATOMIC_CMP_SWAP. 1251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: probably much too conservative. 1261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD, VT, Expand); 1271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_STORE, VT, Expand); 1281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // No special instructions for these. 1301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTPOP, VT, Expand); 1311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTTZ, VT, Expand); 1321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTTZ_ZERO_UNDEF, VT, Expand); 1331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTLZ_ZERO_UNDEF, VT, Expand); 1341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ROTR, VT, Expand); 1351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 136df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Use *MUL_LOHI where possible instead of MULH*. 1371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::MULHS, VT, Expand); 1381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::MULHU, VT, Expand); 139df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford setOperationAction(ISD::SMUL_LOHI, VT, Custom); 140df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford setOperationAction(ISD::UMUL_LOHI, VT, Custom); 1411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have instructions for signed but not unsigned FP conversion. 1431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FP_TO_UINT, VT, Expand); 1441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Type legalization will convert 8- and 16-bit atomic operations into 1481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // forms that operate on i32s (but still keeping the original memory VT). 1491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Lower them into full i32 operations. 1501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Custom); 1511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, Custom); 1521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i32, Custom); 1531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, Custom); 1541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, Custom); 1551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, Custom); 1561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, Custom); 1571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i32, Custom); 1581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i32, Custom); 1591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, Custom); 1601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, Custom); 1611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Custom); 1621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have instructions for signed but not unsigned FP conversion. 1641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle unsigned 32-bit types as signed 64-bit types. 1651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); 1661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 1671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have native support for a 64-bit CTLZ, via FLOGR. 1691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTLZ, MVT::i32, Promote); 1701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::CTLZ, MVT::i64, Legal); 1711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Give LowerOperation the chance to replace 64-bit ORs with subregs. 1731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::OR, MVT::i64, Custom); 1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: Can we support these natively? 1761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand); 1771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand); 1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand); 1791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have native instructions for i8, i16 and i32 extensions, but not i1. 1811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 1821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 1831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 1841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 1851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle the various types of symbolic address. 1871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::ConstantPool, PtrVT, Custom); 1881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::GlobalAddress, PtrVT, Custom); 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom); 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BlockAddress, PtrVT, Custom); 1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::JumpTable, PtrVT, Custom); 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We need to handle dynamic allocations specially because of the 1941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 160-byte area at the bottom of the stack. 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use custom expanders so that we can force the function to use 1981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // a frame pointer. 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::STACKSAVE, MVT::Other, Custom); 2001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::STACKRESTORE, MVT::Other, Custom); 2011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 202a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford // Handle prefetches with PFD or PFDRL. 203a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford setOperationAction(ISD::PREFETCH, MVT::Other, Custom); 204a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford 2051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle floating-point types. 2061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = MVT::FIRST_FP_VALUETYPE; 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I <= MVT::LAST_FP_VALUETYPE; 2081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++I) { 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MVT VT = MVT::SimpleValueType(I); 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isTypeLegal(VT)) { 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We can use FI for FRINT. 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FRINT, VT, Legal); 2131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 214d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford // We can use the extended form of FI for other rounding operations. 215d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford if (Subtarget.hasFPExtension()) { 216d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FNEARBYINT, VT, Legal); 217d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FFLOOR, VT, Legal); 218d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FCEIL, VT, Legal); 219d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FTRUNC, VT, Legal); 220d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford setOperationAction(ISD::FROUND, VT, Legal); 221d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford } 222d95865a2a2daeb7dd8b80c18e7409b28e7e4738aRichard Sandiford 2231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // No special instructions for these. 2241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FSIN, VT, Expand); 2251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FCOS, VT, Expand); 2261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FREM, VT, Expand); 2271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have fused multiply-addition for f32 and f64 but not f128. 2311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FMA, MVT::f32, Legal); 2321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FMA, MVT::f64, Legal); 2331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::FMA, MVT::f128, Expand); 2341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Needed so that we don't try to implement f128 constant loads using 2361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // a load-and-extend of a f80 constant (in cases where the constant 2371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // would fit in an f80). 2381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setLoadExtAction(ISD::EXTLOAD, MVT::f80, Expand); 2391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Floating-point truncation and stores need to be done separately. 2411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setTruncStoreAction(MVT::f64, MVT::f32, Expand); 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setTruncStoreAction(MVT::f128, MVT::f32, Expand); 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setTruncStoreAction(MVT::f128, MVT::f64, Expand); 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have 64-bit FPR<->GPR moves, but need special handling for 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 32-bit forms. 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BITCAST, MVT::i32, Custom); 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::BITCAST, MVT::f32, Custom); 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // VASTART and VACOPY need to deal with the SystemZ-specific varargs 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // structure, but VAEND is a no-op. 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::VASTART, MVT::Other, Custom); 2531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::VACOPY, MVT::Other, Custom); 2541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand setOperationAction(ISD::VAEND, MVT::Other, Expand); 255dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 256dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford // We want to use MVC in preference to even a single load/store pair. 257dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MaxStoresPerMemcpy = 0; 258dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MaxStoresPerMemcpyOptSize = 0; 259f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford 260f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // The main memset sequence is a byte store followed by an MVC. 261f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // Two STC or MV..I stores win over that, but the kind of fused stores 262f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // generated by target-independent code don't when the byte value is 263f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // variable. E.g. "STC <reg>;MHI <reg>,257;STH <reg>" is not better 264f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // than "STC;MVC". Handle the choice in target-specific code instead. 265f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford MaxStoresPerMemset = 0; 266f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford MaxStoresPerMemsetOptSize = 0; 2671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 269e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Linbool 270e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen LinSystemZTargetLowering::isFMAFasterThanFMulAndFAdd(EVT VT) const { 271e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin VT = VT.getScalarType(); 272e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 273e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin if (!VT.isSimple()) 274e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return false; 275e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 276e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin switch (VT.getSimpleVT().SimpleTy) { 277e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin case MVT::f32: 278e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin case MVT::f64: 279e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return true; 280e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin case MVT::f128: 281e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return false; 282e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin default: 283e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin break; 284e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin } 285e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 286e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin return false; 287e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin} 288e54885af9b54bfc7436a928a48d3db1ef88a2a70Stephen Lin 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { 2901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We can load zero using LZ?R and negative zero using LZ?R;LC?BR. 2911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Imm.isZero() || Imm.isNegZero(); 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29414a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandifordbool SystemZTargetLowering::allowsUnalignedMemoryAccesses(EVT VT, 29514a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford bool *Fast) const { 29614a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford // Unaligned accesses should never be slower than the expanded version. 29714a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford // We check specifically for aligned accesses in the few cases where 29814a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford // they are required. 29914a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford if (Fast) 30014a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford *Fast = true; 30114a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford return true; 30214a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford} 30314a926f13b768ee3771bb944bbbb29529a40dbe1Richard Sandiford 30404ded924f3583438c6633823eddb87761fa73cceRichard Sandifordbool SystemZTargetLowering::isLegalAddressingMode(const AddrMode &AM, 30504ded924f3583438c6633823eddb87761fa73cceRichard Sandiford Type *Ty) const { 30604ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // Punt on globals for now, although they can be used in limited 30704ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // RELATIVE LONG cases. 30804ded924f3583438c6633823eddb87761fa73cceRichard Sandiford if (AM.BaseGV) 30904ded924f3583438c6633823eddb87761fa73cceRichard Sandiford return false; 31004ded924f3583438c6633823eddb87761fa73cceRichard Sandiford 31104ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // Require a 20-bit signed offset. 31204ded924f3583438c6633823eddb87761fa73cceRichard Sandiford if (!isInt<20>(AM.BaseOffs)) 31304ded924f3583438c6633823eddb87761fa73cceRichard Sandiford return false; 31404ded924f3583438c6633823eddb87761fa73cceRichard Sandiford 31504ded924f3583438c6633823eddb87761fa73cceRichard Sandiford // Indexing is OK but no scale factor can be applied. 31604ded924f3583438c6633823eddb87761fa73cceRichard Sandiford return AM.Scale == 0 || AM.Scale == 1; 31704ded924f3583438c6633823eddb87761fa73cceRichard Sandiford} 31804ded924f3583438c6633823eddb87761fa73cceRichard Sandiford 31980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::isTruncateFree(Type *FromType, Type *ToType) const { 32080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!FromType->isIntegerTy() || !ToType->isIntegerTy()) 32180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 32280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned FromBits = FromType->getPrimitiveSizeInBits(); 32380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned ToBits = ToType->getPrimitiveSizeInBits(); 32480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return FromBits > ToBits; 32580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 32680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 32780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::isTruncateFree(EVT FromVT, EVT ToVT) const { 32880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!FromVT.isInteger() || !ToVT.isInteger()) 32980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 33080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned FromBits = FromVT.getSizeInBits(); 33180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned ToBits = ToVT.getSizeInBits(); 33280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return FromBits > ToBits; 33380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 33480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 3351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Inline asm support 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 3381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandTargetLowering::ConstraintType 3401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::getConstraintType(const std::string &Constraint) const { 3411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Constraint.size() == 1) { 3421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Constraint[0]) { 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'a': // Address register 3441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'd': // Data register (equivalent to 'r') 3451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'f': // Floating-point register 34655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case 'h': // High-part register 3471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'r': // General-purpose register 3481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return C_RegisterClass; 3491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'Q': // Memory with base and unsigned 12-bit displacement 3511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'R': // Likewise, plus an index 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'S': // Memory with base and signed 20-bit displacement 3531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'T': // Likewise, plus an index 3541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'm': // Equivalent to 'T'. 3551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return C_Memory; 3561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'I': // Unsigned 8-bit constant 3581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'J': // Unsigned 12-bit constant 3591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'K': // Signed 16-bit constant 3601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'L': // Signed 20-bit displacement (on all targets we support) 3611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'M': // 0x7fffffff 3621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return C_Other; 3631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return TargetLowering::getConstraintType(Constraint); 3691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandTargetLowering::ConstraintWeight SystemZTargetLowering:: 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandgetSingleConstraintMatchWeight(AsmOperandInfo &info, 3731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const char *constraint) const { 3741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ConstraintWeight weight = CW_Invalid; 3751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value *CallOperandVal = info.CallOperandVal; 3761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If we don't have a value, we can't do a match, 3771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // but allow it at the lowest weight. 3781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CallOperandVal == NULL) 3791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return CW_Default; 3801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Type *type = CallOperandVal->getType(); 3811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Look at the constraint type. 3821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (*constraint) { 3831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 3841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); 3851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'a': // Address register 3881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'd': // Data register (equivalent to 'r') 38955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case 'h': // High-part register 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'r': // General-purpose register 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CallOperandVal->getType()->isIntegerTy()) 3921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Register; 3931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'f': // Floating-point register 3961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (type->isFloatingPointTy()) 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Register; 3981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'I': // Unsigned 8-bit constant 4011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<8>(C->getZExtValue())) 4031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'J': // Unsigned 12-bit constant 4071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(C->getZExtValue())) 4091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'K': // Signed 16-bit constant 4131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(C->getSExtValue())) 4151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'L': // Signed 20-bit displacement (on all targets we support) 4191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(C->getSExtValue())) 4211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'M': // 0x7fffffff 4251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantInt *C = dyn_cast<ConstantInt>(CallOperandVal)) 4261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (C->getZExtValue() == 0x7fffffff) 4271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand weight = CW_Constant; 4281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 4291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return weight; 4311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 4321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4335e009541973b7935386055066689902aa7134e2dRichard Sandiford// Parse a "{tNNN}" register constraint for which the register type "t" 4345e009541973b7935386055066689902aa7134e2dRichard Sandiford// has already been verified. MC is the class associated with "t" and 4355e009541973b7935386055066689902aa7134e2dRichard Sandiford// Map maps 0-based register numbers to LLVM register numbers. 4365e009541973b7935386055066689902aa7134e2dRichard Sandifordstatic std::pair<unsigned, const TargetRegisterClass *> 4375e009541973b7935386055066689902aa7134e2dRichard SandifordparseRegisterNumber(const std::string &Constraint, 4385e009541973b7935386055066689902aa7134e2dRichard Sandiford const TargetRegisterClass *RC, const unsigned *Map) { 4395e009541973b7935386055066689902aa7134e2dRichard Sandiford assert(*(Constraint.end()-1) == '}' && "Missing '}'"); 4405e009541973b7935386055066689902aa7134e2dRichard Sandiford if (isdigit(Constraint[2])) { 4415e009541973b7935386055066689902aa7134e2dRichard Sandiford std::string Suffix(Constraint.data() + 2, Constraint.size() - 2); 4425e009541973b7935386055066689902aa7134e2dRichard Sandiford unsigned Index = atoi(Suffix.c_str()); 4435e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Index < 16 && Map[Index]) 4445e009541973b7935386055066689902aa7134e2dRichard Sandiford return std::make_pair(Map[Index], RC); 4455e009541973b7935386055066689902aa7134e2dRichard Sandiford } 4465e009541973b7935386055066689902aa7134e2dRichard Sandiford return std::make_pair(0u, static_cast<TargetRegisterClass*>(0)); 4475e009541973b7935386055066689902aa7134e2dRichard Sandiford} 4485e009541973b7935386055066689902aa7134e2dRichard Sandiford 4491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstd::pair<unsigned, const TargetRegisterClass *> SystemZTargetLowering:: 4505b3fca50a08865f0db55fc92ad1c037a04e12177Chad RosiergetRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const { 4511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Constraint.size() == 1) { 4521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // GCC Constraint Letters 4531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Constraint[0]) { 4541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: break; 4551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'd': // Data register (equivalent to 'r') 4561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'r': // General-purpose register 4571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VT == MVT::i64) 4581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::GR64BitRegClass); 4591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VT == MVT::i128) 4601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::GR128BitRegClass); 4611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::GR32BitRegClass); 4621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 4631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'a': // Address register 4641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VT == MVT::i64) 4651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::ADDR64BitRegClass); 4661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VT == MVT::i128) 4671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::ADDR128BitRegClass); 4681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::ADDR32BitRegClass); 4691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 47055d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case 'h': // High-part register (an LLVM extension) 47155d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return std::make_pair(0U, &SystemZ::GRH32BitRegClass); 47255d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 4731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'f': // Floating-point register 4741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VT == MVT::f64) 4751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::FP64BitRegClass); 4761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VT == MVT::f128) 4771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::FP128BitRegClass); 4781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return std::make_pair(0U, &SystemZ::FP32BitRegClass); 4791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 4815e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Constraint[0] == '{') { 4825e009541973b7935386055066689902aa7134e2dRichard Sandiford // We need to override the default register parsing for GPRs and FPRs 4835e009541973b7935386055066689902aa7134e2dRichard Sandiford // because the interpretation depends on VT. The internal names of 4845e009541973b7935386055066689902aa7134e2dRichard Sandiford // the registers are also different from the external names 4855e009541973b7935386055066689902aa7134e2dRichard Sandiford // (F0D and F0S instead of F0, etc.). 4865e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Constraint[1] == 'r') { 4875e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::i32) 4885e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::GR32BitRegClass, 4895e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::GR32Regs); 4905e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::i128) 4915e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::GR128BitRegClass, 4925e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::GR128Regs); 4935e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::GR64BitRegClass, 4945e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::GR64Regs); 4955e009541973b7935386055066689902aa7134e2dRichard Sandiford } 4965e009541973b7935386055066689902aa7134e2dRichard Sandiford if (Constraint[1] == 'f') { 4975e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::f32) 4985e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::FP32BitRegClass, 4995e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::FP32Regs); 5005e009541973b7935386055066689902aa7134e2dRichard Sandiford if (VT == MVT::f128) 5015e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::FP128BitRegClass, 5025e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::FP128Regs); 5035e009541973b7935386055066689902aa7134e2dRichard Sandiford return parseRegisterNumber(Constraint, &SystemZ::FP64BitRegClass, 5045e009541973b7935386055066689902aa7134e2dRichard Sandiford SystemZMC::FP64Regs); 5055e009541973b7935386055066689902aa7134e2dRichard Sandiford } 5065e009541973b7935386055066689902aa7134e2dRichard Sandiford } 5071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 5081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZTargetLowering:: 5111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandLowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, 5121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand std::vector<SDValue> &Ops, 5131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 5141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Only support length 1 constraints for now. 5151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Constraint.length() == 1) { 5161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Constraint[0]) { 5171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'I': // Unsigned 8-bit constant 5181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<8>(C->getZExtValue())) 5201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), 5211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'J': // Unsigned 12-bit constant 5251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(C->getZExtValue())) 5271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), 5281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'K': // Signed 16-bit constant 5321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(C->getSExtValue())) 5341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getSExtValue(), 5351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'L': // Signed 20-bit displacement (on all targets we support) 5391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(C->getSExtValue())) 5411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getSExtValue(), 5421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case 'M': // 0x7fffffff 5461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) 5471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (C->getZExtValue() == 0x7fffffff) 5481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getTargetConstant(C->getZExtValue(), 5491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getValueType())); 5501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); 5541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 5571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Calling conventions 5581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 5591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZGenCallingConv.inc" 5611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 56280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::allowTruncateForTailCall(Type *FromType, 56380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Type *ToType) const { 56480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return isTruncateFree(FromType, ToType); 56580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 56680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 56780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordbool SystemZTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { 56880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!CI->isTailCall()) 56980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 57080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return true; 57180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 57280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 5731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Value is a value that has been passed to us in the location described by VA 5741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// (and so has type VA.getLocVT()). Convert Value to VA.getValVT(), chaining 5751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// any loads onto Chain. 576ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue convertLocVTToValVT(SelectionDAG &DAG, SDLoc DL, 5771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA, SDValue Chain, 5781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Value) { 5791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the argument has been promoted from a smaller type, insert an 5801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // assertion to capture this. 5811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocInfo() == CCValAssign::SExt) 5821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Value, 5831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getValueType(VA.getValVT())); 5841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VA.getLocInfo() == CCValAssign::ZExt) 5851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Value, 5861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getValueType(VA.getValVT())); 5871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.isExtInLoc()) 5891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Value); 5901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (VA.getLocInfo() == CCValAssign::Indirect) 5911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = DAG.getLoad(VA.getValVT(), DL, Chain, Value, 5921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(), false, false, false, 0); 5931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 5941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.getLocInfo() == CCValAssign::Full && "Unsupported getLocInfo"); 5951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Value; 5961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Value is a value of type VA.getValVT() that we need to copy into 5991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the location described by VA. Return a copy of Value converted to 6001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// VA.getValVT(). The caller is responsible for handling indirect values. 601ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic SDValue convertValVTToLocVT(SelectionDAG &DAG, SDLoc DL, 6021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA, SDValue Value) { 6031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (VA.getLocInfo()) { 6041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::SExt: 6051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Value); 6061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::ZExt: 6071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Value); 6081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::AExt: 6091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Value); 6101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case CCValAssign::Full: 6111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Value; 6121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 6131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unhandled getLocInfo()"); 6141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering:: 6181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandLowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 6191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<ISD::InputArg> &Ins, 620ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG, 6211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<SDValue> &InVals) const { 6221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 6231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFI = MF.getFrameInfo(); 6241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 6251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *FuncInfo = 6261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>(); 6271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZFrameLowering *TFL = 6281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand static_cast<const SystemZFrameLowering *>(TM.getFrameLowering()); 6291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Assign locations to all of the incoming arguments. 6311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> ArgLocs; 6321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState CCInfo(CallConv, IsVarArg, MF, TM, ArgLocs, *DAG.getContext()); 6331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCInfo.AnalyzeFormalArguments(Ins, CC_SystemZ); 6341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumFixedGPRs = 0; 6361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumFixedFPRs = 0; 6371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { 6381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgValue; 6391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = ArgLocs[I]; 6401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT LocVT = VA.getLocVT(); 6411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.isRegLoc()) { 6421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Arguments passed in registers 6431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC; 6441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (LocVT.getSimpleVT().SimpleTy) { 6451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 6461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Integers smaller than i64 should be promoted to i64. 6471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected argument type"); 6481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i32: 6491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedGPRs += 1; 6501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::GR32BitRegClass; 6511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::i64: 6531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedGPRs += 1; 6541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::GR64BitRegClass; 6551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::f32: 6571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedFPRs += 1; 6581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::FP32BitRegClass; 6591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case MVT::f64: 6611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NumFixedFPRs += 1; 6621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC = &SystemZ::FP64BitRegClass; 6631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 6641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned VReg = MRI.createVirtualRegister(RC); 6671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.addLiveIn(VA.getLocReg(), VReg); 6681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, LocVT); 6691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 6701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.isMemLoc() && "Argument not register or memory"); 6711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create the frame index object for this incoming parameter. 6731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FI = MFI->CreateFixedObject(LocVT.getSizeInBits() / 8, 6741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand VA.getLocMemOffset(), true); 6751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create the SelectionDAG nodes corresponding to a load 6771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // from this parameter. Unpromoted ints and floats are 6781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // passed as right-justified 8-byte values. 6791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 6801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FIN = DAG.getFrameIndex(FI, PtrVT); 6811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32) 6821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FIN = DAG.getNode(ISD::ADD, DL, PtrVT, FIN, DAG.getIntPtrConstant(4)); 6831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = DAG.getLoad(LocVT, DL, Chain, FIN, 6841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getFixedStack(FI), 6851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, false, 0); 6861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Convert the value of the argument register into the value that's 6891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // being passed. 6901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue)); 6911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 6921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsVarArg) { 6941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Save the number of non-varargs registers for later use by va_start, etc. 6951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setVarArgsFirstGPR(NumFixedGPRs); 6961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setVarArgsFirstFPR(NumFixedFPRs); 6971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Likewise the address (in the form of a frame index) of where the 6991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // first stack vararg would be. The 1-byte size here is arbitrary. 7001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t StackSize = CCInfo.getNextStackOffset(); 7011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, StackSize, true)); 7021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ...and a similar frame index for the caller-allocated save area 7041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // that will be used to store the incoming registers. 7051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t RegSaveOffset = TFL->getOffsetOfLocalArea(); 7061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RegSaveIndex = MFI->CreateFixedObject(1, RegSaveOffset, true); 7071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FuncInfo->setRegSaveFrameIndex(RegSaveIndex); 7081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Store the FPR varargs in the reserved frame slots. (We store the 7101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // GPRs as part of the prologue.) 7111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NumFixedFPRs < SystemZ::NumArgFPRs) { 7121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue MemOps[SystemZ::NumArgFPRs]; 7131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = NumFixedFPRs; I < SystemZ::NumArgFPRs; ++I) { 7141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = TFL->getRegSpillOffset(SystemZ::ArgFPRs[I]); 7151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FI = MFI->CreateFixedObject(8, RegSaveOffset + Offset, true); 7161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); 7171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned VReg = MF.addLiveIn(SystemZ::ArgFPRs[I], 7181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::FP64BitRegClass); 7191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, MVT::f64); 7201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOps[I] = DAG.getStore(ArgValue.getValue(1), DL, ArgValue, FIN, 7211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getFixedStack(FI), 7221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0); 7231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Join the stores, which are independent of one another. 7261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, 7271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &MemOps[NumFixedFPRs], 7281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::NumArgFPRs - NumFixedFPRs); 7291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 7311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Chain; 7331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 7341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 73580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandifordstatic bool canUseSiblingCall(CCState ArgCCInfo, 73680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford SmallVectorImpl<CCValAssign> &ArgLocs) { 73780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // Punt if there are any indirect or stack arguments, or if the call 73880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // needs the call-saved argument register R6. 73980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { 74080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford CCValAssign &VA = ArgLocs[I]; 74180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (VA.getLocInfo() == CCValAssign::Indirect) 74280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 74380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!VA.isRegLoc()) 74480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 74580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford unsigned Reg = VA.getLocReg(); 74655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (Reg == SystemZ::R6H || Reg == SystemZ::R6L || Reg == SystemZ::R6D) 74780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return false; 74880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford } 74980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return true; 75080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford} 75180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 7521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue 7531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, 7541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<SDValue> &InVals) const { 7551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG = CLI.DAG; 756ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &DL = CLI.DL; 757a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 758a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 759a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 7601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = CLI.Chain; 7611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Callee = CLI.Callee; 76280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford bool &IsTailCall = CLI.IsTailCall; 7631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CallingConv::ID CallConv = CLI.CallConv; 7641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsVarArg = CLI.IsVarArg; 7651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 7661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 7671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Analyze the operands of the call, assigning locations to each operand. 7691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> ArgLocs; 7701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState ArgCCInfo(CallConv, IsVarArg, MF, TM, ArgLocs, *DAG.getContext()); 7711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgCCInfo.AnalyzeCallOperands(Outs, CC_SystemZ); 7721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 77380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // We don't support GuaranteedTailCallOpt, only automatically-detected 77480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // sibling calls. 77580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (IsTailCall && !canUseSiblingCall(ArgCCInfo, ArgLocs)) 77680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford IsTailCall = false; 77780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 7781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get a count of how many bytes are to be pushed on the stack. 7791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumBytes = ArgCCInfo.getNextStackOffset(); 7801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Mark the start of the call. 78280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (!IsTailCall) 78380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes, PtrVT, true), 78480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford DL); 7851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy argument values to their designated locations. 7871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<std::pair<unsigned, SDValue>, 9> RegsToPass; 7881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<SDValue, 8> MemOpChains; 7891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue StackPtr; 7901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) { 7911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = ArgLocs[I]; 7921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgValue = OutVals[I]; 7931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 7941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocInfo() == CCValAssign::Indirect) { 7951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Store the argument in a stack slot and pass its address. 7961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT()); 7971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex(); 7981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOpChains.push_back(DAG.getStore(Chain, DL, ArgValue, SpillSlot, 7991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getFixedStack(FI), 8001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0)); 8011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = SpillSlot; 8021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 8031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ArgValue = convertValVTToLocVT(DAG, DL, VA, ArgValue); 8041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.isRegLoc()) 8061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Queue up the argument copies and emit them at the end. 8071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue)); 8081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else { 8091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.isMemLoc() && "Argument not register or memory"); 8101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Work out the address of the stack slot. Unpromoted ints and 8121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // floats are passed as right-justified 8-byte values. 8131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!StackPtr.getNode()) 8141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StackPtr = DAG.getCopyFromReg(Chain, DL, SystemZ::R15D, PtrVT); 8151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = SystemZMC::CallFrameSize + VA.getLocMemOffset(); 8161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (VA.getLocVT() == MVT::i32 || VA.getLocVT() == MVT::f32) 8171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset += 4; 8181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, 8191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getIntPtrConstant(Offset)); 8201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Emit the store. 8221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOpChains.push_back(DAG.getStore(Chain, DL, ArgValue, Address, 8231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(), 8241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0)); 8251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 8261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 8271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Join the stores, which are independent of one another. 8291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!MemOpChains.empty()) 8301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, 8311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &MemOpChains[0], MemOpChains.size()); 8321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Accept direct calls by converting symbolic call addresses to the 83480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // associated Target* opcodes. Force %r1 to be used for indirect 83580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // tail calls. 83680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford SDValue Glue; 8371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { 8381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, PtrVT); 8391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee); 8401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) { 8411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT); 8421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Callee = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Callee); 84380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford } else if (IsTailCall) { 84480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R1D, Callee, Glue); 84580f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Glue = Chain.getValue(1); 84680f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Callee = DAG.getRegister(SystemZ::R1D, Callee.getValueType()); 84780f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford } 84880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford 84980f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford // Build a sequence of copy-to-reg nodes, chained and glued together. 85080f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) { 85180f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[I].first, 85280f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford RegsToPass[I].second, Glue); 85380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford Glue = Chain.getValue(1); 8541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 8551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The first call operand is the chain and the second is the target address. 8571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<SDValue, 8> Ops; 8581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Chain); 8591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Callee); 8601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add argument registers to the end of the list so that they are 8621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // known live into the call. 8631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) 8641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getRegister(RegsToPass[I].first, 8651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RegsToPass[I].second.getValueType())); 8661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Glue the call to the argument copies, if any. 8681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Glue.getNode()) 8691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Glue); 8701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Emit the call. 8721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 87380f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford if (IsTailCall) 87480f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford return DAG.getNode(SystemZISD::SIBCALL, DL, NodeTys, &Ops[0], Ops.size()); 8751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getNode(SystemZISD::CALL, DL, NodeTys, &Ops[0], Ops.size()); 8761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = Chain.getValue(1); 8771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Mark the end of the call, which is glued to the call itself. 8791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getCALLSEQ_END(Chain, 8801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(NumBytes, PtrVT, true), 8811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, PtrVT, true), 8826e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick Glue, DL); 8831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = Chain.getValue(1); 8841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Assign locations to each value returned by this call. 8861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> RetLocs; 8871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState RetCCInfo(CallConv, IsVarArg, MF, TM, RetLocs, *DAG.getContext()); 8881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetCCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ); 8891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy all of the result registers out of their specified physreg. 8911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) { 8921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = RetLocs[I]; 8931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy the value out, gluing the copy to the end of the call sequence. 8951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue RetValue = DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), 8961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand VA.getLocVT(), Glue); 8971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = RetValue.getValue(1); 8981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = RetValue.getValue(2); 8991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Convert the value of the return register into the value that's 9011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // being returned. 9021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, RetValue)); 9031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 9041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Chain; 9061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue 9091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::LowerReturn(SDValue Chain, 9101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CallingConv::ID CallConv, bool IsVarArg, 9111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<ISD::OutputArg> &Outs, 9121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<SDValue> &OutVals, 913ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL, SelectionDAG &DAG) const { 9141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 9151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Assign locations to each returned value. 9171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<CCValAssign, 16> RetLocs; 9181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCState RetCCInfo(CallConv, IsVarArg, MF, TM, RetLocs, *DAG.getContext()); 9191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetCCInfo.AnalyzeReturn(Outs, RetCC_SystemZ); 9201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Quick exit for void returns 9221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (RetLocs.empty()) 9231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::RET_FLAG, DL, MVT::Other, Chain); 9241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy the result values into the output registers. 9261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Glue; 9271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVector<SDValue, 4> RetOps; 9281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.push_back(Chain); 9291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) { 9301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCValAssign &VA = RetLocs[I]; 9311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue RetValue = OutVals[I]; 9321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make the return register live on exit. 9341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(VA.isRegLoc() && "Can only return in registers!"); 9351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Promote the value as required. 9371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetValue = convertValVTToLocVT(DAG, DL, VA, RetValue); 9381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Chain and glue the copies together. 9401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg = VA.getLocReg(); 9411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getCopyToReg(Chain, DL, Reg, RetValue, Glue); 9421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Glue = Chain.getValue(1); 9431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.push_back(DAG.getRegister(Reg, VA.getLocVT())); 9441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 9451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Update chain and glue. 9471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps[0] = Chain; 9481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Glue.getNode()) 9491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.push_back(Glue); 9501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::RET_FLAG, DL, MVT::Other, 9521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RetOps.data(), RetOps.size()); 9531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// CC is a comparison that will be implemented using an integer or 9561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// floating-point comparison. Return the condition code mask for 9571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// a branch on true. In the integer case, CCMASK_CMP_UO is set for 9581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// unsigned comparisons and clear for signed ones. In the floating-point 9591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// case, CCMASK_CMP_UO has its normal mask meaning (unordered). 9601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic unsigned CCMaskForCondCode(ISD::CondCode CC) { 9611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define CONV(X) \ 9621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \ 9631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \ 9641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X 9651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (CC) { 9671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 9681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Invalid integer condition!"); 9691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(EQ); 9711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(NE); 9721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(GT); 9731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(GE); 9741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(LT); 9751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CONV(LE); 9761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETO: return SystemZ::CCMASK_CMP_O; 9781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SETUO: return SystemZ::CCMASK_CMP_UO; 9791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 9801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#undef CONV 9811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 9821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 9831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// If a comparison described by IsUnsigned, CCMask, CmpOp0 and CmpOp1 9843237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford// can be converted to a comparison against zero, adjust the operands 9853237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford// as necessary. 9863237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandifordstatic void adjustZeroCmp(SelectionDAG &DAG, bool &IsUnsigned, 9873237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford SDValue &CmpOp0, SDValue &CmpOp1, 9883237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford unsigned &CCMask) { 9893237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford if (IsUnsigned) 9903237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford return; 9913237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford 9923237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford ConstantSDNode *ConstOp1 = dyn_cast<ConstantSDNode>(CmpOp1.getNode()); 9933237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford if (!ConstOp1) 9943237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford return; 9953237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford 9963237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford int64_t Value = ConstOp1->getSExtValue(); 9973237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford if ((Value == -1 && CCMask == SystemZ::CCMASK_CMP_GT) || 9983237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford (Value == -1 && CCMask == SystemZ::CCMASK_CMP_LE) || 9993237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford (Value == 1 && CCMask == SystemZ::CCMASK_CMP_LT) || 10003237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford (Value == 1 && CCMask == SystemZ::CCMASK_CMP_GE)) { 10013237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford CCMask ^= SystemZ::CCMASK_CMP_EQ; 10023237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford CmpOp1 = DAG.getConstant(0, CmpOp1.getValueType()); 10033237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford } 10043237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford} 10053237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford 10063237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford// If a comparison described by IsUnsigned, CCMask, CmpOp0 and CmpOp1 10071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// is suitable for CLI(Y), CHHSI or CLHHSI, adjust the operands as necessary. 10081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic void adjustSubwordCmp(SelectionDAG &DAG, bool &IsUnsigned, 10091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue &CmpOp0, SDValue &CmpOp1, 10101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &CCMask) { 10111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // For us to make any changes, it must a comparison between a single-use 10121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // load and a constant. 10131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!CmpOp0.hasOneUse() || 10141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CmpOp0.getOpcode() != ISD::LOAD || 10151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CmpOp1.getOpcode() != ISD::Constant) 10161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We must have an 8- or 16-bit load. 10191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadSDNode *Load = cast<LoadSDNode>(CmpOp0); 10201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NumBits = Load->getMemoryVT().getStoreSizeInBits(); 10211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NumBits != 8 && NumBits != 16) 10221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The load must be an extending one and the constant must be within the 10251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // range of the unextended value. 10261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ConstantSDNode *Constant = cast<ConstantSDNode>(CmpOp1); 10271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Value = Constant->getZExtValue(); 10281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Mask = (1 << NumBits) - 1; 10291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Load->getExtensionType() == ISD::SEXTLOAD) { 10301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t SignedValue = Constant->getSExtValue(); 103112cba852f550ae2d2fdb6b6be28d087aae585a76Aaron Ballman if (uint64_t(SignedValue) + (1ULL << (NumBits - 1)) > Mask) 10321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Unsigned comparison between two sign-extended values is equivalent 10341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to unsigned comparison between two zero-extended values. 10351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsUnsigned) 10361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value &= Mask; 10371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (CCMask == SystemZ::CCMASK_CMP_EQ || 10381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CCMask == SystemZ::CCMASK_CMP_NE) 10391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Any choice of IsUnsigned is OK for equality comparisons. 10401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We could use either CHHSI or CLHHSI for 16-bit comparisons, 10411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // but since we use CLHHSI for zero extensions, it seems better 10421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to be consistent and do the same here. 10431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value &= Mask, IsUnsigned = true; 10441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (NumBits == 8) { 10451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Try to treat the comparison as unsigned, so that we can use CLI. 10461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Adjust CCMask and Value as necessary. 10471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Value == 0 && CCMask == SystemZ::CCMASK_CMP_LT) 10481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Test whether the high bit of the byte is set. 10491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = 127, CCMask = SystemZ::CCMASK_CMP_GT, IsUnsigned = true; 10503237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford else if (Value == 0 && CCMask == SystemZ::CCMASK_CMP_GE) 10511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Test whether the high bit of the byte is clear. 10521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value = 128, CCMask = SystemZ::CCMASK_CMP_LT, IsUnsigned = true; 10531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 10541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // No instruction exists for this combination. 10551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (Load->getExtensionType() == ISD::ZEXTLOAD) { 10581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Value > Mask) 10591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Signed comparison between two zero-extended values is equivalent 10611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to unsigned comparison. 10621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IsUnsigned = true; 10631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 10641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 10651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure that the first operand is an i32 of the right extension type. 10671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ISD::LoadExtType ExtType = IsUnsigned ? ISD::ZEXTLOAD : ISD::SEXTLOAD; 10681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CmpOp0.getValueType() != MVT::i32 || 10691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getExtensionType() != ExtType) 1070ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick CmpOp0 = DAG.getExtLoad(ExtType, SDLoc(Load), MVT::i32, 10711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getChain(), Load->getBasePtr(), 10721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getPointerInfo(), Load->getMemoryVT(), 10731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->isVolatile(), Load->isNonTemporal(), 10741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Load->getAlignment()); 10751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Make sure that the second operand is an i32 with the right value. 10771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CmpOp1.getValueType() != MVT::i32 || 10781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value != Constant->getZExtValue()) 10791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CmpOp1 = DAG.getConstant(Value, MVT::i32); 10801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 10811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1082aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford// Return true if Op is either an unextended load, or a load suitable 1083aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford// for integer register-memory comparisons of type ICmpType. 1084aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandifordstatic bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType) { 108535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford LoadSDNode *Load = dyn_cast<LoadSDNode>(Op.getNode()); 1086aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (Load) { 1087aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // There are no instructions to compare a register with a memory byte. 1088aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (Load->getMemoryVT() == MVT::i8) 1089aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return false; 1090aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // Otherwise decide on extension type. 109135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford switch (Load->getExtensionType()) { 109235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford case ISD::NON_EXTLOAD: 109335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return true; 109435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford case ISD::SEXTLOAD: 1095aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return ICmpType != SystemZICMP::UnsignedOnly; 109635c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford case ISD::ZEXTLOAD: 1097aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return ICmpType != SystemZICMP::SignedOnly; 109835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford default: 109935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford break; 110035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford } 1101aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford } 110235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 110335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford} 110435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 110535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford// Return true if it is better to swap comparison operands Op0 and Op1. 1106aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford// ICmpType is the type of an integer comparison. 110735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandifordstatic bool shouldSwapCmpOperands(SDValue Op0, SDValue Op1, 1108aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford unsigned ICmpType) { 110935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Leave f128 comparisons alone, since they have no memory forms. 111035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (Op0.getValueType() == MVT::f128) 111135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 111235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 111335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Always keep a floating-point constant second, since comparisons with 111435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // zero can use LOAD TEST and comparisons with other constants make a 111535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // natural memory operand. 111635c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (isa<ConstantFPSDNode>(Op1)) 111735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 111835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 111935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Never swap comparisons with zero since there are many ways to optimize 112035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // those later. 112135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford ConstantSDNode *COp1 = dyn_cast<ConstantSDNode>(Op1); 112235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (COp1 && COp1->getZExtValue() == 0) 112335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 112435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 112535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // Look for cases where Cmp0 is a single-use load and Cmp1 isn't. 112635c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // In that case we generally prefer the memory to be second. 1127aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if ((isNaturalMemoryOperand(Op0, ICmpType) && Op0.hasOneUse()) && 1128aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford !(isNaturalMemoryOperand(Op1, ICmpType) && Op1.hasOneUse())) { 112935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // The only exceptions are when the second operand is a constant and 113035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford // we can use things like CHHSI. 113135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford if (!COp1) 113235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return true; 1133aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // The unsigned memory-immediate instructions can handle 16-bit 1134aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // unsigned integers. 1135aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (ICmpType != SystemZICMP::SignedOnly && 1136aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford isUInt<16>(COp1->getZExtValue())) 1137aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return false; 1138aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // The signed memory-immediate instructions can handle 16-bit 1139aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // signed integers. 1140aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (ICmpType != SystemZICMP::UnsignedOnly && 1141aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford isInt<16>(COp1->getSExtValue())) 1142aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return false; 114335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return true; 114435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford } 114535c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford return false; 114635c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford} 114735c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 1148856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// Return true if shift operation N has an in-range constant shift value. 1149856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// Store it in ShiftVal if so. 1150856bf594338567a592086fe782f2f51650e4e294Richard Sandifordstatic bool isSimpleShift(SDValue N, unsigned &ShiftVal) { 1151856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ConstantSDNode *Shift = dyn_cast<ConstantSDNode>(N.getOperand(1)); 1152856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (!Shift) 1153856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return false; 1154856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 1155856bf594338567a592086fe782f2f51650e4e294Richard Sandiford uint64_t Amount = Shift->getZExtValue(); 1156856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (Amount >= N.getValueType().getSizeInBits()) 1157856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return false; 1158856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 1159856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ShiftVal = Amount; 1160856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return true; 1161856bf594338567a592086fe782f2f51650e4e294Richard Sandiford} 1162856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 1163856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// Check whether an AND with Mask is suitable for a TEST UNDER MASK 1164856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// instruction and whether the CC value is descriptive enough to handle 1165856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// a comparison of type Opcode between the AND result and CmpVal. 1166856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// CCMask says which comparison result is being tested and BitSize is 1167856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// the number of bits in the operands. If TEST UNDER MASK can be used, 1168856bf594338567a592086fe782f2f51650e4e294Richard Sandiford// return the corresponding CC mask, otherwise return 0. 1169aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandifordstatic unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, 1170aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford uint64_t Mask, uint64_t CmpVal, 1171aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford unsigned ICmpType) { 11728bce43648be1156fdced590beb81aed3915762f1Richard Sandiford assert(Mask != 0 && "ANDs with zero should have been removed by now"); 11738bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 1174856bf594338567a592086fe782f2f51650e4e294Richard Sandiford // Check whether the mask is suitable for TMHH, TMHL, TMLH or TMLL. 1175856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (!SystemZ::isImmLL(Mask) && !SystemZ::isImmLH(Mask) && 1176856bf594338567a592086fe782f2f51650e4e294Richard Sandiford !SystemZ::isImmHL(Mask) && !SystemZ::isImmHH(Mask)) 1177856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return 0; 1178856bf594338567a592086fe782f2f51650e4e294Richard Sandiford 11798bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Work out the masks for the lowest and highest bits. 11808bce43648be1156fdced590beb81aed3915762f1Richard Sandiford unsigned HighShift = 63 - countLeadingZeros(Mask); 11818bce43648be1156fdced590beb81aed3915762f1Richard Sandiford uint64_t High = uint64_t(1) << HighShift; 11828bce43648be1156fdced590beb81aed3915762f1Richard Sandiford uint64_t Low = uint64_t(1) << countTrailingZeros(Mask); 11838bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 11848bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Signed ordered comparisons are effectively unsigned if the sign 11858bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // bit is dropped. 1186aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford bool EffectivelyUnsigned = (ICmpType != SystemZICMP::SignedOnly); 11878bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 11888bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check for equality comparisons with 0, or the equivalent. 11898bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CmpVal == 0) { 11908bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ) 11918bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_0; 11928bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE) 11938bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_1; 11948bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 11958bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal <= Low) { 11968bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LT) 11978bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_0; 11988bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GE) 11998bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_1; 12008bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12018bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal < Low) { 12028bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LE) 12038bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_0; 12048bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GT) 12058bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_1; 12068bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12078bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12088bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check for equality comparisons with the mask, or the equivalent. 12098bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CmpVal == Mask) { 12108bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ) 12118bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_1; 12128bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE) 12138bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_0; 12148bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12158bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal >= Mask - Low && CmpVal < Mask) { 12168bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GT) 12178bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_1; 12188bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LE) 12198bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_0; 12208bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12218bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal > Mask - Low && CmpVal <= Mask) { 12228bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GE) 12238bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_ALL_1; 12248bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LT) 12258bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_SOME_0; 12268bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12278bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12288bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check for ordered comparisons with the top bit. 12298bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal >= Mask - High && CmpVal < High) { 12308bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LE) 12318bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_0; 12328bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GT) 12338bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_1; 12348bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12358bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (EffectivelyUnsigned && CmpVal > Mask - High && CmpVal <= High) { 12368bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_LT) 12378bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_0; 12388bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_GE) 12398bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MSB_1; 12408bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12418bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12428bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // If there are just two bits, we can do equality checks for Low and High 12438bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // as well. 12448bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (Mask == Low + High) { 12458bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == Low) 12468bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_0; 12478bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == Low) 12488bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_0 ^ SystemZ::CCMASK_ANY; 12498bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ && CmpVal == High) 12508bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_1; 12518bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (CCMask == SystemZ::CCMASK_CMP_NE && CmpVal == High) 12528bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return SystemZ::CCMASK_TM_MIXED_MSB_1 ^ SystemZ::CCMASK_ANY; 12538bce43648be1156fdced590beb81aed3915762f1Richard Sandiford } 12548bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 12558bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Looks like we've exhausted our options. 12568bce43648be1156fdced590beb81aed3915762f1Richard Sandiford return 0; 12578bce43648be1156fdced590beb81aed3915762f1Richard Sandiford} 12588bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 1259299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// See whether the comparison (Opcode CmpOp0, CmpOp1, ICmpType) can be 1260299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// implemented as a TEST UNDER MASK instruction when the condition being 1261299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// tested is as described by CCValid and CCMask. Update the arguments 1262299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford// with the TM version if so. 1263856bf594338567a592086fe782f2f51650e4e294Richard Sandifordstatic void adjustForTestUnderMask(SelectionDAG &DAG, unsigned &Opcode, 1264856bf594338567a592086fe782f2f51650e4e294Richard Sandiford SDValue &CmpOp0, SDValue &CmpOp1, 1265856bf594338567a592086fe782f2f51650e4e294Richard Sandiford unsigned &CCValid, unsigned &CCMask, 1266856bf594338567a592086fe782f2f51650e4e294Richard Sandiford unsigned &ICmpType) { 12678bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check that we have a comparison with a constant. 1268477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford ConstantSDNode *ConstCmpOp1 = dyn_cast<ConstantSDNode>(CmpOp1); 12698bce43648be1156fdced590beb81aed3915762f1Richard Sandiford if (!ConstCmpOp1) 1270477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return; 1271856bf594338567a592086fe782f2f51650e4e294Richard Sandiford uint64_t CmpVal = ConstCmpOp1->getZExtValue(); 1272477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford 1273477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford // Check whether the nonconstant input is an AND with a constant mask. 1274477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford if (CmpOp0.getOpcode() != ISD::AND) 1275477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return; 1276477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford SDValue AndOp0 = CmpOp0.getOperand(0); 1277477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford SDValue AndOp1 = CmpOp0.getOperand(1); 1278477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(AndOp1.getNode()); 1279477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford if (!Mask) 1280477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return; 1281477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford uint64_t MaskVal = Mask->getZExtValue(); 1282477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford 12838bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // Check whether the combination of mask, comparison value and comparison 12848bce43648be1156fdced590beb81aed3915762f1Richard Sandiford // type are suitable. 12858bce43648be1156fdced590beb81aed3915762f1Richard Sandiford unsigned BitSize = CmpOp0.getValueType().getSizeInBits(); 1286856bf594338567a592086fe782f2f51650e4e294Richard Sandiford unsigned NewCCMask, ShiftVal; 1287856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (ICmpType != SystemZICMP::SignedOnly && 1288856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0.getOpcode() == ISD::SHL && 1289856bf594338567a592086fe782f2f51650e4e294Richard Sandiford isSimpleShift(AndOp0, ShiftVal) && 1290856bf594338567a592086fe782f2f51650e4e294Richard Sandiford (NewCCMask = getTestUnderMaskCond(BitSize, CCMask, MaskVal >> ShiftVal, 1291856bf594338567a592086fe782f2f51650e4e294Richard Sandiford CmpVal >> ShiftVal, 1292856bf594338567a592086fe782f2f51650e4e294Richard Sandiford SystemZICMP::Any))) { 1293856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0 = AndOp0.getOperand(0); 1294856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp1 = DAG.getConstant(MaskVal >> ShiftVal, AndOp0.getValueType()); 1295856bf594338567a592086fe782f2f51650e4e294Richard Sandiford } else if (ICmpType != SystemZICMP::SignedOnly && 1296856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0.getOpcode() == ISD::SRL && 1297856bf594338567a592086fe782f2f51650e4e294Richard Sandiford isSimpleShift(AndOp0, ShiftVal) && 1298856bf594338567a592086fe782f2f51650e4e294Richard Sandiford (NewCCMask = getTestUnderMaskCond(BitSize, CCMask, 1299856bf594338567a592086fe782f2f51650e4e294Richard Sandiford MaskVal << ShiftVal, 1300856bf594338567a592086fe782f2f51650e4e294Richard Sandiford CmpVal << ShiftVal, 1301856bf594338567a592086fe782f2f51650e4e294Richard Sandiford SystemZICMP::UnsignedOnly))) { 1302856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp0 = AndOp0.getOperand(0); 1303856bf594338567a592086fe782f2f51650e4e294Richard Sandiford AndOp1 = DAG.getConstant(MaskVal << ShiftVal, AndOp0.getValueType()); 1304856bf594338567a592086fe782f2f51650e4e294Richard Sandiford } else { 1305856bf594338567a592086fe782f2f51650e4e294Richard Sandiford NewCCMask = getTestUnderMaskCond(BitSize, CCMask, MaskVal, CmpVal, 1306856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ICmpType); 1307856bf594338567a592086fe782f2f51650e4e294Richard Sandiford if (!NewCCMask) 1308856bf594338567a592086fe782f2f51650e4e294Richard Sandiford return; 1309856bf594338567a592086fe782f2f51650e4e294Richard Sandiford } 13108bce43648be1156fdced590beb81aed3915762f1Richard Sandiford 1311477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford // Go ahead and make the change. 1312477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford Opcode = SystemZISD::TM; 1313477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford CmpOp0 = AndOp0; 1314477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford CmpOp1 = AndOp1; 1315299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford ICmpType = (bool(NewCCMask & SystemZ::CCMASK_TM_MIXED_MSB_0) != 1316299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford bool(NewCCMask & SystemZ::CCMASK_TM_MIXED_MSB_1)); 1317477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford CCValid = SystemZ::CCMASK_TM; 13188bce43648be1156fdced590beb81aed3915762f1Richard Sandiford CCMask = NewCCMask; 1319477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford} 1320477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford 13216824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// Return a target node that compares CmpOp0 with CmpOp1 and stores a 13226824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// 2-bit result in CC. Set CCValid to the CCMASK_* of all possible 13236824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// 2-bit results and CCMask to the subset of those results that are 13246824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford// associated with Cond. 1325aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandifordstatic SDValue emitCmp(const SystemZTargetMachine &TM, SelectionDAG &DAG, 1326aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford SDLoc DL, SDValue CmpOp0, SDValue CmpOp1, 1327aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ISD::CondCode Cond, unsigned &CCValid, 13286824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned &CCMask) { 13291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsUnsigned = false; 13306824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask = CCMaskForCondCode(Cond); 1331aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford unsigned Opcode, ICmpType = 0; 1332aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (CmpOp0.getValueType().isFloatingPoint()) { 13336824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCValid = SystemZ::CCMASK_FCMP; 1334aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford Opcode = SystemZISD::FCMP; 1335aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford } else { 13361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand IsUnsigned = CCMask & SystemZ::CCMASK_CMP_UO; 13376824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCValid = SystemZ::CCMASK_ICMP; 13386824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask &= CCValid; 13393237f88882eed8a67fa679f7071a5441c4306ac3Richard Sandiford adjustZeroCmp(DAG, IsUnsigned, CmpOp0, CmpOp1, CCMask); 13401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand adjustSubwordCmp(DAG, IsUnsigned, CmpOp0, CmpOp1, CCMask); 1341aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford Opcode = SystemZISD::ICMP; 1342aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // Choose the type of comparison. Equality and inequality tests can 1343aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // use either signed or unsigned comparisons. The choice also doesn't 1344aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // matter if both sign bits are known to be clear. In those cases we 1345aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // want to give the main isel code the freedom to choose whichever 1346aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford // form fits best. 1347aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (CCMask == SystemZ::CCMASK_CMP_EQ || 1348aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford CCMask == SystemZ::CCMASK_CMP_NE || 1349aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford (DAG.SignBitIsZero(CmpOp0) && DAG.SignBitIsZero(CmpOp1))) 1350aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ICmpType = SystemZICMP::Any; 1351aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford else if (IsUnsigned) 1352aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ICmpType = SystemZICMP::UnsignedOnly; 1353aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford else 1354aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford ICmpType = SystemZICMP::SignedOnly; 13551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 13561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1357aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford if (shouldSwapCmpOperands(CmpOp0, CmpOp1, ICmpType)) { 135835c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford std::swap(CmpOp0, CmpOp1); 135935c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford CCMask = ((CCMask & SystemZ::CCMASK_CMP_EQ) | 136035c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford (CCMask & SystemZ::CCMASK_CMP_GT ? SystemZ::CCMASK_CMP_LT : 0) | 136135c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford (CCMask & SystemZ::CCMASK_CMP_LT ? SystemZ::CCMASK_CMP_GT : 0) | 136235c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford (CCMask & SystemZ::CCMASK_CMP_UO)); 136335c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford } 136435c93e4e42d7a35a90e89211fa62f478e25ba0a4Richard Sandiford 1365856bf594338567a592086fe782f2f51650e4e294Richard Sandiford adjustForTestUnderMask(DAG, Opcode, CmpOp0, CmpOp1, CCValid, CCMask, 1366856bf594338567a592086fe782f2f51650e4e294Richard Sandiford ICmpType); 1367299fdd814f4c2850d44387d24c440980c5377d3eRichard Sandiford if (Opcode == SystemZISD::ICMP || Opcode == SystemZISD::TM) 1368aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1, 1369aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford DAG.getConstant(ICmpType, MVT::i32)); 1370477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1); 13711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 13721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1373df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford// Implement a 32-bit *MUL_LOHI operation by extending both operands to 1374df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford// 64 bits. Extend is the extension type to use. Store the high part 1375df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford// in Hi and the low part in Lo. 1376df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandifordstatic void lowerMUL_LOHI32(SelectionDAG &DAG, SDLoc DL, 1377df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford unsigned Extend, SDValue Op0, SDValue Op1, 1378df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue &Hi, SDValue &Lo) { 1379df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op0 = DAG.getNode(Extend, DL, MVT::i64, Op0); 1380df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op1 = DAG.getNode(Extend, DL, MVT::i64, Op1); 1381df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue Mul = DAG.getNode(ISD::MUL, DL, MVT::i64, Op0, Op1); 1382df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Hi = DAG.getNode(ISD::SRL, DL, MVT::i64, Mul, DAG.getConstant(32, MVT::i64)); 1383df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Hi = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Hi); 1384df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Lo = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Mul); 1385df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford} 1386df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford 13871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Lower a binary operation that produces two VT results, one in each 13881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// half of a GR128 pair. Op0 and Op1 are the VT operands to the operation, 13891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Extend extends Op0 to a GR128, and Opcode performs the GR128 operation 13901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// on the extended Op0 and (unextended) Op1. Store the even register result 13911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// in Even and the odd register result in Odd. 1392ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trickstatic void lowerGR128Binary(SelectionDAG &DAG, SDLoc DL, EVT VT, 13931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Extend, unsigned Opcode, 13941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0, SDValue Op1, 13951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue &Even, SDValue &Odd) { 13961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDNode *In128 = DAG.getMachineNode(Extend, DL, MVT::Untyped, Op0); 13971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getNode(Opcode, DL, MVT::Untyped, 13981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue(In128, 0), Op1); 13991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool Is32Bit = is32Bit(VT); 14007c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford Even = DAG.getTargetExtractSubreg(SystemZ::even128(Is32Bit), DL, VT, Result); 14017c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford Odd = DAG.getTargetExtractSubreg(SystemZ::odd128(Is32Bit), DL, VT, Result); 14021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 14051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 14061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 14071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp0 = Op.getOperand(2); 14081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp1 = Op.getOperand(3); 14091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Dest = Op.getOperand(4); 1410ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 14111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14126824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid, CCMask; 1413aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask); 14141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(), 14156824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Chain, DAG.getConstant(CCValid, MVT::i32), 14166824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford DAG.getConstant(CCMask, MVT::i32), Dest, Flags); 14171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op, 14201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 14211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp0 = Op.getOperand(0); 14221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpOp1 = Op.getOperand(1); 14231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TrueOp = Op.getOperand(2); 14241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FalseOp = Op.getOperand(3); 14251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 1426ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 14271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14286824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid, CCMask; 1429aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford SDValue Flags = emitCmp(TM, DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask); 14301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14316824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford SmallVector<SDValue, 5> Ops; 14321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(TrueOp); 14331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(FalseOp); 14346824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Ops.push_back(DAG.getConstant(CCValid, MVT::i32)); 14351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(DAG.getConstant(CCMask, MVT::i32)); 14361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Ops.push_back(Flags); 14371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 14391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::SELECT_CCMASK, DL, VTs, &Ops[0], Ops.size()); 14401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerGlobalAddress(GlobalAddressSDNode *Node, 14431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1444ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 14451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const GlobalValue *GV = Node->getGlobal(); 14461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset = Node->getOffset(); 14471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 14481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Reloc::Model RM = TM.getRelocationModel(); 14491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CodeModel::Model CM = TM.getCodeModel(); 14501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result; 14521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Subtarget.isPC32DBLSymbol(GV, RM, CM)) { 14538dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford // Assign anchors at 1<<12 byte boundaries. 14548dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford uint64_t Anchor = Offset & ~uint64_t(0xfff); 14558dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor); 14568dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 14578dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford 14588dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford // The offset can be folded into the address if it is aligned to a halfword. 14598dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Offset -= Anchor; 14608dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford if (Offset != 0 && (Offset & 1) == 0) { 14618dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford SDValue Full = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Anchor + Offset); 14628dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford Result = DAG.getNode(SystemZISD::PCREL_OFFSET, DL, PtrVT, Full, Result); 14631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset = 0; 14641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 14651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 14661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, SystemZII::MO_GOT); 14671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 14681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result, 14691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo::getGOT(), false, false, false, 0); 14701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 14711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If there was a non-zero offset that we didn't fold, create an explicit 14731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // addition for it. 14741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Offset != 0) 14751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getNode(ISD::ADD, DL, PtrVT, Result, 14761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(Offset, PtrVT)); 14771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Result; 14791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 14801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerGlobalTLSAddress(GlobalAddressSDNode *Node, 14821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1483ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 14841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const GlobalValue *GV = Node->getGlobal(); 14851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 14861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TLSModel::Model model = TM.getTLSModel(GV); 14871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (model != TLSModel::LocalExec) 14891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("only local-exec TLS mode supported"); 14901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The high part of the thread pointer is in access register 0. 14921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TPHi = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32, 14931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, MVT::i32)); 14941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TPHi = DAG.getNode(ISD::ANY_EXTEND, DL, PtrVT, TPHi); 14951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 14961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The low part of the thread pointer is in access register 1. 14971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TPLo = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32, 14981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(1, MVT::i32)); 14991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TPLo = DAG.getNode(ISD::ZERO_EXTEND, DL, PtrVT, TPLo); 15001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Merge them into a single 64-bit address. 15021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TPHiShifted = DAG.getNode(ISD::SHL, DL, PtrVT, TPHi, 15031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(32, PtrVT)); 15041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue TP = DAG.getNode(ISD::OR, DL, PtrVT, TPHiShifted, TPLo); 15051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the offset of GA from the thread pointer. 15071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZConstantPoolValue *CPV = 15081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZConstantPoolValue::Create(GV, SystemZCP::NTPOFF); 15091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Force the offset into the constant pool and load it from there. 15111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CPAddr = DAG.getConstantPool(CPV, PtrVT, 8); 15121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Offset = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), 15131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CPAddr, MachinePointerInfo::getConstantPool(), 15141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, false, 0); 15151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Add the base and offset together. 15171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::ADD, DL, PtrVT, TP, Offset); 15181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerBlockAddress(BlockAddressSDNode *Node, 15211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1522ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 15231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const BlockAddress *BA = Node->getBlockAddress(); 15241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset = Node->getOffset(); 15251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 15261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT, Offset); 15281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 15291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Result; 15301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerJumpTable(JumpTableSDNode *JT, 15331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1534ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(JT); 15351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 15361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); 15371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use LARL to load the address of the table. 15391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 15401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerConstantPool(ConstantPoolSDNode *CP, 15431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1544ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(CP); 15451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 15461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result; 15481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (CP->isMachineConstantPoolEntry()) 15491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, 15501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CP->getAlignment()); 15511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 15521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, 15531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CP->getAlignment(), CP->getOffset()); 15541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use LARL to load the address of the constant pool entry. 15561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result); 15571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerBITCAST(SDValue Op, 15601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 1561ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 15621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue In = Op.getOperand(0); 15631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT InVT = In.getValueType(); 15641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT ResVT = Op.getValueType(); 15651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (InVT == MVT::i32 && ResVT == MVT::f32) { 15675fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDValue In64; 15685fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford if (Subtarget.hasHighWord()) { 15695fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, 15705fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford MVT::i64); 15715fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL, 15725fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford MVT::i64, SDValue(U64, 0), In); 15735fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford } else { 15745fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford In64 = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, In); 15755fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford In64 = DAG.getNode(ISD::SHL, DL, MVT::i64, In64, 15765fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford DAG.getConstant(32, MVT::i64)); 15775fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford } 15785fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::f64, In64); 1579745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return DAG.getTargetExtractSubreg(SystemZ::subreg_h32, 15807c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford DL, MVT::f32, Out64); 15811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 15821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (InVT == MVT::f32 && ResVT == MVT::i32) { 15831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDNode *U64 = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f64); 1584745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford SDValue In64 = DAG.getTargetInsertSubreg(SystemZ::subreg_h32, DL, 15857c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford MVT::f64, SDValue(U64, 0), In); 15867c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford SDValue Out64 = DAG.getNode(ISD::BITCAST, DL, MVT::i64, In64); 15875fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford if (Subtarget.hasHighWord()) 15885fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford return DAG.getTargetExtractSubreg(SystemZ::subreg_h32, DL, 15895fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford MVT::i32, Out64); 15905fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford SDValue Shift = DAG.getNode(ISD::SRL, DL, MVT::i64, Out64, 15915fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford DAG.getConstant(32, MVT::i64)); 15925fb8d3144fa5da2b8392b56136163809d8df0527Richard Sandiford return DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Shift); 15931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 15941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected bitcast combination"); 15951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 15961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 15971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerVASTART(SDValue Op, 15981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 15991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 16001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMachineFunctionInfo *FuncInfo = 16011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>(); 16021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = getPointerTy(); 16031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 16051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr = Op.getOperand(1); 16061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 1607ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 16081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The initial values of each field. 16101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const unsigned NumFields = 4; 16111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Fields[NumFields] = { 16121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(FuncInfo->getVarArgsFirstGPR(), PtrVT), 16131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(FuncInfo->getVarArgsFirstFPR(), PtrVT), 16141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT), 16151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(), PtrVT) 16161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand }; 16171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Store each field into its respective slot. 16191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue MemOps[NumFields]; 16201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Offset = 0; 16211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned I = 0; I < NumFields; ++I) { 16221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue FieldAddr = Addr; 16231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Offset != 0) 16241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FieldAddr = DAG.getNode(ISD::ADD, DL, PtrVT, FieldAddr, 16251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getIntPtrConstant(Offset)); 16261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MemOps[I] = DAG.getStore(Chain, DL, Fields[I], FieldAddr, 16271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(SV, Offset), 16281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand false, false, 0); 16291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Offset += 8; 16301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 16311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOps, NumFields); 16321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 16331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerVACOPY(SDValue Op, 16351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 16361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 16371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue DstPtr = Op.getOperand(1); 16381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue SrcPtr = Op.getOperand(2); 16391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue(); 16401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue(); 1641ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 16421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(32), 16441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand /*Align*/8, /*isVolatile*/false, /*AlwaysInline*/false, 16451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV)); 16461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 16471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering:: 16491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandlowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { 16501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Chain = Op.getOperand(0); 16511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Size = Op.getOperand(1); 1652ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 16531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SPReg = getStackPointerRegisterToSaveRestore(); 16551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get a reference to the stack pointer. 16571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i64); 16581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the new stack pointer value. 16601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue NewSP = DAG.getNode(ISD::SUB, DL, MVT::i64, OldSP, Size); 16611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Copy the new stack pointer back. 16631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Chain = DAG.getCopyToReg(Chain, DL, SPReg, NewSP); 16641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The allocated data lives above the 160 bytes allocated for the standard 16661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // frame, plus any outgoing stack arguments. We don't know how much that 16671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // amounts to yet, so emit a special ADJDYNALLOC placeholder. 16681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ArgAdjust = DAG.getNode(SystemZISD::ADJDYNALLOC, DL, MVT::i64); 16691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getNode(ISD::ADD, DL, MVT::i64, NewSP, ArgAdjust); 16701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 16711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2] = { Result, Chain }; 16721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 16731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 16741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1675df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard SandifordSDValue SystemZTargetLowering::lowerSMUL_LOHI(SDValue Op, 16761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 16771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Op.getValueType(); 1678ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 1679df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue Ops[2]; 1680df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford if (is32Bit(VT)) 1681df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Just do a normal 64-bit multiplication and extract the results. 1682df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // We define this so that it can be used for constant division. 1683df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerMUL_LOHI32(DAG, DL, ISD::SIGN_EXTEND, Op.getOperand(0), 1684df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op.getOperand(1), Ops[1], Ops[0]); 1685df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford else { 1686df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Do a full 128-bit multiplication based on UMUL_LOHI64: 1687df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1688df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // (ll * rl) + ((lh * rl) << 64) + ((ll * rh) << 64) 1689df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1690df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // but using the fact that the upper halves are either all zeros 1691df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // or all ones: 1692df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1693df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // (ll * rl) - ((lh & rl) << 64) - ((ll & rh) << 64) 1694df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1695df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // and grouping the right terms together since they are quicker than the 1696df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // multiplication: 1697df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // 1698df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // (ll * rl) - (((lh & rl) + (ll & rh)) << 64) 1699df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue C63 = DAG.getConstant(63, MVT::i64); 1700df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue LL = Op.getOperand(0); 1701df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue RL = Op.getOperand(1); 1702df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue LH = DAG.getNode(ISD::SRA, DL, VT, LL, C63); 1703df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue RH = DAG.getNode(ISD::SRA, DL, VT, RL, C63); 1704df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // UMUL_LOHI64 returns the low result in the odd register and the high 1705df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // result in the even register. SMUL_LOHI is defined to return the 1706df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // low half first, so the results are in reverse order. 1707df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, SystemZISD::UMUL_LOHI64, 1708df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford LL, RL, Ops[1], Ops[0]); 1709df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue NegLLTimesRH = DAG.getNode(ISD::AND, DL, VT, LL, RH); 1710df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue NegLHTimesRL = DAG.getNode(ISD::AND, DL, VT, LH, RL); 1711df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDValue NegSum = DAG.getNode(ISD::ADD, DL, VT, NegLLTimesRH, NegLHTimesRL); 1712df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Ops[1] = DAG.getNode(ISD::SUB, DL, VT, Ops[1], NegSum); 1713df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford } 1714df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford return DAG.getMergeValues(Ops, 2, DL); 1715df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford} 17161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1717df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard SandifordSDValue SystemZTargetLowering::lowerUMUL_LOHI(SDValue Op, 1718df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SelectionDAG &DAG) const { 1719df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford EVT VT = Op.getValueType(); 1720df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford SDLoc DL(Op); 17211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2]; 1722df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford if (is32Bit(VT)) 1723df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // Just do a normal 64-bit multiplication and extract the results. 1724df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // We define this so that it can be used for constant division. 1725df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerMUL_LOHI32(DAG, DL, ISD::ZERO_EXTEND, Op.getOperand(0), 1726df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op.getOperand(1), Ops[1], Ops[0]); 1727df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford else 1728df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // UMUL_LOHI64 returns the low result in the odd register and the high 1729df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // result in the even register. UMUL_LOHI is defined to return the 1730df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford // low half first, so the results are in reverse order. 1731df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, SystemZISD::UMUL_LOHI64, 1732df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]); 17331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 17341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 17351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSDIVREM(SDValue Op, 17371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 17381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op0 = Op.getOperand(0); 17391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Op1 = Op.getOperand(1); 17401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Op.getValueType(); 1741ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 174235b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford unsigned Opcode; 17431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We use DSGF for 32-bit division. 17451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (is32Bit(VT)) { 17461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op0 = DAG.getNode(ISD::SIGN_EXTEND, DL, MVT::i64, Op0); 174735b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Opcode = SystemZISD::SDIVREM32; 174835b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford } else if (DAG.ComputeNumSignBits(Op1) > 32) { 174935b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Op1 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1); 175035b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Opcode = SystemZISD::SDIVREM32; 175135b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford } else 175235b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford Opcode = SystemZISD::SDIVREM64; 17531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // DSG(F) takes a 64-bit dividend, so the even register in the GR128 17551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // input is "don't care". The instruction returns the remainder in 17561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // the even register and the quotient in the odd register. 17571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2]; 175835b7bebe1162326c38217ff80d4a49fbbffcc365Richard Sandiford lowerGR128Binary(DAG, DL, VT, SystemZ::AEXT128_64, Opcode, 17591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op0, Op1, Ops[1], Ops[0]); 17601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 17611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 17621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerUDIVREM(SDValue Op, 17641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 17651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT VT = Op.getValueType(); 1766ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 17671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // DL(G) uses a double-width dividend, so we need to clear the even 17691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // register in the GR128 input. The instruction returns the remainder 17701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // in the even register and the quotient in the odd register. 17711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[2]; 17721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (is32Bit(VT)) 17731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand lowerGR128Binary(DAG, DL, VT, SystemZ::ZEXT128_32, SystemZISD::UDIVREM32, 17741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]); 17751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 17761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand lowerGR128Binary(DAG, DL, VT, SystemZ::ZEXT128_64, SystemZISD::UDIVREM64, 17771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Op.getOperand(0), Op.getOperand(1), Ops[1], Ops[0]); 17781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(Ops, 2, DL); 17791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 17801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerOR(SDValue Op, SelectionDAG &DAG) const { 17821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(Op.getValueType() == MVT::i64 && "Should be 64-bit operation"); 17831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the known-zero masks for each operand. 17851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1) }; 17861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand APInt KnownZero[2], KnownOne[2]; 17871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.ComputeMaskedBits(Ops[0], KnownZero[0], KnownOne[0]); 17881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.ComputeMaskedBits(Ops[1], KnownZero[1], KnownOne[1]); 17891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 17901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // See if the upper 32 bits of one operand and the lower 32 bits of the 17911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // other are known zero. They are the low and high operands respectively. 17921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Masks[] = { KnownZero[0].getZExtValue(), 17931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand KnownZero[1].getZExtValue() }; 17941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned High, Low; 17951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff) 17961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand High = 1, Low = 0; 17971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff) 17981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand High = 0, Low = 1; 17991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 18001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 18011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue LowOp = Ops[Low]; 18031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue HighOp = Ops[High]; 18041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the high part is a constant, we're better off using IILH. 18061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (HighOp.getOpcode() == ISD::Constant) 18071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 18081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the low part is a constant that is outside the range of LHI, 18101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // then we're better off using IILF. 18111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (LowOp.getOpcode() == ISD::Constant) { 18121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Value = int32_t(cast<ConstantSDNode>(LowOp)->getZExtValue()); 18131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isInt<16>(Value)) 18141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 18151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 18161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Check whether the high part is an AND that doesn't change the 18181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // high 32 bits and just masks out low bits. We can skip it if so. 18191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (HighOp.getOpcode() == ISD::AND && 18201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand HighOp.getOperand(1).getOpcode() == ISD::Constant) { 18211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ConstantSDNode *MaskNode = cast<ConstantSDNode>(HighOp.getOperand(1)); 18221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Mask = MaskNode->getZExtValue() | Masks[High]; 18231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((Mask >> 32) == 0xffffffff) 18241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand HighOp = HighOp.getOperand(0); 18251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 18261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Take advantage of the fact that all GR32 operations only change the 18281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // low 32 bits by truncating Low to an i32 and inserting it directly 18291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // using a subreg. The interesting cases are those where the truncation 18301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // can be folded. 1831ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Op); 18321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Low32 = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, LowOp); 1833745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return DAG.getTargetInsertSubreg(SystemZ::subreg_l32, DL, 18347c7b431d2fa3ead0a2a24c4dd81fc92f293203ddRichard Sandiford MVT::i64, HighOp, Low32); 18351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 18361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Op is an 8-, 16-bit or 32-bit ATOMIC_LOAD_* operation. Lower the first 18381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// two into the fullword ATOMIC_LOADW_* operation given by Opcode. 18391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerATOMIC_LOAD(SDValue Op, 18401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG, 18411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode) const { 18421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AtomicSDNode *Node = cast<AtomicSDNode>(Op.getNode()); 18431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // 32-bit operations need no code outside the main loop. 18451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT NarrowVT = Node->getMemoryVT(); 18461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT WideVT = MVT::i32; 18471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NarrowVT == WideVT) 18481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 18491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t BitSize = NarrowVT.getSizeInBits(); 18511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ChainIn = Node->getChain(); 18521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr = Node->getBasePtr(); 18531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Src2 = Node->getVal(); 18541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineMemOperand *MMO = Node->getMemOperand(); 1855ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 18561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = Addr.getValueType(); 18571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Convert atomic subtracts of constants into additions. 18591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == SystemZISD::ATOMIC_LOADW_SUB) 18601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(Src2)) { 18611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZISD::ATOMIC_LOADW_ADD; 18621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Src2 = DAG.getConstant(-Const->getSExtValue(), Src2.getValueType()); 18631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 18641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the address of the containing word. 18661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr, 18671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(-4, PtrVT)); 18681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the number of bits that the word must be rotated left in order 18701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to bring the field to the top bits of a GR32. 18711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr, 18721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(3, PtrVT)); 18731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift); 18741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the complementing shift amount, for rotating a field in the top 18761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits back to its proper position. 18771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT, 18781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, WideVT), BitShift); 18791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extend the source operand to 32 bits and prepare it for the inner loop. 18811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ATOMIC_SWAPW uses RISBG to rotate the field left, but all other 18821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // operations require the source to be shifted in advance. (This shift 18831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // can be folded if the source is constant.) For AND and NAND, the lower 18841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits must be set, while for other opcodes they should be left clear. 18851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode != SystemZISD::ATOMIC_SWAPW) 18861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Src2 = DAG.getNode(ISD::SHL, DL, WideVT, Src2, 18871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(32 - BitSize, WideVT)); 18881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Opcode == SystemZISD::ATOMIC_LOADW_AND || 18891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode == SystemZISD::ATOMIC_LOADW_NAND) 18901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Src2 = DAG.getNode(ISD::OR, DL, WideVT, Src2, 18911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(uint32_t(-1) >> BitSize, WideVT)); 18921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 18931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Construct the ATOMIC_LOADW_* node. 18941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList VTList = DAG.getVTList(WideVT, MVT::Other); 18951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift, 18961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(BitSize, WideVT) }; 18971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AtomicOp = DAG.getMemIntrinsicNode(Opcode, DL, VTList, Ops, 18981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand array_lengthof(Ops), 18991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NarrowVT, MMO); 19001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Rotate the result of the final CS so that the field is in the lower 19021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits of a GR32, then truncate it. 19031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ResultShift = DAG.getNode(ISD::ADD, DL, WideVT, BitShift, 19041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(BitSize, WideVT)); 19051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Result = DAG.getNode(ISD::ROTL, DL, WideVT, AtomicOp, ResultShift); 19061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue RetOps[2] = { Result, AtomicOp.getValue(1) }; 19081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DAG.getMergeValues(RetOps, 2, DL); 19091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Node is an 8- or 16-bit ATOMIC_CMP_SWAP operation. Lower the first two 19121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// into a fullword ATOMIC_CMP_SWAPW operation. 19131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerATOMIC_CMP_SWAP(SDValue Op, 19141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand AtomicSDNode *Node = cast<AtomicSDNode>(Op.getNode()); 19161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // We have native support for 32-bit compare and swap. 19181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT NarrowVT = Node->getMemoryVT(); 19191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT WideVT = MVT::i32; 19201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (NarrowVT == WideVT) 19211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Op; 19221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t BitSize = NarrowVT.getSizeInBits(); 19241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue ChainIn = Node->getOperand(0); 19251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Addr = Node->getOperand(1); 19261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue CmpVal = Node->getOperand(2); 19271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue SwapVal = Node->getOperand(3); 19281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineMemOperand *MMO = Node->getMemOperand(); 1929ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc DL(Node); 19301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EVT PtrVT = Addr.getValueType(); 19311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the address of the containing word. 19331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AlignedAddr = DAG.getNode(ISD::AND, DL, PtrVT, Addr, 19341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(-4, PtrVT)); 19351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the number of bits that the word must be rotated left in order 19371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // to bring the field to the top bits of a GR32. 19381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue BitShift = DAG.getNode(ISD::SHL, DL, PtrVT, Addr, 19391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(3, PtrVT)); 19401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitShift = DAG.getNode(ISD::TRUNCATE, DL, WideVT, BitShift); 19411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the complementing shift amount, for rotating a field in the top 19431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // bits back to its proper position. 19441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue NegBitShift = DAG.getNode(ISD::SUB, DL, WideVT, 19451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DAG.getConstant(0, WideVT), BitShift); 19461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Construct the ATOMIC_CMP_SWAPW node. 19481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDVTList VTList = DAG.getVTList(WideVT, MVT::Other); 19491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift, 19501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NegBitShift, DAG.getConstant(BitSize, WideVT) }; 19511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SDValue AtomicOp = DAG.getMemIntrinsicNode(SystemZISD::ATOMIC_CMP_SWAPW, DL, 19521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand VTList, Ops, array_lengthof(Ops), 19531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NarrowVT, MMO); 19541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return AtomicOp; 19551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSTACKSAVE(SDValue Op, 19581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 19601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true); 1961ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), 19621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::R15D, Op.getValueType()); 19631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 19651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op, 19661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = DAG.getMachineFunction(); 19681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true); 1969ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op), 19701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::R15D, Op.getOperand(1)); 19711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 19721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1973a550b51bac50493db75a7b5788a3f2c3b62fd913Richard SandifordSDValue SystemZTargetLowering::lowerPREFETCH(SDValue Op, 1974a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford SelectionDAG &DAG) const { 1975a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford bool IsData = cast<ConstantSDNode>(Op.getOperand(4))->getZExtValue(); 1976a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford if (!IsData) 1977a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford // Just preserve the chain. 1978a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford return Op.getOperand(0); 1979a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford 1980a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford bool IsWrite = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue(); 1981a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford unsigned Code = IsWrite ? SystemZ::PFD_WRITE : SystemZ::PFD_READ; 1982a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford MemIntrinsicSDNode *Node = cast<MemIntrinsicSDNode>(Op.getNode()); 1983a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford SDValue Ops[] = { 1984a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Op.getOperand(0), 1985a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford DAG.getConstant(Code, MVT::i32), 1986a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Op.getOperand(1) 1987a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford }; 1988a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford return DAG.getMemIntrinsicNode(SystemZISD::PREFETCH, SDLoc(Op), 1989a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Node->getVTList(), Ops, array_lengthof(Ops), 1990a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford Node->getMemoryVT(), Node->getMemOperand()); 1991a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford} 1992a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford 19931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSDValue SystemZTargetLowering::LowerOperation(SDValue Op, 19941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SelectionDAG &DAG) const { 19951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Op.getOpcode()) { 19961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::BR_CC: 19971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerBR_CC(Op, DAG); 19981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SELECT_CC: 19991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSELECT_CC(Op, DAG); 20001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::GlobalAddress: 20011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerGlobalAddress(cast<GlobalAddressSDNode>(Op), DAG); 20021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::GlobalTLSAddress: 20031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerGlobalTLSAddress(cast<GlobalAddressSDNode>(Op), DAG); 20041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::BlockAddress: 20051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerBlockAddress(cast<BlockAddressSDNode>(Op), DAG); 20061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::JumpTable: 20071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerJumpTable(cast<JumpTableSDNode>(Op), DAG); 20081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ConstantPool: 20091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG); 20101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::BITCAST: 20111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerBITCAST(Op, DAG); 20121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::VASTART: 20131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerVASTART(Op, DAG); 20141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::VACOPY: 20151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerVACOPY(Op, DAG); 20161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::DYNAMIC_STACKALLOC: 20171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerDYNAMIC_STACKALLOC(Op, DAG); 2018df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford case ISD::SMUL_LOHI: 2019df40f8e8ad0aa93defa44b8a136e8d871cfd44eaRichard Sandiford return lowerSMUL_LOHI(Op, DAG); 20201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::UMUL_LOHI: 20211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerUMUL_LOHI(Op, DAG); 20221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::SDIVREM: 20231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSDIVREM(Op, DAG); 20241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::UDIVREM: 20251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerUDIVREM(Op, DAG); 20261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::OR: 20271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerOR(Op, DAG); 20281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_SWAP: 20291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_SWAPW); 20301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_ADD: 20311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_ADD); 20321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_SUB: 20331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_SUB); 20341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_AND: 20351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_AND); 20361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_OR: 20371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_OR); 20381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_XOR: 20391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_XOR); 20401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_NAND: 20411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_NAND); 20421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_MIN: 20431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_MIN); 20441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_MAX: 20451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_MAX); 20461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_UMIN: 20471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN); 20481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_LOAD_UMAX: 20491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_LOAD(Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX); 20501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::ATOMIC_CMP_SWAP: 20511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerATOMIC_CMP_SWAP(Op, DAG); 20521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::STACKSAVE: 20531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSTACKSAVE(Op, DAG); 20541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case ISD::STACKRESTORE: 20551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return lowerSTACKRESTORE(Op, DAG); 2056a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford case ISD::PREFETCH: 2057a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford return lowerPREFETCH(Op, DAG); 20581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 20591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected node to lower"); 20601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 20611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 20621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 20631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandconst char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { 20641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define OPCODE(NAME) case SystemZISD::NAME: return "SystemZISD::" #NAME 20651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Opcode) { 20661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(RET_FLAG); 20671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(CALL); 206880f54784da0bd42fb79176bbf447a31d69287fe3Richard Sandiford OPCODE(SIBCALL); 20691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(PCREL_WRAPPER); 20708dac19c0708c9bd0da0b832014918e00ded44d86Richard Sandiford OPCODE(PCREL_OFFSET); 2071aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford OPCODE(ICMP); 2072aff1c6427ce22125adfa29de4145030aa3214a2eRichard Sandiford OPCODE(FCMP); 2073477168192c98e1f75a5bc6db3d34a177f327bd34Richard Sandiford OPCODE(TM); 20741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(BR_CCMASK); 20751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(SELECT_CCMASK); 20761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ADJDYNALLOC); 20771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(EXTRACT_ACCESS); 20781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(UMUL_LOHI64); 20791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(SDIVREM64); 20801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(UDIVREM32); 20811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(UDIVREM64); 2082dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford OPCODE(MVC); 2083842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford OPCODE(MVC_LOOP); 208416277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(NC); 208516277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(NC_LOOP); 208616277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(OC); 208716277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(OC_LOOP); 208816277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(XC); 208916277c4698f36a756c540fae326874774156aaedRichard Sandiford OPCODE(XC_LOOP); 2090e03a56d62fc623e2f72d623b816f91b293d5904bRichard Sandiford OPCODE(CLC); 2091842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford OPCODE(CLC_LOOP); 2092e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford OPCODE(STRCMP); 20934fc7355a21e1fa838406e15459aaf54a58fcf909Richard Sandiford OPCODE(STPCPY); 209419262ee0725a09b7c621a3d2eb66ba1513ae932aRichard Sandiford OPCODE(SEARCH_STRING); 2095ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford OPCODE(IPM); 20961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_SWAPW); 20971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_ADD); 20981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_SUB); 20991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_AND); 21001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_OR); 21011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_XOR); 21021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_NAND); 21031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_MIN); 21041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_MAX); 21051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_UMIN); 21061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_LOADW_UMAX); 21071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OPCODE(ATOMIC_CMP_SWAPW); 2108a550b51bac50493db75a7b5788a3f2c3b62fd913Richard Sandiford OPCODE(PREFETCH); 21091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 21101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return NULL; 21111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#undef OPCODE 21121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 21131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 21151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Custom insertion 21161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 21171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Create a new basic block after MBB. 21191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic MachineBasicBlock *emitBlockAfter(MachineBasicBlock *MBB) { 21201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 21211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *NewMBB = MF.CreateMachineBasicBlock(MBB->getBasicBlock()); 21221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MF.insert(llvm::next(MachineFunction::iterator(MBB)), NewMBB); 21231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return NewMBB; 21241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 21251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 212647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford// Split MBB after MI and return the new block (the one that contains 212747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford// instructions after MI). 212847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandifordstatic MachineBasicBlock *splitBlockAfter(MachineInstr *MI, 212947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *MBB) { 213047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *NewMBB = emitBlockAfter(MBB); 213147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford NewMBB->splice(NewMBB->begin(), MBB, 213247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford llvm::next(MachineBasicBlock::iterator(MI)), 213347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->end()); 213447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford NewMBB->transferSuccessorsAndUpdatePHIs(MBB); 213547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford return NewMBB; 213647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford} 213747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 2138842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford// Split MBB before MI and return the new block (the one that contains MI). 2139842a1be06c53757e7498c9894abc1431b633a92fRichard Sandifordstatic MachineBasicBlock *splitBlockBefore(MachineInstr *MI, 2140842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *MBB) { 21411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *NewMBB = emitBlockAfter(MBB); 2142842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford NewMBB->splice(NewMBB->begin(), MBB, MI, MBB->end()); 21431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand NewMBB->transferSuccessorsAndUpdatePHIs(MBB); 21441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return NewMBB; 21451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 21461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2147842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford// Force base value Base into a register before MI. Return the register. 2148842a1be06c53757e7498c9894abc1431b633a92fRichard Sandifordstatic unsigned forceReg(MachineInstr *MI, MachineOperand &Base, 2149842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford const SystemZInstrInfo *TII) { 2150842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (Base.isReg()) 2151842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford return Base.getReg(); 2152842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2153842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *MBB = MI->getParent(); 2154842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineFunction &MF = *MBB->getParent(); 2155842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineRegisterInfo &MRI = MF.getRegInfo(); 2156842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2157842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass); 2158842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(SystemZ::LA), Reg) 2159842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(Base).addImm(0).addReg(0); 2160842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford return Reg; 2161842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford} 2162842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 21631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo Select* instruction MI. 21641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 21651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitSelect(MachineInstr *MI, 21661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB) const { 21671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 21681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg = MI->getOperand(0).getReg(); 21701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned TrueReg = MI->getOperand(1).getReg(); 21711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned FalseReg = MI->getOperand(2).getReg(); 21726824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = MI->getOperand(3).getImm(); 21736824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = MI->getOperand(4).getImm(); 21741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 21751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2177842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *JoinMBB = splitBlockBefore(MI, MBB); 21781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *FalseMBB = emitBlockAfter(StartMBB); 21791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 2181d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford // BRC CCMask, JoinMBB 21821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fallthrough to FalseMBB 21831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 21846824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 21856824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB); 21861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(JoinMBB); 21871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(FalseMBB); 21881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FalseMBB: 21901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fallthrough to JoinMBB 21911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = FalseMBB; 21921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(JoinMBB); 21931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JoinMBB: 21951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Result = phi [ %FalseReg, FalseMBB ], [ %TrueReg, StartMBB ] 21961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 21971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = JoinMBB; 2198842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, DL, TII->get(SystemZ::PHI), DestReg) 21991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(TrueReg).addMBB(StartMBB) 22001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(FalseReg).addMBB(FalseMBB); 22011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 22021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 22031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return JoinMBB; 22041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 22051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2206722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford// Implement EmitInstrWithCustomInserter for pseudo CondStore* instruction MI. 2207722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford// StoreOpcode is the store to use and Invert says whether the store should 2208b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford// happen when the condition is false rather than true. If a STORE ON 2209b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford// CONDITION is available, STOCOpcode is its opcode, otherwise it is 0. 2210722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard SandifordMachineBasicBlock * 2211722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard SandifordSystemZTargetLowering::emitCondStore(MachineInstr *MI, 2212722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MachineBasicBlock *MBB, 2213b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford unsigned StoreOpcode, unsigned STOCOpcode, 2214b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford bool Invert) const { 2215722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford const SystemZInstrInfo *TII = TM.getInstrInfo(); 2216722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2217b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford unsigned SrcReg = MI->getOperand(0).getReg(); 2218b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford MachineOperand Base = MI->getOperand(1); 2219b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford int64_t Disp = MI->getOperand(2).getImm(); 2220b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford unsigned IndexReg = MI->getOperand(3).getReg(); 22216824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = MI->getOperand(4).getImm(); 22226824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = MI->getOperand(5).getImm(); 2223722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford DebugLoc DL = MI->getDebugLoc(); 2224722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2225722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford StoreOpcode = TII->getOpcodeForOffset(StoreOpcode, Disp); 2226722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2227b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford // Use STOCOpcode if possible. We could use different store patterns in 2228b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford // order to avoid matching the index register, but the performance trade-offs 2229b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford // might be more complicated in that case. 2230b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford if (STOCOpcode && !IndexReg && TM.getSubtargetImpl()->hasLoadStoreOnCond()) { 2231b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford if (Invert) 22326824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask ^= CCValid; 2233b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford BuildMI(*MBB, MI, DL, TII->get(STOCOpcode)) 22348f0ad5ae8f2699f6ab13a229941a0b192273cae8Richard Sandiford .addReg(SrcReg).addOperand(Base).addImm(Disp) 22358f0ad5ae8f2699f6ab13a229941a0b192273cae8Richard Sandiford .addImm(CCValid).addImm(CCMask); 2236b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford MI->eraseFromParent(); 2237b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return MBB; 2238b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford } 2239b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford 2240722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // Get the condition needed to branch around the store. 2241722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford if (!Invert) 22426824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford CCMask ^= CCValid; 2243722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2244722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MachineBasicBlock *StartMBB = MBB; 2245842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *JoinMBB = splitBlockBefore(MI, MBB); 2246722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MachineBasicBlock *FalseMBB = emitBlockAfter(StartMBB); 2247722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2248722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // StartMBB: 2249722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // BRC CCMask, JoinMBB 2250722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // # fallthrough to FalseMBB 2251722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB = StartMBB; 22526824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 22536824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(CCValid).addImm(CCMask).addMBB(JoinMBB); 2254722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB->addSuccessor(JoinMBB); 2255722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB->addSuccessor(FalseMBB); 2256722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2257722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // FalseMBB: 2258722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // store %SrcReg, %Disp(%Index,%Base) 2259722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford // # fallthrough to JoinMBB 2260722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB = FalseMBB; 2261722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford BuildMI(MBB, DL, TII->get(StoreOpcode)) 2262722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford .addReg(SrcReg).addOperand(Base).addImm(Disp).addReg(IndexReg); 2263722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MBB->addSuccessor(JoinMBB); 2264722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 2265722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford MI->eraseFromParent(); 2266722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford return JoinMBB; 2267722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford} 2268722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 22691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo ATOMIC_LOAD{,W}_* 22701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// or ATOMIC_SWAP{,W} instruction MI. BinOpcode is the instruction that 22711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// performs the binary operation elided by "*", or 0 for ATOMIC_SWAP{,W}. 22721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// BitSize is the width of the field in bits, or 0 if this is a partword 22731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// ATOMIC_LOADW_* or ATOMIC_SWAPW instruction, in which case the bitsize 22741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// is one of the operands. Invert says whether the field should be 22751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// inverted after performing BinOpcode (e.g. for NAND). 22761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 22771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitAtomicLoadBinary(MachineInstr *MI, 22781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB, 22791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BinOpcode, 22801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitSize, 22811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool Invert) const { 22821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 22831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 22841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 22851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsSubWord = (BitSize < 32); 22861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 22871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract the operands. Base can be a register or a frame index. 22881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Src2 can be a register or immediate. 22891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 22901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Base = earlyUseOperand(MI->getOperand(1)); 22911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp = MI->getOperand(2).getImm(); 22921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Src2 = earlyUseOperand(MI->getOperand(3)); 22931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitShift = (IsSubWord ? MI->getOperand(4).getReg() : 0); 22941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NegBitShift = (IsSubWord ? MI->getOperand(5).getReg() : 0); 22951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 22961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 22971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitSize = MI->getOperand(6).getImm(); 22981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 22991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Subword operations use 32-bit registers. 23001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC = (BitSize <= 32 ? 23011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR32BitRegClass : 23021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR64BitRegClass); 23031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LOpcode = BitSize <= 32 ? SystemZ::L : SystemZ::LG; 23041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG; 23051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the right opcodes for the displacement. 23071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LOpcode = TII->getOpcodeForOffset(LOpcode, Disp); 23081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp); 23091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LOpcode && CSOpcode && "Displacement out of range"); 23101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create virtual registers for temporary results. 23121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigVal = MRI.createVirtualRegister(RC); 23131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldVal = MRI.createVirtualRegister(RC); 23141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewVal = (BinOpcode || IsSubWord ? 23151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MRI.createVirtualRegister(RC) : Src2.getReg()); 23161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal); 23171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal); 23181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Insert a basic block for the main loop. 23201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2321842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 23221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 23231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 23251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 23261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OrigVal = L Disp(%Base) 23271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to LoopMMB 23281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 23291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(LOpcode), OrigVal) 23301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addOperand(Base).addImm(Disp).addReg(0); 23311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 23321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LoopMBB: 23341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OldVal = phi [ %OrigVal, StartMBB ], [ %Dest, LoopMBB ] 23351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedOldVal = RLL %OldVal, 0(%BitShift) 23361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedNewVal = OP %RotatedOldVal, %Src2 23371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %NewVal = RLL %RotatedNewVal, 0(%NegBitShift) 23381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Dest = CS %OldVal, %NewVal, Disp(%Base) 23391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JNE LoopMBB 23401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to DoneMMB 23411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = LoopMBB; 23421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal) 23431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigVal).addMBB(StartMBB) 23441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Dest).addMBB(LoopMBB); 23451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 23461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal) 23471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(BitShift).addImm(0); 23481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Invert) { 23491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Perform the operation normally and then invert every bit of the field. 23501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Tmp = MRI.createVirtualRegister(RC); 23511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(BinOpcode), Tmp) 23521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addOperand(Src2); 23531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (BitSize < 32) 23541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // XILF with the upper BitSize bits set. 2355259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal) 23561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Tmp).addImm(uint32_t(~0 << (32 - BitSize))); 23571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (BitSize == 32) 23581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // XILF with every bit set. 2359259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::XILF), RotatedNewVal) 23601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Tmp).addImm(~uint32_t(0)); 23611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else { 23621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use LCGR and add -1 to the result, which is more compact than 23631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // an XILF, XILH pair. 23641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Tmp2 = MRI.createVirtualRegister(RC); 23651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::LCGR), Tmp2).addReg(Tmp); 23661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::AGHI), RotatedNewVal) 23671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Tmp2).addImm(-1); 23681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 23691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (BinOpcode) 23701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // A simply binary operation. 23711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(BinOpcode), RotatedNewVal) 23721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addOperand(Src2); 23731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (IsSubWord) 23741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Use RISBG to rotate Src2 into position and use it to replace the 23751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // field in RotatedOldVal. 23761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedNewVal) 23771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addReg(Src2.getReg()) 23781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addImm(32).addImm(31 + BitSize).addImm(32 - BitSize); 23791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 23801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal) 23811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0); 23821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(CSOpcode), Dest) 23831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp); 23846824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 23856824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); 23861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 23871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 23881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 23901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DoneMBB; 23911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 23921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 23931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo 23941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// ATOMIC_LOAD{,W}_{,U}{MIN,MAX} instruction MI. CompareOpcode is the 23951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// instruction that should be used to compare the current field with the 23961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// minimum or maximum value. KeepOldMask is the BRC condition-code mask 23971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// for when the current field should be kept. BitSize is the width of 23981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// the field in bits, or 0 if this is a partword ATOMIC_LOADW_* instruction. 23991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 24001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitAtomicLoadMinMax(MachineInstr *MI, 24011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB, 24021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CompareOpcode, 24031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned KeepOldMask, 24041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitSize) const { 24051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 24061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 24071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 24081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool IsSubWord = (BitSize < 32); 24091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract the operands. Base can be a register or a frame index. 24111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 24121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Base = earlyUseOperand(MI->getOperand(1)); 24131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp = MI->getOperand(2).getImm(); 24141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Src2 = MI->getOperand(3).getReg(); 24151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitShift = (IsSubWord ? MI->getOperand(4).getReg() : 0); 24161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NegBitShift = (IsSubWord ? MI->getOperand(5).getReg() : 0); 24171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 24181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BitSize = MI->getOperand(6).getImm(); 24201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Subword operations use 32-bit registers. 24221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC = (BitSize <= 32 ? 24231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR32BitRegClass : 24241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand &SystemZ::GR64BitRegClass); 24251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LOpcode = BitSize <= 32 ? SystemZ::L : SystemZ::LG; 24261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CSOpcode = BitSize <= 32 ? SystemZ::CS : SystemZ::CSG; 24271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the right opcodes for the displacement. 24291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LOpcode = TII->getOpcodeForOffset(LOpcode, Disp); 24301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand CSOpcode = TII->getOpcodeForOffset(CSOpcode, Disp); 24311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LOpcode && CSOpcode && "Displacement out of range"); 24321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create virtual registers for temporary results. 24341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigVal = MRI.createVirtualRegister(RC); 24351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldVal = MRI.createVirtualRegister(RC); 24361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewVal = MRI.createVirtualRegister(RC); 24371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedOldVal = (IsSubWord ? MRI.createVirtualRegister(RC) : OldVal); 24381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedAltVal = (IsSubWord ? MRI.createVirtualRegister(RC) : Src2); 24391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RotatedNewVal = (IsSubWord ? MRI.createVirtualRegister(RC) : NewVal); 24401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Insert 3 basic blocks for the loop. 24421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2443842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 24441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 24451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *UseAltMBB = emitBlockAfter(LoopMBB); 24461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *UpdateMBB = emitBlockAfter(UseAltMBB); 24471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 24491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 24501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OrigVal = L Disp(%Base) 24511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to LoopMMB 24521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 24531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(LOpcode), OrigVal) 24541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addOperand(Base).addImm(Disp).addReg(0); 24551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 24561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LoopMBB: 24581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OldVal = phi [ %OrigVal, StartMBB ], [ %Dest, UpdateMBB ] 24591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedOldVal = RLL %OldVal, 0(%BitShift) 24601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // CompareOpcode %RotatedOldVal, %Src2 246144b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford // BRC KeepOldMask, UpdateMBB 24621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = LoopMBB; 24631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal) 24641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigVal).addMBB(StartMBB) 24651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(Dest).addMBB(UpdateMBB); 24661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal) 24681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(BitShift).addImm(0); 24690416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(CompareOpcode)) 24700416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford .addReg(RotatedOldVal).addReg(Src2); 24710416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 24726824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(KeepOldMask).addMBB(UpdateMBB); 24731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(UpdateMBB); 24741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(UseAltMBB); 24751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // UseAltMBB: 24771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedAltVal = RISBG %RotatedOldVal, %Src2, 32, 31 + BitSize, 0 24781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to UpdateMMB 24791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = UseAltMBB; 24801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RotatedAltVal) 24821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addReg(Src2) 24831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addImm(32).addImm(31 + BitSize).addImm(0); 24841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(UpdateMBB); 24851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 24861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // UpdateMBB: 24871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RotatedNewVal = PHI [ %RotatedOldVal, LoopMBB ], 24881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // [ %RotatedAltVal, UseAltMBB ] 24891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %NewVal = RLL %RotatedNewVal, 0(%NegBitShift) 24901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Dest = CS %OldVal, %NewVal, Disp(%Base) 24911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JNE LoopMBB 24921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to DoneMMB 24931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = UpdateMBB; 24941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), RotatedNewVal) 24951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedOldVal).addMBB(LoopMBB) 24961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedAltVal).addMBB(UseAltMBB); 24971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (IsSubWord) 24981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), NewVal) 24991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RotatedNewVal).addReg(NegBitShift).addImm(0); 25001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(CSOpcode), Dest) 25011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(NewVal).addOperand(Base).addImm(Disp); 25026824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 25036824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); 25041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 25051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 25061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 25081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DoneMBB; 25091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 25101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Implement EmitInstrWithCustomInserter for pseudo ATOMIC_CMP_SWAPW 25121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// instruction MI. 25131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 25141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, 25151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB) const { 25161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 25171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 25181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 25191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Extract the operands. Base can be a register or a frame index. 25211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 25221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand Base = earlyUseOperand(MI->getOperand(1)); 25231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Disp = MI->getOperand(2).getImm(); 25241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigCmpVal = MI->getOperand(3).getReg(); 25251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigSwapVal = MI->getOperand(4).getReg(); 25261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned BitShift = MI->getOperand(5).getReg(); 25271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NegBitShift = MI->getOperand(6).getReg(); 25281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t BitSize = MI->getOperand(7).getImm(); 25291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 25301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass; 25321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the right opcodes for the displacement. 25341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LOpcode = TII->getOpcodeForOffset(SystemZ::L, Disp); 25351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CSOpcode = TII->getOpcodeForOffset(SystemZ::CS, Disp); 25361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(LOpcode && CSOpcode && "Displacement out of range"); 25371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Create virtual registers for temporary results. 25391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OrigOldVal = MRI.createVirtualRegister(RC); 25401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OldVal = MRI.createVirtualRegister(RC); 25411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned CmpVal = MRI.createVirtualRegister(RC); 25421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SwapVal = MRI.createVirtualRegister(RC); 25431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned StoreVal = MRI.createVirtualRegister(RC); 25441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RetryOldVal = MRI.createVirtualRegister(RC); 25451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RetryCmpVal = MRI.createVirtualRegister(RC); 25461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned RetrySwapVal = MRI.createVirtualRegister(RC); 25471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Insert 2 basic blocks for the loop. 25491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *StartMBB = MBB; 2550842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 25511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 25521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *SetMBB = emitBlockAfter(LoopMBB); 25531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // StartMBB: 25551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ... 25561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OrigOldVal = L Disp(%Base) 25571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to LoopMMB 25581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = StartMBB; 25591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(LOpcode), OrigOldVal) 25601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addOperand(Base).addImm(Disp).addReg(0); 25611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 25621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // LoopMBB: 25641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %OldVal = phi [ %OrigOldVal, EntryBB ], [ %RetryOldVal, SetMBB ] 25651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %CmpVal = phi [ %OrigCmpVal, EntryBB ], [ %RetryCmpVal, SetMBB ] 25661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %SwapVal = phi [ %OrigSwapVal, EntryBB ], [ %RetrySwapVal, SetMBB ] 25671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %Dest = RLL %OldVal, BitSize(%BitShift) 25681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ The low BitSize bits contain the field 25691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // of interest. 25701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RetryCmpVal = RISBG32 %CmpVal, %Dest, 32, 63-BitSize, 0 25711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ Replace the upper 32-BitSize bits of the 25721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // comparison value with those that we loaded, 25731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // so that we can use a full word comparison. 25740416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford // CR %Dest, %RetryCmpVal 25750416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford // JNE DoneMBB 25761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # Fall through to SetMBB 25771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = LoopMBB; 25781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal) 25791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigOldVal).addMBB(StartMBB) 25801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetryOldVal).addMBB(SetMBB); 25811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), CmpVal) 25821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigCmpVal).addMBB(StartMBB) 25831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetryCmpVal).addMBB(SetMBB); 25841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::PHI), SwapVal) 25851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OrigSwapVal).addMBB(StartMBB) 25861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetrySwapVal).addMBB(SetMBB); 25871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), Dest) 25881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(BitShift).addImm(BitSize); 25891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetryCmpVal) 25901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(CmpVal).addReg(Dest).addImm(32).addImm(63 - BitSize).addImm(0); 25910416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::CR)) 25920416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford .addReg(Dest).addReg(RetryCmpVal); 25930416e3c599c22dc656a1115ac983116ad0b2d9daRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 25946824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_ICMP) 25956824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CMP_NE).addMBB(DoneMBB); 25961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 25971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(SetMBB); 25981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 25991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // SetMBB: 26001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RetrySwapVal = RISBG32 %SwapVal, %Dest, 32, 63-BitSize, 0 26011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ Replace the upper 32-BitSize bits of the new 26021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // value with those that we loaded. 26031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %StoreVal = RLL %RetrySwapVal, -BitSize(%NegBitShift) 26041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // ^^ Rotate the new field to its proper position. 26051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // %RetryOldVal = CS %Dest, %StoreVal, Disp(%Base) 26061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // JNE LoopMBB 26071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // # fall through to ExitMMB 26081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB = SetMBB; 26091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetrySwapVal) 26101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SwapVal).addReg(Dest).addImm(32).addImm(63 - BitSize).addImm(0); 26111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(SystemZ::RLL), StoreVal) 26121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(RetrySwapVal).addReg(NegBitShift).addImm(-BitSize); 26131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, DL, TII->get(CSOpcode), RetryOldVal) 26141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(OldVal).addReg(StoreVal).addOperand(Base).addImm(Disp); 26156824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 26166824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(SystemZ::CCMASK_CS).addImm(SystemZ::CCMASK_CS_NE).addMBB(LoopMBB); 26171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(LoopMBB); 26181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->addSuccessor(DoneMBB); 26191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 26211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return DoneMBB; 26221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 26231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Emit an extension from a GR32 or GR64 to a GR128. ClearEven is true 26251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// if the high register of the GR128 value must be cleared or false if 2626745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford// it's "don't care". SubReg is subreg_l32 when extending a GR32 2627745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford// and subreg_l64 when extending a GR64. 26281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock * 26291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZTargetLowering::emitExt128(MachineInstr *MI, 26301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB, 26311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool ClearEven, unsigned SubReg) const { 26321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SystemZInstrInfo *TII = TM.getInstrInfo(); 26331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 26341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineRegisterInfo &MRI = MF.getRegInfo(); 26351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MI->getDebugLoc(); 26361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Dest = MI->getOperand(0).getReg(); 26381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Src = MI->getOperand(1).getReg(); 26391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned In128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass); 26401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::IMPLICIT_DEF), In128); 26421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ClearEven) { 26431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewIn128 = MRI.createVirtualRegister(&SystemZ::GR128BitRegClass); 26441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Zero64 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass); 26451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(SystemZ::LLILL), Zero64) 26471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addImm(0); 26481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), NewIn128) 2649745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford .addReg(In128).addReg(Zero64).addImm(SystemZ::subreg_h64); 26501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand In128 = NewIn128; 26511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 26521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::INSERT_SUBREG), Dest) 26531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(In128).addReg(Src).addImm(SubReg); 26541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->eraseFromParent(); 26561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return MBB; 26571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 26581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2659dff0009d0ced62b92cb5900bc2203ec40142ba15Richard SandifordMachineBasicBlock * 2660ac168b8bc8773a083a10902f64e4ae57a925aee4Richard SandifordSystemZTargetLowering::emitMemMemWrapper(MachineInstr *MI, 2661ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford MachineBasicBlock *MBB, 2662ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford unsigned Opcode) const { 2663dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford const SystemZInstrInfo *TII = TM.getInstrInfo(); 2664842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineFunction &MF = *MBB->getParent(); 2665842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineRegisterInfo &MRI = MF.getRegInfo(); 2666dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford DebugLoc DL = MI->getDebugLoc(); 2667dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 2668842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineOperand DestBase = earlyUseOperand(MI->getOperand(0)); 2669dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford uint64_t DestDisp = MI->getOperand(1).getImm(); 2670842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineOperand SrcBase = earlyUseOperand(MI->getOperand(2)); 2671dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford uint64_t SrcDisp = MI->getOperand(3).getImm(); 2672dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford uint64_t Length = MI->getOperand(4).getImm(); 2673dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 267447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // When generating more than one CLC, all but the last will need to 267547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // branch to the end when a difference is found. 267647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *EndMBB = (Length > 256 && Opcode == SystemZ::CLC ? 267747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford splitBlockAfter(MI, MBB) : 0); 267847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 2679842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Check for the loop form, in which operand 5 is the trip count. 2680842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (MI->getNumExplicitOperands() > 5) { 2681842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford bool HaveSingleBase = DestBase.isIdenticalTo(SrcBase); 2682842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2683842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t StartCountReg = MI->getOperand(5).getReg(); 2684842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t StartSrcReg = forceReg(MI, SrcBase, TII); 2685842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t StartDestReg = (HaveSingleBase ? StartSrcReg : 2686842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford forceReg(MI, DestBase, TII)); 2687842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2688842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass; 2689842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisSrcReg = MRI.createVirtualRegister(RC); 2690842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisDestReg = (HaveSingleBase ? ThisSrcReg : 2691842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MRI.createVirtualRegister(RC)); 2692842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t NextSrcReg = MRI.createVirtualRegister(RC); 2693842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t NextDestReg = (HaveSingleBase ? NextSrcReg : 2694842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MRI.createVirtualRegister(RC)); 2695842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2696842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford RC = &SystemZ::GR64BitRegClass; 2697842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisCountReg = MRI.createVirtualRegister(RC); 2698842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t NextCountReg = MRI.createVirtualRegister(RC); 2699842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2700842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *StartMBB = MBB; 2701842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 2702842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 270347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *NextMBB = (EndMBB ? emitBlockAfter(LoopMBB) : LoopMBB); 2704842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2705842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // StartMBB: 2706842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // # fall through to LoopMMB 2707842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB->addSuccessor(LoopMBB); 2708842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2709842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // LoopMBB: 2710842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // %ThisDestReg = phi [ %StartDestReg, StartMBB ], 271147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // [ %NextDestReg, NextMBB ] 2712842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // %ThisSrcReg = phi [ %StartSrcReg, StartMBB ], 271347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // [ %NextSrcReg, NextMBB ] 2714842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // %ThisCountReg = phi [ %StartCountReg, StartMBB ], 271547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // [ %NextCountReg, NextMBB ] 271647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // ( PFD 2, 768+DestDisp(%ThisDestReg) ) 2717842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Opcode DestDisp(256,%ThisDestReg), SrcDisp(%ThisSrcReg) 271847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // ( JLH EndMBB ) 2719842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // 272047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // The prefetch is used only for MVC. The JLH is used only for CLC. 2721842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB = LoopMBB; 2722842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2723842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisDestReg) 2724842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(StartDestReg).addMBB(StartMBB) 272547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(NextDestReg).addMBB(NextMBB); 2726842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!HaveSingleBase) 2727842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisSrcReg) 2728842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(StartSrcReg).addMBB(StartMBB) 272947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(NextSrcReg).addMBB(NextMBB); 2730842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), ThisCountReg) 2731842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(StartCountReg).addMBB(StartMBB) 273247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(NextCountReg).addMBB(NextMBB); 273347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (Opcode == SystemZ::MVC) 273447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PFD)) 273547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addImm(SystemZ::PFD_WRITE) 273647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addReg(ThisDestReg).addImm(DestDisp + 768).addReg(0); 2737842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(Opcode)) 2738842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisDestReg).addImm(DestDisp).addImm(256) 2739842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisSrcReg).addImm(SrcDisp); 274047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (EndMBB) { 274147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 274247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE) 274347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addMBB(EndMBB); 274447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(EndMBB); 274547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(NextMBB); 274647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford } 274747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 274847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // NextMBB: 274947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // %NextDestReg = LA 256(%ThisDestReg) 275047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // %NextSrcReg = LA 256(%ThisSrcReg) 275147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // %NextCountReg = AGHI %ThisCountReg, -1 275247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // CGHI %NextCountReg, 0 275347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // JLH LoopMBB 275447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // # fall through to DoneMMB 275547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // 275647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // The AGHI, CGHI and JLH should be converted to BRCTG by later passes. 275747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB = NextMBB; 275847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford 2759842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::LA), NextDestReg) 2760842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisDestReg).addImm(256).addReg(0); 2761842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!HaveSingleBase) 2762842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::LA), NextSrcReg) 2763842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisSrcReg).addImm(256).addReg(0); 2764842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::AGHI), NextCountReg) 2765842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(ThisCountReg).addImm(-1); 2766842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::CGHI)) 2767842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addReg(NextCountReg).addImm(0); 2768842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 2769842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE) 2770842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addMBB(LoopMBB); 2771842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB->addSuccessor(LoopMBB); 2772842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB->addSuccessor(DoneMBB); 2773842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford 2774842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestBase = MachineOperand::CreateReg(NextDestReg, false); 2775842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcBase = MachineOperand::CreateReg(NextSrcReg, false); 2776842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford Length &= 255; 2777842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MBB = DoneMBB; 2778842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2779842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Handle any remaining bytes with straight-line code. 2780842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford while (Length > 0) { 2781842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford uint64_t ThisLength = std::min(Length, uint64_t(256)); 2782842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // The previous iteration might have created out-of-range displacements. 2783842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford // Apply them using LAY if so. 2784842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!isUInt<12>(DestDisp)) { 2785842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass); 2786842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(SystemZ::LAY), Reg) 2787842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(DestBase).addImm(DestDisp).addReg(0); 2788842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestBase = MachineOperand::CreateReg(Reg, false); 2789842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestDisp = 0; 2790842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2791842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford if (!isUInt<12>(SrcDisp)) { 2792842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford unsigned Reg = MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass); 2793842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(SystemZ::LAY), Reg) 2794842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(SrcBase).addImm(SrcDisp).addReg(0); 2795842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcBase = MachineOperand::CreateReg(Reg, false); 2796842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcDisp = 0; 2797842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2798842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford BuildMI(*MBB, MI, DL, TII->get(Opcode)) 2799842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(DestBase).addImm(DestDisp).addImm(ThisLength) 2800842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford .addOperand(SrcBase).addImm(SrcDisp); 2801842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford DestDisp += ThisLength; 2802842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford SrcDisp += ThisLength; 2803842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford Length -= ThisLength; 280447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // If there's another CLC to go, branch to the end if a difference 280547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford // was found. 280647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (EndMBB && Length > 0) { 280747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MachineBasicBlock *NextMBB = splitBlockBefore(MI, MBB); 280847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 280947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addImm(SystemZ::CCMASK_ICMP).addImm(SystemZ::CCMASK_CMP_NE) 281047e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford .addMBB(EndMBB); 281147e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(EndMBB); 281247e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(NextMBB); 281347e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB = NextMBB; 281447e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford } 281547e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford } 281647e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford if (EndMBB) { 281747e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addSuccessor(EndMBB); 281847e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB = EndMBB; 281947e70960945ecb33a361987a9745e3dc80a1c78cRichard Sandiford MBB->addLiveIn(SystemZ::CC); 2820842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford } 2821dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 2822dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MI->eraseFromParent(); 2823dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford return MBB; 2824dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford} 2825dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 2826e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford// Decompose string pseudo-instruction MI into a loop that continually performs 2827e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford// Opcode until CC != 3. 2828e1b2af731e2a45344a7c502232f66c55cd746da0Richard SandifordMachineBasicBlock * 2829e1b2af731e2a45344a7c502232f66c55cd746da0Richard SandifordSystemZTargetLowering::emitStringWrapper(MachineInstr *MI, 2830e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineBasicBlock *MBB, 2831e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford unsigned Opcode) const { 2832e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford const SystemZInstrInfo *TII = TM.getInstrInfo(); 2833e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineFunction &MF = *MBB->getParent(); 2834e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineRegisterInfo &MRI = MF.getRegInfo(); 2835e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford DebugLoc DL = MI->getDebugLoc(); 2836e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2837e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t End1Reg = MI->getOperand(0).getReg(); 2838e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t Start1Reg = MI->getOperand(1).getReg(); 2839e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t Start2Reg = MI->getOperand(2).getReg(); 2840e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t CharReg = MI->getOperand(3).getReg(); 2841e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2842e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass; 2843e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t This1Reg = MRI.createVirtualRegister(RC); 2844e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t This2Reg = MRI.createVirtualRegister(RC); 2845e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford uint64_t End2Reg = MRI.createVirtualRegister(RC); 2846e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2847e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineBasicBlock *StartMBB = MBB; 2848842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford MachineBasicBlock *DoneMBB = splitBlockBefore(MI, MBB); 2849e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MachineBasicBlock *LoopMBB = emitBlockAfter(StartMBB); 2850e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2851e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // StartMBB: 2852e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // # fall through to LoopMMB 2853e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB->addSuccessor(LoopMBB); 2854e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2855e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // LoopMBB: 2856e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // %This1Reg = phi [ %Start1Reg, StartMBB ], [ %End1Reg, LoopMBB ] 2857e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // %This2Reg = phi [ %Start2Reg, StartMBB ], [ %End2Reg, LoopMBB ] 2858514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford // R0L = %CharReg 2859514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford // %End1Reg, %End2Reg = CLST %This1Reg, %This2Reg -- uses R0L 2860e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // JO LoopMBB 2861e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford // # fall through to DoneMMB 28628c20158fb0e1e5d747077f065eb0170c5af1fbfaRichard Sandiford // 2863514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford // The load of R0L can be hoisted by post-RA LICM. 2864e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB = LoopMBB; 2865e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2866e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), This1Reg) 2867e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(Start1Reg).addMBB(StartMBB) 2868e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(End1Reg).addMBB(LoopMBB); 2869e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::PHI), This2Reg) 2870e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(Start2Reg).addMBB(StartMBB) 2871e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(End2Reg).addMBB(LoopMBB); 2872514756983e9ba3684a89ed583bf5a98ffb20c203Richard Sandiford BuildMI(MBB, DL, TII->get(TargetOpcode::COPY), SystemZ::R0L).addReg(CharReg); 2873e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(Opcode)) 2874e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(End1Reg, RegState::Define).addReg(End2Reg, RegState::Define) 2875e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addReg(This1Reg).addReg(This2Reg); 2876e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford BuildMI(MBB, DL, TII->get(SystemZ::BRC)) 2877e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford .addImm(SystemZ::CCMASK_ANY).addImm(SystemZ::CCMASK_3).addMBB(LoopMBB); 2878e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB->addSuccessor(LoopMBB); 2879e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MBB->addSuccessor(DoneMBB); 2880e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2881e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford DoneMBB->addLiveIn(SystemZ::CC); 2882e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 2883e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford MI->eraseFromParent(); 2884e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford return DoneMBB; 2885e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford} 2886e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford 28871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMachineBasicBlock *SystemZTargetLowering:: 28881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandEmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const { 28891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 289047086570973e82fe5ea8ace9637ae73c2469e1daRichard Sandiford case SystemZ::Select32Mux: 28911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::Select32: 28921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::SelectF32: 28931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::Select64: 28941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::SelectF64: 28951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::SelectF128: 28961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitSelect(MI, MBB); 28971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 289800f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford case SystemZ::CondStore8Mux: 289900f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STCMux, 0, false); 290000f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford case SystemZ::CondStore8MuxInv: 290100f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STCMux, 0, true); 290200f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford case SystemZ::CondStore16Mux: 290300f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STHMux, 0, false); 290400f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford case SystemZ::CondStore16MuxInv: 290500f5335ea0b62f0921d215a4d04e2fe5f33771ceRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STHMux, 0, true); 2906722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore8: 2907b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STC, 0, false); 2908722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore8Inv: 2909b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STC, 0, true); 2910722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore16: 2911b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STH, 0, false); 2912722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore16Inv: 2913b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STH, 0, true); 2914722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore32: 2915b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, false); 2916722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore32Inv: 2917b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::ST, SystemZ::STOC, true); 2918722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore64: 2919b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, false); 2920722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStore64Inv: 2921b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STG, SystemZ::STOCG, true); 2922722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF32: 2923b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STE, 0, false); 2924722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF32Inv: 2925b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STE, 0, true); 2926722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF64: 2927b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STD, 0, false); 2928722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford case SystemZ::CondStoreF64Inv: 2929b284e1bf08d24deb20b7deab71fce6f3034cc89aRichard Sandiford return emitCondStore(MI, MBB, SystemZ::STD, 0, true); 2930722e9e6d0a5b67d136be40bc015abc5b0b32f97bRichard Sandiford 29311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::AEXT128_64: 2932745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return emitExt128(MI, MBB, false, SystemZ::subreg_l64); 29331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ZEXT128_32: 2934745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return emitExt128(MI, MBB, true, SystemZ::subreg_l32); 29351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ZEXT128_64: 2936745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford return emitExt128(MI, MBB, true, SystemZ::subreg_l64); 29371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_SWAPW: 29391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, 0, 0); 29401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_SWAP_32: 29411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, 0, 32); 29421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_SWAP_64: 29431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, 0, 64); 29441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_AR: 29461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 0); 29471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_AFI: 29481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 0); 29491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AR: 29501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AR, 32); 29511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AHI: 29521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AHI, 32); 29531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AFI: 29541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AFI, 32); 29551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AGR: 29561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AGR, 64); 29571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AGHI: 29581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AGHI, 64); 29591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_AGFI: 29601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::AGFI, 64); 29611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_SR: 29631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 0); 29641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_SR: 29651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::SR, 32); 29661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_SGR: 29671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::SGR, 64); 29681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NR: 29701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0); 29711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NILH: 2972259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0); 29731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NR: 29741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32); 29751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILL: 2976259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32); 29771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILH: 2978259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32); 2979259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILF: 2980259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32); 2981259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NGR: 2982259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64); 2983259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILL64: 2984259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64); 2985259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILH64: 2986259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64); 2987b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHL64: 2988b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64); 2989b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHH64: 2990b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64); 2991259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILF64: 2992259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64); 2993b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHF64: 2994b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64); 29951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 29961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_OR: 29971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 0); 29981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_OILH: 2999259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 0); 30001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_OR: 30011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::OR, 32); 30021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_OILL: 3003259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL, 32); 30041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_OILH: 3005259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH, 32); 3006259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILF: 3007259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF, 32); 3008259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OGR: 3009259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OGR, 64); 3010259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILL64: 3011259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILL64, 64); 3012259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILH64: 3013259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILH64, 64); 30141c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::ATOMIC_LOAD_OIHL64: 30151c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHL64, 64); 30161c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::ATOMIC_LOAD_OIHH64: 30171c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHH64, 64); 3018259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_OILF64: 3019259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OILF64, 64); 30201c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::ATOMIC_LOAD_OIHF64: 30211c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::OIHF64, 64); 30221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_XR: 30241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 0); 30251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_XILF: 3026259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 0); 30271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_XR: 30281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::XR, 32); 3029259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_XILF: 3030259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF, 32); 30311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_XGR: 30321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::XGR, 64); 3033259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_XILF64: 3034259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XILF64, 64); 30351ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford case SystemZ::ATOMIC_LOAD_XIHF64: 30361ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::XIHF64, 64); 30371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NRi: 30391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 0, true); 30401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_NILHi: 3041259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 0, true); 30421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NRi: 30431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadBinary(MI, MBB, SystemZ::NR, 32, true); 30441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILLi: 3045259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL, 32, true); 30461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_NILHi: 3047259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH, 32, true); 3048259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILFi: 3049259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF, 32, true); 3050259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NGRi: 3051259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NGR, 64, true); 3052259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILL64i: 3053259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILL64, 64, true); 3054259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILH64i: 3055259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILH64, 64, true); 3056b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHL64i: 3057b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHL64, 64, true); 3058b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHH64i: 3059b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHH64, 64, true); 3060259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::ATOMIC_LOAD_NILF64i: 3061259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NILF64, 64, true); 3062b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::ATOMIC_LOAD_NIHF64i: 3063b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return emitAtomicLoadBinary(MI, MBB, SystemZ::NIHF64, 64, true); 30641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_MIN: 30661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 0); 30681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MIN_32: 30691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 32); 30711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MIN_64: 30721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR, 30731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 64); 30741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_MAX: 30761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 0); 30781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MAX_32: 30791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CR, 30801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 32); 30811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_MAX_64: 30821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CGR, 30831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 64); 30841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_UMIN: 30861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 30871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 0); 30881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMIN_32: 30891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 30901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 32); 30911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMIN_64: 30921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR, 30931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_LE, 64); 30941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 30951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOADW_UMAX: 30961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 30971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 0); 30981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMAX_32: 30991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLR, 31001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 32); 31011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_LOAD_UMAX_64: 31021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicLoadMinMax(MI, MBB, SystemZ::CLGR, 31031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZ::CCMASK_CMP_GE, 64); 31041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 31051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ATOMIC_CMP_SWAPW: 31061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return emitAtomicCmpSwapW(MI, MBB); 3107842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::MVCSequence: 3108842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::MVCLoop: 3109ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::MVC); 311016277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::NCSequence: 311116277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::NCLoop: 311216277c4698f36a756c540fae326874774156aaedRichard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::NC); 311316277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::OCSequence: 311416277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::OCLoop: 311516277c4698f36a756c540fae326874774156aaedRichard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::OC); 311616277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::XCSequence: 311716277c4698f36a756c540fae326874774156aaedRichard Sandiford case SystemZ::XCLoop: 311816277c4698f36a756c540fae326874774156aaedRichard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::XC); 3119842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::CLCSequence: 3120842a1be06c53757e7498c9894abc1431b633a92fRichard Sandiford case SystemZ::CLCLoop: 3121ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return emitMemMemWrapper(MI, MBB, SystemZ::CLC); 3122e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford case SystemZ::CLSTLoop: 3123e1b2af731e2a45344a7c502232f66c55cd746da0Richard Sandiford return emitStringWrapper(MI, MBB, SystemZ::CLST); 31244fc7355a21e1fa838406e15459aaf54a58fcf909Richard Sandiford case SystemZ::MVSTLoop: 31254fc7355a21e1fa838406e15459aaf54a58fcf909Richard Sandiford return emitStringWrapper(MI, MBB, SystemZ::MVST); 312619262ee0725a09b7c621a3d2eb66ba1513ae932aRichard Sandiford case SystemZ::SRSTLoop: 312719262ee0725a09b7c621a3d2eb66ba1513ae932aRichard Sandiford return emitStringWrapper(MI, MBB, SystemZ::SRST); 31281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 31291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unexpected instr type to insert"); 31301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 31311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3132