- DEBUG(std::cerr << "\t\tloading temporarily used operands to "
- "registers:\n");
- for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
- i != e; ++i) {
- MachineOperand& op = (*currentInstr_)->getOperand(i);
- if (op.isVirtualRegister() && op.opIsUse()) {
- unsigned virtReg = op.getAllocatedRegNum();
- unsigned physReg = v2pMap_[virtReg];
- if (!physReg) {
- physReg = getFreeTempPhysReg(virtReg);
- }
- loadVirt2PhysReg(virtReg, physReg);
- tempUseOperands_.push_back(virtReg);
- (*currentInstr_)->SetMachineOperandReg(i, physReg);
- }
- }
-
- DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
- for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
- clearVirtReg(tempUseOperands_[i]);
- }
- tempUseOperands_.clear();
-
- DEBUG(std::cerr << "\t\tassigning temporarily defined operands to "
- "registers:\n");
- for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
- i != e; ++i) {
- MachineOperand& op = (*currentInstr_)->getOperand(i);
- if (op.isVirtualRegister() && !op.opIsUse()) {
- unsigned virtReg = op.getAllocatedRegNum();
- unsigned physReg = v2pMap_[virtReg];
- if (!physReg) {
- physReg = getFreeTempPhysReg(virtReg);
- }
- if (op.opIsDefAndUse()) {
- loadVirt2PhysReg(virtReg, physReg);
- }
- else {
- assignVirt2PhysReg(virtReg, physReg);
- }
- tempDefOperands_.push_back(virtReg);
- (*currentInstr_)->SetMachineOperandReg(i, physReg);
- }
- }
-
-
- // if the instruction is a two address instruction and the
- // source operands are not identical we need to insert
- // extra instructions.
-
- unsigned opcode = (*currentInstr_)->getOpcode();
- if (tm_->getInstrInfo().isTwoAddrInstr(opcode) &&
- (*currentInstr_)->getOperand(0).getAllocatedRegNum() !=
- (*currentInstr_)->getOperand(1).getAllocatedRegNum()) {
- assert((*currentInstr_)->getOperand(1).isRegister() &&
- (*currentInstr_)->getOperand(1).getAllocatedRegNum() &&
- (*currentInstr_)->getOperand(1).opIsUse() &&
- "Two address instruction invalid");
-
- unsigned regA =
- (*currentInstr_)->getOperand(0).getAllocatedRegNum();
- unsigned regB =
- (*currentInstr_)->getOperand(1).getAllocatedRegNum();
- unsigned regC =
- ((*currentInstr_)->getNumOperands() > 2 &&
- (*currentInstr_)->getOperand(2).isRegister()) ?
- (*currentInstr_)->getOperand(2).getAllocatedRegNum() :
- 0;
-
- const TargetRegisterClass* rc = mri_->getRegClass(regA);
-
- // special case: "a = b op a". If b is a temporary
- // reserved register rewrite as: "b = b op a; a = b"
- // otherwise use a temporary reserved register t and
- // rewrite as: "t = b; t = t op a; a = t"
- if (regC && regA == regC) {
- // b is a temp reserved register
- if (find(reserved_.begin(), reserved_.end(),
- regB) != reserved_.end()) {
- (*currentInstr_)->SetMachineOperandReg(0, regB);
- ++currentInstr_;
- instrAdded_ += mri_->copyRegToReg(*currentMbb_,
- currentInstr_,
- regA,
- regB,
- rc);
- --currentInstr_;
- }
- // b is just a normal register
- else {
- unsigned tempReg = getFreeTempPhysReg(rc);
- assert (tempReg &&
- "no free temp reserved physical register?");
- instrAdded_ += mri_->copyRegToReg(*currentMbb_,
- currentInstr_,
- tempReg,
- regB,
- rc);
- (*currentInstr_)->SetMachineOperandReg(0, tempReg);
- (*currentInstr_)->SetMachineOperandReg(1, tempReg);
- ++currentInstr_;
- instrAdded_ += mri_->copyRegToReg(*currentMbb_,
- currentInstr_,
- regA,
- tempReg,
- rc);
- --currentInstr_;
- }
- }
- // "a = b op c" gets rewritten to "a = b; a = a op c"
- else {
- instrAdded_ += mri_->copyRegToReg(*currentMbb_,
- currentInstr_,
- regA,
- regB,
- rc);
- (*currentInstr_)->SetMachineOperandReg(1, regA);
- }
- }