- 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);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0b) {
- 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)floor_l_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0c) {
- 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)round_w_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0d) {
- 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)trunc_w_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0e) {
- 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)ceil_w_d);
- }
- if(opcode2[i]==0x11&&(source[i]&0x3f)==0x0f) {
- 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)floor_w_d);
- }
-
- restore_regs(reglist);
-#else
- cop1_unusable(i, i_regs);
-#endif
-}
-#define fconv_assemble fconv_assemble_arm
-
-void fcomp_assemble(int i,struct regstat *i_regs)
-{
-#ifndef DISABLE_COP1
- signed char fs=get_reg(i_regs->regmap,FSREG);
- signed char temp=get_reg(i_regs->regmap,-1);
- assert(temp>=0);
- // Check cop1 unusable
- if(!cop1_usable) {
- signed char cs=get_reg(i_regs->regmap,CSREG);
- assert(cs>=0);
- emit_testimm(cs,0x20000000);
- int jaddr=(int)out;
- emit_jeq(0);
- add_stub(FP_STUB,jaddr,(int)out,i,cs,(int)i_regs,is_delayslot,0);
- cop1_usable=1;
- }
-
- if((source[i]&0x3f)==0x30) {
- emit_andimm(fs,~0x800000,fs);
- return;
- }
-
- if((source[i]&0x3e)==0x38) {
- // sf/ngle - these should throw exceptions for NaNs
- emit_andimm(fs,~0x800000,fs);
- return;
- }
-
- #if(defined(__VFP_FP__) && !defined(__SOFTFP__))
- if(opcode2[i]==0x10) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],temp);
- emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],HOST_TEMPREG);
- emit_orimm(fs,0x800000,fs);
- emit_flds(temp,14);
- emit_flds(HOST_TEMPREG,15);
- emit_fcmps(14,15);
- emit_fmstat();
- if((source[i]&0x3f)==0x31) emit_bicvc_imm(fs,0x800000,fs); // c_un_s
- if((source[i]&0x3f)==0x32) emit_bicne_imm(fs,0x800000,fs); // c_eq_s
- if((source[i]&0x3f)==0x33) {emit_bicne_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ueq_s
- if((source[i]&0x3f)==0x34) emit_biccs_imm(fs,0x800000,fs); // c_olt_s
- if((source[i]&0x3f)==0x35) {emit_biccs_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ult_s
- if((source[i]&0x3f)==0x36) emit_bichi_imm(fs,0x800000,fs); // c_ole_s
- if((source[i]&0x3f)==0x37) {emit_bichi_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ule_s
- if((source[i]&0x3f)==0x3a) emit_bicne_imm(fs,0x800000,fs); // c_seq_s
- if((source[i]&0x3f)==0x3b) emit_bicne_imm(fs,0x800000,fs); // c_ngl_s
- if((source[i]&0x3f)==0x3c) emit_biccs_imm(fs,0x800000,fs); // c_lt_s
- if((source[i]&0x3f)==0x3d) emit_biccs_imm(fs,0x800000,fs); // c_nge_s
- if((source[i]&0x3f)==0x3e) emit_bichi_imm(fs,0x800000,fs); // c_le_s
- if((source[i]&0x3f)==0x3f) emit_bichi_imm(fs,0x800000,fs); // c_ngt_s
- return;
- }
- if(opcode2[i]==0x11) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],temp);
- emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],HOST_TEMPREG);
- emit_orimm(fs,0x800000,fs);
- emit_vldr(temp,6);
- emit_vldr(HOST_TEMPREG,7);
- emit_fcmpd(6,7);
- emit_fmstat();
- if((source[i]&0x3f)==0x31) emit_bicvc_imm(fs,0x800000,fs); // c_un_d
- if((source[i]&0x3f)==0x32) emit_bicne_imm(fs,0x800000,fs); // c_eq_d
- if((source[i]&0x3f)==0x33) {emit_bicne_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ueq_d
- if((source[i]&0x3f)==0x34) emit_biccs_imm(fs,0x800000,fs); // c_olt_d
- if((source[i]&0x3f)==0x35) {emit_biccs_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ult_d
- if((source[i]&0x3f)==0x36) emit_bichi_imm(fs,0x800000,fs); // c_ole_d
- if((source[i]&0x3f)==0x37) {emit_bichi_imm(fs,0x800000,fs);emit_orrvs_imm(fs,0x800000,fs);} // c_ule_d
- if((source[i]&0x3f)==0x3a) emit_bicne_imm(fs,0x800000,fs); // c_seq_d
- if((source[i]&0x3f)==0x3b) emit_bicne_imm(fs,0x800000,fs); // c_ngl_d
- if((source[i]&0x3f)==0x3c) emit_biccs_imm(fs,0x800000,fs); // c_lt_d
- if((source[i]&0x3f)==0x3d) emit_biccs_imm(fs,0x800000,fs); // c_nge_d
- if((source[i]&0x3f)==0x3e) emit_bichi_imm(fs,0x800000,fs); // c_le_d
- if((source[i]&0x3f)==0x3f) emit_bichi_imm(fs,0x800000,fs); // c_ngt_d
- return;
- }
- #endif
-
- // C only
-
- u_int hr,reglist=0;
- for(hr=0;hr<HOST_REGS;hr++) {
- if(i_regs->regmap[hr]>=0) reglist|=1<<hr;
- }
- reglist&=~(1<<fs);
- save_regs(reglist);
- if(opcode2[i]==0x10) {
- emit_readword((int)®_cop1_simple[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_simple[(source[i]>>16)&0x1f],ARG2_REG);
- if((source[i]&0x3f)==0x30) emit_call((int)c_f_s);
- if((source[i]&0x3f)==0x31) emit_call((int)c_un_s);
- if((source[i]&0x3f)==0x32) emit_call((int)c_eq_s);
- if((source[i]&0x3f)==0x33) emit_call((int)c_ueq_s);
- if((source[i]&0x3f)==0x34) emit_call((int)c_olt_s);
- if((source[i]&0x3f)==0x35) emit_call((int)c_ult_s);
- if((source[i]&0x3f)==0x36) emit_call((int)c_ole_s);
- if((source[i]&0x3f)==0x37) emit_call((int)c_ule_s);
- if((source[i]&0x3f)==0x38) emit_call((int)c_sf_s);
- if((source[i]&0x3f)==0x39) emit_call((int)c_ngle_s);
- if((source[i]&0x3f)==0x3a) emit_call((int)c_seq_s);
- if((source[i]&0x3f)==0x3b) emit_call((int)c_ngl_s);
- if((source[i]&0x3f)==0x3c) emit_call((int)c_lt_s);
- if((source[i]&0x3f)==0x3d) emit_call((int)c_nge_s);
- if((source[i]&0x3f)==0x3e) emit_call((int)c_le_s);
- if((source[i]&0x3f)==0x3f) emit_call((int)c_ngt_s);
- }
- if(opcode2[i]==0x11) {
- emit_readword((int)®_cop1_double[(source[i]>>11)&0x1f],ARG1_REG);
- emit_readword((int)®_cop1_double[(source[i]>>16)&0x1f],ARG2_REG);
- if((source[i]&0x3f)==0x30) emit_call((int)c_f_d);
- if((source[i]&0x3f)==0x31) emit_call((int)c_un_d);
- if((source[i]&0x3f)==0x32) emit_call((int)c_eq_d);
- if((source[i]&0x3f)==0x33) emit_call((int)c_ueq_d);
- if((source[i]&0x3f)==0x34) emit_call((int)c_olt_d);
- if((source[i]&0x3f)==0x35) emit_call((int)c_ult_d);
- if((source[i]&0x3f)==0x36) emit_call((int)c_ole_d);
- if((source[i]&0x3f)==0x37) emit_call((int)c_ule_d);
- if((source[i]&0x3f)==0x38) emit_call((int)c_sf_d);
- if((source[i]&0x3f)==0x39) emit_call((int)c_ngle_d);
- if((source[i]&0x3f)==0x3a) emit_call((int)c_seq_d);
- if((source[i]&0x3f)==0x3b) emit_call((int)c_ngl_d);
- if((source[i]&0x3f)==0x3c) emit_call((int)c_lt_d);
- if((source[i]&0x3f)==0x3d) emit_call((int)c_nge_d);
- if((source[i]&0x3f)==0x3e) emit_call((int)c_le_d);
- if((source[i]&0x3f)==0x3f) emit_call((int)c_ngt_d);
- }
- restore_regs(reglist);
- emit_loadreg(FSREG,fs);
-#else
- cop1_unusable(i, i_regs);
-#endif