1 //===- AlphaInstrInfo.cpp - Alpha Instruction Information -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Alpha implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 #include "AlphaInstrInfo.h"
16 #include "AlphaGenInstrInfo.inc"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 AlphaInstrInfo::AlphaInstrInfo()
22 : TargetInstrInfo(AlphaInsts, sizeof(AlphaInsts)/sizeof(AlphaInsts[0])) { }
25 bool AlphaInstrInfo::isMoveInstr(const MachineInstr& MI,
27 unsigned& destReg) const {
28 MachineOpCode oc = MI.getOpcode();
29 if (oc == Alpha::BISr ||
32 oc == Alpha::CPYSSt ||
33 oc == Alpha::CPYSTs) {
36 assert(MI.getNumOperands() == 3 &&
37 MI.getOperand(0).isRegister() &&
38 MI.getOperand(1).isRegister() &&
39 MI.getOperand(2).isRegister() &&
40 "invalid Alpha BIS instruction!");
41 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
42 sourceReg = MI.getOperand(1).getReg();
43 destReg = MI.getOperand(0).getReg();
51 AlphaInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const {
52 switch (MI->getOpcode()) {
59 if (MI->getOperand(1).isFrameIndex()) {
60 FrameIndex = MI->getOperand(1).getFrameIndex();
61 return MI->getOperand(0).getReg();
69 AlphaInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
70 switch (MI->getOpcode()) {
77 if (MI->getOperand(1).isFrameIndex()) {
78 FrameIndex = MI->getOperand(1).getFrameIndex();
79 return MI->getOperand(0).getReg();
86 static bool isAlphaIntCondCode(unsigned Opcode) {
102 void AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
103 MachineBasicBlock *FBB,
104 const std::vector<MachineOperand> &Cond)const{
105 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
106 assert((Cond.size() == 2 || Cond.size() == 0) &&
107 "Alpha branch conditions have two components!");
111 if (Cond.empty()) // Unconditional branch
112 BuildMI(&MBB, Alpha::BR, 1).addMBB(TBB);
113 else // Conditional branch
114 if (isAlphaIntCondCode(Cond[0].getImm()))
115 BuildMI(&MBB, Alpha::COND_BRANCH_I, 3)
116 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
118 BuildMI(&MBB, Alpha::COND_BRANCH_F, 3)
119 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
123 // Two-way Conditional Branch.
124 if (isAlphaIntCondCode(Cond[0].getImm()))
125 BuildMI(&MBB, Alpha::COND_BRANCH_I, 3)
126 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
128 BuildMI(&MBB, Alpha::COND_BRANCH_F, 3)
129 .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
130 BuildMI(&MBB, Alpha::BR, 1).addMBB(FBB);
133 static unsigned AlphaRevCondCode(unsigned Opcode) {
135 case Alpha::BEQ: return Alpha::BNE;
136 case Alpha::BNE: return Alpha::BEQ;
137 case Alpha::BGE: return Alpha::BLT;
138 case Alpha::BGT: return Alpha::BLE;
139 case Alpha::BLE: return Alpha::BGT;
140 case Alpha::BLT: return Alpha::BGE;
141 case Alpha::BLBC: return Alpha::BLBS;
142 case Alpha::BLBS: return Alpha::BLBC;
143 case Alpha::FBEQ: return Alpha::FBNE;
144 case Alpha::FBNE: return Alpha::FBEQ;
145 case Alpha::FBGE: return Alpha::FBLT;
146 case Alpha::FBGT: return Alpha::FBLE;
147 case Alpha::FBLE: return Alpha::FBGT;
148 case Alpha::FBLT: return Alpha::FBGE;
150 assert(0 && "Unknown opcode");
155 bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
156 MachineBasicBlock *&FBB,
157 std::vector<MachineOperand> &Cond) const {
158 // If the block has no terminators, it just falls into the block after it.
159 MachineBasicBlock::iterator I = MBB.end();
160 if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode()))
163 // Get the last instruction in the block.
164 MachineInstr *LastInst = I;
166 // If there is only one terminator instruction, process it.
167 if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode())) {
168 if (LastInst->getOpcode() == Alpha::BR) {
169 TBB = LastInst->getOperand(0).getMachineBasicBlock();
171 } else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I ||
172 LastInst->getOpcode() == Alpha::COND_BRANCH_F) {
173 // Block ends with fall-through condbranch.
174 TBB = LastInst->getOperand(2).getMachineBasicBlock();
175 Cond.push_back(LastInst->getOperand(0));
176 Cond.push_back(LastInst->getOperand(1));
179 // Otherwise, don't know what this is.
183 // Get the instruction before it if it's a terminator.
184 MachineInstr *SecondLastInst = I;
186 // If there are three terminators, we don't know what sort of block this is.
187 if (SecondLastInst && I != MBB.begin() &&
188 isTerminatorInstr((--I)->getOpcode()))
191 // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it.
192 if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I ||
193 SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) &&
194 LastInst->getOpcode() == Alpha::BR) {
195 TBB = SecondLastInst->getOperand(2).getMachineBasicBlock();
196 Cond.push_back(SecondLastInst->getOperand(0));
197 Cond.push_back(SecondLastInst->getOperand(1));
198 FBB = LastInst->getOperand(0).getMachineBasicBlock();
202 // Otherwise, can't handle this.
206 void AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
207 MachineBasicBlock::iterator I = MBB.end();
208 if (I == MBB.begin()) return;
210 if (I->getOpcode() != Alpha::BR &&
211 I->getOpcode() != Alpha::COND_BRANCH_I &&
212 I->getOpcode() != Alpha::COND_BRANCH_F)
215 // Remove the branch.
216 I->eraseFromParent();
220 if (I == MBB.begin()) return;
222 if (I->getOpcode() != Alpha::COND_BRANCH_I &&
223 I->getOpcode() != Alpha::COND_BRANCH_F)
226 // Remove the branch.
227 I->eraseFromParent();
230 void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB,
231 MachineBasicBlock::iterator MI) const {
232 BuildMI(MBB, MI, Alpha::BISr, 2, Alpha::R31).addReg(Alpha::R31)
236 bool AlphaInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
237 if (MBB.empty()) return false;
239 switch (MBB.back().getOpcode()) {
240 case Alpha::BR: // Uncond branch.
241 case Alpha::JMP: // Indirect branch.
243 default: return false;
246 bool AlphaInstrInfo::
247 ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
248 assert(Cond.size() == 2 && "Invalid Alpha branch opcode!");
249 Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm()));