Optimize frame enter/leave code in native compiler
This commit is contained in:
parent
4d14cbe3a5
commit
f7a5c94229
|
@ -0,0 +1,32 @@
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
for(int i=0; i<1000; i++)
|
||||||
|
{
|
||||||
|
float w = 0.0123 * i;
|
||||||
|
float co = cos(w), si = sin(w);
|
||||||
|
|
||||||
|
float r = co * co + si * si;
|
||||||
|
|
||||||
|
assert(fabs(r - 1) < 0.001);
|
||||||
|
|
||||||
|
assert(fabs(sqrt(w * w) - w) < 0.001);
|
||||||
|
|
||||||
|
float aw = atan2(si, co);
|
||||||
|
|
||||||
|
float co2 = cos(aw), si2 = sin(aw);
|
||||||
|
|
||||||
|
assert(fabs(co2 - co) < 0.001);
|
||||||
|
assert(fabs(si2 - si) < 0.001);
|
||||||
|
|
||||||
|
float ex = exp(w), em = exp(-w);
|
||||||
|
|
||||||
|
assert(fabs(log(ex) - w) < 0.001);
|
||||||
|
assert(fabs(log(em) + w) < 0.001);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -125,8 +125,13 @@ float exp(float f)
|
||||||
|
|
||||||
int fi = (int)ff;
|
int fi = (int)ff;
|
||||||
|
|
||||||
float fx = 0;
|
union {
|
||||||
((int*)&fx)[1] = (fi + 0x7f) << 7;
|
float f;
|
||||||
|
int i[2];
|
||||||
|
} x;
|
||||||
|
x.f = 0;
|
||||||
|
|
||||||
|
x.i[1] = (fi + 0x7f) << 7;
|
||||||
|
|
||||||
float s = F_EXP_5;
|
float s = F_EXP_5;
|
||||||
s *= g; s += F_EXP_4;
|
s *= g; s += F_EXP_4;
|
||||||
|
@ -135,7 +140,7 @@ float exp(float f)
|
||||||
s *= g; s += F_EXP_1;
|
s *= g; s += F_EXP_1;
|
||||||
s *= g; s += F_EXP_0
|
s *= g; s += F_EXP_0
|
||||||
|
|
||||||
return s * fx;
|
return s * x.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define F_LOG_0 -2.79423993
|
#define F_LOG_0 -2.79423993
|
||||||
|
@ -150,12 +155,17 @@ float log(float f)
|
||||||
if (f == 0.0)
|
if (f == 0.0)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
|
|
||||||
float fx = f;
|
union {
|
||||||
int ei = ((int*)&fx)[1];
|
float f;
|
||||||
int ex = (ei >> 7) - 0x7f;
|
int i[2];
|
||||||
((int*)&fx)[1] = (ei & 0x007f) | 0x3f80;
|
} x;
|
||||||
|
|
||||||
float g = fx;
|
x.f = f;
|
||||||
|
int ei = x.i[1];
|
||||||
|
int ex = (ei >> 7) - 0x7f;
|
||||||
|
x.i[1] = (ei & 0x007f) | 0x3f80;
|
||||||
|
|
||||||
|
float g = x.f;
|
||||||
|
|
||||||
float fex = ex;
|
float fex = ex;
|
||||||
|
|
||||||
|
|
|
@ -11910,25 +11910,50 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
if (!(mGenerator->mCompilerOptions & COPT_NATIVE))
|
if (!(mGenerator->mCompilerOptions & COPT_NATIVE))
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea));
|
||||||
|
|
||||||
|
bool ignoreExpandCommonFrame = false;
|
||||||
|
|
||||||
if (mNoFrame)
|
if (mNoFrame)
|
||||||
{
|
{
|
||||||
if (mStackExpand > 0)
|
if (mStackExpand > 0)
|
||||||
{
|
{
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, mStackExpand & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCS, ASMIM_RELATIVE, 2));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
ignoreExpandCommonFrame = true;
|
||||||
|
|
||||||
if (tempSave)
|
if (tempSave)
|
||||||
{
|
{
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||||
|
if (tempSave == 1)
|
||||||
|
{
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
}
|
||||||
|
else if (tempSave == 2)
|
||||||
|
{
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + 1));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (commonFrameSize > 0)
|
||||||
|
{
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
||||||
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
if (tempSave > 1)
|
|
||||||
{
|
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
}
|
}
|
||||||
|
@ -11975,9 +12000,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proc->mLeafProcedure)
|
if (!proc->mLeafProcedure && commonFrameSize > 0 && !ignoreExpandCommonFrame)
|
||||||
{
|
|
||||||
if (commonFrameSize > 0)
|
|
||||||
{
|
{
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
|
@ -11986,11 +12009,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
||||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!proc->mLeafProcedure && commonFrameSize > 0)
|
|
||||||
{
|
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
||||||
|
@ -12006,12 +12025,34 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
if (tempSave)
|
if (tempSave)
|
||||||
{
|
{
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||||
|
if (tempSave == 1)
|
||||||
|
{
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||||
|
}
|
||||||
|
else if (tempSave == 2)
|
||||||
|
{
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + 1));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (commonFrameSize > 0)
|
||||||
|
{
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||||
if (tempSave > 1)
|
|
||||||
{
|
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||||
}
|
}
|
||||||
|
@ -12019,11 +12060,10 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
|
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, mStackExpand & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCC, ASMIM_RELATIVE, 2));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
|
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue