aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/SparcV9/SparcV9AsmPrinter.cpp329
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp463
2 files changed, 408 insertions, 384 deletions
diff --git a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp
index 6001046b2f..f66b36f9be 100644
--- a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp
+++ b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp
@@ -98,13 +98,13 @@ public:
toAsm << "\n\t.section ";
switch (S)
- {
- default: assert(0 && "Bad section name!");
- case Text: toAsm << "\".text\""; break;
- case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break;
- case InitRWData: toAsm << "\".data\",#alloc,#write"; break;
- case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break;
- }
+ {
+ default: assert(0 && "Bad section name!");
+ case Text: toAsm << "\".text\""; break;
+ case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break;
+ case InitRWData: toAsm << "\".data\",#alloc,#write"; break;
+ case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break;
+ }
toAsm << "\n";
}
@@ -118,16 +118,18 @@ public:
if (isdigit(S[0]))
Result = "ll";
- for (unsigned i = 0; i < S.size(); ++i) {
- char C = S[i];
- if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
- Result += C;
- else {
- Result += '_';
- Result += char('0' + ((unsigned char)C >> 4));
- Result += char('0' + (C & 0xF));
+ for (unsigned i = 0; i < S.size(); ++i)
+ {
+ char C = S[i];
+ if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
+ Result += C;
+ else
+ {
+ Result += '_';
+ Result += char('0' + ((unsigned char)C >> 4));
+ Result += char('0' + (C & 0xF));
+ }
}
- }
return Result;
}
@@ -188,15 +190,15 @@ public:
const TargetMachine& target) {
string S;
switch(CE->getOpcode()) {
- case Instruction::GetElementPtr: {
- // generate a symbolic expression for the byte address
- const Value* ptrVal = CE->getOperand(0);
- std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
- const TargetData &TD = target.getTargetData();
- S += "(" + valToExprString(ptrVal, target) + ") + ("
- + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
- break;
- }
+ case Instruction::GetElementPtr:
+ { // generate a symbolic expression for the byte address
+ const Value* ptrVal = CE->getOperand(0);
+ std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
+ const TargetData &TD = target.getTargetData();
+ S += "(" + valToExprString(ptrVal, target) + ") + ("
+ + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
+ break;
+ }
case Instruction::Cast:
// Support only non-converting casts for now, i.e., a no-op.
@@ -349,22 +351,27 @@ SparcFunctionAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
unsigned int
SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI,
- unsigned int opNum)
+ unsigned int opNum)
{
const MachineOperand& mop = MI->getOperand(opNum);
- if (OpIsBranchTargetLabel(MI, opNum)) {
- PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
- return 2;
- } else if (OpIsMemoryAddressBase(MI, opNum)) {
- toAsm << "[";
- PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
- toAsm << "]";
- return 2;
- } else {
- printOneOperand(mop, MI->getOpCode());
- return 1;
- }
+ if (OpIsBranchTargetLabel(MI, opNum))
+ {
+ PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
+ return 2;
+ }
+ else if (OpIsMemoryAddressBase(MI, opNum))
+ {
+ toAsm << "[";
+ PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
+ toAsm << "]";
+ return 2;
+ }
+ else
+ {
+ printOneOperand(mop, MI->getOpCode());
+ return 1;
+ }
}
void
@@ -385,50 +392,52 @@ SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
needBitsFlag = false;
switch (mop.getType())
- {
- case MachineOperand::MO_VirtualRegister:
- case MachineOperand::MO_CCRegister:
- case MachineOperand::MO_MachineRegister: {
- int regNum = (int)mop.getAllocatedRegNum();
+ {
+ case MachineOperand::MO_VirtualRegister:
+ case MachineOperand::MO_CCRegister:
+ case MachineOperand::MO_MachineRegister:
+ {
+ int regNum = (int)mop.getAllocatedRegNum();
- if (regNum == Target.getRegInfo().getInvalidRegNum()) {
- // better to print code with NULL registers than to die
- toAsm << "<NULL VALUE>";
- } else {
- toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum);
- }
- break;
- }
+ if (regNum == Target.getRegInfo().getInvalidRegNum()) {
+ // better to print code with NULL registers than to die
+ toAsm << "<NULL VALUE>";
+ } else {
+ toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum);
+ }
+ break;
+ }
- case MachineOperand::MO_PCRelativeDisp: {
- const Value *Val = mop.getVRegValue();
- assert(Val && "\tNULL Value in SparcFunctionAsmPrinter");
+ case MachineOperand::MO_PCRelativeDisp:
+ {
+ const Value *Val = mop.getVRegValue();
+ assert(Val && "\tNULL Value in SparcFunctionAsmPrinter");
- if (const BasicBlock *BB = dyn_cast<const BasicBlock>(Val))
- toAsm << getID(BB);
- else if (const Function *M = dyn_cast<Function>(Val))
- toAsm << getID(M);
- else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val))
- toAsm << getID(GV);
- else if (const Constant *CV = dyn_cast<Constant>(Val))
- toAsm << getID(CV);
- else
- assert(0 && "Unrecognized value in SparcFunctionAsmPrinter");
- break;
- }
+ if (const BasicBlock *BB = dyn_cast<const BasicBlock>(Val))
+ toAsm << getID(BB);
+ else if (const Function *M = dyn_cast<Function>(Val))
+ toAsm << getID(M);
+ else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val))
+ toAsm << getID(GV);
+ else if (const Constant *CV = dyn_cast<Constant>(Val))
+ toAsm << getID(CV);
+ else
+ assert(0 && "Unrecognized value in SparcFunctionAsmPrinter");
+ break;
+ }
- case MachineOperand::MO_SignExtendedImmed:
- toAsm << mop.getImmedValue();
- break;
+ case MachineOperand::MO_SignExtendedImmed:
+ toAsm << mop.getImmedValue();
+ break;
- case MachineOperand::MO_UnextendedImmed:
- toAsm << (uint64_t) mop.getImmedValue();
- break;
+ case MachineOperand::MO_UnextendedImmed:
+ toAsm << (uint64_t) mop.getImmedValue();
+ break;
- default:
- toAsm << mop; // use dump field
- break;
- }
+ default:
+ toAsm << mop; // use dump field
+ break;
+ }
if (needBitsFlag)
toAsm << ")";
@@ -441,7 +450,7 @@ SparcFunctionAsmPrinter::emitMachineInst(const MachineInstr *MI)
unsigned Opcode = MI->getOpCode();
if (Target.getInstrInfo().isDummyPhiInstr(Opcode))
- return; // Ignore Phi nodes
+ return; // IGNORE PHI NODES
toAsm << "\t" << Target.getInstrInfo().getName(Opcode) << "\t";
@@ -451,7 +460,7 @@ SparcFunctionAsmPrinter::emitMachineInst(const MachineInstr *MI)
unsigned N = 1;
for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N)
if (! ((1 << OpNum) & Mask)) { // Ignore this operand?
- if (NeedComma) toAsm << ", "; // Handle comma outputing
+ if (NeedComma) toAsm << ", "; // Handle comma outputing
NeedComma = true;
N = printOperands(MI, OpNum);
} else
@@ -658,11 +667,12 @@ TypeToSize(const Type* type, const TargetMachine& target)
inline unsigned int
ConstantToSize(const Constant* CV, const TargetMachine& target)
{
- if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV)) {
- const ArrayType *aty = cast<ArrayType>(CVA->getType());
- if (ArrayTypeIsString(aty))
- return 1 + CVA->getNumOperands();
- }
+ if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV))
+ {
+ const ArrayType *aty = cast<ArrayType>(CVA->getType());
+ if (ArrayTypeIsString(aty))
+ return 1 + CVA->getNumOperands();
+ }
return TypeToSize(CV->getType(), target);
}
@@ -717,40 +727,46 @@ SparcModuleAsmPrinter::printSingleConstantValue(const Constant* CV)
toAsm << "\t" << TypeToDataDirective(CV->getType()) << "\t";
- if (CV->getType()->isPrimitiveType()) {
- if (CV->getType()->isFloatingPoint()) {
- // FP Constants are printed as integer constants to avoid losing
- // precision...
- double Val = cast<ConstantFP>(CV)->getValue();
- if (CV->getType() == Type::FloatTy) {
- float FVal = (float)Val;
- char *ProxyPtr = (char*)&FVal; // Abide by C TBAA rules
- toAsm << *(unsigned int*)ProxyPtr;
- } else if (CV->getType() == Type::DoubleTy) {
- char *ProxyPtr = (char*)&Val; // Abide by C TBAA rules
- toAsm << *(uint64_t*)ProxyPtr;
+ if (CV->getType()->isPrimitiveType())
+ {
+ if (CV->getType()->isFloatingPoint()) {
+ // FP Constants are printed as integer constants to avoid losing
+ // precision...
+ double Val = cast<ConstantFP>(CV)->getValue();
+ if (CV->getType() == Type::FloatTy) {
+ float FVal = (float)Val;
+ char *ProxyPtr = (char*)&FVal; // Abide by C TBAA rules
+ toAsm << *(unsigned int*)ProxyPtr;
+ } else if (CV->getType() == Type::DoubleTy) {
+ char *ProxyPtr = (char*)&Val; // Abide by C TBAA rules
+ toAsm << *(uint64_t*)ProxyPtr;
+ } else {
+ assert(0 && "Unknown floating point type!");
+ }
+
+ toAsm << "\t! " << CV->getType()->getDescription()
+ << " value: " << Val << "\n";
} else {
- assert(0 && "Unknown floating point type!");
+ WriteAsOperand(toAsm, CV, false, false) << "\n";
}
-
- toAsm << "\t! " << CV->getType()->getDescription()
- << " value: " << Val << "\n";
- } else {
- WriteAsOperand(toAsm, CV, false, false) << "\n";
}
- } else if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV)) {
- // This is a constant address for a global variable or method.
- // Use the name of the variable or method as the address value.
- toAsm << getID(CPR->getValue()) << "\n";
- } else if (isa<ConstantPointerNull>(CV)) {
- // Null pointer value
- toAsm << "0\n";
- } else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) {
- // Constant expression built from operators, constants, and symbolic addrs
- toAsm << ConstantExprToString(CE, Target) << "\n";
- } else {
- assert(0 && "Unknown elementary type for constant");
- }
+ else if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV))
+ { // This is a constant address for a global variable or method.
+ // Use the name of the variable or method as the address value.
+ toAsm << getID(CPR->getValue()) << "\n";
+ }
+ else if (isa<ConstantPointerNull>(CV))
+ { // Null pointer value
+ toAsm << "0\n";
+ }
+ else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV))
+ { // Constant expression built from operators, constants, and symbolic addrs
+ toAsm << ConstantExprToString(CE, Target) << "\n";
+ }
+ else
+ {
+ assert(0 && "Unknown elementary type for constant");
+ }
}
void
@@ -759,10 +775,11 @@ SparcModuleAsmPrinter::PrintZeroBytesToPad(int numBytes)
for ( ; numBytes >= 8; numBytes -= 8)
printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
- if (numBytes >= 4) {
- printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
- numBytes -= 4;
- }
+ if (numBytes >= 4)
+ {
+ printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
+ numBytes -= 4;
+ }
while (numBytes--)
printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
@@ -776,37 +793,41 @@ SparcModuleAsmPrinter::printConstantValueOnly(const Constant* CV,
{
const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
- if (CVA && isStringCompatible(CVA)) {
- // print the string alone and return
- toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
- } else if (CVA) {
- // Not a string. Print the values in successive locations
- const std::vector<Use> &constValues = CVA->getValues();
- for (unsigned i=0; i < constValues.size(); i++)
- printConstantValueOnly(cast<Constant>(constValues[i].get()));
- } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
- // Print the fields in successive locations. Pad to align if needed!
- const StructLayout *cvsLayout =
- Target.getTargetData().getStructLayout(CVS->getType());
- const std::vector<Use>& constValues = CVS->getValues();
- unsigned sizeSoFar = 0;
- for (unsigned i=0, N = constValues.size(); i < N; i++) {
- const Constant* field = cast<Constant>(constValues[i].get());
-
- // Check if padding is needed and insert one or more 0s.
- unsigned fieldSize =
- Target.getTargetData().getTypeSize(field->getType());
- int padSize = ((i == N-1? cvsLayout->StructSize
- : cvsLayout->MemberOffsets[i+1])
- - cvsLayout->MemberOffsets[i]) - fieldSize;
- sizeSoFar += (fieldSize + padSize);
-
- // Now print the actual field value
- printConstantValueOnly(field, padSize);
+ if (CVA && isStringCompatible(CVA))
+ { // print the string alone and return
+ toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+ }
+ else if (CVA)
+ { // Not a string. Print the values in successive locations
+ const std::vector<Use> &constValues = CVA->getValues();
+ for (unsigned i=0; i < constValues.size(); i++)
+ printConstantValueOnly(cast<Constant>(constValues[i].get()));
+ }
+ else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
+ { // Print the fields in successive locations. Pad to align if needed!
+ const StructLayout *cvsLayout =
+ Target.getTargetData().getStructLayout(CVS->getType());
+ const std::vector<Use>& constValues = CVS->getValues();
+ unsigned sizeSoFar = 0;
+ for (unsigned i=0, N = constValues.size(); i < N; i++)
+ {
+ const Constant* field = cast<Constant>(constValues[i].get());
+
+ // Check if padding is needed and insert one or more 0s.
+ unsigned fieldSize =
+ Target.getTargetData().getTypeSize(field->getType());
+ int padSize = ((i == N-1? cvsLayout->StructSize
+ : cvsLayout->MemberOffsets[i+1])
+ - cvsLayout->MemberOffsets[i]) - fieldSize;
+ sizeSoFar += (fieldSize + padSize);
+
+ // Now print the actual field value
+ printConstantValueOnly(field, padSize);
+ }
+ assert(sizeSoFar == cvsLayout->StructSize &&
+ "Layout of constant struct may be incorrect!");
}
- assert(sizeSoFar == cvsLayout->StructSize &&
- "Layout of constant struct may be incorrect!");
- } else
+ else
printSingleConstantValue(CV);
if (numPadBytesAfter)
@@ -826,12 +847,12 @@ SparcModuleAsmPrinter::printConstant(const Constant* CV, string valID)
// Print .size and .type only if it is not a string.
const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
- if (CVA && isStringCompatible(CVA)) {
- // print it as a string and return
- toAsm << valID << ":\n";
- toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
- return;
- }
+ if (CVA && isStringCompatible(CVA))
+ { // print it as a string and return
+ toAsm << valID << ":\n";
+ toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+ return;
+ }
toAsm << "\t.type" << "\t" << valID << ",#object\n";
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index 2371a1f602..0670b4971f 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -1445,19 +1445,22 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// Let's check for chain rules outside the switch so that we don't have
// to duplicate the list of chain rule production numbers here again
//
- if (ThisIsAChainRule(ruleForNode)) {
- // Chain rules have a single nonterminal on the RHS.
- // Get the rule that matches the RHS non-terminal and use that instead.
- //
- assert(nts[0] && ! nts[1]
- && "A chain rule should have only one RHS non-terminal!");
- nextRule = burm_rule(subtreeRoot->state, nts[0]);
- nts = burm_nts[nextRule];
- GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec);
- } else {
- switch(ruleForNode) {
- case 1: // stmt: Ret
- case 2: // stmt: RetValue(reg)
+ if (ThisIsAChainRule(ruleForNode))
+ {
+ // Chain rules have a single nonterminal on the RHS.
+ // Get the rule that matches the RHS non-terminal and use that instead.
+ //
+ assert(nts[0] && ! nts[1]
+ && "A chain rule should have only one RHS non-terminal!");
+ nextRule = burm_rule(subtreeRoot->state, nts[0]);
+ nts = burm_nts[nextRule];
+ GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec);
+ }
+ else
+ {
+ switch(ruleForNode) {
+ case 1: // stmt: Ret
+ case 2: // stmt: RetValue(reg)
{ // NOTE: Prepass of register allocation is responsible
// for moving return value to appropriate register.
// Mark the return-address register as a hidden virtual reg.
@@ -1483,24 +1486,24 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
- case 3: // stmt: Store(reg,reg)
- case 4: // stmt: Store(reg,ptrreg)
- SetOperandsForMemInstr(ChooseStoreInstruction(
+ case 3: // stmt: Store(reg,reg)
+ case 4: // stmt: Store(reg,ptrreg)
+ SetOperandsForMemInstr(ChooseStoreInstruction(
subtreeRoot->leftChild()->getValue()->getType()),
mvec, subtreeRoot, target);
- break;
+ break;
- case 5: // stmt: BrUncond
- {
- BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
- mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(0)));
+ case 5: // stmt: BrUncond
+ {
+ BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
+ mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(0)));
- // delay slot
- mvec.push_back(BuildMI(V9::NOP, 0));
- break;
- }
-
- case 206: // stmt: BrCond(setCCconst)
+ // delay slot
+ mvec.push_back(BuildMI(V9::NOP, 0));
+ break;
+ }
+
+ case 206: // stmt: BrCond(setCCconst)
{ // setCCconst => boolean was computed with `%b = setCC type reg1 const'
// If the constant is ZERO, we can use the branch-on-integer-register
// instructions and avoid the SUBcc instruction entirely.
@@ -1516,37 +1519,37 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|| isa<PointerType>(constVal->getType()))
&& GetConstantValueAsSignedInt(constVal, isValidConst) == 0
&& isValidConst)
- {
- // That constant is a zero after all...
- // Use the left child of setCC as the first argument!
- // Mark the setCC node so that no code is generated for it.
- InstructionNode* setCCNode = (InstructionNode*)
- subtreeRoot->leftChild();
- assert(setCCNode->getOpLabel() == SetCCOp);
- setCCNode->markFoldedIntoParent();
+ {
+ // That constant is a zero after all...
+ // Use the left child of setCC as the first argument!
+ // Mark the setCC node so that no code is generated for it.
+ InstructionNode* setCCNode = (InstructionNode*)
+ subtreeRoot->leftChild();
+ assert(setCCNode->getOpLabel() == SetCCOp);
+ setCCNode->markFoldedIntoParent();
- BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction());
+ BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction());
- M = BuildMI(ChooseBprInstruction(subtreeRoot), 2)
- .addReg(setCCNode->leftChild()->getValue())
- .addPCDisp(brInst->getSuccessor(0));
- mvec.push_back(M);
+ M = BuildMI(ChooseBprInstruction(subtreeRoot), 2)
+ .addReg(setCCNode->leftChild()->getValue())
+ .addPCDisp(brInst->getSuccessor(0));
+ mvec.push_back(M);
- // delay slot
- mvec.push_back(BuildMI(V9::NOP, 0));
+ // delay slot
+ mvec.push_back(BuildMI(V9::NOP, 0));
- // false branch
- mvec.push_back(BuildMI(V9::BA, 1)
- .addPCDisp(brInst->getSuccessor(1)));
+ // false branch
+ mvec.push_back(BuildMI(V9::BA, 1)
+ .addPCDisp(brInst->getSuccessor(1)));
- // delay slot
- mvec.push_back(BuildMI(V9::NOP, 0));
- break;
- }
+ // delay slot
+ mvec.push_back(BuildMI(V9::NOP, 0));
+ break;
+ }
// ELSE FALL THROUGH
}
- case 6: // stmt: BrCond(setCC)
+ case 6: // stmt: BrCond(setCC)
{ // bool => boolean was computed with SetCC.
// The branch to use depends on whether it is FP, signed, or unsigned.
// If it is an integer CC, we also need to find the unique
@@ -1559,7 +1562,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
brInst->getParent()->getParent(),
isFPBranch? Type::FloatTy : Type::IntTy);
M = BuildMI(Opcode, 2).addCCReg(ccValue)
- .addPCDisp(brInst->getSuccessor(0));
+ .addPCDisp(brInst->getSuccessor(0));
mvec.push_back(M);
// delay slot
@@ -1572,8 +1575,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.push_back(BuildMI(V9::NOP, 0));
break;
}
-
- case 208: // stmt: BrCond(boolconst)
+
+ case 208: // stmt: BrCond(boolconst)
{
// boolconst => boolean is a constant; use BA to first or second label
Constant* constVal =
@@ -1589,7 +1592,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
- case 8: // stmt: BrCond(boolreg)
+ case 8: // stmt: BrCond(boolreg)
{ // boolreg => boolean is stored in an existing register.
// Just use the branch-on-integer-register instruction!
//
@@ -1609,26 +1612,26 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
- case 9: // stmt: Switch(reg)
- assert(0 && "*** SWITCH instruction is not implemented yet.");
- break;
+ case 9: // stmt: Switch(reg)
+ assert(0 && "*** SWITCH instruction is not implemented yet.");
+ break;
- case 10: // reg: VRegList(reg, reg)
- assert(0 && "VRegList should never be the topmost non-chain rule");
- break;
+ case 10: // reg: VRegList(reg, reg)
+ assert(0 && "VRegList should never be the topmost non-chain rule");
+ break;
- case 21: // bool: Not(bool,reg): Both these are implemented as:
- case 421: // reg: BNot(reg,reg): reg = reg XOR-NOT 0
+ case 21: // bool: Not(bool,reg): Both these are implemented as:
+ case 421: // reg: BNot(reg,reg): reg = reg XOR-NOT 0
{ // First find the unary operand. It may be left or right, usually right.
Value* notArg = BinaryOperator::getNotArgument(
cast<BinaryOperator>(subtreeRoot->getInstruction()));
unsigned ZeroReg = target.getRegInfo().getZeroRegNum();
mvec.push_back(BuildMI(V9::XNORr, 3).addReg(notArg).addMReg(ZeroReg)
- .addRegDef(subtreeRoot->getValue()));
+ .addRegDef(subtreeRoot->getValue()));
break;
}
- case 22: // reg: ToBoolTy(reg):
+ case 22: // reg: ToBoolTy(reg):
{
const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
assert(opType->isIntegral() || isa<PointerType>(opType));
@@ -1636,12 +1639,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
- case 23: // reg: ToUByteTy(reg)
- case 24: // reg: ToSByteTy(reg)
- case 25: // reg: ToUShortTy(reg)
- case 26: // reg: ToShortTy(reg)
- case 27: // reg: ToUIntTy(reg)
- case 28: // reg: ToIntTy(reg)
+ case 23: // reg: ToUByteTy(reg)
+ case 24: // reg: ToSByteTy(reg)
+ case 25: // reg: ToUShortTy(reg)
+ case 26: // reg: ToShortTy(reg)
+ case 27: // reg: ToUIntTy(reg)
+ case 28: // reg: ToIntTy(reg)
{
//======================================================================
// Rules for integer conversions:
@@ -1708,8 +1711,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
- case 29: // reg: ToULongTy(reg)
- case 30: // reg: ToLongTy(reg)
+ case 29: // reg: ToULongTy(reg)
+ case 30: // reg: ToLongTy(reg)
{
Value* opVal = subtreeRoot->leftChild()->getValue();
const Type* opType = opVal->getType();
@@ -1724,106 +1727,106 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
- case 31: // reg: ToFloatTy(reg):
- case 32: // reg: ToDoubleTy(reg):
- case 232: // reg: ToDoubleTy(Constant):
+ case 31: // reg: ToFloatTy(reg):
+ case 32: // reg: ToDoubleTy(reg):
+ case 232: // reg: ToDoubleTy(Constant):
- // If this instruction has a parent (a user) in the tree
- // and the user is translated as an FsMULd instruction,
- // then the cast is unnecessary. So check that first.
- // In the future, we'll want to do the same for the FdMULq instruction,
- // so do the check here instead of only for ToFloatTy(reg).
- //
- if (subtreeRoot->parent() != NULL) {
- const MachineCodeForInstruction& mcfi =
- MachineCodeForInstruction::get(
+ // If this instruction has a parent (a user) in the tree
+ // and the user is translated as an FsMULd instruction,
+ // then the cast is unnecessary. So check that first.
+ // In the future, we'll want to do the same for the FdMULq instruction,
+ // so do the check here instead of only for ToFloatTy(reg).
+ //
+ if (subtreeRoot->parent() != NULL) {
+ const MachineCodeForInstruction& mcfi =
+ MachineCodeForInstruction::get(
cast<InstructionNode>(subtreeRoot->parent())->getInstruction());
- if (mcfi.size() == 0 || mcfi.front()->getOpCode() == V9::FSMULD)
- forwardOperandNum = 0; // forward first operand to user
- }
+ if (mcfi.size() == 0 || mcfi.front()->getOpCode() == V9::FSMULD)
+ forwardOperandNum = 0; // forward first operand to user
+ }
- if (forwardOperandNum != 0) { // we do need the cast
- Value* leftVal = subtreeRoot->leftChild()->getValue();
- const Type* opType = leftVal->getType();
- MachineOpCode opCode=ChooseConvertToFloatInstr(
- subtreeRoot->getOpLabel(), opType);
- if (opCode == V9::INVALID_OPCODE) { // no conversion needed
- forwardOperandNum = 0; // forward first operand to user
- } else {
- // If the source operand is a non-FP type it must be
- // first copied from int to float register via memory!
- Instruction *dest = subtreeRoot->getInstruction();
- Value* srcForCast;
- int n = 0;
- if (! opType->isFloatingPoint()) {
- // Create a temporary to represent the FP register
- // into which the integer will be copied via memory.
- // The type of this temporary will determine the FP
- // register used: single-prec for a 32-bit int or smaller,
- // double-prec for a 64-bit int.
- //
- uint64_t srcSize =
- target.getTargetData().getTypeSize(leftVal->getType());
- Type* tmpTypeToUse =
- (srcSize <= 4)? Type::FloatTy : Type::DoubleTy;
- srcForCast = new TmpInstruction(tmpTypeToUse, dest);
- MachineCodeForInstruction &destMCFI =
- MachineCodeForInstruction::get(dest);
- destMCFI.addTemp(srcForCast);
-
- target.getInstrInfo().CreateCodeToCopyIntToFloat(target,
+ if (forwardOperandNum != 0) { // we do need the cast
+ Value* leftVal = subtreeRoot->leftChild()->getValue();
+ const Type* opType = leftVal->getType();
+ MachineOpCode opCode=ChooseConvertToFloatInstr(
+ subtreeRoot->getOpLabel(), opType);
+ if (opCode == V9::INVALID_OPCODE) { // no conversion needed
+ forwardOperandNum = 0; // forward first operand to user
+ } else {
+ // If the source operand is a non-FP type it must be
+ // first copied from int to float register via memory!
+ Instruction *dest = subtreeRoot->getInstruction();
+ Value* srcForCast;
+ int n = 0;
+ if (! opType->isFloatingPoint()) {
+ // Create a temporary to represent the FP register
+ // into which the integer will be copied via memory.
+ // The type of this temporary will determine the FP
+ // register used: single-prec for a 32-bit int or smaller,
+ // double-prec for a 64-bit int.
+ //
+ uint64_t srcSize =
+ target.getTargetData().getTypeSize(leftVal->getType());
+ Type* tmpTypeToUse =
+ (srcSize <= 4)? Type::FloatTy : Type::DoubleTy;
+ srcForCast = new TmpInstruction(tmpTypeToUse, dest);
+ MachineCodeForInstruction &destMCFI =
+ MachineCodeForInstruction::get(dest);
+ destMCFI.addTemp(srcForCast);
+
+ target.getInstrInfo().CreateCodeToCopyIntToFloat(target,
dest->getParent()->getParent(),
leftVal, cast<Instruction>(srcForCast),
mvec, destMCFI);
- } else
- srcForCast = leftVal;
-
- M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest);
- mvec.push_back(M);
+ } else
+ srcForCast = leftVal;
+
+ M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest);
+ mvec.push_back(M);
+ }
}
- }
- break;
-
- case 19: // reg: ToArrayTy(reg):
- case 20: // reg: ToPointerTy(reg):
- forwardOperandNum = 0; // forward first operand to user
- break;
-
- case 233: // reg: Add(reg, Constant)
- maskUnsignedResult = true;
- M = CreateAddConstInstruction(subtreeRoot);
- if (M != NULL) {
- mvec.push_back(M);
break;
- }
- // ELSE FALL THROUGH
+
+ case 19: // reg: ToArrayTy(reg):
+ case 20: // reg: ToPointerTy(reg):
+ forwardOperandNum = 0; // forward first operand to user
+ break;
+
+ case 233: // reg: Add(reg, Constant)
+ maskUnsignedResult = true;
+ M = CreateAddConstInstruction(subtreeRoot);
+ if (M != NULL) {
+ mvec.push_back(M);
+ break;
+ }
+ // ELSE FALL THROUGH
- case 33: // reg: Add(reg, reg)
- maskUnsignedResult = true;
- Add3OperandInstr(ChooseAddInstruction(subtreeRoot), subtreeRoot, mvec);
- break;
-
- case 234: // reg: Sub(reg, Constant)
- maskUnsignedResult = true;
- M = CreateSubConstInstruction(subtreeRoot);
- if (M != NULL) {
- mvec.push_back(M);
+ case 33: // reg: Add(reg, reg)
+ maskUnsignedResult = true;
+ Add3OperandInstr(ChooseAddInstruction(subtreeRoot), subtreeRoot, mvec);
break;
- }
- // ELSE FALL THROUGH
+
+ case 234: // reg: Sub(reg, Constant)
+ maskUnsignedResult = true;
+ M = CreateSubConstInstruction(subtreeRoot);
+ if (M != NULL) {
+ mvec.push_back(M);
+ break;
+ }
+ // ELSE FALL THROUGH
- case 34: // reg: Sub(reg, reg)
- maskUnsignedResult = true;
- Add3OperandInstr(ChooseSubInstructionByType(
+ case 34: // reg: Sub(reg, reg)
+ maskUnsignedResult = true;
+ Add3OperandInstr(ChooseSubInstructionByType(
subtreeRoot->getInstruction()->getType()),
- subtreeRoot, mvec);
- break;
+ subtreeRoot, mvec);
+ break;
- case 135: // reg: Mul(todouble, todouble)
- checkCast = true;
- // FALL THROUGH
+ case 135: // reg: Mul(todouble, todouble)
+ checkCast = true;
+ // FALL THROUGH
- case 35: // reg: Mul(reg, reg)
+ case 35: // reg: Mul(reg, reg)
{
maskUnsignedResult = true;
MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
@@ -1837,11 +1840,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
MachineCodeForInstruction::get(mulInstr),forceOp);
break;
}
- case 335: // reg: Mul(todouble, todoubleConst)
- checkCast = true;
- // FALL THROUGH
+ case 335: // reg: Mul(todouble, todoubleConst)
+ checkCast = true;
+ // FALL THROUGH
- case 235: // reg: Mul(reg, Constant)
+ case 235: // reg: Mul(reg, Constant)
{
maskUnsignedResult = true;
MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
@@ -1856,22 +1859,22 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
forceOp);
break;
}
- case 236: // reg: Div(reg, Constant)
- maskUnsignedResult = true;
- L = mvec.size();
- CreateDivConstInstruction(target, subtreeRoot, mvec);
- if (mvec.size() > L)
- break;
- // ELSE FALL THROUGH
+ case 236: // reg: Div(reg, Constant)
+ maskUnsignedResult = true;
+ L = mvec.size();
+ CreateDivConstInstruction(target, subtreeRoot, mvec);
+ if (mvec.size() > L)
+ break;
+ // ELSE FALL THROUGH
- case 36: // reg: Div(reg, reg)
- maskUnsignedResult = true;
- Add3OperandInstr(ChooseDivInstruction(target, subtreeRoot),
- subtreeRoot, mvec);
- break;
+ case 36: // reg: Div(reg, reg)
+ maskUnsignedResult = true;
+ Add3OperandInstr(ChooseDivInstruction(target, subtreeRoot),
+ subtreeRoot, mvec);
+ break;
- case 37: // reg: Rem(reg, reg)
- case 237: // reg: Rem(reg, Constant)
+ case 37: // reg: Rem(reg, reg)
+ case 237: // reg: Rem(reg, Constant)
{
maskUnsignedResult = true;
Instruction* remInstr = subtreeRoot->getInstruction();
@@ -1905,15 +1908,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break;
}
- case 38: // bool: And(bool, bool)
- case 238: // bool: And(bool, boolconst)
- case 338: // reg : BAnd(reg, reg)
- case 538: // reg : BAnd(reg, Constant)
- Add3OperandInstr(V9::ANDr, subtreeRoot, mvec);
- break;
+ case 38: // bool: And(bool, bool)
+ case 238: // bool: And(bool, boolconst)
+ case 338: // reg : BAnd(reg, reg)
+ case 538: // reg : BAnd(reg, Constant)
+ Add3OperandInstr(V9::ANDr, subtreeRoot, mvec);