-#ifndef DISABLE_COP1
- int s,th,tl;
- int temp,ar;
- int map=-1;
- int offset;
- int c=0;
- int jaddr,jaddr2=0,jaddr3,type;
- int agr=AGEN1+(i&1);
- u_int hr,reglist=0;
- th=get_reg(i_regs->regmap,FTEMP|64);
- tl=get_reg(i_regs->regmap,FTEMP);
- 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];
- assert(tl>=0);
- assert(rs1[i]>0);
- assert(temp>=0);
- for(hr=0;hr<HOST_REGS;hr++) {
- if(i_regs->regmap[hr]>=0) reglist|=1<<hr;
- }
- if(i_regs->regmap[HOST_CCREG]==CCREG) reglist&=~(1<<HOST_CCREG);
- if (opcode[i]==0x31||opcode[i]==0x35) // LWC1/LDC1
- {
- // Loads use a temporary register which we need to save
- reglist|=1<<temp;
- }
- if (opcode[i]==0x39||opcode[i]==0x3D) // SWC1/SDC1
- ar=temp;
- else // LWC1/LDC1
- ar=tl;
- //if(s<0) emit_loadreg(rs1[i],ar); //address_generation does this now
- //else c=(i_regs->wasconst>>s)&1;
- if(s>=0) c=(i_regs->wasconst>>s)&1;
- // Check cop1 unusable
- if(!cop1_usable) {
- signed char rs=get_reg(i_regs->regmap,CSREG);
- assert(rs>=0);
- emit_testimm(rs,0x20000000);
- jaddr=(int)out;
- emit_jeq(0);
- add_stub(FP_STUB,jaddr,(int)out,i,rs,(int)i_regs,is_delayslot,0);
- cop1_usable=1;
- }
- if (opcode[i]==0x39) { // SWC1 (get float address)
- emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],tl);
- }
- if (opcode[i]==0x3D) { // SDC1 (get double address)
- emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],tl);
- }
- // Generate address + offset
- if(!using_tlb) {
- if(!c)
- emit_cmpimm(offset||c||s<0?ar:s,RAM_SIZE);
- }
- else
- {
- map=get_reg(i_regs->regmap,TLREG);
- assert(map>=0);
- reglist&=~(1<<map);
- if (opcode[i]==0x31||opcode[i]==0x35) { // LWC1/LDC1
- map=do_tlb_r(offset||c||s<0?ar:s,ar,map,0,-1,-1,c,constmap[i][s]+offset);
- }
- if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1
- map=do_tlb_w(offset||c||s<0?ar:s,ar,map,0,c,constmap[i][s]+offset);
- }
- }
- if (opcode[i]==0x39) { // SWC1 (read float)
- emit_readword_indexed(0,tl,tl);
- }
- if (opcode[i]==0x3D) { // SDC1 (read double)
- emit_readword_indexed(4,tl,th);
- emit_readword_indexed(0,tl,tl);
- }
- if (opcode[i]==0x31) { // LWC1 (get target address)
- emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],temp);
- }
- if (opcode[i]==0x35) { // LDC1 (get target address)
- emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],temp);
- }
- if(!using_tlb) {
- if(!c) {
- jaddr2=(int)out;
- emit_jno(0);
- }
- else if(((signed int)(constmap[i][s]+offset))>=(signed int)0x80000000+RAM_SIZE) {
- jaddr2=(int)out;
- emit_jmp(0); // inline_readstub/inline_writestub? Very rare case
- }
- #ifdef DESTRUCTIVE_SHIFT
- if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1
- if(!offset&&!c&&s>=0) emit_mov(s,ar);
- }
- #endif
- }else{
- if (opcode[i]==0x31||opcode[i]==0x35) { // LWC1/LDC1
- do_tlb_r_branch(map,c,constmap[i][s]+offset,&jaddr2);
- }
- if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1
- do_tlb_w_branch(map,c,constmap[i][s]+offset,&jaddr2);
- }
- }
- if (opcode[i]==0x31) { // LWC1
- //if(s>=0&&!c&&!offset) emit_mov(s,tl);
- //gen_tlb_addr_r(ar,map);
- //emit_readword_indexed((int)rdram-0x80000000,tl,tl);
- #ifdef HOST_IMM_ADDR32
- if(c) emit_readword_tlb(constmap[i][s]+offset,map,tl);
- else
- #endif
- emit_readword_indexed_tlb(0,offset||c||s<0?tl:s,map,tl);
- type=LOADW_STUB;
- }
- if (opcode[i]==0x35) { // LDC1
- assert(th>=0);
- //if(s>=0&&!c&&!offset) emit_mov(s,tl);
- //gen_tlb_addr_r(ar,map);
- //emit_readword_indexed((int)rdram-0x80000000,tl,th);
- //emit_readword_indexed((int)rdram-0x7FFFFFFC,tl,tl);
- #ifdef HOST_IMM_ADDR32
- if(c) emit_readdword_tlb(constmap[i][s]+offset,map,th,tl);
- else
- #endif
- emit_readdword_indexed_tlb(0,offset||c||s<0?tl:s,map,th,tl);
- type=LOADD_STUB;
- }
- if (opcode[i]==0x39) { // SWC1
- //emit_writeword_indexed(tl,(int)rdram-0x80000000,temp);
- emit_writeword_indexed_tlb(tl,0,offset||c||s<0?temp:s,map,temp);
- type=STOREW_STUB;
- }
- if (opcode[i]==0x3D) { // SDC1
- assert(th>=0);
- //emit_writeword_indexed(th,(int)rdram-0x80000000,temp);
- //emit_writeword_indexed(tl,(int)rdram-0x7FFFFFFC,temp);
- emit_writedword_indexed_tlb(th,tl,0,offset||c||s<0?temp:s,map,temp);
- type=STORED_STUB;
- }
- if(!using_tlb) {
- if (opcode[i]==0x39||opcode[i]==0x3D) { // SWC1/SDC1
- #ifndef DESTRUCTIVE_SHIFT
- temp=offset||c||s<0?ar:s;
- #endif
- #if defined(HOST_IMM8)
- int ir=get_reg(i_regs->regmap,INVCP);
- assert(ir>=0);
- emit_cmpmem_indexedsr12_reg(ir,temp,1);
- #else
- emit_cmpmem_indexedsr12_imm((int)invalid_code,temp,1);
- #endif
- #if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
- emit_callne(invalidate_addr_reg[temp]);
- #else
- jaddr3=(int)out;
- emit_jne(0);
- add_stub(INVCODE_STUB,jaddr3,(int)out,reglist|(1<<HOST_CCREG),temp,0,0,0);
- #endif
- }
- }
- if(jaddr2) add_stub(type,jaddr2,(int)out,i,offset||c||s<0?ar:s,(int)i_regs,ccadj[i],reglist);
- if (opcode[i]==0x31) { // LWC1 (write float)
- emit_writeword_indexed(tl,0,temp);
- }
- if (opcode[i]==0x35) { // LDC1 (write double)
- emit_writeword_indexed(th,4,temp);
- emit_writeword_indexed(tl,0,temp);
- }
- //if(opcode[i]==0x39)
- /*if(opcode[i]==0x39||opcode[i]==0x31)
- {
- emit_pusha();
- emit_readword((int)&last_count,ECX);
- 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);
- emit_call((int)memdebug);
- emit_popa();
- }/**/
-#else