Change memset and memclr to intrinsic functions

This commit is contained in:
drmortalwombat 2024-03-24 11:22:13 +01:00
parent 85fad64e9c
commit aa601a5727
12 changed files with 744 additions and 134 deletions

View File

@ -2666,6 +2666,23 @@ inp_call_addr:
#pragma bytecode(BC_CALL_ADDR, inp_call.inp_call_addr)
#pragma bytecode(BC_CALL_ABS, inp_call)
__asm inp_fill
{
lda (ip), y
sty tmpy
tay
lda accu
L1: dey
sta (addr), y
bne L1
ldy tmpy
jmp startup.yexec
}
#pragma bytecode(BC_FILL, inp_fill)
__asm inp_copy
{
lda (ip), y
@ -2700,6 +2717,46 @@ L1: iny
#pragma bytecode(BC_STRCPY, inp_strcpy)
__asm inp_filll
{
lda (ip), y
sta tmp
iny
lda (ip), y
tax
sty tmpy
beq W1
ldy #0
lda accu
Loop1:
sta (addr), y
iny
bne Loop1
inc accu + 1
inc addr + 1
dex
bne Loop1
W1:
lda accu
ldy tmp
beq W2
dey
beq W3
Loop2:
sta (addr), y
dey
bne Loop2
W3:
sta (addr), y
W2:
ldy tmpy
jmp startup.yexec
}
#pragma bytecode(BC_FILL_LONG, inp_filll)
__asm inp_copyl
{
lda (ip), y

View File

@ -144,8 +144,8 @@ enum ByteCode
BC_LOOP_U8,
BC_MALLOC,
BC_FREE,
BC_UNUSED_4,
BC_UNUSED_5,
BC_FILL,
BC_FILL_LONG,
BC_UNUSED_6,
BC_JSR,

View File

@ -25,6 +25,10 @@ void * memmove(void * dst, const void * src, int size);
#pragma intrinsic(memcpy)
#pragma intrinsic(memset)
#pragma intrinsic(memclr)
#pragma compile("string.c")
#endif

View File

@ -144,8 +144,8 @@ static const char* ByteCodeNames[] = {
"LOOP_U8",
"MALLOC",
"FREE",
nullptr,
nullptr,
"FILL",
"FILL_LONG",
nullptr,
"JSR", //114
@ -680,6 +680,8 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
used = 0xffffffff;
break;
case BC_FILL:
case BC_FILL_LONG:
case BC_COPY:
case BC_COPY_LONG:
case BC_STRCPY:
@ -780,7 +782,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
return true;
if (mCode == BC_LEA_ACCU_INDEX)
return true;
if (mCode == BC_COPY || mCode == BC_STRCPY)
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL)
return true;
if (mCode == BC_BINOP_ADDA_16)
return true;
@ -793,7 +795,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_STORE_ADDR_32)
return true;
if (mCode == BC_COPY || mCode == BC_STRCPY)
if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL)
return true;
if (mCode == BC_JSR || mCode == BC_CALL_ADDR || mCode == BC_CALL_ABS)
@ -1212,6 +1214,20 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
block->PutByte(mValue);
break;
case BC_FILL:
case BC_FILL_LONG:
if (mValue < 256)
{
block->PutCode(generator, BC_FILL);
block->PutByte(uint8(mValue));
}
else
{
block->PutCode(generator, BC_FILL_LONG);
block->PutWord(uint16(mValue));
}
break;
case BC_COPY:
case BC_COPY_LONG:
if (mValue < 256)
@ -1567,6 +1583,30 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
}
void ByteCodeBasicBlock::FillValue(InterCodeProcedure* proc, const InterInstruction* ins)
{
LoadOperandAddress(proc, ins->mSrc[1], BC_REG_ADDR);
if (ins->mSrc[0].mTemp < 0)
{
ByteCodeInstruction cins(BC_CONST_8);
cins.mRegister = BC_REG_ACCU;
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
else
{
ByteCodeInstruction lins(BC_LOAD_REG_8);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
}
ByteCodeInstruction cins(BC_FILL);
cins.mValue = ins->mConst.mOperandSize;
mIns.Push(cins);
}
void ByteCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins)
{
LoadOperandAddress(proc, ins->mSrc[0], BC_REG_ACCU);
@ -4320,6 +4360,9 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
else
LoadDirectValue(iproc, ins);
break;
case IC_FILL:
FillValue(iproc, ins);
break;
case IC_COPY:
CopyValue(iproc, ins);
break;

View File

@ -145,8 +145,8 @@ enum ByteCode
BC_LOOP_U8,
BC_MALLOC,
BC_FREE,
BC_UNUSED_4,
BC_UNUSED_5,
BC_FILL,
BC_FILL_LONG,
BC_UNUSED_6,
BC_JSR,
@ -281,6 +281,7 @@ public:
void IntConstToAddr(int64 val);
void FloatConstToAccu(double val);
void FloatConstToWork(double val);
void FillValue(InterCodeProcedure* proc, const InterInstruction* ins);
void CopyValue(InterCodeProcedure* proc, const InterInstruction * ins);
void StrcpyValue(InterCodeProcedure* proc, const InterInstruction* ins);
void CallMalloc(InterCodeProcedure* proc, const InterInstruction* ins);

View File

@ -429,6 +429,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
i += 1;
break;
case BC_FILL:
fprintf(file, "FILL\t#%d", memory[start + i + 0]);
i++;
break;
case BC_COPY:
fprintf(file, "COPY\t#%d", memory[start + i + 0]);
i++;
@ -441,6 +445,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
fprintf(file, "COPYL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_FILL_LONG:
fprintf(file, "FILLL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 2;
break;
case BC_OP_NEGATE_16:
fprintf(file, "NEG\tACCU");

View File

@ -39,6 +39,7 @@ enum ErrorID
EWARN_DESTRUCTOR_MISMATCH,
EWARN_NUMERIC_0_USED_AS_NULLPTR,
EWARN_FLOAT_TO_INT,
EWARN_UNDEFINED_POINTER_ARITHMETIC,
EERR_GENERIC = 3000,
EERR_FILE_NOT_FOUND,

View File

@ -418,7 +418,7 @@ static bool MemRange(const InterInstruction* ins, const GrowingInstructionPtrArr
}
else if (ins->mSrc[1].mMemory == IM_INDIRECT)
{
if (ins->mCode == IC_COPY)
if (ins->mCode == IC_COPY ||ins->mCode == IC_FILL)
size = ins->mConst.mOperandSize;
else
size = ins->mSrc[1].mOperandSize;
@ -593,6 +593,8 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op, InterType type, c
return CollidingMem(op, type, ins->mSrc[0], ins->mDst.mType);
else if (ins->mCode == IC_STORE)
return CollidingMem(op, type, ins->mSrc[1], ins->mSrc[0].mType);
else if (ins->mCode == IC_FILL)
return CollidingMem(op, type, ins->mSrc[1], IT_NONE);
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
return CollidingMem(op, type, ins->mSrc[0], IT_NONE) || CollidingMem(op, type, ins->mSrc[1], IT_NONE);
else
@ -605,6 +607,8 @@ bool InterCodeBasicBlock::CollidingMem(const InterInstruction* ins1, const Inter
return CollidingMem(ins1->mSrc[0], ins1->mDst.mType, ins2);
else if (ins1->mCode == IC_STORE)
return CollidingMem(ins1->mSrc[1], ins1->mSrc[0].mType, ins2);
else if (ins1->mCode == IC_FILL)
return CollidingMem(ins1->mSrc[1], IT_NONE, ins2);
else if (ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
return CollidingMem(ins1->mSrc[0], IT_NONE, ins2) || CollidingMem(ins1->mSrc[1], IT_NONE, ins2);
else
@ -617,6 +621,8 @@ bool InterCodeBasicBlock::DestroyingMem(const InterInstruction* lins, const Inte
return false;
else if (sins->mCode == IC_STORE)
return CollidingMem(sins->mSrc[1], sins->mSrc[0].mType, lins);
else if (sins->mCode == IC_FILL)
return CollidingMem(sins->mSrc[1], IT_NONE, lins);
else if (sins->mCode == IC_COPY || sins->mCode == IC_STRCPY)
return CollidingMem(sins->mSrc[1], IT_NONE, lins);
else if (sins->mCode == IC_CALL || sins->mCode == IC_CALL_NATIVE)
@ -631,6 +637,8 @@ bool InterCodeBasicBlock::DestroyingMem(const InterInstruction* lins, const Inte
opmask = 1;
else if (lins->mCode == IC_STORE)
opmask = 2;
else if (lins->mCode == IC_FILL)
opmask = 2;
else if (lins->mCode == IC_COPY)
opmask = 3;
@ -876,7 +884,7 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons
else
return false;
}
else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY)
else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL)
return false;
}
if (ins0->mCode == IC_CALL || ins0->mCode == IC_CALL_NATIVE || ins0->mCode == IC_ASSEMBLER)
@ -885,7 +893,7 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons
ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME || ins1->mCode == IC_MALLOC || ins1->mCode == IC_FREE)
return false;
if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY || ins1->mCode == IC_FILL)
return false;
}
@ -897,12 +905,12 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons
if (ins0->mCode == IC_FREE)
{
if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)
if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY || ins1->mCode == IC_FILL)
return false;
}
if (ins1->mCode == IC_FREE)
{
if (ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY)
if (ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL)
return false;
}
@ -943,8 +951,8 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons
return false;
}
if ((ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) &&
(ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY))
if ((ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL) &&
(ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY || ins1->mCode == IC_FILL))
{
if (ins0->mVolatile || ins1->mVolatile)
return false;
@ -959,7 +967,7 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons
if (DestroyingMem(ins1, ins0))
return false;
}
else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY)
else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL)
{
if (CollidingMem(ins0, ins1))
return false;
@ -1665,12 +1673,12 @@ static bool HasSideEffect(InterCode code)
static bool IsObservable(InterCode code)
{
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_MALLOC || code == IC_FREE;
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_FILL || code == IC_MALLOC || code == IC_FREE;
}
static bool IsMoveable(InterCode code)
{
if (HasSideEffect(code) || code == IC_COPY || code == IC_STRCPY || code == IC_STORE || code == IC_BRANCH || code == IC_POP_FRAME || code == IC_PUSH_FRAME || code == IC_MALLOC || code == IC_FREE)
if (HasSideEffect(code) || code == IC_COPY || code == IC_STRCPY || code == IC_STORE || code == IC_FILL || code == IC_BRANCH || code == IC_POP_FRAME || code == IC_PUSH_FRAME || code == IC_MALLOC || code == IC_FREE)
return false;
if (code == IC_RETURN || code == IC_RETURN_STRUCT || code == IC_RETURN_VALUE || code == IC_DISPATCH)
return false;
@ -1682,7 +1690,7 @@ static bool IsMoveable(InterCode code)
static bool CanBypassLoad(const InterInstruction* lins, const InterInstruction* bins)
{
// Check ambiguity
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY)
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_FILL)
return false;
// Side effects
@ -1737,7 +1745,7 @@ static bool CanBypassLoad(const InterInstruction* lins, const InterInstruction*
static bool CanBypassStoreDown(const InterInstruction* sins, const InterInstruction* bins)
{
// Check ambiguity
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY)
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_FILL)
return false;
// Side effects
@ -1830,7 +1838,7 @@ static bool CanBypass(const InterInstruction* lins, const InterInstruction* bins
bins->mCode == IC_RETURN || bins->mCode == IC_RETURN_STRUCT || bins->mCode == IC_RETURN_VALUE ||
bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME)
return false;
if (bins->mCode == IC_LOAD || bins->mCode == IC_STORE || bins->mCode == IC_COPY)
if (bins->mCode == IC_LOAD || bins->mCode == IC_STORE || bins->mCode == IC_COPY || bins->mCode == IC_FILL)
return false;
}
@ -1878,9 +1886,9 @@ static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bi
if (bins->mDst.mTemp == lins->mSrc[i].mTemp)
return false;
}
if (lins->mCode == IC_STORE || lins->mCode == IC_COPY)
if (lins->mCode == IC_STORE || lins->mCode == IC_COPY || lins->mCode == IC_FILL)
{
if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD || bins->mCode == IC_COPY || bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE)
if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD || bins->mCode == IC_COPY || bins->mCode == IC_FILL || bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE)
return false;
}
@ -1896,7 +1904,7 @@ static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bi
static bool CanBypassLoadUp(const InterInstruction* lins, const InterInstruction* bins)
{
// Check ambiguity
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY)
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_FILL)
return false;
// Side effects
@ -1965,7 +1973,7 @@ static bool IsChained(const InterInstruction* ins, const InterInstruction* nins)
static bool CanBypassStore(const InterInstruction* sins, const InterInstruction* bins)
{
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME)
if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_FILL)
return false;
// True data dependency
@ -2424,6 +2432,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
if (!ins->mVolatile)
InsertValue(ins);
break;
case IC_FILL:
case IC_COPY:
case IC_STRCPY:
i = 0;
@ -3793,7 +3802,7 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV
}
}
}
else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH)
else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH || mCode == IC_FILL)
{
requiredVars.OrNot(providedVars);
}
@ -3841,7 +3850,7 @@ void InterInstruction::FilterStaticVarsByteUsage(const GrowingVariableArray& sta
}
}
}
else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH)
else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH || mCode == IC_FILL)
{
requiredVars.OrNot(providedVars);
}
@ -3912,6 +3921,23 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu
providedParams += mSrc[1].mVarIndex;
}
}
else if (mCode == IC_FILL)
{
if (mSrc[1].mMemory == IM_LOCAL)
{
assert(mSrc[1].mTemp < 0);
if (!providedVars[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != localVars[mSrc[1].mVarIndex]->mSize))
requiredVars += mSrc[1].mVarIndex;
providedVars += mSrc[1].mVarIndex;
}
else if (mSrc[1].mMemory == paramMemory)
{
assert(mSrc[1].mTemp < 0);
if (!providedParams[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != params[mSrc[1].mVarIndex]->mSize))
requiredParams += mSrc[1].mVarIndex;
providedParams += mSrc[1].mVarIndex;
}
}
else if (mCode == IC_COPY || mCode == IC_STRCPY)
{
if (mSrc[0].mMemory == IM_LOCAL)
@ -4478,7 +4504,7 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock*
}
}
}
else if (mCode == IC_COPY || mCode == IC_STRCPY)
else if (mCode == IC_COPY || mCode == IC_STRCPY || mCode == IC_FILL)
{
requiredVars.Fill();
storeIns.SetSize(0);
@ -4534,7 +4560,7 @@ bool InterInstruction::RemoveUnusedStaticStoreByteInstructions(InterCodeBasicBlo
}
}
}
else if (mCode == IC_COPY || mCode == IC_STRCPY)
else if (mCode == IC_COPY || mCode == IC_STRCPY || mCode == IC_FILL)
{
requiredVars.Fill();
}
@ -4771,6 +4797,12 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
else if ((mSrc[0].mMemory == IM_PARAM || mSrc[0].mMemory == IM_FPARAM) && mSrc[0].mTemp < 0)
complexParams += mSrc[0].mVarIndex;
break;
case IC_FILL:
if (mSrc[1].mMemory == IM_LOCAL && mSrc[1].mTemp < 0)
complexLocals += mSrc[1].mVarIndex;
else if ((mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) && mSrc[1].mTemp < 0)
complexParams += mSrc[1].mVarIndex;
break;
case IC_CONSTANT:
if (mDst.mType == IT_POINTER && mConst.mMemory == IM_LOCAL)
complexLocals += mConst.mVarIndex;
@ -5220,6 +5252,13 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc)
else
fprintf(file, "COPY%d:%c%c", mSrc[0].mOperandSize, memchars[mSrc[0].mMemory], memchars[mSrc[1].mMemory]);
break;
case IC_FILL:
assert(mNumOperands == 2);
if (mSrc[1].mStride != 1)
fprintf(file, "FILL%c%d:%d", memchars[mSrc[1].mMemory], mSrc[1].mOperandSize, mSrc[1].mStride);
else
fprintf(file, "FILL%c%d", memchars[mSrc[1].mMemory], mSrc[1].mOperandSize);
break;
case IC_MALLOC:
assert(mNumOperands == 1);
@ -5948,6 +5987,16 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
OptimizeAddress(ins, tvalue, 1);
break;
case IC_FILL:
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{
ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst;
ins->mSrc[0].mTemp = -1;
}
OptimizeAddress(ins, tvalue, 1);
break;
case IC_COPY:
OptimizeAddress(ins, tvalue, 0);
OptimizeAddress(ins, tvalue, 1);
@ -6819,6 +6868,19 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
ltemps.SetSize(j);
break;
case IC_FILL:
j = 0;
for (int k = 0; k < ltemps.Size(); k++)
{
if (!CollidingMem(ltemps[k], ins))
{
ltemps[j++] = ltemps[k];
}
}
ltemps.SetSize(j);
break;
case IC_COPY:
for (int k = 0; k < ltemps.Size(); k++)
{
@ -8285,6 +8347,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
mMemoryValueSize[ins->mSrc[0].mTemp] = int64max(mMemoryValueSize[ins->mSrc[0].mTemp], ins->mSrc[0].mIntConst + InterTypeSize[ins->mDst.mType]);
else if (ins->mCode == IC_STORE && ins->mSrc[1].mMemory == IM_INDIRECT && ins->mSrc[1].mTemp >= 0)
mMemoryValueSize[ins->mSrc[1].mTemp] = int64max(mMemoryValueSize[ins->mSrc[1].mTemp], ins->mSrc[1].mIntConst + InterTypeSize[ins->mSrc[0].mType]);
else if (ins->mCode == IC_FILL)
{
if (ins->mSrc[1].mMemory == IM_INDIRECT && ins->mSrc[1].mTemp >= 0)
mMemoryValueSize[ins->mSrc[1].mTemp] = ins->mConst.mOperandSize;
}
else if (ins->mCode == IC_COPY)
{
if (ins->mSrc[0].mMemory == IM_INDIRECT && ins->mSrc[0].mTemp >= 0)
@ -8901,7 +8968,7 @@ bool InterCodeBasicBlock::PropagateConstOperationsUp(void)
{
const InterInstruction* ins = mInstructions[i];
if (!HasSideEffect(ins->mCode) && ins->mCode != IC_CONSTANT && ins->mCode != IC_STORE && ins->mCode != IC_COPY)
if (!HasSideEffect(ins->mCode) && ins->mCode != IC_CONSTANT && ins->mCode != IC_STORE && ins->mCode != IC_COPY && ins->mCode != IC_FILL)
{
bool isProvided = false;
if (ins->mDst.mTemp >= 0)
@ -9432,7 +9499,7 @@ bool InterCodeBasicBlock::RemoveUnusedLocalStoreInstructions(void)
break;
else if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE)
break;
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY || ins->mCode == IC_FILL)
break;
}
}
@ -10164,6 +10231,13 @@ bool InterCodeBasicBlock::ForwardShortLoadStoreOffsets(void)
mins->mSrc[1].mIntConst += lins->mSrc[0].mIntConst;
changed = true;
}
else if (mins->mCode == IC_FILL && mins->mSrc[1].mTemp == lins2->mDst.mTemp && mins->mSrc[1].mFinal)
{
lins2->mSrc[1].mTemp = lins->mSrc[1].mTemp;
lins->mSrc[1].mFinal = false;
mins->mSrc[1].mIntConst += lins->mSrc[0].mIntConst;
changed = true;
}
}
}
@ -11569,7 +11643,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
nins = ins;
#endif
}
else if (ins->mCode == IC_STRCPY)
else if (ins->mCode == IC_STRCPY || ins->mCode == IC_FILL)
flushMem = true;
else if (ins->mCode == IC_LEA || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_CONVERSION_OPERATOR)
{
@ -11628,7 +11702,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
if (lins->mCode == IC_LOAD)
opmask = 1;
else if (lins->mCode == IC_STORE)
else if (lins->mCode == IC_STORE || lins->mCode == IC_FILL)
opmask = 2;
else if (lins->mCode == IC_COPY)
opmask = 3;
@ -11678,7 +11752,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
while (j < mLoadStoreInstructions.Size())
{
if (flushMem && (mLoadStoreInstructions[j]->mCode == IC_LOAD || mLoadStoreInstructions[j]->mCode == IC_STORE || mLoadStoreInstructions[j]->mCode == IC_COPY))
if (flushMem && (mLoadStoreInstructions[j]->mCode == IC_LOAD || mLoadStoreInstructions[j]->mCode == IC_STORE || mLoadStoreInstructions[j]->mCode == IC_COPY || mLoadStoreInstructions[j]->mCode == IC_FILL))
;
else if (t < 0)
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
@ -11923,6 +11997,7 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
case IC_STORE:
case IC_LEA:
case IC_FILL:
if (mInstructions[i]->mSrc[1].mTemp < 0 && mInstructions[i]->mSrc[1].mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mSrc[1].mVarIndex]->mUsed = true;
@ -12075,7 +12150,7 @@ bool InterCodeBasicBlock::CanMoveInstructionDown(int si, int ti) const
InterInstruction* ins = mInstructions[si];
#if 1
if (ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME ||
if (ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || ins->mCode == IC_FILL ||
ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE || ins->mCode == IC_DISPATCH)
return false;
@ -12137,7 +12212,7 @@ bool InterCodeBasicBlock::CanMoveInstructionBeforeBlock(int ii, const InterInstr
{
#if 1
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE || ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME ||
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE || ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || ins->mCode == IC_FILL ||
ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE || ins->mCode == IC_DISPATCH)
return false;
@ -12946,7 +13021,7 @@ void InterCodeBasicBlock::RemoveNonRelevantStatics(void)
for (i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins(mInstructions[i]);
if (ins->mCode == IC_STORE || ins->mCode == IC_COPY)
if (ins->mCode == IC_STORE || ins->mCode == IC_COPY || ins->mCode == IC_FILL)
{
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && !ins->mVolatile)
{
@ -13294,7 +13369,7 @@ void InterCodeBasicBlock::CollectStaticStack(LinkerObject* lobj, const GrowingVa
if (mInstructions[i]->mCode == IC_LOAD)
ApplyStaticStack(mInstructions[i]->mSrc[0],localVars);
else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA)
else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA || mInstructions[i]->mCode == IC_FILL)
ApplyStaticStack(mInstructions[i]->mSrc[1], localVars);
else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER)
ApplyStaticStack(mInstructions[i]->mConst, localVars);
@ -13336,7 +13411,7 @@ void InterCodeBasicBlock::PromoteStaticStackParams(LinkerObject* paramlobj)
{
if (mInstructions[i]->mCode == IC_LOAD)
PromoteStaticStackParam(mInstructions[i]->mSrc[0], paramlobj);
else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA)
else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA || mInstructions[i]->mCode == IC_FILL)
PromoteStaticStackParam(mInstructions[i]->mSrc[1], paramlobj);
else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER)
PromoteStaticStackParam(mInstructions[i]->mConst, paramlobj);
@ -14663,7 +14738,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
else
hasStore = true;
}
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY)
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY || ins->mCode == IC_FILL)
hasStore = true;
}
}
@ -14726,7 +14801,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
ins->mInvariant = false;
}
}
else if (sins->mCode == IC_COPY)
else if (sins->mCode == IC_COPY || sins->mCode == IC_FILL)
{
ins->mInvariant = false;
}
@ -16445,7 +16520,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
ins->mInvariant = false;
}
}
else if (sins->mCode == IC_COPY)
else if (sins->mCode == IC_COPY || sins->mCode == IC_FILL)
{
ins->mInvariant = false;
}
@ -18945,6 +19020,20 @@ void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals,
else if (ins->mSrc[1].mTemp >= 0 && (ins->mSrc[1].mMemoryBase == IM_NONE || ins->mSrc[1].mMemoryBase == IM_INDIRECT))
storesIndirect = true;
break;
case IC_FILL:
if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0)
{
referencedGlobals += ins->mSrc[1].mVarIndex;
modifiedGlobals += ins->mSrc[1].mVarIndex;
}
else if (ins->mSrc[1].mMemoryBase == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0)
{
referencedGlobals += ins->mSrc[1].mVarIndex;
modifiedGlobals += ins->mSrc[1].mVarIndex;
}
else if (ins->mSrc[1].mTemp >= 0 && (ins->mSrc[1].mMemoryBase == IM_NONE || ins->mSrc[1].mMemoryBase == IM_INDIRECT))
storesIndirect = true;
break;
case IC_COPY:
case IC_STRCPY:
if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0)
@ -19148,6 +19237,7 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
case IC_STORE:
case IC_LOAD:
case IC_COPY:
case IC_FILL:
case IC_STRCPY:
case IC_CALL_NATIVE:
case IC_ASSEMBLER:

View File

@ -24,6 +24,7 @@ enum InterCode
IC_LEA,
IC_COPY, // Copy from src[0] to src[1]
IC_STRCPY,
IC_FILL, // Fill src[1] with src[0]
IC_MALLOC,
IC_FREE,
IC_TYPECAST,

View File

@ -3471,6 +3471,84 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
}
}
else if (!strcmp(iname->mString, "memset"))
{
if (exp->mRight->mType == EX_LIST)
{
Expression* tex = exp->mRight->mLeft, * sex = exp->mRight->mRight->mLeft, * nex = exp->mRight->mRight->mRight;
if (nex && nex->mType == EX_CONSTANT && nex->mDecValue->mType == DT_CONST_INTEGER && nex->mDecValue->mInteger <= 1024)
{
vl = TranslateExpression(procType, proc, block, tex, destack, breakBlock, continueBlock, inlineMapper);
if (vl.mType->mType == DT_TYPE_ARRAY)
vl = Dereference(proc, exp, block, inlineMapper, vl, 1);
else
vl = Dereference(proc, exp, block, inlineMapper, vl);
vr = TranslateExpression(procType, proc, block, sex, destack, breakBlock, continueBlock, inlineMapper);
vr = Dereference(proc, exp, block, inlineMapper, vr);
if (!TheVoidPointerTypeDeclaration->CanAssign(vl.mType))
mErrors->Error(tex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
if (!TheConstCharTypeDeclaration->CanAssign(vr.mType))
mErrors->Error(sex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_FILL);
ins->mNumOperands = 2;
ins->mSrc[0].mType = IT_INT8;
ins->mSrc[0].mTemp = vr.mTemp;
ins->mSrc[1].mType = IT_POINTER;
ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mSrc[1].mTemp = vl.mTemp;
ins->mSrc[0].mOperandSize = 1;
ins->mSrc[1].mOperandSize = int(nex->mDecValue->mInteger);
ins->mConst.mOperandSize = int(nex->mDecValue->mInteger);
block->Append(ins);
return vl;
}
}
}
else if (!strcmp(iname->mString, "memclr"))
{
if (exp->mRight->mType == EX_LIST)
{
Expression* tex = exp->mRight->mLeft, * nex = exp->mRight->mRight;
if (nex && nex->mType == EX_CONSTANT && nex->mDecValue->mType == DT_CONST_INTEGER && nex->mDecValue->mInteger <= 1024)
{
vl = TranslateExpression(procType, proc, block, tex, destack, breakBlock, continueBlock, inlineMapper);
if (vl.mType->mType == DT_TYPE_ARRAY)
vl = Dereference(proc, exp, block, inlineMapper, vl, 1);
else
vl = Dereference(proc, exp, block, inlineMapper, vl);
if (!TheVoidPointerTypeDeclaration->CanAssign(vl.mType))
mErrors->Error(tex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
InterInstruction * zins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
zins->mDst.mType = IT_INT8;
zins->mDst.mTemp = proc->AddTemporary(zins->mDst.mType);
zins->mConst.mType = IT_INT8;
zins->mConst.mIntConst = 0;
block->Append(zins);
InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_FILL);
ins->mNumOperands = 2;
ins->mSrc[0].mType = IT_INT8;
ins->mSrc[0].mTemp = zins->mDst.mTemp;
ins->mSrc[1].mType = IT_POINTER;
ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mSrc[1].mTemp = vl.mTemp;
ins->mSrc[0].mOperandSize = 1;
ins->mSrc[1].mOperandSize = int(nex->mDecValue->mInteger);
ins->mConst.mOperandSize = int(nex->mDecValue->mInteger);
block->Append(ins);
return vl;
}
}
}
else
{
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);

View File

@ -406,7 +406,9 @@ NativeCodeInstruction::NativeCodeInstruction(const InterInstruction* ins, AsmIns
if (mode == ASMIM_IMMEDIATE_ADDRESS)
{
#if _DEBUG
assert(address >= 0);
#endif
assert((mFlags & (NCIF_LOWER | NCIF_UPPER)) != (NCIF_LOWER | NCIF_UPPER));
assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE));
}
@ -5071,6 +5073,9 @@ void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const In
{
if (ins->mConst.mMemory == IM_GLOBAL)
{
if (ins->mConst.mIntConst < 0 || ins->mConst.mIntConst > ins->mConst.mLinkerObject->mSize)
proc->mModule->mErrors->Error(ins->mLocation, EWARN_UNDEFINED_POINTER_ARITHMETIC, "Undefined constant pointer arithmetic");
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mConst.mIntConst, ins->mConst.mLinkerObject, NCIF_LOWER));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mConst.mIntConst, ins->mConst.mLinkerObject, NCIF_UPPER));
@ -7803,6 +7808,349 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
}
}
NativeCodeBasicBlock* NativeCodeBasicBlock::FillValue(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc)
{
int size = ins->mConst.mOperandSize;
int msize = 4, dstride = ins->mSrc[1].mStride;
uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (ins->mVolatile)
flags |= NCIF_VOLATILE;
if (dstride > 1)
msize = 32;
else if (nproc->mInterProc->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL)
msize = 8;
else if (nproc->mInterProc->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE)
msize = 2;
#if 1
if (ins->mSrc[1].mTemp < 0)
{
if ((ins->mSrc[1].mMemory == IM_FRAME || ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) && size < 256 && dstride == 1)
{
int areg = BC_REG_STACK;
int index = int(ins->mSrc[1].mIntConst);
if (ins->mSrc[1].mMemory == IM_FRAME)
index += ins->mSrc[1].mVarIndex + 2;
else
{
if (!mNoFrame)
areg = BC_REG_LOCALS;
if (ins->mSrc[1].mMemory == IM_LOCAL)
index += proc->mLocalVars[ins->mSrc[1].mVarIndex]->mOffset;
else
index += ins->mSrc[1].mVarIndex + proc->mLocalSize + 2;
index += mFrameOffset;
}
CheckFrameIndex(ins, areg, index, size, BC_REG_ADDR);
if (ins->mSrc[0].mTemp < 0)
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
else
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
if (size <= msize)
{
for (int i = 0; i < size; i++)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, index + i * dstride));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
}
return this;
}
else
{
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, index));
this->Close(ins, lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_INY, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_CPY, ASMIM_IMMEDIATE, (index + size) & 255));
lblock->Close(ins, lblock, eblock, ASMIT_BNE);
return eblock;
}
}
else if (ins->mSrc[1].mMemory == IM_GLOBAL || ins->mSrc[1].mMemory == IM_ABSOLUTE)
{
NativeCodeBasicBlock* block = this;
if (ins->mSrc[0].mTemp < 0)
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
else
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
int offset = 0;
if (size >= 256)
{
block = nproc->AllocateBlock();
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
if (size > 256)
{
if (size < 512 && !(size & 1))
{
int step = size >> 1;
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, step));
this->Close(ins, lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + step, ins->mSrc[1].mLinkerObject, flags));
lblock->Close(ins, lblock, block, ASMIT_BNE);
return block;
}
else if (size < 1024 && !(size & 3))
{
int step = size >> 2;
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, step));
this->Close(ins, lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + step, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + 2 * step, ins->mSrc[1].mLinkerObject, flags));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + 3 * step, ins->mSrc[1].mLinkerObject, flags));
lblock->Close(ins, lblock, block, ASMIT_BNE);
return block;
}
}
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, 0));
this->Close(ins, lblock, nullptr, ASMIT_JMP);
while (offset + 255 < size)
{
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + offset, ins->mSrc[1].mLinkerObject, flags));
offset += 256;
}
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_INY, ASMIM_IMPLIED));
lblock->Close(ins, lblock, block, ASMIT_BNE);
size &= 255;
}
if (size <= msize)
{
for (int i = 0; i < size; i++)
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + offset + i * dstride, ins->mSrc[1].mLinkerObject, flags));
}
else
{
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, size));
block->Close(ins, lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + offset, ins->mSrc[1].mLinkerObject, flags));
lblock->Close(ins, lblock, eblock, ASMIT_BNE);
block = eblock;
}
return block;
}
else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME)
{
if (ins->mSrc[0].mTemp < 0)
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
else
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
for (int i = 0; i < size; i++)
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst + i * dstride));
return this;
}
}
#endif
int dreg;
int di = 0;
if (ins->mSrc[1].mTemp < 0)
{
if (ins->mSrc[1].mMemory == IM_GLOBAL)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_LOWER));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM)
{
int index = int(ins->mSrc[1].mIntConst);
dreg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins->mSrc[1].mMemory == IM_LOCAL)
index += proc->mLocalVars[ins->mSrc[1].mVarIndex]->mOffset;
else
index += ins->mSrc[1].mVarIndex + proc->mLocalSize + 2;
index += mFrameOffset;
CheckFrameIndex(ins, dreg, index, 256, BC_REG_ADDR);
}
else if (ins->mSrc[1].mMemory == IM_FRAME)
{
int index = ins->mSrc[1].mVarIndex + int(ins->mSrc[1].mIntConst) + 2;
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
}
else if (ins->mSrc[1].mIntConst != 0)
{
int index = int(ins->mSrc[1].mIntConst);
if (size <= msize && (size - 1) * dstride + 1 + index <= 256)
{
di = index;
dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
}
else
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
}
else if (size * dstride > 256 && !ins->mSrc[1].mFinal)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
else
{
dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
}
if (size <= msize)
{
if (ins->mSrc[0].mTemp < 0)
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
else
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
for (int i = 0; i < size; i++)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, di));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
di += dstride;
if (di >= 256)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_INC, ASMIM_ZERO_PAGE, dreg + 1));
di &= 0xff;
}
}
return this;
}
else
{
NativeCodeBasicBlock* block = this;
if (size >= 256)
{
block = nproc->AllocateBlock();
if (dreg != BC_REG_ADDR && !ins->mSrc[1].mFinal)
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, dreg));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, dreg + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
dreg = BC_REG_ADDR;
}
if (ins->mSrc[0].mTemp < 0)
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
else
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* lblock2 = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, 0));
if (size >= 512)
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDX, ASMIM_IMMEDIATE, size >> 8));
this->Close(ins, lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_INY, ASMIM_IMPLIED));
lblock->Close(ins, lblock, lblock2, ASMIT_BNE);
lblock2->mIns.Push(NativeCodeInstruction(ins, ASMIT_INC, ASMIM_ZERO_PAGE, dreg + 1));
if (size >= 512)
{
lblock2->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEX, ASMIM_IMPLIED));
lblock2->Close(ins, lblock, block, ASMIT_BNE);
}
else
lblock2->Close(ins, block, nullptr, ASMIT_JMP);
size &= 0xff;
}
else
{
if (ins->mSrc[0].mTemp < 0)
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff));
else
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
}
if (size > 0)
{
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, size));
block->Close(ins, lblock, nullptr, ASMIT_JMP);
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags));
lblock->Close(ins, lblock, eblock, ASMIT_BNE);
block = eblock;
}
return block;
}
}
void NativeCodeBasicBlock::CallMalloc(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc)
{
if (ins->mSrc[0].mTemp < 0)
@ -22517,6 +22865,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
}
}
if (mTrueJump) mTrueJump->CheckLive();
if (mFalseJump) mFalseJump->CheckLive();
#if 1
if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2)
{
@ -23080,6 +23430,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
mTrueJump->mIns.Insert(0, pb->mIns[ps - 1]);
mTrueJump->mEntryRequiredRegs += CPU_REG_X;
mFalseJump->BuildSingleExit(proc, this);
mFalseJump->mIns.Insert(0, pb->mIns[ps - 1]);
mFalseJump->mEntryRequiredRegs += CPU_REG_X;
@ -23108,6 +23460,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
mTrueJump->mIns.Insert(0, pb->mIns[ps - 1]);
mTrueJump->mEntryRequiredRegs += CPU_REG_Y;
mFalseJump->BuildSingleExit(proc, this);
mFalseJump->mIns.Insert(0, pb->mIns[ps - 1]);
mFalseJump->mEntryRequiredRegs += CPU_REG_Y;
@ -23559,6 +23913,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
}
CheckLive();
mProc->CheckBlocks();
if (mTrueJump && mTrueJump->JoinTailCodeSequences(proc, loops))
changed = true;
@ -45639,9 +45994,9 @@ void NativeCodeBasicBlock::CheckAsmCode(void)
void NativeCodeBasicBlock::CheckBlocks(bool sequence)
{
#if _DEBUG
if (!mVisited)
if (!mChecked)
{
mVisited = true;
mChecked = true;
assert(this != mProc->mEntryBlock || mNumEntries < 2);
@ -45666,6 +46021,12 @@ void NativeCodeBasicBlock::CheckLive(void)
#if _DEBUG
uint32 live = 0;
if (mFalseJump && mFalseJump->mEntryRequiredRegs.Size() > 0 && mFalseJump->mEntryRequiredRegs[CPU_REG_X])
{
if (mFalseJump->mIns.Size() > 0 && mFalseJump->mIns[0].RequiresXReg())
assert(mExitRequiredRegs[CPU_REG_X]);
}
assert(mBranch == ASMIT_RTS || (mBranch == ASMIT_JMP) == (mFalseJump == nullptr));
if (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS)
@ -46403,7 +46764,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test3");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "chareditor");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -47010,6 +47371,14 @@ void NativeCodeProcedure::RebuildEntry(void)
mEntryBlock->BuildDominatorTree(nullptr, stacks);
}
void NativeCodeProcedure::CheckBlocks(bool sequence)
{
#if _DEBUG
ResetChecked();
mEntryBlock->CheckBlocks();
#endif
}
void NativeCodeProcedure::Optimize(void)
{
#if 1
@ -47019,10 +47388,7 @@ void NativeCodeProcedure::Optimize(void)
CheckCase = false;
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
bool changed, xmapped = false, ymapped = false;
do
@ -47168,10 +47534,7 @@ void NativeCodeProcedure::Optimize(void)
{
changed = true;
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
BuildDataFlowSets();
ResetVisited();
@ -47186,10 +47549,7 @@ void NativeCodeProcedure::Optimize(void)
if (mEntryBlock->AbsoluteValueForwarding(pairs))
{
changed = true;
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
BuildDataFlowSets();
ResetVisited();
@ -47197,10 +47557,7 @@ void NativeCodeProcedure::Optimize(void)
}
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
#if 1
@ -47297,10 +47654,7 @@ void NativeCodeProcedure::Optimize(void)
RebuildEntry();
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks(true);
#endif
CheckBlocks();
#if 1
if (step == 2)
@ -47326,10 +47680,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks(true);
#endif
CheckBlocks();
#if 1
@ -47377,10 +47728,7 @@ void NativeCodeProcedure::Optimize(void)
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks(true);
#endif
CheckBlocks();
#if 1
if (step == 3 || step == 4)
@ -47391,10 +47739,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks(true);
#endif
CheckBlocks(true);
#if 1
ResetVisited();
@ -47402,16 +47747,14 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks(true);
#endif
CheckBlocks(true);
#if 1
ResetVisited();
if (mEntryBlock->ReduceLocalYPressure())
changed = true;
#endif
CheckBlocks(true);
#if 1
if (step == 4)
@ -47422,17 +47765,23 @@ void NativeCodeProcedure::Optimize(void)
}
#endif
CheckBlocks(true);
#if 1
ResetVisited();
if (!changed && mEntryBlock->ShortcutZeroPageCopyUp(this))
changed = true;
#endif
CheckBlocks(true);
#if 1
ResetVisited();
if (!changed && mEntryBlock->CrossBlockXYShortcut())
changed = true;
#endif
CheckBlocks(true);
#if 1
ResetVisited();
if (!changed && mEntryBlock->CrossBlockXYPreservation())
@ -47441,10 +47790,7 @@ void NativeCodeProcedure::Optimize(void)
}
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
if (step > 4 && !changed)
@ -47461,10 +47807,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
#if 1
if (step == 5 || step == 6)
@ -47554,10 +47897,7 @@ void NativeCodeProcedure::Optimize(void)
}
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
#if 1
ResetVisited();
@ -47615,10 +47955,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
if (step == 7)
{
@ -47636,10 +47973,8 @@ void NativeCodeProcedure::Optimize(void)
#if 1
if (step == 9 && cnt < 10)
{
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
ResetVisited();
while (mEntryBlock->OptimizeXYSpilling())
{
@ -47650,10 +47985,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
}
#endif
@ -47672,10 +48004,7 @@ void NativeCodeProcedure::Optimize(void)
}
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
#if 1
ResetVisited();
@ -47695,10 +48024,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
#endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
#if 1
if (step == 6)
@ -47707,18 +48033,13 @@ void NativeCodeProcedure::Optimize(void)
if (mEntryBlock->SimplifyDiamond(this))
changed = true;
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
ResetVisited();
if (mEntryBlock->SimplifyLoopEnd(this))
changed = true;
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
}
#endif
@ -47751,10 +48072,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
if (step == 6 || step == 7)
{
@ -47771,10 +48089,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true;
}
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
#if 1
@ -47979,10 +48294,7 @@ void NativeCodeProcedure::Optimize(void)
if (mEntryBlock->RemoveUnusedResultInstructions())
changed = true;
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
CheckBlocks();
if (!changed)
{
@ -48125,6 +48437,15 @@ void NativeCodeProcedure::ResetPatched(void)
}
}
void NativeCodeProcedure::ResetChecked(void)
{
for (int i = 0; i < mBlocks.Size(); i++)
{
mBlocks[i]->mChecked = false;
}
}
void NativeCodeProcedure::ResetVisited(void)
{
for (int i = 0; i < mBlocks.Size(); i++)
@ -48286,6 +48607,9 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
else
block->LoadValue(iproc, ins);
break;
case IC_FILL:
block = block->FillValue(iproc, ins, this);
break;
case IC_COPY:
block = block->CopyValue(iproc, ins, this);
break;

View File

@ -239,7 +239,7 @@ public:
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX;
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked;
NativeCodeBasicBlock * mDominator, * mSameBlock;
NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock;
@ -354,6 +354,7 @@ public:
void BinaryDivModPair(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins1, const InterInstruction* ins2);
void NumericConversion(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
NativeCodeBasicBlock * FillValue(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc);
NativeCodeBasicBlock * CopyValue(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure* nproc);
NativeCodeBasicBlock * StrcpyValue(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc);
void AddAsrSignedByte(InterCodeProcedure* proc, const InterInstruction* ains, const InterInstruction* sins);
@ -784,10 +785,12 @@ class NativeCodeProcedure
void BuildDataFlowSets(void);
void ResetEntryBlocks(void);
void ResetChecked(void);
void ResetVisited(void);
void ResetPatched(void);
void RebuildEntry(void);
void ResetIndexFlipped(void);
void CheckBlocks(bool sequence = false);
void SaveTempsToStack(int tempSave);
void LoadTempsFromStack(int tempSave);