Optimize inline pointer parameters
This commit is contained in:
parent
d51a30ed2e
commit
a8ed15d67b
|
@ -341,3 +341,4 @@ ASALocalRun/
|
||||||
*.lbl
|
*.lbl
|
||||||
make/oscar64
|
make/oscar64
|
||||||
*.int
|
*.int
|
||||||
|
*.bcs
|
||||||
|
|
|
@ -921,6 +921,39 @@ inp_load_addr_8:
|
||||||
#pragma bytecode(BC_LOAD_ABS_8, inp_load_abs_8)
|
#pragma bytecode(BC_LOAD_ABS_8, inp_load_abs_8)
|
||||||
#pragma bytecode(BC_LOAD_ADDR_8, inp_load_abs_8.inp_load_addr_8)
|
#pragma bytecode(BC_LOAD_ADDR_8, inp_load_abs_8.inp_load_addr_8)
|
||||||
|
|
||||||
|
__asm inp_load_abs_u8
|
||||||
|
{
|
||||||
|
lda (ip), y
|
||||||
|
sta addr
|
||||||
|
iny
|
||||||
|
lda (ip), y
|
||||||
|
sta addr + 1
|
||||||
|
iny
|
||||||
|
lda (ip), y
|
||||||
|
tax
|
||||||
|
sty tmpy
|
||||||
|
ldy #0
|
||||||
|
L0:
|
||||||
|
lda (addr), y
|
||||||
|
sta $00, x
|
||||||
|
lda #0
|
||||||
|
sta $01, x
|
||||||
|
ldy tmpy
|
||||||
|
iny
|
||||||
|
jmp startup.exec
|
||||||
|
inp_load_addr_u8:
|
||||||
|
lda (ip), y
|
||||||
|
tax
|
||||||
|
iny
|
||||||
|
lda (ip), y
|
||||||
|
sty tmpy
|
||||||
|
tay
|
||||||
|
jmp L0
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_LOAD_ABS_U8, inp_load_abs_u8)
|
||||||
|
#pragma bytecode(BC_LOAD_ADDR_U8, inp_load_abs_u8.inp_load_addr_u8)
|
||||||
|
|
||||||
__asm inp_load_abs_16
|
__asm inp_load_abs_16
|
||||||
{
|
{
|
||||||
lda (ip), y
|
lda (ip), y
|
||||||
|
@ -1142,6 +1175,25 @@ __asm inp_lea_abs_index
|
||||||
|
|
||||||
#pragma bytecode(BC_LEA_ABS_INDEX, inp_lea_abs_index)
|
#pragma bytecode(BC_LEA_ABS_INDEX, inp_lea_abs_index)
|
||||||
|
|
||||||
|
__asm inp_lea_abs_index_u8
|
||||||
|
{
|
||||||
|
lda (ip), y
|
||||||
|
tax
|
||||||
|
iny
|
||||||
|
clc
|
||||||
|
lda $00, x
|
||||||
|
adc (ip), y
|
||||||
|
sta addr
|
||||||
|
iny
|
||||||
|
lda #$00
|
||||||
|
adc (ip), y
|
||||||
|
sta addr + 1
|
||||||
|
iny
|
||||||
|
jmp startup.exec
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_LEA_ABS_INDEX_U8, inp_lea_abs_index_u8)
|
||||||
|
|
||||||
__asm inp_load_local_16
|
__asm inp_load_local_16
|
||||||
{
|
{
|
||||||
lda (ip), y
|
lda (ip), y
|
||||||
|
|
|
@ -23,6 +23,7 @@ enum ByteCode
|
||||||
BC_STORE_REG_32,
|
BC_STORE_REG_32,
|
||||||
|
|
||||||
BC_LOAD_ABS_8,
|
BC_LOAD_ABS_8,
|
||||||
|
BC_LOAD_ABS_U8,
|
||||||
BC_LOAD_ABS_16,
|
BC_LOAD_ABS_16,
|
||||||
BC_LOAD_ABS_32,
|
BC_LOAD_ABS_32,
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ enum ByteCode
|
||||||
|
|
||||||
BC_LEA_ABS,
|
BC_LEA_ABS,
|
||||||
BC_LEA_ABS_INDEX,
|
BC_LEA_ABS_INDEX,
|
||||||
|
BC_LEA_ABS_INDEX_U8,
|
||||||
|
|
||||||
BC_LOAD_LOCAL_8,
|
BC_LOAD_LOCAL_8,
|
||||||
BC_LOAD_LOCAL_16,
|
BC_LOAD_LOCAL_16,
|
||||||
|
@ -50,6 +52,7 @@ enum ByteCode
|
||||||
BC_LEA_FRAME,
|
BC_LEA_FRAME,
|
||||||
|
|
||||||
BC_LOAD_ADDR_8,
|
BC_LOAD_ADDR_8,
|
||||||
|
BC_LOAD_ADDR_U8,
|
||||||
BC_LOAD_ADDR_16,
|
BC_LOAD_ADDR_16,
|
||||||
BC_LOAD_ADDR_32,
|
BC_LOAD_ADDR_32,
|
||||||
|
|
||||||
|
|
|
@ -277,6 +277,25 @@ public:
|
||||||
Grow(size, clear);
|
Grow(size, clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Reserve(int to)
|
||||||
|
{
|
||||||
|
if (to > range)
|
||||||
|
{
|
||||||
|
range = to;
|
||||||
|
|
||||||
|
T* a2 = new T[range];
|
||||||
|
if (to > size)
|
||||||
|
for (int i = 0; i < size; i++) a2[i] = array[i];
|
||||||
|
else
|
||||||
|
for (int i = 0; i < to; i++) a2[i] = array[i];
|
||||||
|
|
||||||
|
delete[] array;
|
||||||
|
array = a2;
|
||||||
|
|
||||||
|
for (int i = size; i < range; i++) array[i] = empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Clear(void)
|
void Clear(void)
|
||||||
{
|
{
|
||||||
Grow(size, true);
|
Grow(size, true);
|
||||||
|
|
|
@ -1,6 +1,171 @@
|
||||||
#include "ByteCodeGenerator.h"
|
#include "ByteCodeGenerator.h"
|
||||||
#include "Assembler.h"
|
#include "Assembler.h"
|
||||||
|
|
||||||
|
static const char* ByteCodeNames[] = {
|
||||||
|
"NOP",
|
||||||
|
"EXIT",
|
||||||
|
|
||||||
|
"CONST_8",
|
||||||
|
"CONST_P8",
|
||||||
|
"CONST_N8",
|
||||||
|
"CONST_16",
|
||||||
|
"CONST_32",
|
||||||
|
|
||||||
|
"LOAD_REG_8",
|
||||||
|
"STORE_REG_8",
|
||||||
|
"LOAD_REG_16",
|
||||||
|
"STORE_REG_16",
|
||||||
|
"ADDR_REG",
|
||||||
|
"LOAD_REG_32",
|
||||||
|
"STORE_REG_32",
|
||||||
|
|
||||||
|
"LOAD_ABS_8",
|
||||||
|
"LOAD_ABS_U8",
|
||||||
|
"LOAD_ABS_16",
|
||||||
|
"LOAD_ABS_32",
|
||||||
|
|
||||||
|
"STORE_ABS_8",
|
||||||
|
"STORE_ABS_16",
|
||||||
|
"STORE_ABS_32",
|
||||||
|
|
||||||
|
"LEA_ABS",
|
||||||
|
"LEA_ABS_INDEX",
|
||||||
|
"LEA_ABS_INDEX_U8",
|
||||||
|
|
||||||
|
"LOAD_LOCAL_8",
|
||||||
|
"LOAD_LOCAL_16",
|
||||||
|
"LOAD_LOCAL_32",
|
||||||
|
|
||||||
|
"STORE_LOCAL_8",
|
||||||
|
"STORE_LOCAL_16",
|
||||||
|
"STORE_LOCAL_32",
|
||||||
|
|
||||||
|
"LEA_LOCAL",
|
||||||
|
|
||||||
|
"STORE_FRAME_8",
|
||||||
|
"STORE_FRAME_16",
|
||||||
|
"STORE_FRAME_32",
|
||||||
|
|
||||||
|
"LEA_FRAME",
|
||||||
|
|
||||||
|
"LOAD_ADDR_8",
|
||||||
|
"LOAD_ADDR_U8",
|
||||||
|
"LOAD_ADDR_16",
|
||||||
|
"LOAD_ADDR_32",
|
||||||
|
|
||||||
|
"STORE_ADDR_8",
|
||||||
|
"STORE_ADDR_16",
|
||||||
|
"STORE_ADDR_32",
|
||||||
|
|
||||||
|
"BINOP_ADDR_16",
|
||||||
|
"BINOP_SUBR_16",
|
||||||
|
"BINOP_ANDR_16",
|
||||||
|
"BINOP_ORR_16",
|
||||||
|
"BINOP_XORR_16",
|
||||||
|
"BINOP_MULR_16",
|
||||||
|
"BINOP_DIVR_U16",
|
||||||
|
"BINOP_MODR_U16",
|
||||||
|
"BINOP_DIVR_I16",
|
||||||
|
"BINOP_MODR_I16",
|
||||||
|
"BINOP_SHLR_16",
|
||||||
|
"BINOP_SHRR_U16",
|
||||||
|
"BINOP_SHRR_I16",
|
||||||
|
|
||||||
|
"BINOP_ADDI_16",
|
||||||
|
"BINOP_SUBI_16",
|
||||||
|
"BINOP_ANDI_16",
|
||||||
|
"BINOP_ORI_16",
|
||||||
|
"BINOP_MULI8_16",
|
||||||
|
|
||||||
|
"BINOP_ADDI_8",
|
||||||
|
"BINOP_ANDI_8",
|
||||||
|
"BINOP_ORI_8",
|
||||||
|
|
||||||
|
"BINOP_SHLI_16",
|
||||||
|
"BINOP_SHRI_U16",
|
||||||
|
"BINOP_SHRI_I16",
|
||||||
|
|
||||||
|
"BINOP_CMPUR_16",
|
||||||
|
"BINOP_CMPSR_16",
|
||||||
|
|
||||||
|
"BINOP_CMPUI_16",
|
||||||
|
"BINOP_CMPSI_16",
|
||||||
|
|
||||||
|
"BINOP_CMPUR_8",
|
||||||
|
"BINOP_CMPSR_8",
|
||||||
|
|
||||||
|
"BINOP_CMPUI_8",
|
||||||
|
"BINOP_CMPSI_8",
|
||||||
|
|
||||||
|
"OP_NEGATE_16",
|
||||||
|
"OP_INVERT_16",
|
||||||
|
|
||||||
|
"BINOP_ADD_F32",
|
||||||
|
"BINOP_SUB_F32",
|
||||||
|
"BINOP_MUL_F32",
|
||||||
|
"BINOP_DIV_F32",
|
||||||
|
"BINOP_CMP_F32",
|
||||||
|
"OP_NEGATE_F32",
|
||||||
|
"OP_ABS_F32",
|
||||||
|
"OP_FLOOR_F32",
|
||||||
|
"OP_CEIL_F32",
|
||||||
|
|
||||||
|
"CONV_U16_F32",
|
||||||
|
"CONV_I16_F32",
|
||||||
|
"CONV_F32_U16",
|
||||||
|
"CONV_F32_I16",
|
||||||
|
|
||||||
|
"CONV_I8_I16",
|
||||||
|
|
||||||
|
"JUMPS",
|
||||||
|
"BRANCHS_EQ",
|
||||||
|
"BRANCHS_NE",
|
||||||
|
"BRANCHS_GT",
|
||||||
|
"BRANCHS_GE",
|
||||||
|
"BRANCHS_LT",
|
||||||
|
"BRANCHS_LE",
|
||||||
|
|
||||||
|
"JUMPF",
|
||||||
|
"BRANCHF_EQ",
|
||||||
|
"BRANCHF_NE",
|
||||||
|
"BRANCHF_GT",
|
||||||
|
"BRANCHF_GE",
|
||||||
|
"BRANCHF_LT",
|
||||||
|
"BRANCHF_LE",
|
||||||
|
|
||||||
|
"SET_EQ",
|
||||||
|
"SET_NE",
|
||||||
|
"SET_GT",
|
||||||
|
"SET_GE",
|
||||||
|
"SET_LT",
|
||||||
|
"SET_LE",
|
||||||
|
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
|
||||||
|
"NATIVE",
|
||||||
|
|
||||||
|
"ENTER",
|
||||||
|
"RETURN",
|
||||||
|
"CALL",
|
||||||
|
"PUSH_FRAME",
|
||||||
|
"POP_FRAME",
|
||||||
|
|
||||||
|
"JSR",
|
||||||
|
|
||||||
|
"COPY",
|
||||||
|
"COPY_LONG",
|
||||||
|
"STRCPY",
|
||||||
|
|
||||||
|
"EXTRT"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static ByteCode StoreTypedTmpCodes[] = {
|
static ByteCode StoreTypedTmpCodes[] = {
|
||||||
BC_NOP,
|
BC_NOP,
|
||||||
BC_STORE_REG_8,
|
BC_STORE_REG_8,
|
||||||
|
@ -70,6 +235,11 @@ bool ByteCodeInstruction::ChangesAccu(void) const
|
||||||
return ChangesRegister(BC_REG_ACCU);
|
return ChangesRegister(BC_REG_ACCU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ByteCodeInstruction::UsesAccu(void) const
|
||||||
|
{
|
||||||
|
return UsesRegister(BC_REG_ACCU);
|
||||||
|
}
|
||||||
|
|
||||||
bool ByteCodeInstruction::ChangesAddr(void) const
|
bool ByteCodeInstruction::ChangesAddr(void) const
|
||||||
{
|
{
|
||||||
return ChangesRegister(BC_REG_ADDR);
|
return ChangesRegister(BC_REG_ADDR);
|
||||||
|
@ -166,6 +336,76 @@ bool ByteCodeInstruction::StoresRegister(uint32 reg) const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ByteCodeInstruction::UsesRegister(uint32 reg) const
|
||||||
|
{
|
||||||
|
if (StoresRegister(reg))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mRegister == reg)
|
||||||
|
{
|
||||||
|
if (mCode == BC_LOAD_REG_8 || mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32 || mCode == BC_ADDR_REG || mCode == BC_LEA_ABS_INDEX || mCode == BC_LEA_ABS_INDEX_U8)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode >= BC_BINOP_ADDI_16 && mCode <= BC_BINOP_ORI_8)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode == BC_BINOP_CMPUR_16 || mCode == BC_BINOP_CMPSR_16)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode == BC_BINOP_CMPUR_8 || mCode == BC_BINOP_CMPSR_8)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_BINOP_CMP_F32)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode >= BC_BINOP_ADD_L32 && mCode <= BC_BINOP_CMP_S32)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg == BC_REG_ACCU)
|
||||||
|
{
|
||||||
|
if (mCode == BC_STORE_REG_8 || mCode == BC_STORE_REG_16 || mCode == BC_STORE_REG_32)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode >= BC_BINOP_ADDR_16 && mCode <= BC_BINOP_SHRR_I16)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_BINOP_CMPUR_16 && mCode <= BC_BINOP_CMPSI_16)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_BINOP_CMPUR_8 && mCode <= BC_BINOP_CMPSI_8)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_OP_NEGATE_16 && mCode <= BC_OP_INVERT_16)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_BINOP_ADD_F32 && mCode <= BC_OP_CEIL_F32)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_CONV_U16_F32 && mCode <= BC_CONV_F32_I16)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_I16)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
|
||||||
|
return true;
|
||||||
|
if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reg == BC_REG_ADDR)
|
||||||
|
{
|
||||||
|
if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_LOAD_ADDR_32)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_STORE_ADDR_32)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mCode == BC_JSR || mCode == BC_CALL)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
|
bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
|
||||||
{
|
{
|
||||||
if (mRegister == reg)
|
if (mRegister == reg)
|
||||||
|
@ -222,7 +462,7 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
|
||||||
return true;
|
return true;
|
||||||
if (mCode == BC_JSR || mCode == BC_CALL)
|
if (mCode == BC_JSR || mCode == BC_CALL)
|
||||||
return true;
|
return true;
|
||||||
if (mCode == BC_LEA_ABS_INDEX)
|
if (mCode == BC_LEA_ABS_INDEX || mCode == BC_LEA_ABS_INDEX_U8)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,6 +528,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BC_LOAD_ABS_8:
|
case BC_LOAD_ABS_8:
|
||||||
|
case BC_LOAD_ABS_U8:
|
||||||
case BC_LOAD_ABS_16:
|
case BC_LOAD_ABS_16:
|
||||||
case BC_LOAD_ABS_32:
|
case BC_LOAD_ABS_32:
|
||||||
case BC_STORE_ABS_8:
|
case BC_STORE_ABS_8:
|
||||||
|
@ -312,6 +553,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
||||||
|
|
||||||
case BC_LEA_ABS:
|
case BC_LEA_ABS:
|
||||||
case BC_LEA_ABS_INDEX:
|
case BC_LEA_ABS_INDEX:
|
||||||
|
case BC_LEA_ABS_INDEX_U8:
|
||||||
block->PutCode(generator, mCode); block->PutByte(mRegister);
|
block->PutCode(generator, mCode); block->PutByte(mRegister);
|
||||||
if (mRelocate)
|
if (mRelocate)
|
||||||
{
|
{
|
||||||
|
@ -497,6 +739,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case BC_LOAD_ADDR_8:
|
case BC_LOAD_ADDR_8:
|
||||||
|
case BC_LOAD_ADDR_U8:
|
||||||
case BC_LOAD_ADDR_16:
|
case BC_LOAD_ADDR_16:
|
||||||
case BC_LOAD_ADDR_32:
|
case BC_LOAD_ADDR_32:
|
||||||
case BC_STORE_ADDR_8:
|
case BC_STORE_ADDR_8:
|
||||||
|
@ -594,7 +837,7 @@ void ByteCodeBasicBlock::PutBytes(const uint8* code, int num)
|
||||||
void ByteCodeBasicBlock::PutCode(ByteCodeGenerator* generator, ByteCode code)
|
void ByteCodeBasicBlock::PutCode(ByteCodeGenerator* generator, ByteCode code)
|
||||||
{
|
{
|
||||||
PutByte(uint8(code) * 2);
|
PutByte(uint8(code) * 2);
|
||||||
generator->mByteCodeUsed[code] = true;
|
generator->mByteCodeUsed[code]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ByteCodeBasicBlock::PutBranch(ByteCodeGenerator* generator, ByteCode code, int offset)
|
int ByteCodeBasicBlock::PutBranch(ByteCodeGenerator* generator, ByteCode code, int offset)
|
||||||
|
@ -623,6 +866,7 @@ ByteCodeBasicBlock::ByteCodeBasicBlock(void)
|
||||||
mAssembled = false;
|
mAssembled = false;
|
||||||
mKnownShortBranch = false;
|
mKnownShortBranch = false;
|
||||||
mBypassed = false;
|
mBypassed = false;
|
||||||
|
mExitLive = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteCodeBasicBlock::IntConstToAccu(int64 val)
|
void ByteCodeBasicBlock::IntConstToAccu(int64 val)
|
||||||
|
@ -3482,6 +3726,8 @@ bool ByteCodeBasicBlock::SameTail(ByteCodeInstruction& ins)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint32 LIVE_ACCU = 0x00000001;
|
||||||
|
|
||||||
bool ByteCodeBasicBlock::JoinTailCodeSequences(void)
|
bool ByteCodeBasicBlock::JoinTailCodeSequences(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -3512,6 +3758,7 @@ bool ByteCodeBasicBlock::JoinTailCodeSequences(void)
|
||||||
{
|
{
|
||||||
ByteCodeBasicBlock* b = mEntryBlocks[i];
|
ByteCodeBasicBlock* b = mEntryBlocks[i];
|
||||||
b->mIns.SetSize(b->mIns.Size() - 1);
|
b->mIns.SetSize(b->mIns.Size() - 1);
|
||||||
|
b->mExitLive = LIVE_ACCU;
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -3530,7 +3777,6 @@ bool ByteCodeBasicBlock::JoinTailCodeSequences(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -3561,7 +3807,26 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
}
|
}
|
||||||
mIns.SetSize(j);
|
mIns.SetSize(j);
|
||||||
|
|
||||||
int accuTemp = -1, addrTemp = -1;
|
// mark accu live
|
||||||
|
|
||||||
|
uint32 live = mExitLive;
|
||||||
|
if (mBranch != BC_JUMPS && mBranch != BC_NOP)
|
||||||
|
live |= LIVE_ACCU;
|
||||||
|
|
||||||
|
for (int i = mIns.Size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
mIns[i].mLive = live;
|
||||||
|
|
||||||
|
if (mIns[i].ChangesAccu())
|
||||||
|
live &= ~LIVE_ACCU;
|
||||||
|
if (mIns[i].UsesAccu())
|
||||||
|
live |= LIVE_ACCU;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert(!(live & LIVE_ACCU));
|
||||||
|
|
||||||
|
int accuTemp = -1, addrTemp = -1, accuVal = 0;
|
||||||
|
bool accuConst = false;
|
||||||
|
|
||||||
for (int i = 0; i < mIns.Size(); i++)
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -3569,19 +3834,6 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
if (i + 3 < mIns.Size())
|
if (i + 3 < mIns.Size())
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mCode == BC_LEA_ABS && mIns[i + 0].mRegister == BC_REG_ACCU &&
|
|
||||||
mIns[i + 1].mCode == BC_BINOP_ADDR_16 &&
|
|
||||||
mIns[i + 2].mCode == BC_ADDR_REG && mIns[i + 2].mRegister == BC_REG_ACCU &&
|
|
||||||
mIns[i + 3].ChangesAccu())
|
|
||||||
{
|
|
||||||
mIns[i + 0].mCode = BC_LEA_ABS_INDEX;
|
|
||||||
mIns[i + 0].mRegister = mIns[i + 1].mRegister;
|
|
||||||
mIns[i + 0].mRegisterFinal = mIns[i + 1].mRegisterFinal;
|
|
||||||
mIns[i + 1].mCode = BC_NOP;
|
|
||||||
mIns[i + 2].mCode = BC_NOP;
|
|
||||||
progress = true;
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
mIns[i + 0].mCode == BC_LOAD_REG_8 &&
|
mIns[i + 0].mCode == BC_LOAD_REG_8 &&
|
||||||
mIns[i + 1].mCode == BC_STORE_REG_16 &&
|
mIns[i + 1].mCode == BC_STORE_REG_16 &&
|
||||||
mIns[i + 2].IsIntegerConst() && mIns[i + 2].mRegister == BC_REG_ACCU &&
|
mIns[i + 2].IsIntegerConst() && mIns[i + 2].mRegister == BC_REG_ACCU &&
|
||||||
|
@ -3592,6 +3844,22 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 3].mRegister = mIns[i + 0].mRegister;
|
mIns[i + 3].mRegister = mIns[i + 0].mRegister;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mCode == BC_LOAD_REG_8 &&
|
||||||
|
mIns[i + 1].mCode == BC_LEA_ABS && mIns[i + 1].mRegister != BC_REG_ACCU &&
|
||||||
|
mIns[i + 2].mCode == BC_BINOP_ADDR_16 && mIns[i + 2].mRegister == mIns[i + 1].mRegister && mIns[i + 2].mRegisterFinal &&
|
||||||
|
mIns[i + 3].mCode == BC_ADDR_REG && mIns[i + 3].mRegister == BC_REG_ACCU && !(mIns[i + 3].mLive & LIVE_ACCU))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mCode = BC_LEA_ABS_INDEX_U8;
|
||||||
|
mIns[i + 1].mRegister = mIns[i + 0].mRegister;
|
||||||
|
mIns[i + 1].mRegisterFinal = mIns[i + 0].mRegisterFinal;
|
||||||
|
mIns[i + 1].mLive &= ~LIVE_ACCU;
|
||||||
|
|
||||||
|
mIns[i + 0].mCode = BC_NOP;
|
||||||
|
mIns[i + 2].mCode = BC_NOP;
|
||||||
|
mIns[i + 3].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -3764,6 +4032,16 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 1].mCode = BC_NOP;
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mCode == BC_STORE_REG_16 &&
|
||||||
|
mIns[i + 1].mCode == BC_LOAD_REG_8 && mIns[i + 0].mRegister == mIns[i + 1].mRegister &&
|
||||||
|
mIns[i + 2].mCode == BC_STORE_REG_8)
|
||||||
|
{
|
||||||
|
if (mIns[i + 1].mRegisterFinal)
|
||||||
|
mIns[i + 0].mCode = BC_NOP;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mCode == BC_STORE_REG_16 &&
|
mIns[i + 0].mCode == BC_STORE_REG_16 &&
|
||||||
|
@ -3775,6 +4053,32 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mCode == BC_LEA_ABS && mIns[i + 0].mRegister == BC_REG_ACCU &&
|
||||||
|
mIns[i + 1].mCode == BC_BINOP_ADDR_16 &&
|
||||||
|
mIns[i + 2].mCode == BC_ADDR_REG && mIns[i + 2].mRegister == BC_REG_ACCU && !(mIns[i + 2].mLive & LIVE_ACCU))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mCode = BC_LEA_ABS_INDEX;
|
||||||
|
mIns[i + 0].mRegister = mIns[i + 1].mRegister;
|
||||||
|
mIns[i + 0].mRegisterFinal = mIns[i + 1].mRegisterFinal;
|
||||||
|
mIns[i + 0].mLive &= ~LIVE_ACCU;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
mIns[i + 2].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mCode == BC_LOAD_REG_8 &&
|
||||||
|
mIns[i + 1].mCode == BC_STORE_REG_16 &&
|
||||||
|
mIns[i + 2].mCode == BC_LEA_ABS_INDEX && mIns[i + 2].mRegister == mIns[i + 1].mRegister && !(mIns[i + 2].mLive & LIVE_ACCU) && mIns[i + 2].mRegisterFinal)
|
||||||
|
{
|
||||||
|
mIns[i + 2].mCode = BC_LEA_ABS_INDEX_U8;
|
||||||
|
mIns[i + 2].mRegister = mIns[i + 0].mRegister;
|
||||||
|
mIns[i + 2].mRegisterFinal = mIns[i + 0].mRegisterFinal;
|
||||||
|
mIns[i + 0].mCode = BC_NOP;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -3888,6 +4192,22 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
|
else if (mIns[i + 1].mCode == BC_LOAD_REG_8 && mIns[i + 0].mCode == BC_LOAD_ADDR_8 && mIns[i + 1].mRegisterFinal && mIns[i + 0].mRegister == mIns[i + 1].mRegister)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mCode = BC_LOAD_ADDR_U8;
|
||||||
|
mIns[i + 0].mRegister = BC_REG_ACCU;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i + 1].mCode == BC_LOAD_REG_8 && mIns[i + 0].mCode == BC_LOAD_ABS_8 && mIns[i + 1].mRegisterFinal && mIns[i + 0].mRegister == mIns[i + 1].mRegister)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mCode = BC_LOAD_ABS_U8;
|
||||||
|
mIns[i + 0].mRegister = BC_REG_ACCU;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
else if ((mIns[i].mCode == BC_LOAD_LOCAL_16 || mIns[i].mCode == BC_LOAD_ABS_16) && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
|
else if ((mIns[i].mCode == BC_LOAD_LOCAL_16 || mIns[i].mCode == BC_LOAD_ABS_16) && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
|
||||||
{
|
{
|
||||||
|
@ -3911,8 +4231,39 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accuConst && !mIns[i].mRelocate && mIns[i].mRegister == BC_REG_ACCU)
|
||||||
|
{
|
||||||
|
switch (mIns[i].mCode)
|
||||||
|
{
|
||||||
|
case BC_CONST_16:
|
||||||
|
if ((mIns[i].mValue & 0xffff) == (accuVal & 0xffff))
|
||||||
|
{
|
||||||
|
mIns[i].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BC_CONST_32:
|
||||||
|
if (mIns[i].mValue == accuVal)
|
||||||
|
{
|
||||||
|
mIns[i].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BC_CONST_8:
|
||||||
|
if ((mIns[i].mValue & 0xff) == (accuVal & 0xffff))
|
||||||
|
{
|
||||||
|
mIns[i].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mIns[i].ChangesAccu())
|
if (mIns[i].ChangesAccu())
|
||||||
|
{
|
||||||
accuTemp = -1;
|
accuTemp = -1;
|
||||||
|
accuConst = false;
|
||||||
|
}
|
||||||
if (mIns[i].ChangesAddr())
|
if (mIns[i].ChangesAddr())
|
||||||
addrTemp = -1;
|
addrTemp = -1;
|
||||||
if (accuTemp != -1 && mIns[i].ChangesRegister(accuTemp))
|
if (accuTemp != -1 && mIns[i].ChangesRegister(accuTemp))
|
||||||
|
@ -3924,6 +4275,25 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
accuTemp = mIns[i].mRegister;
|
accuTemp = mIns[i].mRegister;
|
||||||
if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister != BC_REG_ACCU)
|
if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister != BC_REG_ACCU)
|
||||||
addrTemp = mIns[i].mRegister;
|
addrTemp = mIns[i].mRegister;
|
||||||
|
|
||||||
|
if (mIns[i].mRegister == BC_REG_ACCU && !mIns[i].mRelocate)
|
||||||
|
{
|
||||||
|
switch (mIns[i].mCode)
|
||||||
|
{
|
||||||
|
case BC_CONST_16:
|
||||||
|
accuVal = mIns[i].mValue & 0xffff;
|
||||||
|
accuConst = true;
|
||||||
|
break;
|
||||||
|
case BC_CONST_32:
|
||||||
|
accuVal = mIns[i].mValue;
|
||||||
|
accuConst = true;
|
||||||
|
break;
|
||||||
|
case BC_CONST_8:
|
||||||
|
accuVal = mIns[i].mValue & 0xff;
|
||||||
|
accuConst = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress)
|
if (progress)
|
||||||
|
@ -4294,16 +4664,37 @@ ByteCodeGenerator::ByteCodeGenerator(Errors* errors, Linker* linker)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
mByteCodeUsed[i] = false;
|
mByteCodeUsed[i] = 0;
|
||||||
mExtByteCodes[i] = nullptr;
|
mExtByteCodes[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mByteCodeUsed[BC_LEA_ABS] = true;
|
mByteCodeUsed[BC_LEA_ABS] = 1;
|
||||||
mByteCodeUsed[BC_CALL] = true;
|
mByteCodeUsed[BC_CALL] = 1;
|
||||||
mByteCodeUsed[BC_EXIT] = true;
|
mByteCodeUsed[BC_EXIT] = 1;
|
||||||
mByteCodeUsed[BC_NATIVE] = true;
|
mByteCodeUsed[BC_NATIVE] = 1;
|
||||||
|
|
||||||
|
assert(sizeof(ByteCodeNames) == 128 * sizeof(char*));
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteCodeGenerator::~ByteCodeGenerator(void)
|
ByteCodeGenerator::~ByteCodeGenerator(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ByteCodeGenerator::WriteByteCodeStats(const char* filename)
|
||||||
|
{
|
||||||
|
FILE* file;
|
||||||
|
fopen_s(&file, filename, "w");
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 128; i++)
|
||||||
|
{
|
||||||
|
if (mByteCodeUsed[i] > 0)
|
||||||
|
fprintf(file, "BC %s : %d\n", ByteCodeNames[i], mByteCodeUsed[i]);
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ enum ByteCode
|
||||||
BC_STORE_REG_32,
|
BC_STORE_REG_32,
|
||||||
|
|
||||||
BC_LOAD_ABS_8,
|
BC_LOAD_ABS_8,
|
||||||
|
BC_LOAD_ABS_U8,
|
||||||
BC_LOAD_ABS_16,
|
BC_LOAD_ABS_16,
|
||||||
BC_LOAD_ABS_32,
|
BC_LOAD_ABS_32,
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ enum ByteCode
|
||||||
|
|
||||||
BC_LEA_ABS,
|
BC_LEA_ABS,
|
||||||
BC_LEA_ABS_INDEX,
|
BC_LEA_ABS_INDEX,
|
||||||
|
BC_LEA_ABS_INDEX_U8,
|
||||||
|
|
||||||
BC_LOAD_LOCAL_8,
|
BC_LOAD_LOCAL_8,
|
||||||
BC_LOAD_LOCAL_16,
|
BC_LOAD_LOCAL_16,
|
||||||
|
@ -51,6 +53,7 @@ enum ByteCode
|
||||||
BC_LEA_FRAME,
|
BC_LEA_FRAME,
|
||||||
|
|
||||||
BC_LOAD_ADDR_8,
|
BC_LOAD_ADDR_8,
|
||||||
|
BC_LOAD_ADDR_U8,
|
||||||
BC_LOAD_ADDR_16,
|
BC_LOAD_ADDR_16,
|
||||||
BC_LOAD_ADDR_32,
|
BC_LOAD_ADDR_32,
|
||||||
|
|
||||||
|
@ -198,11 +201,16 @@ public:
|
||||||
bool mRelocate, mRegisterFinal;
|
bool mRelocate, mRegisterFinal;
|
||||||
LinkerObject* mLinkerObject;
|
LinkerObject* mLinkerObject;
|
||||||
const char* mRuntime;
|
const char* mRuntime;
|
||||||
|
uint32 mLive;
|
||||||
|
|
||||||
bool IsStore(void) const;
|
bool IsStore(void) const;
|
||||||
bool ChangesAccu(void) const;
|
bool ChangesAccu(void) const;
|
||||||
bool ChangesAddr(void) const;
|
bool ChangesAddr(void) const;
|
||||||
bool ChangesRegister(uint32 reg) const;
|
bool ChangesRegister(uint32 reg) const;
|
||||||
|
|
||||||
|
bool UsesAccu(void) const;
|
||||||
|
bool UsesRegister(uint32 reg) const;
|
||||||
|
|
||||||
bool LoadsRegister(uint32 reg) const;
|
bool LoadsRegister(uint32 reg) const;
|
||||||
bool StoresRegister(uint32 reg) const;
|
bool StoresRegister(uint32 reg) const;
|
||||||
bool IsLocalStore(void) const;
|
bool IsLocalStore(void) const;
|
||||||
|
@ -233,6 +241,7 @@ public:
|
||||||
|
|
||||||
int mOffset, mSize;
|
int mOffset, mSize;
|
||||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mVisited;
|
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mVisited;
|
||||||
|
uint32 mExitLive;
|
||||||
|
|
||||||
ByteCodeBasicBlock(void);
|
ByteCodeBasicBlock(void);
|
||||||
|
|
||||||
|
@ -316,10 +325,8 @@ public:
|
||||||
Errors* mErrors;
|
Errors* mErrors;
|
||||||
Linker* mLinker;
|
Linker* mLinker;
|
||||||
|
|
||||||
bool mByteCodeUsed[128];
|
uint32 mByteCodeUsed[128];
|
||||||
LinkerObject* mExtByteCodes[128];
|
LinkerObject* mExtByteCodes[128];
|
||||||
|
|
||||||
void WriteBasicHeader(void);
|
bool WriteByteCodeStats(const char* filename);
|
||||||
void WriteByteCodeHeader(void);
|
|
||||||
void SetBasicEntry(int index);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -282,7 +282,7 @@ bool Compiler::GenerateCode(void)
|
||||||
|
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
if (mByteCodeGenerator->mByteCodeUsed[i])
|
if (mByteCodeGenerator->mByteCodeUsed[i] > 0)
|
||||||
{
|
{
|
||||||
Declaration* bcdec = mCompilationUnits->mByteCodes[i];
|
Declaration* bcdec = mCompilationUnits->mByteCodes[i];
|
||||||
if (bcdec)
|
if (bcdec)
|
||||||
|
@ -338,7 +338,7 @@ bool Compiler::GenerateCode(void)
|
||||||
|
|
||||||
bool Compiler::WriteOutputFile(const char* targetPath)
|
bool Compiler::WriteOutputFile(const char* targetPath)
|
||||||
{
|
{
|
||||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], crtPath[200], intPath[200];
|
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], crtPath[200], intPath[200], bcsPath[200];
|
||||||
|
|
||||||
strcpy_s(prgPath, targetPath);
|
strcpy_s(prgPath, targetPath);
|
||||||
int i = strlen(prgPath);
|
int i = strlen(prgPath);
|
||||||
|
@ -351,6 +351,7 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
||||||
strcpy_s(lblPath, prgPath);
|
strcpy_s(lblPath, prgPath);
|
||||||
strcpy_s(crtPath, prgPath);
|
strcpy_s(crtPath, prgPath);
|
||||||
strcpy_s(intPath, prgPath);
|
strcpy_s(intPath, prgPath);
|
||||||
|
strcpy_s(bcsPath, prgPath);
|
||||||
|
|
||||||
strcat_s(prgPath, "prg");
|
strcat_s(prgPath, "prg");
|
||||||
strcat_s(mapPath, "map");
|
strcat_s(mapPath, "map");
|
||||||
|
@ -358,6 +359,7 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
||||||
strcat_s(lblPath, "lbl");
|
strcat_s(lblPath, "lbl");
|
||||||
strcat_s(crtPath, "crt");
|
strcat_s(crtPath, "crt");
|
||||||
strcat_s(intPath, "int");
|
strcat_s(intPath, "int");
|
||||||
|
strcat_s(bcsPath, "bcs");
|
||||||
|
|
||||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||||
{
|
{
|
||||||
|
@ -383,6 +385,12 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
||||||
printf("Writing <%s>\n", intPath);
|
printf("Writing <%s>\n", intPath);
|
||||||
mInterCodeModule->Disassemble(intPath);
|
mInterCodeModule->Disassemble(intPath);
|
||||||
|
|
||||||
|
if (!(mCompilerOptions & COPT_NATIVE))
|
||||||
|
{
|
||||||
|
printf("Writing <%s>\n", bcsPath);
|
||||||
|
mByteCodeGenerator->WriteByteCodeStats(bcsPath);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
|
||||||
fprintf(file, "MOVB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
|
fprintf(file, "MOVB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
break;
|
||||||
|
case BC_LOAD_ABS_U8:
|
||||||
|
fprintf(file, "MOVUB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
|
||||||
|
i += 3;
|
||||||
|
break;
|
||||||
case BC_LOAD_ABS_16:
|
case BC_LOAD_ABS_16:
|
||||||
fprintf(file, "MOV\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
|
fprintf(file, "MOV\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
|
||||||
i += 3;
|
i += 3;
|
||||||
|
@ -162,6 +166,11 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BC_LEA_ABS_INDEX_U8:
|
||||||
|
fprintf(file, "LEAXB\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc));
|
||||||
|
i += 3;
|
||||||
|
break;
|
||||||
|
|
||||||
case BC_STORE_ABS_8:
|
case BC_STORE_ABS_8:
|
||||||
fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc));
|
fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc));
|
||||||
i += 3;
|
i += 3;
|
||||||
|
@ -540,6 +549,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
|
||||||
fprintf(file, "MOVB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
|
fprintf(file, "MOVB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
|
case BC_LOAD_ADDR_U8:
|
||||||
|
fprintf(file, "MOVUB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
|
||||||
|
i += 2;
|
||||||
|
break;
|
||||||
case BC_LOAD_ADDR_16:
|
case BC_LOAD_ADDR_16:
|
||||||
fprintf(file, "MOV\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
|
fprintf(file, "MOV\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
|
@ -1569,9 +1569,12 @@ void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable,
|
||||||
|
|
||||||
void InterInstruction::FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps)
|
void InterInstruction::FilterTempUsage(NumberSet& requiredTemps, NumberSet& providedTemps)
|
||||||
{
|
{
|
||||||
for(int i=0; i<mNumOperands; i++)
|
if (mCode != IC_NONE)
|
||||||
FilterTempUseUsage(requiredTemps, providedTemps, mSrc[i].mTemp);
|
{
|
||||||
FilterTempDefineUsage(requiredTemps, providedTemps, mDst.mTemp);
|
for (int i = 0; i < mNumOperands; i++)
|
||||||
|
FilterTempUseUsage(requiredTemps, providedTemps, mSrc[i].mTemp);
|
||||||
|
FilterTempDefineUsage(requiredTemps, providedTemps, mDst.mTemp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars)
|
void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticVars, NumberSet& requiredVars, NumberSet& providedVars)
|
||||||
|
@ -1716,9 +1719,12 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
|
||||||
|
|
||||||
void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable)
|
void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable)
|
||||||
{
|
{
|
||||||
for(int i=0; i<mNumOperands; i++)
|
if (mCode != IC_NONE)
|
||||||
PerformTempUseForwarding(mSrc[i].mTemp, forwardingTable);
|
{
|
||||||
PerformTempDefineForwarding(mDst.mTemp, forwardingTable);
|
for (int i = 0; i < mNumOperands; i++)
|
||||||
|
PerformTempUseForwarding(mSrc[i].mTemp, forwardingTable);
|
||||||
|
PerformTempDefineForwarding(mDst.mTemp, forwardingTable);
|
||||||
|
}
|
||||||
if (mCode == IC_LOAD_TEMPORARY && mDst.mTemp != mSrc[0].mTemp)
|
if (mCode == IC_LOAD_TEMPORARY && mDst.mTemp != mSrc[0].mTemp)
|
||||||
{
|
{
|
||||||
forwardingTable.Build(mDst.mTemp, mSrc[0].mTemp);
|
forwardingTable.Build(mDst.mTemp, mSrc[0].mTemp);
|
||||||
|
@ -1823,6 +1829,7 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
mSrc[0].mTemp = -1;
|
||||||
mCode = IC_NONE;
|
mCode = IC_NONE;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -1838,6 +1845,7 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
mSrc[0].mTemp = -1;
|
||||||
mCode = IC_NONE;
|
mCode = IC_NONE;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -1877,6 +1885,7 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
|
||||||
}
|
}
|
||||||
else if (!mVolatile)
|
else if (!mVolatile)
|
||||||
{
|
{
|
||||||
|
mSrc[0].mTemp = -1;
|
||||||
mCode = IC_NONE;
|
mCode = IC_NONE;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -4104,6 +4113,7 @@ void InterCodeBasicBlock::RemoveNonRelevantStatics(void)
|
||||||
{
|
{
|
||||||
if (!(ins->mSrc[1].mLinkerObject->mFlags & LOBJF_RELEVANT) && (ins->mSrc[1].mLinkerObject->mType == LOT_BSS || ins->mSrc[1].mLinkerObject->mType == LOT_DATA))
|
if (!(ins->mSrc[1].mLinkerObject->mFlags & LOBJF_RELEVANT) && (ins->mSrc[1].mLinkerObject->mType == LOT_BSS || ins->mSrc[1].mLinkerObject->mType == LOT_DATA))
|
||||||
{
|
{
|
||||||
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mCode = IC_NONE;
|
ins->mCode = IC_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5378,50 +5388,53 @@ void InterCodeProcedure::Close(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
for (int j = 0; j < 2; j++)
|
||||||
// Promote local variables to temporaries
|
|
||||||
//
|
|
||||||
|
|
||||||
FastNumberSet simpleLocals(nlocals), complexLocals(nlocals);
|
|
||||||
GrowingTypeArray localTypes(IT_NONE);
|
|
||||||
|
|
||||||
FastNumberSet simpleParams(nparams), complexParams(nparams);
|
|
||||||
GrowingTypeArray paramTypes(IT_NONE);
|
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
mEntryBlock->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
|
|
||||||
|
|
||||||
for (int i = 0; i < simpleLocals.Num(); i++)
|
|
||||||
{
|
{
|
||||||
int vi = simpleLocals.Element(i);
|
//
|
||||||
if (!complexLocals[vi])
|
// Promote local variables to temporaries
|
||||||
|
//
|
||||||
|
|
||||||
|
FastNumberSet simpleLocals(nlocals), complexLocals(nlocals);
|
||||||
|
GrowingTypeArray localTypes(IT_NONE);
|
||||||
|
|
||||||
|
FastNumberSet simpleParams(nparams), complexParams(nparams);
|
||||||
|
GrowingTypeArray paramTypes(IT_NONE);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectSimpleLocals(complexLocals, simpleLocals, localTypes, complexParams, simpleParams, paramTypes);
|
||||||
|
|
||||||
|
for (int i = 0; i < simpleLocals.Num(); i++)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
int vi = simpleLocals.Element(i);
|
||||||
mEntryBlock->SimpleLocalToTemp(vi, AddTemporary(localTypes[vi]));
|
if (!complexLocals[vi])
|
||||||
|
{
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->SimpleLocalToTemp(vi, AddTemporary(localTypes[vi]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DisassembleDebug("local variables to temps");
|
DisassembleDebug("local variables to temps");
|
||||||
|
|
||||||
BuildTraces(false);
|
BuildTraces(false);
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
RenameTemporaries();
|
RenameTemporaries();
|
||||||
|
|
||||||
|
do {
|
||||||
|
TempForwarding();
|
||||||
|
} while (GlobalConstantPropagation());
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now remove unused instructions
|
||||||
|
//
|
||||||
|
|
||||||
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
|
DisassembleDebug("removed unused instructions 2");
|
||||||
|
|
||||||
do {
|
|
||||||
TempForwarding();
|
TempForwarding();
|
||||||
} while (GlobalConstantPropagation());
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Now remove unused instructions
|
|
||||||
//
|
|
||||||
|
|
||||||
RemoveUnusedInstructions();
|
|
||||||
|
|
||||||
DisassembleDebug("removed unused instructions 2");
|
|
||||||
|
|
||||||
TempForwarding();
|
|
||||||
|
|
||||||
BuildDominators();
|
BuildDominators();
|
||||||
DisassembleDebug("added dominators");
|
DisassembleDebug("added dominators");
|
||||||
|
|
|
@ -6830,9 +6830,11 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
|
||||||
// if the global variable is smaller than 256 bytes, we can safely ignore the upper byte?
|
// if the global variable is smaller than 256 bytes, we can safely ignore the upper byte?
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER));
|
||||||
|
#if 1
|
||||||
if (ins->mSrc[1].mLinkerObject->mSize < 256)
|
if (ins->mSrc[1].mLinkerObject->mSize < 256)
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||||
}
|
}
|
||||||
|
@ -8065,6 +8067,37 @@ bool NativeCodeBasicBlock::MoveStoreHighByteDown(int at)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::MoveAddHighByteDown(int at)
|
||||||
|
{
|
||||||
|
int i = at + 4;
|
||||||
|
while (i + 1 < mIns.Size())
|
||||||
|
{
|
||||||
|
if (mIns[i].mLive & LIVE_CPU_REG_C)
|
||||||
|
return false;
|
||||||
|
if (mIns[i].ChangesZeroPage(mIns[at + 1].mAddress) || mIns[i].ChangesZeroPage(mIns[at + 3].mAddress))
|
||||||
|
return false;
|
||||||
|
if (mIns[i].UsesZeroPage(mIns[at + 3].mAddress))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!(mIns[i].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
mIns.Insert(i + 1, mIns[at + 3]);
|
||||||
|
mIns.Insert(i + 1, mIns[at + 2]);
|
||||||
|
mIns.Insert(i + 1, mIns[at + 1]);
|
||||||
|
|
||||||
|
mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mMode = ASMIM_IMPLIED; // LDA U
|
||||||
|
mIns[at + 2].mType = ASMIT_NOP; mIns[at + 2].mMode = ASMIM_IMPLIED; // ADC #
|
||||||
|
mIns[at + 3].mType = ASMIT_NOP; mIns[at + 3].mMode = ASMIM_IMPLIED; // STA T
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
||||||
{
|
{
|
||||||
int j = at;
|
int j = at;
|
||||||
|
@ -8169,14 +8202,15 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data)
|
||||||
AsmInsType carryop;
|
AsmInsType carryop;
|
||||||
|
|
||||||
// Check load and commutative with current accu value
|
// Check load and commutative with current accu value
|
||||||
|
#if 1
|
||||||
if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_LDA && mIns[i + 1].IsCommutative() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mValue == mIns[i + 1].mAddress)
|
if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_LDA && mIns[i + 1].IsCommutative() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mValue == mIns[i + 1].mAddress)
|
||||||
{
|
{
|
||||||
mIns[i].mType = mIns[i + 1].mType;
|
mIns[i].mType = mIns[i + 1].mType;
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (mIns[i].ValueForwarding(mNDataSet, carryop))
|
if (mIns[i].ValueForwarding(mNDataSet, carryop))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (carryop != ASMIT_NOP)
|
if (carryop != ASMIT_NOP)
|
||||||
|
@ -9001,11 +9035,37 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
bool NativeCodeBasicBlock::RemoveNops(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
while (i < mIns.Size())
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_NOP)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i != j)
|
||||||
|
mIns[j] = mIns[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (j != i)
|
||||||
|
changed = true;
|
||||||
|
mIns.SetSize(j);
|
||||||
|
mIns.Reserve(2 * j);
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = RemoveNops();
|
||||||
|
|
||||||
mVisited = true;
|
mVisited = true;
|
||||||
|
|
||||||
|
@ -9084,6 +9144,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
NativeCodeInstruction ins = mIns[i];
|
NativeCodeInstruction ins = mIns[i];
|
||||||
mIns[i] = mIns[i + 1];
|
mIns[i] = mIns[i + 1];
|
||||||
mIns[i + 1] = ins;
|
mIns[i + 1] = ins;
|
||||||
|
mIns[i + 1].mLive |= mIns[i].mLive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9101,49 +9162,50 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// move high byte load down, if low byte is immediatedly needed afterwards
|
|
||||||
|
|
||||||
for (int i = 0; i + 4 < mIns.Size(); i++)
|
#if 1
|
||||||
|
if (pass > 1)
|
||||||
{
|
{
|
||||||
if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
// move high byte load down, if low byte is immediatedly needed afterwards
|
||||||
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
|
||||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && mIns[i + 2].mAddress != mIns[i + 3].mAddress && mIns[i + 2].mAddress + 1 != mIns[i + 3].mAddress &&
|
for (int i = 0; i + 4 < mIns.Size(); i++)
|
||||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 0].mAddress &&
|
|
||||||
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 0].mAddress && !(mIns[i + 4].mLive & LIVE_CPU_REG_Z))
|
|
||||||
{
|
{
|
||||||
if (MoveStoreHighByteDown(i))
|
if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
changed = true;
|
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && mIns[i + 2].mAddress != mIns[i + 3].mAddress && mIns[i + 2].mAddress + 1 != mIns[i + 3].mAddress &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 0].mAddress &&
|
||||||
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 0].mAddress && !(mIns[i + 4].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
if (MoveStoreHighByteDown(i))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i + 4 < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress != mIns[i + 0].mAddress &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress != mIns[i + 0].mAddress &&
|
||||||
|
mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 0].mAddress && !(mIns[i + 4].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
if (MoveAddHighByteDown(i))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
bool progress = false;
|
bool progress = false;
|
||||||
do {
|
do {
|
||||||
progress = false;
|
progress = false;
|
||||||
|
|
||||||
int i = 0;
|
changed = RemoveNops();
|
||||||
int j = 0;
|
|
||||||
while (i < mIns.Size())
|
|
||||||
{
|
|
||||||
if (mIns[i].mType == ASMIT_NOP)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i != j)
|
|
||||||
mIns[j] = mIns[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (j != i)
|
|
||||||
changed = true;
|
|
||||||
mIns.SetSize(j);
|
|
||||||
|
|
||||||
// Replace (a & 0x80) != 0 with bpl/bmi
|
// Replace (a & 0x80) != 0 with bpl/bmi
|
||||||
int sz = mIns.Size();
|
int sz = mIns.Size();
|
||||||
if (sz > 1 &&
|
if (sz > 1 &&
|
||||||
mIns[sz - 2].ChangesAccuAndFlag() &&
|
mIns[sz - 2].ChangesAccuAndFlag() &&
|
||||||
mIns[sz - 1].mType == ASMIT_AND && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !(mIns[i].mLive & LIVE_CPU_REG_A))
|
mIns[sz - 1].mType == ASMIT_AND && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
|
||||||
{
|
{
|
||||||
if (mBranch == ASMIT_BEQ)
|
if (mBranch == ASMIT_BEQ)
|
||||||
{
|
{
|
||||||
|
@ -9282,6 +9344,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_STA && mIns[i + 1].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress && (mIns[i + 1].mLive & LIVE_CPU_REG_Z) == 0)
|
else if (mIns[i].mType == ASMIT_STA && mIns[i + 1].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress && (mIns[i + 1].mLive & LIVE_CPU_REG_Z) == 0)
|
||||||
{
|
{
|
||||||
|
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
@ -9999,9 +10062,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
|
|
||||||
} while (progress);
|
} while (progress);
|
||||||
|
|
||||||
if (this->mTrueJump && this->mTrueJump->PeepHoleOptimizer())
|
if (this->mTrueJump && this->mTrueJump->PeepHoleOptimizer(pass))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (this->mFalseJump && this->mFalseJump->PeepHoleOptimizer())
|
if (this->mFalseJump && this->mFalseJump->PeepHoleOptimizer(pass))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
|
@ -10623,7 +10686,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
} while (changed);
|
} while (changed);
|
||||||
#endif
|
#endif
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->PeepHoleOptimizer())
|
if (mEntryBlock->PeepHoleOptimizer(step))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
|
|
|
@ -120,7 +120,8 @@ public:
|
||||||
void Assemble(void);
|
void Assemble(void);
|
||||||
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
|
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
|
||||||
|
|
||||||
bool PeepHoleOptimizer(void);
|
bool RemoveNops(void);
|
||||||
|
bool PeepHoleOptimizer(int pass);
|
||||||
void BlockSizeReduction(void);
|
void BlockSizeReduction(void);
|
||||||
bool OptimizeSimpleLoop(NativeCodeProcedure* proc);
|
bool OptimizeSimpleLoop(NativeCodeProcedure* proc);
|
||||||
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
|
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
|
||||||
|
@ -179,6 +180,7 @@ public:
|
||||||
bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags);
|
bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags);
|
||||||
bool MoveStoreXUp(int at);
|
bool MoveStoreXUp(int at);
|
||||||
bool MoveStoreHighByteDown(int at);
|
bool MoveStoreHighByteDown(int at);
|
||||||
|
bool MoveAddHighByteDown(int at);
|
||||||
|
|
||||||
bool ValueForwarding(const NativeRegisterDataSet& data);
|
bool ValueForwarding(const NativeRegisterDataSet& data);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue