fix argument alignment for Darwin/ARM

This commit is contained in:
Joel Dice 2011-08-10 21:33:56 -06:00
parent 39cffb8933
commit 44f7bd9fe0
6 changed files with 43 additions and 16 deletions

View File

@ -1834,7 +1834,19 @@ class MyArchitecture: public Assembler::Architecture {
} }
virtual bool argumentAlignment() { virtual bool argumentAlignment() {
#ifdef __APPLE__
return false;
#else
return true; return true;
#endif
}
virtual bool argumentRegisterAlignment() {
#ifdef __APPLE__
return false;
#else
return true;
#endif
} }
virtual unsigned argumentRegisterCount() { virtual unsigned argumentRegisterCount() {

View File

@ -128,6 +128,12 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned argumentCount, unsigned argumentsSize UNUSED, unsigned argumentCount, unsigned argumentsSize UNUSED,
unsigned returnType UNUSED) unsigned returnType UNUSED)
{ {
#ifdef __APPLE__
const unsigned Alignment = 1;
#else
const unsigned Alignment = 2;
#endif
const unsigned GprCount = 4; const unsigned GprCount = 4;
uintptr_t gprTable[GprCount]; uintptr_t gprTable[GprCount];
unsigned gprIndex = 0; unsigned gprIndex = 0;
@ -140,19 +146,21 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
switch (argumentTypes[ati]) { switch (argumentTypes[ati]) {
case DOUBLE_TYPE: case DOUBLE_TYPE:
case INT64_TYPE: { case INT64_TYPE: {
if (gprIndex + (8 / BytesPerWord) <= GprCount) { // pass argument on registers if (gprIndex + Alignment <= GprCount) { // pass argument on registers
if (gprIndex & 1) { // 8-byte alignment if (gprIndex % Alignment) { // 8-byte alignment
memset(gprTable + gprIndex, 0, 4); // probably not necessary, but for good luck memset(gprTable + gprIndex, 0, 4); // probably not necessary, but for good luck
++gprIndex; ++gprIndex;
} }
memcpy(gprTable + gprIndex, arguments + ai, 8); memcpy(gprTable + gprIndex, arguments + ai, 8);
gprIndex += 8 / BytesPerWord; gprIndex += 8 / BytesPerWord;
} else { // pass argument on stack } else { // pass argument on stack
gprIndex = GprCount; gprIndex = GprCount;
if (stackIndex & 1) { // 8-byte alignment if (stackIndex % Alignment) { // 8-byte alignment
memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck
++stackIndex; ++stackIndex;
} }
memcpy(stack + stackIndex, arguments + ai, 8); memcpy(stack + stackIndex, arguments + ai, 8);
stackIndex += 8 / BytesPerWord; stackIndex += 8 / BytesPerWord;
} }

View File

@ -330,6 +330,7 @@ class Assembler {
virtual unsigned frameFootprint(unsigned footprint) = 0; virtual unsigned frameFootprint(unsigned footprint) = 0;
virtual unsigned argumentFootprint(unsigned footprint) = 0; virtual unsigned argumentFootprint(unsigned footprint) = 0;
virtual bool argumentAlignment() = 0; virtual bool argumentAlignment() = 0;
virtual bool argumentRegisterAlignment() = 0;
virtual unsigned argumentRegisterCount() = 0; virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0; virtual int argumentRegister(unsigned index) = 0;

View File

@ -3179,21 +3179,19 @@ class CallEvent: public Event {
unsigned argumentIndex = 0; unsigned argumentIndex = 0;
while (true) { while (true) {
unsigned footprint; unsigned footprint
if (argumentIndex + 1 < argumentCount = (argumentIndex + 1 < argumentCount
and s->value->nextWord == s->next->value) and s->value->nextWord == s->next->value)
{ ? 2 : 1;
footprint = 2;
} else {
footprint = 1;
}
if (footprint > 1 and index & 1 and c->arch->argumentAlignment()) { if (index % (c->arch->argumentAlignment() ? footprint : 1)) {
++ index; ++ index;
} }
SiteMask targetMask; SiteMask targetMask;
if (index + footprint <= c->arch->argumentRegisterCount()) { if (index + (c->arch->argumentRegisterAlignment() ? footprint : 1)
<= c->arch->argumentRegisterCount())
{
int number = c->arch->argumentRegister(index); int number = c->arch->argumentRegister(index);
if (DebugReads) { if (DebugReads) {

View File

@ -2135,6 +2135,10 @@ class MyArchitecture: public Assembler::Architecture {
return AlignArguments; return AlignArguments;
} }
virtual bool argumentRegisterAlignment() {
return true;
}
virtual unsigned argumentRegisterCount() { virtual unsigned argumentRegisterCount() {
return 8; return 8;
} }

View File

@ -2824,6 +2824,10 @@ class MyArchitecture: public Assembler::Architecture {
return false; return false;
} }
virtual bool argumentRegisterAlignment() {
return false;
}
virtual unsigned argumentRegisterCount() { virtual unsigned argumentRegisterCount() {
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
if (BytesPerWord == 8) return 4; else if (BytesPerWord == 8) return 4; else