Add "*" symbol for current address in inline assembler
This commit is contained in:
parent
5ca651bc36
commit
60165a7fc3
|
@ -480,7 +480,7 @@ void bm_polygon_nc_fill(Bitmap * bm, ClipRect * clip, int * px, int * py, char n
|
|||
#define REG_D0 0x0a
|
||||
#define REG_D1 0x0b
|
||||
|
||||
static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up)
|
||||
static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
|
||||
{
|
||||
char ip = 0;
|
||||
|
||||
|
@ -491,6 +491,9 @@ static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, b
|
|||
// set pixel
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_D0);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case LINOP_SET:
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 6);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||
|
@ -499,6 +502,39 @@ static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, b
|
|||
ip += asm_im(BLIT_CODE + ip, ASM_EOR, 0xff);
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_AND, REG_SP);
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
break;
|
||||
case LINOP_OR:
|
||||
if (pattern != 0xff)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 6);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||
}
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_ORA, REG_SP);
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
break;
|
||||
case LINOP_XOR:
|
||||
if (pattern != 0xff)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 6);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||
}
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_EOR, REG_SP);
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
break;
|
||||
case LINOP_AND:
|
||||
if (pattern != 0xff)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||
}
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_EOR, 0xff);
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_AND, REG_SP);
|
||||
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
break;
|
||||
}
|
||||
|
||||
// m >= 0
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
|
@ -587,8 +623,21 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern)
|
|||
}
|
||||
}
|
||||
|
||||
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern)
|
||||
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op)
|
||||
{
|
||||
if (pattern == 0x00)
|
||||
{
|
||||
if (op == LINOP_SET)
|
||||
{
|
||||
pattern = 0xff;
|
||||
op = LINOP_AND;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else if (pattern == 0xff && op == LINOP_SET)
|
||||
op = LINOP_OR;
|
||||
|
||||
int dx = x1 - x0, dy = y1 - y0;
|
||||
byte quad = 0;
|
||||
if (dx < 0)
|
||||
|
@ -617,7 +666,7 @@ void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern)
|
|||
char ry = y0 & 7;
|
||||
int stride = 8 * bm->cwidth;
|
||||
|
||||
buildline(ry, (l + 1) & 0xff, dx, dy, (quad & 2) ? -stride : stride, quad & 1, quad & 2);
|
||||
buildline(ry, (l + 1) & 0xff, dx, dy, (quad & 2) ? -stride : stride, quad & 1, quad & 2, pattern, op);
|
||||
|
||||
callline(dp, bit, m, l >> 8, pattern);
|
||||
}
|
||||
|
@ -627,7 +676,7 @@ static int muldiv(int x, int mul, int div)
|
|||
return (int)((long)x * mul / div);
|
||||
}
|
||||
|
||||
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern)
|
||||
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op)
|
||||
{
|
||||
int dx = x1 - x0, dy = y1 - y0;
|
||||
|
||||
|
@ -711,7 +760,7 @@ void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char
|
|||
return;
|
||||
}
|
||||
|
||||
bmu_line(bm, x0, y0, x1, y1, pattern);
|
||||
bmu_line(bm, x0, y0, x1, y1, pattern, op);
|
||||
}
|
||||
|
||||
static inline void callddop(byte * src, byte * dst, byte pat)
|
||||
|
|
|
@ -48,6 +48,14 @@ enum BlitOp
|
|||
BLTOP_PATTERN_AND_SRC = BLIT_SRC | BLIT_PATTERN | BLIT_AND
|
||||
};
|
||||
|
||||
enum LineOp
|
||||
{
|
||||
LINOP_SET,
|
||||
LINOP_OR,
|
||||
LINOP_AND,
|
||||
LINOP_XOR
|
||||
};
|
||||
|
||||
extern char NineShadesOfGrey[9][8];
|
||||
|
||||
// Fast unsigned integer square root
|
||||
|
@ -102,10 +110,10 @@ inline bool bm_get(Bitmap * bm, int x, int y);
|
|||
inline void bm_put(Bitmap * bm, int x, int y, bool c);
|
||||
|
||||
// Draw an unclipped line using an eight bit pattern
|
||||
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern);
|
||||
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op);
|
||||
|
||||
// Draw a clipped line using an eight bit pattern
|
||||
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern);
|
||||
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op);
|
||||
|
||||
// Unclipped bit blit
|
||||
void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op);
|
||||
|
|
|
@ -545,8 +545,18 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
|
|||
case ASMIM_RELATIVE:
|
||||
if (!aexp)
|
||||
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
|
||||
else
|
||||
{
|
||||
if (aexp->mType == DT_LABEL_REF)
|
||||
{
|
||||
if (aexp->mBase->mBase)
|
||||
d[offset] = aexp->mOffset + aexp->mBase->mInteger - offset - 1;
|
||||
else
|
||||
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mIdent->mString);
|
||||
}
|
||||
else
|
||||
d[offset] = aexp->mInteger - offset - 1;
|
||||
}
|
||||
offset++;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -11683,6 +11683,49 @@ bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc)
|
|||
}
|
||||
|
||||
|
||||
bool NativeCodeBasicBlock::OptimizeSelect(NativeCodeProcedure* proc)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
if (mFalseJump && mIns.Size() > 0 && mIns.Last().ChangesAccuAndFlag() &&
|
||||
mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 &&
|
||||
!mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump &&
|
||||
mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
|
||||
mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
if (mBranch == ASMIT_BNE || mBranch == ASMIT_BEQ)
|
||||
{
|
||||
char vt = mTrueJump->mIns[0].mAddress, vf = mFalseJump->mIns[0].mAddress;
|
||||
mTrueJump = mTrueJump->mTrueJump;
|
||||
mFalseJump = nullptr;
|
||||
|
||||
if (mBranch == ASMIT_BEQ)
|
||||
{
|
||||
char t = vt; vt = vf; vf = t;
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, vt ^ vf));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, vt));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump && mTrueJump->OptimizeSelect(proc))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->OptimizeSelect(proc))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
// Size reduction violating various assumptions such as no branches in basic blocks
|
||||
// must be last step before actual assembly
|
||||
|
||||
|
@ -11931,6 +11974,33 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
|||
j += 2;
|
||||
i += 3;
|
||||
}
|
||||
else if (i + 5 < mIns.Size() &&
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 1].mType == ASMIT_CMP && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0x01 &&
|
||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0x00 &&
|
||||
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||
mIns[i + 4].mType == ASMIT_AND && mIns[i + 4].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 5].mType == ASMIT_EOR && mIns[i + 5].mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
char veq = mIns[i + 4].mAddress ^ mIns[i + 5].mAddress, vne = mIns[i + 5].mAddress;
|
||||
|
||||
mIns[j + 0] = mIns[i + 0];
|
||||
mIns[j + 1].mType = ASMIT_BEQ; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = veq != 0 ? 4 : 2;
|
||||
mIns[j + 2].mType = ASMIT_LDA; mIns[j + 2].mMode = ASMIM_IMMEDIATE; mIns[j + 2].mAddress = vne; mIns[j + 2].mFlags = 0;
|
||||
j += 3;
|
||||
if (veq != 0)
|
||||
{
|
||||
if (vne)
|
||||
mIns[j + 0].mType = ASMIT_BNE;
|
||||
else
|
||||
mIns[j + 0].mType = ASMIT_BEQ;
|
||||
mIns[j + 0].mMode = ASMIM_RELATIVE;
|
||||
mIns[j + 0].mAddress = 2;
|
||||
mIns[j + 1].mType = ASMIT_LDA; mIns[j + 1].mMode = ASMIM_IMMEDIATE; mIns[j + 1].mAddress = veq; mIns[j + 1].mFlags = 0;
|
||||
j += 2;
|
||||
}
|
||||
i += 6;
|
||||
}
|
||||
else
|
||||
mIns[j++] = mIns[i++];
|
||||
}
|
||||
|
@ -12480,6 +12550,92 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// move iny/dey/inx/dex down
|
||||
|
||||
for (int i = 0; i + 1 < mIns.Size(); i++)
|
||||
{
|
||||
if ((mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY) && !mIns[i + 1].ChangesYReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||
{
|
||||
if (!mIns[i + 1].RequiresYReg())
|
||||
{
|
||||
NativeCodeInstruction pins = mIns[i];
|
||||
mIns[i] = mIns[i + 1];
|
||||
mIns[i + 1] = pins;
|
||||
}
|
||||
else if (mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y)
|
||||
{
|
||||
if (mIns[i].mType == ASMIT_INY)
|
||||
mIns[i + 1].mAddress++;
|
||||
else
|
||||
mIns[i + 1].mAddress--;
|
||||
NativeCodeInstruction pins = mIns[i];
|
||||
mIns[i] = mIns[i + 1];
|
||||
mIns[i + 1] = pins;
|
||||
}
|
||||
}
|
||||
else if ((mIns[i].mType == ASMIT_INX || mIns[i].mType == ASMIT_DEX) && !mIns[i + 1].ChangesXReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||
{
|
||||
if (!mIns[i + 1].RequiresXReg())
|
||||
{
|
||||
NativeCodeInstruction pins = mIns[i];
|
||||
mIns[i] = mIns[i + 1];
|
||||
mIns[i + 1] = pins;
|
||||
}
|
||||
else if (mIns[i + 1].mMode == ASMIM_ABSOLUTE_X)
|
||||
{
|
||||
if (mIns[i].mType == ASMIT_INX)
|
||||
mIns[i + 1].mAddress++;
|
||||
else
|
||||
mIns[i + 1].mAddress--;
|
||||
NativeCodeInstruction pins = mIns[i];
|
||||
mIns[i] = mIns[i + 1];
|
||||
mIns[i + 1] = pins;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
// move tya/clc/adc/tay down
|
||||
for (int i = 0; i + 5 < mIns.Size(); i++)
|
||||
{
|
||||
if (mIns[i + 0].mType == ASMIT_TYA && mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
{
|
||||
if (mIns[i + 4].mType == ASMIT_LDA && (mIns[i + 4].mMode == ASMIM_IMMEDIATE || mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS || mIns[i + 4].mMode == ASMIM_ZERO_PAGE) &&
|
||||
mIns[i + 5].mType == ASMIT_STA && !(mIns[i + 5].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||
{
|
||||
mIns[i + 4].mLive |= LIVE_CPU_REG_Y;
|
||||
mIns[i + 5].mLive |= LIVE_CPU_REG_Y;
|
||||
if (mIns[i + 5].mMode == ASMIM_ABSOLUTE_Y)
|
||||
mIns[i + 5].mAddress += mIns[i + 2].mAddress;
|
||||
|
||||
mIns.Insert(i + 0, mIns[i + 4]); mIns.Remove(i + 5);
|
||||
mIns.Insert(i + 1, mIns[i + 5]); mIns.Remove(i + 6);
|
||||
}
|
||||
#if 1
|
||||
else if (i + 6 < mIns.Size() &&
|
||||
mIns[i + 4].mType == ASMIT_LDA && (mIns[i + 4].mMode == ASMIM_IMMEDIATE || mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS || mIns[i + 4].mMode == ASMIM_ZERO_PAGE) &&
|
||||
mIns[i + 5].mType == ASMIT_STA &&
|
||||
mIns[i + 6].mType == ASMIT_STA && !(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||
{
|
||||
mIns[i + 4].mLive |= LIVE_CPU_REG_Y;
|
||||
mIns[i + 5].mLive |= LIVE_CPU_REG_Y;
|
||||
mIns[i + 6].mLive |= LIVE_CPU_REG_Y;
|
||||
if (mIns[i + 5].mMode == ASMIM_ABSOLUTE_Y)
|
||||
mIns[i + 5].mAddress += mIns[i + 2].mAddress;
|
||||
if (mIns[i + 6].mMode == ASMIM_ABSOLUTE_Y)
|
||||
mIns[i + 6].mAddress += mIns[i + 2].mAddress;
|
||||
|
||||
mIns.Insert(i + 0, mIns[i + 4]); mIns.Remove(i + 5);
|
||||
mIns.Insert(i + 1, mIns[i + 5]); mIns.Remove(i + 6);
|
||||
mIns.Insert(i + 2, mIns[i + 6]); mIns.Remove(i + 7);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
|
||||
// reverse "sta t,lda abs,clc,adc t" to "sta t,clc,adc abs,nop"
|
||||
|
@ -14438,6 +14594,83 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (i + 3 < mIns.Size())
|
||||
{
|
||||
if (
|
||||
mIns[i + 0].mType == ASMIT_INY &&
|
||||
mIns[i + 1].mType == ASMIT_TYA &&
|
||||
mIns[i + 2].mType == ASMIT_CLC &&
|
||||
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_NOP;
|
||||
mIns[i + 3].mAddress++;
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_CLC &&
|
||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 2].mType == ASMIT_TAY &&
|
||||
mIns[i + 3].mType == ASMIT_INY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 1].mAddress++;
|
||||
mIns[i + 3].mType = ASMIT_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_INX &&
|
||||
mIns[i + 1].mType == ASMIT_TXA &&
|
||||
mIns[i + 2].mType == ASMIT_CLC &&
|
||||
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_NOP;
|
||||
mIns[i + 3].mAddress++;
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_CLC &&
|
||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 2].mType == ASMIT_TAX &&
|
||||
mIns[i + 3].mType == ASMIT_INX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 1].mAddress++;
|
||||
mIns[i + 3].mType = ASMIT_NOP;
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
if (pass > 2 && i + 4 < mIns.Size())
|
||||
{
|
||||
if (
|
||||
mIns[i + 0].mType == ASMIT_INY &&
|
||||
mIns[i + 1].mType == ASMIT_INY &&
|
||||
mIns[i + 2].mType == ASMIT_INY &&
|
||||
mIns[i + 3].mType == ASMIT_INY &&
|
||||
mIns[i + 4].mType == ASMIT_INY && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_TYA; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 1].mType = ASMIT_CLC; mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 2].mType = ASMIT_ADC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 5; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 3].mType = ASMIT_TAY;
|
||||
mIns[i + 4].mType = ASMIT_NOP;
|
||||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_INX &&
|
||||
mIns[i + 1].mType == ASMIT_INX &&
|
||||
mIns[i + 2].mType == ASMIT_INX &&
|
||||
mIns[i + 3].mType == ASMIT_INX &&
|
||||
mIns[i + 4].mType == ASMIT_INX && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_TXA; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 1].mType = ASMIT_CLC; mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 2].mType = ASMIT_ADC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 5; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
||||
mIns[i + 3].mType = ASMIT_TAX;
|
||||
mIns[i + 4].mType = ASMIT_NOP;
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (i + 5 < mIns.Size())
|
||||
{
|
||||
if (
|
||||
|
@ -15602,6 +15835,12 @@ void NativeCodeProcedure::Optimize(void)
|
|||
#endif
|
||||
#if 1
|
||||
|
||||
ResetVisited();
|
||||
if (mEntryBlock->OptimizeSelect(this))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (step > 0)
|
||||
{
|
||||
ResetVisited();
|
||||
|
|
|
@ -151,6 +151,8 @@ public:
|
|||
bool SimpleLoopReversal(NativeCodeProcedure* proc);
|
||||
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
|
||||
|
||||
bool OptimizeSelect(NativeCodeProcedure* proc);
|
||||
|
||||
NativeCodeBasicBlock* FindTailBlock(NativeCodeBasicBlock* head);
|
||||
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
||||
void CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
|
|
|
@ -2194,7 +2194,7 @@ Expression* Parser::ParseSwitchStatement(void)
|
|||
|
||||
|
||||
|
||||
Expression* Parser::ParseAssemblerBaseOperand(void)
|
||||
Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
|
||||
{
|
||||
Expression* exp = nullptr;
|
||||
Declaration* dec;
|
||||
|
@ -2203,7 +2203,7 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
|||
{
|
||||
case TK_SUB:
|
||||
mScanner->NextToken();
|
||||
exp = ParseAssemblerBaseOperand();
|
||||
exp = ParseAssemblerBaseOperand(pcasm, pcoffset);
|
||||
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||
|
@ -2220,6 +2220,16 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
|||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Cannot negate expression");
|
||||
break;
|
||||
|
||||
case TK_MUL:
|
||||
mScanner->NextToken();
|
||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
dec = new Declaration(mScanner->mLocation, DT_LABEL);
|
||||
exp->mDecType = TheUnsignedIntTypeDeclaration;
|
||||
exp->mDecValue = dec;
|
||||
dec->mInteger = pcoffset;
|
||||
dec->mBase = pcasm;
|
||||
break;
|
||||
|
||||
case TK_INTEGER:
|
||||
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||
dec->mInteger = mScanner->mTokenInteger;
|
||||
|
@ -2329,31 +2339,31 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
|||
return exp;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseAssemblerMulOperand(void)
|
||||
Expression* Parser::ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset)
|
||||
{
|
||||
Expression* exp = ParseAssemblerBaseOperand();
|
||||
Expression* exp = ParseAssemblerBaseOperand(pcasm, pcoffset);
|
||||
while (mScanner->mToken == TK_MUL || mScanner->mToken == TK_DIV || mScanner->mToken == TK_MOD)
|
||||
{
|
||||
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
||||
nexp->mToken = mScanner->mToken;
|
||||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseAssemblerBaseOperand();
|
||||
nexp->mRight = ParseAssemblerBaseOperand(pcasm, pcoffset);
|
||||
exp = nexp->ConstantFold(mErrors);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseAssemblerAddOperand(void)
|
||||
Expression* Parser::ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset)
|
||||
{
|
||||
Expression* exp = ParseAssemblerMulOperand();
|
||||
Expression* exp = ParseAssemblerMulOperand(pcasm, pcoffset);
|
||||
while (mScanner->mToken == TK_ADD || mScanner->mToken == TK_SUB)
|
||||
{
|
||||
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
||||
nexp->mToken = mScanner->mToken;
|
||||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseAssemblerMulOperand();
|
||||
nexp->mRight = ParseAssemblerMulOperand(pcasm, pcoffset);
|
||||
if (!nexp->mLeft->mDecValue || !nexp->mRight->mDecValue)
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid assembler operand");
|
||||
|
@ -2403,12 +2413,12 @@ Expression* Parser::ParseAssemblerAddOperand(void)
|
|||
return exp;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseAssemblerOperand(void)
|
||||
Expression* Parser::ParseAssemblerOperand(Declaration* pcasm, int pcoffset)
|
||||
{
|
||||
if (mScanner->mToken == TK_LESS_THAN)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
Expression* exp = ParseAssemblerOperand();
|
||||
Expression* exp = ParseAssemblerOperand(pcasm, pcoffset);
|
||||
|
||||
if (exp->mType == EX_CONSTANT)
|
||||
{
|
||||
|
@ -2478,7 +2488,7 @@ Expression* Parser::ParseAssemblerOperand(void)
|
|||
else if (mScanner->mToken == TK_GREATER_THAN)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
Expression* exp = ParseAssemblerOperand();
|
||||
Expression* exp = ParseAssemblerOperand(pcasm, pcoffset);
|
||||
|
||||
if (exp->mType == EX_CONSTANT)
|
||||
{
|
||||
|
@ -2546,7 +2556,7 @@ Expression* Parser::ParseAssemblerOperand(void)
|
|||
return exp;
|
||||
}
|
||||
else
|
||||
return ParseAssemblerAddOperand();
|
||||
return ParseAssemblerAddOperand(pcasm, pcoffset);
|
||||
}
|
||||
|
||||
void Parser::AddAssemblerRegister(const Ident* ident, int value)
|
||||
|
@ -2648,12 +2658,12 @@ Expression* Parser::ParseAssembler(void)
|
|||
{
|
||||
ilast->mAsmInsMode = ASMIM_IMMEDIATE;
|
||||
mScanner->NextToken();
|
||||
ilast->mLeft = ParseAssemblerOperand();
|
||||
ilast->mLeft = ParseAssemblerOperand(vdasm, offset);
|
||||
}
|
||||
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
ilast->mLeft = ParseAssemblerOperand();
|
||||
ilast->mLeft = ParseAssemblerOperand(vdasm, offset);
|
||||
if (mScanner->mToken == TK_COMMA)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
|
@ -2693,7 +2703,7 @@ Expression* Parser::ParseAssembler(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
ilast->mLeft = ParseAssemblerOperand();
|
||||
ilast->mLeft = ParseAssemblerOperand(vdasm, offset);
|
||||
if (mScanner->mToken == TK_COMMA)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
|
@ -2960,7 +2970,7 @@ void Parser::ParsePragma(void)
|
|||
{
|
||||
mScanner->NextToken();
|
||||
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||
Expression* exp = ParseAssemblerOperand();
|
||||
Expression* exp = ParseAssemblerOperand(nullptr, 0);
|
||||
|
||||
ConsumeToken(TK_COMMA);
|
||||
if (mScanner->mToken == TK_IDENT)
|
||||
|
|
|
@ -41,10 +41,10 @@ protected:
|
|||
Expression* ParseFunction(Declaration* dec);
|
||||
Expression* ParseAssembler(void);
|
||||
|
||||
Expression* ParseAssemblerBaseOperand(void);
|
||||
Expression* ParseAssemblerMulOperand(void);
|
||||
Expression* ParseAssemblerAddOperand(void);
|
||||
Expression* ParseAssemblerOperand(void);
|
||||
Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset);
|
||||
Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset);
|
||||
Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset);
|
||||
Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset);
|
||||
|
||||
void AddAssemblerRegister(const Ident* ident, int value);
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ int main(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.3.72");
|
||||
strcpy(strProductVersion, "1.3.73");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,3,72,0
|
||||
PRODUCTVERSION 1,3,72,0
|
||||
FILEVERSION 1,3,73,0
|
||||
PRODUCTVERSION 1,3,73,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.3.72.0"
|
||||
VALUE "FileVersion", "1.3.73.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.3.72.0"
|
||||
VALUE "ProductVersion", "1.3.73.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -3414,15 +3414,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{07197B62-14CB-4607-AF17-B93D06B4E603}"
|
||||
"PackageCode" = "8:{05C9040B-AB11-4EEF-B99C-0BC6CAB578AC}"
|
||||
"ProductCode" = "8:{A53359B5-4B83-418F-BE3F-60133D152224}"
|
||||
"PackageCode" = "8:{5B0C1429-92B6-4506-ABF5-36A623D4C056}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.3.72"
|
||||
"ProductVersion" = "8:1.3.73"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
|
|
@ -207,23 +207,23 @@ int main(void)
|
|||
|
||||
bm_line(&Screen, &SRect,
|
||||
p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y,
|
||||
p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, patt);
|
||||
p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, patt, LINOP_SET);
|
||||
|
||||
bm_line(&Screen, &SRect,
|
||||
p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y,
|
||||
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt);
|
||||
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt, LINOP_SET);
|
||||
|
||||
bm_line(&Screen, &SRect,
|
||||
p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y,
|
||||
p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, patt);
|
||||
p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, patt, LINOP_SET);
|
||||
|
||||
bm_line(&Screen, &SRect,
|
||||
p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y,
|
||||
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt);
|
||||
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt, LINOP_SET);
|
||||
}
|
||||
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
// getch();
|
||||
getch();
|
||||
|
||||
restore();
|
||||
|
||||
|
|
|
@ -40,10 +40,10 @@ void draw(ClipRect * cr, byte pattern)
|
|||
{
|
||||
for(int i=0; i<40; i ++)
|
||||
{
|
||||
bm_line(&Screen, cr, 8 * i, 0, 319, 5 * i, pattern);
|
||||
bm_line(&Screen, cr, 319, 5 * i, 319 - 8 * i, 199, pattern);
|
||||
bm_line(&Screen, cr, 319 - 8 * i, 199, 0, 199 - 5 * i, pattern);
|
||||
bm_line(&Screen, cr, 0, 199 - 5 * i, 8 * i, 0, pattern);
|
||||
bm_line(&Screen, cr, 8 * i, 0, 319, 5 * i, pattern, LINOP_SET);
|
||||
bm_line(&Screen, cr, 319, 5 * i, 319 - 8 * i, 199, pattern, LINOP_SET);
|
||||
bm_line(&Screen, cr, 319 - 8 * i, 199, 0, 199 - 5 * i, pattern, LINOP_SET);
|
||||
bm_line(&Screen, cr, 0, 199 - 5 * i, 8 * i, 0, pattern, LINOP_SET);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ int main(void)
|
|||
for(int j=0; j<10; j++)
|
||||
{
|
||||
int k = (j + 1) % 10;
|
||||
bm_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0xff);
|
||||
bm_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0xff, LINOP_SET);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue