From cfe17eee41a12da11f69660c2764813e94d871ea Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 8 Sep 2013 04:40:40 +0300 Subject: [PATCH] avoid using msr causes pipeline flush on newer ARMs, and we don't want that --- OpArith.cpp | 2 +- OpBranch.cpp | 45 +++++---------------- OpLogic.cpp | 110 ++++++++++++++++++++++++++++++++++++++++----------- app.h | 1 + tools/idle.s | 12 +++--- 5 files changed, 104 insertions(+), 66 deletions(-) diff --git a/OpArith.cpp b/OpArith.cpp index d762049..ca279da 100644 --- a/OpArith.cpp +++ b/OpArith.cpp @@ -373,7 +373,7 @@ int GetXBit(int subtract) ot(";@ Get X bit:\n"); ot(" ldr r2,[r7,#0x4c]\n"); if (subtract) ot(" mvn r2,r2 ;@ Invert it\n"); - ot(" msr cpsr_flg,r2 ;@ Get into Carry\n"); + ot(" tst r2,r2,lsl #3 ;@ Get into Carry\n"); ot("\n"); return 0; } diff --git a/OpBranch.cpp b/OpBranch.cpp index fb4f561..051c373 100644 --- a/OpBranch.cpp +++ b/OpBranch.cpp @@ -312,6 +312,7 @@ static const char * const Cond[16]= // Emit a Dbra opcode, 0101cccc 11001nnn vv int OpDbra(int op) { + const char *cond; int use=0; int cc=0; @@ -321,25 +322,12 @@ int OpDbra(int op) if (op!=use) { OpUse(op,use); return 0; } // Use existing handler OpStart(op); - switch (cc) + if (cc>=2) { - case 0: // T - case 1: // F - break; - case 2: // hi - ot(" tst r10,#0x60000000 ;@ hi: !C && !Z\n"); - ot(" beq DbraTrue\n\n"); - break; - case 3: // ls - ot(" tst r10,#0x60000000 ;@ ls: C || Z\n"); - ot(" bne DbraTrue\n\n"); - break; - default: - ot(";@ Is the condition true?\n"); - ot(" msr cpsr_flg,r10 ;@ ARM flags = 68000 flags\n"); - ot(";@ If so, don't dbra\n"); - ot(" b%s DbraTrue\n\n",Cond[cc]); - break; + ot(";@ Is the condition true?\n"); + cond=TestCond(cc); + ot(";@ If so, don't dbra\n"); + ot(" b%s DbraTrue\n\n",cond); } if (cc!=0) @@ -419,6 +407,7 @@ int OpBranch(int op) int offset=0; int cc=0; const char *asr_r11=""; + const char *cond; int pc_reg=0; offset=(char)(op&0xff); @@ -436,24 +425,10 @@ int OpBranch(int op) OpStart(op,size?0x10:0); Cycles=10; // Assume branch taken - switch (cc) + if (cc>=2) { - case 0: // T - case 1: // F - break; - case 2: // hi - ot(" tst r10,#0x60000000 ;@ hi: !C && !Z\n"); - ot(" bne BccDontBranch%i\n\n",8<>8)&15; ea=op&0x003f; @@ -339,32 +413,20 @@ int OpSet(int op) OpStart(op,ea,0,changed_cycles); Cycles=8; if (ea<8) Cycles=4; - if (cc) - ot(" mov r1,#0\n"); - switch (cc) { - case 0: // T + case 0x00: // T ot(" mvn r1,#0\n"); if (ea<8) Cycles+=2; break; - case 1: // F - break; - case 2: // hi - ot(" tst r10,#0x60000000 ;@ hi: !C && !Z\n"); - ot(" mvneq r1,r1\n"); - if (ea<8) ot(" subeq r5,r5,#2 ;@ Extra cycles\n"); - break; - case 3: // ls - ot(" tst r10,#0x60000000 ;@ ls: C || Z\n"); - ot(" mvnne r1,r1\n"); - if (ea<8) ot(" subne r5,r5,#2 ;@ Extra cycles\n"); + case 0x01: // F + ot(" mov r1,#0\n"); break; default: - ot(";@ Is the condition true?\n"); - ot(" msr cpsr_flg,r10 ;@ ARM flags = 68000 flags\n"); - ot(" mvn%s r1,r1\n",cond[cc]); - if (ea<8) ot(" sub%s r5,r5,#2 ;@ Extra cycles\n",cond[cc]); + ot(" mov r1,#0\n"); + cond=TestCond(cc); + ot(" mvn%s r1,#0\n",cond); + if (ea<8) ot(" sub%s r5,r5,#2 ;@ Extra cycles\n",cond); break; } diff --git a/app.h b/app.h index 3528b7b..4a23630 100644 --- a/app.h +++ b/app.h @@ -102,6 +102,7 @@ int OpSet(int op); int OpAsr(int op); int OpAsrEa(int op); int OpTas(int op, int gen_special=0); +const char *TestCond(int m68k_cc, int invert=0); // OpMove.cpp int OpMove(int op); diff --git a/tools/idle.s b/tools/idle.s index e970d2e..e55b5f1 100644 --- a/tools/idle.s +++ b/tools/idle.s @@ -104,15 +104,15 @@ idle_bra: b Op6002 idle_bne: - msr cpsr_flg, r10 - movne r5, #2 @ 2 is intentional due to strange timing issues - inc_counter ne + tst r10, #0x40000000 @ Z set? + moveq r5, #2 @ 2 is intentional due to strange timing issues + inc_counter eq b Op6602 idle_beq: - msr cpsr_flg, r10 ;@ ARM flags = 68000 flags - moveq r5, #2 - inc_counter eq + tst r10, #0x40000000 @ Z set? + movne r5, #2 + inc_counter ne b Op6702 -- 2.39.5