MachineInstr.cpp revision 92dfe2001e96f6e2b6d327e8816f38033f88b295
1035dfbe7f2d109008d2d62d9f2a67efb477a7ab6Chris Lattner//===-- MachineInstr.cpp --------------------------------------------------===// 2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 5b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// This file was developed by the LLVM research group and is distributed under 6b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 7edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 921326fc2ad47ee7e73a8c0b03a4a0cc0b0a0c4e8Brian Gaeke// 1021326fc2ad47ee7e73a8c0b03a4a0cc0b0a0c4e8Brian Gaeke// Methods common to all machine instructions. 1121326fc2ad47ee7e73a8c0b03a4a0cc0b0a0c4e8Brian Gaeke// 12035dfbe7f2d109008d2d62d9f2a67efb477a7ab6Chris Lattner//===----------------------------------------------------------------------===// 1370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 14822b4fb896846b87dd11a330ae13f2239329aeefChris Lattner#include "llvm/CodeGen/MachineInstr.h" 158517e1f0beea9b5e47974f083396d53294c390adChris Lattner#include "llvm/CodeGen/MachineFunction.h" 161049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner#include "llvm/Target/TargetMachine.h" 173501feab811c86c9659248a4875fc31a3165f84dChris Lattner#include "llvm/Target/TargetInstrInfo.h" 182a79a0927c479b69316aa275c1f79c74d20e8040Chris Lattner#include "llvm/Target/MRegisterInfo.h" 19551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/LeakDetector.h" 20a09362eb975730ac624c0bd210a95655ee105296Bill Wendling#include "llvm/Support/Streams.h" 21c21c5eeb4f56f160e79522df2d3aab5cfe73c05dJeff Cohen#include <ostream> 220742b59913a7760eb26f08121cd244a37e83e3b3Chris Lattnerusing namespace llvm; 23d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 24c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng/// MachineInstr ctor - This constructor creates a dummy MachineInstr with 2567f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng/// TID NULL and no operands. 26c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan ChengMachineInstr::MachineInstr() 2767f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng : TID(0), NumImplicitOps(0), parent(0) { 28aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos // Make sure that we get added to a machine basicblock 29aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos LeakDetector::addGarbageObject(this); 307279122e668816bed0d4f38d3392bbab0140fad0Chris Lattner} 317279122e668816bed0d4f38d3392bbab0140fad0Chris Lattner 3267f660cb080965ea93ed6d7265a67100f2fe38e4Evan Chengvoid MachineInstr::addImplicitDefUseOperands() { 3367f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if (TID->ImplicitDefs) 3467f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) { 35d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng MachineOperand Op; 36d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.opType = MachineOperand::MO_Register; 37d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsDef = true; 38d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsImp = true; 39d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsKill = false; 40d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsDead = false; 41d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.contents.RegNo = *ImpDefs; 42d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Operands.push_back(Op); 43d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng } 4467f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if (TID->ImplicitUses) 4567f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) { 46d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng MachineOperand Op; 47d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.opType = MachineOperand::MO_Register; 48d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsDef = false; 49d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsImp = true; 50d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsKill = false; 51d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.IsDead = false; 52d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Op.contents.RegNo = *ImpUses; 53d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng Operands.push_back(Op); 54d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng } 55d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng} 56d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng 57d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng/// MachineInstr ctor - This constructor create a MachineInstr and add the 58c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng/// implicit operands. It reserves space for number of operands specified by 59c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng/// TargetInstrDescriptor or the numOperands if it is not zero. (for 60c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan Cheng/// instructions with variable number of operands). 6167f660cb080965ea93ed6d7265a67100f2fe38e4Evan ChengMachineInstr::MachineInstr(const TargetInstrDescriptor &tid) 6267f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng : TID(&tid), NumImplicitOps(0), parent(0) { 6367f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if (TID->ImplicitDefs) 6467f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) 65d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng NumImplicitOps++; 6667f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if (TID->ImplicitUses) 6767f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) 68d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng NumImplicitOps++; 6967f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng Operands.reserve(NumImplicitOps + TID->numOperands); 7067f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng addImplicitDefUseOperands(); 71d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng // Make sure that we get added to a machine basicblock 72d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng LeakDetector::addGarbageObject(this); 73d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng} 74d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng 75ddd7fcb887be752ec8167276a697994ad9cb9c4eChris Lattner/// MachineInstr ctor - Work exactly the same as the ctor above, except that the 76ddd7fcb887be752ec8167276a697994ad9cb9c4eChris Lattner/// MachineInstr is created and added to the end of the specified basic block. 77ddd7fcb887be752ec8167276a697994ad9cb9c4eChris Lattner/// 78c0f64ffab93d11fb27a3b8a0707b77400918a20eEvan ChengMachineInstr::MachineInstr(MachineBasicBlock *MBB, 7967f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng const TargetInstrDescriptor &tid) 8067f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng : TID(&tid), NumImplicitOps(0), parent(0) { 81ddd7fcb887be752ec8167276a697994ad9cb9c4eChris Lattner assert(MBB && "Cannot use inserting ctor with null basic block!"); 8267f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if (TID->ImplicitDefs) 8367f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) 84d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng NumImplicitOps++; 8567f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if (TID->ImplicitUses) 8667f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) 87d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng NumImplicitOps++; 8867f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng Operands.reserve(NumImplicitOps + TID->numOperands); 8967f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng addImplicitDefUseOperands(); 90aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos // Make sure that we get added to a machine basicblock 91aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos LeakDetector::addGarbageObject(this); 92ddd7fcb887be752ec8167276a697994ad9cb9c4eChris Lattner MBB->push_back(this); // Add instruction to end of basic block! 93ddd7fcb887be752ec8167276a697994ad9cb9c4eChris Lattner} 94ddd7fcb887be752ec8167276a697994ad9cb9c4eChris Lattner 95ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman/// MachineInstr ctor - Copies MachineInstr arg exactly 96ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman/// 97466b534a570f574ed485d875bbca8454f68dcb52Tanya LattnerMachineInstr::MachineInstr(const MachineInstr &MI) { 9867f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng TID = MI.getInstrDescriptor(); 996b2c05f3d3c7b44183c629485ade10c18b86828dEvan Cheng NumImplicitOps = MI.NumImplicitOps; 100943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner Operands.reserve(MI.getNumOperands()); 101b5159ed0cb7943e5938782f7693beb18342165ceTanya Lattner 102ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman // Add operands 103943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner for (unsigned i = 0; i != MI.getNumOperands(); ++i) 104943b5e117fe9a087f9aa529a2632c2d32cc22374Chris Lattner Operands.push_back(MI.getOperand(i)); 1050c63e03e04d3982e1913479bba404c3debc9a27eTanya Lattner 106ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman // Set parent, next, and prev to null 1070c63e03e04d3982e1913479bba404c3debc9a27eTanya Lattner parent = 0; 1080c63e03e04d3982e1913479bba404c3debc9a27eTanya Lattner prev = 0; 1090c63e03e04d3982e1913479bba404c3debc9a27eTanya Lattner next = 0; 110466b534a570f574ed485d875bbca8454f68dcb52Tanya Lattner} 111466b534a570f574ed485d875bbca8454f68dcb52Tanya Lattner 112466b534a570f574ed485d875bbca8454f68dcb52Tanya Lattner 113ce22e76996d3ff0930716fa60c29df60a7e0481bMisha BrukmanMachineInstr::~MachineInstr() { 114aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos LeakDetector::removeGarbageObject(this); 115aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos} 116aad5c0505183a5b7913f1a443a1f0650122551ccAlkis Evlogimenos 11767f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng/// getOpcode - Returns the opcode of this MachineInstr. 11867f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng/// 119cb648f90a26eb05ae8d508d500ca12881df50824Dan Gohmanint MachineInstr::getOpcode() const { 12067f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng return TID->Opcode; 12167f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng} 12267f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng 12348d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner/// removeFromParent - This method unlinks 'this' from the containing basic 12448d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner/// block, and returns it, but does not delete it. 12548d7c069c76882475c23de153bda9483cd3c9bb4Chris LattnerMachineInstr *MachineInstr::removeFromParent() { 12648d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner assert(getParent() && "Not embedded in a basic block!"); 12748d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner getParent()->remove(this); 12848d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner return this; 12948d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner} 13048d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner 13148d7c069c76882475c23de153bda9483cd3c9bb4Chris Lattner 13221326fc2ad47ee7e73a8c0b03a4a0cc0b0a0c4e8Brian Gaeke/// OperandComplete - Return true if it's illegal to add a new operand 13321326fc2ad47ee7e73a8c0b03a4a0cc0b0a0c4e8Brian Gaeke/// 1342a90ba60175f93e7438165d8423100aa573c16c5Chris Lattnerbool MachineInstr::OperandsComplete() const { 13567f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng unsigned short NumOperands = TID->numOperands; 13667f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if ((TID->Flags & M_VARIABLE_OPS) == 0 && 1378bcb042f22f06d034f18aee8cb5dd0a04745fd97Evan Cheng getNumOperands()-NumImplicitOps >= NumOperands) 1383497782f3843007de3be0c43e3ff206a01e2ccacVikram S. Adve return true; // Broken: we have all the operands of this instruction! 139413746e9833d97a8b463ef6a788aa326cf3829a2Chris Lattner return false; 14070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve} 14170bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 14219e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng/// getNumExplicitOperands - Returns the number of non-implicit operands. 14319e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng/// 14419e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Chengunsigned MachineInstr::getNumExplicitOperands() const { 14519e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng unsigned NumOperands = TID->numOperands; 14619e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng if ((TID->Flags & M_VARIABLE_OPS) == 0) 14719e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng return NumOperands; 14819e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng 14919e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng for (unsigned e = getNumOperands(); NumOperands != e; ++NumOperands) { 15019e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng const MachineOperand &MO = getOperand(NumOperands); 15119e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng if (!MO.isRegister() || !MO.isImplicit()) 15219e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng NumOperands++; 15319e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng } 15419e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng return NumOperands; 15519e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng} 15619e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng 1578ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner/// isIdenticalTo - Return true if this operand is identical to the specified 1588ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner/// operand. 1598ace2cd034be10c09be51daf08c3dda327f54262Chris Lattnerbool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 1608ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner if (getType() != Other.getType()) return false; 1618ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner 1628ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner switch (getType()) { 1638ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner default: assert(0 && "Unrecognized operand type"); 1648ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_Register: 1658ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner return getReg() == Other.getReg() && isDef() == Other.isDef(); 1668ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_Immediate: 1678ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner return getImm() == Other.getImm(); 1688ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_MachineBasicBlock: 1698ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner return getMBB() == Other.getMBB(); 1708ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_FrameIndex: 1718ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner return getFrameIndex() == Other.getFrameIndex(); 1728ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_ConstantPoolIndex: 1738ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner return getConstantPoolIndex() == Other.getConstantPoolIndex() && 1748ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner getOffset() == Other.getOffset(); 1758ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_JumpTableIndex: 1768ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner return getJumpTableIndex() == Other.getJumpTableIndex(); 1778ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_GlobalAddress: 1788ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 1798ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner case MachineOperand::MO_ExternalSymbol: 18013a04125df039d118c688df26998343a00d8a749Chris Lattner return !strcmp(getSymbolName(), Other.getSymbolName()) && 1818ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner getOffset() == Other.getOffset(); 1828ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner } 1838ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner} 1848ace2cd034be10c09be51daf08c3dda327f54262Chris Lattner 185faa510726f4b40aa4495e60e4d341c6467e3fb01Evan Cheng/// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 18632eb1f1ca4220d2f24916e587ad7e8574d7d82a1Evan Cheng/// the specific register or -1 if it is not found. It further tightening 18776d7e76c15c258ec4a71fd75a2a32bca3a5e5e27Evan Cheng/// the search criteria to a use that kills the register if isKill is true. 188f277ee4be7edabb759a7f78138b693d72d0c263fEvan Chengint MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill) const { 189576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 190f277ee4be7edabb759a7f78138b693d72d0c263fEvan Cheng const MachineOperand &MO = getOperand(i); 19192dfe2001e96f6e2b6d327e8816f38033f88b295Dan Gohman if (MO.isRegister() && MO.isUse() && MO.getReg() == Reg) 19276d7e76c15c258ec4a71fd75a2a32bca3a5e5e27Evan Cheng if (!isKill || MO.isKill()) 19332eb1f1ca4220d2f24916e587ad7e8574d7d82a1Evan Cheng return i; 194b371f457b0ea4a652a9f526ba4375c80ae542252Evan Cheng } 19532eb1f1ca4220d2f24916e587ad7e8574d7d82a1Evan Cheng return -1; 196b371f457b0ea4a652a9f526ba4375c80ae542252Evan Cheng} 197b371f457b0ea4a652a9f526ba4375c80ae542252Evan Cheng 198b371f457b0ea4a652a9f526ba4375c80ae542252Evan Cheng/// findRegisterDefOperand() - Returns the MachineOperand that is a def of 199b371f457b0ea4a652a9f526ba4375c80ae542252Evan Cheng/// the specific register or NULL if it is not found. 200b371f457b0ea4a652a9f526ba4375c80ae542252Evan ChengMachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) { 201b371f457b0ea4a652a9f526ba4375c80ae542252Evan Cheng for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 202b371f457b0ea4a652a9f526ba4375c80ae542252Evan Cheng MachineOperand &MO = getOperand(i); 20392dfe2001e96f6e2b6d327e8816f38033f88b295Dan Gohman if (MO.isRegister() && MO.isDef() && MO.getReg() == Reg) 204576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng return &MO; 205576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng } 206576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng return NULL; 207576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng} 20819e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng 209f277ee4be7edabb759a7f78138b693d72d0c263fEvan Cheng/// findFirstPredOperandIdx() - Find the index of the first operand in the 210f277ee4be7edabb759a7f78138b693d72d0c263fEvan Cheng/// operand list that is used to represent the predicate. It returns -1 if 211f277ee4be7edabb759a7f78138b693d72d0c263fEvan Cheng/// none is found. 212f277ee4be7edabb759a7f78138b693d72d0c263fEvan Chengint MachineInstr::findFirstPredOperandIdx() const { 21319e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng const TargetInstrDescriptor *TID = getInstrDescriptor(); 214c3a289c4b5a60a204363ba4ae9f017ba87b714f9Evan Cheng if (TID->Flags & M_PREDICABLE) { 21519e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 21619e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) 217f277ee4be7edabb759a7f78138b693d72d0c263fEvan Cheng return i; 21819e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng } 21919e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng 220f277ee4be7edabb759a7f78138b693d72d0c263fEvan Cheng return -1; 22119e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng} 222576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng 223576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng/// copyKillDeadInfo - Copies kill / dead operand properties from MI. 224576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng/// 225576d123e130a8291669dd2384a3735cc4933fd00Evan Chengvoid MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { 226576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 227576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng const MachineOperand &MO = MI->getOperand(i); 22892dfe2001e96f6e2b6d327e8816f38033f88b295Dan Gohman if (!MO.isRegister() || (!MO.isKill() && !MO.isDead())) 229576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng continue; 230576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng for (unsigned j = 0, ee = getNumOperands(); j != ee; ++j) { 231576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng MachineOperand &MOp = getOperand(j); 232576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng if (!MOp.isIdenticalTo(MO)) 233576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng continue; 234576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng if (MO.isKill()) 235576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng MOp.setIsKill(); 236576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng else 237576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng MOp.setIsDead(); 238576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng break; 239576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng } 240576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng } 241576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng} 242576d123e130a8291669dd2384a3735cc4933fd00Evan Cheng 24319e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng/// copyPredicates - Copies predicate operand(s) from MI. 24419e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Chengvoid MachineInstr::copyPredicates(const MachineInstr *MI) { 24519e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng const TargetInstrDescriptor *TID = MI->getInstrDescriptor(); 246c3a289c4b5a60a204363ba4ae9f017ba87b714f9Evan Cheng if (TID->Flags & M_PREDICABLE) { 24719e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 24819e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) { 24919e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng const MachineOperand &MO = MI->getOperand(i); 25019e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng // Predicated operands must be last operands. 25192dfe2001e96f6e2b6d327e8816f38033f88b295Dan Gohman if (MO.isRegister()) 25219e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng addRegOperand(MO.getReg(), false); 25319e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng else { 25419e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng addImmOperand(MO.getImm()); 25519e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng } 25619e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng } 25719e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng } 25819e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng } 25919e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng} 26019e3f31f6acd9f5ce3cdd8372d4cb598ed921f95Evan Cheng 26121326fc2ad47ee7e73a8c0b03a4a0cc0b0a0c4e8Brian Gaekevoid MachineInstr::dump() const { 262e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cerr << " " << *this; 26370bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve} 26470bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 2652a79a0927c479b69316aa275c1f79c74d20e8040Chris Lattnerstatic inline void OutputReg(std::ostream &os, unsigned RegNo, 2662a79a0927c479b69316aa275c1f79c74d20e8040Chris Lattner const MRegisterInfo *MRI = 0) { 267ddcfd9e6fafdbbe5c973477e537119e73c115ee4Alkis Evlogimenos if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) { 2688517e1f0beea9b5e47974f083396d53294c390adChris Lattner if (MRI) 2692a79a0927c479b69316aa275c1f79c74d20e8040Chris Lattner os << "%" << MRI->get(RegNo).Name; 2702a79a0927c479b69316aa275c1f79c74d20e8040Chris Lattner else 2718517e1f0beea9b5e47974f083396d53294c390adChris Lattner os << "%mreg(" << RegNo << ")"; 2722a79a0927c479b69316aa275c1f79c74d20e8040Chris Lattner } else 2738517e1f0beea9b5e47974f083396d53294c390adChris Lattner os << "%reg" << RegNo; 2748c6936a58b75d7d185014839ea95377eb2fbd878Vikram S. Adve} 2758c6936a58b75d7d185014839ea95377eb2fbd878Vikram S. Adve 2761049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattnerstatic void print(const MachineOperand &MO, std::ostream &OS, 277b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner const TargetMachine *TM) { 278ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman const MRegisterInfo *MRI = 0; 279edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 280ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman if (TM) MRI = TM->getRegisterInfo(); 281b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner 2821049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner switch (MO.getType()) { 2832d90ac7ca6117d3b160dde8a4f322c1079a6ffceChris Lattner case MachineOperand::MO_Register: 2844efeab208cf0fe7ae2f68bcdd1264a8fdb18826cChris Lattner OutputReg(OS, MO.getReg(), MRI); 2851049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner break; 28663b3d7113d93fda622c4954c6b1d046ce029044eChris Lattner case MachineOperand::MO_Immediate: 28700aff7d9772e4945e3a946e70a3ef9998006b8deEvan Cheng OS << MO.getImmedValue(); 2881049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner break; 2892109f502d646a1bafc7b21a14347a71771a7b4cfChris Lattner case MachineOperand::MO_MachineBasicBlock: 290988b7ba5bad830379a7108c1f9ea36fb29073245Brian Gaeke OS << "mbb<" 2912109f502d646a1bafc7b21a14347a71771a7b4cfChris Lattner << ((Value*)MO.getMachineBasicBlock()->getBasicBlock())->getName() 292988b7ba5bad830379a7108c1f9ea36fb29073245Brian Gaeke << "," << (void*)MO.getMachineBasicBlock() << ">"; 2932109f502d646a1bafc7b21a14347a71771a7b4cfChris Lattner break; 29410cb79b48430ea7679e83ae045aaeadea04a0cc5Chris Lattner case MachineOperand::MO_FrameIndex: 29510cb79b48430ea7679e83ae045aaeadea04a0cc5Chris Lattner OS << "<fi#" << MO.getFrameIndex() << ">"; 29610cb79b48430ea7679e83ae045aaeadea04a0cc5Chris Lattner break; 2978d95ef4973226044cefdd6dc237d3c326ffc15b3Chris Lattner case MachineOperand::MO_ConstantPoolIndex: 2988d95ef4973226044cefdd6dc237d3c326ffc15b3Chris Lattner OS << "<cp#" << MO.getConstantPoolIndex() << ">"; 2998d95ef4973226044cefdd6dc237d3c326ffc15b3Chris Lattner break; 30037efe6764568a3829fee26aba532283131d1a104Nate Begeman case MachineOperand::MO_JumpTableIndex: 30137efe6764568a3829fee26aba532283131d1a104Nate Begeman OS << "<jt#" << MO.getJumpTableIndex() << ">"; 30237efe6764568a3829fee26aba532283131d1a104Nate Begeman break; 3038d95ef4973226044cefdd6dc237d3c326ffc15b3Chris Lattner case MachineOperand::MO_GlobalAddress: 304ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner OS << "<ga:" << ((Value*)MO.getGlobal())->getName(); 305ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner if (MO.getOffset()) OS << "+" << MO.getOffset(); 306ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner OS << ">"; 3078d95ef4973226044cefdd6dc237d3c326ffc15b3Chris Lattner break; 3088d95ef4973226044cefdd6dc237d3c326ffc15b3Chris Lattner case MachineOperand::MO_ExternalSymbol: 309ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner OS << "<es:" << MO.getSymbolName(); 310ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner if (MO.getOffset()) OS << "+" << MO.getOffset(); 311ca4f6ebefc4dc55d13a0182a0be5b02e92fc63eaChris Lattner OS << ">"; 3128d95ef4973226044cefdd6dc237d3c326ffc15b3Chris Lattner break; 3131049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner default: 3141049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner assert(0 && "Unrecognized operand type"); 3151049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner } 3161049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner} 3171049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 318b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattnervoid MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const { 3196a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner unsigned StartOp = 0; 3206a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner 3216a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner // Specialize printing if op#0 is definition 32292dfe2001e96f6e2b6d327e8816f38033f88b295Dan Gohman if (getNumOperands() && getOperand(0).isRegister() && getOperand(0).isDef()) { 3230742b59913a7760eb26f08121cd244a37e83e3b3Chris Lattner ::print(getOperand(0), OS, TM); 324bdf44b929f6bd0983b0f0df0d2ae66610e81e149Evan Cheng if (getOperand(0).isDead()) 325bdf44b929f6bd0983b0f0df0d2ae66610e81e149Evan Cheng OS << "<dead>"; 3266a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner OS << " = "; 3276a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner ++StartOp; // Don't print this operand again! 3286a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner } 329b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner 33067f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng if (TID) 33167f660cb080965ea93ed6d7265a67100f2fe38e4Evan Cheng OS << TID->Name; 332edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 3336a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 3345f2180c53330502eb2f0f5bf3f21a838ad800906Vikram S. Adve const MachineOperand& mop = getOperand(i); 3356a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner if (i != StartOp) 3366a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner OS << ","; 3376a592271fb2946a0704b06fd66199987cdd40b3cChris Lattner OS << " "; 3380742b59913a7760eb26f08121cd244a37e83e3b3Chris Lattner ::print(mop, OS, TM); 339edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 34092dfe2001e96f6e2b6d327e8816f38033f88b295Dan Gohman if (mop.isRegister()) { 341d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng if (mop.isDef() || mop.isKill() || mop.isDead() || mop.isImplicit()) { 342d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng OS << "<"; 343d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng bool NeedComma = false; 344d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng if (mop.isImplicit()) { 345d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng OS << (mop.isDef() ? "imp-def" : "imp-use"); 346d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng NeedComma = true; 347d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng } else if (mop.isDef()) { 348d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng OS << "def"; 349d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng NeedComma = true; 350d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng } 351d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng if (mop.isKill() || mop.isDead()) { 352d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng if (NeedComma) 353d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng OS << ","; 354d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng if (mop.isKill()) 355d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng OS << "kill"; 356d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng if (mop.isDead()) 357d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng OS << "dead"; 358d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng } 359d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng OS << ">"; 360d7de496b23fca8145f777a56281457bf64e8bbadEvan Cheng } 361438f7bc67cf235ccee7e6f7ac7f4ae2186eb8020Evan Cheng } 3621049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner } 363edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 3641049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner OS << "\n"; 3651049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner} 3661049164aa6b06d91d9b3b557a9a213eaf3f6319aChris Lattner 3674b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohenvoid MachineInstr::print(std::ostream &os) const { 3688517e1f0beea9b5e47974f083396d53294c390adChris Lattner // If the instruction is embedded into a basic block, we can find the target 3698517e1f0beea9b5e47974f083396d53294c390adChris Lattner // info for the instruction. 3704b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen if (const MachineBasicBlock *MBB = getParent()) { 3718517e1f0beea9b5e47974f083396d53294c390adChris Lattner const MachineFunction *MF = MBB->getParent(); 372ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman if (MF) 3734b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen print(os, &MF->getTarget()); 374b140762a45d21aaed054f15adaff0fc2274d939dTanya Lattner else 3754b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen print(os, 0); 3768517e1f0beea9b5e47974f083396d53294c390adChris Lattner } 3778517e1f0beea9b5e47974f083396d53294c390adChris Lattner 3788517e1f0beea9b5e47974f083396d53294c390adChris Lattner // Otherwise, print it out in the "raw" format without symbolic register names 3798517e1f0beea9b5e47974f083396d53294c390adChris Lattner // and such. 3804b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen os << getInstrDescriptor()->Name; 381edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 3824b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen for (unsigned i = 0, N = getNumOperands(); i < N; i++) { 3834b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen os << "\t" << getOperand(i); 38492dfe2001e96f6e2b6d327e8816f38033f88b295Dan Gohman if (getOperand(i).isRegister() && getOperand(i).isDef()) 385d8f44e07b89e651b2f0e3b0d680a775f44e667daChris Lattner os << "<d>"; 3868d24337eea5f9462908b7ac07a997935e31ddd59Ruchira Sasanka } 387edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 3884b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen os << "\n"; 38970bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve} 39070bc4b5d1a3795a8f41be96723cfcbccac8e1671Vikram S. Adve 3914b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohenvoid MachineOperand::print(std::ostream &OS) const { 3924b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen switch (getType()) { 3934b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_Register: 3944b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen OutputReg(OS, getReg()); 395ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 3964b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_Immediate: 3974b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen OS << (long)getImmedValue(); 398ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 3994b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_MachineBasicBlock: 400ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman OS << "<mbb:" 4014b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen << ((Value*)getMachineBasicBlock()->getBasicBlock())->getName() 4024b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen << "@" << (void*)getMachineBasicBlock() << ">"; 403ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 4044b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_FrameIndex: 4054b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen OS << "<fi#" << getFrameIndex() << ">"; 406ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 4074b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_ConstantPoolIndex: 4084b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen OS << "<cp#" << getConstantPoolIndex() << ">"; 409ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 4104b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_JumpTableIndex: 4114b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen OS << "<jt#" << getJumpTableIndex() << ">"; 41237efe6764568a3829fee26aba532283131d1a104Nate Begeman break; 4134b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_GlobalAddress: 4144b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen OS << "<ga:" << ((Value*)getGlobal())->getName() << ">"; 415ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 4164b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen case MO_ExternalSymbol: 4174b607748d86b44cc59e5cf3eee194dfd9b0fcd86Jeff Cohen OS << "<es:" << getSymbolName() << ">"; 418ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 419ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman default: 420ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman assert(0 && "Unrecognized operand type"); 421ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman break; 422ce22e76996d3ff0930716fa60c29df60a7e0481bMisha Brukman } 423c21c5eeb4f56f160e79522df2d3aab5cfe73c05dJeff Cohen} 424c21c5eeb4f56f160e79522df2d3aab5cfe73c05dJeff Cohen 425