+void c2ls_assemble(int i,struct regstat *i_regs)
+{
+ int s,tl;
+ int ar;
+ int offset;
+ int c=0;
+ int jaddr,jaddr2=0,jaddr3,type;
+ int agr=AGEN1+(i&1);
+ u_int hr,reglist=0;
+ u_int copr=(source[i]>>16)&0x1f;
+ s=get_reg(i_regs->regmap,rs1[i]);
+ tl=get_reg(i_regs->regmap,FTEMP);
+ offset=imm[i];
+ assert(rs1[i]>0);
+ assert(tl>=0);
+ assert(!using_tlb);
+
+ 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);
+
+ // get the address
+ if (opcode[i]==0x3a) { // SWC2
+ ar=get_reg(i_regs->regmap,agr);
+ if(ar<0) ar=get_reg(i_regs->regmap,-1);
+ reglist|=1<<ar;
+ } else { // LWC2
+ ar=tl;
+ }
+ if (!offset&&!c&&s>=0) ar=s;
+ assert(ar>=0);
+
+ if (opcode[i]==0x3a) { // SWC2
+ cop2_get_dreg(copr,tl,HOST_TEMPREG);
+ }
+ if(s>=0) c=(i_regs->wasconst>>s)&1;
+ if(!c) {
+ emit_cmpimm(offset||c||s<0?ar:s,0x800000);
+ jaddr2=(int)out;
+ emit_jno(0);
+ }
+ else if(((signed int)(constmap[i][s]+offset))>=(signed int)0x80800000) {
+ jaddr2=(int)out;
+ emit_jmp(0); // inline_readstub/inline_writestub? Very rare case
+ }
+ if (opcode[i]==0x32) { // LWC2
+ #ifdef HOST_IMM_ADDR32
+ if(c) emit_readword_tlb(constmap[i][s]+offset,-1,tl);
+ else
+ #endif
+ emit_readword_indexed(0,ar,tl);
+ type=LOADW_STUB;
+ }
+ if (opcode[i]==0x3a) { // SWC2
+#ifdef DESTRUCTIVE_SHIFT
+ if(!offset&&!c&&s>=0) emit_mov(s,ar);
+#endif
+ emit_writeword_indexed(tl,0,ar);
+ type=STOREW_STUB;
+ }
+ if(jaddr2)
+ add_stub(type,jaddr2,(int)out,i,ar,(int)i_regs,ccadj[i],reglist);
+ if (opcode[i]==0x3a) { // SWC2
+#if defined(HOST_IMM8)
+ int ir=get_reg(i_regs->regmap,INVCP);
+ assert(ir>=0);
+ emit_cmpmem_indexedsr12_reg(ir,ar,1);
+#else
+ emit_cmpmem_indexedsr12_imm((int)invalid_code,ar,1);
+#endif
+ jaddr3=(int)out;
+ emit_jne(0);
+ add_stub(INVCODE_STUB,jaddr3,(int)out,reglist|(1<<HOST_CCREG),ar,0,0,0);
+ }
+ if (opcode[i]==0x32) { // LWC2
+ cop2_put_dreg(copr,tl,HOST_TEMPREG);
+ }
+}
+