XCoreInstrInfo.cpp revision 6c6f28ffe42d06655f5977bd0d01214e32de93a5
1b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===- XCoreInstrInfo.cpp - XCore Instruction Information -------*- C++ -*-===// 2b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 3b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// The LLVM Compiler Infrastructure 4b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 5b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file is distributed under the University of Illinois Open Source 6b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// License. See LICENSE.TXT for details. 7b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 8b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 9b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 10b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file contains the XCore implementation of the TargetInstrInfo class. 11b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 12b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 13b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 14b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreMachineFunctionInfo.h" 15b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreInstrInfo.h" 16b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCore.h" 1766f20c8e82685a699447144dbd659c4e465eccc8Chris Lattner#include "llvm/MC/MCContext.h" 18b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineInstrBuilder.h" 19b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineFrameInfo.h" 2066f20c8e82685a699447144dbd659c4e465eccc8Chris Lattner#include "llvm/ADT/STLExtras.h" 21b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Support/Debug.h" 22c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 233e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 24b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 254db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_CTOR 2622fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng#include "XCoreGenInstrInfo.inc" 2722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng 28b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornenamespace llvm { 29b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornenamespace XCore { 30b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 31b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // XCore Condition Codes 32b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne enum CondCode { 33b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne COND_TRUE, 34b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne COND_FALSE, 35b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne COND_INVALID 36b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne }; 37b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 38b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 39b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 40b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneusing namespace llvm; 41b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 42a9ad04191cb56c42944b17980b8b2bb2afe11ab2Dan GohmanXCoreInstrInfo::XCoreInstrInfo() 434db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), 44b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne RI(*this) { 45b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 46b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 47b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic bool isZeroImm(const MachineOperand &op) { 48b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return op.isImm() && op.getImm() == 0; 49b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 50b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 51b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// isLoadFromStackSlot - If the specified machine instruction is a direct 52b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// load from a stack slot, return the virtual or physical register number of 53b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// the destination along with the FrameIndex of the loaded stack slot. If 54b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// not, return 0. This predicate must return 0 if the instruction has 55b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// any side effects other than loading from the stack slot. 56b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned 57cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan GohmanXCoreInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const{ 58b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne int Opcode = MI->getOpcode(); 5929cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne if (Opcode == XCore::LDWFI) 60b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne { 61b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if ((MI->getOperand(1).isFI()) && // is a stack slot 62b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne (MI->getOperand(2).isImm()) && // the imm is zero 63b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne (isZeroImm(MI->getOperand(2)))) 64b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne { 65b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne FrameIndex = MI->getOperand(1).getIndex(); 66b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return MI->getOperand(0).getReg(); 67b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 68b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 69b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return 0; 70b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 71b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 72b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne /// isStoreToStackSlot - If the specified machine instruction is a direct 73b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne /// store to a stack slot, return the virtual or physical register number of 74b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne /// the source reg along with the FrameIndex of the loaded stack slot. If 75b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne /// not, return 0. This predicate must return 0 if the instruction has 76b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne /// any side effects other than storing to the stack slot. 77b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned 78cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan GohmanXCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 79cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan Gohman int &FrameIndex) const { 80b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne int Opcode = MI->getOpcode(); 8129cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne if (Opcode == XCore::STWFI) 82b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne { 83b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if ((MI->getOperand(1).isFI()) && // is a stack slot 84b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne (MI->getOperand(2).isImm()) && // the imm is zero 8529cab5f0ee477f86d305ed080d61c17ff64b602fRichard Osborne (isZeroImm(MI->getOperand(2)))) 86b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne { 87b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne FrameIndex = MI->getOperand(1).getIndex(); 88b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return MI->getOperand(0).getReg(); 89b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 90b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 91b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return 0; 92b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 93b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 94b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 95b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// Branch Analysis 96b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 97b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 98b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsBRU(unsigned BrOpc) { 99b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return BrOpc == XCore::BRFU_u6 100b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRFU_lu6 101b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRBU_u6 102b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRBU_lu6; 103b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 104b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 105b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsBRT(unsigned BrOpc) { 106b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return BrOpc == XCore::BRFT_ru6 107b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRFT_lru6 108b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRBT_ru6 109b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRBT_lru6; 110b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 111b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 112b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsBRF(unsigned BrOpc) { 113b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return BrOpc == XCore::BRFF_ru6 114b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRFF_lru6 115b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRBF_ru6 116b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne || BrOpc == XCore::BRBF_lru6; 117b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 118b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 119b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline bool IsCondBranch(unsigned BrOpc) { 120b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return IsBRF(BrOpc) || IsBRT(BrOpc); 121b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 122b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 12378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osbornestatic inline bool IsBR_JT(unsigned BrOpc) { 12478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne return BrOpc == XCore::BR_JT 12578700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne || BrOpc == XCore::BR_JT32; 12678700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne} 12778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne 128b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// GetCondFromBranchOpc - Return the XCore CC that matches 129b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// the correspondent Branch instruction opcode. 130b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) 131b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{ 132b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (IsBRT(BrOpc)) { 133b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return XCore::COND_TRUE; 134b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } else if (IsBRF(BrOpc)) { 135b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return XCore::COND_FALSE; 136b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } else { 137b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return XCore::COND_INVALID; 138b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 139b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 140b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 141b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// GetCondBranchFromCond - Return the Branch instruction 142b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// opcode that matches the cc. 143b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline unsigned GetCondBranchFromCond(XCore::CondCode CC) 144b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{ 145b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne switch (CC) { 146c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Illegal condition code!"); 147b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case XCore::COND_TRUE : return XCore::BRFT_lru6; 148b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case XCore::COND_FALSE : return XCore::BRFF_lru6; 149b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 150b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 151b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 152b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// GetOppositeBranchCondition - Return the inverse of the specified 153b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// condition, e.g. turning COND_E to COND_NE. 154b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC) 155b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{ 156b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne switch (CC) { 157c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Illegal condition code!"); 158b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case XCore::COND_TRUE : return XCore::COND_FALSE; 159b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case XCore::COND_FALSE : return XCore::COND_TRUE; 160b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 161b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 162b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 163b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning 164b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// true if it cannot be understood (e.g. it's a switch dispatch or isn't 165b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// implemented for a target). Upon success, this returns false and returns 166b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// with the following information in various cases: 167b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 168b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 1. If this block ends with no branches (it just falls through to its succ) 169b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// just return false, leaving TBB/FBB null. 170b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 2. If this block ends with only an unconditional branch, it sets TBB to be 171b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// the destination block. 172b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 3. If this block ends with an conditional branch and it falls through to 173b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// an successor block, it sets TBB to be the branch destination block and a 174b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// list of operands that evaluate the condition. These 175b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// operands can be passed to other TargetInstrInfo methods to create new 176b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// branches. 177b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 4. If this block ends with an conditional branch and an unconditional 178b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// block, it returns the 'true' destination in TBB, the 'false' destination 179b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// in FBB, and a list of operands that evaluate the condition. These 180b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// operands can be passed to other TargetInstrInfo methods to create new 181b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// branches. 182b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 183b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// Note that RemoveBranch and InsertBranch must be implemented to support 184b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// cases where this method returns success. 185b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 186b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornebool 187b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 188dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng MachineBasicBlock *&FBB, 189dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng SmallVectorImpl<MachineOperand> &Cond, 190dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng bool AllowModify) const { 191b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // If the block has no terminators, it just falls into the block after it. 192b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne MachineBasicBlock::iterator I = MBB.end(); 19393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (I == MBB.begin()) 19493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen return false; 19593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen --I; 19693d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen while (I->isDebugValue()) { 19793d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (I == MBB.begin()) 19893d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen return false; 19993d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen --I; 20093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen } 20193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (!isUnpredicatedTerminator(I)) 202b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 203b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 204b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Get the last instruction in the block. 205b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne MachineInstr *LastInst = I; 206b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 207b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // If there is only one terminator instruction, process it. 208b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 209b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (IsBRU(LastInst->getOpcode())) { 210b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne TBB = LastInst->getOperand(0).getMBB(); 211b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 212b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 213b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 214b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne XCore::CondCode BranchCode = GetCondFromBranchOpc(LastInst->getOpcode()); 215b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (BranchCode == XCore::COND_INVALID) 216b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; // Can't handle indirect branch. 217b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 218b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Conditional branch 219b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Block ends with fall-through condbranch. 220b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 221b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne TBB = LastInst->getOperand(1).getMBB(); 222b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Cond.push_back(MachineOperand::CreateImm(BranchCode)); 223b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Cond.push_back(LastInst->getOperand(0)); 224b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 225b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 226b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 227b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Get the instruction before it if it's a terminator. 228b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne MachineInstr *SecondLastInst = I; 229b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 230b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // If there are three terminators, we don't know what sort of block this is. 231b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (SecondLastInst && I != MBB.begin() && 232b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne isUnpredicatedTerminator(--I)) 233b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 234b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 235b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne unsigned SecondLastOpc = SecondLastInst->getOpcode(); 236b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne XCore::CondCode BranchCode = GetCondFromBranchOpc(SecondLastOpc); 237b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 238b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // If the block ends with conditional branch followed by unconditional, 239b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // handle it. 240b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (BranchCode != XCore::COND_INVALID 241b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne && IsBRU(LastInst->getOpcode())) { 242b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 243b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne TBB = SecondLastInst->getOperand(1).getMBB(); 244b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Cond.push_back(MachineOperand::CreateImm(BranchCode)); 245b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Cond.push_back(SecondLastInst->getOperand(0)); 246b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 247b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne FBB = LastInst->getOperand(0).getMBB(); 248b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 249b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 250b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 251b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // If the block ends with two unconditional branches, handle it. The second 252b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // one is not executed, so remove it. 253b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (IsBRU(SecondLastInst->getOpcode()) && 254b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne IsBRU(LastInst->getOpcode())) { 255b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne TBB = SecondLastInst->getOperand(0).getMBB(); 256b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne I = LastInst; 257dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng if (AllowModify) 258dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng I->eraseFromParent(); 259b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 260b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 261b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 26278700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne // Likewise if it ends with a branch table followed by an unconditional branch. 26378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) { 26478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne I = LastInst; 26578700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne if (AllowModify) 26678700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne I->eraseFromParent(); 26778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne return true; 26878700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne } 26978700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne 270b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Otherwise, can't handle this. 271b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return true; 272b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 273b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 274b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned 275b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 276b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne MachineBasicBlock *FBB, 2773bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings const SmallVectorImpl<MachineOperand> &Cond, 2783bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings DebugLoc DL)const{ 279b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Shouldn't be a fall through. 280b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 281b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne assert((Cond.size() == 2 || Cond.size() == 0) && 282b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne "Unexpected number of components!"); 283b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 284b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (FBB == 0) { // One way branch. 285b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (Cond.empty()) { 286b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Unconditional branch 2873bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB); 288b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } else { 289b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Conditional branch. 290b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 2913bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 292b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne .addMBB(TBB); 293b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 294b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return 1; 295b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 296b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 297b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Two-way Conditional branch. 298b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne assert(Cond.size() == 2 && "Unexpected number of components!"); 299b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); 3003bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) 301b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne .addMBB(TBB); 3023bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB); 303b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return 2; 304b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 305b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 306b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneunsigned 307b25baef26f03b9909b65dd5f762b38f93000445dRichard OsborneXCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 308b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne MachineBasicBlock::iterator I = MBB.end(); 309b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (I == MBB.begin()) return 0; 310b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne --I; 31193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen while (I->isDebugValue()) { 31293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen if (I == MBB.begin()) 31393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen return 0; 31493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen --I; 31593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen } 316b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode())) 317b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return 0; 318b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 319b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Remove the branch. 320b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne I->eraseFromParent(); 321b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 322b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne I = MBB.end(); 323b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 324b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (I == MBB.begin()) return 1; 325b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne --I; 326b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (!IsCondBranch(I->getOpcode())) 327b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return 1; 328b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 329b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // Remove the branch. 330b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne I->eraseFromParent(); 331b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return 2; 332b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 333b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 334a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesenvoid XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 335a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen MachineBasicBlock::iterator I, DebugLoc DL, 336a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen unsigned DestReg, unsigned SrcReg, 337a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen bool KillSrc) const { 338a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen bool GRDest = XCore::GRRegsRegClass.contains(DestReg); 339a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen bool GRSrc = XCore::GRRegsRegClass.contains(SrcReg); 340a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen 341a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen if (GRDest && GRSrc) { 342a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg) 343a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen .addReg(SrcReg, getKillRegState(KillSrc)) 344a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen .addImm(0); 345a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen return; 346b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 347b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 348a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen if (GRDest && SrcReg == XCore::SP) { 349a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0); 350a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen return; 351b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 352a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen 353a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen if (DestReg == XCore::SP && GRSrc) { 354d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling BuildMI(MBB, I, DL, get(XCore::SETSP_1r)) 355a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen .addReg(SrcReg, getKillRegState(KillSrc)); 356a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen return; 357b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 358a98625cdad0a4fefaaf00174669e0cd2f0dbe1bdJakob Stoklund Olesen llvm_unreachable("Impossible reg-to-reg copy"); 359b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 360b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 361b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornevoid XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 362d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling MachineBasicBlock::iterator I, 363d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling unsigned SrcReg, bool isKill, 364d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling int FrameIndex, 365746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 366746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const 367b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{ 368c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 369d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling if (I != MBB.end()) DL = I->getDebugLoc(); 370d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling BuildMI(MBB, I, DL, get(XCore::STWFI)) 371587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling .addReg(SrcReg, getKillRegState(isKill)) 372d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling .addFrameIndex(FrameIndex) 373d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling .addImm(0); 374b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 375b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 376b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornevoid XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 377d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling MachineBasicBlock::iterator I, 378d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling unsigned DestReg, int FrameIndex, 379746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 380746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const 381b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne{ 382c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 383d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling if (I != MBB.end()) DL = I->getDebugLoc(); 384d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg) 385d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling .addFrameIndex(FrameIndex) 386d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling .addImm(0); 387b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 388b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 3896c6f28ffe42d06655f5977bd0d01214e32de93a5Richard OsborneMachineInstr* 3906c6f28ffe42d06655f5977bd0d01214e32de93a5Richard OsborneXCoreInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, 3916c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne uint64_t Offset, const MDNode *MDPtr, 3926c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne DebugLoc DL) const { 3936c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne MachineInstrBuilder MIB = BuildMI(MF, DL, get(XCore::DBG_VALUE)) 3946c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr); 3956c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne return &*MIB; 3966c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne} 3976c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne 398b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// ReverseBranchCondition - Return the inverse opcode of the 399b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// specified Branch instruction. 400b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornebool XCoreInstrInfo:: 401cd775ceff0b25a0b026f643a7990c2924bd310a3Anton KorobeynikovReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { 402b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne assert((Cond.size() == 2) && 403b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne "Invalid XCore branch condition!"); 404b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm())); 405b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 406b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 407