mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
Implement ConstantExprs in CWriter
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3394 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -107,7 +107,8 @@ namespace {
|
|||||||
}
|
}
|
||||||
void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
|
void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
|
||||||
unsigned Indent);
|
unsigned Indent);
|
||||||
void printIndexingExpr(MemAccessInst &MAI);
|
void printIndexingExpression(Value *Ptr, User::op_iterator I,
|
||||||
|
User::op_iterator E);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +175,6 @@ ostream &CWriter::printType(const Type *Ty, const string &NameSoFar,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string Result;
|
|
||||||
switch (Ty->getPrimitiveID()) {
|
switch (Ty->getPrimitiveID()) {
|
||||||
case Type::FunctionTyID: {
|
case Type::FunctionTyID: {
|
||||||
const FunctionType *MTy = cast<FunctionType>(Ty);
|
const FunctionType *MTy = cast<FunctionType>(Ty);
|
||||||
@ -211,14 +211,7 @@ ostream &CWriter::printType(const Type *Ty, const string &NameSoFar,
|
|||||||
|
|
||||||
case Type::PointerTyID: {
|
case Type::PointerTyID: {
|
||||||
const PointerType *PTy = cast<PointerType>(Ty);
|
const PointerType *PTy = cast<PointerType>(Ty);
|
||||||
// If this is a pointer to a function, we need parens. In all other cases,
|
return printType(PTy->getElementType(), "(*" + NameSoFar + ")");
|
||||||
// we don't though, and adding them all the time clutters stuff up a ton, so
|
|
||||||
// special case this.
|
|
||||||
//
|
|
||||||
if (isa<FunctionType>(PTy->getElementType()))
|
|
||||||
return printType(PTy->getElementType(), "(*" + NameSoFar + ")");
|
|
||||||
else
|
|
||||||
return printType(PTy->getElementType(), "*" + NameSoFar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::ArrayTyID: {
|
case Type::ArrayTyID: {
|
||||||
@ -293,6 +286,35 @@ void CWriter::printConstantArray(ConstantArray *CPA) {
|
|||||||
void CWriter::printConstant(Constant *CPV) {
|
void CWriter::printConstant(Constant *CPV) {
|
||||||
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
||||||
switch (CE->getOpcode()) {
|
switch (CE->getOpcode()) {
|
||||||
|
case Instruction::Cast:
|
||||||
|
Out << "((";
|
||||||
|
printType(CPV->getType());
|
||||||
|
Out << ")";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(0)));
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Instruction::GetElementPtr:
|
||||||
|
Out << "&(";
|
||||||
|
printIndexingExpression(CPV->getOperand(0),
|
||||||
|
CPV->op_begin()+1, CPV->op_end());
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
case Instruction::Add:
|
||||||
|
Out << "(";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(0)));
|
||||||
|
Out << " + ";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(1)));
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
case Instruction::Sub:
|
||||||
|
Out << "(";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(0)));
|
||||||
|
Out << " - ";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(1)));
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::cerr << "CWriter Error: Unhandled constant expression: "
|
std::cerr << "CWriter Error: Unhandled constant expression: "
|
||||||
<< CE << "\n";
|
<< CE << "\n";
|
||||||
@ -358,6 +380,15 @@ void CWriter::printConstant(Constant *CPV) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::writeOperandInternal(Value *Operand) {
|
void CWriter::writeOperandInternal(Value *Operand) {
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(Operand))
|
||||||
|
if (isInlinableInst(*I)) {
|
||||||
|
// Should we inline this instruction to build a tree?
|
||||||
|
Out << "(";
|
||||||
|
visit(*I);
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Operand->hasName()) {
|
if (Operand->hasName()) {
|
||||||
Out << getValueName(Operand);
|
Out << getValueName(Operand);
|
||||||
} else if (Constant *CPV = dyn_cast<Constant>(Operand)) {
|
} else if (Constant *CPV = dyn_cast<Constant>(Operand)) {
|
||||||
@ -370,15 +401,6 @@ void CWriter::writeOperandInternal(Value *Operand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::writeOperand(Value *Operand) {
|
void CWriter::writeOperand(Value *Operand) {
|
||||||
if (Instruction *I = dyn_cast<Instruction>(Operand))
|
|
||||||
if (isInlinableInst(*I)) {
|
|
||||||
// Should we inline this instruction to build a tree?
|
|
||||||
Out << "(";
|
|
||||||
visit(*I);
|
|
||||||
Out << ")";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isa<GlobalVariable>(Operand))
|
if (isa<GlobalVariable>(Operand))
|
||||||
Out << "(&"; // Global variables are references as their addresses by llvm
|
Out << "(&"; // Global variables are references as their addresses by llvm
|
||||||
|
|
||||||
@ -482,9 +504,8 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
|
|||||||
|
|
||||||
for (; I != End; ++I)
|
for (; I != End; ++I)
|
||||||
if (const Type *Ty = dyn_cast<StructType>(I->second)) {
|
if (const Type *Ty = dyn_cast<StructType>(I->second)) {
|
||||||
string Name = "struct l_" + makeNameProper(I->first);
|
string Name = "struct l_" + makeNameProper(I->first);
|
||||||
Out << Name << ";\n";
|
Out << Name << ";\n";
|
||||||
|
|
||||||
TypeNames.insert(std::make_pair(Ty, Name));
|
TypeNames.insert(std::make_pair(Ty, Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -787,28 +808,45 @@ void CWriter::visitFreeInst(FreeInst &I) {
|
|||||||
Out << ")";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::printIndexingExpr(MemAccessInst &MAI) {
|
void CWriter::printIndexingExpression(Value *Ptr, User::op_iterator I,
|
||||||
MemAccessInst::op_iterator I = MAI.idx_begin(), E = MAI.idx_end();
|
User::op_iterator E) {
|
||||||
if (I == E) {
|
bool HasImplicitAddress = false;
|
||||||
// If accessing a global value with no indexing, avoid *(&GV) syndrome
|
// If accessing a global value with no indexing, avoid *(&GV) syndrome
|
||||||
if (GlobalValue *V = dyn_cast<GlobalValue>(MAI.getPointerOperand())) {
|
if (GlobalValue *V = dyn_cast<GlobalValue>(Ptr)) {
|
||||||
writeOperandInternal(V);
|
HasImplicitAddress = true;
|
||||||
return;
|
} else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Ptr)) {
|
||||||
}
|
HasImplicitAddress = true;
|
||||||
|
Ptr = CPR->getValue(); // Get to the global...
|
||||||
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOperand(MAI.getPointerOperand());
|
if (I == E) {
|
||||||
|
if (!HasImplicitAddress)
|
||||||
|
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
||||||
|
|
||||||
if (I == E) return;
|
writeOperandInternal(Ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Constant *CI = dyn_cast<Constant>(I->get());
|
||||||
|
if (HasImplicitAddress && (!CI || !CI->isNullValue()))
|
||||||
|
Out << "(&";
|
||||||
|
|
||||||
|
writeOperandInternal(Ptr);
|
||||||
|
|
||||||
|
if (HasImplicitAddress && (!CI || !CI->isNullValue()))
|
||||||
|
Out << ")";
|
||||||
|
|
||||||
// Print out the -> operator if possible...
|
// Print out the -> operator if possible...
|
||||||
const Constant *CI = dyn_cast<Constant>(I->get());
|
if (CI && CI->isNullValue() && I+1 != E) {
|
||||||
if (CI && CI->isNullValue() && I+1 != E &&
|
if ((*(I+1))->getType() == Type::UByteTy) {
|
||||||
(*(I+1))->getType() == Type::UByteTy) {
|
Out << (HasImplicitAddress ? "." : "->");
|
||||||
Out << "->field" << cast<ConstantUInt>(*(I+1))->getValue();
|
Out << "field" << cast<ConstantUInt>(*(I+1))->getValue();
|
||||||
I += 2;
|
I += 2;
|
||||||
|
} else { // Performing array indexing. Just skip the 0
|
||||||
|
++I;
|
||||||
|
}
|
||||||
|
} else if (HasImplicitAddress) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; I != E; ++I)
|
for (; I != E; ++I)
|
||||||
@ -822,18 +860,18 @@ void CWriter::printIndexingExpr(MemAccessInst &MAI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitLoadInst(LoadInst &I) {
|
void CWriter::visitLoadInst(LoadInst &I) {
|
||||||
printIndexingExpr(I);
|
printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitStoreInst(StoreInst &I) {
|
void CWriter::visitStoreInst(StoreInst &I) {
|
||||||
printIndexingExpr(I);
|
printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
|
||||||
Out << " = ";
|
Out << " = ";
|
||||||
writeOperand(I.getOperand(0));
|
writeOperand(I.getOperand(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
|
void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
|
||||||
Out << "&";
|
Out << "&";
|
||||||
printIndexingExpr(I);
|
printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -107,7 +107,8 @@ namespace {
|
|||||||
}
|
}
|
||||||
void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
|
void printBranchToBlock(BasicBlock *CurBlock, BasicBlock *SuccBlock,
|
||||||
unsigned Indent);
|
unsigned Indent);
|
||||||
void printIndexingExpr(MemAccessInst &MAI);
|
void printIndexingExpression(Value *Ptr, User::op_iterator I,
|
||||||
|
User::op_iterator E);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +175,6 @@ ostream &CWriter::printType(const Type *Ty, const string &NameSoFar,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string Result;
|
|
||||||
switch (Ty->getPrimitiveID()) {
|
switch (Ty->getPrimitiveID()) {
|
||||||
case Type::FunctionTyID: {
|
case Type::FunctionTyID: {
|
||||||
const FunctionType *MTy = cast<FunctionType>(Ty);
|
const FunctionType *MTy = cast<FunctionType>(Ty);
|
||||||
@ -211,14 +211,7 @@ ostream &CWriter::printType(const Type *Ty, const string &NameSoFar,
|
|||||||
|
|
||||||
case Type::PointerTyID: {
|
case Type::PointerTyID: {
|
||||||
const PointerType *PTy = cast<PointerType>(Ty);
|
const PointerType *PTy = cast<PointerType>(Ty);
|
||||||
// If this is a pointer to a function, we need parens. In all other cases,
|
return printType(PTy->getElementType(), "(*" + NameSoFar + ")");
|
||||||
// we don't though, and adding them all the time clutters stuff up a ton, so
|
|
||||||
// special case this.
|
|
||||||
//
|
|
||||||
if (isa<FunctionType>(PTy->getElementType()))
|
|
||||||
return printType(PTy->getElementType(), "(*" + NameSoFar + ")");
|
|
||||||
else
|
|
||||||
return printType(PTy->getElementType(), "*" + NameSoFar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::ArrayTyID: {
|
case Type::ArrayTyID: {
|
||||||
@ -293,6 +286,35 @@ void CWriter::printConstantArray(ConstantArray *CPA) {
|
|||||||
void CWriter::printConstant(Constant *CPV) {
|
void CWriter::printConstant(Constant *CPV) {
|
||||||
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
||||||
switch (CE->getOpcode()) {
|
switch (CE->getOpcode()) {
|
||||||
|
case Instruction::Cast:
|
||||||
|
Out << "((";
|
||||||
|
printType(CPV->getType());
|
||||||
|
Out << ")";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(0)));
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Instruction::GetElementPtr:
|
||||||
|
Out << "&(";
|
||||||
|
printIndexingExpression(CPV->getOperand(0),
|
||||||
|
CPV->op_begin()+1, CPV->op_end());
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
case Instruction::Add:
|
||||||
|
Out << "(";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(0)));
|
||||||
|
Out << " + ";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(1)));
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
case Instruction::Sub:
|
||||||
|
Out << "(";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(0)));
|
||||||
|
Out << " - ";
|
||||||
|
printConstant(cast<Constant>(CPV->getOperand(1)));
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::cerr << "CWriter Error: Unhandled constant expression: "
|
std::cerr << "CWriter Error: Unhandled constant expression: "
|
||||||
<< CE << "\n";
|
<< CE << "\n";
|
||||||
@ -358,6 +380,15 @@ void CWriter::printConstant(Constant *CPV) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::writeOperandInternal(Value *Operand) {
|
void CWriter::writeOperandInternal(Value *Operand) {
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(Operand))
|
||||||
|
if (isInlinableInst(*I)) {
|
||||||
|
// Should we inline this instruction to build a tree?
|
||||||
|
Out << "(";
|
||||||
|
visit(*I);
|
||||||
|
Out << ")";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Operand->hasName()) {
|
if (Operand->hasName()) {
|
||||||
Out << getValueName(Operand);
|
Out << getValueName(Operand);
|
||||||
} else if (Constant *CPV = dyn_cast<Constant>(Operand)) {
|
} else if (Constant *CPV = dyn_cast<Constant>(Operand)) {
|
||||||
@ -370,15 +401,6 @@ void CWriter::writeOperandInternal(Value *Operand) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::writeOperand(Value *Operand) {
|
void CWriter::writeOperand(Value *Operand) {
|
||||||
if (Instruction *I = dyn_cast<Instruction>(Operand))
|
|
||||||
if (isInlinableInst(*I)) {
|
|
||||||
// Should we inline this instruction to build a tree?
|
|
||||||
Out << "(";
|
|
||||||
visit(*I);
|
|
||||||
Out << ")";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isa<GlobalVariable>(Operand))
|
if (isa<GlobalVariable>(Operand))
|
||||||
Out << "(&"; // Global variables are references as their addresses by llvm
|
Out << "(&"; // Global variables are references as their addresses by llvm
|
||||||
|
|
||||||
@ -482,9 +504,8 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
|
|||||||
|
|
||||||
for (; I != End; ++I)
|
for (; I != End; ++I)
|
||||||
if (const Type *Ty = dyn_cast<StructType>(I->second)) {
|
if (const Type *Ty = dyn_cast<StructType>(I->second)) {
|
||||||
string Name = "struct l_" + makeNameProper(I->first);
|
string Name = "struct l_" + makeNameProper(I->first);
|
||||||
Out << Name << ";\n";
|
Out << Name << ";\n";
|
||||||
|
|
||||||
TypeNames.insert(std::make_pair(Ty, Name));
|
TypeNames.insert(std::make_pair(Ty, Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -787,28 +808,45 @@ void CWriter::visitFreeInst(FreeInst &I) {
|
|||||||
Out << ")";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::printIndexingExpr(MemAccessInst &MAI) {
|
void CWriter::printIndexingExpression(Value *Ptr, User::op_iterator I,
|
||||||
MemAccessInst::op_iterator I = MAI.idx_begin(), E = MAI.idx_end();
|
User::op_iterator E) {
|
||||||
if (I == E) {
|
bool HasImplicitAddress = false;
|
||||||
// If accessing a global value with no indexing, avoid *(&GV) syndrome
|
// If accessing a global value with no indexing, avoid *(&GV) syndrome
|
||||||
if (GlobalValue *V = dyn_cast<GlobalValue>(MAI.getPointerOperand())) {
|
if (GlobalValue *V = dyn_cast<GlobalValue>(Ptr)) {
|
||||||
writeOperandInternal(V);
|
HasImplicitAddress = true;
|
||||||
return;
|
} else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Ptr)) {
|
||||||
}
|
HasImplicitAddress = true;
|
||||||
|
Ptr = CPR->getValue(); // Get to the global...
|
||||||
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writeOperand(MAI.getPointerOperand());
|
if (I == E) {
|
||||||
|
if (!HasImplicitAddress)
|
||||||
|
Out << "*"; // Implicit zero first argument: '*x' is equivalent to 'x[0]'
|
||||||
|
|
||||||
if (I == E) return;
|
writeOperandInternal(Ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Constant *CI = dyn_cast<Constant>(I->get());
|
||||||
|
if (HasImplicitAddress && (!CI || !CI->isNullValue()))
|
||||||
|
Out << "(&";
|
||||||
|
|
||||||
|
writeOperandInternal(Ptr);
|
||||||
|
|
||||||
|
if (HasImplicitAddress && (!CI || !CI->isNullValue()))
|
||||||
|
Out << ")";
|
||||||
|
|
||||||
// Print out the -> operator if possible...
|
// Print out the -> operator if possible...
|
||||||
const Constant *CI = dyn_cast<Constant>(I->get());
|
if (CI && CI->isNullValue() && I+1 != E) {
|
||||||
if (CI && CI->isNullValue() && I+1 != E &&
|
if ((*(I+1))->getType() == Type::UByteTy) {
|
||||||
(*(I+1))->getType() == Type::UByteTy) {
|
Out << (HasImplicitAddress ? "." : "->");
|
||||||
Out << "->field" << cast<ConstantUInt>(*(I+1))->getValue();
|
Out << "field" << cast<ConstantUInt>(*(I+1))->getValue();
|
||||||
I += 2;
|
I += 2;
|
||||||
|
} else { // Performing array indexing. Just skip the 0
|
||||||
|
++I;
|
||||||
|
}
|
||||||
|
} else if (HasImplicitAddress) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; I != E; ++I)
|
for (; I != E; ++I)
|
||||||
@ -822,18 +860,18 @@ void CWriter::printIndexingExpr(MemAccessInst &MAI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitLoadInst(LoadInst &I) {
|
void CWriter::visitLoadInst(LoadInst &I) {
|
||||||
printIndexingExpr(I);
|
printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitStoreInst(StoreInst &I) {
|
void CWriter::visitStoreInst(StoreInst &I) {
|
||||||
printIndexingExpr(I);
|
printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
|
||||||
Out << " = ";
|
Out << " = ";
|
||||||
writeOperand(I.getOperand(0));
|
writeOperand(I.getOperand(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
|
void CWriter::visitGetElementPtrInst(GetElementPtrInst &I) {
|
||||||
Out << "&";
|
Out << "&";
|
||||||
printIndexingExpr(I);
|
printIndexingExpression(I.getPointerOperand(), I.idx_begin(), I.idx_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
Reference in New Issue
Block a user