- if(!c||memtarget)
- //emit_writeword_indexed(tl,(int)rdram-0x80000000,addr);
- emit_writeword_indexed_tlb(tl,0,addr,map,temp);
- type=STOREW_STUB;
- }
- if (opcode[i]==0x3F) { // SD
- if(!c||memtarget) {
- if(rs2[i]) {
- assert(th>=0);
- //emit_writeword_indexed(th,(int)rdram-0x80000000,addr);
- //emit_writeword_indexed(tl,(int)rdram-0x7FFFFFFC,addr);
- emit_writedword_indexed_tlb(th,tl,0,addr,map,temp);
- }else{
- // Store zero
- //emit_writeword_indexed(tl,(int)rdram-0x80000000,temp);
- //emit_writeword_indexed(tl,(int)rdram-0x7FFFFFFC,temp);
- emit_writedword_indexed_tlb(tl,tl,0,addr,map,temp);
- }
- }
- type=STORED_STUB;
- }
- if(!using_tlb&&(!c||memtarget))
- // addr could be a temp, make sure it survives STORE*_STUB
- reglist|=1<<addr;
- if(jaddr) {
- add_stub(type,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
- } else if(!memtarget) {
- inline_writestub(type,i,constmap[i][s]+offset,i_regs->regmap,rs2[i],ccadj[i],reglist);
- }
- if(!using_tlb) {
- if(!c||memtarget) {
- #ifdef DESTRUCTIVE_SHIFT
- // The x86 shift operation is 'destructive'; it overwrites the
- // source register, so we need to make a copy first and use that.
- addr=temp;
- #endif
- #if defined(HOST_IMM8)
- int ir=get_reg(i_regs->regmap,INVCP);
- assert(ir>=0);
- emit_cmpmem_indexedsr12_reg(ir,addr,1);
- #else
- emit_cmpmem_indexedsr12_imm((int)invalid_code,addr,1);
- #endif
- jaddr2=(int)out;
- emit_jne(0);
- add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<<HOST_CCREG),addr,0,0,0);
- }
- }
- //if(opcode[i]==0x2B || opcode[i]==0x3F)
- //if(opcode[i]==0x2B || opcode[i]==0x28)
- //if(opcode[i]==0x2B || opcode[i]==0x29)
- //if(opcode[i]==0x2B)
- /*if(opcode[i]==0x2B || opcode[i]==0x28 || opcode[i]==0x29 || opcode[i]==0x3F)
- {
- //emit_pusha();
- save_regs(0x100f);
- emit_readword((int)&last_count,ECX);
- #ifdef __i386__
- if(get_reg(i_regs->regmap,CCREG)<0)
- emit_loadreg(CCREG,HOST_CCREG);
- emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG);
- emit_writeword(HOST_CCREG,(int)&Count);
- #endif
- #ifdef __arm__
- if(get_reg(i_regs->regmap,CCREG)<0)
- emit_loadreg(CCREG,0);
- else
- emit_mov(HOST_CCREG,0);
- emit_add(0,ECX,0);
- emit_addimm(0,2*ccadj[i],0);
- emit_writeword(0,(int)&Count);
- #endif
- emit_call((int)memdebug);
- //emit_popa();
- restore_regs(0x100f);
- }/**/
-}
-
-void storelr_assemble(int i,struct regstat *i_regs)
-{
- int s,th,tl;
- int temp;
- int temp2;
- int offset;
- int jaddr=0,jaddr2;
- int case1,case2,case3;
- int done0,done1,done2;
- int memtarget,c=0;
- int agr=AGEN1+(i&1);
- u_int hr,reglist=0;
- th=get_reg(i_regs->regmap,rs2[i]|64);
- tl=get_reg(i_regs->regmap,rs2[i]);
- s=get_reg(i_regs->regmap,rs1[i]);
- temp=get_reg(i_regs->regmap,agr);
- if(temp<0) temp=get_reg(i_regs->regmap,-1);
- offset=imm[i];
- if(s>=0) {
- c=(i_regs->isconst>>s)&1;
- memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
- if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
- }
- assert(tl>=0);
- for(hr=0;hr<HOST_REGS;hr++) {
- if(i_regs->regmap[hr]>=0) reglist|=1<<hr;
- }
- if(tl>=0) {
- assert(temp>=0);
- if(!using_tlb) {
- if(!c) {
- emit_cmpimm(s<0||offset?temp:s,RAM_SIZE);
- if(!offset&&s!=temp) emit_mov(s,temp);
- jaddr=(int)out;
- emit_jno(0);
- }
- else
- {
- if(!memtarget||!rs1[i]) {
- jaddr=(int)out;
- emit_jmp(0);
- }
- }
- if((u_int)rdram!=0x80000000)
- emit_addimm_no_flags((u_int)rdram-(u_int)0x80000000,temp);
- }else{ // using tlb
- int map=get_reg(i_regs->regmap,TLREG);
- assert(map>=0);
- map=do_tlb_w(c||s<0||offset?temp:s,temp,map,0,c,constmap[i][s]+offset);
- if(!c&&!offset&&s>=0) emit_mov(s,temp);
- do_tlb_w_branch(map,c,constmap[i][s]+offset,&jaddr);
- if(!jaddr&&!memtarget) {
- jaddr=(int)out;
- emit_jmp(0);
- }
- gen_tlb_addr_w(temp,map);
- }
-
- if (opcode[i]==0x2C||opcode[i]==0x2D) { // SDL/SDR
- temp2=get_reg(i_regs->regmap,FTEMP);
- if(!rs2[i]) temp2=th=tl;
- }
-
-#ifndef BIG_ENDIAN_MIPS
- emit_xorimm(temp,3,temp);
-#endif
- emit_testimm(temp,2);
- case2=(int)out;
- emit_jne(0);
- emit_testimm(temp,1);
- case1=(int)out;
- emit_jne(0);
- // 0
- if (opcode[i]==0x2A) { // SWL
- emit_writeword_indexed(tl,0,temp);
- }
- if (opcode[i]==0x2E) { // SWR
- emit_writebyte_indexed(tl,3,temp);
- }
- if (opcode[i]==0x2C) { // SDL
- emit_writeword_indexed(th,0,temp);
- if(rs2[i]) emit_mov(tl,temp2);
- }
- if (opcode[i]==0x2D) { // SDR
- emit_writebyte_indexed(tl,3,temp);
- if(rs2[i]) emit_shldimm(th,tl,24,temp2);