Fix drop of Y register in asm code
This commit is contained in:
parent
b3ed9cf160
commit
71a65ce87d
|
@ -27,6 +27,7 @@ struct XMMU
|
|||
|
||||
#define xmmu (*((struct XMMU *)0xd500))
|
||||
|
||||
inline char mmu_set(char cr);
|
||||
|
||||
#pragma compile("mmu.c")
|
||||
|
||||
|
|
|
@ -3628,11 +3628,19 @@ W1:
|
|||
sec
|
||||
sbc #$8e
|
||||
bcc W2
|
||||
bit accu + 3
|
||||
bmi W5
|
||||
lda #$ff
|
||||
sta accu
|
||||
lda #$7f
|
||||
sta accu + 1
|
||||
bne W3
|
||||
rts
|
||||
W5:
|
||||
lda #$00
|
||||
sta accu
|
||||
lda #$80
|
||||
sta accu + 1
|
||||
rts
|
||||
W2:
|
||||
tax
|
||||
L1:
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define CHAR_MIN SCHAR_MIN
|
||||
#define CHAR_MAX SCHAR_MAX
|
||||
|
||||
#define INT_MIN -32767
|
||||
#define INT_MIN (-32767-1)
|
||||
#define INT_MAX 32767
|
||||
#define UINT_MAX 65535
|
||||
|
||||
|
|
|
@ -517,6 +517,41 @@ Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataS
|
|||
return this;
|
||||
}
|
||||
|
||||
static int64 signextend(int64 v, Declaration* type)
|
||||
{
|
||||
if (type->mFlags & DTF_SIGNED)
|
||||
{
|
||||
switch (type->mSize)
|
||||
{
|
||||
case 1:
|
||||
if (v & 0x80)
|
||||
return (v & 0xff) - 0x100;
|
||||
else
|
||||
return v;
|
||||
case 2:
|
||||
if (v & 0x8000)
|
||||
return (v & 0xffff) - 0x10000;
|
||||
else
|
||||
return v;
|
||||
default:
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (type->mSize)
|
||||
{
|
||||
case 1:
|
||||
return v & 0xff;
|
||||
case 2:
|
||||
return v & 0xffff;
|
||||
default:
|
||||
return v & 0xffffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection, Linker* linker)
|
||||
{
|
||||
if (mType == EX_PREFIX && mToken == TK_BANKOF && linker)
|
||||
|
@ -554,11 +589,14 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
{
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration * dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
if (mLeft->mDecValue->mBase->mSize <= 2)
|
||||
|
||||
if (mLeft->mDecValue->mBase->mSize < 2)
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
else
|
||||
dec->mBase = TheSignedLongTypeDeclaration;
|
||||
dec->mInteger = - mLeft->mDecValue->mInteger;
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
|
||||
dec->mInteger = signextend ( - mLeft->mDecValue->mInteger, dec->mBase );
|
||||
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
|
@ -568,17 +606,12 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
|
||||
dec->mInteger = ~mLeft->mDecValue->mInteger;
|
||||
if (mLeft->mDecValue->mBase->mSize <= 2)
|
||||
{
|
||||
dec->mInteger &= 0xffff;
|
||||
dec->mBase = TheUnsignedIntTypeDeclaration;
|
||||
}
|
||||
if (mLeft->mDecValue->mBase->mSize < 2)
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
else
|
||||
{
|
||||
dec->mInteger &= 0xffffffff;
|
||||
dec->mBase = TheUnsignedLongTypeDeclaration;
|
||||
}
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
|
||||
dec->mInteger = signextend( ~mLeft->mDecValue->mInteger, dec->mBase );
|
||||
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
|
@ -750,6 +783,11 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
{
|
||||
int64 ival = 0, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
|
||||
|
||||
bool signop =
|
||||
(mLeft->mDecValue->mBase->mSize < 2 || (mLeft->mDecValue->mBase->mFlags & DTF_SIGNED)) &&
|
||||
(mRight->mDecValue->mBase->mSize < 2 || (mRight->mDecValue->mBase->mFlags & DTF_SIGNED));
|
||||
|
||||
bool promote = true;
|
||||
switch (mToken)
|
||||
{
|
||||
case TK_ADD:
|
||||
|
@ -764,20 +802,26 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
case TK_DIV:
|
||||
if (iright == 0)
|
||||
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
|
||||
else
|
||||
else if (signop)
|
||||
ival = ileft / iright;
|
||||
else
|
||||
ival = (uint64)ileft / (uint64)iright;
|
||||
break;
|
||||
case TK_MOD:
|
||||
if (iright == 0)
|
||||
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
|
||||
else
|
||||
else if (signop)
|
||||
ival = ileft % iright;
|
||||
else
|
||||
ival = (uint64)ileft % (uint64)iright;
|
||||
break;
|
||||
case TK_LEFT_SHIFT:
|
||||
ival = ileft << iright;
|
||||
promote = false;
|
||||
break;
|
||||
case TK_RIGHT_SHIFT:
|
||||
ival = ileft >> iright;
|
||||
promote = false;
|
||||
break;
|
||||
case TK_BINARY_AND:
|
||||
ival = ileft & iright;
|
||||
|
@ -794,10 +838,21 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
if (promote)
|
||||
{
|
||||
if (mLeft->mDecValue->mBase->mSize <= 2 && mRight->mDecValue->mBase->mSize <= 2)
|
||||
dec->mBase = ival < 32768 ? TheSignedIntTypeDeclaration : TheUnsignedIntTypeDeclaration;
|
||||
else
|
||||
dec->mBase = ival < 2147483648 ? TheSignedLongTypeDeclaration : TheUnsignedLongTypeDeclaration;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mLeft->mDecValue->mBase->mSize < 2)
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
else
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
}
|
||||
|
||||
dec->mInteger = ival;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
|
|
|
@ -1666,6 +1666,7 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
if (op1.mType == IT_FLOAT)
|
||||
dop.mFloatConst = op1.mFloatConst / op2.mFloatConst;
|
||||
else
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) / ToTypedUnsigned(op2.mIntConst, op1.mType);
|
||||
dop.mIntConst = op1.mIntConst / op2.mIntConst;
|
||||
break;
|
||||
case IA_DIVS:
|
||||
|
@ -1673,15 +1674,15 @@ static InterOperand OperandConstantFolding(InterOperator oper, InterOperand op1,
|
|||
if (op1.mType == IT_FLOAT)
|
||||
dop.mFloatConst = op1.mFloatConst / op2.mFloatConst;
|
||||
else
|
||||
dop.mIntConst = op1.mIntConst / op2.mIntConst;
|
||||
dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) / ToTypedSigned(op2.mIntConst, op1.mType);
|
||||
break;
|
||||
case IA_MODU:
|
||||
dop.mType = op1.mType;
|
||||
dop.mIntConst = op1.mIntConst % op2.mIntConst;
|
||||
dop.mIntConst = ToTypedUnsigned(op1.mIntConst, op1.mType) % ToTypedUnsigned(op2.mIntConst, op1.mType);
|
||||
break;
|
||||
case IA_MODS:
|
||||
dop.mType = op1.mType;
|
||||
dop.mIntConst = op1.mIntConst % op2.mIntConst;
|
||||
dop.mIntConst = ToTypedSigned(op1.mIntConst, op1.mType) % ToTypedSigned(op2.mIntConst, op1.mType);
|
||||
break;
|
||||
case IA_OR:
|
||||
dop.mType = op1.mType;
|
||||
|
@ -5257,6 +5258,38 @@ bool InterInstruction::ConstantFolding(void)
|
|||
return true;
|
||||
}
|
||||
break;
|
||||
case IC_SELECT:
|
||||
if (mSrc[2].mTemp < 0)
|
||||
{
|
||||
bool cond = mSrc[2].mIntConst != 0;
|
||||
|
||||
if (IsIntegerType(mSrc[2].mType))
|
||||
cond = mSrc[2].mIntConst != 0;
|
||||
else if (mSrc[2].mType == IT_FLOAT)
|
||||
cond = mSrc[2].mFloatConst != 0;
|
||||
else if (mSrc[2].mType == IT_POINTER)
|
||||
{
|
||||
if (mSrc[2].mMemory == IM_ABSOLUTE)
|
||||
cond = mSrc[2].mIntConst != 0;
|
||||
else
|
||||
cond = true;
|
||||
}
|
||||
|
||||
int ci = cond ? 1 : 0;
|
||||
if (mSrc[ci].mTemp < 0)
|
||||
{
|
||||
mCode = IC_CONSTANT;
|
||||
mConst = mSrc[ci];
|
||||
}
|
||||
else
|
||||
{
|
||||
mCode = IC_LOAD_TEMPORARY;
|
||||
mSrc[0] = mSrc[ci];
|
||||
}
|
||||
mNumOperands = 1;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -7363,6 +7396,14 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
|
|||
(cins->mSrc[0].mRange.mMinValue < 0 && cins->mSrc[1].mRange.mMaxValue >= 256 + cins->mSrc[0].mRange.mMinValue ||
|
||||
cins->mSrc[1].mRange.mMinValue < 0 && cins->mSrc[0].mRange.mMaxValue >= 256 + cins->mSrc[1].mRange.mMinValue))
|
||||
;
|
||||
else if (cins->mSrc[0].mType == IT_INT16 && cins->mSrc[1].mType == IT_INT16 &&
|
||||
(cins->mSrc[0].mRange.mMinValue < 0 && cins->mSrc[1].mRange.mMaxValue >= 65536 + cins->mSrc[0].mRange.mMinValue ||
|
||||
cins->mSrc[1].mRange.mMinValue < 0 && cins->mSrc[0].mRange.mMaxValue >= 65536 + cins->mSrc[1].mRange.mMinValue))
|
||||
;
|
||||
else if (cins->mSrc[0].mType == IT_INT32 && cins->mSrc[1].mType == IT_INT32 &&
|
||||
(cins->mSrc[0].mRange.mMinValue < 0 && cins->mSrc[1].mRange.mMaxValue >= 0x100000000ll + cins->mSrc[0].mRange.mMinValue ||
|
||||
cins->mSrc[1].mRange.mMinValue < 0 && cins->mSrc[0].mRange.mMaxValue >= 0x100000000ll + cins->mSrc[1].mRange.mMinValue))
|
||||
;
|
||||
else if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue || cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue)
|
||||
constFalse = true;
|
||||
break;
|
||||
|
@ -7371,6 +7412,14 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
|
|||
(cins->mSrc[0].mRange.mMinValue < 0 && cins->mSrc[1].mRange.mMaxValue >= 256 + cins->mSrc[0].mRange.mMinValue ||
|
||||
cins->mSrc[1].mRange.mMinValue < 0 && cins->mSrc[0].mRange.mMaxValue >= 256 + cins->mSrc[1].mRange.mMinValue))
|
||||
;
|
||||
else if (cins->mSrc[0].mType == IT_INT16 && cins->mSrc[1].mType == IT_INT16 &&
|
||||
(cins->mSrc[0].mRange.mMinValue < 0 && cins->mSrc[1].mRange.mMaxValue >= 65536 + cins->mSrc[0].mRange.mMinValue ||
|
||||
cins->mSrc[1].mRange.mMinValue < 0 && cins->mSrc[0].mRange.mMaxValue >= 65536 + cins->mSrc[1].mRange.mMinValue))
|
||||
;
|
||||
else if (cins->mSrc[0].mType == IT_INT32 && cins->mSrc[1].mType == IT_INT32 &&
|
||||
(cins->mSrc[0].mRange.mMinValue < 0 && cins->mSrc[1].mRange.mMaxValue >= 0x100000000ll + cins->mSrc[0].mRange.mMinValue ||
|
||||
cins->mSrc[1].mRange.mMinValue < 0 && cins->mSrc[0].mRange.mMaxValue >= 0x100000000ll + cins->mSrc[1].mRange.mMinValue))
|
||||
;
|
||||
else if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue || cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue)
|
||||
constTrue = true;
|
||||
break;
|
||||
|
@ -8557,6 +8606,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSetsForward(const GrowingVariab
|
|||
vr.LimitMax(ins->mSrc[1].mRange.mMaxValue);
|
||||
else
|
||||
vr.mMaxState = IntegerValueRange::S_UNBOUND;
|
||||
if (vr.mMaxValue < 0)
|
||||
vr.mMaxState = IntegerValueRange::S_UNBOUND;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -9165,6 +9216,8 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
if (s1 >= 0)
|
||||
{
|
||||
if (s0 < 0)
|
||||
{
|
||||
if (mInstructions[sz - 2]->mSrc[0].mIntConst > 0)
|
||||
{
|
||||
mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst - 1);
|
||||
|
||||
|
@ -9178,6 +9231,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
mFalseValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mInstructions[sz - 2]->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND)
|
||||
{
|
||||
mTrueValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mRange.mMaxValue - 1);
|
||||
|
@ -9215,12 +9269,15 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
|
||||
mTrueValueRange[s1].LimitMin(1);
|
||||
if (s0 < 0)
|
||||
{
|
||||
if (mInstructions[sz - 2]->mSrc[0].mIntConst >= 0)
|
||||
{
|
||||
mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1);
|
||||
mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
|
||||
mFalseValueRange[s1].LimitMin(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IA_CMPGEU:
|
||||
if (s0 < 0)
|
||||
|
|
|
@ -128,6 +128,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
|||
srins->mNumOperands = 2;
|
||||
block->Append(srins);
|
||||
|
||||
// Promote unsigned bitfields that fit into a signed int to signed int
|
||||
Declaration* vtype = v.mType;
|
||||
if (vtype->mSize == 2 && v.mBits < 16 && !(vtype->mFlags & DTF_SIGNED))
|
||||
vtype = TheSignedIntTypeDeclaration;
|
||||
|
||||
if (InterTypeSize[ins->mDst.mType] < v.mType->mSize)
|
||||
{
|
||||
InterInstruction* crins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
|
||||
|
@ -142,10 +147,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
|||
else
|
||||
crins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_EXT8TO32S : IA_EXT8TO32U;
|
||||
block->Append(crins);
|
||||
v = ExValue(v.mType, crins->mDst.mTemp, v.mReference - 1);
|
||||
v = ExValue(vtype, crins->mDst.mTemp, v.mReference - 1);
|
||||
}
|
||||
else
|
||||
v = ExValue(v.mType, srins->mDst.mTemp, v.mReference - 1);
|
||||
v = ExValue(vtype, srins->mDst.mTemp, v.mReference - 1);
|
||||
}
|
||||
else
|
||||
v = ExValue(v.mType, ins->mDst.mTemp, v.mReference - 1, v.mBits, v.mShift);
|
||||
|
@ -3218,7 +3223,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (!(vl.mType->mType == DT_TYPE_POINTER || vl.mType->IsNumericType()))
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a numeric or pointer type");
|
||||
else if (vl.mType->mType == DT_TYPE_INTEGER && vl.mType->mSize < 2)
|
||||
vl = CoerceType(proc, exp, block, inlineMapper, vl, TheUnsignedIntTypeDeclaration);
|
||||
vl = CoerceType(proc, exp, block, inlineMapper, vl, TheSignedIntTypeDeclaration);
|
||||
ins->mOperator = IA_NOT;
|
||||
break;
|
||||
case TK_MUL:
|
||||
|
@ -5839,14 +5844,30 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
|
||||
if (!strcmp(proc->mIdent->mString, "main"))
|
||||
{
|
||||
InterInstruction* zins = new InterInstruction(dec->mLocation, IC_CONSTANT);
|
||||
zins->mDst.mType = IT_INT16;
|
||||
zins->mDst.mTemp = proc->AddTemporary(IT_INT16);
|
||||
zins->mConst.mType = IT_INT16;
|
||||
zins->mConst.mIntConst = 0;
|
||||
exitBlock->Append(zins);
|
||||
|
||||
InterInstruction* rins = new InterInstruction(dec->mLocation, IC_RETURN_VALUE);
|
||||
rins->mSrc[0].mType = IT_INT16;
|
||||
rins->mSrc[0].mTemp = zins->mDst.mTemp;
|
||||
exitBlock->Append(rins);
|
||||
|
||||
mMainStartupBlock = entryBlock;
|
||||
}
|
||||
}
|
||||
else
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString);
|
||||
|
||||
if (strcmp(proc->mIdent->mString, "main"))
|
||||
{
|
||||
InterInstruction* ins = new InterInstruction(exp ? exp->mEndLocation : dec->mLocation, IC_RETURN);
|
||||
exitBlock->Append(ins);
|
||||
}
|
||||
|
||||
exitBlock->Close(nullptr, nullptr);
|
||||
|
||||
if (mErrors->mErrorCount == 0 && proc != mMainInitProc)
|
||||
|
|
|
@ -2154,7 +2154,7 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data)
|
|||
{
|
||||
if (data.mRegs[reg].mMode == NRDM_IMMEDIATE)
|
||||
{
|
||||
data.mRegs[reg].mValue = (data.mRegs[reg].mValue + 1) & 255;
|
||||
data.mRegs[reg].mValue = (data.mRegs[reg].mValue - 1) & 255;
|
||||
data.mRegs[CPU_REG_Z].mValue = data.mRegs[reg].mValue;
|
||||
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||
}
|
||||
|
@ -16989,7 +16989,7 @@ bool NativeCodeBasicBlock::CanGlobalSwapXY(void)
|
|||
return false;
|
||||
if (ins.mMode == ASMIM_ABSOLUTE_X && (ins.mType != ASMIT_LDY && !HasAsmInstructionMode(ins.mType, ASMIM_ABSOLUTE_Y)))
|
||||
return false;
|
||||
if (ins.mType == ASMIT_JSR && (ins.mFlags & (NCIF_USE_CPU_REG_X | NCIF_USE_ZP_32_X)))
|
||||
if (ins.mType == ASMIT_JSR && (ins.mFlags & (NCIF_USE_CPU_REG_X | NCIF_USE_CPU_REG_Y | NCIF_USE_ZP_32_X)))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -51643,7 +51643,6 @@ void NativeCodeProcedure::Optimize(void)
|
|||
ResetVisited();
|
||||
mEntryBlock->CheckAsmCode();
|
||||
#endif
|
||||
|
||||
int t = 0;
|
||||
#if 1
|
||||
do
|
||||
|
|
|
@ -2354,8 +2354,10 @@ void Scanner::ParseNumberToken(void)
|
|||
NextChar();
|
||||
mToken = TK_INTEGERUL;
|
||||
}
|
||||
else
|
||||
else if (mant <= 0x7fffffff)
|
||||
mToken = TK_INTEGERL;
|
||||
else
|
||||
mToken = TK_INTEGERUL;
|
||||
}
|
||||
else if (mant < 65536)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue