Change memset and memclr to intrinsic functions
This commit is contained in:
parent
85fad64e9c
commit
aa601a5727
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue