Index: vm/jitrino/src/codegenerator/ia32/Ia32Inst.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (revision 526683) +++ vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (working copy) @@ -42,6 +42,7 @@ class Inst; class BasicBlock; class I8Lowerer; +class ConstantAreaItem; //========================================================================================================= // class Opnd @@ -1124,12 +1125,17 @@ void setTarget(uint32 i, Node* bb); Opnd * getTableAddress() const; + ConstantAreaItem * getConstantAreaItem() const; virtual void verify() const; protected: SwitchInst(Mnemonic mnemonic, int id, Opnd * addr = 0) : ControlTransferInst(mnemonic, id), tableAddr(addr) - {kind=Kind_SwitchInst; } + { + kind=Kind_SwitchInst; + tableAddrRI = addr->getRuntimeInfo(); + assert(tableAddrRI->getKind()==Opnd::RuntimeInfo::Kind_ConstantAreaItem); + } // called by CFG to detect BB->BB block edges @@ -1140,7 +1146,13 @@ virtual void removeRedundantBranch(); void replaceTarget(Node* bbFrom, Node* bbTo); + +private: Opnd * tableAddr; + //keep original opnd runtime info. + //if orig opnd is spilled by spillgen and it's replacement has no runtime info + Opnd::RuntimeInfo* tableAddrRI; + }; //========================================================================================================= @@ -1328,9 +1340,6 @@ }; -}}; // namespace Ia32 - - //========================================================================================================= // class ConstantAreaItem //========================================================================================================= @@ -1368,5 +1377,6 @@ void * address; }; +}}; // namespace Ia32 #endif Index: vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (revision 526683) +++ vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (working copy) @@ -189,18 +189,6 @@ } //_____________________________________________________________________________________________ -Opnd * IRManager::newSwitchTableConstantMemOpnd(uint32 numTargets, Opnd * index) -{ - ConstantAreaItem * item=newSwitchTableConstantAreaItem(numTargets); -#ifdef _EM64T_ - Opnd * switchTable=newImmOpnd(typeManager.getInt32Type(), Opnd::RuntimeInfo::Kind_ConstantAreaItem, item); -#else - Opnd * switchTable=newImmOpnd(typeManager.getIntPtrType(), Opnd::RuntimeInfo::Kind_ConstantAreaItem, item); -#endif - return newMemOpnd(typeManager.getIntPtrType(), MemOpndKind_ConstantArea, 0, index, newImmOpnd(typeManager.getInt32Type(), sizeof(POINTER_SIZE_INT)), switchTable); -} - -//_____________________________________________________________________________________________ Opnd * IRManager::newInternalStringConstantImmOpnd(const char * str) { ConstantAreaItem * item=newInternalStringConstantAreaItem(str); @@ -217,32 +205,28 @@ //_____________________________________________________________________________________________ SwitchInst * IRManager::newSwitchInst(uint32 numTargets, Opnd * index) { - Inst * instList = NULL; -#ifndef _EM64T_ assert(numTargets>0); assert(index!=NULL); - Opnd* targetOpnd=newSwitchTableConstantMemOpnd(numTargets, index); - // Extract the switch table constant address that is stored as - // displacement on IA32. + Inst * instList = NULL; + ConstantAreaItem * item=newSwitchTableConstantAreaItem(numTargets); // This tableAddress in SwitchInst is kept separately [from getOpnd(0)] // so it allows to replace an Opnd (used in SpillGen) and keep the table // itself intact. - Opnd* tableAddr = targetOpnd->getMemOpndSubOpnd(MemOpndSubOpndKind_Displacement); - SwitchInst * inst=new(memoryManager, 1) SwitchInst(Mnemonic_JMP, instId++, tableAddr); + Opnd * tableAddr=newImmOpnd(typeManager.getIntPtrType(), Opnd::RuntimeInfo::Kind_ConstantAreaItem, item); +#ifndef _EM64T_ + Opnd * targetOpnd = newMemOpnd(typeManager.getIntPtrType(), + MemOpndKind_ConstantArea, 0, index, newImmOpnd(typeManager.getInt32Type(), sizeof(POINTER_SIZE_INT)), tableAddr); #else - - ConstantAreaItem * item=newSwitchTableConstantAreaItem(numTargets); - Opnd * tableAddr = newImmOpnd(typeManager.getInt64Type(), Opnd::RuntimeInfo::Kind_ConstantAreaItem, item); - - SwitchInst * inst=new(memoryManager, 1) SwitchInst(Mnemonic_JMP, instId++, tableAddr); - assert(numTargets>0); - assert(index!=NULL); + // on EM64T immediate displacement cannot be of 64 bit size, so move it to a register first Opnd * baseOpnd = newOpnd(typeManager.getInt64Type()); appendToInstList(instList, newCopyPseudoInst(Mnemonic_MOV, baseOpnd, tableAddr)); - Opnd * targetOpnd = newMemOpnd(typeManager.getUnmanagedPtrType(typeManager.getIntPtrType()), MemOpndKind_ConstantArea, baseOpnd, index, newImmOpnd(typeManager.getInt32Type(), sizeof(POINTER_SIZE_INT)), 0); + Opnd * targetOpnd = newMemOpnd(typeManager.getUnmanagedPtrType(typeManager.getIntPtrType()), + MemOpndKind_ConstantArea, baseOpnd, index, newImmOpnd(typeManager.getInt32Type(), sizeof(POINTER_SIZE_INT)), 0); #endif + SwitchInst * inst=new(memoryManager, 1) SwitchInst(Mnemonic_JMP, instId++, tableAddr); inst->insertOpnd(0, targetOpnd, Inst::OpndRole_Explicit); inst->assignOpcodeGroup(this); + appendToInstList(instList, inst); return (SwitchInst *)instList; } Index: vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h (revision 526683) +++ vm/jitrino/src/codegenerator/ia32/Ia32IRManager.h (working copy) @@ -150,7 +150,6 @@ Opnd * newFPConstantMemOpnd(float f, Opnd * baseOpnd=0, BasicBlock * bb=0); Opnd * newFPConstantMemOpnd(double f, Opnd * baseOpnd=0, BasicBlock * bb=0); - Opnd * newSwitchTableConstantMemOpnd(uint32 numTargets, Opnd * index); Opnd * newInternalStringConstantImmOpnd(const char * str); Opnd * newBinaryConstantImmOpnd(uint32 size, const void * pv); Index: vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp (revision 526683) +++ vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp (working copy) @@ -682,12 +682,14 @@ // class SwitchInst //========================================================================================================= +ConstantAreaItem * SwitchInst::getConstantAreaItem() const +{ + return (ConstantAreaItem *)tableAddrRI->getValue(0); +} + Node* SwitchInst::getTarget(uint32 i)const { - Opnd * tableAddr=getTableAddress(); - Opnd::RuntimeInfo * ri=tableAddr->getRuntimeInfo(); - assert(ri->getKind()==Opnd::RuntimeInfo::Kind_ConstantAreaItem); - ConstantAreaItem * cai = (ConstantAreaItem *)ri->getValue(0); + ConstantAreaItem * cai = getConstantAreaItem(); assert(igetSize()/sizeof(Node*)); return ((Node**)cai->getValue())[i]; } @@ -714,21 +716,15 @@ //_________________________________________________________________________________________________ uint32 SwitchInst::getNumTargets() const { - Opnd * tableAddr=getTableAddress(); - Opnd::RuntimeInfo * ri= tableAddr->getRuntimeInfo(); - assert(ri->getKind()==Opnd::RuntimeInfo::Kind_ConstantAreaItem); - ConstantAreaItem * cai = (ConstantAreaItem *)ri->getValue(0); - return cai->getSize() / sizeof(Node*); + return getConstantAreaItem()->getSize() / sizeof(Node*); } //_________________________________________________________________________________________________ void SwitchInst::setTarget(uint32 i, Node* bb) { assert(bb->isBlockNode()); - Opnd * tableAddr=getTableAddress(); - Opnd::RuntimeInfo * ri=tableAddr->getRuntimeInfo(); - assert(ri->getKind()==Opnd::RuntimeInfo::Kind_ConstantAreaItem); - ConstantAreaItem * cai = (ConstantAreaItem *)ri->getValue(0); + + ConstantAreaItem * cai = getConstantAreaItem(); assert(igetSize()/sizeof(Node*)); ((Node**)cai->getValue())[i]=bb; } @@ -737,10 +733,7 @@ void SwitchInst::replaceTarget(Node * bbFrom, Node * bbTo) { assert(bbTo->isBlockNode()); - Opnd * tableAddr=getTableAddress(); - Opnd::RuntimeInfo * ri=tableAddr->getRuntimeInfo(); - assert(ri->getKind()==Opnd::RuntimeInfo::Kind_ConstantAreaItem); - ConstantAreaItem * cai = (ConstantAreaItem *)ri->getValue(0); + ConstantAreaItem * cai = getConstantAreaItem(); Node** bbs=(Node**)cai->getValue(); #ifdef _DEBUG bool found = false; @@ -771,7 +764,7 @@ // called from CFG when 2 blocks are merging and one of the branches is redundant. void SwitchInst::removeRedundantBranch() { - assert(0); + unlink(); } //_________________________________________________________________________________________________ @@ -943,3 +936,4 @@ }}; // namespace Ia32 +