mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-24 08:18:33 +00:00
Handle more complex array indexing expressions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1424 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -180,26 +180,59 @@ const Type *ConvertableToGEP(const Type *Ty, Value *OffsetVal,
|
|||||||
unsigned ElSize = TD.getTypeSize(ElTy);
|
unsigned ElSize = TD.getTypeSize(ElTy);
|
||||||
|
|
||||||
// See if the user is indexing into a different cell of this array...
|
// See if the user is indexing into a different cell of this array...
|
||||||
if (Offset >= ElSize) {
|
if (Scale && Scale >= ElSize) {
|
||||||
|
// A scale n*ElSize might occur if we are not stepping through
|
||||||
|
// array by one. In this case, we will have to insert math to munge
|
||||||
|
// the index.
|
||||||
|
//
|
||||||
|
unsigned ScaleAmt = Scale/ElSize;
|
||||||
|
if (Scale-ScaleAmt*ElSize)
|
||||||
|
return 0; // Didn't scale by a multiple of element size, bail out
|
||||||
|
Scale = ElSize;
|
||||||
|
|
||||||
|
unsigned Index = Offset/ElSize; // is zero unless Offset > ElSize
|
||||||
|
Offset -= Index*ElSize; // Consume part of the offset
|
||||||
|
|
||||||
|
if (BI) { // Generate code?
|
||||||
|
BasicBlock *BB = (**BI)->getParent();
|
||||||
|
if (Expr.Var->getType() != Type::UIntTy) {
|
||||||
|
CastInst *IdxCast = new CastInst(Expr.Var, Type::UIntTy);
|
||||||
|
if (Expr.Var->hasName())
|
||||||
|
IdxCast->setName(Expr.Var->getName()+"-idxcast");
|
||||||
|
*BI = BB->getInstList().insert(*BI, IdxCast)+1;
|
||||||
|
Expr.Var = IdxCast;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Scale > ElSize) { // If we have to scale up our index, do so now
|
||||||
|
Value *ScaleAmtVal = ConstantUInt::get(Type::UIntTy, ScaleAmt);
|
||||||
|
Instruction *Scaler = BinaryOperator::create(Instruction::Mul,
|
||||||
|
Expr.Var,ScaleAmtVal);
|
||||||
|
if (Expr.Var->hasName())
|
||||||
|
Scaler->setName(Expr.Var->getName()+"-scale");
|
||||||
|
|
||||||
|
*BI = BB->getInstList().insert(*BI, Scaler)+1;
|
||||||
|
Expr.Var = Scaler;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Index) { // Add an offset to the index
|
||||||
|
Value *IndexAmt = ConstantUInt::get(Type::UIntTy, Index);
|
||||||
|
Instruction *Offseter = BinaryOperator::create(Instruction::Add,
|
||||||
|
Expr.Var, IndexAmt);
|
||||||
|
if (Expr.Var->hasName())
|
||||||
|
Offseter->setName(Expr.Var->getName()+"-offset");
|
||||||
|
*BI = BB->getInstList().insert(*BI, Offseter)+1;
|
||||||
|
Expr.Var = Offseter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Indices.push_back(Expr.Var);
|
||||||
|
Scale = 0; // Consume scale factor!
|
||||||
|
} else if (Offset >= ElSize) {
|
||||||
// Calculate the index that we are entering into the array cell with
|
// Calculate the index that we are entering into the array cell with
|
||||||
unsigned Index = Offset/ElSize;
|
unsigned Index = Offset/ElSize;
|
||||||
Indices.push_back(ConstantUInt::get(Type::UIntTy, Index));
|
Indices.push_back(ConstantUInt::get(Type::UIntTy, Index));
|
||||||
Offset -= Index*ElSize; // Consume part of the offset
|
Offset -= Index*ElSize; // Consume part of the offset
|
||||||
|
|
||||||
} else if (Scale && Scale != 1) {
|
|
||||||
// Must be indexing into this element with a variable...
|
|
||||||
if (Scale != ElSize)
|
|
||||||
return 0; // Type must not be finished yet...
|
|
||||||
|
|
||||||
if (Expr.Var->getType() != Type::UIntTy && BI) {
|
|
||||||
BasicBlock *BB = (**BI)->getParent();
|
|
||||||
CastInst *IdxCast = new CastInst(Expr.Var, Type::UIntTy);
|
|
||||||
*BI = BB->getInstList().insert(*BI, IdxCast)+1;
|
|
||||||
Expr.Var = IdxCast;
|
|
||||||
}
|
|
||||||
|
|
||||||
Indices.push_back(Expr.Var);
|
|
||||||
Scale = 0; // Consume scale factor!
|
|
||||||
} else {
|
} else {
|
||||||
// Must be indexing a small amount into the first cell of the array
|
// Must be indexing a small amount into the first cell of the array
|
||||||
// Just index into element zero of the array here.
|
// Just index into element zero of the array here.
|
||||||
|
|||||||
Reference in New Issue
Block a user