-#ifndef DISABLE_COP1
- // Check cop1 unusable
- if(!cop1_usable) {
- signed char rs=get_reg(i_regs->regmap,CSREG);
- assert(rs>=0);
- emit_testimm(rs,0x20000000);
- int 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 (opcode2[i]==0) { // MFC1
- signed char tl=get_reg(i_regs->regmap,rt1[i]);
- if(tl>=0) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],tl);
- emit_readword_indexed(0,tl,tl);
- }
- }
- else if (opcode2[i]==1) { // DMFC1
- signed char tl=get_reg(i_regs->regmap,rt1[i]);
- signed char th=get_reg(i_regs->regmap,rt1[i]|64);
- if(tl>=0) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],tl);
- if(th>=0) emit_readword_indexed(4,tl,th);
- emit_readword_indexed(0,tl,tl);
- }
- }
- else if (opcode2[i]==4) { // MTC1
- signed char sl=get_reg(i_regs->regmap,rs1[i]);
- signed char temp=get_reg(i_regs->regmap,-1);
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp);
- emit_writeword_indexed(sl,0,temp);
- }
- else if (opcode2[i]==5) { // DMTC1
- signed char sl=get_reg(i_regs->regmap,rs1[i]);
- signed char sh=rs1[i]>0?get_reg(i_regs->regmap,rs1[i]|64):sl;
- signed char temp=get_reg(i_regs->regmap,-1);
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp);
- emit_writeword_indexed(sh,4,temp);
- emit_writeword_indexed(sl,0,temp);
- }
- else if (opcode2[i]==2) // CFC1
- {
- signed char tl=get_reg(i_regs->regmap,rt1[i]);
- if(tl>=0) {
- u_int copr=(source[i]>>11)&0x1f;
- if(copr==0) emit_readword((int)&FCR0,tl);
- if(copr==31) emit_readword((int)&FCR31,tl);
- }
- }
- else if (opcode2[i]==6) // CTC1
- {
- signed char sl=get_reg(i_regs->regmap,rs1[i]);
- u_int copr=(source[i]>>11)&0x1f;
- assert(sl>=0);
- if(copr==31)
- {
- emit_writeword(sl,(int)&FCR31);
- // Set the rounding mode
- //FIXME
- //char temp=get_reg(i_regs->regmap,-1);
- //emit_andimm(sl,3,temp);
- //emit_fldcw_indexed((int)&rounding_modes,temp);
- }
- }
-#else
- cop1_unusable(i, i_regs);
-#endif
-}
-
-void fconv_assemble_arm(int i,struct regstat *i_regs)
-{
-#ifndef DISABLE_COP1
- signed char temp=get_reg(i_regs->regmap,-1);
- assert(temp>=0);
- // Check cop1 unusable
- if(!cop1_usable) {
- signed char rs=get_reg(i_regs->regmap,CSREG);
- assert(rs>=0);
- emit_testimm(rs,0x20000000);
- int 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(defined(__VFP_FP__) && !defined(__SOFTFP__))
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0d) { // trunc_w_s
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp);
- emit_flds(temp,15);
- emit_ftosizs(15,15); // float->int, truncate
- if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f))
- emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp);
- emit_fsts(15,temp);
- return;
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0d) { // trunc_w_d
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp);
- emit_vldr(temp,7);
- emit_ftosizd(7,13); // double->int, truncate
- emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp);
- emit_fsts(13,temp);
- return;
- }
-
- if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) { // cvt_s_w
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp);
- emit_flds(temp,13);
- if(((source[i]>>11)&0x1f)!=((source[i]>>6)&0x1f))
- emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp);
- emit_fsitos(13,15);
- emit_fsts(15,temp);
- return;
- }
- if(opcode2[i]==0x14&&(source[i]&0x3f)==0x21) { // cvt_d_w
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp);
- emit_flds(temp,13);
- emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp);
- emit_fsitod(13,7);
- emit_vstr(7,temp);
- return;
- }
-
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x21) { // cvt_d_s
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp);
- emit_flds(temp,13);
- emit_readword((int)®_cop1_double[(source[i]>>6)&0x1f],temp);
- emit_fcvtds(13,7);
- emit_vstr(7,temp);
- return;
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x20) { // cvt_s_d
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp);
- emit_vldr(temp,7);
- emit_readword((int)®_cop1_simple[(source[i]>>6)&0x1f],temp);
- emit_fcvtsd(7,13);
- emit_fsts(13,temp);
- return;
- }
- #endif
-
- // C emulation code
-
- u_int hr,reglist=0;
- for(hr=0;hr<HOST_REGS;hr++) {
- if(i_regs->regmap[hr]>=0) reglist|=1<<hr;
- }
- save_regs(reglist);
-
- if(opcode2[i]==0x14&&(source[i]&0x3f)==0x20) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_s_w);
- }
- if(opcode2[i]==0x14&&(source[i]&0x3f)==0x21) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_d_w);
- }
- if(opcode2[i]==0x15&&(source[i]&0x3f)==0x20) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_s_l);
- }
- if(opcode2[i]==0x15&&(source[i]&0x3f)==0x21) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_d_l);
- }
-
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x21) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_d_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x24) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_w_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x25) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_l_s);
- }
-
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x20) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_s_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x24) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_w_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x25) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)cvt_l_d);
- }
-
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x08) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)round_l_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x09) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)trunc_l_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0a) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)ceil_l_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0b) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)floor_l_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0c) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)round_w_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0d) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)trunc_w_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0e) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)ceil_w_s);
- }
- if(opcode2[i]==0x10&&(source[i]&0x3f)==0x0f) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)floor_w_s);
- }
-
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x08) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)round_l_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x09) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)trunc_l_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0a) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>> 6)&0x1f],ARG2_REG);
- emit_call((int)ceil_l_d);