// If top is 0 and sign_extend is not, then ARM register v is sign extended,\r
// e.g. 0xc000 -> 0xffffc000 (else it may or may not be sign extended)\r
\r
-int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend)\r
+int EaRead(int a,int v,int ea,int size,int mask,int top,int sign_extend,int set_nz)\r
{\r
char text[32]="";\r
+ const char *s="";\r
+ int flags_set=0;\r
int shift=0;\r
\r
+ if (set_nz) s="s";\r
+\r
shift=32-(8<<size);\r
\r
DisaPc=2; DisaGetEa(text,ea,size); // Get text version of the effective address\r
else if (lsl<0) ot(" ldr%s r%d,[r7,r%d,lsr #%i]\n",Narm[nsarm],v,a,-lsl);\r
else ot(" ldr%s r%d,[r7,r%d]\n",Sarm[nsarm],v,a);\r
\r
- if (top&&shift) ot(" mov r%d,r%d,asl #%d\n",v,v,shift);\r
+ if (top&&shift) ot(" mov%s r%d,r%d,asl #%d\n",s,v,v,shift);\r
+ else if(set_nz) ot(" tst r%d,r%d\n",v,v);\r
\r
ot("\n"); return 0;\r
}\r
\r
if (top) asl=shift;\r
\r
- if (asl) ot(" mov r%d,r%d,asl #%d\n",v,a,asl);\r
- else if (v!=a) ot(" mov r%d,r%d\n",v,a);\r
+ if (asl) ot(" mov%s r%d,r%d,asl #%d\n",s,v,a,asl);\r
+ else if (v!=a) ot(" mov%s r%d,r%d\n",s,v,a);\r
+ else if (set_nz) ot(" tst r%d,r%d\n",v,v);\r
ot("\n"); return 0;\r
}\r
\r
{\r
int d_reg=0;\r
if (shift) {\r
- ot(" mov r%d,r%d,asl #%d\n",v,d_reg,shift);\r
+ ot(" mov%s r%d,r%d,asl #%d\n",s,v,d_reg,shift);\r
d_reg=v;\r
+ flags_set=1;\r
}\r
if (!top && shift) {\r
- ot(" mov r%d,r%d,asr #%d\n",v,d_reg,shift);\r
+ ot(" mov%s r%d,r%d,asr #%d\n",s,v,d_reg,shift);\r
d_reg=v;\r
+ flags_set=1;\r
+ }\r
+ if (d_reg != v) {\r
+ ot(" mov%s r%d,r%d\n",s,v,d_reg);\r
+ flags_set=1;\r
}\r
- if (d_reg != v)\r
- ot(" mov r%d,r%d\n",v,d_reg);\r
}\r
else\r
{\r
- if (top && shift)\r
- ot(" mov r%d,r0,asl #%d\n",v,shift);\r
- else if (v!=0)\r
- ot(" mov r%d,r0\n",v);\r
+ if (top && shift) {\r
+ ot(" mov%s r%d,r0,asl #%d\n",s,v,shift);\r
+ flags_set=1;\r
+ }\r
+ else if (v!=0) {\r
+ ot(" mov%s r%d,r0\n",s,v);\r
+ flags_set=1;\r
+ }\r
}\r
\r
+ if (set_nz&&!flags_set)\r
+ ot(" tst r%d,r%d\n",v,v);\r
+\r
ot("\n"); return 0;\r
}\r
\r
// size values 0, 1, 2 ~ byte, word, long\r
// r_ea is reg to store ea in (-1 means ea is not needed), r is dst reg\r
// if sign_extend is 0, non-32bit values will have MS bits undefined\r
-int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend)\r
+int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend,int set_nz)\r
{\r
if (ea<0x10)\r
{\r
}\r
\r
EaCalc (r_ea,mask,ea,size,0,sign_extend);\r
- EaRead (r_ea, r,ea,size,mask,0,sign_extend);\r
+ EaRead (r_ea, r,ea,size,mask,0,sign_extend,set_nz);\r
\r
return 0;\r
}\r
return 0;\r
}\r
\r
+void OpGetFlagsNZ(int rd)\r
+{\r
+ ot(" and r10,r%d,#0x80000000 ;@ r10=N_flag\n",rd);\r
+ ot(" orreq r10,r10,#0x40000000 ;@ get NZ, clear CV\n");\r
+}\r
+\r
// -----------------------------------------------------------------\r
\r
int g_op;\r
\r
ot(";@ Do arithmetic:\n");\r
\r
- if (type==0) ot(" orr r1,r10,r0%s\n",shiftstr);\r
- if (type==1) ot(" and r1,r10,r0%s\n",shiftstr);\r
+ if (type==0) ot(" orrs r1,r10,r0%s\n",shiftstr);\r
+ if (type==1) ot(" ands r1,r10,r0%s\n",shiftstr);\r
if (type==2||type==6)\r
ot(" rsbs r1,r10,r0%s ;@ Defines NZCV\n",shiftstr);\r
if (type==3) ot(" adds r1,r10,r0%s ;@ Defines NZCV\n",shiftstr);\r
- if (type==5) ot(" eor r1,r10,r0%s\n",shiftstr);\r
+ if (type==5) ot(" eors r1,r10,r0%s\n",shiftstr);\r
\r
- if (type<2 || type==5) ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n"); // 0,1,5\r
-\r
- if (type< 2) OpGetFlags(0,0); // Ori/And\r
+ if (type< 2) OpGetFlagsNZ(1); // Ori/And\r
if (type==2) OpGetFlags(1,1); // Sub: Subtract/X-bit\r
if (type==3) OpGetFlags(0,1); // Add: X-bit\r
- if (type==5) OpGetFlags(0,0); // Eor\r
+ if (type==5) OpGetFlagsNZ(1); // Eor\r
if (type==6) OpGetFlags(1,0); // Cmp: Subtract\r
ot("\n");\r
\r
EaCalcReadNoSE(dir?-1:11,1,rea,size,0x0e00);\r
\r
ot(";@ Do arithmetic:\n");\r
- if (type==0) strop = "orr";\r
+ if (type==0) strop = "orrs";\r
if (type==1) strop = (char *) (dir ? "subs" : "rsbs");\r
- if (type==4) strop = "and";\r
+ if (type==4) strop = "ands";\r
if (type==5) strop = "adds";\r
\r
if (size==0) asl=",asl #24";\r
if (size<2) ot(" mov r0,r0%s\n",asl);\r
ot(" %s r1,r0,r1%s\n",strop,asl);\r
\r
- if ((type&1)==0) ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
-\r
- OpGetFlags(type==1,type&1); // 1==subtract\r
+ if (type&1) OpGetFlags(type==1,type&1); // add/subtract\r
+ else OpGetFlagsNZ(1);\r
ot("\n");\r
\r
ot(";@ Save result:\n");\r
ot("\n");\r
}\r
\r
- ot(" mov r1,r3,lsl #16 ;@ Clip to 16-bits\n");\r
- ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
- OpGetFlags(0,0);\r
+ ot(" movs r1,r3,lsl #16 ;@ Clip to 16-bits\n");\r
+ OpGetFlagsNZ(1);\r
\r
ot(" mov r1,r1,lsr #16\n");\r
ot(" orr r1,r1,r2,lsl #16 ;@ Insert remainder\n");\r
ot(" mov r2,r2,%s #16\n",sign?"asr":"lsr");\r
ot("\n");\r
\r
- ot(" mul r1,r2,r0\n");\r
- ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
- OpGetFlags(0,0);\r
+ ot(" muls r1,r2,r0\n");\r
+ OpGetFlagsNZ(1);\r
}\r
ot("\n");\r
\r
if (size<2) asl=(char *)(size?",asl #16":",asl #24");\r
\r
ot(";@ Do arithmetic:\n");\r
- if (eor==0) ot(" rsbs r1,r0,r1%s\n",asl);\r
if (eor)\r
{\r
- ot(" eor r1,r0,r1%s\n",asl);\r
- ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
+ ot(" eors r1,r0,r1%s\n",asl);\r
+ OpGetFlagsNZ(1);\r
+ }\r
+ else\r
+ {\r
+ ot(" rsbs r1,r0,r1%s\n",asl);\r
+ OpGetFlags(1,0); // Cmp like subtract\r
}\r
-\r
- OpGetFlags(eor==0,0); // Cmp like subtract\r
ot("\n");\r
\r
if (eor) EaWrite(11, 1,ea,size,0x003f,1);\r
EaCalcReadNoSE(-1,1,rea,size,0x0e00);\r
\r
if (size<2) ot(" mov r0,r0,asl #%d\n",size?16:24);\r
- if (size<2) ot(" mov r1,r1,asl #%d\n\n",size?16:24);\r
+\r
+ if (size<2) ot(" movs r1,r1,asl #%d\n\n",size?16:24);\r
+ else ot(" adds r1,r1,#0 ;@ Define flags\n");\r
\r
ot(";@ get flags, including undocumented ones\n");\r
ot(" and r3,r10,#0x80000000\n");\r
- ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
- OpGetFlags(0,0);\r
+ OpGetFlagsNZ(1);\r
\r
ot(";@ is reg negative?\n");\r
ot(" bmi chktrap%.4x\n",op);\r
\r
ot(";@ Do arithmetic:\n");\r
- ot(" bic r10,r10,#0x80000000 ;@ N\n");\r
ot(" cmp r1,r0\n");\r
ot(" bgt chktrap%.4x\n",op);\r
\r
ot(";@ Not:\n");\r
if(size!=2) {\r
ot(" mov r0,r0,asl #%i\n",size?16:24);\r
- ot(" mvn r1,r0,asr #%i\n",size?16:24);\r
+ ot(" mvns r1,r0,asr #%i\n",size?16:24);\r
}\r
else\r
- ot(" mvn r1,r0\n");\r
- ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
- OpGetFlags(0,0);\r
+ ot(" mvns r1,r0\n");\r
+ OpGetFlagsNZ(1);\r
ot("\n");\r
}\r
\r
EaCalc (11,0x0007,ea,2,1);\r
EaRead (11, 0,ea,2,0x0007,1);\r
\r
- ot(" mov r1,r0,ror #16\n");\r
- ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
- OpGetFlags(0,0);\r
+ ot(" movs r1,r0,ror #16\n");\r
+ OpGetFlagsNZ(1);\r
\r
EaWrite(11, 1,8,2,0x0007,1);\r
\r
\r
OpStart(op,sea); Cycles=4;\r
\r
- EaCalc ( 0,0x003f,sea,size,1);\r
- EaRead ( 0, 0,sea,size,0x003f,1);\r
+ EaCalc (0,0x003f,sea,size,1);\r
+ EaRead (0, 0,sea,size,0x003f,1,0,1);\r
\r
- ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n");\r
- ot(" mrs r10,cpsr ;@ r10=flags\n");\r
+ OpGetFlagsNZ(0);\r
ot("\n");\r
\r
OpEnd(sea);\r
EaCalc (11,0x0007,ea,size+1,0,0);\r
EaRead (11, 0,ea,size+1,0x0007,0,0);\r
\r
- ot(" mov r0,r0,asl #%d\n",shift);\r
- ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n");\r
- ot(" mrs r10,cpsr ;@ r10=flags\n");\r
+ ot(" movs r0,r0,asl #%d\n",shift);\r
+ OpGetFlagsNZ(0);\r
ot(" mov r1,r0,asr #%d\n",shift);\r
ot("\n");\r
\r
ot(" b nozerox%.4x\n",op);\r
ot("norotx_%.4x%s\n",op,ms?"":":");\r
ot(" ldr r2,[r7,#0x4c]\n");\r
- ot(" adds r0,r0,#0 ;@ Defines NZ, clears CV\n");\r
- OpGetFlags(0,0);\r
+ ot(" adds r0,r0,#0 ;@ Define flags\n");\r
+ OpGetFlagsNZ(0);\r
ot(" and r2,r2,#0x20000000\n");\r
ot(" orr r10,r10,r2 ;@ C = old_X\n");\r
ot("nozerox%.4x%s\n",op,ms?"":":");\r
if(ea>=8) Cycles+=10;\r
\r
EaCalc (11,0x003f,ea,0,1);\r
- EaRead (11, 1,ea,0,0x003f,1);\r
+ EaRead (11, 1,ea,0,0x003f,1,0,1);\r
\r
- ot(" adds r1,r1,#0 ;@ Defines NZ, clears CV\n");\r
- OpGetFlags(0,0);\r
+ OpGetFlagsNZ(1);\r
ot("\n");\r
\r
#if CYCLONE_FOR_GENESIS\r
\r
if (movea==0)\r
{\r
- EaCalcRead(-1,0,sea,size,0x003f);\r
- ot(" adds r1,r0,#0 ;@ Defines NZ, clears CV\n");\r
- ot(" mrs r10,cpsr ;@ r10=NZCV flags\n");\r
+ EaCalcRead(-1,1,sea,size,0x003f,1,1);\r
+ OpGetFlagsNZ(1);\r
ot("\n");\r
}\r
else\r
ot(" movs r0,r8,asl #24\n");\r
ot(" and r1,r8,#0x0e00\n");\r
ot(" mov r0,r0,asr #24 ;@ Sign extended Quick value\n");\r
- ot(" mrs r10,cpsr ;@ r10=NZ flags\n");\r
+ OpGetFlagsNZ(0);\r
ot(" str r0,[r7,r1,lsr #7] ;@ Store into Dn\n");\r
ot("\n");\r
\r
extern int g_movem_cycle_table[];\r
int Ea_add_ns(int *tab, int ea); // add nonstandard EA cycles\r
int EaCalc(int a,int mask,int ea,int size,int top=0,int sign_extend=1); // 6\r
-int EaRead(int a,int v,int ea,int size,int mask,int top=0,int sign_extend=1); // 7\r
-int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend=1); // 6\r
+int EaRead(int a,int v,int ea,int size,int mask,int top=0,int sign_extend=1,int set_nz=0); // 8\r
+int EaCalcRead(int r_ea,int r,int ea,int size,int mask,int sign_extend=1,int set_nz=0); // 7\r
int EaCalcReadNoSE(int r_ea,int r,int ea,int size,int mask);\r
int EaCanRead(int ea,int size);\r
int EaWrite(int a,int v,int ea,int size,int mask,int top=0,int sign_extend_ea=1);\r
extern int g_op;\r
extern int opend_op_changes_cycles, opend_check_interrupt, opend_check_trace;\r
int OpGetFlags(int subtract,int xbit,int sprecialz=0);\r
+void OpGetFlagsNZ(int rd);\r
void OpUse(int op,int use);\r
void OpStart(int op,int sea=0,int tea=0,int op_changes_cycles=0,int supervisor_check=0);\r
void OpEnd(int sea=0,int tea=0);\r