Change runtime assembler generator use value and return instead of reference

This commit is contained in:
drmortalwombat 2021-11-29 18:37:15 +01:00
parent a6fa114a5b
commit 15c65f69aa
3 changed files with 124 additions and 60 deletions

View File

@ -82,91 +82,91 @@ enum AsmIns
ASM_JSR = 0x2c ASM_JSR = 0x2c
}; };
inline void asm_np(byte ** ip, AsmIns ins) inline byte asm_np(byte * ip, AsmIns ins)
{ {
(*ip)[0] = ins & 0xff; ip[0] = ins & 0xff;
(*ip)++; return 1;
} }
inline void asm_zp(byte ** ip, AsmIns ins, byte addr) inline byte asm_zp(byte * ip, AsmIns ins, byte addr)
{ {
(*ip)[0] = (ins & 0xff) | 0x04; ip[0] = (ins & 0xff) | 0x04;
(*ip)[1] = addr; ip[1] = addr;
(*ip) += 2; return 2;
} }
inline void asm_rl(byte ** ip, AsmIns ins, byte addr) inline byte asm_rl(byte * ip, AsmIns ins, byte addr)
{ {
(*ip)[0] = ins & 0xff; ip[0] = ins & 0xff;
(*ip)[1] = addr; ip[1] = addr;
(*ip) += 2; return 2;
} }
inline void asm_im(byte ** ip, AsmIns ins, byte value) inline byte asm_im(byte * ip, AsmIns ins, byte value)
{ {
(*ip)[0] = (ins & 0xff) | ((ins & 0x01) << 3); ip[0] = (ins & 0xff) | ((ins & 0x01) << 3);
(*ip)[1] = value; ip[1] = value;
(*ip) += 2; return 2;
} }
inline void asm_zx(byte ** ip, AsmIns ins, byte addr) inline byte asm_zx(byte * ip, AsmIns ins, byte addr)
{ {
(*ip)[0] = (ins & 0xff) | 0x05; ip[0] = (ins & 0xff) | 0x05;
(*ip)[1] = addr; ip[1] = addr;
(*ip) += 2; return 2;
} }
inline void asm_zy(byte ** ip, AsmIns ins, byte addr) inline byte asm_zy(byte * ip, AsmIns ins, byte addr)
{ {
(*ip)[0] = (ins & 0xff) | 0x05; ip[0] = (ins & 0xff) | 0x05;
(*ip)[1] = addr; ip[1] = addr;
(*ip) += 2; return 2;
} }
inline void asm_ab(byte ** ip, AsmIns ins, unsigned addr) inline byte asm_ab(byte * ip, AsmIns ins, unsigned addr)
{ {
(*ip)[0] = (ins & 0xff) ^ 0x0c; ip[0] = (ins & 0xff) ^ 0x0c;
(*ip)[1] = addr & 0xff; ip[1] = addr & 0xff;
(*ip)[2] = addr >> 8; ip[2] = addr >> 8;
(*ip) += 3; return 3;
} }
inline void asm_in(byte ** ip, AsmIns ins, unsigned addr) inline byte asm_in(byte * ip, AsmIns ins, unsigned addr)
{ {
(*ip)[0] = (ins & 0xff) ^ 0x2c; ip[0] = (ins & 0xff) ^ 0x2c;
(*ip)[1] = addr & 0xff; ip[1] = addr & 0xff;
(*ip)[2] = addr >> 8; ip[2] = addr >> 8;
(*ip) += 3; return 3;
} }
inline void asm_ax(byte ** ip, AsmIns ins, unsigned addr) inline byte asm_ax(byte * ip, AsmIns ins, unsigned addr)
{ {
(*ip)[0] = (ins & 0xff) | 0x1c; ip[0] = (ins & 0xff) | 0x1c;
(*ip)[1] = addr & 0xff; ip[1] = addr & 0xff;
(*ip)[2] = addr >> 8; ip[2] = addr >> 8;
(*ip) += 3; return 3;
} }
inline void asm_ay(byte ** ip, AsmIns ins, unsigned addr) inline byte asm_ay(byte * ip, AsmIns ins, unsigned addr)
{ {
(*ip)[0] = (ins & 0xff) | 0x18; ip[0] = (ins & 0xff) | 0x18;
(*ip)[1] = addr & 0xff; ip[1] = addr & 0xff;
(*ip)[2] = addr >> 8; ip[2] = addr >> 8;
(*ip) += 3; return 3;
} }
inline void asm_ix(byte ** ip, AsmIns ins, byte addr) inline byte asm_ix(byte * ip, AsmIns ins, byte addr)
{ {
(*ip)[0] = (ins & 0xff) | 0x00; ip[0] = (ins & 0xff) | 0x00;
(*ip)[1] = addr; ip[1] = addr;
(*ip) += 2; return 2;
} }
inline void asm_iy(byte ** ip, AsmIns ins, byte addr) inline byte * asm_iy(byte * ip, AsmIns ins, byte addr)
{ {
(*ip)[0] = (ins & 0xff) | 0x01; ip[0] = (ins & 0xff) | 0x01;
(*ip)[1] = addr; ip[1] = addr;
(*ip) += 2; return 2;
} }
#endif #endif

View File

@ -2,6 +2,7 @@
#include <c64/vic.h> #include <c64/vic.h>
#include <c64/cia.h> #include <c64/cia.h>
#include <c64/asm6502.h>
volatile char npos = 1, tpos = 0; volatile char npos = 1, tpos = 0;
@ -164,6 +165,12 @@ void rirq_build(RIRQCode * ic, byte size)
{ {
ic->size = size; ic->size = size;
asm_im(ic->code + 0, ASM_LDY, 0);
asm_im(ic->code + 2, ASM_LDA, 0);
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
asm_rl(ic->code + 7, ASM_BCS, -5);
asm_ab(ic->code + 9, ASM_STY, 0x0000);
/*
ic->code[0] = 0xa0; // ldy # ic->code[0] = 0xa0; // ldy #
ic->code[2] = 0xa9; // lda # ic->code[2] = 0xa9; // lda #
ic->code[4] = 0xec; // cpx ic->code[4] = 0xec; // cpx
@ -172,23 +179,28 @@ void rirq_build(RIRQCode * ic, byte size)
ic->code[7] = 0xb0; // bcs ic->code[7] = 0xb0; // bcs
ic->code[8] = -5; ic->code[8] = -5;
ic->code[9] = 0x8c; // sty ic->code[9] = 0x8c; // sty
*/
if (size == 1) if (size == 1)
{ {
ic->code[12] = 0x60; // rts asm_np(ic->code + 12, ASM_RTS);
//ic->code[12] = 0x60; // rts
} }
else else
{ {
ic->code[12] = 0x8d; // sty asm_ab(ic->code + 12, ASM_STA, 0x0000);
// ic->code[12] = 0x8d; // sty
byte p = 15; byte p = 15;
for(byte i=2; i<size; i++) for(byte i=2; i<size; i++)
{ {
ic->code[p] = 0xa9; // lda # p += asm_im(ic->code + p, ASM_LDA, 0x00);
ic->code[p + 2] = 0x8d; // sta p += asm_ab(ic->code + p, ASM_STA, 0x0000);
p += 5; //ic->code[p] = 0xa9; // lda #
//ic->code[p + 2] = 0x8d; // sta
//p += 5;
} }
ic->code[p] = 0x60; asm_np(ic->code + p, ASM_RTS);
//ic->code[p] = 0x60;
} }
} }

View File

@ -10272,7 +10272,47 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
} }
#endif #endif
#if 1
if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 3 &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y)
{
int apos, breg, ireg;
if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg))
{
if (breg != mIns[i + 1].mAddress && ireg != mIns[i + 1].mAddress)// || !(mIns[i + 1].mLive & LIVE_MEM))
{
int yoffset = mIns[i + 0].mAddress;
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, yoffset));
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;
for(int j=0; j<yoffset; j++)
{
mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns[i + 1].mLive = mIns[i + 0].mLive;
}
progress = true;
}
}
}
#endif
} }
@ -10540,13 +10580,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
#endif #endif
#if 1 #if 1
if ( if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_LDA &&
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 2].mLive & LIVE_MEM)) mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 2].mLive & LIVE_MEM))
{ {
int apos, breg, ireg; int apos, breg, ireg;
if (FindAddressSumY(i, mIns[i + 2].mAddress, apos, breg, ireg)) if (FindAddressSumY(i, mIns[i + 2].mAddress, apos, breg, ireg))
{ {
int yoffset = mIns[i + 0].mAddress;
if (breg == mIns[i + 2].mAddress) if (breg == mIns[i + 2].mAddress)
{ {
mIns[apos + 3].mType = ASMIT_NOP; mIns[apos + 3].mType = ASMIT_NOP;
@ -10556,9 +10598,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
if (mIns[i + 2].mLive & LIVE_CPU_REG_Y) if (mIns[i + 2].mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(i + 3, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); mIns.Insert(i + 3, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, yoffset));
mIns[i + 3].mLive |= LIVE_CPU_REG_Y; mIns[i + 3].mLive |= LIVE_CPU_REG_Y;
} }
int ypos = i;
if (mIns[i + 1].mMode != ASMIM_INDIRECT_Y && mIns[i + 1].mMode != ASMIM_ABSOLUTE_Y) if (mIns[i + 1].mMode != ASMIM_INDIRECT_Y && mIns[i + 1].mMode != ASMIM_ABSOLUTE_Y)
{ {
mIns[i + 0].mMode = ASMIM_ZERO_PAGE; mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
@ -10569,8 +10613,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
{ {
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
mIns[i + 2].mLive = mIns[i + 3].mLive | LIVE_CPU_REG_Y | LIVE_MEM; mIns[i + 2].mLive = mIns[i + 3].mLive | LIVE_CPU_REG_Y | LIVE_MEM;
ypos = i + 2;
mIns[i + 3].mAddress = breg; mIns[i + 3].mAddress = breg;
} }
if (yoffset == 1)
{
mIns.Insert(ypos + 1, NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns[ypos + 1].mLive = mIns[ypos].mLive;
}
progress = true; progress = true;
} }
} }