output_w32(0xe3a00000|rd_rn_rm(rt,0,0));
}
+void emit_loadlp(u_int imm,u_int rt)
+{
+ add_literal((int)out,imm);
+ assem_debug("ldr %s,pc+? [=%x]\n",regname[rt],imm);
+ output_w32(0xe5900000|rd_rn_rm(rt,15,0));
+}
+void emit_movw(u_int imm,u_int rt)
+{
+ assert(imm<65536);
+ assem_debug("movw %s,#%d (0x%x)\n",regname[rt],imm,imm);
+ output_w32(0xe3000000|rd_rn_rm(rt,0,0)|(imm&0xfff)|((imm<<4)&0xf0000));
+}
+void emit_movt(u_int imm,u_int rt)
+{
+ assem_debug("movt %s,#%d (0x%x)\n",regname[rt],imm&0xffff0000,imm&0xffff0000);
+ output_w32(0xe3400000|rd_rn_rm(rt,0,0)|((imm>>16)&0xfff)|((imm>>12)&0xf0000));
+}
+void emit_movimm(u_int imm,u_int rt)
+{
+ u_int armval;
+ if(genimm(imm,&armval)) {
+ assem_debug("mov %s,#%d\n",regname[rt],imm);
+ output_w32(0xe3a00000|rd_rn_rm(rt,0,0)|armval);
+ }else if(genimm(~imm,&armval)) {
+ assem_debug("mvn %s,#%d\n",regname[rt],imm);
+ output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval);
+ }else if(imm<65536) {
+ #ifdef ARMv5_ONLY
+ assem_debug("mov %s,#%d\n",regname[rt],imm&0xFF00);
+ output_w32(0xe3a00000|rd_rn_imm_shift(rt,0,imm>>8,8));
+ assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF);
+ output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm&0xff,0));
+ #else
+ emit_movw(imm,rt);
+ #endif
+ }else{
+ #ifdef ARMv5_ONLY
+ emit_loadlp(imm,rt);
+ #else
+ emit_movw(imm&0x0000FFFF,rt);
+ emit_movt(imm&0xFFFF0000,rt);
+ #endif
+ }
+}
+void emit_pcreladdr(u_int rt)
+{
+ assem_debug("add %s,pc,#?\n",regname[rt]);
+ output_w32(0xe2800000|rd_rn_rm(rt,15,0));
+}
+
void emit_loadreg(int r, int hr)
{
#ifdef FORCE32
output_w32(0xe0200000|rd_rn_rm(rt,rs1,rs2));
}
-void emit_loadlp(u_int imm,u_int rt)
-{
- add_literal((int)out,imm);
- assem_debug("ldr %s,pc+? [=%x]\n",regname[rt],imm);
- output_w32(0xe5900000|rd_rn_rm(rt,15,0));
-}
-void emit_movw(u_int imm,u_int rt)
-{
- assert(imm<65536);
- assem_debug("movw %s,#%d (0x%x)\n",regname[rt],imm,imm);
- output_w32(0xe3000000|rd_rn_rm(rt,0,0)|(imm&0xfff)|((imm<<4)&0xf0000));
-}
-void emit_movt(u_int imm,u_int rt)
-{
- assem_debug("movt %s,#%d (0x%x)\n",regname[rt],imm&0xffff0000,imm&0xffff0000);
- output_w32(0xe3400000|rd_rn_rm(rt,0,0)|((imm>>16)&0xfff)|((imm>>12)&0xf0000));
-}
-void emit_movimm(u_int imm,u_int rt)
-{
- u_int armval;
- if(genimm(imm,&armval)) {
- assem_debug("mov %s,#%d\n",regname[rt],imm);
- output_w32(0xe3a00000|rd_rn_rm(rt,0,0)|armval);
- }else if(genimm(~imm,&armval)) {
- assem_debug("mvn %s,#%d\n",regname[rt],imm);
- output_w32(0xe3e00000|rd_rn_rm(rt,0,0)|armval);
- }else if(imm<65536) {
- #ifdef ARMv5_ONLY
- assem_debug("mov %s,#%d\n",regname[rt],imm&0xFF00);
- output_w32(0xe3a00000|rd_rn_imm_shift(rt,0,imm>>8,8));
- assem_debug("add %s,%s,#%d\n",regname[rt],regname[rt],imm&0xFF);
- output_w32(0xe2800000|rd_rn_imm_shift(rt,rt,imm&0xff,0));
- #else
- emit_movw(imm,rt);
- #endif
- }else{
- #ifdef ARMv5_ONLY
- emit_loadlp(imm,rt);
- #else
- emit_movw(imm&0x0000FFFF,rt);
- emit_movt(imm&0xFFFF0000,rt);
- #endif
- }
-}
-void emit_pcreladdr(u_int rt)
-{
- assem_debug("add %s,pc,#?\n",regname[rt]);
- output_w32(0xe2800000|rd_rn_rm(rt,15,0));
-}
-
void emit_addimm(u_int rs,int imm,u_int rt)
{
assert(rs<16);
void emit_andimm(int rs,int imm,int rt)
{
u_int armval;
- if(genimm(imm,&armval)) {
+ if(imm==0) {
+ emit_zeroreg(rt);
+ }else if(genimm(imm,&armval)) {
assem_debug("and %s,%s,#%d\n",regname[rt],regname[rs],imm);
output_w32(0xe2000000|rd_rn_rm(rt,rs,0)|armval);
}else if(genimm(~imm,&armval)) {
void emit_orimm(int rs,int imm,int rt)
{
u_int armval;
- if(genimm(imm,&armval)) {
+ if(imm==0) {
+ if(rs!=rt) emit_mov(rs,rt);
+ }else if(genimm(imm,&armval)) {
assem_debug("orr %s,%s,#%d\n",regname[rt],regname[rs],imm);
output_w32(0xe3800000|rd_rn_rm(rt,rs,0)|armval);
}else{
void emit_xorimm(int rs,int imm,int rt)
{
u_int armval;
- if(genimm(imm,&armval)) {
+ if(imm==0) {
+ if(rs!=rt) emit_mov(rs,rt);
+ }else if(genimm(imm,&armval)) {
assem_debug("eor %s,%s,#%d\n",regname[rt],regname[rs],imm);
output_w32(0xe2200000|rd_rn_rm(rt,rs,0)|armval);
}else{
}
assert(rs>=0);
if(addr<0) addr=rt;
- if(addr<0)
- // assume dummy read, no alloced reg
- addr=get_reg(i_regmap,-1);
+ if(addr<0&&itype[i]!=C1LS&&itype[i]!=C2LS&&itype[i]!=LOADLR) addr=get_reg(i_regmap,-1);
assert(addr>=0);
int ftable=0;
if(type==LOADB_STUB||type==LOADBU_STUB)
int rs=get_reg(regmap,target);
int rth=get_reg(regmap,target|64);
int rt=get_reg(regmap,target);
- // allow for PCSX dummy reads
- //assert(rt>=0);
- if(rs<0)
- rs=get_reg(regmap,-1);
+ if(rs<0) rs=get_reg(regmap,-1);
assert(rs>=0);
int ftable=0;
if(type==LOADB_STUB||type==LOADBU_STUB)
memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
}
- if(tl>=0) {
- //assert(tl>=0);
- //assert(rt1[i]);
- if(!using_tlb) {
- if(!c) {
- emit_shlimm(addr,3,temp);
- if (opcode[i]==0x22||opcode[i]==0x26) {
- emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR
- }else{
- emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR
- }
- emit_cmpimm(addr,RAM_SIZE);
- jaddr=(int)out;
- emit_jno(0);
- }
- else {
- if (opcode[i]==0x22||opcode[i]==0x26) {
- emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
- }else{
- emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
- }
- }
- }else{ // using tlb
- int a;
- if(c) {
- a=-1;
- }else if (opcode[i]==0x22||opcode[i]==0x26) {
- a=0xFFFFFFFC; // LWL/LWR
+ if(!using_tlb) {
+ if(!c) {
+ #ifdef RAM_OFFSET
+ map=get_reg(i_regs->regmap,ROREG);
+ if(map<0) emit_loadreg(ROREG,map=HOST_TEMPREG);
+ #endif
+ emit_shlimm(addr,3,temp);
+ if (opcode[i]==0x22||opcode[i]==0x26) {
+ emit_andimm(addr,0xFFFFFFFC,temp2); // LWL/LWR
}else{
- a=0xFFFFFFF8; // LDL/LDR
+ emit_andimm(addr,0xFFFFFFF8,temp2); // LDL/LDR
}
- map=get_reg(i_regs->regmap,TLREG);
- assert(map>=0);
- map=do_tlb_r(addr,temp2,map,0,a,c?-1:temp,c,constmap[i][s]+offset);
- if(c) {
- if (opcode[i]==0x22||opcode[i]==0x26) {
- emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
- }else{
- emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
- }
+ emit_cmpimm(addr,RAM_SIZE);
+ jaddr=(int)out;
+ emit_jno(0);
+ }
+ else {
+ if (opcode[i]==0x22||opcode[i]==0x26) {
+ emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
+ }else{
+ emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
}
- do_tlb_r_branch(map,c,constmap[i][s]+offset,&jaddr);
}
- if (opcode[i]==0x22||opcode[i]==0x26) { // LWL/LWR
- if(!c||memtarget) {
- //emit_readword_indexed((int)rdram-0x80000000,temp2,temp2);
- emit_readword_indexed_tlb((int)rdram-0x80000000,temp2,map,temp2);
- if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
+ }else{ // using tlb
+ int a;
+ if(c) {
+ a=-1;
+ }else if (opcode[i]==0x22||opcode[i]==0x26) {
+ a=0xFFFFFFFC; // LWL/LWR
+ }else{
+ a=0xFFFFFFF8; // LDL/LDR
+ }
+ map=get_reg(i_regs->regmap,TLREG);
+ assert(map>=0);
+ map=do_tlb_r(addr,temp2,map,0,a,c?-1:temp,c,constmap[i][s]+offset);
+ if(c) {
+ if (opcode[i]==0x22||opcode[i]==0x26) {
+ emit_movimm(((constmap[i][s]+offset)<<3)&24,temp); // LWL/LWR
+ }else{
+ emit_movimm(((constmap[i][s]+offset)<<3)&56,temp); // LDL/LDR
}
- else
- inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj[i],reglist);
+ }
+ do_tlb_r_branch(map,c,constmap[i][s]+offset,&jaddr);
+ }
+ if (opcode[i]==0x22||opcode[i]==0x26) { // LWL/LWR
+ if(!c||memtarget) {
+ //emit_readword_indexed((int)rdram-0x80000000,temp2,temp2);
+ emit_readword_indexed_tlb(0,temp2,map,temp2);
+ if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
+ }
+ else
+ inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj[i],reglist);
+ if(rt1[i]) {
+ assert(tl>=0);
emit_andimm(temp,24,temp);
#ifdef BIG_ENDIAN_MIPS
if (opcode[i]==0x26) // LWR
emit_bic_lsl(tl,HOST_TEMPREG,temp,tl);
}
emit_or(temp2,tl,tl);
- //emit_storereg(rt1[i],tl); // DEBUG
}
- if (opcode[i]==0x1A||opcode[i]==0x1B) { // LDL/LDR
- // FIXME: little endian
- int temp2h=get_reg(i_regs->regmap,FTEMP|64);
- if(!c||memtarget) {
- //if(th>=0) emit_readword_indexed((int)rdram-0x80000000,temp2,temp2h);
- //emit_readword_indexed((int)rdram-0x7FFFFFFC,temp2,temp2);
- emit_readdword_indexed_tlb((int)rdram-0x80000000,temp2,map,temp2h,temp2);
- if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
- }
- else
- inline_readstub(LOADD_STUB,i,(constmap[i][s]+offset)&0xFFFFFFF8,i_regs->regmap,FTEMP,ccadj[i],reglist);
+ //emit_storereg(rt1[i],tl); // DEBUG
+ }
+ if (opcode[i]==0x1A||opcode[i]==0x1B) { // LDL/LDR
+ // FIXME: little endian
+ int temp2h=get_reg(i_regs->regmap,FTEMP|64);
+ if(!c||memtarget) {
+ //if(th>=0) emit_readword_indexed((int)rdram-0x80000000,temp2,temp2h);
+ //emit_readword_indexed((int)rdram-0x7FFFFFFC,temp2,temp2);
+ emit_readdword_indexed_tlb(0,temp2,map,temp2h,temp2);
+ if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
+ }
+ else
+ inline_readstub(LOADD_STUB,i,(constmap[i][s]+offset)&0xFFFFFFF8,i_regs->regmap,FTEMP,ccadj[i],reglist);
+ if(rt1[i]) {
+ assert(th>=0);
+ assert(tl>=0);
emit_testimm(temp,32);
emit_andimm(temp,24,temp);
if (opcode[i]==0x1A) { // LDL