Skip to content

Commit

Permalink
Program Status, CC flags, and FR81 (#5)
Browse files Browse the repository at this point in the history
Fixes: #6

* Pack and unpack PS when possible

* Adding three new fr81

* Update fr60.sinc

Fix use of _flag vs register

* Remove unused defines

* special register cleanup and bugfix

* Changed INT logic to reduce noise from packing PS
  • Loading branch information
mumbel authored Dec 26, 2022
1 parent a8ecd56 commit 7986bba
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 43 deletions.
110 changes: 81 additions & 29 deletions data/languages/fr60.sinc
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ define token instr32 (32)

attach variables [ ri rj ] [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 AC FP SP ];

attach variables [ rs ] [ TBR RP SSP USP MDH MDL _ _ _ _ _ _ _ _ _ _ ];
attach variables [ rs rs4_4 ] [ TBR RP SSP USP MDH MDL _ _ _ _ _ _ _ _ _ _ ];

# ====

Expand All @@ -95,22 +95,40 @@ macro mulFlags64(val1, val2) {
V = (val1 != 0 && (val1 > (0xFFFFFFFFFFFFFFFF / val2)));
}

macro loadCCR() {
S = (PS & 0b00100000) != 0;
I = (PS & 0b00010000) != 0;
N = (PS & 0b00001000) != 0;
Z = (PS & 0b00000100) != 0;
V = (PS & 0b00000010) != 0;
C = (PS & 0b00000001) != 0;
macro unpackCCR() {
S = PS[5,1];
I = PS[4,1];
N = PS[3,1];
Z = PS[2,1];
V = PS[1,1];
C = PS[0,1];
}

macro loadProgramStatus() {
local ilm_sft:4 = (PS & 0b11110000000000000000) >> 16;
ILM = ilm_sft:1;
D1 = (PS & 0b0000010000000000) != 0;
D0 = (PS & 0b0000001000000000) != 0;
T = (PS & 0b0000000100000000) != 0;
loadCCR();
macro packCCR() {
PS[0,1] = C;
PS[1,1] = V;
PS[2,1] = Z;
PS[3,1] = N;
PS[4,1] = I;
PS[5,1] = S;
}

# Pack before an instruction reads from PS
macro packProgramStatus() {
packCCR();
PS[8,1] = T;
PS[9,1] = D0;
PS[10,1] = D1;
PS[16,4] = ILM;
}

# Unpack after an instruction writes to PS
macro unpackProgramStatus() {
ILM = PS[16,4];
D1 = PS[10,1];
D0 = PS[9,1];
T = PS[8,1];
unpackCCR();
}

# ====
Expand All @@ -124,6 +142,8 @@ define pcodeop copld;
define pcodeop copst;
define pcodeop copsv;

define pcodeop clz;

# ====

bandl_ext: u4 is u4 {
Expand Down Expand Up @@ -289,19 +309,19 @@ ldm0_list: ldm_r1 is ldm_r1 {

CC: "RA" is cc=0x0 { local tmp:1 = 1; export tmp; }
CC: "NO" is cc=0x1 { local tmp:1 = 0; export tmp; }
CC: "EQ" is cc=0x2 { local tmp:1 = (Z == 1); export tmp; }
CC: "EQ" is cc=0x2 { local tmp:1 = (Z != 0); export tmp; }
CC: "NE" is cc=0x3 { local tmp:1 = (Z == 0); export tmp; }
CC: "C" is cc=0x4 { local tmp:1 = (C == 1); export tmp; }
CC: "C" is cc=0x4 { local tmp:1 = (C != 0); export tmp; }
CC: "NC" is cc=0x5 { local tmp:1 = (C == 0); export tmp; }
CC: "N" is cc=0x6 { local tmp:1 = (N == 1); export tmp; }
CC: "N" is cc=0x6 { local tmp:1 = (N != 0); export tmp; }
CC: "P" is cc=0x7 { local tmp:1 = (N == 0); export tmp; }
CC: "V" is cc=0x8 { local tmp:1 = (V == 1); export tmp; }
CC: "V" is cc=0x8 { local tmp:1 = (V != 0); export tmp; }
CC: "NV" is cc=0x9 { local tmp:1 = (V == 0); export tmp; }
CC: "LT" is cc=0xA { local tmp:1 = ((V ^ N) == 1); export tmp; }
CC: "GE" is cc=0xB { local tmp:1 = ((V ^ N) == 0); export tmp; }
CC: "LE" is cc=0xC { local tmp:1 = (((V ^ N) | Z) == 1); export tmp; }
CC: "GT" is cc=0xD { local tmp:1 = (((V ^ N) | Z) == 0); export tmp; }
CC: "LS" is cc=0xE { local tmp:1 = ((C | Z) == 1); export tmp; }
CC: "LT" is cc=0xA { local tmp:1 = ((V != N) != 0); export tmp; }
CC: "GE" is cc=0xB { local tmp:1 = ((V != N) == 0); export tmp; }
CC: "LE" is cc=0xC { local tmp:1 = (((V != N) | Z) != 0); export tmp; }
CC: "GT" is cc=0xD { local tmp:1 = (((V != N) | Z) == 0); export tmp; }
CC: "LS" is cc=0xE { local tmp:1 = ((C | Z) != 0); export tmp; }
CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }


Expand Down Expand Up @@ -613,7 +633,7 @@ CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }
MDL = MDL | 0x1;
<END>

$(Z_flag) = MDH == 0;
Z = MDH == 0;
}

# DIV2 Ri E 97-7 1 -C-C
Expand Down Expand Up @@ -800,6 +820,7 @@ CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }
# LD @R15+, PS E 07-9 1+a+b CCCC (R15) --> PS, R15+=4
:LD @SP+, PS is op16=0x0790 & SP & PS {
PS = *:4 SP;
unpackProgramStatus();
SP = SP + 4;
}

Expand Down Expand Up @@ -860,20 +881,21 @@ CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }
}

# ST Ri, @-R15 E 17-0 a ---- R15-=4,Ri --> (R15)
:ST ri @-SP is op12=0x170 & ri & SP {
:ST ri, @-SP is op12=0x170 & ri & SP {
SP = SP - 4;
*:4 SP = ri;
}

# ST Rs, @-R15 E 17-8 a ---- R15-=4, Rs --> (R15)
:ST rs @-SP is op12=0x178 & rs & SP {
:ST rs, @-SP is op12=0x178 & rs & SP {
SP = SP - 4;
*:4 SP = rs;
}

# ST PS, @-R15 E 17-9 a ---- R15-=4, PS --> (R15)
:ST PS, @-SP is op16=0x1790 & SP & PS {
SP = SP - 4;
packProgramStatus();
*:4 SP = PS;
}

Expand Down Expand Up @@ -930,12 +952,14 @@ CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }

# MOV PS, Ri E 17-1 1 ---- PS --> Ri
:MOV PS, ri is op12=0x171 & ri & PS {
packProgramStatus();
ri = PS;
}

# MOV Ri, PS E 07-1 c CCCC Ri --> PS
:MOV ri, PS is op12=0x071 & ri & PS {
PS = ri;
unpackProgramStatus();
}

# ====
Expand Down Expand Up @@ -990,7 +1014,8 @@ CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }

# INT #u8 D AC 3+3a ---- SSP-=4,PS --> (SSP),SSP-=4,PC+2 --> (SSP),(TBR+0x3FC-u8x4) --> PC
:INT #u8 is op8=0x1f & u8 {
local ea:4 = inst_next;
local ea:4 = inst_next;
# Could packProgramStatus() into PS, but letting pcodeop handle that;
_interrupt_prelude(PS, ea);
call [((TBR + 0x3FC) - (sext(u8:2) << 2))];
}
Expand All @@ -1004,7 +1029,7 @@ CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }
SP = SP + 4;
PS = *:4 SP;
SP = SP + 4;
loadProgramStatus();
unpackProgramStatus();
return [tempsp];
}

Expand Down Expand Up @@ -1285,3 +1310,30 @@ CC: "HI" is cc=0xF { local tmp:1 = ((C | Z) == 0); export tmp; }
ri = zext(*:1 rj);
*:1 rj = temp;
}

# ===
# SRCH0 Ri E 97-C ---- search_zero(Ri) → Ri
:SRCH0 ri is op12=0x97c & ri {
local tmp:4 = ~ri;
ri = 32;
if (tmp == 0) goto inst_next;
ri = clz(tmp);
}

# SRCH1 Ri E 97-D ---- search_one(Ri) → Ri
:SRCH1 ri is op12=0x97d & ri {
local tmp:4 = ri;
ri = 32;
if (tmp == 0) goto inst_next;
ri = clz(tmp);
}

# SRCHC Ri E 97-E ---- search_change(Ri) → Ri
:SRCHC ri is op12=0x97e & ri {
local tmp:4 = ri;
local neg = tmp s< 0;
tmp = (tmp * zext(neg == 0)) + (~tmp * zext(neg != 0));
ri = 32;
if (tmp == 0) goto inst_next;
ri = clz(tmp);
}
16 changes: 2 additions & 14 deletions data/languages/fr60.slaspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,8 @@ define register offset=0x20 size=4 [ R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12
define register offset=0x20 size=4 [ _ _ _ _ _ _ _ _ _ _ _ _ _ AC FP SP ];

# Fake flag registers for cleaner p-code decomp
# Instead of reading/writing bits to PS directly in each instruction
# these registers are used and then synced when there is PS access
define register offset=0x80 size=1 [ ILM D1 D0 T S I N Z V C ];

# Flag bits
@define ILM_flag "PS[16,4]" # ILM: Interrupt Level Mask
@define D1_flag "PS[10,1]"
@define D0_flag "PS[9,1]"
@define D_flag "PS[9,2]" # D: step Division
@define T_flag "PS[8,1]" # T: step Trace trap
@define S_flag "PS[5,1]" # S: Stack
@define I_flag "PS[4,1]" # I: Interrupt
@define N_flag "PS[3,1]" # N: Negative
@define Z_flag "PS[2,1]" # Z: Zero
@define V_flag "PS[1,1]" # V: oVerflow
@define C_flag "PS[0,1]" # C: Carry
@define CCR "PS[0,8]" # CCR: Condition Code Register

@include "fr60.sinc"

0 comments on commit 7986bba

Please sign in to comment.