/* -*- linux-c -*- */ #include #include "generator.h" #include "cpu68k.h" #include "cpu68k-inline.h" #include "mem68k.h" #include "compile.h" /* TODO: use 2 files. One for processor specific stuff, and one for generic */ /*#ifdef PROCESSOR_SPARC*/ #if ((defined PROCESSOR_SPARC) && (defined GENERATOR_JIT)) #cpu sparc #define JSR regs.sr /* statistic */ static uint32 instr_stat[i_LINE15+1]; static uint32 nb_flag; static uint32 nb_func; static uint32 nb_recomp; /* flag mask */ static uint32 mask_t,nmask_t; static uint32 mask_s,nmask_s; static uint32 mask_x,nmask_x; static uint32 mask_n,nmask_n; static uint32 mask_z,nmask_z; static uint32 mask_v,nmask_v; static uint32 mask_c,nmask_c; #define CMASK 0x01 #define VMASK 0x02 #define ZMASK 0x04 #define NMASK 0x08 #define XMASK 0x10 /* helper/debug func */ static void gen68k_dumpreg(void) { int i; printf("d0=%08lx d4=%08lx a0=%08lx a4=%08lx %c%c%c%c%c\n", regs.regs[0],regs.regs[4],regs.regs[8],regs.regs[12], ((regs.sr.sr_int >> 4) & 1 ? 'X' : '-'), ((regs.sr.sr_int >> 3) & 1 ? 'N' : '-'), ((regs.sr.sr_int >> 2) & 1 ? 'Z' : '-'), ((regs.sr.sr_int >> 1) & 1 ? 'V' : '-'), ((regs.sr.sr_int ) & 1 ? 'C' : '-')); printf("d1=%08lx d5=%08lx a1=%08lx a5=%08lx\n", regs.regs[1],regs.regs[5],regs.regs[9],regs.regs[13]); printf("d2=%08lx d6=%08lx a2=%08lx a6=%08lx\n", regs.regs[2],regs.regs[6],regs.regs[10],regs.regs[14]); printf("d3=%08lx d7=%08lx a3=%08lx a7=%08lx usp=%08lx\n", regs.regs[3],regs.regs[7],regs.regs[11],regs.regs[15],regs.sp); printf("PC=%08lx SR=%04x\n",PC,SR); } void jit_dump68kreg(void) { #[ call gen68k_dumpreg nop ]#; } void jit_printipc(struct _t_ipc *ipc) { #[ set ipc,%o0 call cpu68k_printipc nop ]# } void sparc_dump_localreg(void) { #[ set (int)"l0=%08lx l1=%08lx l2=%08lx l3=%08lx\n",%o0 mov %l0,%o1 mov %l1,%o2 mov %l2,%o3 mov %l3,%o4 call printf nop set (int)"l4=%08lx l5=%08lx l6=%08lx l7=%08lx\n",%o0 mov %l4,%o1 mov %l5,%o2 mov %l6,%o3 mov %l7,%o4 call printf nop ]#; } typedef void (*pvfi)(struct _t_ipc *ipc); static insn *code_buf; static unsigned int buf_size; #define CODE_BUF_MAX 1024*1024 //#define CODE_BUF_MAX 128000 #define CODE_BUF_MARGE 1024 /* should be ok */ static uint32 jit_fetchbyte_sigext(uint32 addr) { return (sint32)(sint8)fetchbyte(addr); } static uint32 jit_fetchword_sigext(uint32 addr) { return (sint32)(sint16)fetchword(addr); } static uint32 jit_fetchbyte(uint32 addr) { return (uint32)fetchbyte(addr); } static uint32 jit_fetchword(uint32 addr) { return (uint32)fetchword(addr); } static uint32 jit_fetchlong(uint32 addr) { //printf("fetchlong %x\n",addr); return fetchlong(addr); } static void jit_storebyte(uint32 addr,uint32 data) { storebyte(addr,data&0xFF); } static void jit_storeword(uint32 addr,uint32 data) { storeword(addr,data&0xFFFF); } static void jit_storelong(uint32 addr,uint32 data) { //printf("storelong %x=%x\n",addr,data); storelong(addr,data); } static int srcreg,dstreg; static uint32 srcaddr,dstaddr; static uint32 srcdata,dstdata,outdata; #define CLEAR_SR_FLAG(a) /* #define CLEAR_SR_FLAG(a) \ clmask=0xFFFFFFFF; \ if ((ipc->set & IIB_FLAG_C) && ((a)&mask_c)) clmask&=nmask_c; \ if ((ipc->set & IIB_FLAG_N) && ((a)&mask_n)) clmask&=nmask_n; \ if ((ipc->set & IIB_FLAG_Z) && ((a)&mask_z)) clmask&=nmask_z; \ if ((ipc->set & IIB_FLAG_V) && ((a)&mask_v)) clmask&=nmask_v; \ if ((ipc->set & IIB_FLAG_X) && ((a)&mask_x)) clmask&=nmask_x; \ jit_andi_ui(JIT_V2,JIT_V2,clmask); */ static uint32 pc_incr; /* processor dependant stuff: */ #define REGBASE 0 /* %l0 */ #define SRCDATA 1 /* %l1 */ #define DSTDATA 2 /* %l2 */ #define SRCADDR 4 /* %l4 */ #define DSTADDR 5 /* %l5 */ #define HOSTSR 7 static __inline__ void jit_idxval_dst(t_ipc *ipc, t_iib *iib) { t_datatype datatype = iib->dtype; uint32 dsp=ipc->dst; dsp=(dsp&0x800000?dsp|0xFF000000:dsp&0xFFFFFF); switch( ((ipc->dst>>27) & 1) | ((ipc->dst>>30) & 2) ) { case 0: /* data, word */ #[ ldsh [%l0+(((ipc->dst>>28)&7)*4+2)],%l6 ]#; break; case 1: /* data, long */ #[ ld [%l0+(((ipc->dst>>28)&7)*4)],%l6 ]#; break; case 2: /* addr, word */ #[ ldsh [%l0+((8+((ipc->dst>>28)&7))*4+2)],%l6 ]#; break; case 3: /* addr, long */ #[ ld [%l0+((8+((ipc->dst>>28)&7))*4)],%l6 ]#; break; } if (datatype==dt_Aidx) { #[ add %l6,%l5,%l5 set dsp,%l6 add %l6,%l5,%l5 ]#; } else { #[ set dsp,%l5 add %l6,%l5,%l5 ]#; } } static __inline__ void jit_idxval_src(t_ipc *ipc, t_iib *iib) { t_datatype datatype = iib->stype; uint32 dsp=ipc->src; dsp=(dsp&0x800000?dsp|0xFF000000:dsp&0xFFFFFF); switch( ((ipc->src>>27) & 1) | ((ipc->src>>30) & 2) ) { case 0: /* data, word */ #[ ldsh [%l0+(((ipc->src>>28)&7)*4+2)],%l6 ]#; break; case 1: /* data, long */ #[ ld [%l0+(((ipc->src>>28)&7)*4)],%l6 ]#; break; case 2: /* addr, word */ #[ ldsh [%l0+((8+((ipc->src>>28)&7))*4+2)],%l6 ]#; break; case 3: /* addr, long */ #[ ld [%l0+((8+((ipc->src>>28)&7))*4)],%l6 ]#; break; } if (datatype==dt_Aidx) { #[ add %l6,%l4,%l4 set dsp,%l6 add %l6,%l4,%l4 ]#; } else { #[ set dsp,%l4 add %l6,%l4,%l4 ]#; } } static int generate_ea(t_ipc *ipc, t_iib *iib, t_type type, int update) { t_datatype datatype = type ? iib->dtype : iib->stype; switch(datatype) { case dt_Dreg: if (type == tp_src) { srcreg=((ipc->opcode >> iib->sbitpos) & 7)*4; } else { dstreg=((ipc->opcode >> iib->dbitpos) & 7)*4; } break; case dt_Areg: case dt_Aind: case dt_Ainc: case dt_Adec: case dt_Adis: case dt_Aidx: if (type == tp_src) { srcreg=(8+((ipc->opcode >> iib->sbitpos) & 7))*4; } else { dstreg=(8+((ipc->opcode >> iib->dbitpos) & 7))*4; } break; default: break; } if (datatype == dt_Ainc && update) { uint8 incr=0; switch(iib->size) { //case sz_byte:incr=(type == tp_src?(srcreg == (8+7)*4 ? 2 : 1):(dstreg == (8+7*4) ? 2 : 1));break; case sz_byte:incr=(type == tp_src?(((ipc->opcode >> iib->sbitpos) & 7) == 7 ? 2 : 1):(((ipc->opcode >> iib->dbitpos) & 7) == 7 ? 2 : 1));break; case sz_word:incr=2;break; case sz_long:incr=4;break; default: break; } if (type == tp_src) { #[ ld [%l0+srcreg],%l4 add %l4,incr,%l6 st %l6,[%l0+srcreg] ]#; } else { #[ ld [%l0+dstreg],%l5 add %l5,incr,%l6 st %l6,[%l0+dstreg] ]#; } } else if (datatype == dt_Adec && update) { uint8 incr=0; switch(iib->size) { //case sz_byte:incr=(type == tp_src?(srcreg == (8+7)*4 ? 2 : 1):(dstreg == (8+7)*4 ? 2 : 1));break; case sz_byte:incr=(type == tp_src?(((ipc->opcode >> iib->sbitpos) & 7) == 7 ? 2 : 1):(((ipc->opcode >> iib->dbitpos) & 7) == 7 ? 2 : 1));break; case sz_word:incr=2;break; case sz_long:incr=4;break; default: break; } if (type == tp_src) { #[ ld [%l0+srcreg],%l4 sub %l4,incr,%l4 st %l4,[%l0+srcreg] ]#; } else { #[ ld [%l0+dstreg],%l5 sub %l5,incr,%l5 st %l5,[%l0+dstreg] ]#; } } else { /* no update required */ switch(datatype) { case dt_Dreg: case dt_Areg: break; case dt_Aind: case dt_Adec: case dt_Ainc: if (type == tp_src) { #[ ld [%l0+srcreg],%l4 ]#; } else { #[ ld [%l0+dstreg],%l5 ]#; } break; case dt_Adis: if (type == tp_src) { #[ sethi %hi(ipc->src&0x8000?ipc->src|0xFFFF0000:ipc->src&0xFFFF),%l6 ld [%l0+srcreg],%l4 # set (ipc->src&0x8000?ipc->src|0xFFFF0000:ipc->src&0xFFFF),%l6 or %l6,%lo(ipc->src&0x8000?ipc->src|0xFFFF0000:ipc->src&0xFFFF),%l6 add %l4,%l6,%l4 ]#; } else { #[ sethi %hi(ipc->dst&0x8000?ipc->dst|0xFFFF0000:ipc->dst&0xFFFF),%l6 ld [%l0+dstreg],%l5 # set (ipc->dst&0x8000?ipc->dst|0xFFFF0000:ipc->dst&0xFFFF),%l6 or %l6,%lo(ipc->dst&0x8000?ipc->dst|0xFFFF0000:ipc->dst&0xFFFF),%l6 add %l5,%l6,%l5 ]#; } break; case dt_Aidx: //return 1; if (type == tp_src) { #[ ld [%l0+srcreg],%l4 ]#; jit_idxval_src(ipc,iib); } else { #[ ld [%l0+dstreg],%l5 ]#; jit_idxval_dst(ipc,iib); } break; case dt_AbsW: case dt_AbsL: case dt_Pdis: if (type == tp_src) { #[ set ipc->src,%l4 ]#; } else { #[ set ipc->dst,%l5 ]#; } break; case dt_Pidx: if (type == tp_src) { jit_idxval_src(ipc,iib); } else { jit_idxval_dst(ipc,iib); } break; case dt_ImmB: case dt_ImmW: case dt_ImmL: case dt_ImmS: case dt_Imm3: case dt_Imm4: case dt_Imm8: case dt_Imm8s: /* no address - it is immediate */ break; default: break; } } return 0; } static int generate_eaval(t_ipc *ipc, t_iib *iib, t_type type,unsigned char sigext) { t_datatype datatype = type ? iib->dtype : iib->stype; int areg,lreg,hreg; /* get value in EA */ if (type == tp_src) { areg=#(%l4)#;lreg=#(%l1)#;hreg=srcreg; } else { areg=#(%l5)#;lreg=#(%l2)#;hreg=dstreg; } switch(datatype) { case dt_Dreg: case dt_Areg: /* TODO: verify if sign extend is necessary */ if (sigext) { switch(iib->size) { case sz_byte: #[ ldsb [%l0+hreg+3],%r(lreg) ]#; break; case sz_word: #[ ldsh [%l0+hreg+2],%r(lreg) ]#; break; case sz_long: #[ ld [%l0+hreg],%r(lreg) ]#; break; default: break; } } else { switch(iib->size) { case sz_byte: #[ ldub [%l0+hreg+3],%r(lreg) ]#; break; case sz_word: #[ lduh [%l0+hreg+2],%r(lreg) ]#; break; case sz_long: #[ ld [%l0+hreg],%r(lreg) ]#; break; default: break; } // #[ ld [%l0+hreg],%r(lreg) ]#; /* if (type == tp_src) { #[ ld [%l0+srcreg],%l1 ]#; } else { #[ ld [%l0+dstreg],%l2 ]#; } */ } break; case dt_Aind: case dt_Adec: case dt_Ainc: case dt_Adis: case dt_Aidx: case dt_AbsW: case dt_AbsL: case dt_Pdis: case dt_Pidx: switch(iib->size) { case sz_byte: if (sigext) { #[call jit_fetchbyte_sigext]# } else { #[call jit_fetchbyte]# } break; case sz_word: if (sigext) { #[call jit_fetchword_sigext]# } else { #[call jit_fetchword]# } break; case sz_long: #[call jit_fetchlong]#; break; } #[ mov %r(areg),%o0 # delay slot mov %o0,%r(lreg) ]#; break; case dt_Imm3: case dt_Imm4: case dt_Imm8: case dt_ImmB: if (type == tp_src) { #[ mov (ipc->src&0xFF),%l1 ]#; } else { #[ mov (ipc->dst&0xFF),%l2 ]#; } break; case dt_ImmW: if (type == tp_src) { #[ set (ipc->src&0xFFFF),%l1 ]#; } else { #[ set (ipc->dst&0xFFFF),%l2 ]#; } break; case dt_ImmL: if (type == tp_src) { #[ set (ipc->src),%l1 ]#; } else { #[ set (ipc->dst),%l2 ]#; } break; case dt_ImmS: if (type == tp_src) { #[ set (iib->immvalue),%l1 ]#; } else { #[ set (iib->immvalue),%l2 ]#; } break; case dt_Imm8s: if (type == tp_src) { #[ set (ipc->src&0x80?ipc->src|0xFFFFFF00:ipc->src&0xFF),%l1 ]#; } else { #[ set (ipc->dst&0x80?ipc->dst|0xFFFFFF00:ipc->dst&0xFF),%l2 ]#; } break; default: break; } return 0; } static int generate_eastore(t_ipc *ipc, t_iib *iib, t_type type,int outdatareg) { /* get value in EA */ switch(type == tp_dst ? iib->dtype : iib->stype) { case dt_Dreg: case dt_Areg: switch (iib->size) { case sz_byte: if (type == tp_src) { #[ stb %r(outdatareg),[%l0+(srcreg+3)] ]#; } else { #[ stb %r(outdatareg),[%l0+(dstreg+3)] ]#; } break; case sz_word: if (type == tp_src) { #[ sth %r(outdatareg),[%l0+(srcreg+2)] ]#; } else { #[ sth %r(outdatareg),[%l0+(dstreg+2)] ]#; } break; case sz_long: if (type == tp_src) { #[ st %r(outdatareg),[%l0+(srcreg)] ]#; } else { #[ st %r(outdatareg),[%l0+(dstreg)] ]#; } break; default: break; } break; case dt_Adec: switch(iib->size) { case sz_byte: if (type == tp_src) { #[ mov %l4,%o0 call jit_storebyte mov %r(outdatareg),%o1 # delayslot ]#; } else { #[ mov %l5,%o0 call jit_storebyte mov %r(outdatareg),%o1 # delayslot ]#; } break; case sz_word: if (type == tp_src) { #[ mov %l4,%o0 call jit_storeword mov %r(outdatareg),%o1 # delayslot ]#; } else { #[ mov %l5,%o0 call jit_storeword mov %r(outdatareg),%o1 # delayslot ]#; } break; case sz_long: if (type == tp_src) { #[ /* storeword(srcaddr + 2, (uint16)outdata); */ add %l4,2,%o0 call jit_storeword mov %r(outdatareg),%o1 # delayslot /* storeword(srcaddr, (uint16)(outdata >> 16)) */ mov %l4,%o0 call jit_storeword srl %r(outdatareg),16,%o1 # delayslot ]#; } else { #[ /* storeword(dstaddr + 2, (uint16)outdata); */ add %l5,2,%o0 call jit_storeword mov %r(outdatareg),%o1 # delayslot /* storeword(dstaddr, (uint16)(outdata >> 16)) */ mov %l5,%o0 call jit_storeword srl %r(outdatareg),16,%o1 # delayslot ]#; } break; default: break; } break; case dt_Aind: case dt_Ainc: case dt_Adis: case dt_Aidx: case dt_AbsW: case dt_AbsL: case dt_Pdis: case dt_Pidx: switch(iib->size) { case sz_byte: if (type == tp_src) { #[ mov %l4,%o0 call jit_storebyte mov %r(outdatareg),%o1 # delayslot ]#; } else { #[ mov %l5,%o0 call jit_storebyte mov %r(outdatareg),%o1 # delayslot ]#; } break; case sz_word: if (type == tp_src) { #[ mov %l4,%o0 call jit_storeword mov %r(outdatareg),%o1 # delayslot ]#; } else { #[ mov %l5,%o0 call jit_storeword mov %r(outdatareg),%o1 # delayslot ]#; } break; case sz_long: if (type == tp_src) { #[ mov %l4,%o0 call jit_storelong mov %r(outdatareg),%o1 # delayslot ]#; } else { #[ mov %l5,%o0 call jit_storelong mov %r(outdatareg),%o1 # delayslot ]#; } break; default: break; } break; default: break; } return 0; } void generate_cc(t_ipc *ipc, t_iib *iib) { switch(iib->cc) { case 6: #[ and %l7,ZMASK,%l6 orn %g0,%l6,%l6 andcc %l6,ZMASK,%g0 ]#; break; default: break; } } void end_func(void) { /*jit_dump68kreg(); sparc_dump_localreg();*/ #[ /* restore SR */ set &JSR,%l6 sth %l7,[%l6] ret restore ]#; } void update_pc(void) { //printf("updatepc, pc_incr=%d\n",pc_incr); if (pc_incr) { /* TODO, pc+=((iib->wordlen)*2) */ #[ set &PC,%l1 ld [%l1],%l2 add %l2,pc_incr,%l2 st %l2,[%l1] ]# pc_incr=0; } } static void call_c_function(struct _t_ipc *ipc) { update_pc(); nb_func++; #[ # update SR set &JSR,%l6 sth %l7,[%l6] # ipc->function(ipc) sethi %hi(ipc),%o0 call ipc->function or %o0,%lo(ipc),%o0 # delay slot #set &JSR,%l6 lduh [%l6],%l7 ]#; } void compile_ipc(struct _t_ipc *ipc) { t_iib * iib = cpu68k_iibtable[ipc->opcode]; uint32 clmask; insn *fref; instr_stat[iib->mnemonic]++; switch (iib->mnemonic) { case i_BTST: case i_BCHG: case i_BCLR: case i_BSET: break; default: if (ipc->set) { //printf("flags version\n"); nb_flag++; call_c_function(ipc); return; } break; } nb_recomp++; //cpu68k_printipc(ipc); switch (iib->mnemonic) { case i_OR: case i_AND: case i_EOR: generate_ea(ipc, iib, tp_src, 1); generate_ea(ipc, iib, tp_dst, 1); generate_eaval(ipc, iib, tp_src,0); generate_eaval(ipc, iib, tp_dst,0); switch(iib->mnemonic) { case i_OR: #[ or %l2,%l1,%l3 ]#; break; case i_AND: #[ and %l2,%l1,%l3 ]#; break; case i_EOR: #[ xor %l2,%l1,%l3 ]#; break; default: break; } //cast_outdata(ipc,iib); generate_eastore(ipc, iib, tp_dst,#(%l3)# ); pc_incr+=((iib->wordlen)*2); break; case i_SUB: generate_ea(ipc, iib, tp_src, 1); generate_ea(ipc, iib, tp_dst, 1); generate_eaval(ipc, iib, tp_src,0); generate_eaval(ipc, iib, tp_dst,0); #[ sub %l2,%l1,%l3 ]#; generate_eastore(ipc, iib, tp_dst,#(%l3)# ); pc_incr+=((iib->wordlen)*2); break; case i_ADD: //cpu68k_printipc(ipc); generate_ea(ipc, iib, tp_src, 1); generate_ea(ipc, iib, tp_dst, 1); generate_eaval(ipc, iib, tp_src,0); generate_eaval(ipc, iib, tp_dst,0); #[ add %l2,%l1,%l3 ]#; generate_eastore(ipc, iib, tp_dst,#(%l3)# ); pc_incr+=((iib->wordlen)*2); break; case i_ADDA: generate_ea(ipc, iib, tp_src, 1); generate_ea(ipc, iib, tp_dst, 1); generate_eaval(ipc, iib, tp_src,1); //generate_eaval(ipc, iib, tp_dst); #[ ld [%l0+dstreg],%l2 add %l2,%l1,%l3 st %l3,[%l0+dstreg] ]#; //generate_eastore(ipc, iib, tp_dst,#(%l3)# ); pc_incr+=((iib->wordlen)*2); break; case i_BTST: case i_BCHG: case i_BCLR: case i_BSET: generate_ea(ipc, iib, tp_src, 1); generate_ea(ipc, iib, tp_dst, 1); generate_eaval(ipc, iib, tp_src,0); generate_eaval(ipc, iib, tp_dst,0); /* %l1 = 1<<(bitpos&(7 or 31)) */ #[ mov 1,%l6 ]#; switch (iib->size) { case sz_byte: #[ and %l1,7,%l1 ]#;break; case sz_long: #[ and %l1,31,%l1 ]#;break; default: break; } #[ sll %l6,%l1,%l1 ]#; switch(iib->mnemonic) { case i_BTST: break; case i_BCHG: #[ xor %l2,%l1,%l3 ]#; //generate_eastore(ipc, iib, tp_dst,#(%l3)# ); break; case i_BCLR: #[ andn %l2,%l1,%l3 ]#; //generate_eastore(ipc, iib, tp_dst,#(%l3)# ); break; case i_BSET: #[ or %l2,%l1,%l3 ]#; //generate_eastore(ipc, iib, tp_dst,#(%l3)# ); break; default: break; } //OUT(" ZFLAG = !(dstdata & bitpos);\n"); #{ andcc %l2,%l1,%g0 be fref or %l7,0x04,%l7 andn %l7,0x04,%l7 fref: }#; if (iib->mnemonic!=i_BTST) generate_eastore(ipc, iib, tp_dst,#(%l3)# ); pc_incr+=((iib->wordlen)*2); break; case i_MOVE: generate_ea(ipc, iib, tp_src, 1); generate_ea(ipc, iib, tp_dst, 1); generate_eaval(ipc, iib, tp_src,0); generate_eastore(ipc, iib, tp_dst,#(%l1)#); pc_incr+=((iib->wordlen)*2); break; case i_LEA: generate_ea(ipc, iib, tp_src, 1); generate_ea(ipc, iib, tp_dst, 1); generate_eastore(ipc, iib, tp_dst,#(%l4)# ); pc_incr+=((iib->wordlen)*2); break; case i_EXT: /* TODO: optimize that */ if (iib->size==sz_long) { #[ sethi %hi(0x8000),%l2 sethi %hi(0xFFFF),%l5 or %l2,%lo(0x8000),%l2 or %l5,%lo(0xFFFF),%l5 ]#; } generate_ea(ipc, iib, tp_src, 1); generate_eaval(ipc, iib, tp_src,0); switch(iib->size) { case sz_word: #{ andcc %l1,0x80,%g0 # ; be fref # ; and %l1,0xFF,%l1 #; orn %l1,0xFF,%l1 # ; fref: }#; break; case sz_long: #{ andcc %l1,%l2,%g0 # ; be fref # ; and %l1,%l5,%l1 # ; orn %l1,%l5,%l1 # ; fref: }#; break; default: break; } generate_eastore(ipc, iib, tp_src,#(%l1)# ); pc_incr+=((iib->wordlen)*2); break; case i_NOP: pc_incr+=((iib->wordlen)*2); break; case i_RTS: #[ sethi %hi(&PC),%l1 ld [%l0 + ((8+7)*4)],%o0 or %l1,%lo(&PC),%l1 call jit_fetchlong add %o0,4,%l2 st %o0,[%l1] st %l2,[%l0 + ((8+7)*4)] ]#; pc_incr=0; break; case i_JSR: generate_ea(ipc, iib, tp_src, 1); /* TODO: check the size of pc_incr */ pc_incr+=((iib->wordlen)*2); #[ sethi %hi(&PC),%l1 ld [%l0 + ((8+7)*4)],%o0 or %l1,%lo(&PC),%l1 ld [%l1],%l3 sub %o0,4,%o0 call jit_storelong add %l3,pc_incr,%o1 st %o0,[%l0 + ((8+7)*4)] st %l4,[%l1] ]#; pc_incr=0; break; case i_Bcc: switch (iib->cc) { /*case 0: case 1:*/ case 2: case 3: case 4: case 5: //case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: call_c_function(ipc); break; default: //printf("YOOYOYOOY\n"); #[ set (ipc->src),%l1 set &PC,%l2 ld [%l2],%l3 ]#; if (iib->cc==0) { #[ mov %l1,%l3 st %l3,[%l2] ]#; } else if (iib->cc==1) { #[ add %l3,(pc_incr+(iib->wordlen)*2),%l3 # ; st %l3,[%l2] ]#; } else { generate_cc(ipc,iib); #{ be fref # ; add %l3,(pc_incr+(iib->wordlen)*2),%l3 # ; mov %l1,%l3 fref: st %l3,[%l2] #; }#; } pc_incr=0; break; } break; default: //printf("Default\n"); call_c_function(ipc); break; } return; } void (*compile_make(t_ipclist *list))(struct _t_ipc *ipc) { pvfi block_function; /* ptr to generated code */ insn *start, *end; /* a couple of labels */ int ofs; /* to get the argument */ t_ipc * ipc; char need_more=0; int i; void (*func)(struct _t_ipc *ipc); char *printformat="SR =%x\n"; if (!code_buf) { /* init */ t_sr sr_reg; sr_reg.sr_int=0;sr_reg.sr_struct.t=1; mask_t=(uint32)sr_reg.sr_int;nmask_t=~mask_t; sr_reg.sr_int=0;sr_reg.sr_struct.s=1; mask_s=(uint32)sr_reg.sr_int;nmask_s=~mask_s; sr_reg.sr_int=0;sr_reg.sr_struct.x=1; mask_x=(uint32)sr_reg.sr_int;nmask_x=~mask_x; sr_reg.sr_int=0;sr_reg.sr_struct.n=1; mask_n=(uint32)sr_reg.sr_int;nmask_n=~mask_n; sr_reg.sr_int=0;sr_reg.sr_struct.z=1; mask_z=(uint32)sr_reg.sr_int;nmask_z=~mask_z; sr_reg.sr_int=0;sr_reg.sr_struct.v=1; mask_v=(uint32)sr_reg.sr_int;nmask_v=~mask_v; sr_reg.sr_int=0;sr_reg.sr_struct.c=1; mask_c=(uint32)sr_reg.sr_int;nmask_c=~mask_c; } do { ipc = (t_ipc *) (list + 1); if ((!code_buf) || need_more) { code_buf=malloc(CODE_BUF_MAX*sizeof(insn)); buf_size=0; need_more=0; printf("alloc new code buf\n"); } block_function=(pvfi)(code_buf+buf_size); #[ .org block_function #code_buf+buf_size # start = jit_get_ip().ptr; # %i0=ipc start: save %sp, -64, %sp /* %l7=SR, %l0=DATAREG */ set &(JSR), %l6 set &DATAREG(0), %l0 lduh [%l6], %l7 ]#; //jit_dump68kreg(); //printf("SR=%08lx\n",SR); do { //cpu68k_printipc(ipc); compile_ipc(ipc); if (buf_size+(unsigned int)(asm_pc-start)>(CODE_BUF_MAX-CODE_BUF_MARGE)) { printf("Warning %d %d\n",buf_size,(unsigned int)(asm_pc-start)); need_more=1; break; } //jit_addi_p(JIT_R0,JIT_R0,1); ipc++; } while (*(int *)ipc); } while(need_more!=0); update_pc(); end_func(); #[ end: ]#; iflush(start, end); buf_size+=(unsigned int)(end-start); buf_size|=0xf;buf_size+=1; //printf("End compile buf_size=%d\n",buf_size); //printf("func=%d (flag=%d nonflag=%d) recomp=%d\n",nb_func,nb_flag,nb_func-nb_flag,nb_recomp); /* for(i=0;i