11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZInstrInfo.cpp - SystemZ instruction information ------------===// 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 contains the SystemZ implementation of the TargetInstrInfo class. 111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZInstrInfo.h" 151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZInstrBuilder.h" 1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "SystemZTargetMachine.h" 1793c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford#include "llvm/CodeGen/LiveVariables.h" 181ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford#include "llvm/CodeGen/MachineRegisterInfo.h" 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesusing namespace llvm; 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 22354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka#define GET_INSTRINFO_CTOR_DTOR 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define GET_INSTRMAP_INFO 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZGenInstrInfo.inc" 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 26b3f912b510f8040690864126351b7021980558bbRichard Sandiford// Return a mask with Count low bits set. 27b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic uint64_t allOnes(unsigned int Count) { 28b3f912b510f8040690864126351b7021980558bbRichard Sandiford return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1; 29b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 30b3f912b510f8040690864126351b7021980558bbRichard Sandiford 3155d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// Reg should be a 32-bit GPR. Return true if it is a high register rather 3255d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// than a low register. 3355d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandifordstatic bool isHighReg(unsigned int Reg) { 3455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (SystemZ::GRH32BitRegClass.contains(Reg)) 3555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return true; 3655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford assert(SystemZ::GR32BitRegClass.contains(Reg) && "Invalid GRX32"); 3755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return false; 3855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford} 3955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 40354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka// Pin the vtable to this file. 41354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzkavoid SystemZInstrInfo::anchor() {} 42354362524a72b3fa43a6c09380b7ae3b2380cbbaJuergen Ributzka 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesSystemZInstrInfo::SystemZInstrInfo(SystemZSubtarget &sti) 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP), 45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RI(), STI(sti) { 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// MI is a 128-bit load or store. Split it into two 64-bit loads or stores, 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// each having the opcode given by NewOpcode. 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI, 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode) const { 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get two load or store instructions. Use the original instruction for one 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // of them (arbitrarily the second here) and create a clone for the other. 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineInstr *EarlierMI = MF.CloneMachineInstr(MI); 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MBB->insert(MI, EarlierMI); 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set up the two 64-bit registers. 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighRegOp = EarlierMI->getOperand(0); 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowRegOp = MI->getOperand(0); 63745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_h64)); 64745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_l64)); 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // The address in the first (high) instruction is already correct. 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Adjust the offset in the second (low) instruction. 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &HighOffsetOp = EarlierMI->getOperand(2); 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &LowOffsetOp = MI->getOperand(2); 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LowOffsetOp.setImm(LowOffsetOp.getImm() + 8); 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Set the opcodes. 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm()); 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm()); 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(HighOpcode && LowOpcode && "Both offsets should be in range"); 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand EarlierMI->setDesc(get(HighOpcode)); 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(LowOpcode)); 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Split ADJDYNALLOC instruction MI. 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const { 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *MBB = MI->getParent(); 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFunction &MF = *MBB->getParent(); 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineFrameInfo *MFFrame = MF.getFrameInfo(); 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineOperand &OffsetMO = MI->getOperand(2); 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Offset = (MFFrame->getMaxCallFrameSize() + 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMC::CallFrameSize + 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.getImm()); 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset); 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(NewOpcode && "No support for huge argument lists yet"); 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->setDesc(get(NewOpcode)); 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OffsetMO.setImm(Offset); 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 974c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford// MI is an RI-style pseudo instruction. Replace it with LowOpcode 984c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford// if the first operand is a low GR32 and HighOpcode if the first operand 994c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford// is a high GR32. ConvertHigh is true if LowOpcode takes a signed operand 1004c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford// and HighOpcode takes an unsigned 32-bit operand. In those cases, 1014c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford// MI has the same kind of operand as LowOpcode, so needs to be converted 1024c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford// if HighOpcode is used. 1034c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandifordvoid SystemZInstrInfo::expandRIPseudo(MachineInstr *MI, unsigned LowOpcode, 1044c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford unsigned HighOpcode, 1054c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford bool ConvertHigh) const { 1064c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford unsigned Reg = MI->getOperand(0).getReg(); 1074c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford bool IsHigh = isHighReg(Reg); 1084c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford MI->setDesc(get(IsHigh ? HighOpcode : LowOpcode)); 1094c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford if (IsHigh && ConvertHigh) 1104c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford MI->getOperand(1).setImm(uint32_t(MI->getOperand(1).getImm())); 1114c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford} 1124c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford 113ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford// MI is a three-operand RIE-style pseudo instruction. Replace it with 114ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford// LowOpcode3 if the registers are both low GR32s, otherwise use a move 115ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford// followed by HighOpcode or LowOpcode, depending on whether the target 116ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford// is a high or low GR32. 117ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandifordvoid SystemZInstrInfo::expandRIEPseudo(MachineInstr *MI, unsigned LowOpcode, 118ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford unsigned LowOpcodeK, 119ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford unsigned HighOpcode) const { 120ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford unsigned DestReg = MI->getOperand(0).getReg(); 121ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford unsigned SrcReg = MI->getOperand(1).getReg(); 122ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford bool DestIsHigh = isHighReg(DestReg); 123ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford bool SrcIsHigh = isHighReg(SrcReg); 124ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford if (!DestIsHigh && !SrcIsHigh) 125ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MI->setDesc(get(LowOpcodeK)); 126ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford else { 127ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford emitGRX32Move(*MI->getParent(), MI, MI->getDebugLoc(), 128ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford DestReg, SrcReg, SystemZ::LR, 32, 129ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MI->getOperand(1).isKill()); 130ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MI->setDesc(get(DestIsHigh ? HighOpcode : LowOpcode)); 131ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MI->getOperand(1).setReg(DestReg); 132ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford } 133ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford} 134ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford 13555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// MI is an RXY-style pseudo instruction. Replace it with LowOpcode 13655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// if the first operand is a low GR32 and HighOpcode if the first operand 13755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// is a high GR32. 13855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandifordvoid SystemZInstrInfo::expandRXYPseudo(MachineInstr *MI, unsigned LowOpcode, 13955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford unsigned HighOpcode) const { 14055d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford unsigned Reg = MI->getOperand(0).getReg(); 14155d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford unsigned Opcode = getOpcodeForOffset(isHighReg(Reg) ? HighOpcode : LowOpcode, 14255d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford MI->getOperand(2).getImm()); 14355d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford MI->setDesc(get(Opcode)); 14455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford} 14555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 14679e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford// MI is an RR-style pseudo instruction that zero-extends the low Size bits 14779e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford// of one GRX32 into another. Replace it with LowOpcode if both operands 14879e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford// are low registers, otherwise use RISB[LH]G. 14979e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandifordvoid SystemZInstrInfo::expandZExtPseudo(MachineInstr *MI, unsigned LowOpcode, 15079e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford unsigned Size) const { 15179e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford emitGRX32Move(*MI->getParent(), MI, MI->getDebugLoc(), 15279e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford MI->getOperand(0).getReg(), MI->getOperand(1).getReg(), 15379e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford LowOpcode, Size, MI->getOperand(1).isKill()); 15479e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford MI->eraseFromParent(); 15579e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford} 15679e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford 15755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// Emit a zero-extending move from 32-bit GPR SrcReg to 32-bit GPR 15855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// DestReg before MBBI in MBB. Use LowLowOpcode when both DestReg and SrcReg 15955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// are low registers, otherwise use RISB[LH]G. Size is the number of bits 16055d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// taken from the low end of SrcReg (8 for LLCR, 16 for LLHR and 32 for LR). 16155d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford// KillSrc is true if this move is the last use of SrcReg. 16255d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandifordvoid SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB, 16355d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford MachineBasicBlock::iterator MBBI, 16455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford DebugLoc DL, unsigned DestReg, 16555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford unsigned SrcReg, unsigned LowLowOpcode, 16655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford unsigned Size, bool KillSrc) const { 16755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford unsigned Opcode; 16855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford bool DestIsHigh = isHighReg(DestReg); 16955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford bool SrcIsHigh = isHighReg(SrcReg); 17055d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (DestIsHigh && SrcIsHigh) 17155d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford Opcode = SystemZ::RISBHH; 17255d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford else if (DestIsHigh && !SrcIsHigh) 17355d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford Opcode = SystemZ::RISBHL; 17455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford else if (!DestIsHigh && SrcIsHigh) 17555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford Opcode = SystemZ::RISBLH; 17655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford else { 17755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford BuildMI(MBB, MBBI, DL, get(LowLowOpcode), DestReg) 17855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford .addReg(SrcReg, getKillRegState(KillSrc)); 17955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return; 18055d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford } 18155d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0); 18255d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) 18355d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford .addReg(DestReg, RegState::Undef) 18455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford .addReg(SrcReg, getKillRegState(KillSrc)) 18555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford .addImm(32 - Size).addImm(128 + 31).addImm(Rotate); 18655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford} 18755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 1881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// If MI is a simple load or store for a frame object, return the register 1891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// it loads or stores and set FrameIndex to the index of the frame object. 1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return 0 otherwise. 1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 1931ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandifordstatic int isSimpleMove(const MachineInstr *MI, int &FrameIndex, 1941ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned Flag) { 1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = MI->getDesc(); 1961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if ((MCID.TSFlags & Flag) && 1971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(1).isFI() && 1981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(2).getImm() == 0 && 1991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(3).getReg() == 0) { 2001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIndex = MI->getOperand(1).getIndex(); 2011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return MI->getOperand(0).getReg(); 2021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 2041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 2071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 2081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad); 2091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 2121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int &FrameIndex) const { 2131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore); 2141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 2151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 21671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandifordbool SystemZInstrInfo::isStackSlotCopy(const MachineInstr *MI, 21771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int &DestFrameIndex, 21871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int &SrcFrameIndex) const { 21971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford // Check for MVC 0(Length,FI1),0(FI2) 22071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford const MachineFrameInfo *MFI = MI->getParent()->getParent()->getFrameInfo(); 22171804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford if (MI->getOpcode() != SystemZ::MVC || 22271804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford !MI->getOperand(0).isFI() || 22371804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MI->getOperand(1).getImm() != 0 || 22471804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford !MI->getOperand(3).isFI() || 22571804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MI->getOperand(4).getImm() != 0) 22671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return false; 22771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 22871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford // Check that Length covers the full slots. 22971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford int64_t Length = MI->getOperand(2).getImm(); 23071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford unsigned FI1 = MI->getOperand(0).getIndex(); 23171804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford unsigned FI2 = MI->getOperand(3).getIndex(); 23271804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford if (MFI->getObjectSize(FI1) != Length || 23371804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford MFI->getObjectSize(FI2) != Length) 23471804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return false; 23571804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 23671804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford DestFrameIndex = FI1; 23771804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford SrcFrameIndex = FI2; 23871804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford return true; 23971804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford} 24071804149a3a6f6c081b874869b27fafe7d3288ceRichard Sandiford 2411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 2421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&TBB, 2431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *&FBB, 2441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SmallVectorImpl<MachineOperand> &Cond, 2451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool AllowModify) const { 2461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 2471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Start from the bottom of the block and work up, examining the 2491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // terminator instructions. 2501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 2511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 2521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 2531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 2541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 2551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, when we see a non-terminator instruction, we're 2571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // done. 2581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!isUnpredicatedTerminator(I)) 2591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 2601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // A terminator that isn't a branch can't easily be handled by this 2621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // analysis. 26306c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 2641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 2651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Can't handle indirect branches. 26706c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford SystemZII::Branch Branch(getBranchInfo(I)); 26806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!Branch.Target->isMBB()) 2691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 2701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 271d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford // Punt on compound branches. 272d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford if (Branch.Type != SystemZII::BranchNormal) 273d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return true; 274d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 27506c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (Branch.CCMask == SystemZ::CCMASK_ANY) { 2761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle unconditional branches. 2771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!AllowModify) { 27806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 2791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 2801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the block has any instructions after a JMP, delete them. 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (std::next(I) != MBB.end()) 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::next(I)->eraseFromParent(); 2851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Cond.clear(); 287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FBB = nullptr; 2881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Delete the JMP if it's equivalent to a fall-through. 29006c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (MBB.isLayoutSuccessor(Branch.Target->getMBB())) { 291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TBB = nullptr; 2921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 2931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 2941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 2951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 2961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 2971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // TBB is used to indicate the unconditinal destination. 29806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 2991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 3001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Working from the bottom, handle the first conditional branch. 3031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 3041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: add X86-style branch swap 3051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FBB = TBB; 30606c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford TBB = Branch.Target->getMBB(); 3076824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Cond.push_back(MachineOperand::CreateImm(Branch.CCValid)); 30806c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford Cond.push_back(MachineOperand::CreateImm(Branch.CCMask)); 3091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 3101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Handle subsequent conditional branches. 3136824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert(Cond.size() == 2 && TBB && "Should have seen a conditional branch"); 3141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Only handle the case where all conditional branches branch to the same 3161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // destination. 31706c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (TBB != Branch.Target->getMBB()) 3181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 3191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // If the conditions are the same, we can leave them alone. 3216824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned OldCCValid = Cond[0].getImm(); 3226824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned OldCCMask = Cond[1].getImm(); 3236824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask) 3241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 3251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // FIXME: Try combining conditions like X86 does. Should be easy on Z! 3276824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return false; 3281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 3311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 3341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Most of the code and comments here are boilerplate. 3351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator I = MBB.end(); 3361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 3371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand while (I != MBB.begin()) { 3391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand --I; 3401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (I->isDebugValue()) 3411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand continue; 34206c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!I->isBranch()) 3431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 34406c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford if (!getBranchInfo(I).Target->isMBB()) 3451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand break; 3461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Remove the branch. 3471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I->eraseFromParent(); 3481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand I = MBB.end(); 3491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 3501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 3531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3556824f127f90197b26af93cf5d6c13b7941567e54Richard Sandifordbool SystemZInstrInfo:: 3566824f127f90197b26af93cf5d6c13b7941567e54Richard SandifordReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 3576824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert(Cond.size() == 2 && "Invalid condition"); 3586824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford Cond[1].setImm(Cond[1].getImm() ^ Cond[0].getImm()); 3596824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return false; 3606824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford} 3616824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford 3621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned 3631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 3641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock *FBB, 3651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const SmallVectorImpl<MachineOperand> &Cond, 3661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL) const { 3671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // In this function we output 32-bit branches, which should always 3681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // have enough range. They can be shortened and relaxed by later code 3691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // in the pipeline, if desired. 3701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Shouldn't be a fall through. 3721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 3736824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert((Cond.size() == 2 || Cond.size() == 0) && 3741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand "SystemZ branch conditions have one component!"); 3751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Cond.empty()) { 3771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Unconditional branch? 3781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(!FBB && "Unconditional branch with multiple successors!"); 37944b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB); 3801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 1; 3811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Conditional branch. 3841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Count = 0; 3856824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = Cond[0].getImm(); 3866824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = Cond[1].getImm(); 3876824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::BRC)) 3886824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford .addImm(CCValid).addImm(CCMask).addMBB(TBB); 3891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 3901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 3911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (FBB) { 3921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Two-way Conditional branch. Insert the second branch. 39344b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB); 3941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand ++Count; 3951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 3961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Count; 3971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 3981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 399ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandifordbool SystemZInstrInfo::analyzeCompare(const MachineInstr *MI, 400ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford unsigned &SrcReg, unsigned &SrcReg2, 401ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford int &Mask, int &Value) const { 402ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford assert(MI->isCompare() && "Caller should have checked for a comparison"); 403ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 404ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford if (MI->getNumExplicitOperands() == 2 && 405ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford MI->getOperand(0).isReg() && 406ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford MI->getOperand(1).isImm()) { 407ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford SrcReg = MI->getOperand(0).getReg(); 408ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford SrcReg2 = 0; 409ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford Value = MI->getOperand(1).getImm(); 410ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford Mask = ~0; 411ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return true; 412ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford } 413ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 414ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return false; 415ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford} 416ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 4176c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford// If Reg is a virtual register, return its definition, otherwise return null. 4186c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandifordstatic MachineInstr *getDef(unsigned Reg, 4196c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford const MachineRegisterInfo *MRI) { 420ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford if (TargetRegisterInfo::isPhysicalRegister(Reg)) 421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 422ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return MRI->getUniqueVRegDef(Reg); 423ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford} 424ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 425ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford// Return true if MI is a shift of type Opcode by Imm bits. 426ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandifordstatic bool isShift(MachineInstr *MI, int Opcode, int64_t Imm) { 427ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return (MI->getOpcode() == Opcode && 428ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford !MI->getOperand(2).getReg() && 429ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford MI->getOperand(3).getImm() == Imm); 430ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford} 431ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 4326c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford// If the destination of MI has no uses, delete it as dead. 4336c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandifordstatic void eraseIfDead(MachineInstr *MI, const MachineRegisterInfo *MRI) { 4346c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford if (MRI->use_nodbg_empty(MI->getOperand(0).getReg())) 4356c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford MI->eraseFromParent(); 4366c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford} 4376c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford 438ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford// Compare compares SrcReg against zero. Check whether SrcReg contains 4396c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford// the result of an IPM sequence whose input CC survives until Compare, 4406c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford// and whether Compare is therefore redundant. Delete it and return 4416c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford// true if so. 4426c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandifordstatic bool removeIPMBasedCompare(MachineInstr *Compare, unsigned SrcReg, 4436c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford const MachineRegisterInfo *MRI, 4446c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford const TargetRegisterInfo *TRI) { 445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineInstr *LGFR = nullptr; 4466c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford MachineInstr *RLL = getDef(SrcReg, MRI); 4476a079fef4fad3e6c2e07c9e1d0776e20a0b05b1eRichard Sandiford if (RLL && RLL->getOpcode() == SystemZ::LGFR) { 4486a079fef4fad3e6c2e07c9e1d0776e20a0b05b1eRichard Sandiford LGFR = RLL; 4496a079fef4fad3e6c2e07c9e1d0776e20a0b05b1eRichard Sandiford RLL = getDef(LGFR->getOperand(1).getReg(), MRI); 4506a079fef4fad3e6c2e07c9e1d0776e20a0b05b1eRichard Sandiford } 4516c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford if (!RLL || !isShift(RLL, SystemZ::RLL, 31)) 452ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return false; 453ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 4546c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford MachineInstr *SRL = getDef(RLL->getOperand(1).getReg(), MRI); 455d1a4f579bf45aec933c79292b6b9663581438738Richard Sandiford if (!SRL || !isShift(SRL, SystemZ::SRL, SystemZ::IPM_CC)) 456ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return false; 457ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 4586c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford MachineInstr *IPM = getDef(SRL->getOperand(1).getReg(), MRI); 459ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford if (!IPM || IPM->getOpcode() != SystemZ::IPM) 460ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return false; 461ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 462ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford // Check that there are no assignments to CC between the IPM and Compare, 463ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford if (IPM->getParent() != Compare->getParent()) 464ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return false; 465ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford MachineBasicBlock::iterator MBBI = IPM, MBBE = Compare; 466ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford for (++MBBI; MBBI != MBBE; ++MBBI) { 467ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford MachineInstr *MI = MBBI; 4686c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford if (MI->modifiesRegister(SystemZ::CC, TRI)) 469ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return false; 470ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford } 471ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 472ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford Compare->eraseFromParent(); 4736a079fef4fad3e6c2e07c9e1d0776e20a0b05b1eRichard Sandiford if (LGFR) 4746a079fef4fad3e6c2e07c9e1d0776e20a0b05b1eRichard Sandiford eraseIfDead(LGFR, MRI); 4756c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford eraseIfDead(RLL, MRI); 4766c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford eraseIfDead(SRL, MRI); 4776c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford eraseIfDead(IPM, MRI); 4786c51f89498dd813c8dd16e46069decf2897b31b2Richard Sandiford 479ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return true; 480ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford} 481ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 482ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandifordbool 483ac168b8bc8773a083a10902f64e4ae57a925aee4Richard SandifordSystemZInstrInfo::optimizeCompareInstr(MachineInstr *Compare, 484ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford unsigned SrcReg, unsigned SrcReg2, 485ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford int Mask, int Value, 486ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford const MachineRegisterInfo *MRI) const { 487ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford assert(!SrcReg2 && "Only optimizing constant comparisons so far"); 488ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford bool IsLogical = (Compare->getDesc().TSFlags & SystemZII::IsLogical) != 0; 489ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford if (Value == 0 && 490ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford !IsLogical && 491cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines removeIPMBasedCompare(Compare, SrcReg, MRI, &RI)) 492ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return true; 493ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford return false; 494ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford} 495ac168b8bc8773a083a10902f64e4ae57a925aee4Richard Sandiford 496bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford// If Opcode is a move that has a conditional variant, return that variant, 497bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford// otherwise return 0. 498bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordstatic unsigned getConditionalMove(unsigned Opcode) { 499bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford switch (Opcode) { 500bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford case SystemZ::LR: return SystemZ::LOCR; 501bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford case SystemZ::LGR: return SystemZ::LOCGR; 502bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford default: return 0; 503bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford } 504bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 505bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 506bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo::isPredicable(MachineInstr *MI) const { 507bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned Opcode = MI->getOpcode(); 508cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (STI.hasLoadStoreOnCond() && 509bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford getConditionalMove(Opcode)) 510bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return true; 511bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return false; 512bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 513bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 514bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo:: 515bf99364f819465536a6b230b95735b239e3fc7a5Richard SandifordisProfitableToIfCvt(MachineBasicBlock &MBB, 516bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned NumCycles, unsigned ExtraPredCycles, 517bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford const BranchProbability &Probability) const { 518bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford // For now only convert single instructions. 519bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return NumCycles == 1; 520bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 521bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 522bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo:: 523bf99364f819465536a6b230b95735b239e3fc7a5Richard SandifordisProfitableToIfCvt(MachineBasicBlock &TMBB, 524bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned NumCyclesT, unsigned ExtraPredCyclesT, 525bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford MachineBasicBlock &FMBB, 526bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned NumCyclesF, unsigned ExtraPredCyclesF, 527bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford const BranchProbability &Probability) const { 528bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford // For now avoid converting mutually-exclusive cases. 529bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return false; 530bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 531bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 532bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandifordbool SystemZInstrInfo:: 533bf99364f819465536a6b230b95735b239e3fc7a5Richard SandifordPredicateInstruction(MachineInstr *MI, 534bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford const SmallVectorImpl<MachineOperand> &Pred) const { 5356824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford assert(Pred.size() == 2 && "Invalid condition"); 5366824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCValid = Pred[0].getImm(); 5376824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford unsigned CCMask = Pred[1].getImm(); 538bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford assert(CCMask > 0 && CCMask < 15 && "Invalid predicate"); 539bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford unsigned Opcode = MI->getOpcode(); 540cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (STI.hasLoadStoreOnCond()) { 541bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford if (unsigned CondOpcode = getConditionalMove(Opcode)) { 542bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford MI->setDesc(get(CondOpcode)); 5436824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MachineInstrBuilder(*MI->getParent()->getParent(), MI) 5448f0ad5ae8f2699f6ab13a229941a0b192273cae8Richard Sandiford .addImm(CCValid).addImm(CCMask) 545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines .addReg(SystemZ::CC, RegState::Implicit); 546bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return true; 547bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford } 548bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford } 549bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford return false; 550bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford} 551bf99364f819465536a6b230b95735b239e3fc7a5Richard Sandiford 5521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 5531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 5541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, DebugLoc DL, 5551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, unsigned SrcReg, 5561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand bool KillSrc) const { 5571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Split 128-bit GPR moves into two 64-bit moves. This handles ADDR128 too. 5581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) { 559745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_h64), 560745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc); 561745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_l64), 562745ca1eed7dc0a056b066f16aea750ce6fa8a530Richard Sandiford RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc); 5631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return; 5641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 5651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 56655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (SystemZ::GRX32BitRegClass.contains(DestReg, SrcReg)) { 56755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford emitGRX32Move(MBB, MBBI, DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc); 56855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return; 56955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford } 57055d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 5711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Everything else needs only one instruction. 5721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 57355d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg)) 5741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGR; 5751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg)) 5761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LER; 5771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP64BitRegClass.contains(DestReg, SrcReg)) 5781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LDR; 5791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::FP128BitRegClass.contains(DestReg, SrcReg)) 5801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LXR; 5811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else 5821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Impossible reg-to-reg copy"); 5831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), DestReg) 5851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(KillSrc)); 5861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 5871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 5891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 5901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 5911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned SrcReg, bool isKill, 5921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int FrameIdx, 5931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 5941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 5951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 5961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 5971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 5981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 5991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 6001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 6011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode)) 6021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand .addReg(SrcReg, getKillRegState(isKill)), FrameIdx); 6031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid 6061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 6071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 6081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned DestReg, int FrameIdx, 6091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterClass *RC, 6101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetRegisterInfo *TRI) const { 6111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 6121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Callers may expect a single instruction, so keep 128-bit moves 6141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // together for now and lower them after register allocation. 6151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned LoadOpcode, StoreOpcode; 6161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode); 6171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg), 6181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand FrameIdx); 6191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 6201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 6211ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford// Return true if MI is a simple load or store with a 12-bit displacement 6221ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford// and no index. Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores. 6231ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandifordstatic bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) { 6241ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const MCInstrDesc &MCID = MI->getDesc(); 6251ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return ((MCID.TSFlags & Flag) && 6261ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford isUInt<12>(MI->getOperand(2).getImm()) && 6271ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MI->getOperand(3).getReg() == 0); 6281ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 6291ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 630b3f912b510f8040690864126351b7021980558bbRichard Sandifordnamespace { 63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct LogicOp { 63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LogicOp() : RegSize(0), ImmLSB(0), ImmSize(0) {} 63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize) 63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {} 635b3f912b510f8040690864126351b7021980558bbRichard Sandiford 63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines operator bool() const { return RegSize; } 637b3f912b510f8040690864126351b7021980558bbRichard Sandiford 63836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned RegSize, ImmLSB, ImmSize; 63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end anonymous namespace 641b3f912b510f8040690864126351b7021980558bbRichard Sandiford 642b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic LogicOp interpretAndImmediate(unsigned Opcode) { 643b3f912b510f8040690864126351b7021980558bbRichard Sandiford switch (Opcode) { 644b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NILMux: return LogicOp(32, 0, 16); 645b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NIHMux: return LogicOp(32, 16, 16); 646259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::NILL64: return LogicOp(64, 0, 16); 647259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::NILH64: return LogicOp(64, 16, 16); 648b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NIHL64: return LogicOp(64, 32, 16); 649b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NIHH64: return LogicOp(64, 48, 16); 650b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NIFMux: return LogicOp(32, 0, 32); 651259a6006e89576704e52e7392ef2bfd83f277ce3Richard Sandiford case SystemZ::NILF64: return LogicOp(64, 0, 32); 652b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NIHF64: return LogicOp(64, 32, 32); 653b3f912b510f8040690864126351b7021980558bbRichard Sandiford default: return LogicOp(); 654b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 655b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 656b3f912b510f8040690864126351b7021980558bbRichard Sandiford 657b3f912b510f8040690864126351b7021980558bbRichard Sandiford// Used to return from convertToThreeAddress after replacing two-address 658b3f912b510f8040690864126351b7021980558bbRichard Sandiford// instruction OldMI with three-address instruction NewMI. 659b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic MachineInstr *finishConvertToThreeAddress(MachineInstr *OldMI, 660b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineInstr *NewMI, 661b3f912b510f8040690864126351b7021980558bbRichard Sandiford LiveVariables *LV) { 662b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (LV) { 663b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned NumOps = OldMI->getNumOperands(); 664b3f912b510f8040690864126351b7021980558bbRichard Sandiford for (unsigned I = 1; I < NumOps; ++I) { 665b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineOperand &Op = OldMI->getOperand(I); 666b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Op.isReg() && Op.isKill()) 667b3f912b510f8040690864126351b7021980558bbRichard Sandiford LV->replaceKillInstruction(Op.getReg(), OldMI, NewMI); 668b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 669b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 670b3f912b510f8040690864126351b7021980558bbRichard Sandiford return NewMI; 671b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 672b3f912b510f8040690864126351b7021980558bbRichard Sandiford 6731ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordMachineInstr * 67493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard SandifordSystemZInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, 67593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MachineBasicBlock::iterator &MBBI, 67693c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford LiveVariables *LV) const { 67793c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MachineInstr *MI = MBBI; 67893c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MachineBasicBlock *MBB = MI->getParent(); 679ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); 68093c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford 68193c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford unsigned Opcode = MI->getOpcode(); 68293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford unsigned NumOps = MI->getNumOperands(); 68393c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford 68493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // Try to convert something like SLL into SLLK, if supported. 68593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // We prefer to keep the two-operand form where possible both 68693c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // because it tends to be shorter and because some instructions 68793c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // have memory forms that can be used during spilling. 688cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (STI.hasDistinctOps()) { 689ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MachineOperand &Dest = MI->getOperand(0); 690ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MachineOperand &Src = MI->getOperand(1); 691ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford unsigned DestReg = Dest.getReg(); 692ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford unsigned SrcReg = Src.getReg(); 693ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford // AHIMux is only really a three-operand instruction when both operands 694ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford // are low registers. Try to constrain both operands to be low if 695ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford // possible. 696ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford if (Opcode == SystemZ::AHIMux && 697ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford TargetRegisterInfo::isVirtualRegister(DestReg) && 698ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford TargetRegisterInfo::isVirtualRegister(SrcReg) && 699ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MRI.getRegClass(DestReg)->contains(SystemZ::R1L) && 700ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MRI.getRegClass(SrcReg)->contains(SystemZ::R1L)) { 701ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MRI.constrainRegClass(DestReg, &SystemZ::GR32BitRegClass); 702ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford MRI.constrainRegClass(SrcReg, &SystemZ::GR32BitRegClass); 703ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford } 70493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford int ThreeOperandOpcode = SystemZ::getThreeOperandOpcode(Opcode); 70593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford if (ThreeOperandOpcode >= 0) { 706b3f912b510f8040690864126351b7021980558bbRichard Sandiford MachineInstrBuilder MIB = 707b3f912b510f8040690864126351b7021980558bbRichard Sandiford BuildMI(*MBB, MBBI, MI->getDebugLoc(), get(ThreeOperandOpcode)) 708b3f912b510f8040690864126351b7021980558bbRichard Sandiford .addOperand(Dest); 70993c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // Keep the kill state, but drop the tied flag. 710b3f912b510f8040690864126351b7021980558bbRichard Sandiford MIB.addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg()); 71193c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford // Keep the remaining operands as-is. 71293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford for (unsigned I = 2; I < NumOps; ++I) 71393c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford MIB.addOperand(MI->getOperand(I)); 714b3f912b510f8040690864126351b7021980558bbRichard Sandiford return finishConvertToThreeAddress(MI, MIB, LV); 715b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 716b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 717b3f912b510f8040690864126351b7021980558bbRichard Sandiford 718b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Try to convert an AND into an RISBG-type instruction. 719b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (LogicOp And = interpretAndImmediate(Opcode)) { 720b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford uint64_t Imm = MI->getOperand(2).getImm() << And.ImmLSB; 721b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford // AND IMMEDIATE leaves the other bits of the register unchanged. 722b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford Imm |= allOnes(And.RegSize) & ~(allOnes(And.ImmSize) << And.ImmLSB); 723b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford unsigned Start, End; 724b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford if (isRxSBGMask(Imm, And.RegSize, Start, End)) { 725b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford unsigned NewOpcode; 726b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford if (And.RegSize == 64) 727b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford NewOpcode = SystemZ::RISBG; 728b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford else { 729b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford NewOpcode = SystemZ::RISBMux; 730b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford Start &= 31; 731b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford End &= 31; 73293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford } 733b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford MachineOperand &Dest = MI->getOperand(0); 734b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford MachineOperand &Src = MI->getOperand(1); 735b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford MachineInstrBuilder MIB = 736b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford BuildMI(*MBB, MI, MI->getDebugLoc(), get(NewOpcode)) 737b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford .addOperand(Dest).addReg(0) 738b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford .addReg(Src.getReg(), getKillRegState(Src.isKill()), Src.getSubReg()) 739b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford .addImm(Start).addImm(End + 128).addImm(0); 740b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return finishConvertToThreeAddress(MI, MIB, LV); 74193c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford } 74293c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford } 743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 74493c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford} 74593c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard Sandiford 74693c2125c3979bcb4656daf3c2fb5748fb3973e1aRichard SandifordMachineInstr * 7471ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordSystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 7481ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineInstr *MI, 7491ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const SmallVectorImpl<unsigned> &Ops, 7501ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford int FrameIndex) const { 7511ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const MachineFrameInfo *MFI = MF.getFrameInfo(); 7521ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned Size = MFI->getObjectSize(FrameIndex); 753f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford unsigned Opcode = MI->getOpcode(); 754f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford 755f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { 756f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford if ((Opcode == SystemZ::LA || Opcode == SystemZ::LAY) && 757f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford isInt<8>(MI->getOperand(2).getImm()) && 758f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford !MI->getOperand(3).getReg()) { 759f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford // LA(Y) %reg, CONST(%reg) -> AGSI %mem, CONST 760f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::AGSI)) 761f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford .addFrameIndex(FrameIndex).addImm(0) 762f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford .addImm(MI->getOperand(2).getImm()); 763f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford } 764dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 765f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford } 7661ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 767f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford // All other cases require a single operand. 7681ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (Ops.size() != 1) 769dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 7701ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 7711ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford unsigned OpNum = Ops[0]; 772985148ea873db018dbd2b53f066f5817a9b11aadNAKAMURA Takumi assert(Size == MF.getRegInfo() 773985148ea873db018dbd2b53f066f5817a9b11aadNAKAMURA Takumi .getRegClass(MI->getOperand(OpNum).getReg())->getSize() && 77424dd7dbe7f2a3338a20314b3863f6b738cc1c298Benjamin Kramer "Invalid size combination"); 7751ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 776f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && 777f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford OpNum == 0 && 778f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford isInt<8>(MI->getOperand(2).getImm())) { 779f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford // A(G)HI %reg, CONST -> A(G)SI %mem, CONST 780f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI); 781f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(Opcode)) 782f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford .addFrameIndex(FrameIndex).addImm(0) 783f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford .addImm(MI->getOperand(2).getImm()); 784f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford } 785f8f993b675568ea6380ad141371c67679a1b9ac4Richard Sandiford 7866cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) { 7876cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford bool Op0IsGPR = (Opcode == SystemZ::LGDR); 7886cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford bool Op1IsGPR = (Opcode == SystemZ::LDGR); 7896cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // If we're spilling the destination of an LDGR or LGDR, store the 7906cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // source register instead. 7916cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (OpNum == 0) { 7926cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD; 7936cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(StoreOpcode)) 7946cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addOperand(MI->getOperand(1)).addFrameIndex(FrameIndex) 7956cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addImm(0).addReg(0); 7966cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 7976cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // If we're spilling the source of an LDGR or LGDR, load the 7986cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford // destination register instead. 7996cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford if (OpNum == 1) { 8006cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD; 8016cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford unsigned Dest = MI->getOperand(0).getReg(); 8026cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(LoadOpcode), Dest) 8036cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford .addFrameIndex(FrameIndex).addImm(0).addReg(0); 8046cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 8056cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford } 8066cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford 8071ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Look for cases where the source of a simple store or the destination 8081ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // of a simple load is being spilled. Try to use MVC instead. 8091ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // 8101ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Although MVC is in practice a fast choice in these cases, it is still 8111ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // logically a bytewise copy. This means that we cannot use it if the 8120548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // load or store is volatile. We also wouldn't be able to use MVC if 8130548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // the two memories partially overlap, but that case cannot occur here, 8140548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // because we know that one of the memories is a full frame index. 8150548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // 8160548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // For performance reasons, we also want to avoid using MVC if the addresses 8170548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // might be equal. We don't worry about that case here, because spill slot 8180548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // coloring happens later, and because we have special code to remove 8190548a5487ab8648c7c017f87c507ea1bc38bbb1fRichard Sandiford // MVCs that turn out to be redundant. 8201ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (OpNum == 0 && MI->hasOneMemOperand()) { 8211ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineMemOperand *MMO = *MI->memoperands_begin(); 8221ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford if (MMO->getSize() == Size && !MMO->isVolatile()) { 8231ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Handle conversion of loads. 824cf1b5bd60ab7cf907bef20c3997ffb249b4fe90aRichard Sandiford if (isSimpleBD12Move(MI, SystemZII::SimpleBDXLoad)) { 8251ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) 826e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addFrameIndex(FrameIndex).addImm(0).addImm(Size) 8271ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) 828e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addMemOperand(MMO); 8291ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 8301ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford // Handle conversion of stores. 831cf1b5bd60ab7cf907bef20c3997ffb249b4fe90aRichard Sandiford if (isSimpleBD12Move(MI, SystemZII::SimpleBDXStore)) { 8321ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford return BuildMI(MF, MI->getDebugLoc(), get(SystemZ::MVC)) 8331ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford .addOperand(MI->getOperand(1)).addImm(MI->getOperand(2).getImm()) 834e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addImm(Size).addFrameIndex(FrameIndex).addImm(0) 835e684b96e3c6513f88137afee7c344a4d2d9f0694Richard Sandiford .addMemOperand(MMO); 8361ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 8371ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 8381ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford } 8391ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 840fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford // If the spilled operand is the final one, try to change <INSN>R 841fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford // into <INSN>. 8426cf3cfa0ab1da0c52730fec103bbc69eb0370081Richard Sandiford int MemOpcode = SystemZ::getMemOpcode(Opcode); 843fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (MemOpcode >= 0) { 844fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford unsigned NumOps = MI->getNumExplicitOperands(); 845fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (OpNum == NumOps - 1) { 846fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford const MCInstrDesc &MemDesc = get(MemOpcode); 847fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford uint64_t AccessBytes = SystemZII::getAccessSize(MemDesc.TSFlags); 848fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford assert(AccessBytes != 0 && "Size of access should be known"); 849fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford assert(AccessBytes <= Size && "Access outside the frame index"); 850fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford uint64_t Offset = Size - AccessBytes; 851fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MachineInstrBuilder MIB = BuildMI(MF, MI->getDebugLoc(), get(MemOpcode)); 852fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford for (unsigned I = 0; I < OpNum; ++I) 853fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addOperand(MI->getOperand(I)); 854fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addFrameIndex(FrameIndex).addImm(Offset); 855fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford if (MemDesc.TSFlags & SystemZII::HasIndex) 856fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford MIB.addReg(0); 857fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford return MIB; 858fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford } 859fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford } 860fa487e83a83c260d6a50f3df00a0eb012553a912Richard Sandiford 861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 8621ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 8631ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 8641ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordMachineInstr * 8651ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard SandifordSystemZInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, 8661ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford const SmallVectorImpl<unsigned> &Ops, 8671ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford MachineInstr* LoadMI) const { 868dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 8691ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford} 8701ce4894a3f1ce6e63c1b109c24235d81dea2908fRichard Sandiford 8711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool 8721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandSystemZInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 8731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 8741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::L128: 8751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LG); 8761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 8771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ST128: 8791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STG); 8801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 8811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::LX: 8831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::LD); 8841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 8851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 8861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::STX: 8871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitMove(MI, SystemZ::STD); 8881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 8891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 890ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford case SystemZ::LBMux: 891ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford expandRXYPseudo(MI, SystemZ::LB, SystemZ::LBH); 892ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford return true; 893ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford 894ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford case SystemZ::LHMux: 895ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford expandRXYPseudo(MI, SystemZ::LH, SystemZ::LHH); 896ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford return true; 897ced450f0e6266eb8c2624fc1895cbc2749d715c3Richard Sandiford 89879e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford case SystemZ::LLCRMux: 89979e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford expandZExtPseudo(MI, SystemZ::LLCR, 8); 90079e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford return true; 90179e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford 90279e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford case SystemZ::LLHRMux: 90379e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford expandZExtPseudo(MI, SystemZ::LLHR, 16); 90479e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford return true; 90579e2ed4d838354d8aeaadbbfe0a3779d63e72b25Richard Sandiford 9069a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford case SystemZ::LLCMux: 9079a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford expandRXYPseudo(MI, SystemZ::LLC, SystemZ::LLCH); 9089a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford return true; 9099a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford 9109a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford case SystemZ::LLHMux: 9119a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford expandRXYPseudo(MI, SystemZ::LLH, SystemZ::LLHH); 9129a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford return true; 9139a05f040e70494ab0092faa9ed10dc70ff1f4e66Richard Sandiford 91455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case SystemZ::LMux: 91555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford expandRXYPseudo(MI, SystemZ::L, SystemZ::LFH); 91655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return true; 91755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 9189813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford case SystemZ::STCMux: 9199813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford expandRXYPseudo(MI, SystemZ::STC, SystemZ::STCH); 9209813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford return true; 9219813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford 9229813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford case SystemZ::STHMux: 9239813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford expandRXYPseudo(MI, SystemZ::STH, SystemZ::STHH); 9249813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford return true; 9259813dbf396e63f6d4fd99fe0f6651e831cb7414bRichard Sandiford 92655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford case SystemZ::STMux: 92755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford expandRXYPseudo(MI, SystemZ::ST, SystemZ::STFH); 92855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford return true; 92955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford 9304c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford case SystemZ::LHIMux: 9314c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford expandRIPseudo(MI, SystemZ::LHI, SystemZ::IIHF, true); 9324c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford return true; 9334c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford 9344c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford case SystemZ::IIFMux: 9354c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford expandRIPseudo(MI, SystemZ::IILF, SystemZ::IIHF, false); 9364c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford return true; 9374c8feae136bbb54ba09d8f8dc7e61714270f7cd5Richard Sandiford 938645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford case SystemZ::IILMux: 939645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford expandRIPseudo(MI, SystemZ::IILL, SystemZ::IIHL, false); 940645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford return true; 941645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford 942645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford case SystemZ::IIHMux: 943645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford expandRIPseudo(MI, SystemZ::IILH, SystemZ::IIHH, false); 944645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford return true; 945645d250b84fe0d097e7813b980ae58daeca2c2e6Richard Sandiford 946b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NIFMux: 947b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford expandRIPseudo(MI, SystemZ::NILF, SystemZ::NIHF, false); 948b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return true; 949b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford 950b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NILMux: 951b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford expandRIPseudo(MI, SystemZ::NILL, SystemZ::NIHL, false); 952b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return true; 953b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford 954b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::NIHMux: 955b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford expandRIPseudo(MI, SystemZ::NILH, SystemZ::NIHH, false); 956b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return true; 957b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford 9581c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::OIFMux: 9591c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford expandRIPseudo(MI, SystemZ::OILF, SystemZ::OIHF, false); 9601c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return true; 9611c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford 9621c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::OILMux: 9631c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford expandRIPseudo(MI, SystemZ::OILL, SystemZ::OIHL, false); 9641c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return true; 9651c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford 9661c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford case SystemZ::OIHMux: 9671c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford expandRIPseudo(MI, SystemZ::OILH, SystemZ::OIHH, false); 9681c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford return true; 9691c831f7f1f7e869516f5a70c1e6dd8896bef76f5Richard Sandiford 9701ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford case SystemZ::XIFMux: 9711ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford expandRIPseudo(MI, SystemZ::XILF, SystemZ::XIHF, false); 9721ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford return true; 9731ff62e182e648c72e6fce4f9d7911f2edfd914d2Richard Sandiford 974bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford case SystemZ::TMLMux: 975bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford expandRIPseudo(MI, SystemZ::TMLL, SystemZ::TMHL, false); 976bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford return true; 977bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford 978bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford case SystemZ::TMHMux: 979bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford expandRIPseudo(MI, SystemZ::TMLH, SystemZ::TMHH, false); 980bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford return true; 981bd1958d8e99ebd5a885f848b2f688c399cfc9886Richard Sandiford 982ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford case SystemZ::AHIMux: 983ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford expandRIPseudo(MI, SystemZ::AHI, SystemZ::AIH, false); 984ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford return true; 985ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford 986ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford case SystemZ::AHIMuxK: 987ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford expandRIEPseudo(MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH); 988ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford return true; 989ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford 990ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford case SystemZ::AFIMux: 991ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford expandRIPseudo(MI, SystemZ::AFI, SystemZ::AIH, false); 992ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford return true; 993ad366a3f67679a56d25464dc2bcad3a0a6a51780Richard Sandiford 994185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford case SystemZ::CFIMux: 995185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford expandRIPseudo(MI, SystemZ::CFI, SystemZ::CIH, false); 996185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford return true; 997185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford 998185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford case SystemZ::CLFIMux: 999185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford expandRIPseudo(MI, SystemZ::CLFI, SystemZ::CLIH, false); 1000185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford return true; 1001185ef05ad6fdcaad1e831020b1f88d0046dd15d6Richard Sandiford 1002e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford case SystemZ::CMux: 1003e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford expandRXYPseudo(MI, SystemZ::C, SystemZ::CHF); 1004e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford return true; 1005e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford 1006e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford case SystemZ::CLMux: 1007e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford expandRXYPseudo(MI, SystemZ::CL, SystemZ::CLHF); 1008e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford return true; 1009e22c56d6d81b84d6f4ba24c2f5b0b203e7ddffe9Richard Sandiford 1010b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford case SystemZ::RISBMux: { 1011b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford bool DestIsHigh = isHighReg(MI->getOperand(0).getReg()); 1012b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford bool SrcIsHigh = isHighReg(MI->getOperand(2).getReg()); 1013b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford if (SrcIsHigh == DestIsHigh) 1014b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford MI->setDesc(get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL)); 1015b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford else { 1016b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford MI->setDesc(get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH)); 1017b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford MI->getOperand(5).setImm(MI->getOperand(5).getImm() ^ 32); 1018b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford } 1019b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford return true; 1020b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford } 1021b9dcca8265e9da01119c47e65f114c3adc972ba6Richard Sandiford 10221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::ADJDYNALLOC: 10231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand splitAdjDynAlloc(MI); 10241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 10251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 10271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 10281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 10301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 103144b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiforduint64_t SystemZInstrInfo::getInstSizeInBytes(const MachineInstr *MI) const { 103244b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford if (MI->getOpcode() == TargetOpcode::INLINEASM) { 103344b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const MachineFunction *MF = MI->getParent()->getParent(); 103444b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford const char *AsmStr = MI->getOperand(0).getSymbolName(); 103544b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); 103644b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford } 103744b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford return MI->getDesc().getSize(); 103844b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford} 103944b486ed78c60b50aa14d4eed92ee828d4d44293Richard Sandiford 104006c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZII::Branch 104106c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard SandifordSystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { 10421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (MI->getOpcode()) { 10431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BR: 10441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::J: 10451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::JG: 1046d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, 10476824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford SystemZ::CCMASK_ANY, &MI->getOperand(0)); 10481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRC: 10501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZ::BRCL: 1051d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZII::Branch(SystemZII::BranchNormal, 10526824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(0).getImm(), 10536824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(1).getImm(), &MI->getOperand(2)); 1054d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 105593795574785de252703591e7fcc8f052c762f25eRichard Sandiford case SystemZ::BRCT: 105693795574785de252703591e7fcc8f052c762f25eRichard Sandiford return SystemZII::Branch(SystemZII::BranchCT, SystemZ::CCMASK_ICMP, 105793795574785de252703591e7fcc8f052c762f25eRichard Sandiford SystemZ::CCMASK_CMP_NE, &MI->getOperand(2)); 105893795574785de252703591e7fcc8f052c762f25eRichard Sandiford 105993795574785de252703591e7fcc8f052c762f25eRichard Sandiford case SystemZ::BRCTG: 106093795574785de252703591e7fcc8f052c762f25eRichard Sandiford return SystemZII::Branch(SystemZII::BranchCTG, SystemZ::CCMASK_ICMP, 106193795574785de252703591e7fcc8f052c762f25eRichard Sandiford SystemZ::CCMASK_CMP_NE, &MI->getOperand(2)); 106293795574785de252703591e7fcc8f052c762f25eRichard Sandiford 10632d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CIJ: 1064d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CRJ: 10656824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return SystemZII::Branch(SystemZII::BranchC, SystemZ::CCMASK_ICMP, 10666824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(2).getImm(), &MI->getOperand(3)); 1067d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 1068e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLIJ: 1069e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLRJ: 1070e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford return SystemZII::Branch(SystemZII::BranchCL, SystemZ::CCMASK_ICMP, 1071e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford MI->getOperand(2).getImm(), &MI->getOperand(3)); 1072e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford 10732d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGIJ: 1074d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGRJ: 10756824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford return SystemZII::Branch(SystemZII::BranchCG, SystemZ::CCMASK_ICMP, 10766824f127f90197b26af93cf5d6c13b7941567e54Richard Sandiford MI->getOperand(2).getImm(), &MI->getOperand(3)); 10771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1078e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLGIJ: 1079e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLGRJ: 1080e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford return SystemZII::Branch(SystemZII::BranchCLG, SystemZ::CCMASK_ICMP, 1081e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford MI->getOperand(2).getImm(), &MI->getOperand(3)); 1082e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford 10831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand default: 108406c3c9a9e1cc313d911e939e3e994feaf43cc3a7Richard Sandiford llvm_unreachable("Unrecognized branch opcode"); 10851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 10861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 10871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 10881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC, 10891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &LoadOpcode, 10901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned &StoreOpcode) const { 10911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) { 10921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L; 1093e39a156b921f47a374f091b43205555ee90cd555Richard Sandiford StoreOpcode = SystemZ::ST; 109455d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford } else if (RC == &SystemZ::GRH32BitRegClass) { 109555d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford LoadOpcode = SystemZ::LFH; 109655d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford StoreOpcode = SystemZ::STFH; 109755d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford } else if (RC == &SystemZ::GRX32BitRegClass) { 109855d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford LoadOpcode = SystemZ::LMux; 109955d7d83b6c9e55fa73d667660c8e90f92999385bRichard Sandiford StoreOpcode = SystemZ::STMux; 11001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR64BitRegClass || 11011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR64BitRegClass) { 11021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LG; 11031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STG; 11041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::GR128BitRegClass || 11051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RC == &SystemZ::ADDR128BitRegClass) { 11061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::L128; 11071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::ST128; 11081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP32BitRegClass) { 11091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LE; 11101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STE; 11111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP64BitRegClass) { 11121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LD; 11131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STD; 11141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else if (RC == &SystemZ::FP128BitRegClass) { 11151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand LoadOpcode = SystemZ::LX; 11161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand StoreOpcode = SystemZ::STX; 11171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else 11181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Unsupported regclass to load or store"); 11191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 11201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandunsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, 11221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset) const { 11231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCInstrDesc &MCID = get(Opcode); 11241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset); 11251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isUInt<12>(Offset) && isUInt<12>(Offset2)) { 11261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for unsigned 12-bit displacements. 11271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode); 11281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp12Opcode >= 0) 11291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp12Opcode; 11301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // All address-related instructions can use unsigned 12-bit 11321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // displacements. 11331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 11341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 11351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<20>(Offset) && isInt<20>(Offset2)) { 11361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Get the instruction to use for signed 20-bit displacements. 11371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode); 11381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Disp20Opcode >= 0) 11391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Disp20Opcode; 11401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Check whether Opcode allows signed 20-bit displacements. 11421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (MCID.TSFlags & SystemZII::Has20BitOffset) 11431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return Opcode; 11441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 11451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return 0; 11461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 11471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 11489b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandifordunsigned SystemZInstrInfo::getLoadAndTest(unsigned Opcode) const { 11499b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford switch (Opcode) { 11509b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::L: return SystemZ::LT; 11519b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LY: return SystemZ::LT; 11529b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LG: return SystemZ::LTG; 11539b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LGF: return SystemZ::LTGF; 11549b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LR: return SystemZ::LTR; 11559b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LGFR: return SystemZ::LTGFR; 11569b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford case SystemZ::LGR: return SystemZ::LTGR; 115729e873ddb6b21c4a934926a0cf7809e98ac1fff0Richard Sandiford case SystemZ::LER: return SystemZ::LTEBR; 115829e873ddb6b21c4a934926a0cf7809e98ac1fff0Richard Sandiford case SystemZ::LDR: return SystemZ::LTDBR; 115929e873ddb6b21c4a934926a0cf7809e98ac1fff0Richard Sandiford case SystemZ::LXR: return SystemZ::LTXBR; 11609b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford default: return 0; 11619b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford } 11629b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford} 11639b05c709c65ba05645853ca49bc2a1ea8b554f37Richard Sandiford 1164b3f912b510f8040690864126351b7021980558bbRichard Sandiford// Return true if Mask matches the regexp 0*1+0*, given that zero masks 1165b3f912b510f8040690864126351b7021980558bbRichard Sandiford// have already been filtered out. Store the first set bit in LSB and 1166b3f912b510f8040690864126351b7021980558bbRichard Sandiford// the number of set bits in Length if so. 1167b3f912b510f8040690864126351b7021980558bbRichard Sandifordstatic bool isStringOfOnes(uint64_t Mask, unsigned &LSB, unsigned &Length) { 1168b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned First = findFirstSet(Mask); 1169b3f912b510f8040690864126351b7021980558bbRichard Sandiford uint64_t Top = (Mask >> First) + 1; 1170b3f912b510f8040690864126351b7021980558bbRichard Sandiford if ((Top & -Top) == Top) { 1171b3f912b510f8040690864126351b7021980558bbRichard Sandiford LSB = First; 1172b3f912b510f8040690864126351b7021980558bbRichard Sandiford Length = findFirstSet(Top); 1173b3f912b510f8040690864126351b7021980558bbRichard Sandiford return true; 1174b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 1175b3f912b510f8040690864126351b7021980558bbRichard Sandiford return false; 1176b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 1177b3f912b510f8040690864126351b7021980558bbRichard Sandiford 1178b3f912b510f8040690864126351b7021980558bbRichard Sandifordbool SystemZInstrInfo::isRxSBGMask(uint64_t Mask, unsigned BitSize, 1179b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned &Start, unsigned &End) const { 1180b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Reject trivial all-zero masks. 1181b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (Mask == 0) 1182b3f912b510f8040690864126351b7021980558bbRichard Sandiford return false; 1183b3f912b510f8040690864126351b7021980558bbRichard Sandiford 1184b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Handle the 1+0+ or 0+1+0* cases. Start then specifies the index of 1185b3f912b510f8040690864126351b7021980558bbRichard Sandiford // the msb and End specifies the index of the lsb. 1186b3f912b510f8040690864126351b7021980558bbRichard Sandiford unsigned LSB, Length; 1187b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (isStringOfOnes(Mask, LSB, Length)) { 1188b3f912b510f8040690864126351b7021980558bbRichard Sandiford Start = 63 - (LSB + Length - 1); 1189b3f912b510f8040690864126351b7021980558bbRichard Sandiford End = 63 - LSB; 1190b3f912b510f8040690864126351b7021980558bbRichard Sandiford return true; 1191b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 1192b3f912b510f8040690864126351b7021980558bbRichard Sandiford 1193b3f912b510f8040690864126351b7021980558bbRichard Sandiford // Handle the wrap-around 1+0+1+ cases. Start then specifies the msb 1194b3f912b510f8040690864126351b7021980558bbRichard Sandiford // of the low 1s and End specifies the lsb of the high 1s. 1195b3f912b510f8040690864126351b7021980558bbRichard Sandiford if (isStringOfOnes(Mask ^ allOnes(BitSize), LSB, Length)) { 1196b3f912b510f8040690864126351b7021980558bbRichard Sandiford assert(LSB > 0 && "Bottom bit must be set"); 1197b3f912b510f8040690864126351b7021980558bbRichard Sandiford assert(LSB + Length < BitSize && "Top bit must be set"); 1198b3f912b510f8040690864126351b7021980558bbRichard Sandiford Start = 63 - (LSB - 1); 1199b3f912b510f8040690864126351b7021980558bbRichard Sandiford End = 63 - (LSB + Length); 1200b3f912b510f8040690864126351b7021980558bbRichard Sandiford return true; 1201b3f912b510f8040690864126351b7021980558bbRichard Sandiford } 1202b3f912b510f8040690864126351b7021980558bbRichard Sandiford 1203b3f912b510f8040690864126351b7021980558bbRichard Sandiford return false; 1204b3f912b510f8040690864126351b7021980558bbRichard Sandiford} 1205b3f912b510f8040690864126351b7021980558bbRichard Sandiford 12062d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandifordunsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode, 12072d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford const MachineInstr *MI) const { 1208d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford switch (Opcode) { 1209d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CR: 1210d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CRJ; 1211d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford case SystemZ::CGR: 1212d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return SystemZ::CGRJ; 12132d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CHI: 12142d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CIJ : 0; 12152d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford case SystemZ::CGHI: 12162d664abbfca8b9fa3d99e8a2f74bd52faf007f12Richard Sandiford return MI && isInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CGIJ : 0; 1217e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLR: 1218e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford return SystemZ::CLRJ; 1219e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLGR: 1220e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford return SystemZ::CLGRJ; 1221e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLFI: 1222e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford return MI && isUInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CLIJ : 0; 1223e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford case SystemZ::CLGFI: 1224e2d6f91d63a2e8cf77b07794cda7d9ef72504769Richard Sandiford return MI && isUInt<8>(MI->getOperand(1).getImm()) ? SystemZ::CLGIJ : 0; 1225d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford default: 1226d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford return 0; 1227d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford } 1228d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford} 1229d50bcb2162a529534da42748ab4a418bfc9aaf06Richard Sandiford 12301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, 12311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineBasicBlock::iterator MBBI, 12321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Reg, uint64_t Value) const { 12331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 12341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned Opcode; 12351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (isInt<16>(Value)) 12361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGHI; 12371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLL(Value)) 12381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILL; 12391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand else if (SystemZ::isImmLH(Value)) { 12401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LLILH; 12411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Value >>= 16; 12421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 12431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand assert(isInt<32>(Value) && "Huge values not handled yet"); 12441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Opcode = SystemZ::LGFI; 12451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 12461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value); 12471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1248