Code beautification, no functional changes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6459 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Misha Brukman 2003-05-31 06:22:37 +00:00
parent 162421522b
commit b3fabe0c83
2 changed files with 386 additions and 410 deletions

View File

@ -98,13 +98,13 @@ public:
toAsm << "\n\t.section "; toAsm << "\n\t.section ";
switch (S) switch (S)
{ {
default: assert(0 && "Bad section name!"); default: assert(0 && "Bad section name!");
case Text: toAsm << "\".text\""; break; case Text: toAsm << "\".text\""; break;
case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break; case ReadOnlyData: toAsm << "\".rodata\",#alloc"; break;
case InitRWData: toAsm << "\".data\",#alloc,#write"; break; case InitRWData: toAsm << "\".data\",#alloc,#write"; break;
case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break; case ZeroInitRWData: toAsm << "\".bss\",#alloc,#write"; break;
} }
toAsm << "\n"; toAsm << "\n";
} }
@ -118,18 +118,16 @@ public:
if (isdigit(S[0])) if (isdigit(S[0]))
Result = "ll"; Result = "ll";
for (unsigned i = 0; i < S.size(); ++i) for (unsigned i = 0; i < S.size(); ++i) {
{ char C = S[i];
char C = S[i]; if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C)) Result += C;
Result += C; else {
else Result += '_';
{ Result += char('0' + ((unsigned char)C >> 4));
Result += '_'; Result += char('0' + (C & 0xF));
Result += char('0' + ((unsigned char)C >> 4));
Result += char('0' + (C & 0xF));
}
} }
}
return Result; return Result;
} }
@ -190,15 +188,15 @@ public:
const TargetMachine& target) { const TargetMachine& target) {
string S; string S;
switch(CE->getOpcode()) { switch(CE->getOpcode()) {
case Instruction::GetElementPtr: case Instruction::GetElementPtr: {
{ // generate a symbolic expression for the byte address // generate a symbolic expression for the byte address
const Value* ptrVal = CE->getOperand(0); const Value* ptrVal = CE->getOperand(0);
std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end()); std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
const TargetData &TD = target.getTargetData(); const TargetData &TD = target.getTargetData();
S += "(" + valToExprString(ptrVal, target) + ") + (" S += "(" + valToExprString(ptrVal, target) + ") + ("
+ utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")"; + utostr(TD.getIndexedOffset(ptrVal->getType(),idxVec)) + ")";
break; break;
} }
case Instruction::Cast: case Instruction::Cast:
// Support only non-converting casts for now, i.e., a no-op. // Support only non-converting casts for now, i.e., a no-op.
@ -351,27 +349,22 @@ SparcFunctionAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
unsigned int unsigned int
SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI, SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI,
unsigned int opNum) unsigned int opNum)
{ {
const MachineOperand& mop = MI->getOperand(opNum); const MachineOperand& mop = MI->getOperand(opNum);
if (OpIsBranchTargetLabel(MI, opNum)) if (OpIsBranchTargetLabel(MI, opNum)) {
{ PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode()); return 2;
return 2; } else if (OpIsMemoryAddressBase(MI, opNum)) {
} toAsm << "[";
else if (OpIsMemoryAddressBase(MI, opNum)) PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
{ toAsm << "]";
toAsm << "["; return 2;
PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode()); } else {
toAsm << "]"; printOneOperand(mop, MI->getOpCode());
return 2; return 1;
} }
else
{
printOneOperand(mop, MI->getOpCode());
return 1;
}
} }
void void
@ -392,52 +385,50 @@ SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
needBitsFlag = false; needBitsFlag = false;
switch (mop.getType()) switch (mop.getType())
{ {
case MachineOperand::MO_VirtualRegister: case MachineOperand::MO_VirtualRegister:
case MachineOperand::MO_CCRegister: case MachineOperand::MO_CCRegister:
case MachineOperand::MO_MachineRegister: case MachineOperand::MO_MachineRegister: {
{ int regNum = (int)mop.getAllocatedRegNum();
int regNum = (int)mop.getAllocatedRegNum();
if (regNum == Target.getRegInfo().getInvalidRegNum()) { if (regNum == Target.getRegInfo().getInvalidRegNum()) {
// better to print code with NULL registers than to die // better to print code with NULL registers than to die
toAsm << "<NULL VALUE>"; toAsm << "<NULL VALUE>";
} else { } else {
toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum); toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum);
}
break;
}
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;
}
case MachineOperand::MO_SignExtendedImmed:
toAsm << mop.getImmedValue();
break;
case MachineOperand::MO_UnextendedImmed:
toAsm << (uint64_t) mop.getImmedValue();
break;
default:
toAsm << mop; // use dump field
break;
} }
break;
}
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;
}
case MachineOperand::MO_SignExtendedImmed:
toAsm << mop.getImmedValue();
break;
case MachineOperand::MO_UnextendedImmed:
toAsm << (uint64_t) mop.getImmedValue();
break;
default:
toAsm << mop; // use dump field
break;
}
if (needBitsFlag) if (needBitsFlag)
toAsm << ")"; toAsm << ")";
@ -450,7 +441,7 @@ SparcFunctionAsmPrinter::emitMachineInst(const MachineInstr *MI)
unsigned Opcode = MI->getOpCode(); unsigned Opcode = MI->getOpCode();
if (Target.getInstrInfo().isDummyPhiInstr(Opcode)) if (Target.getInstrInfo().isDummyPhiInstr(Opcode))
return; // IGNORE PHI NODES return; // Ignore Phi nodes
toAsm << "\t" << Target.getInstrInfo().getName(Opcode) << "\t"; toAsm << "\t" << Target.getInstrInfo().getName(Opcode) << "\t";
@ -460,7 +451,7 @@ SparcFunctionAsmPrinter::emitMachineInst(const MachineInstr *MI)
unsigned N = 1; unsigned N = 1;
for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N) for (unsigned OpNum = 0; OpNum < MI->getNumOperands(); OpNum += N)
if (! ((1 << OpNum) & Mask)) { // Ignore this operand? if (! ((1 << OpNum) & Mask)) { // Ignore this operand?
if (NeedComma) toAsm << ", "; // Handle comma outputing if (NeedComma) toAsm << ", "; // Handle comma outputing
NeedComma = true; NeedComma = true;
N = printOperands(MI, OpNum); N = printOperands(MI, OpNum);
} else } else
@ -667,12 +658,11 @@ TypeToSize(const Type* type, const TargetMachine& target)
inline unsigned int inline unsigned int
ConstantToSize(const Constant* CV, const TargetMachine& target) ConstantToSize(const Constant* CV, const TargetMachine& target)
{ {
if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV)) if (const ConstantArray* CVA = dyn_cast<ConstantArray>(CV)) {
{ const ArrayType *aty = cast<ArrayType>(CVA->getType());
const ArrayType *aty = cast<ArrayType>(CVA->getType()); if (ArrayTypeIsString(aty))
if (ArrayTypeIsString(aty)) return 1 + CVA->getNumOperands();
return 1 + CVA->getNumOperands(); }
}
return TypeToSize(CV->getType(), target); return TypeToSize(CV->getType(), target);
} }
@ -727,46 +717,40 @@ SparcModuleAsmPrinter::printSingleConstantValue(const Constant* CV)
toAsm << "\t" << TypeToDataDirective(CV->getType()) << "\t"; toAsm << "\t" << TypeToDataDirective(CV->getType()) << "\t";
if (CV->getType()->isPrimitiveType()) if (CV->getType()->isPrimitiveType()) {
{ if (CV->getType()->isFloatingPoint()) {
if (CV->getType()->isFloatingPoint()) { // FP Constants are printed as integer constants to avoid losing
// FP Constants are printed as integer constants to avoid losing // precision...
// precision... double Val = cast<ConstantFP>(CV)->getValue();
double Val = cast<ConstantFP>(CV)->getValue(); if (CV->getType() == Type::FloatTy) {
if (CV->getType() == Type::FloatTy) { float FVal = (float)Val;
float FVal = (float)Val; char *ProxyPtr = (char*)&FVal; // Abide by C TBAA rules
char *ProxyPtr = (char*)&FVal; // Abide by C TBAA rules toAsm << *(unsigned int*)ProxyPtr;
toAsm << *(unsigned int*)ProxyPtr; } else if (CV->getType() == Type::DoubleTy) {
} else if (CV->getType() == Type::DoubleTy) { char *ProxyPtr = (char*)&Val; // Abide by C TBAA rules
char *ProxyPtr = (char*)&Val; // Abide by C TBAA rules toAsm << *(uint64_t*)ProxyPtr;
toAsm << *(uint64_t*)ProxyPtr;
} else {
assert(0 && "Unknown floating point type!");
}
toAsm << "\t! " << CV->getType()->getDescription()
<< " value: " << Val << "\n";
} else { } else {
WriteAsOperand(toAsm, CV, false, false) << "\n"; assert(0 && "Unknown floating point type!");
} }
toAsm << "\t! " << CV->getType()->getDescription()
<< " value: " << Val << "\n";
} else {
WriteAsOperand(toAsm, CV, false, false) << "\n";
} }
else if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV)) } else if (const ConstantPointerRef* CPR = dyn_cast<ConstantPointerRef>(CV)) {
{ // This is a constant address for a global variable or method. // This is a constant address for a global variable or method.
// Use the name of the variable or method as the address value. // Use the name of the variable or method as the address value.
toAsm << getID(CPR->getValue()) << "\n"; toAsm << getID(CPR->getValue()) << "\n";
} } else if (isa<ConstantPointerNull>(CV)) {
else if (isa<ConstantPointerNull>(CV)) // Null pointer value
{ // Null pointer value toAsm << "0\n";
toAsm << "0\n"; } else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) {
} // Constant expression built from operators, constants, and symbolic addrs
else if (const ConstantExpr* CE = dyn_cast<ConstantExpr>(CV)) toAsm << ConstantExprToString(CE, Target) << "\n";
{ // Constant expression built from operators, constants, and symbolic addrs } else {
toAsm << ConstantExprToString(CE, Target) << "\n"; assert(0 && "Unknown elementary type for constant");
} }
else
{
assert(0 && "Unknown elementary type for constant");
}
} }
void void
@ -775,11 +759,10 @@ SparcModuleAsmPrinter::PrintZeroBytesToPad(int numBytes)
for ( ; numBytes >= 8; numBytes -= 8) for ( ; numBytes >= 8; numBytes -= 8)
printSingleConstantValue(Constant::getNullValue(Type::ULongTy)); printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
if (numBytes >= 4) if (numBytes >= 4) {
{ printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
printSingleConstantValue(Constant::getNullValue(Type::UIntTy)); numBytes -= 4;
numBytes -= 4; }
}
while (numBytes--) while (numBytes--)
printSingleConstantValue(Constant::getNullValue(Type::UByteTy)); printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
@ -793,41 +776,37 @@ SparcModuleAsmPrinter::printConstantValueOnly(const Constant* CV,
{ {
const ConstantArray *CVA = dyn_cast<ConstantArray>(CV); const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
if (CVA && isStringCompatible(CVA)) if (CVA && isStringCompatible(CVA)) {
{ // print the string alone and return // print the string alone and return
toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
} } else if (CVA) {
else if (CVA) // Not a string. Print the values in successive locations
{ // Not a string. Print the values in successive locations const std::vector<Use> &constValues = CVA->getValues();
const std::vector<Use> &constValues = CVA->getValues(); for (unsigned i=0; i < constValues.size(); i++)
for (unsigned i=0; i < constValues.size(); i++) printConstantValueOnly(cast<Constant>(constValues[i].get()));
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!
else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) const StructLayout *cvsLayout =
{ // Print the fields in successive locations. Pad to align if needed! Target.getTargetData().getStructLayout(CVS->getType());
const StructLayout *cvsLayout = const std::vector<Use>& constValues = CVS->getValues();
Target.getTargetData().getStructLayout(CVS->getType()); unsigned sizeSoFar = 0;
const std::vector<Use>& constValues = CVS->getValues(); for (unsigned i=0, N = constValues.size(); i < N; i++) {
unsigned sizeSoFar = 0; const Constant* field = cast<Constant>(constValues[i].get());
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. // Check if padding is needed and insert one or more 0s.
unsigned fieldSize = unsigned fieldSize =
Target.getTargetData().getTypeSize(field->getType()); Target.getTargetData().getTypeSize(field->getType());
int padSize = ((i == N-1? cvsLayout->StructSize int padSize = ((i == N-1? cvsLayout->StructSize
: cvsLayout->MemberOffsets[i+1]) : cvsLayout->MemberOffsets[i+1])
- cvsLayout->MemberOffsets[i]) - fieldSize; - cvsLayout->MemberOffsets[i]) - fieldSize;
sizeSoFar += (fieldSize + padSize); sizeSoFar += (fieldSize + padSize);
// Now print the actual field value // Now print the actual field value
printConstantValueOnly(field, padSize); printConstantValueOnly(field, padSize);
}
assert(sizeSoFar == cvsLayout->StructSize &&
"Layout of constant struct may be incorrect!");
} }
else assert(sizeSoFar == cvsLayout->StructSize &&
"Layout of constant struct may be incorrect!");
} else
printSingleConstantValue(CV); printSingleConstantValue(CV);
if (numPadBytesAfter) if (numPadBytesAfter)
@ -847,12 +826,12 @@ SparcModuleAsmPrinter::printConstant(const Constant* CV, string valID)
// Print .size and .type only if it is not a string. // Print .size and .type only if it is not a string.
const ConstantArray *CVA = dyn_cast<ConstantArray>(CV); const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
if (CVA && isStringCompatible(CVA)) if (CVA && isStringCompatible(CVA)) {
{ // print it as a string and return // print it as a string and return
toAsm << valID << ":\n"; toAsm << valID << ":\n";
toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
return; return;
} }
toAsm << "\t.type" << "\t" << valID << ",#object\n"; toAsm << "\t.type" << "\t" << valID << ",#object\n";

View File

@ -1445,22 +1445,19 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// Let's check for chain rules outside the switch so that we don't have // 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 // to duplicate the list of chain rule production numbers here again
// //
if (ThisIsAChainRule(ruleForNode)) if (ThisIsAChainRule(ruleForNode)) {
{ // Chain rules have a single nonterminal on the RHS.
// Chain rules have a single nonterminal on the RHS. // Get the rule that matches the RHS non-terminal and use that instead.
// Get the rule that matches the RHS non-terminal and use that instead. //
// assert(nts[0] && ! nts[1]
assert(nts[0] && ! nts[1] && "A chain rule should have only one RHS non-terminal!");
&& "A chain rule should have only one RHS non-terminal!"); nextRule = burm_rule(subtreeRoot->state, nts[0]);
nextRule = burm_rule(subtreeRoot->state, nts[0]); nts = burm_nts[nextRule];
nts = burm_nts[nextRule]; GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec);
GetInstructionsByRule(subtreeRoot, nextRule, nts, target, mvec); } else {
} switch(ruleForNode) {
else case 1: // stmt: Ret
{ case 2: // stmt: RetValue(reg)
switch(ruleForNode) {
case 1: // stmt: Ret
case 2: // stmt: RetValue(reg)
{ // NOTE: Prepass of register allocation is responsible { // NOTE: Prepass of register allocation is responsible
// for moving return value to appropriate register. // for moving return value to appropriate register.
// Mark the return-address register as a hidden virtual reg. // Mark the return-address register as a hidden virtual reg.
@ -1486,24 +1483,24 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 3: // stmt: Store(reg,reg) case 3: // stmt: Store(reg,reg)
case 4: // stmt: Store(reg,ptrreg) case 4: // stmt: Store(reg,ptrreg)
SetOperandsForMemInstr(ChooseStoreInstruction( SetOperandsForMemInstr(ChooseStoreInstruction(
subtreeRoot->leftChild()->getValue()->getType()), subtreeRoot->leftChild()->getValue()->getType()),
mvec, subtreeRoot, target); mvec, subtreeRoot, target);
break; break;
case 5: // stmt: BrUncond case 5: // stmt: BrUncond
{ {
BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction()); BranchInst *BI = cast<BranchInst>(subtreeRoot->getInstruction());
mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(0))); mvec.push_back(BuildMI(V9::BA, 1).addPCDisp(BI->getSuccessor(0)));
// delay slot // delay slot
mvec.push_back(BuildMI(V9::NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
case 206: // stmt: BrCond(setCCconst) case 206: // stmt: BrCond(setCCconst)
{ // setCCconst => boolean was computed with `%b = setCC type reg1 const' { // setCCconst => boolean was computed with `%b = setCC type reg1 const'
// If the constant is ZERO, we can use the branch-on-integer-register // If the constant is ZERO, we can use the branch-on-integer-register
// instructions and avoid the SUBcc instruction entirely. // instructions and avoid the SUBcc instruction entirely.
@ -1519,37 +1516,37 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|| isa<PointerType>(constVal->getType())) || isa<PointerType>(constVal->getType()))
&& GetConstantValueAsSignedInt(constVal, isValidConst) == 0 && GetConstantValueAsSignedInt(constVal, isValidConst) == 0
&& isValidConst) && isValidConst)
{ {
// That constant is a zero after all... // That constant is a zero after all...
// Use the left child of setCC as the first argument! // Use the left child of setCC as the first argument!
// Mark the setCC node so that no code is generated for it. // Mark the setCC node so that no code is generated for it.
InstructionNode* setCCNode = (InstructionNode*) InstructionNode* setCCNode = (InstructionNode*)
subtreeRoot->leftChild(); subtreeRoot->leftChild();
assert(setCCNode->getOpLabel() == SetCCOp); assert(setCCNode->getOpLabel() == SetCCOp);
setCCNode->markFoldedIntoParent(); setCCNode->markFoldedIntoParent();
BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction()); BranchInst* brInst=cast<BranchInst>(subtreeRoot->getInstruction());
M = BuildMI(ChooseBprInstruction(subtreeRoot), 2) M = BuildMI(ChooseBprInstruction(subtreeRoot), 2)
.addReg(setCCNode->leftChild()->getValue()) .addReg(setCCNode->leftChild()->getValue())
.addPCDisp(brInst->getSuccessor(0)); .addPCDisp(brInst->getSuccessor(0));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
mvec.push_back(BuildMI(V9::NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
// false branch // false branch
mvec.push_back(BuildMI(V9::BA, 1) mvec.push_back(BuildMI(V9::BA, 1)
.addPCDisp(brInst->getSuccessor(1))); .addPCDisp(brInst->getSuccessor(1)));
// delay slot // delay slot
mvec.push_back(BuildMI(V9::NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
// ELSE FALL THROUGH // ELSE FALL THROUGH
} }
case 6: // stmt: BrCond(setCC) case 6: // stmt: BrCond(setCC)
{ // bool => boolean was computed with SetCC. { // bool => boolean was computed with SetCC.
// The branch to use depends on whether it is FP, signed, or unsigned. // 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 // If it is an integer CC, we also need to find the unique
@ -1562,7 +1559,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
brInst->getParent()->getParent(), brInst->getParent()->getParent(),
isFPBranch? Type::FloatTy : Type::IntTy); isFPBranch? Type::FloatTy : Type::IntTy);
M = BuildMI(Opcode, 2).addCCReg(ccValue) M = BuildMI(Opcode, 2).addCCReg(ccValue)
.addPCDisp(brInst->getSuccessor(0)); .addPCDisp(brInst->getSuccessor(0));
mvec.push_back(M); mvec.push_back(M);
// delay slot // delay slot
@ -1575,8 +1572,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
mvec.push_back(BuildMI(V9::NOP, 0)); mvec.push_back(BuildMI(V9::NOP, 0));
break; break;
} }
case 208: // stmt: BrCond(boolconst) case 208: // stmt: BrCond(boolconst)
{ {
// boolconst => boolean is a constant; use BA to first or second label // boolconst => boolean is a constant; use BA to first or second label
Constant* constVal = Constant* constVal =
@ -1592,7 +1589,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 8: // stmt: BrCond(boolreg) case 8: // stmt: BrCond(boolreg)
{ // boolreg => boolean is stored in an existing register. { // boolreg => boolean is stored in an existing register.
// Just use the branch-on-integer-register instruction! // Just use the branch-on-integer-register instruction!
// //
@ -1612,26 +1609,26 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 9: // stmt: Switch(reg) case 9: // stmt: Switch(reg)
assert(0 && "*** SWITCH instruction is not implemented yet."); assert(0 && "*** SWITCH instruction is not implemented yet.");
break; break;
case 10: // reg: VRegList(reg, reg) case 10: // reg: VRegList(reg, reg)
assert(0 && "VRegList should never be the topmost non-chain rule"); assert(0 && "VRegList should never be the topmost non-chain rule");
break; break;
case 21: // bool: Not(bool,reg): Both these are implemented as: case 21: // bool: Not(bool,reg): Both these are implemented as:
case 421: // reg: BNot(reg,reg): reg = reg XOR-NOT 0 case 421: // reg: BNot(reg,reg): reg = reg XOR-NOT 0
{ // First find the unary operand. It may be left or right, usually right. { // First find the unary operand. It may be left or right, usually right.
Value* notArg = BinaryOperator::getNotArgument( Value* notArg = BinaryOperator::getNotArgument(
cast<BinaryOperator>(subtreeRoot->getInstruction())); cast<BinaryOperator>(subtreeRoot->getInstruction()));
unsigned ZeroReg = target.getRegInfo().getZeroRegNum(); unsigned ZeroReg = target.getRegInfo().getZeroRegNum();
mvec.push_back(BuildMI(V9::XNORr, 3).addReg(notArg).addMReg(ZeroReg) mvec.push_back(BuildMI(V9::XNORr, 3).addReg(notArg).addMReg(ZeroReg)
.addRegDef(subtreeRoot->getValue())); .addRegDef(subtreeRoot->getValue()));
break; break;
} }
case 22: // reg: ToBoolTy(reg): case 22: // reg: ToBoolTy(reg):
{ {
const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
assert(opType->isIntegral() || isa<PointerType>(opType)); assert(opType->isIntegral() || isa<PointerType>(opType));
@ -1639,12 +1636,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 23: // reg: ToUByteTy(reg) case 23: // reg: ToUByteTy(reg)
case 24: // reg: ToSByteTy(reg) case 24: // reg: ToSByteTy(reg)
case 25: // reg: ToUShortTy(reg) case 25: // reg: ToUShortTy(reg)
case 26: // reg: ToShortTy(reg) case 26: // reg: ToShortTy(reg)
case 27: // reg: ToUIntTy(reg) case 27: // reg: ToUIntTy(reg)
case 28: // reg: ToIntTy(reg) case 28: // reg: ToIntTy(reg)
{ {
//====================================================================== //======================================================================
// Rules for integer conversions: // Rules for integer conversions:
@ -1711,8 +1708,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 29: // reg: ToULongTy(reg) case 29: // reg: ToULongTy(reg)
case 30: // reg: ToLongTy(reg) case 30: // reg: ToLongTy(reg)
{ {
Value* opVal = subtreeRoot->leftChild()->getValue(); Value* opVal = subtreeRoot->leftChild()->getValue();
const Type* opType = opVal->getType(); const Type* opType = opVal->getType();
@ -1727,106 +1724,106 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 31: // reg: ToFloatTy(reg): case 31: // reg: ToFloatTy(reg):
case 32: // reg: ToDoubleTy(reg): case 32: // reg: ToDoubleTy(reg):
case 232: // reg: ToDoubleTy(Constant): case 232: // reg: ToDoubleTy(Constant):
// If this instruction has a parent (a user) in the tree // If this instruction has a parent (a user) in the tree
// and the user is translated as an FsMULd instruction, // and the user is translated as an FsMULd instruction,
// then the cast is unnecessary. So check that first. // then the cast is unnecessary. So check that first.
// In the future, we'll want to do the same for the FdMULq instruction, // 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). // so do the check here instead of only for ToFloatTy(reg).
// //
if (subtreeRoot->parent() != NULL) { if (subtreeRoot->parent() != NULL) {
const MachineCodeForInstruction& mcfi = const MachineCodeForInstruction& mcfi =
MachineCodeForInstruction::get( MachineCodeForInstruction::get(
cast<InstructionNode>(subtreeRoot->parent())->getInstruction()); cast<InstructionNode>(subtreeRoot->parent())->getInstruction());
if (mcfi.size() == 0 || mcfi.front()->getOpCode() == V9::FSMULD) if (mcfi.size() == 0 || mcfi.front()->getOpCode() == V9::FSMULD)
forwardOperandNum = 0; // forward first operand to user forwardOperandNum = 0; // forward first operand to user
} }
if (forwardOperandNum != 0) { // we do need the cast if (forwardOperandNum != 0) { // we do need the cast
Value* leftVal = subtreeRoot->leftChild()->getValue(); Value* leftVal = subtreeRoot->leftChild()->getValue();
const Type* opType = leftVal->getType(); const Type* opType = leftVal->getType();
MachineOpCode opCode=ChooseConvertToFloatInstr( MachineOpCode opCode=ChooseConvertToFloatInstr(
subtreeRoot->getOpLabel(), opType); subtreeRoot->getOpLabel(), opType);
if (opCode == V9::INVALID_OPCODE) { // no conversion needed if (opCode == V9::INVALID_OPCODE) { // no conversion needed
forwardOperandNum = 0; // forward first operand to user forwardOperandNum = 0; // forward first operand to user
} else { } else {
// If the source operand is a non-FP type it must be // If the source operand is a non-FP type it must be
// first copied from int to float register via memory! // first copied from int to float register via memory!
Instruction *dest = subtreeRoot->getInstruction(); Instruction *dest = subtreeRoot->getInstruction();
Value* srcForCast; Value* srcForCast;
int n = 0; int n = 0;
if (! opType->isFloatingPoint()) { if (! opType->isFloatingPoint()) {
// Create a temporary to represent the FP register // Create a temporary to represent the FP register
// into which the integer will be copied via memory. // into which the integer will be copied via memory.
// The type of this temporary will determine the FP // The type of this temporary will determine the FP
// register used: single-prec for a 32-bit int or smaller, // register used: single-prec for a 32-bit int or smaller,
// double-prec for a 64-bit int. // double-prec for a 64-bit int.
// //
uint64_t srcSize = uint64_t srcSize =
target.getTargetData().getTypeSize(leftVal->getType()); target.getTargetData().getTypeSize(leftVal->getType());
Type* tmpTypeToUse = Type* tmpTypeToUse =
(srcSize <= 4)? Type::FloatTy : Type::DoubleTy; (srcSize <= 4)? Type::FloatTy : Type::DoubleTy;
srcForCast = new TmpInstruction(tmpTypeToUse, dest); srcForCast = new TmpInstruction(tmpTypeToUse, dest);
MachineCodeForInstruction &destMCFI = MachineCodeForInstruction &destMCFI =
MachineCodeForInstruction::get(dest); MachineCodeForInstruction::get(dest);
destMCFI.addTemp(srcForCast); destMCFI.addTemp(srcForCast);
target.getInstrInfo().CreateCodeToCopyIntToFloat(target, target.getInstrInfo().CreateCodeToCopyIntToFloat(target,
dest->getParent()->getParent(), dest->getParent()->getParent(),
leftVal, cast<Instruction>(srcForCast), leftVal, cast<Instruction>(srcForCast),
mvec, destMCFI); mvec, destMCFI);
} else } else
srcForCast = leftVal; srcForCast = leftVal;
M = BuildMI(opCode, 2).addReg(srcForCast).addRegDef(dest); 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); mvec.push_back(M);
break;
} }
// ELSE FALL THROUGH }
break;
case 33: // reg: Add(reg, reg)
maskUnsignedResult = true; case 19: // reg: ToArrayTy(reg):
Add3OperandInstr(ChooseAddInstruction(subtreeRoot), subtreeRoot, mvec); 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; break;
}
case 234: // reg: Sub(reg, Constant) // ELSE FALL THROUGH
maskUnsignedResult = true;
M = CreateSubConstInstruction(subtreeRoot);
if (M != NULL) {
mvec.push_back(M);
break;
}
// ELSE FALL THROUGH
case 34: // reg: Sub(reg, reg) case 33: // reg: Add(reg, reg)
maskUnsignedResult = true; maskUnsignedResult = true;
Add3OperandInstr(ChooseSubInstructionByType( Add3OperandInstr(ChooseAddInstruction(subtreeRoot), subtreeRoot, mvec);
break;
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(
subtreeRoot->getInstruction()->getType()), subtreeRoot->getInstruction()->getType()),
subtreeRoot, mvec); subtreeRoot, mvec);
break; break;
case 135: // reg: Mul(todouble, todouble) case 135: // reg: Mul(todouble, todouble)
checkCast = true; checkCast = true;
// FALL THROUGH // FALL THROUGH
case 35: // reg: Mul(reg, reg) case 35: // reg: Mul(reg, reg)
{ {
maskUnsignedResult = true; maskUnsignedResult = true;
MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot)) MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
@ -1840,11 +1837,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
MachineCodeForInstruction::get(mulInstr),forceOp); MachineCodeForInstruction::get(mulInstr),forceOp);
break; break;
} }
case 335: // reg: Mul(todouble, todoubleConst) case 335: // reg: Mul(todouble, todoubleConst)
checkCast = true; checkCast = true;
// FALL THROUGH // FALL THROUGH
case 235: // reg: Mul(reg, Constant) case 235: // reg: Mul(reg, Constant)
{ {
maskUnsignedResult = true; maskUnsignedResult = true;
MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot)) MachineOpCode forceOp = ((checkCast && BothFloatToDouble(subtreeRoot))
@ -1859,22 +1856,22 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
forceOp); forceOp);
break; break;
} }
case 236: // reg: Div(reg, Constant) case 236: // reg: Div(reg, Constant)
maskUnsignedResult = true; maskUnsignedResult = true;
L = mvec.size(); L = mvec.size();
CreateDivConstInstruction(target, subtreeRoot, mvec); CreateDivConstInstruction(target, subtreeRoot, mvec);
if (mvec.size() > L) if (mvec.size() > L)
break;
// ELSE FALL THROUGH
case 36: // reg: Div(reg, reg)
maskUnsignedResult = true;
Add3OperandInstr(ChooseDivInstruction(target, subtreeRoot),
subtreeRoot, mvec);
break; break;
// ELSE FALL THROUGH
case 36: // reg: Div(reg, reg)
maskUnsignedResult = true;
Add3OperandInstr(ChooseDivInstruction(target, subtreeRoot),
subtreeRoot, mvec);
break;
case 37: // reg: Rem(reg, reg) case 37: // reg: Rem(reg, reg)
case 237: // reg: Rem(reg, Constant) case 237: // reg: Rem(reg, Constant)
{ {
maskUnsignedResult = true; maskUnsignedResult = true;
Instruction* remInstr = subtreeRoot->getInstruction(); Instruction* remInstr = subtreeRoot->getInstruction();
@ -1908,15 +1905,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 38: // bool: And(bool, bool) case 38: // bool: And(bool, bool)
case 238: // bool: And(bool, boolconst) case 238: // bool: And(bool, boolconst)
case 338: // reg : BAnd(reg, reg) case 338: // reg : BAnd(reg, reg)
case 538: // reg : BAnd(reg, Constant) case 538: // reg : BAnd(reg, Constant)
Add3OperandInstr(V9::ANDr, subtreeRoot, mvec); Add3OperandInstr(V9::ANDr, subtreeRoot, mvec);
break; break;
case 138: // bool: And(bool, not) case 138: // bool: And(bool, not)
case 438: // bool: BAnd(bool, bnot) case 438: // bool: BAnd(bool, bnot)
{ // Use the argument of NOT as the second argument! { // Use the argument of NOT as the second argument!
// Mark the NOT node so that no code is generated for it. // Mark the NOT node so that no code is generated for it.
InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild(); InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild();
@ -1930,15 +1927,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 39: // bool: Or(bool, bool) case 39: // bool: Or(bool, bool)
case 239: // bool: Or(bool, boolconst) case 239: // bool: Or(bool, boolconst)
case 339: // reg : BOr(reg, reg) case 339: // reg : BOr(reg, reg)
case 539: // reg : BOr(reg, Constant) case 539: // reg : BOr(reg, Constant)
Add3OperandInstr(V9::ORr, subtreeRoot, mvec); Add3OperandInstr(V9::ORr, subtreeRoot, mvec);
break; break;
case 139: // bool: Or(bool, not) case 139: // bool: Or(bool, not)
case 439: // bool: BOr(bool, bnot) case 439: // bool: BOr(bool, bnot)
{ // Use the argument of NOT as the second argument! { // Use the argument of NOT as the second argument!
// Mark the NOT node so that no code is generated for it. // Mark the NOT node so that no code is generated for it.
InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild(); InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild();
@ -1952,15 +1949,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 40: // bool: Xor(bool, bool) case 40: // bool: Xor(bool, bool)
case 240: // bool: Xor(bool, boolconst) case 240: // bool: Xor(bool, boolconst)
case 340: // reg : BXor(reg, reg) case 340: // reg : BXor(reg, reg)
case 540: // reg : BXor(reg, Constant) case 540: // reg : BXor(reg, Constant)
Add3OperandInstr(V9::XORr, subtreeRoot, mvec); Add3OperandInstr(V9::XORr, subtreeRoot, mvec);
break; break;
case 140: // bool: Xor(bool, not) case 140: // bool: Xor(bool, not)
case 440: // bool: BXor(bool, bnot) case 440: // bool: BXor(bool, bnot)
{ // Use the argument of NOT as the second argument! { // Use the argument of NOT as the second argument!
// Mark the NOT node so that no code is generated for it. // Mark the NOT node so that no code is generated for it.
InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild(); InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild();
@ -1974,13 +1971,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 41: // boolconst: SetCC(reg, Constant) case 41: // boolconst: SetCC(reg, Constant)
// //
// If the SetCC was folded into the user (parent), it will be // If the SetCC was folded into the user (parent), it will be
// caught above. All other cases are the same as case 42, // caught above. All other cases are the same as case 42,
// so just fall through. // so just fall through.
// //
case 42: // bool: SetCC(reg, reg): case 42: // bool: SetCC(reg, reg):
{ {
// This generates a SUBCC instruction, putting the difference in // This generates a SUBCC instruction, putting the difference in
// a result register, and setting a condition code. // a result register, and setting a condition code.
@ -2087,21 +2084,21 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 51: // reg: Load(reg) case 51: // reg: Load(reg)
case 52: // reg: Load(ptrreg) case 52: // reg: Load(ptrreg)
SetOperandsForMemInstr(ChooseLoadInstruction( SetOperandsForMemInstr(ChooseLoadInstruction(
subtreeRoot->getValue()->getType()), subtreeRoot->getValue()->getType()),
mvec, subtreeRoot, target); mvec, subtreeRoot, target);
break; break;
case 55: // reg: GetElemPtr(reg) case 55: // reg: GetElemPtr(reg)
case 56: // reg: GetElemPtrIdx(reg,reg) case 56: // reg: GetElemPtrIdx(reg,reg)
// If the GetElemPtr was folded into the user (parent), it will be // If the GetElemPtr was folded into the user (parent), it will be
// caught above. For other cases, we have to compute the address. // caught above. For other cases, we have to compute the address.
SetOperandsForMemInstr(V9::ADDr, mvec, subtreeRoot, target); SetOperandsForMemInstr(V9::ADDr, mvec, subtreeRoot, target);
break; break;
case 57: // reg: Alloca: Implement as 1 instruction: case 57: // reg: Alloca: Implement as 1 instruction:
{ // add %fp, offsetFromFP -> result { // add %fp, offsetFromFP -> result
AllocationInst* instr = AllocationInst* instr =
cast<AllocationInst>(subtreeRoot->getInstruction()); cast<AllocationInst>(subtreeRoot->getInstruction());
@ -2112,7 +2109,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 58: // reg: Alloca(reg): Implement as 3 instructions: case 58: // reg: Alloca(reg): Implement as 3 instructions:
// mul num, typeSz -> tmp // mul num, typeSz -> tmp
// sub %sp, tmp -> %sp // sub %sp, tmp -> %sp
{ // add %sp, frameSizeBelowDynamicArea -> result { // add %sp, frameSizeBelowDynamicArea -> result
@ -2140,7 +2137,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 61: // reg: Call case 61: // reg: Call
{ // Generate a direct (CALL) or indirect (JMPL) call. { // Generate a direct (CALL) or indirect (JMPL) call.
// Mark the return-address register, the indirection // Mark the return-address register, the indirection
// register (for indirect calls), the operands of the Call, // register (for indirect calls), the operands of the Call,
@ -2257,7 +2254,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 62: // reg: Shl(reg, reg) case 62: // reg: Shl(reg, reg)
{ {
Value* argVal1 = subtreeRoot->leftChild()->getValue(); Value* argVal1 = subtreeRoot->leftChild()->getValue();
Value* argVal2 = subtreeRoot->rightChild()->getValue(); Value* argVal2 = subtreeRoot->rightChild()->getValue();
@ -2274,7 +2271,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 63: // reg: Shr(reg, reg) case 63: // reg: Shr(reg, reg)
{ {
const Type* opType = subtreeRoot->leftChild()->getValue()->getType(); const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
assert((opType->isInteger() || isa<PointerType>(opType)) && assert((opType->isInteger() || isa<PointerType>(opType)) &&
@ -2286,10 +2283,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 64: // reg: Phi(reg,reg) case 64: // reg: Phi(reg,reg)
break; // don't forward the value break; // don't forward the value
case 65: // reg: VaArg(reg) case 65: // reg: VaArg(reg)
{ {
// Use value initialized by va_start as pointer to args on the stack. // Use value initialized by va_start as pointer to args on the stack.
// Load argument via current pointer value, then increment pointer. // Load argument via current pointer value, then increment pointer.
@ -2302,15 +2299,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
break; break;
} }
case 71: // reg: VReg case 71: // reg: VReg
case 72: // reg: Constant case 72: // reg: Constant
break; // don't forward the value break; // don't forward the value
default: default:
assert(0 && "Unrecognized BURG rule"); assert(0 && "Unrecognized BURG rule");
break; break;
}
} }
}
if (forwardOperandNum >= 0) { if (forwardOperandNum >= 0) {
// We did not generate a machine instruction but need to use operand. // We did not generate a machine instruction but need to use operand.