void insnCodeGen::generateInterFunctionBranch(codeGen &gen, Address from, Address to, bool link) { long disp = to - from; if (ABS(disp) <= MAX_BRANCH) { // We got lucky... return generateBranch(gen, from, to); } instPoint *point = gen.point(); if (!point) { return generateBranchViaTrap(gen, from, to, false); } assert(point); bitArray liveRegs = point->liveRegisters(); if (liveRegs[registerSpace::ctr] == true) { fprintf(stderr, " COUNT REGISTER NOT AVAILABLE. We cannot insterument this point. skipping ...\n"); return; } insnCodeGen::loadImmIntoReg(gen, 0, to); insnCodeGen::generateMoveToCR(gen, 0); // And branch to CTR instruction btctr(link ? BCTRLraw : BCTRraw); insnCodeGen::generate(gen,btctr); }
void insnCodeGen::generateBranch(codeGen &gen, Address from, Address to, bool link) { long disp = (to - from); if (ABS(disp) > MAX_BRANCH) { return generateLongBranch(gen, from, to, link); } return generateBranch(gen, disp, link); }
bool SakuraMatrix::perform(const InvocationInfo &info) { bool commandProcessed = false; bool moveFocus = false; int direction = -1; switch(info.commandID) { case generateCommandId: generateBranch(); repaint(); commandProcessed = true; break; case shuffleCommandId: shuffleMatrix(); commandProcessed = true; break; case peekCommandId: if(!info.isKeyDown) { setPeekMode(false); commandProcessed = true; } else { if(!isAlreadySolved()) { setPeekMode(true); commandProcessed = true; } } break; case settingsCommandId: toggleSettings(); break; case keyboardMoveLeftCommandId: if(_keyboardSupport && !_solved) { moveFocus = true; direction = int(Direction::Left); } break; case keyboardMoveUpCommandId: if(_keyboardSupport && !_solved) { moveFocus = true; direction = int(Direction::Top); } break; case keyboardMoveRightCommandId: if(_keyboardSupport && !_solved) { moveFocus = true; direction = int(Direction::Right); } break; case keyboardMoveDownCommandId: if(_keyboardSupport && !_solved) { moveFocus = true; direction = int(Direction::Bottom); } break; case rotateLeftCommandId: if(_keyboardSupport && !_solved) { rotateCell(_matrix[_y_focus][_x_focus], true); } break; case rotateRightCommandId: if(_keyboardSupport && !_solved) { rotateCell(_matrix[_y_focus][_x_focus], false); } break; } if(moveFocus && direction >= 0) { _matrix[_y_focus][_x_focus]->setDrawFocus(false); _x_focus += __delta[direction].first; _y_focus += __delta[direction].second; if(_x_focus < 0) _x_focus = _numberOfCellsX - 1; else if(_x_focus >= _numberOfCellsX) _x_focus = 0; else if(_y_focus < 0) _y_focus = _numberOfCellsY - 1; else if(_y_focus >= _numberOfCellsY) _y_focus = 0; _matrix[_y_focus][_x_focus]->setDrawFocus(true); commandProcessed = true; } return commandProcessed; }
void SakuraMatrix::buildMatrix(int x_cells, int y_cells, int cellSize) { if(x_cells < 3 || y_cells < 3 || (_numberOfCellsX == x_cells && _numberOfCellsY == y_cells && _cellSize == cellSize && _matrix.size())) return; if(_cellSize != cellSize || !SakuraMatrix::__figure_images.size()) { for(SakuraMatrix::FigureImagesType::iterator it = __figure_images.begin(), end = __figure_images.end(); it != end; it++) for(sakura_map<int, Image*>::iterator it2 = (*it).second.begin(), end2 = (*it).second.end(); it2 != end2; it2++) delete (*it2).second; __figure_images.clear(); Image *pTempImage = 0; for(SakuraMatrix::FiguresType::iterator it = SakuraMatrix::__figures.begin(), end = SakuraMatrix::__figures.end(); it != end; ++it) { for(sakura_map<int, Drawable*>::iterator it2 = (*it).second.begin(), end2 = (*it).second.end(); it2 != end2; ++it2) { pTempImage = new Image(Image::ARGB, cellSize, cellSize, true); Graphics g(*pTempImage); (*it2).second->drawWithin(g, 0, 0, pTempImage->getWidth(), pTempImage->getHeight(), RectanglePlacement::stretchToFit); SakuraMatrix::__figure_images[(*it).first][(*it2).first] = pTempImage; } } } _numberOfCellsX = _tempWidthInCells = x_cells; _numberOfCellsY = _tempHeightInCells = y_cells; _cellSize = _tempCellSize = cellSize; int iWindowWidth = _cellSize * _numberOfCellsX + (_cellSize * 2); int iWindowHeight = _cellSize * _numberOfCellsY + _iStatusBarHeight + (_cellSize * 2); centreWithSize(iWindowWidth + (_settingsVisible ? _settingsPanelWidth : 0), iWindowHeight); clear(); int index = 0; int x = 0; int y = 0; _matrix.resize(_numberOfCellsY); for(MatrixTypeIterator it = _matrix.begin(), end = _matrix.end(); it != end; ++it) { (*it).resize(_numberOfCellsX); for(MatrixRowTypeIterator it2 = (*it).begin(), end2 = (*it).end(); it2 != end2; ++it2) { (*it2) = new CellComponent(this); addAndMakeVisible((*it2)); x = index % _numberOfCellsX; y = index / _numberOfCellsX; (*it2)->setBounds(_cellSize + (x * _cellSize), _cellSize + (y * _cellSize), _cellSize, _cellSize); index++; } } generateBranch(); _pStatusBar->setBounds(0, iWindowHeight - _iStatusBarHeight, iWindowWidth, _iStatusBarHeight); _pSettingsPanel->setBounds(iWindowWidth, 0, _settingsPanelWidth, iWindowHeight); }
void insnCodeGen::generateLongBranch(codeGen &gen, Address from, Address to, bool isCall) { // First, see if we can cheap out long disp = (to - from); if (ABS(disp) <= MAX_BRANCH) { return generateBranch(gen, disp, isCall); } // We can use a register branch via the LR or CTR, if either of them // is free. // Let's see if we can grab a free GPregister... instPoint *point = gen.point(); if (!point) { // fprintf(stderr, " %s[%d] No point generateBranchViaTrap \n", FILE__, __LINE__); return generateBranchViaTrap(gen, from, to, isCall); } assert(point); // Could see if the codeGen has it, but right now we have assert // code there and we don't want to hit that. registerSpace *rs = registerSpace::actualRegSpace(point); gen.setRegisterSpace(rs); Register scratch = rs->getScratchRegister(gen, true); bool mustRestore = false; if (scratch == REG_NULL) { // On Linux we save under the stack and hope it doesn't // cause problems. fprintf(stderr, " %s[%d] No registers generateBranchViaTrap \n", FILE__, __LINE__); return generateBranchViaTrap(gen, from, to, isCall); } // Load the destination into our scratch register insnCodeGen::loadImmIntoReg(gen, scratch, to); // Find out whether the LR or CTR is "dead"... bitArray liveRegs = point->liveRegisters(); unsigned branchRegister = 0; if (liveRegs[registerSpace::lr] == false) { branchRegister = registerSpace::lr; } else if (liveRegs[registerSpace::ctr] == false) { branchRegister = registerSpace::ctr; } if (!branchRegister) { fprintf(stderr, " %s[%d] No branch register generateBranchViaTrap \n", FILE__, __LINE__); return generateBranchViaTrap(gen, from, to, isCall); } assert(branchRegister); instruction moveToBr; moveToBr.clear(); XFXFORM_OP_SET(moveToBr, MTSPRop); XFXFORM_RT_SET(moveToBr, scratch); if (branchRegister == registerSpace::lr) { XFORM_RA_SET(moveToBr, SPR_LR & 0x1f); XFORM_RB_SET(moveToBr, (SPR_LR >> 5) & 0x1f); // The two halves (top 5 bits/bottom 5 bits) are _reversed_ in this encoding. }
void insnCodeGen::generateCall(codeGen &gen, Address from, Address to) { generateBranch(gen, from, to, true); }
bool insnCodeGen::generate(codeGen &gen, instruction &insn, AddressSpace * /*proc*/, Address origAddr, Address relocAddr, patchTarget *fallthroughOverride, patchTarget *targetOverride) { assert(0); //#warning "This function is not implemented yet!" assert(0 && "Deprecated!"); return false; #if 0 assert(fallthroughOverride == NULL); Address targetAddr = targetOverride ? targetOverride->get_address() : 0; long newOffset = 0; Address to; if (insn.isThunk()) { } else if (insn.isUncondBranch()) { // unconditional pc relative branch. #if defined(os_vxworks) if (!targetOverride) relocationTarget(origAddr, &targetAddr); #endif // This was a check in old code. Assert it isn't the case, // since this is a _conditional_ branch... assert(insn.isInsnType(Bmask, BCAAmatch) == false); // We may need an instPoint for liveness calculations instPoint *point = gen.func()->findInstPByAddr(origAddr); if (!point) point = instPoint::createArbitraryInstPoint(origAddr, gen.addrSpace(), gen.func()); gen.setPoint(point); if (targetAddr) { generateBranch(gen, relocAddr, targetAddr, IFORM_LK(insn)); } else { generateBranch(gen, relocAddr, insn.getTarget(origAddr), IFORM_LK(insn)); } } else if (insn.isCondBranch()) { // conditional pc relative branch. #if defined(os_vxworks) if (!targetOverride) relocationTarget(origAddr, &targetAddr); #endif if (!targetAddr) { newOffset = origAddr - relocAddr + insn.getBranchOffset(); to = origAddr + insn.getBranchOffset(); } else { newOffset = targetAddr - relocAddr; to = targetAddr; } } else { #if defined(os_vxworks) if (relocationTarget(origAddr + 2, &targetAddr)) DFORM_SI_SET(insn, targetAddr); #endif generate(gen,insn); } return true; #endif }