From 44f7bd9fe0e65b9620c1258db25a19d5b0d9e987 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 10 Aug 2011 21:33:56 -0600 Subject: [PATCH] fix argument alignment for Darwin/ARM --- src/arm.cpp | 12 ++++++++++++ src/arm.h | 20 ++++++++++++++------ src/assembler.h | 1 + src/compiler.cpp | 18 ++++++++---------- src/powerpc.cpp | 4 ++++ src/x86.cpp | 4 ++++ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/arm.cpp b/src/arm.cpp index e23ad3cfd1..f7a50b815a 100644 --- a/src/arm.cpp +++ b/src/arm.cpp @@ -1834,7 +1834,19 @@ class MyArchitecture: public Assembler::Architecture { } virtual bool argumentAlignment() { +#ifdef __APPLE__ + return false; +#else return true; +#endif + } + + virtual bool argumentRegisterAlignment() { +#ifdef __APPLE__ + return false; +#else + return true; +#endif } virtual unsigned argumentRegisterCount() { diff --git a/src/arm.h b/src/arm.h index ab97c88767..a5285f86c3 100644 --- a/src/arm.h +++ b/src/arm.h @@ -128,6 +128,12 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, unsigned argumentCount, unsigned argumentsSize UNUSED, unsigned returnType UNUSED) { +#ifdef __APPLE__ + const unsigned Alignment = 1; +#else + const unsigned Alignment = 2; +#endif + const unsigned GprCount = 4; uintptr_t gprTable[GprCount]; unsigned gprIndex = 0; @@ -140,19 +146,21 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, switch (argumentTypes[ati]) { case DOUBLE_TYPE: case INT64_TYPE: { - if (gprIndex + (8 / BytesPerWord) <= GprCount) { // pass argument on registers - if (gprIndex & 1) { // 8-byte alignment - memset(gprTable + gprIndex, 0, 4); // probably not necessary, but for good luck + if (gprIndex + Alignment <= GprCount) { // pass argument on registers + if (gprIndex % Alignment) { // 8-byte alignment + memset(gprTable + gprIndex, 0, 4); // probably not necessary, but for good luck ++gprIndex; } + memcpy(gprTable + gprIndex, arguments + ai, 8); gprIndex += 8 / BytesPerWord; - } else { // pass argument on stack + } else { // pass argument on stack gprIndex = GprCount; - if (stackIndex & 1) { // 8-byte alignment - memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck + if (stackIndex % Alignment) { // 8-byte alignment + memset(stack + stackIndex, 0, 4); // probably not necessary, but for good luck ++stackIndex; } + memcpy(stack + stackIndex, arguments + ai, 8); stackIndex += 8 / BytesPerWord; } diff --git a/src/assembler.h b/src/assembler.h index 4107d19854..4805f54e80 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -330,6 +330,7 @@ class Assembler { virtual unsigned frameFootprint(unsigned footprint) = 0; virtual unsigned argumentFootprint(unsigned footprint) = 0; virtual bool argumentAlignment() = 0; + virtual bool argumentRegisterAlignment() = 0; virtual unsigned argumentRegisterCount() = 0; virtual int argumentRegister(unsigned index) = 0; diff --git a/src/compiler.cpp b/src/compiler.cpp index a81d597beb..0b7e8d1917 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -3179,21 +3179,19 @@ class CallEvent: public Event { unsigned argumentIndex = 0; while (true) { - unsigned footprint; - if (argumentIndex + 1 < argumentCount - and s->value->nextWord == s->next->value) - { - footprint = 2; - } else { - footprint = 1; - } + unsigned footprint + = (argumentIndex + 1 < argumentCount + and s->value->nextWord == s->next->value) + ? 2 : 1; - if (footprint > 1 and index & 1 and c->arch->argumentAlignment()) { + if (index % (c->arch->argumentAlignment() ? footprint : 1)) { ++ index; } SiteMask targetMask; - if (index + footprint <= c->arch->argumentRegisterCount()) { + if (index + (c->arch->argumentRegisterAlignment() ? footprint : 1) + <= c->arch->argumentRegisterCount()) + { int number = c->arch->argumentRegister(index); if (DebugReads) { diff --git a/src/powerpc.cpp b/src/powerpc.cpp index 67a223e46a..f518dea650 100644 --- a/src/powerpc.cpp +++ b/src/powerpc.cpp @@ -2135,6 +2135,10 @@ class MyArchitecture: public Assembler::Architecture { return AlignArguments; } + virtual bool argumentRegisterAlignment() { + return true; + } + virtual unsigned argumentRegisterCount() { return 8; } diff --git a/src/x86.cpp b/src/x86.cpp index 6c4fe1f21b..670c5482d3 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -2824,6 +2824,10 @@ class MyArchitecture: public Assembler::Architecture { return false; } + virtual bool argumentRegisterAlignment() { + return false; + } + virtual unsigned argumentRegisterCount() { #ifdef PLATFORM_WINDOWS if (BytesPerWord == 8) return 4; else