diff --git a/include/crt.c b/include/crt.c index 2139929..d077e5f 100644 --- a/include/crt.c +++ b/include/crt.c @@ -64,7 +64,7 @@ __asm bcexec { lda ip pha - lda ip + 1 + lda ip + 1 pha lda accu sta ip @@ -145,6 +145,58 @@ W1: dey rts } +// divide accu by tmp result in accu, remainder in tmp + 4 + +__asm divmod32 +{ + sty tmpy + lda #0 + sta tmp + 4 + sta tmp + 5 + sta tmp + 6 + sta tmp + 7 + ldy #32 + clc +L1: rol accu + rol accu + 1 + rol accu + 2 + rol accu + 3 + rol tmp + 4 + rol tmp + 5 + rol tmp + 6 + rol tmp + 7 + + lda tmp + 4 + cmp tmp + 0 + lda tmp + 5 + sbc tmp + 1 + lda tmp + 6 + sbc tmp + 2 + lda tmp + 7 + sbc tmp + 3 + bcc W1 + lda tmp + 4 + sbc tmp + 0 + sta tmp + 4 + lda tmp + 5 + sbc tmp + 1 + sta tmp + 5 + lda tmp + 6 + sbc tmp + 2 + sta tmp + 6 + lda tmp + 7 + sbc tmp + 3 + sta tmp + 7 +W1: dey + bne L1 + rol accu + rol accu + 1 + rol accu + 2 + rol accu + 3 + ldy tmpy + rts +} + // Multiply accu by tmp result in tmp + 2 __asm mul16 @@ -2972,3 +3024,491 @@ W1: jsr fround.frup #pragma bytecode(BC_OP_CEIL_F32, inp_op_ceil_f32) +__asm inp_op_extrt +{ + lda (ip), y + iny + sta c1 + 1 + lda (ip), y + iny + sta c1 + 2 + lda (ip), y + iny + tax +c1: jsr $0000 + jmp startup.exec +} + +#pragma bytecode(BC_EXTRT, inp_op_extrt) + + +__asm inp_op_ext_u16 +{ + lda #0 + sta accu + 2 + sta accu + 3 +} + +#pragma bytecode(BC_CONV_U16_U32, inp_op_ext_u16) + + +__asm inp_op_ext_s16 +{ + lda accu + 1 + ora #$7f + bmi w1 + lda #0 +w1: + sta accu + 2 + sta accu + 3 +} + +#pragma bytecode(BC_CONV_I16_I32, inp_op_ext_s16) + +__asm inp_op_invert_32 +{ + lda accu + 0 + eor #$ff + sta accu + 0 + lda accu + 1 + eor #$ff + sta accu + 1 + lda accu + 2 + eor #$ff + sta accu + 2 + lda accu + 3 + eor #$ff + sta accu + 3 +} + +#pragma bytecode(BC_OP_INVERT_32, inp_op_invert_32) + +__asm inp_op_negate_32 +{ + jmp negaccu +} + +#pragma bytecode(BC_OP_NEGATE_32, inp_op_negate_32) + + +__asm inp_op_addr_32 +{ + clc + lda accu + 0 + adc $00, x + sta accu + 0 + lda accu + 1 + adc $01, x + sta accu + 1 + lda accu + 2 + adc $02, x + sta accu + 2 + lda accu + 3 + adc $03, x + sta accu + 3 +} + +#pragma bytecode(BC_BINOP_ADD_L32, inp_op_addr_32) + +__asm inp_op_subr_32 +{ + sec + lda accu + 0 + sbc $00, x + sta accu + 0 + lda accu + 1 + sbc $01, x + sta accu + 1 + lda accu + 2 + sbc $02, x + sta accu + 2 + lda accu + 3 + sbc $03, x + sta accu + 3 +} + +#pragma bytecode(BC_BINOP_SUB_L32, inp_op_subr_32) + +__asm inp_op_andr_32 +{ + lda accu + 0 + and $00, x + sta accu + 0 + lda accu + 1 + and $01, x + sta accu + 1 + lda accu + 2 + and $02, x + sta accu + 2 + lda accu + 3 + and $03, x + sta accu + 3 +} + +#pragma bytecode(BC_BINOP_AND_L32, inp_op_andr_32) + +__asm inp_op_orr_32 +{ + lda accu + 0 + ora $00, x + sta accu + 0 + lda accu + 1 + ora $01, x + sta accu + 1 + lda accu + 2 + ora $02, x + sta accu + 2 + lda accu + 3 + ora $03, x + sta accu + 3 +} + +#pragma bytecode(BC_BINOP_OR_L32, inp_op_orr_32) + +__asm inp_op_xorr_32 +{ + lda accu + 0 + eor $00, x + sta accu + 0 + lda accu + 1 + eor $01, x + sta accu + 1 + lda accu + 2 + eor $02, x + sta accu + 2 + lda accu + 3 + eor $03, x + sta accu + 3 +} + +#pragma bytecode(BC_BINOP_XOR_L32, inp_op_xorr_32) + +__asm inp_op_mulr_32 +{ + lda #0 + sta tmp + 4 + sta tmp + 5 + sta tmp + 6 + sta tmp + 7 + + lda $00, x + sta tmp + 0 + lda $01, x + sta tmp + 1 + lda $02, x + sta tmp + 2 + lda $03, x + sta tmp + 3 + ldx #32 +L1: lsr tmp + 3 + ror tmp + 2 + ror tmp + 1 + ror tmp + 0 + bcc W1 + clc + lda tmp + 4 + adc accu + sta tmp + 4 + lda tmp + 5 + adc accu + 1 + sta tmp + 5 + lda tmp + 6 + adc accu + 2 + sta tmp + 6 + lda tmp + 7 + adc accu + 3 + sta tmp + 7 +W1: asl accu + rol accu + 1 + rol accu + 2 + rol accu + 3 + dex + bne L1 + lda tmp + 4 + sta accu + lda tmp + 5 + sta accu + 1 + lda tmp + 6 + sta accu + 2 + lda tmp + 7 + sta accu + 3 +} + +#pragma bytecode(BC_BINOP_MUL_L32, inp_op_mulr_32) + +__asm negaccu32 +{ + sec + lda #0 + sbc accu + sta accu + lda #0 + sbc accu + 1 + sta accu + 1 + lda #0 + sbc accu + 2 + sta accu + 2 + lda #0 + sbc accu + 3 + sta accu + 3 + rts +} + +__asm negtmp32 +{ + sec + lda #0 + sbc tmp + sta tmp + lda #0 + sbc tmp + 1 + sta tmp + 1 + lda #0 + sbc tmp + 2 + sta tmp + 2 + lda #0 + sbc tmp + 3 + sta tmp + 3 + rts +} + +__asm inp_binop_div_u32 +{ + lda $00, x + sta tmp + 0 + lda $01, x + sta tmp + 1 + lda $02, x + sta tmp + 2 + lda $03, x + sta tmp + 3 + jsr divmod32 +} + +#pragma bytecode(BC_BINOP_DIV_U32, inp_binop_div_u32) + +__asm inp_binop_mod_u32 +{ + lda $00, x + sta tmp + 0 + lda $01, x + sta tmp + 1 + lda $02, x + sta tmp + 2 + lda $03, x + sta tmp + 3 + jsr divmod32 + lda tmp + 4 + sta accu + lda tmp + 5 + sta accu + 1 + lda tmp + 6 + sta accu + 2 + lda tmp + 7 + sta accu + 3 +} + +#pragma bytecode(BC_BINOP_MOD_U32, inp_binop_mod_u32) + +__asm inp_binop_div_s32 +{ + lda $00, x + sta tmp + 0 + lda $01, x + sta tmp + 1 + lda $02, x + sta tmp + 2 + lda $03, x + sta tmp + 3 + bit accu + 3 + bpl L1 + jsr negaccu32 + bit tmp + 3 + bpl L2 + jsr negtmp32 +L3: jsr divmod32 + rts +L1: bit tmp + 3 + bpl L3 + jsr negtmp32 +L2: jsr divmod32 + jsr negaccu32 +} + +#pragma bytecode(BC_BINOP_DIV_I32, inp_binop_div_s32) + +__asm inp_binop_mod_s32 +{ + lda $00, x + sta tmp + 0 + lda $01, x + sta tmp + 1 + lda $02, x + sta tmp + 2 + lda $03, x + sta tmp + 3 + bit accu + 3 + bpl L1 + jsr negaccu32 + bit tmp + 3 + bpl L2 + jsr negtmp32 +L3: jsr divmod32 + lda tmp + 4 + sta accu + lda tmp + 5 + sta accu + 1 + lda tmp + 6 + sta accu + 2 + lda tmp + 7 + sta accu + 3 + rts +L1: bit tmp + 3 + bpl L3 + jsr negtmp32 +L2: jsr divmod32 + lda tmp + 4 + sta accu + lda tmp + 5 + sta accu + 1 + lda tmp + 6 + sta accu + 2 + lda tmp + 7 + sta accu + 3 + jsr negaccu32 +} + +#pragma bytecode(BC_BINOP_MOD_I32, inp_binop_mod_s32) + +__asm inp_op_shl_l32 +{ + lda $00, x + and #31 + beq W1 + tax + lda accu + 0 +L1: asl + rol accu + 1 + rol accu + 2 + rol accu + 3 + dex + bne L1 + sta accu + 0 +W1: +} + +#pragma bytecode(BC_BINOP_SHL_L32, inp_op_shl_l32) + + +__asm inp_op_shr_u32 +{ + lda $00, x + and #31 + beq W1 + tax + lda accu + 3 +L1: lsr + ror accu + 2 + ror accu + 1 + ror accu + 0 + dex + bne L1 + sta accu + 3 +W1: +} + +#pragma bytecode(BC_BINOP_SHR_U32, inp_op_shr_u32) + +__asm inp_op_shr_s32 +{ + lda $00, x + and #31 + beq W1 + tax + lda accu + 3 +L1: cmp #$80 + ror + ror accu + 2 + ror accu + 1 + ror accu + 0 + dex + bne L1 + sta accu + 3 +W1: +} + +#pragma bytecode(BC_BINOP_SHR_I32, inp_op_shr_s32) + +__asm inp_op_cmp_u32 +{ + lda $03, x + cmp accu + 3 + bne cmpne + lda $02, x + cmp accu + 2 + bne cmpne + lda $01, x + cmp accu + 1 + bne cmpne + lda $00 , x + cmp accu + bne cmpne + + lda #0 + sta accu + sta accu + 1 + rts +cmp_lt: + lda #$ff + sta accu + sta accu +1 + rts +cmpne: + bcc cmp_lt + lda #1 + sta accu + lda #0 + sta accu + 1 + rts +} + +#pragma bytecode(BC_BINOP_CMP_U32, inp_op_cmp_u32) + +__asm inp_op_cmp_s32 +{ + lda accu + 3 + eor #$80 + sta accu + 3 + lda $03, x + eor #$80 + cmp accu + 3 + bne cmpne + lda $02, x + cmp accu + 2 + bne cmpne + lda $01, x + cmp accu + 1 + bne cmpne + lda $00 , x + cmp accu + bne cmpne + + lda #0 + sta accu + sta accu + 1 + rts +cmp_lt: + lda #$ff + sta accu + sta accu +1 + rts +cmpne: + bcc cmp_lt + lda #1 + sta accu + lda #0 + sta accu + 1 + rts +} + +#pragma bytecode(BC_BINOP_CMP_S32, inp_op_cmp_s32) diff --git a/include/crt.h b/include/crt.h index f189141..35cf9a6 100644 --- a/include/crt.h +++ b/include/crt.h @@ -161,7 +161,31 @@ enum ByteCode BC_COPY, BC_COPY_LONG, - BC_NATIVE = 0x75 + BC_EXTRT, + + BC_NATIVE = 0x75, + + BC_CONV_I16_I32 = 0x80, + BC_CONV_U16_U32, + + BC_OP_NEGATE_32, + BC_OP_INVERT_32, + + BC_BINOP_ADD_L32, + BC_BINOP_SUB_L32, + BC_BINOP_AND_L32, + BC_BINOP_OR_L32, + BC_BINOP_XOR_L32, + BC_BINOP_MUL_L32, + BC_BINOP_DIV_U32, + BC_BINOP_MOD_U32, + BC_BINOP_DIV_I32, + BC_BINOP_MOD_I32, + BC_BINOP_SHL_L32, + BC_BINOP_SHR_U32, + BC_BINOP_SHR_I32, + BC_BINOP_CMP_U32, + BC_BINOP_CMP_S32, }; #endif diff --git a/include/stdlib.c b/include/stdlib.c index 0a6a23f..9e4b79a 100644 --- a/include/stdlib.c +++ b/include/stdlib.c @@ -3,7 +3,7 @@ #include "stdio.h" #include "math.h" -void itoa(int n, char * s, int radix) +void itoa(int n, char * s, unsigned radix) { bool neg = n < 0; if (neg) @@ -35,7 +35,7 @@ void itoa(int n, char * s, int radix) } } -void utoa(unsigned int n, char * s, unsigned int radix) +void utoa(unsigned int n, char * s, unsigned radix) { int i = 0; do { @@ -57,6 +57,61 @@ void utoa(unsigned int n, char * s, unsigned int radix) } } +void ltoa(long n, char * s, unsigned radix) +{ + bool neg = n < 0; + if (neg) + { + n = - n; + } + + int i = 0; + do { + int d = n % radix; + if (d < 10) + d += '0'; + else + d += 'A' - 10; + s[i++] = d; + } while ((n /= radix) > 0); + + if (neg) + { + s[i++] = '-'; + } + s[i] = 0; + int j = 0; + while (j + 1 < i) + { + char c = s[j]; + s[j++] = s[--i]; + s[i] = c; + } +} + +void ultoa(unsigned long n, char * s, unsigned radix) +{ + int i = 0; + do { + unsigned int d = n % radix; + if (d < 10) + d += '0'; + else + d += 'A' - 10; + s[i++] = d; + } while ((n /= radix) > 0); + + s[i] = 0; + int j = 0; + while (j + 1 < i) + { + char c = s[j]; + s[j++] = s[--i]; + s[i] = c; + } +} + + void ftoa(float f, char * s) { if (f < 0.0) diff --git a/include/stdlib.h b/include/stdlib.h index 444a626..8c9f8e2 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -1,16 +1,21 @@ #ifndef STDLIB_H #define STDLIB_H -void itoa(int n, char * s, int radix); +void itoa(int n, char * s, unsigned radix); -void utoa(unsigned int n, char * s, unsigned int radix); +void utoa(unsigned int n, char * s, unsigned radix); void ftoa(float f, char * s); +void ltoa(long n, char * s, unsigned radix); + +void ultoa(unsigned long n, char * s, unsigned radix); + int atoi(const char * s); float atof(const char * s); + void exit(int status); void * malloc(unsigned int size); diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index fec5be4..c978495 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -102,6 +102,9 @@ bool ByteCodeInstruction::IsCommutative(void) const if (mCode == BC_BINOP_ADD_F32 || mCode == BC_BINOP_MUL_F32) return true; + if (mCode == BC_BINOP_ADD_L32 || mCode == BC_BINOP_AND_L32 || mCode == BC_BINOP_OR_L32 || mCode == BC_BINOP_XOR_L32 || mCode == BC_BINOP_MUL_L32) + return true; + return false; } @@ -191,6 +194,8 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const return true; if (mCode == BC_JSR || mCode == BC_CALL) return true; + if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32) + return true; } if (reg == BC_REG_ADDR) @@ -495,6 +500,39 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl } break; + case BC_CONV_I16_I32: + case BC_CONV_U16_U32: + case BC_OP_NEGATE_32: + case BC_OP_INVERT_32: + case BC_BINOP_ADD_L32: + case BC_BINOP_SUB_L32: + case BC_BINOP_AND_L32: + case BC_BINOP_OR_L32: + case BC_BINOP_XOR_L32: + case BC_BINOP_MUL_L32: + case BC_BINOP_DIV_U32: + case BC_BINOP_MOD_U32: + case BC_BINOP_DIV_I32: + case BC_BINOP_MOD_I32: + case BC_BINOP_SHL_L32: + case BC_BINOP_SHR_U32: + case BC_BINOP_SHR_I32: + case BC_BINOP_CMP_U32: + case BC_BINOP_CMP_S32: + { + block->PutCode(generator, BC_EXTRT); + + LinkerReference rl; + rl.mOffset = block->mCode.Size(); + rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE; + rl.mRefObject = generator->mExtByteCodes[mCode - 128]; + rl.mRefOffset = 0; + block->mRelocations.Push(rl); + block->PutWord(0); + block->PutByte(mRegister); + break; + } + default: assert(false); } @@ -570,6 +608,22 @@ void ByteCodeBasicBlock::IntConstToAccu(int64 val) mIns.Push(ins); } +void ByteCodeBasicBlock::LongConstToAccu(int64 val) +{ + ByteCodeInstruction bins(BC_CONST_32); + bins.mRegister = BC_REG_ACCU; + bins.mValue = int(val); + mIns.Push(bins); +} + +void ByteCodeBasicBlock::LongConstToWork(int64 val) +{ + ByteCodeInstruction bins(BC_CONST_32); + bins.mRegister = BC_REG_WORK; + bins.mValue = int(val); + mIns.Push(bins); +} + void ByteCodeBasicBlock::FloatConstToAccu(double val) { union { float f; int v; } cc; @@ -666,6 +720,13 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr bins.mValue = ins->mIntValue; mIns.Push(bins); } + else if (ins->mTType == IT_INT32) + { + ByteCodeInstruction bins(BC_CONST_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + bins.mValue = ins->mIntValue; + mIns.Push(bins); + } else { ByteCodeInstruction bins(BC_CONST_16); @@ -1005,7 +1066,10 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI { if (ins->mSTemp[0] < 0) { - IntConstToAccu(ins->mSIntConst[0]); + if (ins->mOperandSize <= 2) + IntConstToAccu(ins->mSIntConst[0]); + else + LongConstToAccu(ins->mSIntConst[0]); if (ins->mOperandSize == 1) { @@ -1113,6 +1177,59 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI mIns.Push(bins); } } + else if (ins->mOperandSize == 4) + { + if (ins->mMemory == IM_GLOBAL) + { + ByteCodeInstruction bins(BC_STORE_ABS_32); + bins.mRelocate = true; + bins.mLinkerObject = ins->mLinkerObject; + bins.mValue = ins->mSIntConst[1]; + bins.mRegister = BC_REG_ACCU; + mIns.Push(bins); + } + else if (ins->mMemory == IM_ABSOLUTE) + { + ByteCodeInstruction bins(BC_STORE_ABS_32); + bins.mValue = ins->mSIntConst[1]; + bins.mRegister = BC_REG_ACCU; + mIns.Push(bins); + } + else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) + { + int index = ins->mSIntConst[1]; + if (ins->mMemory == IM_LOCAL) + index += proc->mLocalVars[ins->mVarIndex]->mOffset; + else + index += ins->mVarIndex + proc->mLocalSize + 2; + + if (index <= 252) + { + ByteCodeInstruction bins(BC_STORE_LOCAL_32); + bins.mRegister = BC_REG_ACCU; + bins.mValue = index; + mIns.Push(bins); + } + else + { + ByteCodeInstruction lins(BC_LEA_LOCAL); + lins.mRegister = BC_REG_ADDR; + lins.mValue = index; + mIns.Push(lins); + ByteCodeInstruction bins(BC_STORE_ADDR_32); + bins.mRegister = BC_REG_ACCU; + bins.mValue = 0; + mIns.Push(bins); + } + } + else if (ins->mMemory == IM_FRAME) + { + ByteCodeInstruction bins(BC_STORE_FRAME_32); + bins.mRegister = BC_REG_ACCU; + bins.mValue = ins->mVarIndex + ins->mSIntConst[1] + 2; + mIns.Push(bins); + } + } } else { @@ -1232,13 +1349,74 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI mIns.Push(bins); } } + else if (ins->mOperandSize == 4) + { + if (ins->mMemory == IM_GLOBAL) + { + ByteCodeInstruction bins(BC_STORE_ABS_32); + bins.mRelocate = true; + bins.mLinkerObject = ins->mLinkerObject; + bins.mValue = ins->mSIntConst[1]; + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + bins.mRegisterFinal = ins->mSFinal[0]; + mIns.Push(bins); + } + else if (ins->mMemory == IM_ABSOLUTE) + { + ByteCodeInstruction bins(BC_STORE_ABS_32); + bins.mValue = ins->mSIntConst[1]; + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + bins.mRegisterFinal = ins->mSFinal[0]; + mIns.Push(bins); + } + else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) + { + int index = ins->mSIntConst[1]; + if (ins->mMemory == IM_LOCAL) + index += proc->mLocalVars[ins->mVarIndex]->mOffset; + else + index += ins->mVarIndex + proc->mLocalSize + 2; + + if (index <= 252) + { + ByteCodeInstruction bins(BC_STORE_LOCAL_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + bins.mRegisterFinal = ins->mSFinal[0]; + bins.mValue = index; + mIns.Push(bins); + } + else + { + ByteCodeInstruction lins(BC_LEA_LOCAL); + lins.mRegister = BC_REG_ADDR; + lins.mValue = index; + mIns.Push(lins); + ByteCodeInstruction bins(BC_STORE_ADDR_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + bins.mRegisterFinal = ins->mSFinal[0]; + bins.mValue = 0; + mIns.Push(bins); + } + } + else if (ins->mMemory == IM_FRAME) + { + ByteCodeInstruction bins(BC_STORE_FRAME_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + bins.mRegisterFinal = ins->mSFinal[0]; + bins.mValue = ins->mVarIndex + ins->mSIntConst[1] + 2; + mIns.Push(bins); + } + } } } else { if (ins->mSTemp[0] < 0) { - IntConstToAccu(ins->mSIntConst[0]); + if (ins->mOperandSize <= 2) + IntConstToAccu(ins->mSIntConst[0]); + else + LongConstToAccu(ins->mSIntConst[0]); if (ins->mMemory == IM_INDIRECT) { @@ -1260,6 +1438,13 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mValue = ins->mSIntConst[1]; mIns.Push(bins); } + else if (ins->mOperandSize == 4) + { + ByteCodeInstruction bins(BC_STORE_ADDR_32); + bins.mRegister = BC_REG_ACCU; + bins.mValue = ins->mSIntConst[1]; + mIns.Push(bins); + } } } else @@ -1286,6 +1471,14 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI bins.mValue = ins->mSIntConst[1]; mIns.Push(bins); } + else if (ins->mOperandSize == 4) + { + ByteCodeInstruction bins(BC_STORE_ADDR_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + bins.mRegisterFinal = ins->mSFinal[0]; + bins.mValue = ins->mSIntConst[1]; + mIns.Push(bins); + } } } } @@ -1516,6 +1709,52 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn } } } + else if (ins->mOperandSize == 4) + { + if (ins->mMemory == IM_GLOBAL) + { + ByteCodeInstruction bins(BC_LOAD_ABS_32); + bins.mRelocate = true; + bins.mLinkerObject = ins->mLinkerObject; + bins.mValue = ins->mSIntConst[0]; + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + mIns.Push(bins); + } + else if (ins->mMemory == IM_ABSOLUTE) + { + ByteCodeInstruction bins(BC_LOAD_ABS_32); + bins.mValue = ins->mSIntConst[0]; + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + mIns.Push(bins); + } + else if (ins->mMemory == IM_LOCAL || ins->mMemory == IM_PARAM) + { + int index = ins->mSIntConst[0]; + if (ins->mMemory == IM_LOCAL) + index += proc->mLocalVars[ins->mVarIndex]->mOffset; + else + index += ins->mVarIndex + proc->mLocalSize + 2; + + if (index <= 252) + { + ByteCodeInstruction bins(BC_LOAD_LOCAL_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + bins.mValue = index; + mIns.Push(bins); + } + else + { + ByteCodeInstruction lins(BC_LEA_LOCAL); + lins.mRegister = BC_REG_ADDR; + lins.mValue = index; + mIns.Push(lins); + ByteCodeInstruction bins(BC_LOAD_ADDR_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + bins.mValue = 0; + mIns.Push(bins); + } + } + } } else { @@ -1540,6 +1779,13 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn bins.mValue = ins->mSIntConst[0]; mIns.Push(bins); } + else if (ins->mOperandSize == 4) + { + ByteCodeInstruction bins(BC_LOAD_ADDR_32); + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + bins.mValue = ins->mSIntConst[0]; + mIns.Push(bins); + } } } } @@ -1745,6 +1991,38 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const cins.mRegisterFinal = ins->mSFinal[1]; mIns.Push(cins); } + else if (ins->mSType[0] == IT_INT32) + { + if (ins->mSTemp[0] < 0) + { + LongConstToAccu(ins->mSIntConst[0]); + } + else + { + ByteCodeInstruction lins(BC_LOAD_REG_32); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + lins.mRegisterFinal = ins->mSFinal[0]; + mIns.Push(lins); + } + + + ByteCodeInstruction cins(BC_BINOP_CMP_U32); + if (csigned) + cins.mCode = BC_BINOP_CMP_S32; + + if (ins->mSTemp[1] < 0) + { + LongConstToWork(ins->mSIntConst[1]); + cins.mRegister = BC_REG_WORK; + } + else + { + cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]; + } + + cins.mRegisterFinal = ins->mSFinal[1]; + mIns.Push(cins); + } else { if (ins->mSTemp[1] < 0) @@ -1828,6 +2106,29 @@ static ByteCode ByteCodeBinRegOperator(const InterInstruction * ins) return BC_EXIT; } } + else if (ins->mTType == IT_INT32) + { + switch (ins->mOperator) + { + case IA_ADD: return BC_BINOP_ADD_L32; + case IA_SUB: return BC_BINOP_SUB_L32; + case IA_MUL: return BC_BINOP_MUL_L32; + case IA_DIVU: return BC_BINOP_DIV_U32; + case IA_MODU: return BC_BINOP_MOD_U32; + case IA_DIVS: return BC_BINOP_DIV_I32; + case IA_MODS: return BC_BINOP_MOD_I32; + case IA_AND: return BC_BINOP_AND_L32; + case IA_OR: return BC_BINOP_OR_L32; + case IA_XOR: return BC_BINOP_XOR_L32; + + case IA_SHL: return BC_BINOP_SHL_L32; + case IA_SHR: return BC_BINOP_SHR_U32; + case IA_SAR: return BC_BINOP_SHR_I32; + + default: + return BC_EXIT; + } + } else { switch (ins->mOperator) @@ -1972,7 +2273,38 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter mIns.Push(sins); } } break; + case IA_EXT16TO32S: + { + ByteCodeInstruction lins(BC_LOAD_REG_16); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + lins.mRegisterFinal = ins->mSFinal[0]; + mIns.Push(lins); + ByteCodeInstruction cins(BC_CONV_I16_I32); + cins.mRegister = 0; + mIns.Push(cins); + + ByteCodeInstruction sins(BC_STORE_REG_32); + sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + mIns.Push(sins); + } break; + + case IA_EXT16TO32U: + { + ByteCodeInstruction lins(BC_LOAD_REG_16); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + lins.mRegisterFinal = ins->mSFinal[0]; + mIns.Push(lins); + + ByteCodeInstruction cins(BC_CONV_U16_U32); + cins.mRuntime = "lextu16"; + cins.mRegister = 0; + mIns.Push(cins); + + ByteCodeInstruction sins(BC_STORE_REG_32); + sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + mIns.Push(sins); + } break; } } @@ -2013,6 +2345,31 @@ void ByteCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterInst sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; mIns.Push(sins); } + else if (ins->mTType == IT_INT32) + { + ByteCodeInstruction lins(BC_LOAD_REG_32); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + lins.mRegisterFinal = ins->mSFinal[0]; + mIns.Push(lins); + + switch (ins->mOperator) + { + case IA_NEG: + { + ByteCodeInstruction oins(BC_OP_NEGATE_32); + mIns.Push(oins); + } break; + case IA_NOT: + { + ByteCodeInstruction oins(BC_OP_INVERT_32); + mIns.Push(oins); + } break; + } + + ByteCodeInstruction sins(BC_STORE_REG_32); + sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + mIns.Push(sins); + } else { ByteCodeInstruction lins(BC_LOAD_REG_16); @@ -2078,6 +2435,41 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; mIns.Push(sins); } + else if (ins->mTType == IT_INT32) + { + ByteCode bc = ByteCodeBinRegOperator(ins); + + if (ins->mSTemp[1] < 0) + { + LongConstToAccu(ins->mSIntConst[1]); + } + else + { + ByteCodeInstruction lins(BC_LOAD_REG_32); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]]; + lins.mRegisterFinal = ins->mSFinal[1]; + mIns.Push(lins); + } + + ByteCodeInstruction bins(bc); + + if (ins->mSTemp[0] < 0) + { + LongConstToWork(ins->mSIntConst[0]); + bins.mRegister = BC_REG_WORK; + } + else if (ins->mSTemp[1] == ins->mSTemp[0]) + bins.mRegister = BC_REG_ACCU; + else + bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]; + + bins.mRegisterFinal = ins->mSFinal[0]; + mIns.Push(bins); + + ByteCodeInstruction sins(BC_STORE_REG_32); + sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; + mIns.Push(sins); + } else { switch (ins->mOperator) @@ -3312,7 +3704,10 @@ ByteCodeGenerator::ByteCodeGenerator(Errors* errors, Linker* linker) : mErrors(errors), mLinker(linker) { for (int i = 0; i < 128; i++) + { mByteCodeUsed[i] = false; + mExtByteCodes[i] = nullptr; + } mByteCodeUsed[BC_LEA_ABS] = true; mByteCodeUsed[BC_CALL] = true; diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 8903210..a15d332 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -151,7 +151,31 @@ enum ByteCode BC_COPY, BC_COPY_LONG, - BC_NATIVE = 0x75 + BC_EXTRT, + + BC_NATIVE = 0x75, + + BC_CONV_I16_I32 = 0x80, + BC_CONV_U16_U32, + + BC_OP_NEGATE_32, + BC_OP_INVERT_32, + + BC_BINOP_ADD_L32, + BC_BINOP_SUB_L32, + BC_BINOP_AND_L32, + BC_BINOP_OR_L32, + BC_BINOP_XOR_L32, + BC_BINOP_MUL_L32, + BC_BINOP_DIV_U32, + BC_BINOP_MOD_U32, + BC_BINOP_DIV_I32, + BC_BINOP_MOD_I32, + BC_BINOP_SHL_L32, + BC_BINOP_SHR_U32, + BC_BINOP_SHR_I32, + BC_BINOP_CMP_U32, + BC_BINOP_CMP_S32 }; class ByteCodeProcedure; @@ -171,6 +195,7 @@ public: int mValue; bool mRelocate, mRegisterFinal; LinkerObject* mLinkerObject; + const char* mRuntime; bool IsStore(void) const; bool ChangesAccu(void) const; @@ -223,6 +248,8 @@ public: void CalculateOffset(int& total); void CopyCode(ByteCodeGenerator* generator, LinkerObject * linkerObject, uint8* target); + void LongConstToAccu(int64 val); + void LongConstToWork(int64 val); void IntConstToAccu(int64 val); void IntConstToAddr(int64 val); void FloatConstToAccu(double val); @@ -282,6 +309,7 @@ public: Linker* mLinker; bool mByteCodeUsed[128]; + LinkerObject* mExtByteCodes[128]; void WriteBasicHeader(void); void WriteByteCodeHeader(void); diff --git a/oscar64/CompilationUnits.cpp b/oscar64/CompilationUnits.cpp index 2fd7a89..e78ab47 100644 --- a/oscar64/CompilationUnits.cpp +++ b/oscar64/CompilationUnits.cpp @@ -16,7 +16,7 @@ CompilationUnits::CompilationUnits(Errors * errors) mRuntimeScope = new DeclarationScope(nullptr); mStartup = nullptr; - for (int i = 0; i < 128; i++) + for (int i = 0; i < 256; i++) mByteCodes[i] = nullptr; } diff --git a/oscar64/CompilationUnits.h b/oscar64/CompilationUnits.h index 6eef704..027ea0f 100644 --- a/oscar64/CompilationUnits.h +++ b/oscar64/CompilationUnits.h @@ -23,7 +23,7 @@ public: CompilationUnit* mCompilationUnits, * mPendingUnits; Declaration* mStartup; - Declaration* mByteCodes[128]; + Declaration* mByteCodes[256]; DeclarationScope* mRuntimeScope; diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 21f38c1..2539c19 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -183,7 +183,24 @@ bool Compiler::GenerateCode(void) RegisterRuntime(loc, Ident::Unique("fcmp")); RegisterRuntime(loc, Ident::Unique("bcexec")); - // + // Register extended byte code functions + + for (int i = 0; i < 128; i++) + { + Declaration* bcdec = mCompilationUnits->mByteCodes[i + 128]; + if (bcdec) + { + LinkerObject* linkerObject = nullptr; + + int offset = 0; + if (bcdec->mType == DT_CONST_ASSEMBLER) + { + if (!bcdec->mLinkerObject) + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue); + mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject; + } + } + } if (mErrors->mErrorCount != 0) return false; diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 0287189..3359924 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -483,7 +483,8 @@ bool Declaration::IsNumericType(void) const return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM; } -Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration; +Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration; +Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration; void InitDeclarations(void) { @@ -504,6 +505,14 @@ void InitDeclarations(void) TheUnsignedIntTypeDeclaration->mSize = 2; TheUnsignedIntTypeDeclaration->mFlags = DTF_DEFINED; + TheSignedLongTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER); + TheSignedLongTypeDeclaration->mSize = 4; + TheSignedLongTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED; + + TheUnsignedLongTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER); + TheUnsignedLongTypeDeclaration->mSize = 4; + TheUnsignedLongTypeDeclaration->mFlags = DTF_DEFINED; + TheSignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER); TheSignedCharTypeDeclaration->mSize = 1; TheSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED; diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 8e155d9..9a33518 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -174,4 +174,5 @@ public: void InitDeclarations(void); -extern Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration; +extern Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration; +extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration, * TheSignedLongTypeDeclaration, * TheUnsignedLongTypeDeclaration; diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index 403c3ff..92a8454 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -538,6 +538,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star i += 2; break; + case BC_EXTRT: + fprintf(file, "EXTRT\t%s, %08x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); + i += 3; + break; } fprintf(file, "\n"); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 7a8120a..eb3e494 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -251,12 +251,22 @@ static void ConversionConstantFold(InterInstruction * ins, InterInstruction * ci break; case IA_EXT8TO16S: ins->mCode = IC_CONSTANT; - ins->mIntValue = (char)(cins->mIntValue); + ins->mIntValue = (int8)(cins->mIntValue); ins->mSTemp[0] = -1; break; case IA_EXT8TO16U: ins->mCode = IC_CONSTANT; - ins->mIntValue = (unsigned char)(cins->mIntValue); + ins->mIntValue = (uint8)(cins->mIntValue); + ins->mSTemp[0] = -1; + break; + case IA_EXT16TO32S: + ins->mCode = IC_CONSTANT; + ins->mIntValue = (int16)(cins->mIntValue); + ins->mSTemp[0] = -1; + break; + case IA_EXT16TO32U: + ins->mCode = IC_CONSTANT; + ins->mIntValue = (uint16)(cins->mIntValue); ins->mSTemp[0] = -1; break; } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 4984490..49634bd 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -148,6 +148,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p stemp = xins->mTTemp; } } + else if (v.mType->mSize == 2 && type->mSize == 4) + { + if (v.mType->mFlags & DTF_SIGNED) + { + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_CONVERSION_OPERATOR; + xins->mOperator = IA_EXT16TO32S; + xins->mSType[0] = IT_INT16; + xins->mSTemp[0] = stemp; + xins->mTType = IT_INT32; + xins->mTTemp = proc->AddTemporary(IT_INT32); + block->Append(xins); + stemp = xins->mTTemp; + } + else + { + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_CONVERSION_OPERATOR; + xins->mOperator = IA_EXT16TO32U; + xins->mSType[0] = IT_INT16; + xins->mSTemp[0] = stemp; + xins->mTType = IT_INT32; + xins->mTTemp = proc->AddTemporary(IT_INT32); + block->Append(xins); + stemp = xins->mTTemp; + } + } v.mTemp = stemp; v.mType = type; @@ -507,27 +534,44 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { if (dec->mInteger < -128 || dec->mInteger > 127) mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); + ins->mIntValue = int8(dec->mInteger); } else { if (dec->mInteger < 0 || dec->mInteger > 255) mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated"); + ins->mIntValue = uint8(dec->mInteger); } - ins->mIntValue = char(dec->mInteger); } - else if (ins->mTType == IT_INT8) + else if (ins->mTType == IT_INT16) { if (dec->mFlags & DTF_SIGNED) { if (dec->mInteger < -32768 || dec->mInteger > 32767) mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); + ins->mIntValue = int16(dec->mInteger); } else { if (dec->mInteger < 0 || dec->mInteger > 65535) mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated"); + ins->mIntValue = uint16(dec->mInteger); + } + } + else if (ins->mTType == IT_INT32) + { + if (dec->mFlags & DTF_SIGNED) + { + if (dec->mInteger < -2147483648LL || dec->mInteger > 2147483647LL) + mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); + ins->mIntValue = int32(dec->mInteger); + } + else + { + if (dec->mInteger < 0 || dec->mInteger > 4294967296LL) + mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated"); + ins->mIntValue = uint32(dec->mInteger); } - ins->mIntValue = short(dec->mInteger); } else { @@ -1080,13 +1124,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT) dtype = TheFloatTypeDeclaration; else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED)) - dtype = TheSignedIntTypeDeclaration; + { + if (vl.mType->mSize == 4) + dtype = TheSignedLongTypeDeclaration; + else + dtype = TheSignedIntTypeDeclaration; + } else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED)) - dtype = TheSignedIntTypeDeclaration; + { + if (vr.mType->mSize == 4) + dtype = TheSignedLongTypeDeclaration; + else + dtype = TheSignedIntTypeDeclaration; + } else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED)) - dtype = TheSignedIntTypeDeclaration; + { + if (vl.mType->mSize == 4) + dtype = TheSignedLongTypeDeclaration; + else + dtype = TheSignedIntTypeDeclaration; + } else - dtype = TheUnsignedIntTypeDeclaration; + { + if (vl.mType->mSize == 4 || vr.mType->mSize == 4) + dtype = TheUnsignedLongTypeDeclaration; + else + dtype = TheUnsignedIntTypeDeclaration; + } vl = CoerceType(proc, block, vl, dtype); vr = CoerceType(proc, block, vr, dtype); @@ -1319,13 +1383,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT) dtype = TheFloatTypeDeclaration; else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED)) - dtype = TheSignedIntTypeDeclaration; + { + if (vl.mType->mSize == 4) + dtype = TheSignedLongTypeDeclaration; + else + dtype = TheSignedIntTypeDeclaration; + } else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED)) - dtype = TheSignedIntTypeDeclaration; + { + if (vr.mType->mSize == 4) + dtype = TheSignedLongTypeDeclaration; + else + dtype = TheSignedIntTypeDeclaration; + } else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED)) - dtype = TheSignedIntTypeDeclaration; + { + if (vl.mType->mSize == 4) + dtype = TheSignedLongTypeDeclaration; + else + dtype = TheSignedIntTypeDeclaration; + } else - dtype = TheUnsignedIntTypeDeclaration; + { + if (vl.mType->mSize == 4 || vr.mType->mSize == 4) + dtype = TheUnsignedLongTypeDeclaration; + else + dtype = TheUnsignedIntTypeDeclaration; + } vl = CoerceType(proc, block, vl, dtype); vr = CoerceType(proc, block, vr, dtype); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a5c8359..73954f0 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -17,15 +17,14 @@ static const uint32 LIVE_MEM = 0x00000020; NativeRegisterData::NativeRegisterData(void) - : mImmediate(false), mZeroPage(false) + : mMode(NRDM_UNKNOWN) { } void NativeRegisterData::Reset(void) { - mImmediate = false; - mZeroPage = false; + mMode = NRDM_UNKNOWN; } void NativeRegisterDataSet::Reset(void) @@ -39,8 +38,8 @@ void NativeRegisterDataSet::ResetZeroPage(int addr) mRegs[addr].Reset(); for (int i = 0; i < NUM_REGS; i++) { - if (mRegs[i].mZeroPage && mRegs[i].mValue == addr) - mRegs[i].mZeroPage = false; + if (mRegs[i].mMode == NRDM_ZERO_PAGE && mRegs[i].mValue == addr) + mRegs[i].mMode = NRDM_UNKNOWN; } } @@ -571,7 +570,7 @@ bool NativeCodeInstruction::ApplySimulation(const NativeRegisterDataSet& data) case ASMIT_CMP: case ASMIT_CPX: case ASMIT_CPY: - if (mMode == ASMIM_ZERO_PAGE && data.mRegs[mAddress].mImmediate) + if (mMode == ASMIM_ZERO_PAGE && data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { mMode = ASMIM_IMMEDIATE; mAddress = data.mRegs[mAddress].mValue; @@ -594,581 +593,581 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data) switch (mType) { case ASMIT_JSR: - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_X].mImmediate = false; - data.mRegs[CPU_REG_Y].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_X].Reset(); + data.mRegs[CPU_REG_Y].Reset(); for (int i = 0; i < 4; i++) { - data.mRegs[BC_REG_ACCU + i].mImmediate = false; - data.mRegs[BC_REG_WORK + i].mImmediate = false; - data.mRegs[BC_REG_ADDR + i].mImmediate = false; + data.mRegs[BC_REG_ACCU + i].Reset(); + data.mRegs[BC_REG_WORK + i].Reset(); + data.mRegs[BC_REG_ADDR + i].Reset(); } break; case ASMIT_ROL: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_C].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue << 1) | data.mRegs[CPU_REG_C].mValue; data.mRegs[CPU_REG_C].mValue = t >= 256; data.mRegs[reg].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[reg].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_ROR: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_C].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue >> 1) | (data.mRegs[CPU_REG_C].mValue << 7); data.mRegs[CPU_REG_C].mValue = data.mRegs[reg].mValue & 1; data.mRegs[reg].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[reg].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_ASL: if (reg >= 0) { - if (data.mRegs[reg].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue << 1); data.mRegs[CPU_REG_C].mValue = t >= 256; data.mRegs[reg].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[reg].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_LSR: if (reg >= 0) { - if (data.mRegs[reg].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue >> 1); data.mRegs[CPU_REG_C].mValue = data.mRegs[reg].mValue & 1; data.mRegs[reg].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[reg].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_INC: if (reg >= 0) { - if (data.mRegs[reg].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE) { 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].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[reg].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_Z].Reset(); break; case ASMIT_DEC: if (reg >= 0) { - if (data.mRegs[reg].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE) { 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].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[reg].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_Z].Reset(); break; case ASMIT_ADC: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_C].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) { int t = data.mRegs[reg].mValue + data.mRegs[CPU_REG_A].mValue + data.mRegs[CPU_REG_C].mValue; data.mRegs[CPU_REG_C].mValue = t >= 256; data.mRegs[CPU_REG_A].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_SBC: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_C].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_A].mValue + data.mRegs[CPU_REG_C].mValue; data.mRegs[CPU_REG_C].mValue = t >= 256; data.mRegs[CPU_REG_A].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_AND: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { int t = data.mRegs[reg].mValue & data.mRegs[CPU_REG_A].mValue; data.mRegs[CPU_REG_A].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } - else if ((data.mRegs[reg].mImmediate && data.mRegs[reg].mValue == 0) || (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == 0)) + else if ((data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[reg].mValue == 0) || (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mValue == 0)) { data.mRegs[CPU_REG_A].mValue = 0; - data.mRegs[CPU_REG_A].mImmediate = true; + data.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = 0; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_ORA: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { int t = data.mRegs[reg].mValue | data.mRegs[CPU_REG_A].mValue; data.mRegs[CPU_REG_A].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } - else if ((data.mRegs[reg].mImmediate && data.mRegs[reg].mValue == 0xff) || (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == 0xff)) + else if ((data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[reg].mValue == 0xff) || (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mValue == 0xff)) { data.mRegs[CPU_REG_A].mValue = 0xff; - data.mRegs[CPU_REG_A].mImmediate = true; + data.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = 0xff; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_EOR: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { int t = data.mRegs[reg].mValue | data.mRegs[CPU_REG_A].mValue; data.mRegs[CPU_REG_A].mValue = t & 255; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_INX: - if (data.mRegs[CPU_REG_X].mImmediate) + if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_X].mValue = (data.mRegs[CPU_REG_X].mValue + 1) & 255; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_DEX: - if (data.mRegs[CPU_REG_X].mImmediate) + if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_X].mValue = (data.mRegs[CPU_REG_X].mValue - 1) & 255; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_INY: - if (data.mRegs[CPU_REG_Y].mImmediate) + if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_Y].mValue = (data.mRegs[CPU_REG_Y].mValue + 1) & 255; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_DEY: - if (data.mRegs[CPU_REG_Y].mImmediate) + if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_Y].mValue = (data.mRegs[CPU_REG_Y].mValue - 1) & 255; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_TXA: - if (data.mRegs[CPU_REG_X].mImmediate) + if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_A].mValue = data.mRegs[CPU_REG_X].mValue; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_TYA: - if (data.mRegs[CPU_REG_Y].mImmediate) + if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_A].mValue = data.mRegs[CPU_REG_Y].mValue; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_TAX: - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_X].mValue = data.mRegs[CPU_REG_A].mValue; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_X].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_X].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_TAY: - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_Y].mValue = data.mRegs[CPU_REG_A].mValue; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_Y].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_Y].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_CMP: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_A].mValue + 1; data.mRegs[CPU_REG_C].mValue = t >= 256; - data.mRegs[CPU_REG_C].mImmediate = true; + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_CPX: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_X].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_X].mValue + 1; data.mRegs[CPU_REG_C].mValue = t >= 256; - data.mRegs[CPU_REG_C].mImmediate = true; + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_CPY: if (reg >= 0) { - if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_Y].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) { int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_Y].mValue + 1; data.mRegs[CPU_REG_C].mValue = t >= 256; - data.mRegs[CPU_REG_C].mImmediate = true; + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = t & 255; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else { - data.mRegs[CPU_REG_C].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_C].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_LDA: if (reg >= 0) { - if (data.mRegs[reg].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE) { int t = data.mRegs[reg].mValue; data.mRegs[CPU_REG_A].mValue = t; - data.mRegs[CPU_REG_A].mImmediate = true; + data.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = t; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else if (mMode == ASMIM_IMMEDIATE) { data.mRegs[CPU_REG_A].mValue = mAddress; - data.mRegs[CPU_REG_A].mImmediate = true; + data.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = mAddress; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_LDX: if (reg >= 0) { - if (data.mRegs[reg].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE) { int t = data.mRegs[reg].mValue; data.mRegs[CPU_REG_X].mValue = t; - data.mRegs[CPU_REG_X].mImmediate = true; + data.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = t; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_X].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_X].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else if (mMode == ASMIM_IMMEDIATE) { data.mRegs[CPU_REG_X].mValue = mAddress; - data.mRegs[CPU_REG_X].mImmediate = true; + data.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = mAddress; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_X].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_X].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_LDY: if (reg >= 0) { - if (data.mRegs[reg].mImmediate) + if (data.mRegs[reg].mMode == NRDM_IMMEDIATE) { int t = data.mRegs[reg].mValue; data.mRegs[CPU_REG_Y].mValue = t; - data.mRegs[CPU_REG_Y].mImmediate = true; + data.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = t; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_Y].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_Y].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } } else if (mMode == ASMIM_IMMEDIATE) { data.mRegs[CPU_REG_Y].mValue = mAddress; - data.mRegs[CPU_REG_Y].mImmediate = true; + data.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = mAddress; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[CPU_REG_Y].mImmediate = false; - data.mRegs[CPU_REG_Z].mImmediate = false; + data.mRegs[CPU_REG_Y].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } break; case ASMIT_STA: if (reg >= 0) { - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { data.mRegs[reg].mValue = data.mRegs[CPU_REG_A].mValue; - data.mRegs[reg].mImmediate = true; + data.mRegs[reg].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; + data.mRegs[reg].Reset(); } } break; @@ -1176,14 +1175,14 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data) case ASMIT_STX: if (reg >= 0) { - if (data.mRegs[CPU_REG_X].mImmediate) + if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) { data.mRegs[reg].mValue = data.mRegs[CPU_REG_X].mValue; - data.mRegs[reg].mImmediate = true; + data.mRegs[reg].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; + data.mRegs[reg].Reset(); } } break; @@ -1191,14 +1190,14 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data) case ASMIT_STY: if (reg >= 0) { - if (data.mRegs[CPU_REG_Y].mImmediate) + if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) { data.mRegs[reg].mValue = data.mRegs[CPU_REG_Y].mValue; - data.mRegs[reg].mImmediate = true; + data.mRegs[reg].mMode = NRDM_IMMEDIATE; } else { - data.mRegs[reg].mImmediate = false; + data.mRegs[reg].Reset(); } } break; @@ -1247,7 +1246,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) case ASMIT_LDA: if (mMode == ASMIM_IMMEDIATE) { - if (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z)) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z)) { mType = ASMIT_NOP; mMode = ASMIM_IMPLIED; @@ -1255,14 +1254,20 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) } else { - data.mRegs[CPU_REG_A].mImmediate = true; - data.mRegs[CPU_REG_A].mZeroPage = false; + data.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_A].mValue = mAddress; } - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = mAddress; } + else if (mMode == ASMIM_IMMEDIATE_ADDRESS) + { + data.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE_ADDRESS; + data.mRegs[CPU_REG_A].mValue = mAddress; + data.mRegs[CPU_REG_A].mLinkerObject = mLinkerObject; + data.mRegs[CPU_REG_A].mFlags = mFlags; + } else { if (mMode != ASMIM_ZERO_PAGE) @@ -1278,11 +1283,11 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) data.mRegs[CPU_REG_Z].Reset(); break; case ASMIT_CMP: - if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_A].mImmediate) + if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue - mAddress; - data.mRegs[CPU_REG_C].mImmediate = true; + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_A].mValue >= mAddress; } else @@ -1292,11 +1297,11 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) } break; case ASMIT_CPX: - if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_X].mImmediate) + if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue - mAddress; - data.mRegs[CPU_REG_C].mImmediate = true; + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_X].mValue >= mAddress; } else @@ -1306,11 +1311,11 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) } break; case ASMIT_CPY: - if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_Y].mImmediate) + if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue - mAddress; - data.mRegs[CPU_REG_C].mImmediate = true; + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_Y].mValue >= mAddress; } else @@ -1323,7 +1328,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) case ASMIT_ORA: case ASMIT_EOR: case ASMIT_AND: - if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_A].mImmediate) + if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { if (mType == ASMIT_ORA) mAddress |= data.mRegs[CPU_REG_A].mValue; @@ -1333,16 +1338,15 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) mAddress ^= data.mRegs[CPU_REG_A].mValue; mType = ASMIT_LDA; data.mRegs[CPU_REG_A].mValue = mAddress; - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = mAddress; } - else if (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == 0) + else if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_A].mValue == 0) { if (mType == ASMIT_ORA || mType == ASMIT_EOR) { mType = ASMIT_LDA; - data.mRegs[CPU_REG_A].mImmediate = false; - data.mRegs[CPU_REG_A].mZeroPage = false; + data.mRegs[CPU_REG_A].Reset(); } else { @@ -1360,7 +1364,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) case ASMIT_LDX: if (mMode == ASMIM_IMMEDIATE) { - if (data.mRegs[CPU_REG_X].mImmediate && data.mRegs[CPU_REG_X].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z)) + if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_X].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z)) { mType = ASMIT_NOP; mMode = ASMIM_IMPLIED; @@ -1368,11 +1372,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) } else { - data.mRegs[CPU_REG_X].mImmediate = true; - data.mRegs[CPU_REG_X].mZeroPage = false; + data.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_X].mValue = mAddress; - - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = mAddress; } } @@ -1391,7 +1393,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) case ASMIT_LDY: if (mMode == ASMIM_IMMEDIATE) { - if (data.mRegs[CPU_REG_Y].mImmediate && data.mRegs[CPU_REG_Y].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z)) + if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_Y].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z)) { mType = ASMIT_NOP; mMode = ASMIM_IMPLIED; @@ -1399,11 +1401,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) } else { - data.mRegs[CPU_REG_Y].mImmediate = true; - data.mRegs[CPU_REG_Y].mZeroPage = false; + data.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Y].mValue = mAddress; - - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = mAddress; } } @@ -1422,9 +1422,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) case ASMIT_TXA: data.mRegs[CPU_REG_A] = data.mRegs[CPU_REG_X]; - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; } else @@ -1432,9 +1432,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) break; case ASMIT_TYA: data.mRegs[CPU_REG_A] = data.mRegs[CPU_REG_Y]; - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; } else @@ -1442,9 +1442,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) break; case ASMIT_TAX: data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A]; - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; } else @@ -1452,9 +1452,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) break; case ASMIT_TAY: data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A]; - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Z].mImmediate = true; + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; } else @@ -1467,7 +1467,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) switch (mType) { case ASMIT_LDA: - if (data.mRegs[CPU_REG_A].mZeroPage && data.mRegs[CPU_REG_A].mValue == mAddress) + if (data.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && data.mRegs[CPU_REG_A].mValue == mAddress) { if (mLive & LIVE_CPU_REG_Z) { @@ -1482,26 +1482,35 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) } changed = true; } - else if (data.mRegs[mAddress].mImmediate) + else if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_A] = data.mRegs[mAddress]; mAddress = data.mRegs[CPU_REG_A].mValue; mMode = ASMIM_IMMEDIATE; changed = true; } - else if (data.mRegs[mAddress].mZeroPage) + else if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE_ADDRESS) + { + data.mRegs[CPU_REG_A] = data.mRegs[mAddress]; + mAddress = data.mRegs[CPU_REG_A].mValue; + mLinkerObject = data.mRegs[CPU_REG_A].mLinkerObject; + mFlags = (mFlags & ~(NCIF_LOWER | NCIF_UPPER)) | (data.mRegs[CPU_REG_A].mFlags & (NCIF_LOWER | NCIF_UPPER)); + mMode = ASMIM_IMMEDIATE_ADDRESS; + changed = true; + } + else if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE) { data.mRegs[CPU_REG_A] = data.mRegs[mAddress]; mAddress = data.mRegs[CPU_REG_A].mValue; changed = true; } - else if (data.mRegs[CPU_REG_X].mZeroPage && data.mRegs[CPU_REG_X].mValue == mAddress) + else if (data.mRegs[CPU_REG_X].mMode == NRDM_ZERO_PAGE && data.mRegs[CPU_REG_X].mValue == mAddress) { mType = ASMIT_TXA; mMode = ASMIM_IMPLIED; data.mRegs[CPU_REG_A] = data.mRegs[CPU_REG_X]; } - else if (data.mRegs[CPU_REG_Y].mZeroPage && data.mRegs[CPU_REG_Y].mValue == mAddress) + else if (data.mRegs[CPU_REG_Y].mMode == NRDM_ZERO_PAGE && data.mRegs[CPU_REG_Y].mValue == mAddress) { mType = ASMIT_TYA; mMode = ASMIM_IMPLIED; @@ -1510,34 +1519,34 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) else { data.mRegs[CPU_REG_A].Reset(); - if (data.mRegs[mAddress].mImmediate) + if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_A].mImmediate = true; + data.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_A].mValue = data.mRegs[mAddress].mValue; } else { - data.mRegs[CPU_REG_A].mZeroPage = true; + data.mRegs[CPU_REG_A].mMode = NRDM_ZERO_PAGE; data.mRegs[CPU_REG_A].mValue = mAddress; } } break; case ASMIT_LDX: - if (data.mRegs[CPU_REG_X].mZeroPage && data.mRegs[CPU_REG_X].mValue == mAddress) + if (data.mRegs[CPU_REG_X].mMode == NRDM_ZERO_PAGE && data.mRegs[CPU_REG_X].mValue == mAddress) { mType = ASMIT_NOP; mMode = ASMIM_IMPLIED; changed = true; } - else if (data.mRegs[mAddress].mImmediate) + else if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_X] = data.mRegs[mAddress]; mAddress = data.mRegs[CPU_REG_X].mValue; mMode = ASMIM_IMMEDIATE; changed = true; } - else if (data.mRegs[CPU_REG_A].mZeroPage && data.mRegs[CPU_REG_A].mValue == mAddress) + else if (data.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && data.mRegs[CPU_REG_A].mValue == mAddress) { mType = ASMIT_TAX; mMode = ASMIM_IMPLIED; @@ -1546,34 +1555,34 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) else { data.mRegs[CPU_REG_X].Reset(); - if (data.mRegs[mAddress].mImmediate) + if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_X].mImmediate = true; + data.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_X].mValue = data.mRegs[mAddress].mValue; } else { - data.mRegs[CPU_REG_X].mZeroPage = true; + data.mRegs[CPU_REG_X].mMode = NRDM_ZERO_PAGE; data.mRegs[CPU_REG_X].mValue = mAddress; } } break; case ASMIT_LDY: - if (data.mRegs[CPU_REG_Y].mZeroPage && data.mRegs[CPU_REG_Y].mValue == mAddress) + if (data.mRegs[CPU_REG_Y].mMode == NRDM_ZERO_PAGE && data.mRegs[CPU_REG_Y].mValue == mAddress) { mType = ASMIT_NOP; mMode = ASMIM_IMPLIED; changed = true; } - else if (data.mRegs[mAddress].mImmediate) + else if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { data.mRegs[CPU_REG_Y] = data.mRegs[mAddress]; mAddress = data.mRegs[CPU_REG_Y].mValue; mMode = ASMIM_IMMEDIATE; changed = true; } - else if (data.mRegs[CPU_REG_A].mZeroPage && data.mRegs[CPU_REG_A].mValue == mAddress) + else if (data.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && data.mRegs[CPU_REG_A].mValue == mAddress) { mType = ASMIT_TAY; mMode = ASMIM_IMPLIED; @@ -1582,14 +1591,14 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) else { data.mRegs[CPU_REG_Y].Reset(); - if (data.mRegs[mAddress].mImmediate) + if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { - data.mRegs[CPU_REG_Y].mImmediate = true; + data.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE; data.mRegs[CPU_REG_Y].mValue = data.mRegs[mAddress].mValue; } else { - data.mRegs[CPU_REG_Y].mZeroPage = true; + data.mRegs[CPU_REG_Y].mMode = NRDM_ZERO_PAGE; data.mRegs[CPU_REG_Y].mValue = mAddress; } } @@ -1603,13 +1612,13 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) case ASMIT_CMP: case ASMIT_CPX: case ASMIT_CPY: - if (data.mRegs[mAddress].mImmediate) + if (data.mRegs[mAddress].mMode == NRDM_IMMEDIATE) { mAddress = data.mRegs[mAddress].mValue; mMode = ASMIM_IMMEDIATE; changed = true; } - else if (data.mRegs[mAddress].mZeroPage) + else if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE) { mAddress = data.mRegs[mAddress].mValue; changed = true; @@ -1618,45 +1627,44 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) case ASMIT_STA: data.ResetZeroPage(mAddress); - if (data.mRegs[CPU_REG_A].mImmediate) + if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE || data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE_ADDRESS) { - data.mRegs[mAddress].mImmediate = true; - data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_A].mValue; + data.mRegs[mAddress] = data.mRegs[CPU_REG_A]; } - else if (data.mRegs[CPU_REG_A].mZeroPage) + else if (data.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE) { - data.mRegs[mAddress].mZeroPage = true; + data.mRegs[mAddress].mMode = NRDM_ZERO_PAGE; data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_A].mValue; } else { - data.mRegs[CPU_REG_A].mZeroPage = true; + data.mRegs[CPU_REG_A].mMode = NRDM_ZERO_PAGE; data.mRegs[CPU_REG_A].mValue = mAddress; } break; case ASMIT_STX: data.ResetZeroPage(mAddress); - if (data.mRegs[CPU_REG_X].mImmediate) + if (data.mRegs[CPU_REG_X].mMode == NRDM_IMMEDIATE) { - data.mRegs[mAddress].mImmediate = true; + data.mRegs[mAddress].mMode = NRDM_IMMEDIATE; data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_X].mValue; } else { - data.mRegs[CPU_REG_X].mZeroPage = true; + data.mRegs[CPU_REG_X].mMode = NRDM_ZERO_PAGE; data.mRegs[CPU_REG_X].mValue = mAddress; } break; case ASMIT_STY: data.ResetZeroPage(mAddress); - if (data.mRegs[CPU_REG_Y].mImmediate) + if (data.mRegs[CPU_REG_Y].mMode == NRDM_IMMEDIATE) { - data.mRegs[mAddress].mImmediate = true; + data.mRegs[mAddress].mMode = NRDM_IMMEDIATE; data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_Y].mValue; } else { - data.mRegs[CPU_REG_Y].mZeroPage = true; + data.mRegs[CPU_REG_Y].mMode = NRDM_ZERO_PAGE; data.mRegs[CPU_REG_Y].mValue = mAddress; } break; @@ -5125,17 +5133,17 @@ void NativeCodeBasicBlock::BuildEntryDataSet(const NativeRegisterDataSet& set) bool changed = false; for (int i = 0; i < NUM_REGS; i++) { - if (set.mRegs[i].mImmediate) + if (set.mRegs[i].mMode == NRDM_IMMEDIATE) { - if (mEntryRegisterDataSet.mRegs[i].mImmediate && set.mRegs[i].mValue != mEntryRegisterDataSet.mRegs[i].mValue) + if (mEntryRegisterDataSet.mRegs[i].mMode == NRDM_IMMEDIATE && set.mRegs[i].mValue != mEntryRegisterDataSet.mRegs[i].mValue) { - mEntryRegisterDataSet.mRegs[i].mImmediate = false; + mEntryRegisterDataSet.mRegs[i].Reset(); mVisited = false; } } - else if (mEntryRegisterDataSet.mRegs[i].mImmediate) + else if (mEntryRegisterDataSet.mRegs[i].mMode == NRDM_IMMEDIATE) { - mEntryRegisterDataSet.mRegs[i].mImmediate = false; + mEntryRegisterDataSet.mRegs[i].Reset(); mVisited = false; } } @@ -5419,7 +5427,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) switch (mBranch) { case ASMIT_BCS: - if (ndata.mRegs[CPU_REG_C].mImmediate) + if (ndata.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) { mBranch = ASMIT_JMP; if (!ndata.mRegs[CPU_REG_C].mValue) @@ -5429,7 +5437,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) } break; case ASMIT_BCC: - if (ndata.mRegs[CPU_REG_C].mImmediate) + if (ndata.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE) { mBranch = ASMIT_JMP; if (ndata.mRegs[CPU_REG_C].mValue) @@ -5439,7 +5447,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) } break; case ASMIT_BNE: - if (ndata.mRegs[CPU_REG_Z].mImmediate) + if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) { mBranch = ASMIT_JMP; if (!ndata.mRegs[CPU_REG_Z].mValue) @@ -5449,7 +5457,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) } break; case ASMIT_BEQ: - if (ndata.mRegs[CPU_REG_Z].mImmediate) + if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) { mBranch = ASMIT_JMP; if (ndata.mRegs[CPU_REG_Z].mValue) @@ -5459,7 +5467,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) } break; case ASMIT_BPL: - if (ndata.mRegs[CPU_REG_Z].mImmediate) + if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) { mBranch = ASMIT_JMP; if ((ndata.mRegs[CPU_REG_Z].mValue & 0x80)) @@ -5469,7 +5477,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) } break; case ASMIT_BMI: - if (ndata.mRegs[CPU_REG_Z].mImmediate) + if (ndata.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE) { mBranch = ASMIT_JMP; if (!(ndata.mRegs[CPU_REG_Z].mValue & 0x80)) @@ -5979,24 +5987,27 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) const NativeCodeInstruction* ains; int apos, breg, ireg; - if (!(mIns[i + 1].mLive & LIVE_MEM) && FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg)) + if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg)) { - if (breg == mIns[i + 1].mAddress) + if (breg != mIns[i + 1].mAddress || !(mIns[i + 1].mLive & LIVE_MEM)) { - mIns[apos + 3].mType = ASMIT_NOP; - mIns[apos + 3].mMode = ASMIM_IMPLIED; - mIns[apos + 6].mType = ASMIT_NOP; - mIns[apos + 6].mMode = ASMIM_IMPLIED; + if (breg == mIns[i + 1].mAddress) + { + mIns[apos + 3].mType = ASMIT_NOP; + mIns[apos + 3].mMode = ASMIM_IMPLIED; + mIns[apos + 6].mType = ASMIT_NOP; + mIns[apos + 6].mMode = ASMIM_IMPLIED; + } + if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) + { + mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns[i + 2].mLive |= LIVE_CPU_REG_Y; + } + mIns[i + 0].mMode = ASMIM_ZERO_PAGE; + mIns[i + 0].mAddress = ireg; + mIns[i + 1].mAddress = breg; + progress = true; } - if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); - mIns[i + 2].mLive |= LIVE_CPU_REG_Y; - } - mIns[i + 0].mMode = ASMIM_ZERO_PAGE; - mIns[i + 0].mAddress = ireg; - mIns[i + 1].mAddress = breg; - progress = true; } else if (FindGlobalAddressSumY(i, mIns[i + 1].mAddress, ains, ireg)) { @@ -6158,39 +6169,70 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) if (i + 3 < mIns.Size()) { - if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && - mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && - (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && - (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) + if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && + mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && + (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && + (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) + { + mIns[i + 0].mType = ASMIT_NOP; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_INC; + progress = true; + } + else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && + mIns[i + 1].mType == ASMIT_SEC && mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && + (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && + (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) + { + mIns[i + 0].mType = ASMIT_NOP; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_DEC; + progress = true; + } + else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && + mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress & 0xff) == 0xff && + (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && + (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) + { + mIns[i + 0].mType = ASMIT_NOP; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_DEC; + progress = true; + } +#if 0 + if ( + mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && + !mIns[i + 2].ChangesYReg() && (mIns[i + 2].mMode == ASMIM_IMMEDIATE || mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress) && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mAddress == mIns[i + 3].mAddress && !(mIns[i + 3].mLive & LIVE_MEM)) + { + int apos, breg, ireg; + if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg)) { - mIns[i + 0].mType = ASMIT_NOP; - mIns[i + 1].mType = ASMIT_NOP; - mIns[i + 2].mType = ASMIT_NOP; - mIns[i + 3].mType = ASMIT_INC; - progress = true; - } - else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && - mIns[i + 1].mType == ASMIT_SEC && mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && - (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && - (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) - { - mIns[i + 0].mType = ASMIT_NOP; - mIns[i + 1].mType = ASMIT_NOP; - mIns[i + 2].mType = ASMIT_NOP; - mIns[i + 3].mType = ASMIT_DEC; - progress = true; - } - else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && - mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress & 0xff)== 0xff && - (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && - (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) - { - mIns[i + 0].mType = ASMIT_NOP; - mIns[i + 1].mType = ASMIT_NOP; - mIns[i + 2].mType = ASMIT_NOP; - mIns[i + 3].mType = ASMIT_DEC; + if (breg == mIns[i + 1].mAddress) + { + mIns[apos + 3].mType = ASMIT_NOP; + mIns[apos + 3].mMode = ASMIM_IMPLIED; + mIns[apos + 6].mType = ASMIT_NOP; + mIns[apos + 6].mMode = ASMIM_IMPLIED; + } + if (mIns[i + 3].mLive & LIVE_CPU_REG_Y) + { + mIns.Insert(i + 4, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns[i + 4].mLive |= LIVE_CPU_REG_Y; + } + mIns[i + 0].mMode = ASMIM_ZERO_PAGE; + mIns[i + 0].mAddress = ireg; + mIns[i + 1].mAddress = breg; + mIns[i + 3].mAddress = breg; progress = true; } + } + +#endif } @@ -6210,6 +6252,45 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) progress = true; } } + +#if 1 + if (i + 9 < mIns.Size()) + { + if ( + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && + mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 && + mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 && + mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 && + + mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mAddress == 0 && + mIns[i + 7].mType == ASMIT_LDA && mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && + !mIns[i + 8].ChangesYReg() && (mIns[i + 8].mMode == ASMIM_IMMEDIATE || mIns[i + 8].mMode == ASMIM_ZERO_PAGE && mIns[i + 8].mAddress != mIns[i + 2].mAddress && mIns[i + 8].mAddress != mIns[i + 1].mAddress) && + mIns[i + 9].mType == ASMIT_STA && mIns[i + 9].mMode == ASMIM_INDIRECT_Y && mIns[i + 9].mAddress == mIns[i + 2].mAddress && !(mIns[i + 9].mLive & LIVE_MEM) + ) + { + for(int j=0; j<6; j++) + { + mIns[i + j].mType = ASMIT_NOP; + mIns[i + j].mMode = ASMIM_IMPLIED; + } + + if (mIns[i + 9].mLive & LIVE_CPU_REG_Y) + { + mIns.Insert(i + 10, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns[i + 10].mLive |= LIVE_CPU_REG_Y; + } + + mIns[i + 6].mType = ASMIT_TAY; + mIns[i + 6].mMode = ASMIM_IMPLIED; + mIns[i + 7].mAddress = mIns[i + 1].mAddress; + mIns[i + 9].mAddress = mIns[i + 1].mAddress; + progress = true; + } + } +#endif + #endif #endif } diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 6578af1..7aad923 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -8,10 +8,20 @@ class NativeCodeProcedure; class NativeCodeBasicBlock; class NativeCodeGenerator; +enum NativeRegisterDataMode +{ + NRDM_UNKNOWN, + NRDM_IMMEDIATE, + NRDM_IMMEDIATE_ADDRESS, + NRDM_ZERO_PAGE +}; + struct NativeRegisterData { - bool mImmediate, mZeroPage; - int mValue; + NativeRegisterDataMode mMode; + int mValue; + uint32 mFlags; + LinkerObject * mLinkerObject; NativeRegisterData(void); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 1caf5ee..7b06cae 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -897,6 +897,39 @@ Expression* Parser::ParseSimpleExpression(void) exp->mDecValue = dec; exp->mDecType = dec->mBase; + mScanner->NextToken(); + break; + case TK_INTEGERU: + dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + dec->mInteger = mScanner->mTokenInteger; + dec->mBase = TheUnsignedIntTypeDeclaration; + exp = new Expression(mScanner->mLocation, EX_CONSTANT); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + + mScanner->NextToken(); + break; + case TK_INTEGERL: + dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + dec->mInteger = mScanner->mTokenInteger; + if (dec->mInteger < 0x80000000) + dec->mBase = TheSignedLongTypeDeclaration; + else + dec->mBase = TheUnsignedLongTypeDeclaration; + exp = new Expression(mScanner->mLocation, EX_CONSTANT); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + + mScanner->NextToken(); + break; + case TK_INTEGERUL: + dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + dec->mInteger = mScanner->mTokenInteger; + dec->mBase = TheUnsignedLongTypeDeclaration; + exp = new Expression(mScanner->mLocation, EX_CONSTANT); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + mScanner->NextToken(); break; case TK_NUMBER: @@ -1819,6 +1852,16 @@ Expression* Parser::ParseAssemblerBaseOperand(void) exp->mDecValue = dec; exp->mDecType = dec->mBase; + mScanner->NextToken(); + break; + case TK_INTEGERU: + dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + dec->mInteger = mScanner->mTokenInteger; + dec->mBase = TheUnsignedIntTypeDeclaration; + exp = new Expression(mScanner->mLocation, EX_CONSTANT); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + mScanner->NextToken(); break; @@ -2459,7 +2502,7 @@ void Parser::ParsePragma(void) mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected"); } - if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER && exp->mDecValue->mInteger >= 0 && exp->mDecValue->mInteger < 128) + if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER && exp->mDecValue->mInteger >= 0 && exp->mDecValue->mInteger < 256) { if (mCompilationUnits->mByteCodes[exp->mDecValue->mInteger]) mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate bytecode function"); diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 6f8deb5..556d523 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -32,6 +32,9 @@ const char* TokenNames[] = { "'long'", "'continue'", "'integer'", + "'integeru'", + "'integerl'", + "'integerul'", "'bool'", "'const'", "'volatile'", @@ -1037,7 +1040,13 @@ void Scanner::NextRawToken(void) if (n == 0) mErrors->Error(mLocation, EERR_SYNTAX, "Missing digits in hex constant"); - mToken = TK_INTEGER; + if (mTokenChar == 'L' || mTokenChar == 'l') + { + NextChar(); + mToken = TK_INTEGERUL; + } + else + mToken = TK_INTEGERU; mTokenInteger = mant; } else @@ -1288,7 +1297,7 @@ void Scanner::CharToken(void) if (mLine[mOffset] && mLine[mOffset] == '\'') { - mToken = TK_INTEGER; + mToken = TK_INTEGERU; mOffset++; NextChar(); } @@ -1358,7 +1367,14 @@ void Scanner::ParseNumberToken(void) if (n == 0) Error("Missing digits in hex constant"); - mToken = TK_INTEGER; + if (mTokenChar == 'L' || mTokenChar == 'l') + { + NextChar(); + mToken = TK_INTEGERUL; + } + else + mToken = TK_INTEGERU; + mTokenInteger = mant; } else if (mant == 0 && (mTokenChar == 'b' || mTokenChar == 'B')) @@ -1376,7 +1392,13 @@ void Scanner::ParseNumberToken(void) if (n == 0) Error("Missing digits in binary constant"); - mToken = TK_INTEGER; + if (mTokenChar == 'L' || mTokenChar == 'l') + { + NextChar(); + mToken = TK_INTEGERUL; + } + else + mToken = TK_INTEGERU; mTokenInteger = mant; } else @@ -1397,7 +1419,27 @@ void Scanner::ParseNumberToken(void) if (mTokenChar != '.') { - mToken = TK_INTEGER; + if (mTokenChar == 'U' || mTokenChar == 'u') + { + NextChar(); + if (mTokenChar == 'L' || mTokenChar == 'l') + { + NextChar(); + mToken = TK_INTEGERUL; + } + else + mToken = TK_INTEGERU; + } + else + { + if (mTokenChar == 'L' || mTokenChar == 'l') + { + NextChar(); + mToken = TK_INTEGERL; + } + else + mToken = TK_INTEGER; + } mTokenInteger = mant; } else @@ -1461,6 +1503,9 @@ int64 Scanner::PrepParseSimple(void) switch (mToken) { case TK_INTEGER: + case TK_INTEGERU: + case TK_INTEGERL: + case TK_INTEGERUL: v = mTokenInteger; NextToken(); break; diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index 548be3b..d1e57cc 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -31,6 +31,9 @@ enum Token TK_LONG, TK_CONTINUE, TK_INTEGER, + TK_INTEGERU, + TK_INTEGERL, + TK_INTEGERUL, TK_BOOL, TK_CONST, TK_VOLATILE,