Fix a bug in the X86 ABI. The size of a struct is different from the size of a

pointer to that struct...
This commit is contained in:
Frits van Bommel 2009-03-06 21:15:13 +01:00
parent 1c6c4bc361
commit 5af82ee8d3
4 changed files with 46 additions and 7 deletions

View file

@ -133,9 +133,9 @@ struct X86_struct_to_register : ABIRewrite
const LLType* t = LLIntegerType::get(dty->size()*8); const LLType* t = LLIntegerType::get(dty->size()*8);
DtoLoad(DtoBitCast(mem, getPtrToType(t))); DtoLoad(DtoBitCast(mem, getPtrToType(t)));
} }
const LLType* type(Type*, const LLType* t) const LLType* type(Type* t, const LLType*)
{ {
size_t sz = getTypePaddedSize(t)*8; size_t sz = t->size()*8;
return LLIntegerType::get(sz); return LLIntegerType::get(sz);
} }
}; };
@ -178,6 +178,7 @@ struct X86TargetABI : TargetABI
// complex {re,im} -> {im,re} // complex {re,im} -> {im,re}
if (rt->iscomplex()) if (rt->iscomplex())
{ {
Logger::println("Rewriting complex return value");
fty->ret->rewrite = &swapComplex; fty->ret->rewrite = &swapComplex;
} }
@ -186,10 +187,12 @@ struct X86TargetABI : TargetABI
// mark this/nested params inreg // mark this/nested params inreg
if (fty->arg_this) if (fty->arg_this)
{ {
Logger::println("Putting 'this' in register");
fty->arg_this->attrs = llvm::Attribute::InReg; fty->arg_this->attrs = llvm::Attribute::InReg;
} }
else if (fty->arg_nest) else if (fty->arg_nest)
{ {
Logger::println("Putting context ptr in register");
fty->arg_nest->attrs = llvm::Attribute::InReg; fty->arg_nest->attrs = llvm::Attribute::InReg;
} }
// otherwise try to mark the last param inreg // otherwise try to mark the last param inreg
@ -206,6 +209,7 @@ struct X86TargetABI : TargetABI
if (last->byref && !last->isByVal()) if (last->byref && !last->isByVal())
{ {
Logger::println("Putting last (byref) parameter in register");
last->attrs |= llvm::Attribute::InReg; last->attrs |= llvm::Attribute::InReg;
} }
else if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) // right? else if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) // right?

View file

@ -373,6 +373,16 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
else else
{ {
Logger::println("doing normal arguments"); Logger::println("doing normal arguments");
if (Logger::enabled()) {
Logger::println("Arguments so far: (%d)", (int)args.size());
Logger::indent();
for (size_t i = 0; i < args.size(); i++) {
Logger::cout() << *args[i] << '\n';
}
Logger::undent();
Logger::cout() << "Function type: " << tf->toChars() << '\n';
Logger::cout() << "LLVM functype: " << *callable->getType() << '\n';
}
size_t n = Argument::dim(tf->parameters); size_t n = Argument::dim(tf->parameters);
@ -386,9 +396,19 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
assert(fnarg); assert(fnarg);
DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
if (Logger::enabled()) {
Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n';
Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n';
}
// give the ABI a say // give the ABI a say
LLValue* arg = tf->fty->putParam(argval->getType(), i, argval); LLValue* arg = tf->fty->putParam(argval->getType(), i, argval);
if (Logger::enabled()) {
Logger::cout() << "Argument after ABI: " << *arg << '\n';
Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n';
}
int j = tf->fty->reverseParams ? beg + n - i - 1 : beg + i; int j = tf->fty->reverseParams ? beg + n - i - 1 : beg + i;
// Hack around LDC assuming structs are in memory: // Hack around LDC assuming structs are in memory:

View file

@ -578,7 +578,7 @@ LLValue* DtoBitCast(LLValue* v, const LLType* t, const char* name)
{ {
if (v->getType() == t) if (v->getType() == t)
return v; return v;
assert(!(isaStruct(t) || isaStruct(v->getType()))); assert(!isaStruct(t));
return gIR->ir->CreateBitCast(v, t, name ? name : "tmp"); return gIR->ir->CreateBitCast(v, t, name ? name : "tmp");
} }

View file

@ -3,6 +3,7 @@
#include "gen/tollvm.h" #include "gen/tollvm.h"
#include "gen/abi.h" #include "gen/abi.h"
#include "gen/dvalue.h" #include "gen/dvalue.h"
#include "gen/logger.h"
#include "ir/irfunction.h" #include "ir/irfunction.h"
#include <sstream> #include <sstream>
@ -27,32 +28,44 @@ IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, unsigned a)
llvm::Value* IrFuncTy::putRet(Type* dty, DValue* val) llvm::Value* IrFuncTy::putRet(Type* dty, DValue* val)
{ {
assert(!arg_sret); assert(!arg_sret);
if (ret->rewrite) if (ret->rewrite) {
Logger::println("Rewrite: putRet");
LOG_SCOPE
return ret->rewrite->put(dty, val); return ret->rewrite->put(dty, val);
}
return val->getRVal(); return val->getRVal();
} }
llvm::Value* IrFuncTy::getRet(Type* dty, DValue* val) llvm::Value* IrFuncTy::getRet(Type* dty, DValue* val)
{ {
assert(!arg_sret); assert(!arg_sret);
if (ret->rewrite) if (ret->rewrite) {
Logger::println("Rewrite: getRet");
LOG_SCOPE
return ret->rewrite->get(dty, val); return ret->rewrite->get(dty, val);
}
return val->getRVal(); return val->getRVal();
} }
llvm::Value* IrFuncTy::putParam(Type* dty, int idx, DValue* val) llvm::Value* IrFuncTy::putParam(Type* dty, int idx, DValue* val)
{ {
assert(idx >= 0 && idx < args.size() && "invalid putParam"); assert(idx >= 0 && idx < args.size() && "invalid putParam");
if (args[idx]->rewrite) if (args[idx]->rewrite) {
Logger::println("Rewrite: putParam");
LOG_SCOPE
return args[idx]->rewrite->put(dty, val); return args[idx]->rewrite->put(dty, val);
}
return val->getRVal(); return val->getRVal();
} }
llvm::Value* IrFuncTy::getParam(Type* dty, int idx, DValue* val) llvm::Value* IrFuncTy::getParam(Type* dty, int idx, DValue* val)
{ {
assert(idx >= 0 && idx < args.size() && "invalid getParam"); assert(idx >= 0 && idx < args.size() && "invalid getParam");
if (args[idx]->rewrite) if (args[idx]->rewrite) {
Logger::println("Rewrite: getParam (get)");
LOG_SCOPE
return args[idx]->rewrite->get(dty, val); return args[idx]->rewrite->get(dty, val);
}
return val->getRVal(); return val->getRVal();
} }
@ -62,6 +75,8 @@ void IrFuncTy::getParam(Type* dty, int idx, DValue* val, llvm::Value* lval)
if (args[idx]->rewrite) if (args[idx]->rewrite)
{ {
Logger::println("Rewrite: getParam (getL)");
LOG_SCOPE
args[idx]->rewrite->getL(dty, val, lval); args[idx]->rewrite->getL(dty, val, lval);
return; return;
} }