output_w32(0xe2c00000|rd_rn_rm(rt,rt,0)|armval);
}*/
-static void emit_rscimm(int rs,int imm,u_int rt)
+static void emit_rscimm(int rs,int imm,u_int rt) //*SEB* why the assert(0) here?
{
- assert(0);
+// assert(0);
u_int armval, ret;
ret = genimm(imm,&armval);
assert(ret);
}
if(opcode2[i]==0x1A) // DIV
{
+ #if 0
+ signed char m1l=get_reg(i_regs->regmap,rs1[i]);
+ signed char m2l=get_reg(i_regs->regmap,rs2[i]);
+ assert(m1l>=0);
+ assert(m2l>=0);
+ save_regs(0x100f);
+ if(m1l!=0) emit_mov(m1l,0);
+ if(m2l<1) emit_readword((int)&dynarec_local,1);
+ else if(m2l>1) emit_mov(m2l,1);
+ emit_call((int)&div32);
+ restore_regs(0x100f);
+ signed char hil=get_reg(i_regs->regmap,HIREG);
+ if(hil>=0) emit_loadreg(HIREG,hil);
+ signed char lol=get_reg(i_regs->regmap,LOREG);
+ if(lol>=0) emit_loadreg(LOREG,lol);
+ #else
signed char d1=get_reg(i_regs->regmap,rs1[i]);
signed char d2=get_reg(i_regs->regmap,rs2[i]);
assert(d1>=0);
emit_negmi(quotient,quotient);
emit_test(d1,d1);
emit_negmi(remainder,remainder);
+ #endif
}
if(opcode2[i]==0x1B) // DIVU
{
- signed char d1=get_reg(i_regs->regmap,rs1[i]); // dividend
+ #if 0
+ signed char m1l=get_reg(i_regs->regmap,rs1[i]);
+ signed char m2l=get_reg(i_regs->regmap,rs2[i]);
+ assert(m1l>=0);
+ assert(m2l>=0);
+ save_regs(0x100f);
+ if(m1l!=0) emit_mov(m1l,0);
+ if(m2l<1) emit_readword((int)&dynarec_local,1);
+ else if(m2l>1) emit_mov(m2l,1);
+ emit_call((int)&divu32);
+ restore_regs(0x100f);
+ signed char hil=get_reg(i_regs->regmap,HIREG);
+ if(hil>=0) emit_loadreg(HIREG,hil);
+ signed char lol=get_reg(i_regs->regmap,LOREG);
+ if(lol>=0) emit_loadreg(LOREG,lol);
+ #else
+ signed char d1=get_reg(i_regs->regmap,rs1[i]); // dividend
signed char d2=get_reg(i_regs->regmap,rs2[i]); // divisor
assert(d1>=0);
assert(d2>=0);
emit_adcs(quotient,quotient,quotient);
emit_shrcc_imm(d2,1,d2);
emit_jcc((int)out-16); // -4
+ #endif
}
}
else // 64-bit
{
if(opcode2[i]==0x1C) // DMULT
{
- assert(opcode2[i]!=0x1C);
+ //assert(opcode2[i]!=0x1C);
signed char m1h=get_reg(i_regs->regmap,rs1[i]|64);
signed char m1l=get_reg(i_regs->regmap,rs1[i]);
signed char m2h=get_reg(i_regs->regmap,rs2[i]|64);
assert(m2h>=0);
assert(m1l>=0);
assert(m2l>=0);
- emit_pushreg(m2h);
- emit_pushreg(m2l);
- emit_pushreg(m1h);
- emit_pushreg(m1l);
+ save_regs(0x100f);
+ if(m1l!=0) emit_mov(m1l,0);
+ if(m1h==0) emit_readword((int)&dynarec_local,1);
+ else if(m1h>1) emit_mov(m1h,1);
+ if(m2l<2) emit_readword((int)&dynarec_local+m2l*4,2);
+ else if(m2l>2) emit_mov(m2l,2);
+ if(m2h<3) emit_readword((int)&dynarec_local+m2h*4,3);
+ else if(m2h>3) emit_mov(m2h,3);
emit_call((int)&mult64);
- emit_popreg(m1l);
- emit_popreg(m1h);
- emit_popreg(m2l);
- emit_popreg(m2h);
+ restore_regs(0x100f);
signed char hih=get_reg(i_regs->regmap,HIREG|64);
signed char hil=get_reg(i_regs->regmap,HIREG);
if(hih>=0) emit_loadreg(HIREG|64,hih);
restore_regs(0x100f);
signed char hih=get_reg(i_regs->regmap,HIREG|64);
signed char hil=get_reg(i_regs->regmap,HIREG);
+ if(hih>=0) emit_loadreg(HIREG|64,hih);
+ if(hil>=0) emit_loadreg(HIREG,hil);
signed char loh=get_reg(i_regs->regmap,LOREG|64);
signed char lol=get_reg(i_regs->regmap,LOREG);
+ if(loh>=0) emit_loadreg(LOREG|64,loh);
+ if(lol>=0) emit_loadreg(LOREG,lol);
/*signed char temp=get_reg(i_regs->regmap,-1);
signed char rh=get_reg(i_regs->regmap,HIREG|64);
signed char rl=get_reg(i_regs->regmap,HIREG);
// Multiply by zero is zero.
// MIPS does not have a divide by zero exception.
// The result is undefined, we return zero.
- signed char hr=get_reg(i_regs->regmap,HIREG);
- signed char lr=get_reg(i_regs->regmap,LOREG);
- if(hr>=0) emit_zeroreg(hr);
- if(lr>=0) emit_zeroreg(lr);
+ if((opcode2[i]&4)!=0) // 64-bit
+ {
+ signed char hih=get_reg(i_regs->regmap,HIREG|64);
+ signed char hr=get_reg(i_regs->regmap,HIREG);
+ signed char loh=get_reg(i_regs->regmap,LOREG|64);
+ signed char lr=get_reg(i_regs->regmap,LOREG);
+ if(hih>=0) emit_zeroreg(hih);
+ if(hr>=0) emit_zeroreg(hr);
+ if(loh>=0) emit_zeroreg(loh);
+ if(lr>=0) emit_zeroreg(lr);
+ } else
+ {
+ signed char hr=get_reg(i_regs->regmap,HIREG);
+ signed char lr=get_reg(i_regs->regmap,LOREG);
+ if(hr>=0) emit_zeroreg(hr);
+ if(lr>=0) emit_zeroreg(lr);
+ }
}
}
#define multdiv_assemble multdiv_assemble_arm