mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
Reverting previous beautification changes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6464 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f86d635e20
commit
af9fd51da2
@ -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;
|
||||
} else {
|
||||
assert(0 && "Unknown floating point type!");
|
||||
}
|
||||
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 {
|
||||
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";
|
||||
}
|
||||
assert(sizeSoFar == cvsLayout->StructSize &&
|
||||
"Layout of constant struct may be incorrect!");
|
||||
} else
|
||||
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!");
|
||||
}
|
||||
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";
|
||||
|
||||
|
@ -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;
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
{ // 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);
|
||||
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,
|
||||
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 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 19: // reg: ToArrayTy(reg):
|
||||
case 20: // reg: ToPointerTy(reg):
|
||||
forwardOperandNum = 0; // forward first operand to user
|
||||
break;
|
||||
}
|
||||
// ELSE FALL THROUGH
|
||||
|
||||
case 233: // reg: Add(reg, Constant)
|
||||
maskUnsignedResult = true;
|
||||
M = CreateAddConstInstruction(subtreeRoot);
|
||||
if (M != NULL) {
|
||||
mvec.push_back(M);
|
||||
break;
|
||||
}
|
||||
// ELSE FALL THROUGH
|
||||
|
||||
case 34: // reg: Sub(reg, reg)
|
||||
maskUnsignedResult = true;
|
||||
Add3OperandInstr(ChooseSubInstructionByType(
|
||||
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);
|
||||
break;
|
||||
}
|
||||
// ELSE FALL THROUGH
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case 138: // bool: And(bool, not)
|
||||
case 438: // bool: BAnd(bool, bnot)
|
||||
case 138: // bool: And(bool, not)
|
||||
case 438: // bool: BAnd(bool, bnot)
|
||||
{ // Use the argument of NOT as the second argument!
|
||||
// Mark the NOT node so that no code is generated for it.
|
||||
InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild();
|
||||
@ -1927,15 +1930,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 39: // bool: Or(bool, bool)
|
||||
case 239: // bool: Or(bool, boolconst)
|
||||
case 339: // reg : BOr(reg, reg)
|
||||
case 539: // reg : BOr(reg, Constant)
|
||||
Add3OperandInstr(V9::ORr, subtreeRoot, mvec);
|
||||
break;
|
||||
case 39: // bool: Or(bool, bool)
|
||||
case 239: // bool: Or(bool, boolconst)
|
||||
case 339: // reg : BOr(reg, reg)
|
||||
case 539: // reg : BOr(reg, Constant)
|
||||
Add3OperandInstr(V9::ORr, subtreeRoot, mvec);
|
||||
break;
|
||||
|
||||
case 139: // bool: Or(bool, not)
|
||||
case 439: // bool: BOr(bool, bnot)
|
||||
case 139: // bool: Or(bool, not)
|
||||
case 439: // bool: BOr(bool, bnot)
|
||||
{ // Use the argument of NOT as the second argument!
|
||||
// Mark the NOT node so that no code is generated for it.
|
||||
InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild();
|
||||
@ -1949,15 +1952,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 40: // bool: Xor(bool, bool)
|
||||
case 240: // bool: Xor(bool, boolconst)
|
||||
case 340: // reg : BXor(reg, reg)
|
||||
case 540: // reg : BXor(reg, Constant)
|
||||
Add3OperandInstr(V9::XORr, subtreeRoot, mvec);
|
||||
break;
|
||||
case 40: // bool: Xor(bool, bool)
|
||||
case 240: // bool: Xor(bool, boolconst)
|
||||
case 340: // reg : BXor(reg, reg)
|
||||
case 540: // reg : BXor(reg, Constant)
|
||||
Add3OperandInstr(V9::XORr, subtreeRoot, mvec);
|
||||
break;
|
||||
|
||||
case 140: // bool: Xor(bool, not)
|
||||
case 440: // bool: BXor(bool, bnot)
|
||||
case 140: // bool: Xor(bool, not)
|
||||
case 440: // bool: BXor(bool, bnot)
|
||||
{ // Use the argument of NOT as the second argument!
|
||||
// Mark the NOT node so that no code is generated for it.
|
||||
InstructionNode* notNode = (InstructionNode*) subtreeRoot->rightChild();
|
||||
@ -1971,13 +1974,13 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 41: // boolconst: SetCC(reg, Constant)
|
||||
//
|
||||
// If the SetCC was folded into the user (parent), it will be
|
||||
// caught above. All other cases are the same as case 42,
|
||||
// so just fall through.
|
||||
//
|
||||
case 42: // bool: SetCC(reg, reg):
|
||||
case 41: // boolconst: SetCC(reg, Constant)
|
||||
//
|
||||
// If the SetCC was folded into the user (parent), it will be
|
||||
// caught above. All other cases are the same as case 42,
|
||||
// so just fall through.
|
||||
//
|
||||
case 42: // bool: SetCC(reg, reg):
|
||||
{
|
||||
// This generates a SUBCC instruction, putting the difference in
|
||||
// a result register, and setting a condition code.
|
||||
@ -2084,21 +2087,21 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 51: // reg: Load(reg)
|
||||
case 52: // reg: Load(ptrreg)
|
||||
case 51: // reg: Load(reg)
|
||||
case 52: // reg: Load(ptrreg)
|
||||
SetOperandsForMemInstr(ChooseLoadInstruction(
|
||||
subtreeRoot->getValue()->getType()),
|
||||
mvec, subtreeRoot, target);
|
||||
break;
|
||||
|
||||
case 55: // reg: GetElemPtr(reg)
|
||||
case 56: // reg: GetElemPtrIdx(reg,reg)
|
||||
// If the GetElemPtr was folded into the user (parent), it will be
|
||||
// caught above. For other cases, we have to compute the address.
|
||||
SetOperandsForMemInstr(V9::ADDr, mvec, subtreeRoot, target);
|
||||
break;
|
||||
case 55: // reg: GetElemPtr(reg)
|
||||
case 56: // reg: GetElemPtrIdx(reg,reg)
|
||||
// If the GetElemPtr was folded into the user (parent), it will be
|
||||
// caught above. For other cases, we have to compute the address.
|
||||
SetOperandsForMemInstr(V9::ADDr, mvec, subtreeRoot, target);
|
||||
break;
|
||||
|
||||
case 57: // reg: Alloca: Implement as 1 instruction:
|
||||
case 57: // reg: Alloca: Implement as 1 instruction:
|
||||
{ // add %fp, offsetFromFP -> result
|
||||
AllocationInst* instr =
|
||||
cast<AllocationInst>(subtreeRoot->getInstruction());
|
||||
@ -2109,7 +2112,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 58: // reg: Alloca(reg): Implement as 3 instructions:
|
||||
case 58: // reg: Alloca(reg): Implement as 3 instructions:
|
||||
// mul num, typeSz -> tmp
|
||||
// sub %sp, tmp -> %sp
|
||||
{ // add %sp, frameSizeBelowDynamicArea -> result
|
||||
@ -2137,7 +2140,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 61: // reg: Call
|
||||
case 61: // reg: Call
|
||||
{ // Generate a direct (CALL) or indirect (JMPL) call.
|
||||
// Mark the return-address register, the indirection
|
||||
// register (for indirect calls), the operands of the Call,
|
||||
@ -2254,7 +2257,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 62: // reg: Shl(reg, reg)
|
||||
case 62: // reg: Shl(reg, reg)
|
||||
{
|
||||
Value* argVal1 = subtreeRoot->leftChild()->getValue();
|
||||
Value* argVal2 = subtreeRoot->rightChild()->getValue();
|
||||
@ -2271,7 +2274,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 63: // reg: Shr(reg, reg)
|
||||
case 63: // reg: Shr(reg, reg)
|
||||
{
|
||||
const Type* opType = subtreeRoot->leftChild()->getValue()->getType();
|
||||
assert((opType->isInteger() || isa<PointerType>(opType)) &&
|
||||
@ -2283,10 +2286,10 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 64: // reg: Phi(reg,reg)
|
||||
break; // don't forward the value
|
||||
case 64: // reg: Phi(reg,reg)
|
||||
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.
|
||||
// Load argument via current pointer value, then increment pointer.
|
||||
@ -2299,15 +2302,15 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
||||
break;
|
||||
}
|
||||
|
||||
case 71: // reg: VReg
|
||||
case 72: // reg: Constant
|
||||
break; // don't forward the value
|
||||
case 71: // reg: VReg
|
||||
case 72: // reg: Constant
|
||||
break; // don't forward the value
|
||||
|
||||
default:
|
||||
assert(0 && "Unrecognized BURG rule");
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unrecognized BURG rule");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (forwardOperandNum >= 0) {
|
||||
// We did not generate a machine instruction but need to use operand.
|
||||
|
Loading…
Reference in New Issue
Block a user